]>
Commit | Line | Data |
---|---|---|
e0a84778 VB |
1 | import pytest |
2 | import pyroute2 | |
3 | import time | |
4 | ||
5 | ||
6 | def test_simple_bridge(lldpd1, lldpd, lldpcli, namespaces, links): | |
7 | links(namespaces(3), namespaces(2)) # Another link to setup a bridge | |
8 | with namespaces(2): | |
9 | links.bridge('br42', 'eth1', 'eth3') | |
10 | lldpd() | |
11 | with namespaces(1): | |
12 | out = lldpcli("-f", "keyvalue", "show", "neighbors", "details") | |
13 | assert out['lldp.eth0.port.descr'] == 'eth1' | |
14 | assert out['lldp.eth0.chassis.Bridge.enabled'] == 'on' | |
15 | ||
16 | ||
703f6a0d VB |
17 | def test_remove_bridge(lldpd, lldpcli, namespaces, links): |
18 | links(namespaces(1), namespaces(2)) | |
19 | links(namespaces(3), namespaces(1)) # Another link to setup a bridge | |
20 | with namespaces(1): | |
21 | links.bridge('br42', 'eth0', 'eth3') | |
22 | lldpd("-r") | |
23 | with namespaces(2): | |
24 | lldpd() | |
25 | time.sleep(2) | |
26 | lldpcli("pause") # Prevent any updates | |
27 | with namespaces(1): | |
28 | out = lldpcli("-f", "keyvalue", "show", "neighbors", "details") | |
29 | assert out['lldp.eth0.port.descr'] == 'eth1' | |
69594747 VB |
30 | # Remove from bridge. We don't use netlink because we wouldn't |
31 | # get the wanted effect: we also get a RTM_NEWLINK by doing | |
32 | # that. Only the bridge ioctl() would prevent that. | |
33 | links.unbridge('br42', 'eth0') | |
703f6a0d VB |
34 | time.sleep(1) |
35 | # Check if we still have eth0 | |
36 | out = lldpcli("-f", "keyvalue", "show", "neighbors", "details") | |
37 | assert out['lldp.eth0.port.descr'] == 'eth1' | |
38 | ||
39 | ||
f6bbc43b | 40 | @pytest.mark.skipif("'Dot1' not in config.lldpd.features", |
e0a84778 VB |
41 | reason="Dot1 not supported") |
42 | @pytest.mark.parametrize('when', ['before', 'after']) | |
43 | def test_bridge_with_vlan(lldpd1, lldpd, lldpcli, namespaces, links, when): | |
44 | links(namespaces(3), namespaces(2)) # Another link to setup a bridge | |
45 | with namespaces(2): | |
46 | if when == 'after': | |
47 | lldpd() | |
48 | links.bridge('br42', 'eth1', 'eth3') | |
49 | links.vlan('vlan100', 100, 'br42') | |
50 | links.vlan('vlan200', 200, 'br42') | |
51 | links.vlan('vlan300', 300, 'br42') | |
52 | if when == 'before': | |
53 | lldpd() | |
54 | else: | |
e0a84778 VB |
55 | time.sleep(6) |
56 | with namespaces(1): | |
57 | out = lldpcli("-f", "keyvalue", "show", "neighbors", "details") | |
58 | assert out['lldp.eth0.port.descr'] == 'eth1' | |
59 | assert out['lldp.eth0.vlan'] == \ | |
60 | ['vlan100', 'vlan200', 'vlan300'] | |
61 | assert out['lldp.eth0.vlan.vlan-id'] == \ | |
62 | ['100', '200', '300'] | |
63 | ||
64 | ||
011056b3 VB |
65 | @pytest.mark.skipif("'Dot1' not in config.lldpd.features", |
66 | reason="Dot1 not supported") | |
67 | @pytest.mark.parametrize('when', ['before', 'after']) | |
68 | def test_vlan_aware_bridge_with_vlan(lldpd1, lldpd, lldpcli, namespaces, links, | |
69 | when): | |
70 | links(namespaces(3), namespaces(2)) # Another link to setup a bridge | |
24e8fda8 VB |
71 | with namespaces(3): |
72 | lldpd() | |
011056b3 VB |
73 | with namespaces(2): |
74 | if when == 'after': | |
75 | lldpd() | |
385e5e4c | 76 | links.bridge('br42', 'eth1', 'eth3', filtering=True) |
011056b3 VB |
77 | links.bridge_vlan('eth1', 100, pvid=True) |
78 | links.bridge_vlan('eth1', 200) | |
79 | links.bridge_vlan('eth1', 300) | |
24e8fda8 | 80 | links.bridge_vlan('eth3', 400) |
011056b3 VB |
81 | if when == 'before': |
82 | lldpd() | |
83 | else: | |
84 | time.sleep(6) | |
85 | with namespaces(1): | |
86 | out = lldpcli("-f", "keyvalue", "show", "neighbors", "details") | |
87 | assert out['lldp.eth0.port.descr'] == 'eth1' | |
88 | assert out['lldp.eth0.vlan'] == \ | |
626ea361 | 89 | ['vlan100', 'vlan200', 'vlan300'] |
011056b3 VB |
90 | assert out['lldp.eth0.vlan.vlan-id'] == \ |
91 | ['100', '200', '300'] | |
92 | assert out['lldp.eth0.vlan.pvid'] == \ | |
93 | ['yes', 'no', 'no'] | |
24e8fda8 VB |
94 | with namespaces(3): |
95 | out = lldpcli("-f", "keyvalue", "show", "neighbors", "details") | |
96 | assert out['lldp.eth2.port.descr'] == 'eth3' | |
97 | assert out['lldp.eth2.vlan'] == \ | |
98 | 'vlan400' | |
99 | assert out['lldp.eth2.vlan.vlan-id'] == \ | |
100 | '400' | |
101 | assert out['lldp.eth2.vlan.pvid'] == \ | |
102 | 'no' | |
011056b3 VB |
103 | |
104 | ||
385e5e4c VB |
105 | @pytest.mark.skipif("'Dot1' not in config.lldpd.features", |
106 | reason="Dot1 not supported") | |
107 | @pytest.mark.parametrize('filtering', [False, True]) | |
108 | def test_vlan_aware_bridge_filtering(lldpd1, lldpd, lldpcli, | |
109 | namespaces, links, filtering): | |
110 | links(namespaces(3), namespaces(2)) # Another link to setup a bridge | |
111 | with namespaces(2): | |
112 | links.bridge('br42', 'eth1', 'eth3', filtering=filtering) | |
113 | links.bridge_vlan('eth1', 100, pvid=True) | |
114 | links.bridge_vlan('eth1', 200) | |
115 | links.bridge_vlan('eth1', 300) | |
116 | links.bridge_vlan('eth3', 400) | |
117 | links.vlan('vlan400', 400, 'br42') | |
118 | lldpd() | |
119 | with namespaces(1): | |
120 | out = lldpcli("-f", "keyvalue", "show", "neighbors", "details") | |
121 | assert out['lldp.eth0.port.descr'] == 'eth1' | |
122 | if filtering: | |
123 | assert out['lldp.eth0.vlan'] == \ | |
124 | ['vlan100', 'vlan200', 'vlan300'] | |
125 | assert out['lldp.eth0.vlan.vlan-id'] == \ | |
126 | ['100', '200', '300'] | |
127 | assert out['lldp.eth0.vlan.pvid'] == \ | |
128 | ['yes', 'no', 'no'] | |
129 | else: | |
130 | assert out['lldp.eth0.vlan'] == \ | |
131 | ['vlan100', 'vlan200', 'vlan300', 'vlan400'] | |
132 | assert out['lldp.eth0.vlan.vlan-id'] == \ | |
133 | ['100', '200', '300', '400'] | |
134 | assert out['lldp.eth0.vlan.pvid'] == \ | |
135 | ['yes', 'no', 'no', 'no'] | |
136 | ||
137 | ||
f6bbc43b | 138 | @pytest.mark.skipif("'Dot3' not in config.lldpd.features", |
e0a84778 VB |
139 | reason="Dot3 not supported") |
140 | @pytest.mark.parametrize('when', ['before', 'after']) | |
141 | def test_bond(lldpd1, lldpd, lldpcli, namespaces, links, when): | |
142 | links(namespaces(3), namespaces(2)) # Another link to setup a bond | |
143 | with namespaces(2): | |
144 | if when == 'after': | |
145 | lldpd() | |
146 | idx = links.bond('bond42', 'eth3', 'eth1') | |
147 | ipr = pyroute2.IPRoute() | |
148 | # The bond has the MAC of eth3 | |
149 | assert ipr.get_links(idx)[0].get_attr('IFLA_ADDRESS') == \ | |
150 | "00:00:00:00:00:04" | |
151 | if when == 'before': | |
152 | lldpd() | |
153 | else: | |
e0a84778 VB |
154 | time.sleep(6) |
155 | with namespaces(1): | |
156 | out = lldpcli("-f", "keyvalue", "show", "neighbors", "details") | |
157 | assert out['lldp.eth0.port.descr'] == 'eth1' | |
158 | assert out['lldp.eth0.port.aggregation'] == str(idx) | |
159 | # lldpd should be able to retrieve the right MAC | |
160 | assert out['lldp.eth0.port.mac'] == '00:00:00:00:00:02' | |
161 | ||
162 | ||
f6bbc43b | 163 | @pytest.mark.skipif("'Dot3' not in config.lldpd.features", |
5f658dac | 164 | reason="Dot3 not supported") |
cbafbacc VB |
165 | @pytest.mark.skipif("'rtnl-link-team' not in config.kernel.features", |
166 | reason="No team support in kernel") | |
5f658dac VB |
167 | @pytest.mark.parametrize('when', ['before', 'after']) |
168 | def test_team(lldpd1, lldpd, lldpcli, namespaces, links, when): | |
169 | links(namespaces(3), namespaces(2)) # Another link to setup a bond | |
170 | with namespaces(2): | |
171 | if when == 'after': | |
172 | lldpd() | |
173 | idx = links.team('team42', 'eth3', 'eth1') | |
174 | if when == 'before': | |
175 | lldpd() | |
176 | else: | |
177 | time.sleep(6) | |
178 | with namespaces(1): | |
179 | out = lldpcli("-f", "keyvalue", "show", "neighbors", "details") | |
180 | assert out['lldp.eth0.port.descr'] == 'eth1' | |
181 | assert out['lldp.eth0.port.aggregation'] == str(idx) | |
182 | # Unfortunately, we cannot get the right MAC currently... So, | |
a3bea2f6 | 183 | # this bit will succeed by chance. |
5f658dac VB |
184 | assert out['lldp.eth0.port.mac'] == '00:00:00:00:00:02' |
185 | ||
186 | ||
f6bbc43b | 187 | @pytest.mark.skipif("'Dot3' not in config.lldpd.features", |
e0a84778 | 188 | reason="Dot3 not supported") |
f6bbc43b | 189 | @pytest.mark.skipif("'Dot1' not in config.lldpd.features", |
e0a84778 VB |
190 | reason="Dot1 not supported") |
191 | @pytest.mark.parametrize('when', ['before', 'after']) | |
192 | def test_bond_with_vlan(lldpd1, lldpd, lldpcli, namespaces, links, when): | |
193 | links(namespaces(3), namespaces(2)) # Another link to setup a bond | |
194 | with namespaces(2): | |
195 | if when == 'after': | |
196 | lldpd() | |
197 | links.bond('bond42', 'eth3', 'eth1') | |
198 | links.vlan('vlan300', 300, 'bond42') | |
199 | links.vlan('vlan301', 301, 'bond42') | |
200 | links.vlan('vlan302', 302, 'bond42') | |
201 | links.vlan('vlan303', 303, 'bond42') | |
202 | if when == 'before': | |
203 | lldpd() | |
204 | else: | |
e0a84778 VB |
205 | time.sleep(6) |
206 | with namespaces(1): | |
207 | out = lldpcli("-f", "keyvalue", "show", "neighbors", "details") | |
208 | assert out['lldp.eth0.port.descr'] == 'eth1' | |
209 | assert out['lldp.eth0.vlan'] == \ | |
210 | ['vlan300', 'vlan301', 'vlan302', 'vlan303'] | |
211 | assert out['lldp.eth0.vlan.vlan-id'] == \ | |
212 | ['300', '301', '302', '303'] | |
213 | ||
214 | ||
f6bbc43b | 215 | @pytest.mark.skipif("'Dot1' not in config.lldpd.features", |
e0a84778 VB |
216 | reason="Dot1 not supported") |
217 | @pytest.mark.parametrize('when', ['before', 'after']) | |
218 | def test_just_vlan(lldpd1, lldpd, lldpcli, namespaces, links, when): | |
219 | with namespaces(2): | |
220 | if when == 'after': | |
221 | lldpd() | |
222 | links.vlan('vlan300', 300, 'eth1') | |
223 | links.vlan('vlan400', 400, 'eth1') | |
224 | if when == 'before': | |
225 | lldpd() | |
226 | else: | |
227 | time.sleep(6) | |
228 | with namespaces(1): | |
229 | out = lldpcli("-f", "keyvalue", "show", "neighbors", "details") | |
230 | assert out['lldp.eth0.port.descr'] == 'eth1' | |
231 | assert out['lldp.eth0.vlan'] == ['vlan300', 'vlan400'] | |
232 | assert out['lldp.eth0.vlan.vlan-id'] == ['300', '400'] | |
233 | ||
234 | ||
f6bbc43b | 235 | @pytest.mark.skipif("'Dot1' not in config.lldpd.features", |
e0a84778 | 236 | reason="Dot1 not supported") |
011056b3 | 237 | @pytest.mark.parametrize('kind', ['plain', 'bridge', 'vlan-aware-bridge', 'bond']) |
e0a84778 VB |
238 | def test_remove_vlan(lldpd1, lldpd, lldpcli, namespaces, links, kind): |
239 | with namespaces(2): | |
240 | if kind == 'bond': | |
241 | iface = 'bond42' | |
242 | links.bond(iface, 'eth1') | |
011056b3 | 243 | elif kind in ('bridge', 'vlan-aware-bridge'): |
e0a84778 VB |
244 | iface = 'bridge42' |
245 | links.bridge(iface, 'eth1') | |
246 | else: | |
247 | assert kind == 'plain' | |
248 | iface = 'eth1' | |
011056b3 VB |
249 | if kind != 'vlan-aware-bridge': |
250 | links.vlan('vlan300', 300, iface) | |
251 | links.vlan('vlan400', 400, iface) | |
252 | links.vlan('vlan500', 500, iface) | |
253 | lldpd() | |
254 | links.remove('vlan300') | |
255 | else: | |
256 | links.bridge_vlan('eth1', 300, pvid=True) | |
257 | links.bridge_vlan('eth1', 400) | |
258 | links.bridge_vlan('eth1', 500) | |
259 | lldpd() | |
260 | links.bridge_vlan('eth1', 300, remove=True) | |
4af75e55 | 261 | time.sleep(6) |
e0a84778 VB |
262 | with namespaces(1): |
263 | out = lldpcli("-f", "keyvalue", "show", "neighbors", "details") | |
264 | assert out['lldp.eth0.port.descr'] == 'eth1' | |
626ea361 | 265 | assert out['lldp.eth0.vlan'] == ['vlan400', 'vlan500'] |
e0a84778 | 266 | assert out['lldp.eth0.vlan.vlan-id'] == ['400', '500'] |
011056b3 | 267 | assert out['lldp.eth0.vlan.pvid'] == ['no', 'no'] |
e0a84778 VB |
268 | |
269 | ||
f6bbc43b | 270 | @pytest.mark.skipif("'Dot3' not in config.lldpd.features", |
e0a84778 VB |
271 | reason="Dot3 not supported") |
272 | def test_unenslave_bond(lldpd1, lldpd, lldpcli, namespaces, links): | |
273 | with namespaces(2): | |
274 | links.bond('bond42', 'eth1') | |
275 | lldpd() | |
276 | links.remove('bond42') | |
277 | links.up('eth1') | |
ab8db0c0 | 278 | time.sleep(6) |
e0a84778 VB |
279 | with namespaces(1): |
280 | out = lldpcli("-f", "keyvalue", "show", "neighbors", "details") | |
281 | assert out['lldp.eth0.port.descr'] == 'eth1' | |
282 | assert 'lldp.eth0.port.aggregation' not in out | |
283 | ||
284 | ||
f6bbc43b | 285 | @pytest.mark.skipif("'Dot1' not in config.lldpd.features", |
e0a84778 VB |
286 | reason="Dot1 not supported") |
287 | def test_unenslave_bond_with_vlan(lldpd1, lldpd, lldpcli, namespaces, links): | |
288 | with namespaces(2): | |
289 | links.bond('bond42', 'eth1') | |
290 | links.vlan('vlan300', 300, 'bond42') | |
291 | links.vlan('vlan400', 400, 'eth1') | |
292 | lldpd() | |
293 | links.remove('bond42') | |
294 | links.up('eth1') | |
ab8db0c0 | 295 | time.sleep(6) |
e0a84778 VB |
296 | with namespaces(1): |
297 | out = lldpcli("-f", "keyvalue", "show", "neighbors", "details") | |
298 | assert out['lldp.eth0.port.descr'] == 'eth1' | |
299 | assert out['lldp.eth0.vlan'] == 'vlan400' | |
300 | assert out['lldp.eth0.vlan.vlan-id'] == '400' | |
301 | ||
302 | ||
303 | def test_down_then_up(lldpd1, lldpd, lldpcli, namespaces, links): | |
304 | with namespaces(2): | |
305 | links.down('eth1') | |
306 | lldpd() | |
307 | with namespaces(1): | |
308 | out = lldpcli("-f", "keyvalue", "show", "neighbors", "details") | |
309 | assert out == {} | |
310 | with namespaces(2): | |
311 | links.up('eth1') | |
fe7e202d | 312 | time.sleep(6) |
e0a84778 VB |
313 | with namespaces(1): |
314 | out = lldpcli("-f", "keyvalue", "show", "neighbors", "details") | |
315 | assert out['lldp.eth0.port.descr'] == 'eth1' | |
316 | ||
317 | ||
f6bbc43b | 318 | @pytest.mark.skipif("'Dot1' not in config.lldpd.features", |
aceb61b4 | 319 | reason="Dot1 not supported") |
e0a84778 VB |
320 | def test_down_then_up_with_vlan(lldpd1, lldpd, lldpcli, namespaces, links): |
321 | with namespaces(2): | |
322 | links.vlan('vlan300', 300, 'eth1') | |
323 | links.vlan('vlan400', 400, 'eth1') | |
324 | links.down('eth1') | |
325 | lldpd() | |
326 | links.up('eth1') | |
fe7e202d | 327 | time.sleep(6) |
e0a84778 VB |
328 | with namespaces(1): |
329 | out = lldpcli("-f", "keyvalue", "show", "neighbors", "details") | |
330 | assert out['lldp.eth0.port.descr'] == 'eth1' | |
331 | assert out['lldp.eth0.vlan'] == ['vlan300', 'vlan400'] | |
332 | assert out['lldp.eth0.vlan.vlan-id'] == ['300', '400'] | |
333 | ||
334 | ||
335 | def test_new_interface(lldpd1, lldpd, lldpcli, namespaces, links): | |
336 | with namespaces(2): | |
337 | lldpd() | |
36d0c286 VB |
338 | links(namespaces(1), namespaces(2), 4) |
339 | time.sleep(6) | |
e0a84778 VB |
340 | with namespaces(1): |
341 | out = lldpcli("-f", "keyvalue", "show", "neighbors", "details") | |
342 | assert out['lldp.eth0.port.descr'] == 'eth1' | |
343 | assert out['lldp.eth2.port.descr'] == 'eth3' | |
344 | assert out['lldp.eth0.rid'] == out['lldp.eth2.rid'] # Same chassis |