blob: 9e77fa172664e953ece18a41af75cb15ba9de0b8 [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 #
Laszlo Kiraly0f8f4352022-09-16 13:20:07 +020060 self.vapi.bridge_domain_add_del_v2(
61 bd_id=1, is_add=1, flood=1, uu_flood=1, forward=1, learn=1
62 )
Neale Ranns055b2312018-07-20 01:16:04 -070063
64 #
65 # add each interface to the BD. 3 interfaces per split horizon group
66 #
67 for i in self.pg_interfaces[0:4]:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020068 self.vapi.sw_interface_set_l2_bridge(
69 rx_sw_if_index=i.sw_if_index, bd_id=1, shg=0
70 )
Neale Ranns055b2312018-07-20 01:16:04 -070071 for i in self.pg_interfaces[4:8]:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020072 self.vapi.sw_interface_set_l2_bridge(
73 rx_sw_if_index=i.sw_if_index, bd_id=1, shg=1
74 )
Neale Ranns055b2312018-07-20 01:16:04 -070075 for i in self.pg_interfaces[8:12]:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020076 self.vapi.sw_interface_set_l2_bridge(
77 rx_sw_if_index=i.sw_if_index, bd_id=1, shg=2
78 )
Neale Ranns192b13f2019-03-15 02:16:20 -070079 for i in self.bvi_interfaces:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020080 self.vapi.sw_interface_set_l2_bridge(
81 rx_sw_if_index=i.sw_if_index, bd_id=1, shg=2, port_type=L2_PORT_TYPE.BVI
82 )
Neale Ranns055b2312018-07-20 01:16:04 -070083
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020084 p = (
85 Ether(dst="ff:ff:ff:ff:ff:ff", src="00:00:de:ad:be:ef")
86 / IP(src="10.10.10.10", dst="1.1.1.1")
87 / UDP(sport=1234, dport=1234)
88 / Raw(b"\xa5" * 100)
89 )
Neale Ranns055b2312018-07-20 01:16:04 -070090
91 #
92 # input on pg0 expect copies on pg1->11
93 # this is in SHG=0 so its flooded to all, expect the pg0 since that's
94 # the ingress link
95 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020096 self.pg0.add_stream(p * NUM_PKTS)
Neale Ranns055b2312018-07-20 01:16:04 -070097 self.pg_enable_capture(self.pg_interfaces)
98 self.pg_start()
99
100 for i in self.pg_interfaces[1:12]:
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400101 rx0 = i.get_capture(NUM_PKTS, timeout=1)
Neale Ranns055b2312018-07-20 01:16:04 -0700102
Neale Ranns055b2312018-07-20 01:16:04 -0700103 #
104 # input on pg4 (SHG=1) expect copies on pg0->3 (SHG=0)
105 # and pg8->11 (SHG=2)
106 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200107 self.pg4.add_stream(p * NUM_PKTS)
Neale Ranns055b2312018-07-20 01:16:04 -0700108 self.pg_enable_capture(self.pg_interfaces)
109 self.pg_start()
110
111 for i in self.pg_interfaces[:4]:
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[8:12]:
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400114 rx0 = i.get_capture(NUM_PKTS, timeout=1)
Neale Ranns055b2312018-07-20 01:16:04 -0700115 for i in self.pg_interfaces[4:8]:
116 i.assert_nothing_captured(remark="Different SH group")
117
118 #
119 # An IP route so the packet that hits the BVI is sent out of pg12
120 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200121 ip_route = VppIpRoute(
122 self,
123 "1.1.1.1",
124 32,
125 [VppRoutePath(self.pg12.remote_ip4, self.pg12.sw_if_index)],
126 )
Neale Ranns055b2312018-07-20 01:16:04 -0700127 ip_route.add_vpp_config()
128
129 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
130
131 #
132 # input on pg0 expect copies on pg1->12
133 # this is in SHG=0 so its flooded to all, expect the pg0 since that's
134 # the ingress link
135 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200136 self.pg0.add_stream(p * NUM_PKTS)
Neale Ranns055b2312018-07-20 01:16:04 -0700137 self.pg_enable_capture(self.pg_interfaces)
138 self.pg_start()
139
140 for i in self.pg_interfaces[1:]:
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400141 rx0 = i.get_capture(NUM_PKTS, timeout=1)
Neale Ranns055b2312018-07-20 01:16:04 -0700142
143 #
144 # input on pg4 (SHG=1) expect copies on pg0->3 (SHG=0)
145 # and pg8->12 (SHG=2)
146 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200147 self.pg4.add_stream(p * NUM_PKTS)
Neale Ranns055b2312018-07-20 01:16:04 -0700148 self.pg_enable_capture(self.pg_interfaces)
149 self.pg_start()
150
151 for i in self.pg_interfaces[:4]:
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[8:13]:
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400154 rx0 = i.get_capture(NUM_PKTS, timeout=1)
Neale Ranns055b2312018-07-20 01:16:04 -0700155 for i in self.pg_interfaces[4:8]:
156 i.assert_nothing_captured(remark="Different SH group")
157
158 #
159 # cleanup
160 #
161 for i in self.pg_interfaces[:12]:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200162 self.vapi.sw_interface_set_l2_bridge(
163 rx_sw_if_index=i.sw_if_index, bd_id=1, enable=0
164 )
Neale Ranns192b13f2019-03-15 02:16:20 -0700165 for i in self.bvi_interfaces:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200166 self.vapi.sw_interface_set_l2_bridge(
167 rx_sw_if_index=i.sw_if_index,
168 bd_id=1,
169 shg=2,
170 port_type=L2_PORT_TYPE.BVI,
171 enable=0,
172 )
Neale Rannsb4743802018-09-05 09:13:57 -0700173
Laszlo Kiraly0f8f4352022-09-16 13:20:07 +0200174 self.vapi.bridge_domain_add_del_v2(bd_id=1, is_add=0)
Neale Rannsb4743802018-09-05 09:13:57 -0700175
Neale Rannsb9fa29d2018-10-02 07:27:02 -0700176 def test_flood_one(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200177 """L2 no-Flood Test"""
Neale Rannsb9fa29d2018-10-02 07:27:02 -0700178
179 #
180 # Create a single bridge Domain
181 #
Laszlo Kiraly0f8f4352022-09-16 13:20:07 +0200182 self.vapi.bridge_domain_add_del_v2(
183 bd_id=1, is_add=1, flood=1, uu_flood=1, forward=1, learn=1
184 )
Neale Rannsb9fa29d2018-10-02 07:27:02 -0700185
186 #
187 # add 2 interfaces to the BD. this means a flood goes to only
188 # one member
189 #
190 for i in self.pg_interfaces[:2]:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200191 self.vapi.sw_interface_set_l2_bridge(
192 rx_sw_if_index=i.sw_if_index, bd_id=1, shg=0
193 )
Neale Rannsb9fa29d2018-10-02 07:27:02 -0700194
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200195 p = (
196 Ether(dst="ff:ff:ff:ff:ff:ff", src="00:00:de:ad:be:ef")
197 / IP(src="10.10.10.10", dst="1.1.1.1")
198 / UDP(sport=1234, dport=1234)
199 / Raw(b"\xa5" * 100)
200 )
Neale Rannsb9fa29d2018-10-02 07:27:02 -0700201
202 #
203 # input on pg0 expect copies on pg1
204 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200205 self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg1)
Neale Rannsb9fa29d2018-10-02 07:27:02 -0700206
207 #
208 # cleanup
209 #
210 for i in self.pg_interfaces[:2]:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200211 self.vapi.sw_interface_set_l2_bridge(
212 rx_sw_if_index=i.sw_if_index, bd_id=1, enable=0
213 )
Laszlo Kiraly0f8f4352022-09-16 13:20:07 +0200214 self.vapi.bridge_domain_add_del_v2(bd_id=1, is_add=0)
Neale Rannsb9fa29d2018-10-02 07:27:02 -0700215
Neale Rannsb4743802018-09-05 09:13:57 -0700216 def test_uu_fwd(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200217 """UU Flood"""
Neale Rannsb4743802018-09-05 09:13:57 -0700218
219 #
220 # Create a single bridge Domain
221 #
Laszlo Kiraly0f8f4352022-09-16 13:20:07 +0200222 self.vapi.bridge_domain_add_del_v2(
223 bd_id=1, is_add=1, uu_flood=1, flood=1, forward=1, learn=1
224 )
Neale Rannsb4743802018-09-05 09:13:57 -0700225
226 #
227 # add each interface to the BD. 3 interfaces per split horizon group
228 #
229 for i in self.pg_interfaces[0:4]:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200230 self.vapi.sw_interface_set_l2_bridge(
231 rx_sw_if_index=i.sw_if_index, bd_id=1, shg=0
232 )
Neale Rannsb4743802018-09-05 09:13:57 -0700233
234 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700235 # an unknown unicast and broadcast packets
Neale Rannsb4743802018-09-05 09:13:57 -0700236 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200237 p_uu = (
238 Ether(dst="00:00:00:c1:5c:00", 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 )
243 p_bm = (
244 Ether(dst="ff:ff:ff:ff:ff:ff", src="00:00:de:ad:be:ef")
245 / IP(src="10.10.10.10", dst="1.1.1.1")
246 / UDP(sport=1234, dport=1234)
247 / Raw(b"\xa5" * 100)
248 )
Neale Rannsb4743802018-09-05 09:13:57 -0700249
250 #
251 # input on pg0, expected copies on pg1->4
252 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200253 self.pg0.add_stream(p_uu * NUM_PKTS)
Neale Rannsb4743802018-09-05 09:13:57 -0700254 self.pg_enable_capture(self.pg_interfaces)
255 self.pg_start()
256
257 for i in self.pg_interfaces[1:4]:
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400258 rx0 = i.get_capture(NUM_PKTS, timeout=1)
Neale Rannsb4743802018-09-05 09:13:57 -0700259
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200260 self.pg0.add_stream(p_bm * NUM_PKTS)
Neale Rannsd29cc882018-10-10 15:55:01 +0000261 self.pg_enable_capture(self.pg_interfaces)
262 self.pg_start()
263
264 for i in self.pg_interfaces[1:4]:
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400265 rx0 = i.get_capture(NUM_PKTS, timeout=1)
Neale Rannsd29cc882018-10-10 15:55:01 +0000266
Neale Rannsb4743802018-09-05 09:13:57 -0700267 #
268 # use pg8 as the uu-fwd interface
269 #
Ole Troana5b2eec2019-03-11 19:23:25 +0100270 self.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200271 rx_sw_if_index=self.pg8.sw_if_index,
272 bd_id=1,
273 shg=0,
274 port_type=L2_PORT_TYPE.UU_FWD,
275 )
Neale Rannsb4743802018-09-05 09:13:57 -0700276
277 #
278 # expect the UU packet on the uu-fwd interface and not be flooded
279 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200280 self.pg0.add_stream(p_uu * NUM_PKTS)
Neale Rannsb4743802018-09-05 09:13:57 -0700281 self.pg_enable_capture(self.pg_interfaces)
282 self.pg_start()
283
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400284 rx0 = self.pg8.get_capture(NUM_PKTS, timeout=1)
Neale Rannsb4743802018-09-05 09:13:57 -0700285
286 for i in self.pg_interfaces[0:4]:
287 i.assert_nothing_captured(remark="UU not flooded")
288
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200289 self.pg0.add_stream(p_bm * NUM_PKTS)
Neale Rannsd29cc882018-10-10 15:55:01 +0000290 self.pg_enable_capture(self.pg_interfaces)
291 self.pg_start()
292
293 for i in self.pg_interfaces[1:4]:
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400294 rx0 = i.get_capture(NUM_PKTS, timeout=1)
Neale Rannsd29cc882018-10-10 15:55:01 +0000295
Neale Rannsb4743802018-09-05 09:13:57 -0700296 #
297 # remove the uu-fwd interface and expect UU to be flooded again
298 #
Ole Troana5b2eec2019-03-11 19:23:25 +0100299 self.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200300 rx_sw_if_index=self.pg8.sw_if_index,
301 bd_id=1,
302 shg=0,
303 port_type=L2_PORT_TYPE.UU_FWD,
304 enable=0,
305 )
Neale Rannsb4743802018-09-05 09:13:57 -0700306
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200307 self.pg0.add_stream(p_uu * NUM_PKTS)
Neale Rannsb4743802018-09-05 09:13:57 -0700308 self.pg_enable_capture(self.pg_interfaces)
309 self.pg_start()
310
311 for i in self.pg_interfaces[1:4]:
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400312 rx0 = i.get_capture(NUM_PKTS, timeout=1)
Neale Rannsb4743802018-09-05 09:13:57 -0700313
314 #
315 # change the BD config to not support UU-flood
316 #
Ole Troana5b2eec2019-03-11 19:23:25 +0100317 self.vapi.bridge_flags(bd_id=1, is_set=0, flags=BRIDGE_FLAGS.UU_FLOOD)
Neale Rannsb4743802018-09-05 09:13:57 -0700318
319 self.send_and_assert_no_replies(self.pg0, p_uu)
320
321 #
322 # re-add the uu-fwd interface
323 #
Ole Troana5b2eec2019-03-11 19:23:25 +0100324 self.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200325 rx_sw_if_index=self.pg8.sw_if_index,
326 bd_id=1,
327 shg=0,
328 port_type=L2_PORT_TYPE.UU_FWD,
329 )
Neale Rannsb4743802018-09-05 09:13:57 -0700330 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
331
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200332 self.pg0.add_stream(p_uu * NUM_PKTS)
Neale Rannsb4743802018-09-05 09:13:57 -0700333 self.pg_enable_capture(self.pg_interfaces)
334 self.pg_start()
335
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400336 rx0 = self.pg8.get_capture(NUM_PKTS, timeout=1)
Neale Rannsb4743802018-09-05 09:13:57 -0700337
338 for i in self.pg_interfaces[0:4]:
339 i.assert_nothing_captured(remark="UU not flooded")
340
341 #
342 # remove the uu-fwd interface
343 #
Ole Troana5b2eec2019-03-11 19:23:25 +0100344 self.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200345 rx_sw_if_index=self.pg8.sw_if_index,
346 bd_id=1,
347 shg=0,
348 port_type=L2_PORT_TYPE.UU_FWD,
349 enable=0,
350 )
Neale Rannsb4743802018-09-05 09:13:57 -0700351 self.send_and_assert_no_replies(self.pg0, p_uu)
352
353 #
354 # cleanup
355 #
356 for i in self.pg_interfaces[:4]:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200357 self.vapi.sw_interface_set_l2_bridge(
358 rx_sw_if_index=i.sw_if_index, bd_id=1, enable=0
359 )
Neale Ranns055b2312018-07-20 01:16:04 -0700360
Laszlo Kiraly0f8f4352022-09-16 13:20:07 +0200361 self.vapi.bridge_domain_add_del_v2(bd_id=1, is_add=0)
Neale Ranns055b2312018-07-20 01:16:04 -0700362
363
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200364if __name__ == "__main__":
Neale Ranns055b2312018-07-20 01:16:04 -0700365 unittest.main(testRunner=VppTestRunner)