Skip to content

Commit ff8d28b

Browse files
committed
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 <luethi@osism.tech>
1 parent 051ede1 commit ff8d28b

2 files changed

Lines changed: 146 additions & 4 deletions

File tree

‎tests/e2e/golden/osism_e2e-portchannel_config_db.json‎

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,30 @@
3636
"default|L2VPN_EVPN|IPV4_UNICAST": {},
3737
"default|L2VPN_EVPN|IPV6_UNICAST": {}
3838
},
39-
"BGP_NEIGHBOR": {},
40-
"BGP_NEIGHBOR_AF": {},
39+
"BGP_NEIGHBOR": {
40+
"default|192.168.60.10": {
41+
"peer_type": "external",
42+
"v6only": "true"
43+
},
44+
"default|PortChannel1": {
45+
"peer_type": "external",
46+
"v6only": "true"
47+
}
48+
},
49+
"BGP_NEIGHBOR_AF": {
50+
"default|Ethernet8|ipv4_unicast": {
51+
"admin_status": "true"
52+
},
53+
"default|Ethernet8|ipv6_unicast": {
54+
"admin_status": "true"
55+
},
56+
"default|PortChannel1|ipv4_unicast": {
57+
"admin_status": "true"
58+
},
59+
"default|PortChannel1|ipv6_unicast": {
60+
"admin_status": "true"
61+
}
62+
},
4163
"BREAKOUT_CFG": {},
4264
"BREAKOUT_PORTS": {},
4365
"DEVICE_METADATA": {
@@ -49,7 +71,11 @@
4971
}
5072
},
5173
"DNS_NAMESERVER": {},
52-
"INTERFACE": {},
74+
"INTERFACE": {
75+
"Ethernet8": {
76+
"ipv6_use_link_local_only": "enable"
77+
}
78+
},
5379
"LOOPBACK": {},
5480
"LOOPBACK_INTERFACE": {},
5581
"MGMT_INTERFACE": {},
@@ -420,7 +446,7 @@
420446
"valid_speeds": "100000,40000"
421447
},
422448
"Ethernet8": {
423-
"admin_status": "down",
449+
"admin_status": "up",
424450
"adv_speeds": "all",
425451
"alias": "Eth1/3",
426452
"autoneg": "off",

‎tests/e2e/scenario/resources/600-portchannel.yml‎

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
# ports referencing it via their lag field, exactly as real deployments
88
# model it. Reuses the site / location / tenant from 100-base.yml, and
99
# takes the next free position in the shared E2E rack.
10+
#
11+
# The device is also where the BGP peering modes are pinned: its LAG is
12+
# cabled (an uncabled one never reaches the neighbour loops), and one of
13+
# its plain ports faces an endpoint that carries an address while the port
14+
# itself carries none. See the two blocks at the end of this file.
1015

1116
- device:
1217
name: e2e-portchannel
@@ -40,3 +45,114 @@
4045
device: e2e-portchannel
4146
name: Ethernet4
4247
lag: PortChannel1
48+
49+
# ----------------------------------------------------- connected LAG --
50+
# Cabling the two members is what makes PortChannel1 reach the BGP
51+
# neighbour loops: get_connected_interfaces() walks members and marks the
52+
# port channel connected, so an uncabled LAG (which is all this scenario
53+
# modelled before) never got there and left BGP_NEIGHBOR/BGP_NEIGHBOR_AF
54+
# empty on this device.
55+
#
56+
# The peer is the metalbox rather than a switch so that only this device's
57+
# golden moves: e2e-metalbox-1 has no SONiC role and no managed-by-metalbox
58+
# tag, so it never gets a golden of its own. A bonded server NIC facing a
59+
# switch is also how a LAG is usually cabled in the first place, so the far
60+
# end is a LAG too -- an aggregate cabled to two standalone routed ports
61+
# would not form.
62+
#
63+
# The peer address sits on the aggregate, not on the cabled members, which
64+
# is the conventional way to model it and the shape live fleet data uses.
65+
# Two lookups would have to reach it and neither does: the resolver's
66+
# LAG member fallback is off for BGP on purpose (turning it on would key
67+
# BGP_NEIGHBOR by a peer address the AF rows do not share), and nothing
68+
# follows a member up to the peer's own aggregate. So this pins the port
69+
# channel peering *unnumbered* -- both tables key on PortChannel1 and both
70+
# address families are activated on that link-local session -- and it moves
71+
# the day either lookup changes. The numbered port-channel case cannot be
72+
# reached from NetBox data at all, since a LAG interface is not cablable;
73+
# the unit tests pin that one.
74+
75+
- device_interface:
76+
device: e2e-metalbox-1
77+
name: bond0
78+
type: lag
79+
80+
- device_interface:
81+
device: e2e-metalbox-1
82+
name: Ethernet8
83+
type: 100gbase-x-qsfp28
84+
lag: bond0
85+
86+
- device_interface:
87+
device: e2e-metalbox-1
88+
name: Ethernet12
89+
type: 100gbase-x-qsfp28
90+
lag: bond0
91+
92+
- ip_address:
93+
tenant: Testbed
94+
address: 192.168.61.1/24
95+
assigned_object:
96+
name: bond0
97+
device: e2e-metalbox-1
98+
99+
- cable:
100+
termination_a_type: dcim.interface
101+
termination_a:
102+
device: e2e-portchannel
103+
name: Ethernet0
104+
termination_b_type: dcim.interface
105+
termination_b:
106+
device: e2e-metalbox-1
107+
name: Ethernet8
108+
109+
- cable:
110+
termination_a_type: dcim.interface
111+
termination_a:
112+
device: e2e-portchannel
113+
name: Ethernet4
114+
termination_b_type: dcim.interface
115+
termination_b:
116+
device: e2e-metalbox-1
117+
name: Ethernet12
118+
119+
# ------------------------------------------- peer address, none of ours --
120+
# A cabled port that carries no address of its own facing an endpoint that
121+
# does. The peer address resolves, but there is no local address to source
122+
# a numbered session from -- no Transfer prefix covers 192.168.60.0/24, and
123+
# this switch has nothing on Ethernet8 at all -- so the session must stay
124+
# unnumbered and both tables must key on Ethernet8.
125+
#
126+
# This is the shape where the neighbour identity and the ipv6_unicast guard
127+
# used to disagree: keying on the peer address alone produced a numbered
128+
# BGP_NEIGHBOR with no local_addr, and an ipv6_unicast row underneath an
129+
# IPv4 literal. Nothing else in the fixture set reaches it, because every
130+
# other cabled port is either addressed from the Transfer prefix or faces
131+
# an endpoint with no address.
132+
133+
- device_interface:
134+
device: e2e-portchannel
135+
name: Ethernet8
136+
type: 100gbase-x-qsfp28
137+
138+
- device_interface:
139+
device: e2e-metalbox-1
140+
name: Ethernet16
141+
type: 100gbase-x-qsfp28
142+
143+
- ip_address:
144+
tenant: Testbed
145+
address: 192.168.60.10/24
146+
assigned_object:
147+
name: Ethernet16
148+
device: e2e-metalbox-1
149+
150+
- cable:
151+
termination_a_type: dcim.interface
152+
termination_a:
153+
device: e2e-portchannel
154+
name: Ethernet8
155+
termination_b_type: dcim.interface
156+
termination_b:
157+
device: e2e-metalbox-1
158+
name: Ethernet16

0 commit comments

Comments
 (0)