Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions docs/module/vrf.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ VRFs are supported on these platforms:
| Cisco IOS | ✅ | ✅ | ✅ |
| Cisco IOS XE[^18v] | ✅ | ✅ | ✅ |
| Cisco Nexus OS | ✅ | ✅ | ✅ |
| Cumulus Linux | ✅ | ✅ | ✅ |
| Cumulus NVUE | ✅ | ❌ | |
| Cumulus Linux 4.x | ✅ | ✅ | ✅ |
| Cumulus 5.x (NVUE) | ✅ | ❌ | |
| Dell OS10 | ✅ | ✅ | ✅ |
| FRR [❗](caveats-frr) | ✅ | ✅ | ✅ |
| Junos[^Junos] | ✅ | ✅ | ✅ |
Expand All @@ -45,7 +45,8 @@ These platforms support routing protocols in VRFs:
| Cisco IOS/IOSvL2 | ✅ [❗](caveats-iosv) | ✅ | ✅ | ✅ | ✅ |
| Cisco IOS XE[^18v] | ✅ [❗](caveats-csr) | ✅ | ✅ | ✅ | ✅ |
| Cisco Nexus OS | ✅ | ❌ | ✅ |
| Cumulus Linux | ✅ | ❌ | ✅ | ✅ | ✅ |
| Cumulus Linux 4.x | ✅ | ❌ | ✅ | ✅ | ✅ |
| Cumulus 5.x (NVUE) | ✅ | ❌ | ❌ | ❌ | ❌ |
| Dell OS10 | ✅ | ❌ | ✅ |
| FRR [❗](caveats-frr) | ✅ | ✅ | ✅ | ✅ | ✅ |
| Junos[^Junos] | ✅ | ✅ | ✅ |
Expand Down
64 changes: 37 additions & 27 deletions netsim/ansible/templates/ospf/cumulus_nvue.j2
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,51 @@
router:
ospf:
enable: on

{% macro vrf_ospf(vrfname,vrf) %}
{% set _ospf = vrf.ospf %}
{% set _intfs = _ospf.interfaces|default([]) %}
{% if _intfs!=[] %}
- set:
vrf:
default:
{{ vrfname }}:
router:
ospf:
enable: on
{% if ospf.reference_bandwidth is defined %}
reference-bandwidth: {{ ospf.reference_bandwidth }}
{% endif %}
{% if 'router_id' in ospf %}
router-id: {{ ospf.router_id }}
{% endif %}
{% set node_area = ospf.area|default('0.0.0.0') %}
area:
{% for o_area in interfaces|json_query('[*].ospf.area')|union([node_area])|unique %}
'{{ o_area }}':
network:
{% if o_area == node_area and 'ipv4' in loopback %}
{{ loopback.ipv4 }}: {}
{% endif %}
{% for l in interfaces if 'ipv4' in l and l.ipv4 is string and l.ospf.area|default('') == o_area %}
{{ l.ipv4 }}: {}
{% endfor %}
{% endfor %}
{% for l in interfaces|default([]) if 'ospf' in l %}
{% if loop.first %}
redistribute:
connected:
enable: on
{% if _ospf.reference_bandwidth is defined %}
reference-bandwidth: {{ _ospf.reference_bandwidth }}
{% endif %}
{% if 'router_id' in _ospf %}
router-id: {{ _ospf.router_id }}
{% endif %}

{% for l in _intfs %}
{% if loop.first %}
interface:
{% endif %}
{% endif %}
{{ l.ifname }}:
router:
ospf:
{% if l.ospf.cost is defined %}
area: {{ l.ospf.area|default(ospf.area) }}
{% if l.ospf.cost is defined %}
cost: {{ l.ospf.cost }}
{% endif %}
{% endif %}
network-type: {{ l.ospf.network_type|default('broadcast') }}
{% if l.ospf.passive | default(False) %}
{% if l.ospf.passive | default(False) %}
passive: on
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}

{% else %}
# No OSPF interfaces in VRF {{ vrfname }}
{% endif %}
{% endmacro %}

{% if ospf is defined %}
{% set _lo = (loopback + { 'ospf': { 'area': ospf.area|default('0.0.0.0') } }) if 'ipv4' in loopback else {} %}
{% set _ospf_intfs = [_lo] + interfaces|default([])|selectattr('ospf','defined')|list %}
{{ vrf_ospf("default", { 'ospf': ospf + { 'interfaces': _ospf_intfs } } ) }}
{% endif %}
8 changes: 8 additions & 0 deletions netsim/ansible/templates/vrf/cumulus_nvue.j2
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
{% from "ospf/cumulus_nvue.j2" import vrf_ospf with context %}

- set:
vrf:
{% for vname,vdata in vrfs.items() %}
{{ vname }}:
table: auto
{% endfor %}

{% for vname,vdata in vrfs.items() if 'ospf' in vdata %}
{% if vdata.af.ipv4|default(False) %}
{{ vrf_ospf(vname,vdata) }}
{% endif %}
{% endfor %}
15 changes: 15 additions & 0 deletions netsim/devices/cumulus_nvue.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,18 @@ def nvue_check_stp_features(node: Box, topology: Box) -> None:
more_data=err_data,
node=node)

"""
Checks for vrf route leaking usage which is not yet implemented
"""
def nvue_check_vrf_route_leaking(node: Box) -> None:
for vname,vdata in node.get("vrfs",{}).items():
if len(vdata.get('export',[]))>1 or len(vdata.get('import',[]))>1:
log.error(f"Topology uses vrf route leaking which Netlab does not implement (yet) for Cumulus NVUE node '{node.name}'",
category=log.FatalError,
module='vrf',
hint='route leaking')
return

class Cumulus_Nvue(_Quirks):

@classmethod
Expand All @@ -49,3 +61,6 @@ def device_quirks(self, node: Box, topology: Box) -> None:
# NVUE specific quirks
if 'stp' in mods:
nvue_check_stp_features(node,topology)

if 'vrf' in mods:
nvue_check_vrf_route_leaking(node)
3 changes: 2 additions & 1 deletion netsim/devices/cumulus_nvue.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ features:
model: switch
svi_interface_name: "vlan{vlan}"
subif_name: "{ifname}.{vlan.access_id}"
vrf: True
vrf:
ospfv2: True
clab:
kmods:
initial: [ ebtables ]
Expand Down
Loading