cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
1575
Views
0
Helpful
7
Replies

can't remove sub interfaces - remove the whole interface

Noel Cantenot
Level 1
Level 1

Hi,

I wrote a yang model to configure a sub interface on a Juniper srx like this:

 

 

                     <interfaces xmlns="http://yang.juniper.net/junos-es/conf/interfaces">
                       <interface>
                         <name>st0</name>
                         <unit>
                           <name>{interface_number}</name>
                           <family>
                             <inet/>
                           </family>
                         </unit>
                       </interface>
                     </interfaces>

 

 

It works fine when creating the interface.

But when I want to remove the service I get an error because NSO tries to remove the interface st0, instead of removing only the subinterface st0.x.

 

 

 

admin@ncs(config)# no services vpn-remote-access gcf-myvpn
admin@ncs(config)# commit dry-run outformat cli-c
cli-c {
    local-node {
        data devices device srx
              config
                 .../...
               no configuration interfaces interface st0
                 .../...
    }
}
admin@ncs(config)#

 

 

 I tried to add tags "create" at the <unit> level, but it does not change anything. Do I misunderstood something with tags usage ?

Regards.

1 Accepted Solution

Accepted Solutions

I believe sync-from then create the service would bump the refcount on interface{st0} to 2, after which removal of the service doesn't delete interface{st0}, you can check the service-meta-data after service deployment.

that aside, the default operation on interface list is "merge", which means creation and removal of the service increases/decreases the refcount of interface{st0}, when refcount drops to 0 the list entry is deleted. check https://cisco-tailf.gitbook.io/nso-docs/guides/development/advanced-development/developing-services/services-deep-dive#ch_svcref.refcount

if you don't want your service to own interface{st0}, you should use "nocreate" tag and ensure it's always there in service pre-mod().

View solution in original post

7 Replies 7

Marcel Zehnder
Spotlight
Spotlight

Can you please post the yang module of your service?

Noel Cantenot
Level 1
Level 1

Here is the complet yang module.

<config-template xmlns="http://tail-f.com/ns/config/1.0">
  <devices xmlns="http://tail-f.com/ns/ncs">
               <device>
                 <name>{device_name}</name>
                 <config>
                   <configuration xmlns="http://yang.juniper.net/junos-es/conf/root">
                     <access xmlns="http://yang.juniper.net/junos-es/conf/access">
                       <profile>
                         <name>{$AccesProfileLocal}</name>
                         <client>
                           <name>{user/user_name}</name>
                           <firewall-user>
                             <password>{user_password}</password>
                           </firewall-user>
                         </client>
                         <address-assignment>
                           <pool>{$PoolVPN}</pool>
                         </address-assignment>
                       </profile>
                       <address-assignment>
                         <pool>
                           <name>{$PoolVPN}</name>
                           <family>
                             <inet>
                               <network>{client_ip_pool_network}</network>
                               <range>
                                 <name>{$PoolVPNRange}</name>
                                 <low>{client_ip_pool_low}</low>
                                 <high>{client_ip_pool_high}</high>
                               </range>
                             </inet>
                           </family>
                         </pool>
                       </address-assignment>
                     </access>
                     <interfaces xmlns="http://yang.juniper.net/junos-es/conf/interfaces">
                       <interface>
                         <name>st0</name>
                         <unit>
                           <name>{interface_number}</name>
                           <description>{$Description}</description>
                           <family>
                             <inet/>
                           </family>
                         </unit>
                       </interface>
                     </interfaces>
                     <security xmlns="http://yang.juniper.net/junos-es/conf/security">
                       <tcp-encap>
                         <profile>
                           <name>{$TCPEncapProfile}</name>
                           <ssl-profile>{$ProfileSSL}</ssl-profile>
                         </profile>
                       </tcp-encap>
                       <ike>
                         <proposal>
                           <name>{$RaProfileName}</name>
                           <description>{$Description}</description>
                           <authentication-method>pre-shared-keys</authentication-method>
                           <dh-group>group19</dh-group>
                           <authentication-algorithm>sha-256</authentication-algorithm>
                           <encryption-algorithm>aes-256-cbc</encryption-algorithm>
                           <lifetime-seconds>28800</lifetime-seconds>
                         </proposal>
                         <policy>
                           <name>{vpn_name}</name>
                           <mode>aggressive</mode>
                           <description>{$Description}</description>
                           <proposals>{$RaProfileName}</proposals>
                           <pre-shared-key>
                             <ascii-text>{$PreSharedKey}</ascii-text>
                           </pre-shared-key>
                         </policy>
                         <gateway>
                           <name>{vpn_name}</name>
                           <ike-policy>{vpn_name}</ike-policy>
                           <dynamic>
                             <user-at-hostname>{$UserAtHostname}</user-at-hostname>
                             <ike-user-type>shared-ike-id</ike-user-type>
                           </dynamic>
                           <dead-peer-detection>
                             <optimized/>
                             <interval>10</interval>
                             <threshold>5</threshold>
                           </dead-peer-detection>
                           <external-interface>{$ExternalInterface}</external-interface>
                           <local-address>{$PublicLocalAddress}</local-address>
                           <aaa>
                             <access-profile>
                               <name>{$AccesProfileLocal}</name>
                             </access-profile>
                           </aaa>
                           <version>v1-only</version>
                           <tcp-encap-profile>{$TCPEncapProfile}</tcp-encap-profile>
                         </gateway>
                       </ike>
                       <ipsec>
                         <proposal>
                           <name>{$RaProfileName}</name>
                           <description>{$Description}</description>
                           <protocol>esp</protocol>
                           <encryption-algorithm>aes-256-gcm</encryption-algorithm>
                           <lifetime-seconds>3600</lifetime-seconds>
                         </proposal>
                         <policy>
                           <name>{vpn_name}</name>
                           <description>{$Description}</description>
                           <perfect-forward-secrecy>
                             <keys>group19</keys>
                           </perfect-forward-secrecy>
                           <proposals>{$RaProfileName}</proposals>
                         </policy>
                         <vpn>
                           <name>{vpn_name}</name>
                           <bind-interface>{$InterfaceNumber}</bind-interface>
                           <df-bit>clear</df-bit>
                           <copy-outer-dscp/>
                           <ike>
                             <gateway>{vpn_name}</gateway>
                             <ipsec-policy>{vpn_name}</ipsec-policy>
                           </ike>
                           <traffic-selector>
                             <name>{/traffic_selector/traffic_selector_name}</name>
                             <local-ip>{traffic_selector_local_ip}</local-ip>
                             <remote-ip>0.0.0.0/0</remote-ip>
                           </traffic-selector>
                         </vpn>
                       </ipsec>
                       <remote-access>
                         <profile>
                           <name>{vpn_name}</name>
                           <description>{$Description}</description>
                           <ipsec-vpn>{vpn_name}</ipsec-vpn>
                           <access-profile>{$AccesProfileLocal}</access-profile>
                           <client-config>{vpn_name}</client-config>
                         </profile>
                         <client-config>
                           <name>{vpn_name}</name>
                           <connection-mode>manual</connection-mode>
                           <dead-peer-detection>
                             <interval>60</interval>
                             <threshold>5</threshold>
                           </dead-peer-detection>
                         </client-config>
                       </remote-access>
                     </security>
                     <services xmlns="http://yang.juniper.net/junos-es/conf/services">
                       <ssl>
                         <termination>
                           <profile>
                             <name>{$ProfileSSL}</name>
                             <server-certificate>{$ServerCertificat}</server-certificate>
                           </profile>
                         </termination>
                       </ssl>
                     </services>
                   </configuration>
                 </config>
               </device>  </devices>
</config-template>

Hi @Noel Cantenot that's the XML template, the YANG module would be more interesting, can you post this as well? 

oups, sorry

Here it is:

module vpn-remote-access {
 
  namespace "http://example.com/vpn-remote-access";
  prefix vpn-ra;
 
  import ietf-inet-types {
    prefix inet;
  }
  import tailf-common {
    prefix tailf;
  }
  import tailf-ncs {
    prefix ncs;
  }
 
  description
    "Modèle YANG pour la configuration VPN Remote Access.";
 
  revision 2024-10-14 {
    description
      "Initial revision.";
  }
 
  typedef network {
    description "Représentation simplifiée d'un network en notation CIDR.";
    type string {
      pattern '([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]{1,2}';
    }
}
 
  augment /ncs:services {
 
    list vpn-remote-access {
      description "Liste des VPN Remote Access.";
 
      key vpn_name;
      leaf vpn_name {
        tailf:info "Nom du VPN;
        type string{
          length "1..32";
        }
      }
      uses ncs:service-data;
      ncs:servicepoint vpn-remote-access-servicepoint;
 
      leaf device_name {
        type leafref {
          tailf:info "Nom du firewall.";
          path "/ncs:devices/ncs:device/ncs:name";
        }
      }
 
      leaf interface_number {
        tailf:info "Numéro de l'interface st0.x";
        type uint32 {
          range "100..300";
        }
 
      }
 
      leaf client_ip_pool_network {
        tailf:info "Plage d'adresses IP pour le pool client.";
        type network;
      }
 
      leaf client_ip_pool_low {
        tailf:info "Adresse IP basse du pool client.";
        type inet:ip-address;
      }
 
      leaf client_ip_pool_high {
        tailf:info "Adresse IP haute du pool client.";
        type inet:ip-address;
      }
 
      list traffic_selector {
        tailf:info "Liste de local IP (remote-ip toujours 0.0.0.0/0)";
        key "traffic_selector_name";
 
        leaf traffic_selector_name {
          type string;
        }
        leaf traffic_selector_local_ip {
          tailf:info "Adresse IP locale du sélecteur de trafic.";
          type network;
        }
      }
 
      list user {
        key "user_name";
 
        leaf user_name {
          tailf:info "Nom de l'utilisateur.";
          type string {
            length "0..32";
          }
        }
        leaf user_password {
          tailf:info "Mot de passe de l'utilisateur.";
          type string;
        }
      }
 
    }
  }
}
 

I ran some more tests, and I figured out that the srx and NSO were not synchronized.

After sync-from the srx, the problem disappears, and only sub interface is removed.

I don't understand this side effect, but it seems to be the "explanation".

I believe sync-from then create the service would bump the refcount on interface{st0} to 2, after which removal of the service doesn't delete interface{st0}, you can check the service-meta-data after service deployment.

that aside, the default operation on interface list is "merge", which means creation and removal of the service increases/decreases the refcount of interface{st0}, when refcount drops to 0 the list entry is deleted. check https://cisco-tailf.gitbook.io/nso-docs/guides/development/advanced-development/developing-services/services-deep-dive#ch_svcref.refcount

if you don't want your service to own interface{st0}, you should use "nocreate" tag and ensure it's always there in service pre-mod().

Marcel Zehnder
Spotlight
Spotlight

Awesome, that's great news! Sorry for the delay—I haven’t had time to look into this.