From 82aee257f70d187cdfd5e387ba895f59b4ffc2c4 Mon Sep 17 00:00:00 2001 From: Roger Luethi Date: Sat, 1 Aug 2026 07:51:31 +0200 Subject: [PATCH 1/2] tests/e2e: cover port-channel generation Add a port-channel (LAG) device to the SONiC E2E synthetic fixtures. Until now the base/breakout fixtures modelled no LAGs, so PORTCHANNEL, PORTCHANNEL_INTERFACE and PORTCHANNEL_MEMBER were emitted by the generator but always empty in every golden -- that code path had no coverage. e2e-portchannel (rack E2E, position 9, edgecore-7726-32x-e2e / Accton-AS7726-32X, role leaf) reuses the site/location/tenant/tag objects created by 100-base.yml. It bonds Ethernet0 and Ethernet4 into PortChannel1: a NetBox LAG interface (type: lag) with the two data ports referencing it via their lag field, the same way real deployments model a port-channel. This brings cumulative non-empty config_db table coverage across the golden set from 32 to 35 of the 38 tables the generator emits (only the VXLAN EVPN/tunnel tables remain uncovered). Verified with a full down/regen/verify cycle against a freshly started NetBox stack, so the goldens reflect a from-scratch database rather than an UPDATE over a reused one. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Roger Luethi --- .../osism_e2e-portchannel_config_db.json | 587 ++++++++++++++++++ .../scenario/resources/600-portchannel.yml | 42 ++ 2 files changed, 629 insertions(+) create mode 100644 tests/e2e/golden/osism_e2e-portchannel_config_db.json create mode 100644 tests/e2e/scenario/resources/600-portchannel.yml diff --git a/tests/e2e/golden/osism_e2e-portchannel_config_db.json b/tests/e2e/golden/osism_e2e-portchannel_config_db.json new file mode 100644 index 000000000..a6d0c1364 --- /dev/null +++ b/tests/e2e/golden/osism_e2e-portchannel_config_db.json @@ -0,0 +1,587 @@ +{ + "BGP_GLOBALS": { + "default": { + "always_compare_med": "true", + "ebgp_requires_policy": "false", + "external_compare_router_id": "false", + "fast_external_failover": "true", + "holdtime": "180", + "ignore_as_path_length": "false", + "keepalive": "60", + "load_balance_mp_relax": "false", + "log_nbr_state_changes": "true", + "network_import_check": "true" + } + }, + "BGP_GLOBALS_AF": { + "default|ipv4_unicast": { + "ibgp_equal_cluster_length": "false", + "max_ebgp_paths": "2", + "max_ibgp_paths": "2", + "route_flap_dampen": "false" + }, + "default|ipv6_unicast": { + "ibgp_equal_cluster_length": "false", + "max_ebgp_paths": "2", + "max_ibgp_paths": "2" + }, + "default|l2vpn_evpn": { + "advertise-all-vni": "true", + "advertise-svi-ip": "true", + "dad-enabled": "true" + } + }, + "BGP_GLOBALS_AF_NETWORK": {}, + "BGP_GLOBALS_ROUTE_ADVERTISE": { + "default|L2VPN_EVPN|IPV4_UNICAST": {}, + "default|L2VPN_EVPN|IPV6_UNICAST": {} + }, + "BGP_NEIGHBOR": {}, + "BGP_NEIGHBOR_AF": {}, + "BREAKOUT_CFG": {}, + "BREAKOUT_PORTS": {}, + "DEVICE_METADATA": { + "localhost": { + "hostname": "e2e-portchannel", + "hwsku": "Accton-AS7726-32X", + "mac": "00:00:00:00:00:00", + "platform": "x86_64-accton_as7726_32x-r0" + } + }, + "DNS_NAMESERVER": {}, + "INTERFACE": {}, + "LOOPBACK": {}, + "LOOPBACK_INTERFACE": {}, + "MGMT_INTERFACE": {}, + "NTP_SERVER": {}, + "PORT": { + "Ethernet0": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/1", + "autoneg": "off", + "index": "1", + "lanes": "1,2,3,4", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet100": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/26", + "autoneg": "off", + "index": "26", + "lanes": "101,102,103,104", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet104": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/27", + "autoneg": "off", + "index": "27", + "lanes": "105,106,107,108", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet108": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/28", + "autoneg": "off", + "index": "28", + "lanes": "109,110,111,112", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet112": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/29", + "autoneg": "off", + "index": "29", + "lanes": "113,114,115,116", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet116": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/30", + "autoneg": "off", + "index": "30", + "lanes": "117,118,119,120", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet12": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/4", + "autoneg": "off", + "index": "4", + "lanes": "13,14,15,16", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet120": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/31", + "autoneg": "off", + "index": "31", + "lanes": "121,122,123,124", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet124": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/32", + "autoneg": "off", + "index": "32", + "lanes": "125,126,127,128", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet125": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/33", + "autoneg": "off", + "index": "33", + "lanes": "129", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet126": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/34", + "autoneg": "off", + "index": "34", + "lanes": "128", + "link_training": "off", + "mtu": "9100", + "speed": "10000", + "unreliable_los": "auto", + "valid_speeds": "10000,1000" + }, + "Ethernet16": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/5", + "autoneg": "off", + "index": "5", + "lanes": "17,18,19,20", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet20": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/6", + "autoneg": "off", + "index": "6", + "lanes": "21,22,23,24", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet24": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/7", + "autoneg": "off", + "index": "7", + "lanes": "25,26,27,28", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet28": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/8", + "autoneg": "off", + "index": "8", + "lanes": "29,30,31,32", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet32": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/9", + "autoneg": "off", + "index": "9", + "lanes": "33,34,35,36", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet36": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/10", + "autoneg": "off", + "index": "10", + "lanes": "37,38,39,40", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet4": { + "admin_status": "up", + "adv_speeds": "all", + "alias": "Eth1/2", + "autoneg": "off", + "index": "2", + "lanes": "5,6,7,8", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet40": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/11", + "autoneg": "off", + "index": "11", + "lanes": "41,42,43,44", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet44": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/12", + "autoneg": "off", + "index": "12", + "lanes": "45,46,47,48", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet48": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/13", + "autoneg": "off", + "index": "13", + "lanes": "49,50,51,52", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet52": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/14", + "autoneg": "off", + "index": "14", + "lanes": "53,54,55,56", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet56": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/15", + "autoneg": "off", + "index": "15", + "lanes": "57,58,59,60", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet60": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/16", + "autoneg": "off", + "index": "16", + "lanes": "61,62,63,64", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet64": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/17", + "autoneg": "off", + "index": "17", + "lanes": "65,66,67,68", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet68": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/18", + "autoneg": "off", + "index": "18", + "lanes": "69,70,71,72", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet72": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/19", + "autoneg": "off", + "index": "19", + "lanes": "73,74,75,76", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet76": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/20", + "autoneg": "off", + "index": "20", + "lanes": "77,78,79,80", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet8": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/3", + "autoneg": "off", + "index": "3", + "lanes": "9,10,11,12", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet80": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/21", + "autoneg": "off", + "index": "21", + "lanes": "81,82,83,84", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet84": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/22", + "autoneg": "off", + "index": "22", + "lanes": "85,86,87,88", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet88": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/23", + "autoneg": "off", + "index": "23", + "lanes": "89,90,91,92", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet92": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/24", + "autoneg": "off", + "index": "24", + "lanes": "93,94,95,96", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + }, + "Ethernet96": { + "admin_status": "down", + "adv_speeds": "all", + "alias": "Eth1/25", + "autoneg": "off", + "index": "25", + "lanes": "97,98,99,100", + "link_training": "off", + "mtu": "9100", + "speed": "100000", + "unreliable_los": "auto", + "valid_speeds": "100000,40000" + } + }, + "PORTCHANNEL": { + "PortChannel1": { + "admin_status": "up", + "fast_rate": "true", + "min_links": "1", + "mtu": "9100" + } + }, + "PORTCHANNEL_INTERFACE": { + "PortChannel1": { + "ipv6_use_link_local_only": "enable" + } + }, + "PORTCHANNEL_MEMBER": { + "PortChannel1|Ethernet0": {}, + "PortChannel1|Ethernet4": {} + }, + "ROUTE_REDISTRIBUTE": { + "default|connected|bgp|ipv4": {}, + "default|connected|bgp|ipv6": {} + }, + "SNMP_SERVER": { + "SYSTEM": { + "sysContact": "e2e@example.com", + "sysLocation": "E2E Lab", + "traps": "enable" + } + }, + "SNMP_SERVER_GROUP_MEMBER": { + "monitoring|e2e-monitor": { + "securityModel": [ + "usm" + ] + } + }, + "SNMP_SERVER_PARAMS": { + "targetEntry1": { + "security-level": "auth-priv", + "user": "e2e-monitor" + } + }, + "SNMP_SERVER_TARGET": { + "targetEntry1": { + "ip": "172.16.10.254", + "port": "162", + "retries": "3", + "tag": [ + "trapNotify", + "mgmt" + ], + "targetParams": "targetEntry1", + "timeout": "1500" + } + }, + "SNMP_SERVER_USER": { + "e2e-monitor": { + "aesKey": "OBFUSCATEDPRIVSECRET", + "shaKey": "OBFUSCATEDAUTHSECRET" + } + }, + "STATIC_ROUTE": {}, + "SYSLOG_SERVER": { + "172.16.10.254": { + "message-type": "log", + "protocol": "UDP", + "remote-port": "514", + "severity": "info", + "vrf_name": "mgmt" + } + }, + "VERSIONS": { + "DATABASE": { + "VERSION": "version_4_0_1" + } + }, + "VLAN": {}, + "VLAN_INTERFACE": {}, + "VLAN_MEMBER": {}, + "VRF": { + "default": { + "enabled": "true" + } + }, + "VXLAN_EVPN_NVO": {}, + "VXLAN_TUNNEL": {}, + "VXLAN_TUNNEL_MAP": {} +} diff --git a/tests/e2e/scenario/resources/600-portchannel.yml b/tests/e2e/scenario/resources/600-portchannel.yml new file mode 100644 index 000000000..2f1b8e6e8 --- /dev/null +++ b/tests/e2e/scenario/resources/600-portchannel.yml @@ -0,0 +1,42 @@ +--- +# Port-channel (LAG) scenario for the SONiC E2E golden test. +# +# The base fixtures model no LAGs, so PORTCHANNEL / PORTCHANNEL_MEMBER / +# PORTCHANNEL_INTERFACE are emitted-but-empty. This device bonds two data +# ports into PortChannel1: a NetBox LAG interface (type: lag) with the two +# ports referencing it via their lag field, exactly as real deployments +# model it. Reuses the site / location / tenant from 100-base.yml, and +# takes the next free position in the shared E2E rack. + +- device: + name: e2e-portchannel + tenant: Testbed + site: Discworld + location: Ankh-Morpork + rack: E2E + device_type: edgecore-7726-32x-e2e + device_role: leaf + face: front + position: 9 + status: active + tags: + - managed-by-metalbox + custom_fields: + sonic_parameters: + hwsku: Accton-AS7726-32X + version: 4.5.0 + +- device_interface: + device: e2e-portchannel + name: PortChannel1 + type: lag + +- device_interface: + device: e2e-portchannel + name: Ethernet0 + lag: PortChannel1 + +- device_interface: + device: e2e-portchannel + name: Ethernet4 + lag: PortChannel1 From d07d744b495a6d58f71e6ac4e4dfd44141702c3d Mon Sep 17 00:00:00 2001 From: Roger Luethi Date: Fri, 28 Aug 2026 20:27:05 +0200 Subject: [PATCH 2/2] tests/e2e: cover the BGP peering modes Nothing in the golden set distinguished a numbered BGP session from an unnumbered one on the paths that generate most of them. e2e-portchannel modelled an uncabled LAG, so its BGP_NEIGHBOR and BGP_NEIGHBOR_AF were both empty -- get_connected_interfaces() marks a port channel connected only when a member is cabled, so those loops were never entered at all. No fixture reached the shape where an interface carries no address of its own while the endpoint it faces carries one, which is where the neighbour identity and the address family selection can disagree. Two blocks are added to 600-portchannel.yml. The first cables both members of PortChannel1 to e2e-metalbox-1, whose side is a LAG as well: an aggregate cabled to two standalone routed ports would not form. The peer address sits on that aggregate, not on the cabled members, which is the conventional way to model it. Two lookups would have to reach it and neither does -- the resolver's LAG member fallback is off for BGP on purpose, and nothing follows a member up to the peer's own aggregate -- so this pins the port channel peering unnumbered, and it moves the day either lookup changes. The numbered port-channel case cannot be reached from NetBox data at all, since a LAG interface is not cablable; the unit tests pin that one. The second gives the device a plain port with no address facing a metalbox port that has one, outside any Transfer prefix. With no local address there is nothing to source a numbered session from, so the peering is link-local and both address families are activated on Ethernet8. The two tables do not agree on who the peer is: the neighbour is keyed by the address found on the far end while the address families are keyed by the interface, so the golden records a session whose halves point at different names. That disagreement is as much the reason for this block as the peering mode is -- nothing else in tree captures it, and it moves the day the two are derived from one decision. e2e-metalbox-1 is the peer in both because it has no SONiC role and no managed-by-metalbox tag, so it never gets a golden of its own and the churn stays in this device's golden. Assisted-by: Claude:claude-opus-5 Signed-off-by: Roger Luethi --- .../osism_e2e-portchannel_config_db.json | 34 ++++- .../scenario/resources/600-portchannel.yml | 116 ++++++++++++++++++ 2 files changed, 146 insertions(+), 4 deletions(-) diff --git a/tests/e2e/golden/osism_e2e-portchannel_config_db.json b/tests/e2e/golden/osism_e2e-portchannel_config_db.json index a6d0c1364..c2489c68d 100644 --- a/tests/e2e/golden/osism_e2e-portchannel_config_db.json +++ b/tests/e2e/golden/osism_e2e-portchannel_config_db.json @@ -36,8 +36,30 @@ "default|L2VPN_EVPN|IPV4_UNICAST": {}, "default|L2VPN_EVPN|IPV6_UNICAST": {} }, - "BGP_NEIGHBOR": {}, - "BGP_NEIGHBOR_AF": {}, + "BGP_NEIGHBOR": { + "default|192.168.60.10": { + "peer_type": "external", + "v6only": "true" + }, + "default|PortChannel1": { + "peer_type": "external", + "v6only": "true" + } + }, + "BGP_NEIGHBOR_AF": { + "default|Ethernet8|ipv4_unicast": { + "admin_status": "true" + }, + "default|Ethernet8|ipv6_unicast": { + "admin_status": "true" + }, + "default|PortChannel1|ipv4_unicast": { + "admin_status": "true" + }, + "default|PortChannel1|ipv6_unicast": { + "admin_status": "true" + } + }, "BREAKOUT_CFG": {}, "BREAKOUT_PORTS": {}, "DEVICE_METADATA": { @@ -49,7 +71,11 @@ } }, "DNS_NAMESERVER": {}, - "INTERFACE": {}, + "INTERFACE": { + "Ethernet8": { + "ipv6_use_link_local_only": "enable" + } + }, "LOOPBACK": {}, "LOOPBACK_INTERFACE": {}, "MGMT_INTERFACE": {}, @@ -420,7 +446,7 @@ "valid_speeds": "100000,40000" }, "Ethernet8": { - "admin_status": "down", + "admin_status": "up", "adv_speeds": "all", "alias": "Eth1/3", "autoneg": "off", diff --git a/tests/e2e/scenario/resources/600-portchannel.yml b/tests/e2e/scenario/resources/600-portchannel.yml index 2f1b8e6e8..6ddf26bc3 100644 --- a/tests/e2e/scenario/resources/600-portchannel.yml +++ b/tests/e2e/scenario/resources/600-portchannel.yml @@ -7,6 +7,11 @@ # ports referencing it via their lag field, exactly as real deployments # model it. Reuses the site / location / tenant from 100-base.yml, and # takes the next free position in the shared E2E rack. +# +# The device is also where the BGP peering modes are pinned: its LAG is +# cabled (an uncabled one never reaches the neighbour loops), and one of +# its plain ports faces an endpoint that carries an address while the port +# itself carries none. See the two blocks at the end of this file. - device: name: e2e-portchannel @@ -40,3 +45,114 @@ device: e2e-portchannel name: Ethernet4 lag: PortChannel1 + +# ----------------------------------------------------- connected LAG -- +# Cabling the two members is what makes PortChannel1 reach the BGP +# neighbour loops: get_connected_interfaces() walks members and marks the +# port channel connected, so an uncabled LAG (which is all this scenario +# modelled before) never got there and left BGP_NEIGHBOR/BGP_NEIGHBOR_AF +# empty on this device. +# +# The peer is the metalbox rather than a switch so that only this device's +# golden moves: e2e-metalbox-1 has no SONiC role and no managed-by-metalbox +# tag, so it never gets a golden of its own. A bonded server NIC facing a +# switch is also how a LAG is usually cabled in the first place, so the far +# end is a LAG too -- an aggregate cabled to two standalone routed ports +# would not form. +# +# The peer address sits on the aggregate, not on the cabled members, which +# is the conventional way to model it and the shape live fleet data uses. +# Two lookups would have to reach it and neither does: the resolver's +# LAG member fallback is off for BGP on purpose (turning it on would key +# BGP_NEIGHBOR by a peer address the AF rows do not share), and nothing +# follows a member up to the peer's own aggregate. So this pins the port +# channel peering *unnumbered* -- both tables key on PortChannel1 and both +# address families are activated on that link-local session -- and it moves +# the day either lookup changes. The numbered port-channel case cannot be +# reached from NetBox data at all, since a LAG interface is not cablable; +# the unit tests pin that one. + +- device_interface: + device: e2e-metalbox-1 + name: bond0 + type: lag + +- device_interface: + device: e2e-metalbox-1 + name: Ethernet8 + type: 100gbase-x-qsfp28 + lag: bond0 + +- device_interface: + device: e2e-metalbox-1 + name: Ethernet12 + type: 100gbase-x-qsfp28 + lag: bond0 + +- ip_address: + tenant: Testbed + address: 192.168.61.1/24 + assigned_object: + name: bond0 + device: e2e-metalbox-1 + +- cable: + termination_a_type: dcim.interface + termination_a: + device: e2e-portchannel + name: Ethernet0 + termination_b_type: dcim.interface + termination_b: + device: e2e-metalbox-1 + name: Ethernet8 + +- cable: + termination_a_type: dcim.interface + termination_a: + device: e2e-portchannel + name: Ethernet4 + termination_b_type: dcim.interface + termination_b: + device: e2e-metalbox-1 + name: Ethernet12 + +# ------------------------------------------- peer address, none of ours -- +# A cabled port that carries no address of its own facing an endpoint that +# does. The peer address resolves, but there is no local address to source +# a numbered session from -- no Transfer prefix covers 192.168.60.0/24, and +# this switch has nothing on Ethernet8 at all -- so the session must stay +# unnumbered and both tables must key on Ethernet8. +# +# This is the shape where the neighbour identity and the ipv6_unicast guard +# used to disagree: keying on the peer address alone produced a numbered +# BGP_NEIGHBOR with no local_addr, and an ipv6_unicast row underneath an +# IPv4 literal. Nothing else in the fixture set reaches it, because every +# other cabled port is either addressed from the Transfer prefix or faces +# an endpoint with no address. + +- device_interface: + device: e2e-portchannel + name: Ethernet8 + type: 100gbase-x-qsfp28 + +- device_interface: + device: e2e-metalbox-1 + name: Ethernet16 + type: 100gbase-x-qsfp28 + +- ip_address: + tenant: Testbed + address: 192.168.60.10/24 + assigned_object: + name: Ethernet16 + device: e2e-metalbox-1 + +- cable: + termination_a_type: dcim.interface + termination_a: + device: e2e-portchannel + name: Ethernet8 + termination_b_type: dcim.interface + termination_b: + device: e2e-metalbox-1 + name: Ethernet16