blob: db4af60745113787e737405f2a841b0bd3aa7793 [file] [log] [blame]
Renato Botelho do Coutoead1e532019-10-31 13:31:07 -05001#!/usr/bin/env python3
Neale Ranns055b2312018-07-20 01:16:04 -07002
3import unittest
4import socket
5
6from framework import VppTestCase, VppTestRunner
7from vpp_ip_route import VppIpRoute, VppRoutePath
Neale Ranns93cc3ee2018-10-10 07:22:51 -07008from vpp_l2 import L2_PORT_TYPE, BRIDGE_FLAGS
Neale Ranns055b2312018-07-20 01:16:04 -07009
10from scapy.packet import Raw
11from scapy.layers.l2 import Ether
12from scapy.layers.inet import IP, UDP
13
Paul Vinciguerra4271c972019-05-14 13:25:49 -040014NUM_PKTS = 67
15
Neale Ranns055b2312018-07-20 01:16:04 -070016
17class TestL2Flood(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020018 """L2-flood"""
Neale Ranns055b2312018-07-20 01:16:04 -070019
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -070020 @classmethod
21 def setUpClass(cls):
22 super(TestL2Flood, cls).setUpClass()
23
24 @classmethod
25 def tearDownClass(cls):
26 super(TestL2Flood, cls).tearDownClass()
27
Neale Ranns055b2312018-07-20 01:16:04 -070028 def setUp(self):
29 super(TestL2Flood, self).setUp()
30
31 # 12 l2 interface and one l3
32 self.create_pg_interfaces(range(13))
Neale Ranns192b13f2019-03-15 02:16:20 -070033 self.create_bvi_interfaces(1)
Neale Ranns055b2312018-07-20 01:16:04 -070034
35 for i in self.pg_interfaces:
36 i.admin_up()
Neale Ranns192b13f2019-03-15 02:16:20 -070037 for i in self.bvi_interfaces:
Neale Ranns055b2312018-07-20 01:16:04 -070038 i.admin_up()
39
40 self.pg12.config_ip4()
41 self.pg12.resolve_arp()
Neale Ranns192b13f2019-03-15 02:16:20 -070042 self.bvi0.config_ip4()
Neale Ranns055b2312018-07-20 01:16:04 -070043
44 def tearDown(self):
45 self.pg12.unconfig_ip4()
Neale Ranns192b13f2019-03-15 02:16:20 -070046 self.bvi0.unconfig_ip4()
Neale Ranns055b2312018-07-20 01:16:04 -070047
48 for i in self.pg_interfaces:
49 i.admin_down()
Neale Ranns192b13f2019-03-15 02:16:20 -070050 for i in self.bvi_interfaces:
Neale Ranns055b2312018-07-20 01:16:04 -070051 i.admin_down()
52 super(TestL2Flood, self).tearDown()
53
54 def test_flood(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020055 """L2 Flood Tests"""
Neale Ranns055b2312018-07-20 01:16:04 -070056
57 #
58 # Create a single bridge Domain
59 #
Ole Troana5b2eec2019-03-11 19:23:25 +010060 self.vapi.bridge_domain_add_del(bd_id=1)
Neale Ranns055b2312018-07-20 01:16:04 -070061
62 #
63 # add each interface to the BD. 3 interfaces per split horizon group
64 #
65 for i in self.pg_interfaces[0:4]:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020066 self.vapi.sw_interface_set_l2_bridge(
67 rx_sw_if_index=i.sw_if_index, bd_id=1, shg=0
68 )
Neale Ranns055b2312018-07-20 01:16:04 -070069 for i in self.pg_interfaces[4:8]:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020070 self.vapi.sw_interface_set_l2_bridge(
71 rx_sw_if_index=i.sw_if_index, bd_id=1, shg=1
72 )
Neale Ranns055b2312018-07-20 01:16:04 -070073 for i in self.pg_interfaces[8:12]:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020074 self.vapi.sw_interface_set_l2_bridge(
75 rx_sw_if_index=i.sw_if_index, bd_id=1, shg=2
76 )
Neale Ranns192b13f2019-03-15 02:16:20 -070077 for i in self.bvi_interfaces:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020078 self.vapi.sw_interface_set_l2_bridge(
79 rx_sw_if_index=i.sw_if_index, bd_id=1, shg=2, port_type=L2_PORT_TYPE.BVI
80 )
Neale Ranns055b2312018-07-20 01:16:04 -070081
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020082 p = (
83 Ether(dst="ff:ff:ff:ff:ff:ff", src="00:00:de:ad:be:ef")
84 / IP(src="10.10.10.10", dst="1.1.1.1")
85 / UDP(sport=1234, dport=1234)
86 / Raw(b"\xa5" * 100)
87 )
Neale Ranns055b2312018-07-20 01:16:04 -070088
89 #
90 # input on pg0 expect copies on pg1->11
91 # this is in SHG=0 so its flooded to all, expect the pg0 since that's
92 # the ingress link
93 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020094 self.pg0.add_stream(p * NUM_PKTS)
Neale Ranns055b2312018-07-20 01:16:04 -070095 self.pg_enable_capture(self.pg_interfaces)
96 self.pg_start()
97
98 for i in self.pg_interfaces[1:12]:
Paul Vinciguerra4271c972019-05-14 13:25:49 -040099 rx0 = i.get_capture(NUM_PKTS, timeout=1)
Neale Ranns055b2312018-07-20 01:16:04 -0700100
Neale Ranns055b2312018-07-20 01:16:04 -0700101 #
102 # input on pg4 (SHG=1) expect copies on pg0->3 (SHG=0)
103 # and pg8->11 (SHG=2)
104 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200105 self.pg4.add_stream(p * NUM_PKTS)
Neale Ranns055b2312018-07-20 01:16:04 -0700106 self.pg_enable_capture(self.pg_interfaces)
107 self.pg_start()
108
109 for i in self.pg_interfaces[:4]:
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400110 rx0 = i.get_capture(NUM_PKTS, timeout=1)
Neale Ranns055b2312018-07-20 01:16:04 -0700111 for i in self.pg_interfaces[8:12]:
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400112 rx0 = i.get_capture(NUM_PKTS, timeout=1)
Neale Ranns055b2312018-07-20 01:16:04 -0700113 for i in self.pg_interfaces[4:8]:
114 i.assert_nothing_captured(remark="Different SH group")
115
116 #
117 # An IP route so the packet that hits the BVI is sent out of pg12
118 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200119 ip_route = VppIpRoute(
120 self,
121 "1.1.1.1",
122 32,
123 [VppRoutePath(self.pg12.remote_ip4, self.pg12.sw_if_index)],
124 )
Neale Ranns055b2312018-07-20 01:16:04 -0700125 ip_route.add_vpp_config()
126
127 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
128
129 #
130 # input on pg0 expect copies on pg1->12
131 # this is in SHG=0 so its flooded to all, expect the pg0 since that's
132 # the ingress link
133 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200134 self.pg0.add_stream(p * NUM_PKTS)
Neale Ranns055b2312018-07-20 01:16:04 -0700135 self.pg_enable_capture(self.pg_interfaces)
136 self.pg_start()
137
138 for i in self.pg_interfaces[1:]:
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400139 rx0 = i.get_capture(NUM_PKTS, timeout=1)
Neale Ranns055b2312018-07-20 01:16:04 -0700140
141 #
142 # input on pg4 (SHG=1) expect copies on pg0->3 (SHG=0)
143 # and pg8->12 (SHG=2)
144 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200145 self.pg4.add_stream(p * NUM_PKTS)
Neale Ranns055b2312018-07-20 01:16:04 -0700146 self.pg_enable_capture(self.pg_interfaces)
147 self.pg_start()
148
149 for i in self.pg_interfaces[:4]:
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400150 rx0 = i.get_capture(NUM_PKTS, timeout=1)
Neale Ranns055b2312018-07-20 01:16:04 -0700151 for i in self.pg_interfaces[8:13]:
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400152 rx0 = i.get_capture(NUM_PKTS, timeout=1)
Neale Ranns055b2312018-07-20 01:16:04 -0700153 for i in self.pg_interfaces[4:8]:
154 i.assert_nothing_captured(remark="Different SH group")
155
156 #
157 # cleanup
158 #
159 for i in self.pg_interfaces[:12]:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200160 self.vapi.sw_interface_set_l2_bridge(
161 rx_sw_if_index=i.sw_if_index, bd_id=1, enable=0
162 )
Neale Ranns192b13f2019-03-15 02:16:20 -0700163 for i in self.bvi_interfaces:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200164 self.vapi.sw_interface_set_l2_bridge(
165 rx_sw_if_index=i.sw_if_index,
166 bd_id=1,
167 shg=2,
168 port_type=L2_PORT_TYPE.BVI,
169 enable=0,
170 )
Neale Rannsb4743802018-09-05 09:13:57 -0700171
Ole Troana5b2eec2019-03-11 19:23:25 +0100172 self.vapi.bridge_domain_add_del(bd_id=1, is_add=0)
Neale Rannsb4743802018-09-05 09:13:57 -0700173
Neale Rannsb9fa29d2018-10-02 07:27:02 -0700174 def test_flood_one(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200175 """L2 no-Flood Test"""
Neale Rannsb9fa29d2018-10-02 07:27:02 -0700176
177 #
178 # Create a single bridge Domain
179 #
Ole Troana5b2eec2019-03-11 19:23:25 +0100180 self.vapi.bridge_domain_add_del(bd_id=1)
Neale Rannsb9fa29d2018-10-02 07:27:02 -0700181
182 #
183 # add 2 interfaces to the BD. this means a flood goes to only
184 # one member
185 #
186 for i in self.pg_interfaces[:2]:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200187 self.vapi.sw_interface_set_l2_bridge(
188 rx_sw_if_index=i.sw_if_index, bd_id=1, shg=0
189 )
Neale Rannsb9fa29d2018-10-02 07:27:02 -0700190
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200191 p = (
192 Ether(dst="ff:ff:ff:ff:ff:ff", src="00:00:de:ad:be:ef")
193 / IP(src="10.10.10.10", dst="1.1.1.1")
194 / UDP(sport=1234, dport=1234)
195 / Raw(b"\xa5" * 100)
196 )
Neale Rannsb9fa29d2018-10-02 07:27:02 -0700197
198 #
199 # input on pg0 expect copies on pg1
200 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200201 self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg1)
Neale Rannsb9fa29d2018-10-02 07:27:02 -0700202
203 #
204 # cleanup
205 #
206 for i in self.pg_interfaces[:2]:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200207 self.vapi.sw_interface_set_l2_bridge(
208 rx_sw_if_index=i.sw_if_index, bd_id=1, enable=0
209 )
Ole Troana5b2eec2019-03-11 19:23:25 +0100210 self.vapi.bridge_domain_add_del(bd_id=1, is_add=0)
Neale Rannsb9fa29d2018-10-02 07:27:02 -0700211
Neale Rannsb4743802018-09-05 09:13:57 -0700212 def test_uu_fwd(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200213 """UU Flood"""
Neale Rannsb4743802018-09-05 09:13:57 -0700214
215 #
216 # Create a single bridge Domain
217 #
Ole Troana5b2eec2019-03-11 19:23:25 +0100218 self.vapi.bridge_domain_add_del(bd_id=1, uu_flood=1)
Neale Rannsb4743802018-09-05 09:13:57 -0700219
220 #
221 # add each interface to the BD. 3 interfaces per split horizon group
222 #
223 for i in self.pg_interfaces[0:4]:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200224 self.vapi.sw_interface_set_l2_bridge(
225 rx_sw_if_index=i.sw_if_index, bd_id=1, shg=0
226 )
Neale Rannsb4743802018-09-05 09:13:57 -0700227
228 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700229 # an unknown unicast and broadcast packets
Neale Rannsb4743802018-09-05 09:13:57 -0700230 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200231 p_uu = (
232 Ether(dst="00:00:00:c1:5c:00", src="00:00:de:ad:be:ef")
233 / IP(src="10.10.10.10", dst="1.1.1.1")
234 / UDP(sport=1234, dport=1234)
235 / Raw(b"\xa5" * 100)
236 )
237 p_bm = (
238 Ether(dst="ff:ff:ff:ff:ff:ff", src="00:00:de:ad:be:ef")
239 / IP(src="10.10.10.10", dst="1.1.1.1")
240 / UDP(sport=1234, dport=1234)
241 / Raw(b"\xa5" * 100)
242 )
Neale Rannsb4743802018-09-05 09:13:57 -0700243
244 #
245 # input on pg0, expected copies on pg1->4
246 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200247 self.pg0.add_stream(p_uu * NUM_PKTS)
Neale Rannsb4743802018-09-05 09:13:57 -0700248 self.pg_enable_capture(self.pg_interfaces)
249 self.pg_start()
250
251 for i in self.pg_interfaces[1:4]:
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400252 rx0 = i.get_capture(NUM_PKTS, timeout=1)
Neale Rannsb4743802018-09-05 09:13:57 -0700253
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200254 self.pg0.add_stream(p_bm * NUM_PKTS)
Neale Rannsd29cc882018-10-10 15:55:01 +0000255 self.pg_enable_capture(self.pg_interfaces)
256 self.pg_start()
257
258 for i in self.pg_interfaces[1:4]:
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400259 rx0 = i.get_capture(NUM_PKTS, timeout=1)
Neale Rannsd29cc882018-10-10 15:55:01 +0000260
Neale Rannsb4743802018-09-05 09:13:57 -0700261 #
262 # use pg8 as the uu-fwd interface
263 #
Ole Troana5b2eec2019-03-11 19:23:25 +0100264 self.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200265 rx_sw_if_index=self.pg8.sw_if_index,
266 bd_id=1,
267 shg=0,
268 port_type=L2_PORT_TYPE.UU_FWD,
269 )
Neale Rannsb4743802018-09-05 09:13:57 -0700270
271 #
272 # expect the UU packet on the uu-fwd interface and not be flooded
273 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200274 self.pg0.add_stream(p_uu * NUM_PKTS)
Neale Rannsb4743802018-09-05 09:13:57 -0700275 self.pg_enable_capture(self.pg_interfaces)
276 self.pg_start()
277
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400278 rx0 = self.pg8.get_capture(NUM_PKTS, timeout=1)
Neale Rannsb4743802018-09-05 09:13:57 -0700279
280 for i in self.pg_interfaces[0:4]:
281 i.assert_nothing_captured(remark="UU not flooded")
282
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200283 self.pg0.add_stream(p_bm * NUM_PKTS)
Neale Rannsd29cc882018-10-10 15:55:01 +0000284 self.pg_enable_capture(self.pg_interfaces)
285 self.pg_start()
286
287 for i in self.pg_interfaces[1:4]:
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400288 rx0 = i.get_capture(NUM_PKTS, timeout=1)
Neale Rannsd29cc882018-10-10 15:55:01 +0000289
Neale Rannsb4743802018-09-05 09:13:57 -0700290 #
291 # remove the uu-fwd interface and expect UU to be flooded again
292 #
Ole Troana5b2eec2019-03-11 19:23:25 +0100293 self.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200294 rx_sw_if_index=self.pg8.sw_if_index,
295 bd_id=1,
296 shg=0,
297 port_type=L2_PORT_TYPE.UU_FWD,
298 enable=0,
299 )
Neale Rannsb4743802018-09-05 09:13:57 -0700300
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200301 self.pg0.add_stream(p_uu * NUM_PKTS)
Neale Rannsb4743802018-09-05 09:13:57 -0700302 self.pg_enable_capture(self.pg_interfaces)
303 self.pg_start()
304
305 for i in self.pg_interfaces[1:4]:
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400306 rx0 = i.get_capture(NUM_PKTS, timeout=1)
Neale Rannsb4743802018-09-05 09:13:57 -0700307
308 #
309 # change the BD config to not support UU-flood
310 #
Ole Troana5b2eec2019-03-11 19:23:25 +0100311 self.vapi.bridge_flags(bd_id=1, is_set=0, flags=BRIDGE_FLAGS.UU_FLOOD)
Neale Rannsb4743802018-09-05 09:13:57 -0700312
313 self.send_and_assert_no_replies(self.pg0, p_uu)
314
315 #
316 # re-add the uu-fwd interface
317 #
Ole Troana5b2eec2019-03-11 19:23:25 +0100318 self.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200319 rx_sw_if_index=self.pg8.sw_if_index,
320 bd_id=1,
321 shg=0,
322 port_type=L2_PORT_TYPE.UU_FWD,
323 )
Neale Rannsb4743802018-09-05 09:13:57 -0700324 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
325
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200326 self.pg0.add_stream(p_uu * NUM_PKTS)
Neale Rannsb4743802018-09-05 09:13:57 -0700327 self.pg_enable_capture(self.pg_interfaces)
328 self.pg_start()
329
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400330 rx0 = self.pg8.get_capture(NUM_PKTS, timeout=1)
Neale Rannsb4743802018-09-05 09:13:57 -0700331
332 for i in self.pg_interfaces[0:4]:
333 i.assert_nothing_captured(remark="UU not flooded")
334
335 #
336 # remove the uu-fwd interface
337 #
Ole Troana5b2eec2019-03-11 19:23:25 +0100338 self.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200339 rx_sw_if_index=self.pg8.sw_if_index,
340 bd_id=1,
341 shg=0,
342 port_type=L2_PORT_TYPE.UU_FWD,
343 enable=0,
344 )
Neale Rannsb4743802018-09-05 09:13:57 -0700345 self.send_and_assert_no_replies(self.pg0, p_uu)
346
347 #
348 # cleanup
349 #
350 for i in self.pg_interfaces[:4]:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200351 self.vapi.sw_interface_set_l2_bridge(
352 rx_sw_if_index=i.sw_if_index, bd_id=1, enable=0
353 )
Neale Ranns055b2312018-07-20 01:16:04 -0700354
Ole Troana5b2eec2019-03-11 19:23:25 +0100355 self.vapi.bridge_domain_add_del(bd_id=1, is_add=0)
Neale Ranns055b2312018-07-20 01:16:04 -0700356
357
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200358if __name__ == "__main__":
Neale Ranns055b2312018-07-20 01:16:04 -0700359 unittest.main(testRunner=VppTestRunner)