6 from framework import VppTestCase, VppTestRunner
7 from vpp_ip_route import VppIpRoute, VppRoutePath
8 from vpp_l2 import L2_PORT_TYPE, BRIDGE_FLAGS
10 from scapy.packet import Raw
11 from scapy.layers.l2 import Ether
12 from scapy.layers.inet import IP, UDP
15 class TestL2Flood(VppTestCase):
20 super(TestL2Flood, cls).setUpClass()
23 def tearDownClass(cls):
24 super(TestL2Flood, cls).tearDownClass()
27 super(TestL2Flood, self).setUp()
29 # 12 l2 interface and one l3
30 self.create_pg_interfaces(range(13))
31 self.create_bvi_interfaces(1)
33 for i in self.pg_interfaces:
35 for i in self.bvi_interfaces:
38 self.pg12.config_ip4()
39 self.pg12.resolve_arp()
40 self.bvi0.config_ip4()
43 self.pg12.unconfig_ip4()
44 self.bvi0.unconfig_ip4()
46 for i in self.pg_interfaces:
48 for i in self.bvi_interfaces:
50 super(TestL2Flood, self).tearDown()
53 """ L2 Flood Tests """
56 # Create a single bridge Domain
58 self.vapi.bridge_domain_add_del(bd_id=1)
61 # add each interface to the BD. 3 interfaces per split horizon group
63 for i in self.pg_interfaces[0:4]:
64 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
66 for i in self.pg_interfaces[4:8]:
67 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
69 for i in self.pg_interfaces[8:12]:
70 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
72 for i in self.bvi_interfaces:
73 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
75 port_type=L2_PORT_TYPE.BVI)
77 p = (Ether(dst="ff:ff:ff:ff:ff:ff",
78 src="00:00:de:ad:be:ef") /
79 IP(src="10.10.10.10", dst="1.1.1.1") /
80 UDP(sport=1234, dport=1234) /
84 # input on pg0 expect copies on pg1->11
85 # this is in SHG=0 so its flooded to all, expect the pg0 since that's
88 self.pg0.add_stream(p*65)
89 self.pg_enable_capture(self.pg_interfaces)
92 for i in self.pg_interfaces[1:12]:
93 rx0 = i.get_capture(65, timeout=1)
96 # input on pg4 (SHG=1) expect copies on pg0->3 (SHG=0)
99 self.pg4.add_stream(p*65)
100 self.pg_enable_capture(self.pg_interfaces)
103 for i in self.pg_interfaces[:4]:
104 rx0 = i.get_capture(65, timeout=1)
105 for i in self.pg_interfaces[8:12]:
106 rx0 = i.get_capture(65, timeout=1)
107 for i in self.pg_interfaces[4:8]:
108 i.assert_nothing_captured(remark="Different SH group")
111 # An IP route so the packet that hits the BVI is sent out of pg12
113 ip_route = VppIpRoute(self, "1.1.1.1", 32,
114 [VppRoutePath(self.pg12.remote_ip4,
115 self.pg12.sw_if_index)])
116 ip_route.add_vpp_config()
118 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
121 # input on pg0 expect copies on pg1->12
122 # this is in SHG=0 so its flooded to all, expect the pg0 since that's
125 self.pg0.add_stream(p*65)
126 self.pg_enable_capture(self.pg_interfaces)
129 for i in self.pg_interfaces[1:]:
130 rx0 = i.get_capture(65, timeout=1)
133 # input on pg4 (SHG=1) expect copies on pg0->3 (SHG=0)
134 # and pg8->12 (SHG=2)
136 self.pg4.add_stream(p*65)
137 self.pg_enable_capture(self.pg_interfaces)
140 for i in self.pg_interfaces[:4]:
141 rx0 = i.get_capture(65, timeout=1)
142 for i in self.pg_interfaces[8:13]:
143 rx0 = i.get_capture(65, timeout=1)
144 for i in self.pg_interfaces[4:8]:
145 i.assert_nothing_captured(remark="Different SH group")
150 for i in self.pg_interfaces[:12]:
151 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
153 for i in self.bvi_interfaces:
154 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
156 port_type=L2_PORT_TYPE.BVI,
159 self.vapi.bridge_domain_add_del(bd_id=1, is_add=0)
161 def test_flood_one(self):
162 """ L2 no-Flood Test """
165 # Create a single bridge Domain
167 self.vapi.bridge_domain_add_del(bd_id=1)
170 # add 2 interfaces to the BD. this means a flood goes to only
173 for i in self.pg_interfaces[:2]:
174 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
177 p = (Ether(dst="ff:ff:ff:ff:ff:ff",
178 src="00:00:de:ad:be:ef") /
179 IP(src="10.10.10.10", dst="1.1.1.1") /
180 UDP(sport=1234, dport=1234) /
184 # input on pg0 expect copies on pg1
186 self.send_and_expect(self.pg0, p*65, self.pg1)
191 for i in self.pg_interfaces[:2]:
192 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
194 self.vapi.bridge_domain_add_del(bd_id=1, is_add=0)
196 def test_uu_fwd(self):
200 # Create a single bridge Domain
202 self.vapi.bridge_domain_add_del(bd_id=1, uu_flood=1)
205 # add each interface to the BD. 3 interfaces per split horizon group
207 for i in self.pg_interfaces[0:4]:
208 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
212 # an unknown unicast and broadcast packets
214 p_uu = (Ether(dst="00:00:00:c1:5c:00",
215 src="00:00:de:ad:be:ef") /
216 IP(src="10.10.10.10", dst="1.1.1.1") /
217 UDP(sport=1234, dport=1234) /
219 p_bm = (Ether(dst="ff:ff:ff:ff:ff:ff",
220 src="00:00:de:ad:be:ef") /
221 IP(src="10.10.10.10", dst="1.1.1.1") /
222 UDP(sport=1234, dport=1234) /
226 # input on pg0, expected copies on pg1->4
228 self.pg0.add_stream(p_uu*65)
229 self.pg_enable_capture(self.pg_interfaces)
232 for i in self.pg_interfaces[1:4]:
233 rx0 = i.get_capture(65, timeout=1)
235 self.pg0.add_stream(p_bm*65)
236 self.pg_enable_capture(self.pg_interfaces)
239 for i in self.pg_interfaces[1:4]:
240 rx0 = i.get_capture(65, timeout=1)
243 # use pg8 as the uu-fwd interface
245 self.vapi.sw_interface_set_l2_bridge(
246 rx_sw_if_index=self.pg8.sw_if_index, bd_id=1, shg=0,
247 port_type=L2_PORT_TYPE.UU_FWD)
250 # expect the UU packet on the uu-fwd interface and not be flooded
252 self.pg0.add_stream(p_uu*65)
253 self.pg_enable_capture(self.pg_interfaces)
256 rx0 = self.pg8.get_capture(65, timeout=1)
258 for i in self.pg_interfaces[0:4]:
259 i.assert_nothing_captured(remark="UU not flooded")
261 self.pg0.add_stream(p_bm*65)
262 self.pg_enable_capture(self.pg_interfaces)
265 for i in self.pg_interfaces[1:4]:
266 rx0 = i.get_capture(65, timeout=1)
269 # remove the uu-fwd interface and expect UU to be flooded again
271 self.vapi.sw_interface_set_l2_bridge(
272 rx_sw_if_index=self.pg8.sw_if_index, bd_id=1, shg=0,
273 port_type=L2_PORT_TYPE.UU_FWD, enable=0)
275 self.pg0.add_stream(p_uu*65)
276 self.pg_enable_capture(self.pg_interfaces)
279 for i in self.pg_interfaces[1:4]:
280 rx0 = i.get_capture(65, timeout=1)
283 # change the BD config to not support UU-flood
285 self.vapi.bridge_flags(bd_id=1, is_set=0, flags=BRIDGE_FLAGS.UU_FLOOD)
287 self.send_and_assert_no_replies(self.pg0, p_uu)
290 # re-add the uu-fwd interface
292 self.vapi.sw_interface_set_l2_bridge(
293 rx_sw_if_index=self.pg8.sw_if_index, bd_id=1, shg=0,
294 port_type=L2_PORT_TYPE.UU_FWD)
295 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
297 self.pg0.add_stream(p_uu*65)
298 self.pg_enable_capture(self.pg_interfaces)
301 rx0 = self.pg8.get_capture(65, timeout=1)
303 for i in self.pg_interfaces[0:4]:
304 i.assert_nothing_captured(remark="UU not flooded")
307 # remove the uu-fwd interface
309 self.vapi.sw_interface_set_l2_bridge(
310 rx_sw_if_index=self.pg8.sw_if_index, bd_id=1, shg=0,
311 port_type=L2_PORT_TYPE.UU_FWD, enable=0)
312 self.send_and_assert_no_replies(self.pg0, p_uu)
317 for i in self.pg_interfaces[:4]:
318 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
321 self.vapi.bridge_domain_add_del(bd_id=1, is_add=0)
324 if __name__ == '__main__':
325 unittest.main(testRunner=VppTestRunner)