From b8754b1fc7188247876909c370be646e777087dd Mon Sep 17 00:00:00 2001 From: Jeroen van Bemmel Date: Sat, 14 Dec 2024 12:31:32 -0600 Subject: [PATCH 1/8] Rename interface.type to interface._type internally, to avoid validation issues --- netsim/augment/links.py | 6 +++--- netsim/modules/_routing.py | 4 ++-- netsim/modules/lag.py | 4 ++-- netsim/modules/vlan.py | 10 +++++----- netsim/modules/vrf.py | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/netsim/augment/links.py b/netsim/augment/links.py index ed9646501e..29f380dd30 100644 --- a/netsim/augment/links.py +++ b/netsim/augment/links.py @@ -266,7 +266,7 @@ def create_regular_interface(node: Box, ifdata: Box, defaults: Box) -> None: ifdata[provider] = pdata def create_virtual_interface(node: Box, ifdata: Box, defaults: Box) -> None: - devtype = ifdata.get('type','loopback') # Get virtual interface type, default to loopback interface + devtype = ifdata.get('_type','loopback') # Get virtual interface type, default to loopback interface ifindex_offset = ( devices.get_device_attribute(node,f'{devtype}_offset',defaults) or 1 if devtype == 'loopback' else 0) # Loopback interfaces have to start with 1 to prevent overlap with built-in loopback @@ -308,7 +308,7 @@ def create_virtual_interface(node: Box, ifdata: Box, defaults: Box) -> None: module='links') def add_node_interface(node: Box, ifdata: Box, defaults: Box) -> Box: - if ifdata.get('type',None) in VIRTUAL_INTERFACE_TYPES: + if ifdata.get('_type',None) in VIRTUAL_INTERFACE_TYPES: create_virtual_interface(node,ifdata,defaults) else: create_regular_interface(node,ifdata,defaults) @@ -326,7 +326,7 @@ def add_node_interface(node: Box, ifdata: Box, defaults: Box) -> Box: if not sys_mtu: # .. does the device support system MTU? ifdata.mtu = node.mtu # .... no, copy node MTU to interface MTU - if ifdata.get('type',None) == 'loopback': + if ifdata.get('_type',None) == 'loopback': ifdata.pop('mtu',None) # Remove MTU from loopback interfaces node.interfaces.append(ifdata) diff --git a/netsim/modules/_routing.py b/netsim/modules/_routing.py index 26587ab8dc..b616055190 100644 --- a/netsim/modules/_routing.py +++ b/netsim/modules/_routing.py @@ -151,11 +151,11 @@ def passive( return role = intf.get('role',"") - if role in ["passive","external"] or intf.type == 'stub': # Passive/external role or stub link ==> must be passive + if role in ["passive","external"] or intf._type == 'stub': # Passive/external role or stub link ==> must be passive intf[proto].passive = True return - if role != "stub": # Not a stub role ==> not passive + if role != "stub": # Not a stub role ==> not passive intf[proto].passive = False return diff --git a/netsim/modules/lag.py b/netsim/modules/lag.py index 73f8e033e8..6a18a5772a 100644 --- a/netsim/modules/lag.py +++ b/netsim/modules/lag.py @@ -209,7 +209,7 @@ def analyze_lag(members: list, node_count: dict) -> tuple[bool,bool,str]: l.interfaces = [] # Build interface list for lag link skip_atts = list(topology.defaults.lag.attributes.lag_no_propagate) for node in node_count: - ifatts = data.get_box({ 'node': node }) + ifatts = data.get_box({ 'node': node, '_type': 'lag' }) for m in members: # Collect attributes from member links if node in [ i.node for i in m.interfaces ]:# ...in which is involved ifatts = ifatts + { k:v for k,v in m.items() if k not in skip_atts } @@ -385,7 +385,7 @@ def node_post_transform(self, node: Box, topology: Box) -> None: if i.get(PEERLINK_ID_ATT,None): # Fill in peer loopback IP and vMAC for MLAG peer links populate_mlag_peer(node,i,topology) has_peerlink = True - elif i.type=='lag': + elif i._type=='lag': i.lag = node.get('lag',{}) + i.lag # Merge node level settings with interface overrides lacp_mode = i.get('lag.lacp_mode') # Inheritance copying is done elsewhere if lacp_mode=='passive' and not features.lag.get('passive',False): diff --git a/netsim/modules/vlan.py b/netsim/modules/vlan.py index 650606c566..a3ac5c7bf7 100644 --- a/netsim/modules/vlan.py +++ b/netsim/modules/vlan.py @@ -800,7 +800,7 @@ def create_svi_interfaces(node: Box, topology: Box) -> dict: continue # ... good, move on routed_intf = get_vlan_interface_mode(ifdata) == 'route' # Identify routed VLAN interfaces - vlan_subif = routed_intf and ifdata.get('type','') == 'vlan_member' # ... and VLAN-based subinterfaces + vlan_subif = routed_intf and ifdata.get('_type','') == 'vlan_member' # ... and VLAN-based subinterfaces vlan_data = create_node_vlan(node,access_vlan,topology) if vlan_data is None: # pragma: no-cover @@ -856,7 +856,7 @@ def create_svi_interfaces(node: Box, topology: Box) -> dict: ifname=ifdata.ifname) vlan_ifdata.name = f'VLAN {access_vlan} ({vlan_data.id})' vlan_ifdata.virtual_interface = True # Mark interface as virtual - vlan_ifdata.type = "svi" + vlan_ifdata._type = "svi" vlan_ifdata.neighbors = [] # No neighbors so far # Overwrite interface settings with VLAN settings vlan_ifdata = vlan_ifdata + { @@ -976,12 +976,12 @@ def rename_vlan_subinterfaces(node: Box, topology: Box) -> None: features = devices.get_device_features(node,topology.defaults) if 'switch' in features.vlan.model: # No need for VLAN subinterfaces, remove non-routed vlan_member interfaces node.interfaces = [ intf for intf in node.interfaces \ - if intf.type != 'vlan_member' or intf.vlan.get('mode','') == 'route' ] + if intf._type != 'vlan_member' or intf.vlan.get('mode','') == 'route' ] subif_name = features.vlan.routed_subif_name # Just in case: try to get interface name pattern for routed subinterface has_vlan_loopbacks = False for intf in node.interfaces: # Now loop over remaining vlan_member interfaces - if intf.type != 'vlan_member': + if intf._type != 'vlan_member': continue if not 'router' in features.vlan.model and not 'l3-switch' in features.vlan.model: @@ -1086,7 +1086,7 @@ def check_mixed_trunks(node: Box, topology: Box) -> None: err_ifmap = {} for intf in node.interfaces: - if not intf.get('parent_ifindex') or intf.type != 'vlan_member': # Skip everything that is not a VLAN subinterface + if not intf.get('parent_ifindex') or intf._type != 'vlan_member': # Skip everything that is not a VLAN subinterface continue parent_intf_list = [ x for x in node.interfaces if x.ifindex == intf.parent_ifindex ] diff --git a/netsim/modules/vrf.py b/netsim/modules/vrf.py index 79e7ed0e65..af521576f8 100644 --- a/netsim/modules/vrf.py +++ b/netsim/modules/vrf.py @@ -374,7 +374,7 @@ def vrf_loopbacks(node : Box, topology: Box) -> None: """ def get_vrf_loopback(node: Box, vrf: str) -> typing.Optional[Box]: for intf in node.interfaces: # Loop over all interfaces - if intf.type != 'loopback': # Not a loopback interface? Move on... + if intf._type != 'loopback': # Not a loopback interface? Move on... continue if intf.get('vrf',None) != vrf: # Not in the correct VRF? Move on continue From 2de39c59385af9fe3f6425ef45899bf1864d25f4 Mon Sep 17 00:00:00 2001 From: Jeroen van Bemmel Date: Sat, 14 Dec 2024 13:13:21 -0600 Subject: [PATCH 2/8] More renaming --- netsim/augment/links.py | 4 +++- netsim/augment/nodes.py | 2 ++ netsim/defaults/attributes.yml | 1 + netsim/devices/dellos10.py | 4 ++-- netsim/devices/eos.py | 2 +- netsim/devices/iosv.py | 2 +- netsim/devices/junos.py | 2 +- netsim/modules/lag.py | 8 ++++---- netsim/modules/lag.yml | 2 +- netsim/modules/vlan.py | 2 +- netsim/modules/vlan.yml | 4 ++-- netsim/modules/vrf.py | 2 +- netsim/modules/vxlan.py | 2 +- 13 files changed, 21 insertions(+), 16 deletions(-) diff --git a/netsim/augment/links.py b/netsim/augment/links.py index 29f380dd30..e90516cae0 100644 --- a/netsim/augment/links.py +++ b/netsim/augment/links.py @@ -209,7 +209,7 @@ def get_unique_ifindex( idx_list = [ # Build a list of already-used ifindex values intf.ifindex for intf in node.interfaces - if iftype == intf.type or (iftype is None and intf.type not in VIRTUAL_INTERFACE_TYPES) ] + if iftype == intf._type or (iftype is None and intf._type not in VIRTUAL_INTERFACE_TYPES) ] ifindex = start while ifindex < stop: # Iterate through ifindex values if ifindex not in idx_list: # ... returning the first one that is not used @@ -776,6 +776,8 @@ def create_node_interfaces(link: Box, addr_pools: Box, ndict: Box, defaults: Box set_interface_name(ifdata,link,intf_cnt) set_parent_interface(ifdata,ndict[node]) ifdata.pop('node',None) # Remove the node name (not needed within the node) + if 'type' in ifdata: + ifdata._type = ifdata.pop('type',None) # rename 'type' to '_type' node_intf = add_node_interface(ndict[node],ifdata,defaults) # Attach new interface to its node value.ifindex = node_intf.ifindex # Save ifindex and ifname in link interface data value.ifname = node_intf.ifname # ... needed for things like Graph output module that works with links diff --git a/netsim/augment/nodes.py b/netsim/augment/nodes.py index b0c61df99a..ac98bd670a 100644 --- a/netsim/augment/nodes.py +++ b/netsim/augment/nodes.py @@ -444,6 +444,8 @@ def check_unique_ifnames(n: Box) -> None: else: ifnames[intf.ifname] = intf + intf.type = intf.pop('_type',None) # Rename '_type' attribute for backwards compatibility + ''' Final cleanup of node data ''' diff --git a/netsim/defaults/attributes.yml b/netsim/defaults/attributes.yml index ff247320c7..88c178448c 100644 --- a/netsim/defaults/attributes.yml +++ b/netsim/defaults/attributes.yml @@ -69,6 +69,7 @@ link: # Global link attributes link_internal: # Internal link attributes linkindex: int parentindex: int + link_no_propagate: [ prefix, interfaces, gateway ] # Do not propagate VLAN attributes to node interfaces -- see #575 # Also: do not propagate DHCP attributes from links to interfaces diff --git a/netsim/devices/dellos10.py b/netsim/devices/dellos10.py index 5887b8dc94..8ceec00c5d 100644 --- a/netsim/devices/dellos10.py +++ b/netsim/devices/dellos10.py @@ -11,7 +11,7 @@ def check_vlan_ospf(node: Box, iflist: BoxList, vname: str) -> None: name = node.name err_data = [] for intf in iflist: - if 'ospf' not in intf or intf.type != 'svi': + if 'ospf' not in intf or intf._type != 'svi': continue err_data.append(f'Interface {intf.ifname} VRF {vname}') @@ -34,7 +34,7 @@ def check_vlan_ospf(node: Box, iflist: BoxList, vname: str) -> None: def check_anycast_gateways(node: Box) -> None: err_data = [] for intf in node.get('interfaces',[]): - if intf.type != 'svi' and intf.get('gateway.anycast',None): + if intf._type != 'svi' and intf.get('gateway.anycast',None): err_data.append(f'Interface {intf.ifname}') if err_data: diff --git a/netsim/devices/eos.py b/netsim/devices/eos.py index 417b7d706c..ddaa6abde1 100644 --- a/netsim/devices/eos.py +++ b/netsim/devices/eos.py @@ -68,7 +68,7 @@ def check_dhcp_clients(node: Box, topology: Box) -> None: def check_l3_lag(node: Box, topology: Box) -> None: for intf in node.interfaces: - if intf.type != 'lag': + if intf._type != 'lag': continue if intf.get('ipv4',False) is not False or intf.get('ipv6',False) is not False: log.error( diff --git a/netsim/devices/iosv.py b/netsim/devices/iosv.py index 6239916da4..2a0aa73c27 100644 --- a/netsim/devices/iosv.py +++ b/netsim/devices/iosv.py @@ -14,7 +14,7 @@ def check_vrrp_bvi(node: Box, topology: Box) -> None: if intf.get('gateway.protocol',None) != 'vrrp': # No VRRP, move on continue - if intf.get('type',None) != 'svi': # Not a BVI interface, move on + if intf.get('_type',None) != 'svi': # Not a BVI interface, move on continue log.error( diff --git a/netsim/devices/junos.py b/netsim/devices/junos.py index 9fe63abc48..e6a6eff7d0 100644 --- a/netsim/devices/junos.py +++ b/netsim/devices/junos.py @@ -61,7 +61,7 @@ def check_multiple_loopbacks(node: Box, topology: Box) -> None: vrf_count['default'] = 1 for intf in node.interfaces: - if intf.get('type','') != 'loopback': + if intf.get('_type','') != 'loopback': continue vrf = intf.get('vrf','default') diff --git a/netsim/modules/lag.py b/netsim/modules/lag.py index 6a18a5772a..5185a8033c 100644 --- a/netsim/modules/lag.py +++ b/netsim/modules/lag.py @@ -38,11 +38,11 @@ def populate_peerlink_id_set(topology: Box) -> None: create_l2_link_base - Create a L2 P2P link as base for member links """ def create_l2_link_base(l: Box, topology: Box) -> Box: - l2_ifdata = data.get_box({ 'type': "p2p", 'prefix': False, 'lag': {} }) # Construct an L2 member link - for a in list(topology.defaults.lag.attributes.lag_l2_ifattr): + l2_linkdata = data.get_box({ 'type': "p2p", 'prefix': False, 'lag': {} }) # Construct an L2 member link + for a in list(topology.defaults.lag.attributes.lag_l2_linkattr): if a in l: - l2_ifdata[a] = l[a] - return l2_ifdata + l2_linkdata[a] = l[a] + return l2_linkdata """ check_lag_config - check if the given node supports lag and has the module enabled diff --git a/netsim/modules/lag.yml b/netsim/modules/lag.yml index e6f2955444..a05da58524 100644 --- a/netsim/modules/lag.yml +++ b/netsim/modules/lag.yml @@ -36,7 +36,7 @@ attributes: # _mlag: bool # Copy only these L2 attributes into LAG physical link members - lag_l2_ifattr: + lag_l2_linkattr: mtu: bandwidth: diff --git a/netsim/modules/vlan.py b/netsim/modules/vlan.py index a3ac5c7bf7..96e567a3bb 100644 --- a/netsim/modules/vlan.py +++ b/netsim/modules/vlan.py @@ -1131,7 +1131,7 @@ def check_mixed_native_trunk(node: Box, topology: Box) -> None: f'Device type {node.device} (node {node.name}) cannot have a routed native VLAN with a bridged trunk', category=log.IncorrectValue, module='vlan', - more_data=f'Found on interface {intf.ifname} ({intf.name})') + more_data=f'Found on interface {intf.ifname} ({intf.name}) ({intf})') """ fix_vlan_gateways -- set VLAN-wide gateway IP diff --git a/netsim/modules/vlan.yml b/netsim/modules/vlan.yml index 7608a8bea1..b8c67fb943 100644 --- a/netsim/modules/vlan.yml +++ b/netsim/modules/vlan.yml @@ -50,7 +50,7 @@ attributes: parentindex: ifname: linkindex: - type: + _type: vlan: mtu: bandwidth: @@ -65,7 +65,7 @@ attributes: vlan: ifindex: ifname: - type: + _type: virtual_interface: features: diff --git a/netsim/modules/vrf.py b/netsim/modules/vrf.py index af521576f8..b3d9ccdc7f 100644 --- a/netsim/modules/vrf.py +++ b/netsim/modules/vrf.py @@ -323,7 +323,7 @@ def vrf_loopbacks(node : Box, topology: Box) -> None: # Note: set interface ifindex to v.vrfidx if you want to have VRF-numbered loopbacks # ifdata = data.get_box({ # Create interface data structure - 'type': "loopback", + '_type': "loopback", 'name': f'VRF Loopback {vrfname}', 'neighbors': [], 'vrf': vrfname,}) diff --git a/netsim/modules/vxlan.py b/netsim/modules/vxlan.py index 1aef265a5b..0c94e9bc23 100644 --- a/netsim/modules/vxlan.py +++ b/netsim/modules/vxlan.py @@ -102,7 +102,7 @@ def node_set_vtep(node: Box, topology: Box) -> bool: # Search for additional loopback interfaces with vxlan.vtep' flag, and use the first one for intf in node.interfaces: - if intf.get('type', '') == 'loopback' and 'vxlan' in intf and intf.vxlan.get('vtep', False): + if intf.get('_type', '') == 'loopback' and 'vxlan' in intf and intf.vxlan.get('vtep', False): vtep_interface = intf loopback_name = intf.ifname break From fe9c836a65cf636713d3585c636d64aacfb597a9 Mon Sep 17 00:00:00 2001 From: Jeroen van Bemmel Date: Sat, 14 Dec 2024 13:15:45 -0600 Subject: [PATCH 3/8] Fix bgp type check --- netsim/modules/bgp.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netsim/modules/bgp.py b/netsim/modules/bgp.py index 32cf147e3d..059dac5326 100644 --- a/netsim/modules/bgp.py +++ b/netsim/modules/bgp.py @@ -467,7 +467,7 @@ def bgp_set_advertise(node: Box, topology: Box) -> None: continue role = l.get("role",None) # Get interface/link role - if l.get("type",None) in stub_roles or role in stub_roles: + if l.get("_type",None) in stub_roles or role in stub_roles: # We have a potential stub link according to advertised_roles, but we still have to check for true stub # if role != "stub": @@ -476,7 +476,7 @@ def bgp_set_advertise(node: Box, topology: Box) -> None: l.bgp.advertise = _routing.is_true_stub(l,topology) continue # And move on - if l.get('type',None) == 'loopback' and node.bgp.advertise_loopback: + if l.get('_type',None) == 'loopback' and node.bgp.advertise_loopback: l.bgp.advertise = True # ... also advertise loopback prefixes if bgp.advertise_loopback is set """ From c152c8dd9f34dc70643c7b09e038aed05265000a Mon Sep 17 00:00:00 2001 From: Jeroen van Bemmel Date: Sat, 14 Dec 2024 14:21:31 -0600 Subject: [PATCH 4/8] cleanup() runs before devices get involved -> _type is already back to type --- netsim/augment/links.py | 14 ++++++-------- netsim/augment/nodes.py | 8 ++++++-- netsim/data/__init__.py | 8 ++++++++ netsim/devices/dellos10.py | 4 ++-- netsim/devices/eos.py | 2 +- netsim/devices/iosv.py | 2 +- netsim/devices/junos.py | 2 +- 7 files changed, 25 insertions(+), 15 deletions(-) diff --git a/netsim/augment/links.py b/netsim/augment/links.py index e90516cae0..15fa0d9f16 100644 --- a/netsim/augment/links.py +++ b/netsim/augment/links.py @@ -209,7 +209,7 @@ def get_unique_ifindex( idx_list = [ # Build a list of already-used ifindex values intf.ifindex for intf in node.interfaces - if iftype == intf._type or (iftype is None and intf._type not in VIRTUAL_INTERFACE_TYPES) ] + if iftype == intf.get('_type',None) or (iftype is None and intf.get('_type',None) not in VIRTUAL_INTERFACE_TYPES) ] ifindex = start while ifindex < stop: # Iterate through ifindex values if ifindex not in idx_list: # ... returning the first one that is not used @@ -776,9 +776,9 @@ def create_node_interfaces(link: Box, addr_pools: Box, ndict: Box, defaults: Box set_interface_name(ifdata,link,intf_cnt) set_parent_interface(ifdata,ndict[node]) ifdata.pop('node',None) # Remove the node name (not needed within the node) - if 'type' in ifdata: - ifdata._type = ifdata.pop('type',None) # rename 'type' to '_type' node_intf = add_node_interface(ndict[node],ifdata,defaults) # Attach new interface to its node + if 'type' in node_intf: + node_intf._type = node_intf.pop('type',None) # rename 'type' (from link) to '_type' value.ifindex = node_intf.ifindex # Save ifindex and ifname in link interface data value.ifname = node_intf.ifname # ... needed for things like Graph output module that works with links interfaces.append({ 'node': node, 'data': node_intf }) # Save newly-created interface for the next step @@ -1185,8 +1185,6 @@ def transform(link_list: typing.Optional[Box], defaults: Box, nodes: Box, pools: return link_list def cleanup(topology: Box) -> None: - if not 'links' in topology: - return - -# for link in topology.links: -# link.pop('_linkname',None) + for link in topology.get('links',[]): + # link.pop('_linkname',None) + data.cleanup_interface_type(link) diff --git a/netsim/augment/nodes.py b/netsim/augment/nodes.py index ac98bd670a..0ff0c94ed0 100644 --- a/netsim/augment/nodes.py +++ b/netsim/augment/nodes.py @@ -444,8 +444,6 @@ def check_unique_ifnames(n: Box) -> None: else: ifnames[intf.ifname] = intf - intf.type = intf.pop('_type',None) # Rename '_type' attribute for backwards compatibility - ''' Final cleanup of node data ''' @@ -462,6 +460,12 @@ def cleanup(topology: Box) -> None: n.config = [ cfg for cfg in n.config if cfg in plugin_config ] + \ [ cfg for cfg in n.config if cfg not in plugin_config ] + data.cleanup_interface_type(n) + if 'vrfs' in n: + for vname,vdata in n.vrfs.items(): + if vdata.get('ospf.interfaces',[]): + data.cleanup_interface_type(vdata.ospf) + topology.pop('_plugin_config',None) ''' diff --git a/netsim/data/__init__.py b/netsim/data/__init__.py index 26b1a5c145..cd48fa3f22 100644 --- a/netsim/data/__init__.py +++ b/netsim/data/__init__.py @@ -181,3 +181,11 @@ def kw_list_transform(lookup_table: typing.Union[dict,Box], kw_list: list) -> li xf_list.append(lookup_kw) return xf_list + +""" +cleanup_interface_type - rename '_type' back to 'type' for all interfaces in the given obj +""" +def cleanup_interface_type(obj: Box) -> None: + for intf in obj.get('interfaces',[]): + if '_type' in intf: + intf.type = intf.pop('_type',None) diff --git a/netsim/devices/dellos10.py b/netsim/devices/dellos10.py index 8ceec00c5d..5887b8dc94 100644 --- a/netsim/devices/dellos10.py +++ b/netsim/devices/dellos10.py @@ -11,7 +11,7 @@ def check_vlan_ospf(node: Box, iflist: BoxList, vname: str) -> None: name = node.name err_data = [] for intf in iflist: - if 'ospf' not in intf or intf._type != 'svi': + if 'ospf' not in intf or intf.type != 'svi': continue err_data.append(f'Interface {intf.ifname} VRF {vname}') @@ -34,7 +34,7 @@ def check_vlan_ospf(node: Box, iflist: BoxList, vname: str) -> None: def check_anycast_gateways(node: Box) -> None: err_data = [] for intf in node.get('interfaces',[]): - if intf._type != 'svi' and intf.get('gateway.anycast',None): + if intf.type != 'svi' and intf.get('gateway.anycast',None): err_data.append(f'Interface {intf.ifname}') if err_data: diff --git a/netsim/devices/eos.py b/netsim/devices/eos.py index ddaa6abde1..417b7d706c 100644 --- a/netsim/devices/eos.py +++ b/netsim/devices/eos.py @@ -68,7 +68,7 @@ def check_dhcp_clients(node: Box, topology: Box) -> None: def check_l3_lag(node: Box, topology: Box) -> None: for intf in node.interfaces: - if intf._type != 'lag': + if intf.type != 'lag': continue if intf.get('ipv4',False) is not False or intf.get('ipv6',False) is not False: log.error( diff --git a/netsim/devices/iosv.py b/netsim/devices/iosv.py index 2a0aa73c27..6239916da4 100644 --- a/netsim/devices/iosv.py +++ b/netsim/devices/iosv.py @@ -14,7 +14,7 @@ def check_vrrp_bvi(node: Box, topology: Box) -> None: if intf.get('gateway.protocol',None) != 'vrrp': # No VRRP, move on continue - if intf.get('_type',None) != 'svi': # Not a BVI interface, move on + if intf.get('type',None) != 'svi': # Not a BVI interface, move on continue log.error( diff --git a/netsim/devices/junos.py b/netsim/devices/junos.py index e6a6eff7d0..9fe63abc48 100644 --- a/netsim/devices/junos.py +++ b/netsim/devices/junos.py @@ -61,7 +61,7 @@ def check_multiple_loopbacks(node: Box, topology: Box) -> None: vrf_count['default'] = 1 for intf in node.interfaces: - if intf.get('_type','') != 'loopback': + if intf.get('type','') != 'loopback': continue vrf = intf.get('vrf','default') From ce55a39142125aa1399947956429392104c57e22 Mon Sep 17 00:00:00 2001 From: Jeroen van Bemmel Date: Sat, 14 Dec 2024 14:35:49 -0600 Subject: [PATCH 5/8] Change type before method --- netsim/augment/links.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netsim/augment/links.py b/netsim/augment/links.py index 15fa0d9f16..fbad85ae76 100644 --- a/netsim/augment/links.py +++ b/netsim/augment/links.py @@ -776,9 +776,9 @@ def create_node_interfaces(link: Box, addr_pools: Box, ndict: Box, defaults: Box set_interface_name(ifdata,link,intf_cnt) set_parent_interface(ifdata,ndict[node]) ifdata.pop('node',None) # Remove the node name (not needed within the node) + if 'type' in ifdata: + ifdata._type = ifdata.pop('type',None) # rename 'type' (from link) to '_type' node_intf = add_node_interface(ndict[node],ifdata,defaults) # Attach new interface to its node - if 'type' in node_intf: - node_intf._type = node_intf.pop('type',None) # rename 'type' (from link) to '_type' value.ifindex = node_intf.ifindex # Save ifindex and ifname in link interface data value.ifname = node_intf.ifname # ... needed for things like Graph output module that works with links interfaces.append({ 'node': node, 'data': node_intf }) # Save newly-created interface for the next step From e7af675c2c9719b39a6bfab764a1145f1f437734 Mon Sep 17 00:00:00 2001 From: Jeroen van Bemmel Date: Sat, 14 Dec 2024 14:42:50 -0600 Subject: [PATCH 6/8] Also fix ISIS interfaces --- netsim/augment/nodes.py | 5 +++-- tests/topology/expected/lag-l2.yml | 2 ++ tests/topology/expected/lag-l3-access-vlan.yml | 2 ++ tests/topology/expected/lag-l3-vlan-trunk.yml | 2 ++ tests/topology/expected/lag-l3.yml | 2 ++ tests/topology/expected/lag-mlag-m_to_m.yml | 4 ++++ tests/topology/expected/lag-mlag.yml | 11 +++++++++++ tests/topology/expected/node.clone-plugin-lag.yml | 14 ++++++++++++++ 8 files changed, 40 insertions(+), 2 deletions(-) diff --git a/netsim/augment/nodes.py b/netsim/augment/nodes.py index 0ff0c94ed0..848647c1ee 100644 --- a/netsim/augment/nodes.py +++ b/netsim/augment/nodes.py @@ -463,8 +463,9 @@ def cleanup(topology: Box) -> None: data.cleanup_interface_type(n) if 'vrfs' in n: for vname,vdata in n.vrfs.items(): - if vdata.get('ospf.interfaces',[]): - data.cleanup_interface_type(vdata.ospf) + for igp in ['ospf','isis']: + if vdata.get(f'{igp}.interfaces',[]): + data.cleanup_interface_type(vdata[igp]) topology.pop('_plugin_config',None) diff --git a/tests/topology/expected/lag-l2.yml b/tests/topology/expected/lag-l2.yml index 0499a8fa2a..e92e3b571a 100644 --- a/tests/topology/expected/lag-l2.yml +++ b/tests/topology/expected/lag-l2.yml @@ -14,11 +14,13 @@ links: lag: ifindex: 1 node: r1 + type: lag - ifindex: 30000 ifname: port-channel1 lag: ifindex: 1 node: r2 + type: lag lag: {} linkindex: 1 mtu: 1600 diff --git a/tests/topology/expected/lag-l3-access-vlan.yml b/tests/topology/expected/lag-l3-access-vlan.yml index 3e2d8927ac..334a1c333c 100644 --- a/tests/topology/expected/lag-l3-access-vlan.yml +++ b/tests/topology/expected/lag-l3-access-vlan.yml @@ -16,6 +16,7 @@ links: lag: ifindex: 1 node: r1 + type: lag vlan: access: v1 - _vlan_mode: irb @@ -25,6 +26,7 @@ links: lag: ifindex: 1 node: r2 + type: lag vlan: access: v1 lag: diff --git a/tests/topology/expected/lag-l3-vlan-trunk.yml b/tests/topology/expected/lag-l3-vlan-trunk.yml index f85f9de2ed..3d71d434ed 100644 --- a/tests/topology/expected/lag-l3-vlan-trunk.yml +++ b/tests/topology/expected/lag-l3-vlan-trunk.yml @@ -14,6 +14,7 @@ links: lag: ifindex: 1 node: r1 + type: lag vlan: trunk: v1: {} @@ -23,6 +24,7 @@ links: lag: ifindex: 1 node: r2 + type: lag vlan: trunk: v1: {} diff --git a/tests/topology/expected/lag-l3.yml b/tests/topology/expected/lag-l3.yml index 22342110cf..edfd1db769 100644 --- a/tests/topology/expected/lag-l3.yml +++ b/tests/topology/expected/lag-l3.yml @@ -15,12 +15,14 @@ links: lag: ifindex: 1 node: r1 + type: lag - ifindex: 30000 ifname: port-channel1 ipv4: 10.1.0.2/30 lag: ifindex: 1 node: r2 + type: lag lag: {} linkindex: 1 node_count: 2 diff --git a/tests/topology/expected/lag-mlag-m_to_m.yml b/tests/topology/expected/lag-mlag-m_to_m.yml index cbd4a94997..7c22af418a 100644 --- a/tests/topology/expected/lag-mlag-m_to_m.yml +++ b/tests/topology/expected/lag-mlag-m_to_m.yml @@ -60,6 +60,7 @@ links: lag: _mlag: true node: a2 + type: lag vlan: trunk: red: {} @@ -68,6 +69,7 @@ links: lag: _mlag: true node: b2 + type: lag vlan: trunk: red: {} @@ -88,6 +90,7 @@ links: lag: _mlag: true node: a1 + type: lag vlan: trunk: red: {} @@ -96,6 +99,7 @@ links: lag: _mlag: true node: b1 + type: lag vlan: trunk: red: {} diff --git a/tests/topology/expected/lag-mlag.yml b/tests/topology/expected/lag-mlag.yml index 3ae998882b..547d94c668 100644 --- a/tests/topology/expected/lag-mlag.yml +++ b/tests/topology/expected/lag-mlag.yml @@ -42,6 +42,7 @@ links: lag: ifindex: 1 node: h1 + type: lag vlan: access: red - _vlan_mode: irb @@ -51,6 +52,7 @@ links: lag: _mlag: true node: s1 + type: lag vlan: access: red - _vlan_mode: irb @@ -60,6 +62,7 @@ links: lag: _mlag: true node: s2 + type: lag vlan: access: red lag: @@ -80,11 +83,13 @@ links: lag: ifindex: 2 node: h1 + type: lag - ifindex: 30001 ifname: port-channel2 lag: ifindex: 2 node: s1 + type: lag lag: {} linkindex: 3 node_count: 2 @@ -100,6 +105,7 @@ links: lag: ifindex: 1 node: h2 + type: lag vlan: access: red - _vlan_mode: irb @@ -109,6 +115,7 @@ links: lag: _mlag: true node: s1 + type: lag vlan: access: red - _vlan_mode: irb @@ -118,6 +125,7 @@ links: lag: _mlag: true node: s2 + type: lag vlan: access: red lag: @@ -140,6 +148,7 @@ links: lag: ifindex: 2 node: h2 + type: lag vlan: access: red - _vlan_mode: irb @@ -149,6 +158,7 @@ links: lag: _mlag: true node: s1 + type: lag vlan: access: red - _vlan_mode: irb @@ -158,6 +168,7 @@ links: lag: _mlag: true node: s2 + type: lag vlan: access: red lag: diff --git a/tests/topology/expected/node.clone-plugin-lag.yml b/tests/topology/expected/node.clone-plugin-lag.yml index e71c82dc35..8a6882b67a 100644 --- a/tests/topology/expected/node.clone-plugin-lag.yml +++ b/tests/topology/expected/node.clone-plugin-lag.yml @@ -36,9 +36,11 @@ links: - ifindex: 30000 ifname: port-channel8 node: r1 + type: lag - ifindex: 30000 ifname: bond8 node: h-01 + type: lag lag: ifindex: 8 linkindex: 2 @@ -51,9 +53,11 @@ links: - ifindex: 30001 ifname: port-channel9 node: r1 + type: lag - ifindex: 30000 ifname: bond9 node: h-02 + type: lag lag: ifindex: 9 linkindex: 3 @@ -68,11 +72,13 @@ links: lag: ifindex: 1 node: r2 + type: lag - ifindex: 30001 ifname: bond9 lag: ifindex: 9 node: h-01 + type: lag lag: {} linkindex: 4 node_count: 2 @@ -86,11 +92,13 @@ links: lag: ifindex: 2 node: r2 + type: lag - ifindex: 30001 ifname: bond10 lag: ifindex: 10 node: h-02 + type: lag lag: {} linkindex: 5 node_count: 2 @@ -106,6 +114,7 @@ links: lag: ifindex: 1 node: h2-01 + type: lag vlan: access: red - _vlan_mode: irb @@ -115,6 +124,7 @@ links: lag: _mlag: true node: r1 + type: lag vlan: access: red - _vlan_mode: irb @@ -124,6 +134,7 @@ links: lag: _mlag: true node: r2 + type: lag vlan: access: red lag: @@ -146,6 +157,7 @@ links: lag: ifindex: 1 node: h2-02 + type: lag vlan: access: red - _vlan_mode: irb @@ -155,6 +167,7 @@ links: lag: _mlag: true node: r1 + type: lag vlan: access: red - _vlan_mode: irb @@ -164,6 +177,7 @@ links: lag: _mlag: true node: r2 + type: lag vlan: access: red lag: From 2ae13ff0a93200f3d5f82588b17a49111ed95153 Mon Sep 17 00:00:00 2001 From: Jeroen van Bemmel Date: Sat, 14 Dec 2024 14:44:38 -0600 Subject: [PATCH 7/8] _type is defined here --- netsim/augment/links.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netsim/augment/links.py b/netsim/augment/links.py index fbad85ae76..5d7a2fb5bb 100644 --- a/netsim/augment/links.py +++ b/netsim/augment/links.py @@ -209,7 +209,7 @@ def get_unique_ifindex( idx_list = [ # Build a list of already-used ifindex values intf.ifindex for intf in node.interfaces - if iftype == intf.get('_type',None) or (iftype is None and intf.get('_type',None) not in VIRTUAL_INTERFACE_TYPES) ] + if iftype == intf._type or (iftype is None and intf._type not in VIRTUAL_INTERFACE_TYPES) ] ifindex = start while ifindex < stop: # Iterate through ifindex values if ifindex not in idx_list: # ... returning the first one that is not used From 2255053b9a592218b234a716c620b6aa57a711d0 Mon Sep 17 00:00:00 2001 From: Jeroen van Bemmel Date: Sat, 14 Dec 2024 14:45:59 -0600 Subject: [PATCH 8/8] No change --- netsim/defaults/attributes.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/netsim/defaults/attributes.yml b/netsim/defaults/attributes.yml index 88c178448c..ff247320c7 100644 --- a/netsim/defaults/attributes.yml +++ b/netsim/defaults/attributes.yml @@ -69,7 +69,6 @@ link: # Global link attributes link_internal: # Internal link attributes linkindex: int parentindex: int - link_no_propagate: [ prefix, interfaces, gateway ] # Do not propagate VLAN attributes to node interfaces -- see #575 # Also: do not propagate DHCP attributes from links to interfaces