diff --git a/docs/module/isis.md b/docs/module/isis.md index dff263291..d0ab59167 100644 --- a/docs/module/isis.md +++ b/docs/module/isis.md @@ -37,7 +37,7 @@ The following table describes per-platform support of individual IS-IS features: | Cisco Nexus OS | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | | FRR | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | Junos[^Junos] | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | -| Nokia SR Linux | ✅ | ✅ | ✅ | ✅ | ✅ [❗](caveats-srlinux) | ❌ | +| Nokia SR Linux | ✅ | ✅ | ✅ | ✅ | ✅ [❗](caveats-srlinux) | ✅ | | Nokia SR OS | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | | VyOS | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | diff --git a/netsim/ansible/templates/isis/srlinux.j2 b/netsim/ansible/templates/isis/srlinux.j2 index d37c1e202..c7898d039 100644 --- a/netsim/ansible/templates/isis/srlinux.j2 +++ b/netsim/ansible/templates/isis/srlinux.j2 @@ -1,64 +1,8 @@ {% import "templates/routing/_redistribute.srlinux.j2" as redistribute with context %} - +{% import "srlinux.macro.j2" as isis_config with context %} +{% if isis is defined %} updates: -{{ redistribute.config(vrf='default',proto='isis',p_data=isis,evpn_active=False,af=isis.af.keys()) }} -- path: /network-instance[name=default]/protocols/isis - value: - instance: - - name: {{ isis.instance }} - admin-state: enable - net: [ "{{ isis.net | default( "%s.0000.0000.%04d.00" % (isis.area,id) ) }}" ] - level-capability: "{{ 'L2' if isis.type=='level-2' else 'L1' if isis.type=='level-1' else 'L1L2' }}" -{% if isis.default|default(False) or isis.import|default(False) %} - export-policy: "default_export_isis" +{{ isis_config.config(isis,interfaces) }} +{% else %} +empty: {% endif %} -{% if isis.af.ipv6 is defined %} - ipv6-unicast: - admin-state: enable -{% if clab.type in ['ixr6','ixr10','ixr6e','ixr10e'] %} - multi-topology: {{ 'sr' not in module|default([]) }} - _annotate_multi-topology: "Not supported in combination with SR" -{% else %} - multi-topology: True -{% endif %} -{% endif %} -{% if ldp is defined and ldp.igp_sync|default(True) %} - ldp-synchronization: { } -{% endif %} - interface: - - interface-name: system0.0 - passive: True - ipv4-unicast: - admin-state: {{ 'enable' if 'ipv4' in loopback and 'ipv4' in isis.af else 'disable' }} - ipv6-unicast: - admin-state: {{ 'enable' if 'ipv6' in loopback and 'ipv6' in isis.af else 'disable' }} - -{% for l in interfaces if (l.vlan is not defined or l.vlan.mode|default('irb')!='bridge') and l.subif_index is not defined %} -{% set ifname = l.ifname if '.' in l.ifname else l.ifname|replace('vlan','irb0.') if l.type=='svi' else (l.ifname+'.0') %} -{% if "isis" not in l %} - # IS-IS not configured on external interface {{ ifname }} -{% else %} - - interface-name: {{ ifname }} - circuit-type: {{ l.isis.network_type|default("broadcast") }} - passive: {{ l.isis.passive }} - ipv4-unicast: - admin-state: {{ 'enable' if 'ipv4' in l and 'ipv4' in isis.af else 'disable' }} - enable-bfd: {{ l.isis.bfd.ipv4|default(False) }} -{% if 'ipv6' in l and 'ipv6' in isis.af %} - ipv6-unicast: - admin-state: enable - enable-bfd: {{ l.isis.bfd.ipv6|default(False) }} -{% endif %} -{% if l.isis.metric is defined or l.isis.cost is defined %} - level: -{% if isis.type!='level-2' %} - - level-number: 1 - metric: {{ l.isis.metric|default(l.isis.cost) }} -{% endif %} -{% if isis.type!='level-1' %} - - level-number: 2 - metric: {{ l.isis.metric|default(l.isis.cost) }} -{% endif %} -{% endif %} -{% endif %} -{% endfor %} diff --git a/netsim/ansible/templates/isis/srlinux.macro.j2 b/netsim/ansible/templates/isis/srlinux.macro.j2 new file mode 100644 index 000000000..c047843d1 --- /dev/null +++ b/netsim/ansible/templates/isis/srlinux.macro.j2 @@ -0,0 +1,67 @@ +{% import "templates/routing/_redistribute.srlinux.j2" as redistribute with context %} +{% macro config(isis,interfaces,vrf='default') %} +{{ redistribute.config(vrf=vrf,proto='isis',p_data=isis,evpn_active=False,af=isis.af.keys()) }} +- path: /network-instance[name={{ vrf }}]/protocols/isis + value: + instance: + - name: {{ isis.instance }} + admin-state: enable + net: [ "{{ isis.net | default( "%s.0000.0000.%04d.00" % (isis.area,id) ) }}" ] + level-capability: "{{ 'L2' if isis.type=='level-2' else 'L1' if isis.type=='level-1' else 'L1L2' }}" +{% if isis.default|default(False) or isis.import|default(False) %} + export-policy: "{{ vrf }}_export_isis" +{% endif %} +{% if isis.af.ipv6 is defined %} + ipv6-unicast: + admin-state: enable +{% if clab.type in ['ixr6','ixr10','ixr6e','ixr10e'] %} + multi-topology: {{ 'sr' not in module|default([]) }} + _annotate_multi-topology: "Not supported in combination with SR" +{% else %} + multi-topology: True +{% endif %} +{% endif %} +{% if ldp is defined and ldp.igp_sync|default(True) %} + ldp-synchronization: { } +{% endif %} +{% if vrf == 'default' or interfaces %} + interface: +{% endif %} +{% if vrf == 'default' %} + - interface-name: system0.0 + passive: True + ipv4-unicast: + admin-state: {{ 'enable' if 'ipv4' in loopback and 'ipv4' in isis.af else 'disable' }} + ipv6-unicast: + admin-state: {{ 'enable' if 'ipv6' in loopback and 'ipv6' in isis.af else 'disable' }} +{% endif %} +{% for l in interfaces if (l.vlan is not defined or l.vlan.mode|default('irb')!='bridge') and l.subif_index is not defined %} +{% set ifname = l.ifname if '.' in l.ifname else l.ifname|replace('vlan','irb0.') if l.type=='svi' else (l.ifname+'.0') %} +{% if "isis" not in l %} + # IS-IS not configured on external interface {{ ifname }} +{% else %} + - interface-name: {{ ifname }} + circuit-type: {{ l.isis.network_type|default("broadcast") }} + passive: {{ l.isis.passive }} + ipv4-unicast: + admin-state: {{ 'enable' if 'ipv4' in l and 'ipv4' in isis.af else 'disable' }} + enable-bfd: {{ l.isis.bfd.ipv4|default(False) }} +{% if 'ipv6' in l and 'ipv6' in isis.af %} + ipv6-unicast: + admin-state: enable + enable-bfd: {{ l.isis.bfd.ipv6|default(False) }} +{% endif %} +{% if l.isis.metric is defined or l.isis.cost is defined %} + level: +{% if isis.type!='level-2' %} + - level-number: 1 + metric: {{ l.isis.metric|default(l.isis.cost) }} +{% endif %} +{% if isis.type!='level-1' %} + - level-number: 2 + metric: {{ l.isis.metric|default(l.isis.cost) }} +{% endif %} +{% endif %} +{% endif %} +{% endfor %} +{% endmacro %} \ No newline at end of file diff --git a/netsim/ansible/templates/vrf/srlinux.j2 b/netsim/ansible/templates/vrf/srlinux.j2 index 0fa103e1e..30aa10f34 100644 --- a/netsim/ansible/templates/vrf/srlinux.j2 +++ b/netsim/ansible/templates/vrf/srlinux.j2 @@ -1,5 +1,6 @@ {% from "templates/ospf/srlinux.macro.j2" import ospf_config with context %} {% from "templates/bgp/srlinux.macro.j2" import bgp_config with context %} +{% from "templates/isis/srlinux.macro.j2" import config as isis_config with context %} updates: {% for vname,vdata in vrfs.items() %} @@ -15,7 +16,9 @@ updates: {% endif %} {% endfor %} {% endif %} - +{% if 'isis' in vdata %} +{{ isis_config(vdata.isis,vdata.isis.interfaces,vname) }} +{% endif %} {# Create an AS path set for this VRF, if vrf.as is set #} {% if vdata.as is defined %} - path: /routing-policy/as-path-set[name={{vname}}] diff --git a/netsim/devices/srlinux.yml b/netsim/devices/srlinux.yml index abbe01570..43ca4ce0f 100644 --- a/netsim/devices/srlinux.yml +++ b/netsim/devices/srlinux.yml @@ -80,6 +80,7 @@ features: ospfv2: True ospfv3: True bgp: True + isis: True vxlan: requires: [ evpn ] # vrf for l3 vxlan external: