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
17 class TestL2Flood(VppTestCase):
22 super(TestL2Flood, cls).setUpClass()
25 def tearDownClass(cls):
26 super(TestL2Flood, cls).tearDownClass()
29 super(TestL2Flood, self).setUp()
31 # 12 l2 interface and one l3
32 self.create_pg_interfaces(range(13))
33 self.create_bvi_interfaces(1)
35 for i in self.pg_interfaces:
37 for i in self.bvi_interfaces:
40 self.pg12.config_ip4()
41 self.pg12.resolve_arp()
42 self.bvi0.config_ip4()
45 self.pg12.unconfig_ip4()
46 self.bvi0.unconfig_ip4()
48 for i in self.pg_interfaces:
50 for i in self.bvi_interfaces:
52 super(TestL2Flood, self).tearDown()
55 """ L2 Flood Tests """
58 # Create a single bridge Domain
60 self.vapi.bridge_domain_add_del(bd_id=1)
63 # add each interface to the BD. 3 interfaces per split horizon group
65 for i in self.pg_interfaces[0:4]:
66 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
68 for i in self.pg_interfaces[4:8]:
69 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
71 for i in self.pg_interfaces[8:12]:
72 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
74 for i in self.bvi_interfaces:
75 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
77 port_type=L2_PORT_TYPE.BVI)
79 p = (Ether(dst="ff:ff:ff:ff:ff:ff",
80 src="00:00:de:ad:be:ef") /
81 IP(src="10.10.10.10", dst="1.1.1.1") /
82 UDP(sport=1234, dport=1234) /
86 # input on pg0 expect copies on pg1->11
87 # this is in SHG=0 so its flooded to all, expect the pg0 since that's
90 self.pg0.add_stream(p*NUM_PKTS)
91 self.pg_enable_capture(self.pg_interfaces)
94 for i in self.pg_interfaces[1:12]:
95 rx0 = i.get_capture(NUM_PKTS, timeout=1)
98 # input on pg4 (SHG=1) expect copies on pg0->3 (SHG=0)
101 self.pg4.add_stream(p*NUM_PKTS)
102 self.pg_enable_capture(self.pg_interfaces)
105 for i in self.pg_interfaces[:4]:
106 rx0 = i.get_capture(NUM_PKTS, timeout=1)
107 for i in self.pg_interfaces[8:12]:
108 rx0 = i.get_capture(NUM_PKTS, timeout=1)
109 for i in self.pg_interfaces[4:8]:
110 i.assert_nothing_captured(remark="Different SH group")
113 # An IP route so the packet that hits the BVI is sent out of pg12
115 ip_route = VppIpRoute(self, "1.1.1.1", 32,
116 [VppRoutePath(self.pg12.remote_ip4,
117 self.pg12.sw_if_index)])
118 ip_route.add_vpp_config()
120 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
123 # input on pg0 expect copies on pg1->12
124 # this is in SHG=0 so its flooded to all, expect the pg0 since that's
127 self.pg0.add_stream(p*NUM_PKTS)
128 self.pg_enable_capture(self.pg_interfaces)
131 for i in self.pg_interfaces[1:]:
132 rx0 = i.get_capture(NUM_PKTS, timeout=1)
135 # input on pg4 (SHG=1) expect copies on pg0->3 (SHG=0)
136 # and pg8->12 (SHG=2)
138 self.pg4.add_stream(p*NUM_PKTS)
139 self.pg_enable_capture(self.pg_interfaces)
142 for i in self.pg_interfaces[:4]:
143 rx0 = i.get_capture(NUM_PKTS, timeout=1)
144 for i in self.pg_interfaces[8:13]:
145 rx0 = i.get_capture(NUM_PKTS, timeout=1)
146 for i in self.pg_interfaces[4:8]:
147 i.assert_nothing_captured(remark="Different SH group")
152 for i in self.pg_interfaces[:12]:
153 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
155 for i in self.bvi_interfaces:
156 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
158 port_type=L2_PORT_TYPE.BVI,
161 self.vapi.bridge_domain_add_del(bd_id=1, is_add=0)
163 def test_flood_one(self):
164 """ L2 no-Flood Test """
167 # Create a single bridge Domain
169 self.vapi.bridge_domain_add_del(bd_id=1)
172 # add 2 interfaces to the BD. this means a flood goes to only
175 for i in self.pg_interfaces[:2]:
176 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
179 p = (Ether(dst="ff:ff:ff:ff:ff:ff",
180 src="00:00:de:ad:be:ef") /
181 IP(src="10.10.10.10", dst="1.1.1.1") /
182 UDP(sport=1234, dport=1234) /
186 # input on pg0 expect copies on pg1
188 self.send_and_expect(self.pg0, p*NUM_PKTS, self.pg1)
193 for i in self.pg_interfaces[:2]:
194 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
196 self.vapi.bridge_domain_add_del(bd_id=1, is_add=0)
198 def test_uu_fwd(self):
202 # Create a single bridge Domain
204 self.vapi.bridge_domain_add_del(bd_id=1, uu_flood=1)
207 # add each interface to the BD. 3 interfaces per split horizon group
209 for i in self.pg_interfaces[0:4]:
210 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
214 # an unknown unicast and broadcast packets
216 p_uu = (Ether(dst="00:00:00:c1:5c:00",
217 src="00:00:de:ad:be:ef") /
218 IP(src="10.10.10.10", dst="1.1.1.1") /
219 UDP(sport=1234, dport=1234) /
221 p_bm = (Ether(dst="ff:ff:ff:ff:ff:ff",
222 src="00:00:de:ad:be:ef") /
223 IP(src="10.10.10.10", dst="1.1.1.1") /
224 UDP(sport=1234, dport=1234) /
228 # input on pg0, expected copies on pg1->4
230 self.pg0.add_stream(p_uu*NUM_PKTS)
231 self.pg_enable_capture(self.pg_interfaces)
234 for i in self.pg_interfaces[1:4]:
235 rx0 = i.get_capture(NUM_PKTS, timeout=1)
237 self.pg0.add_stream(p_bm*NUM_PKTS)
238 self.pg_enable_capture(self.pg_interfaces)
241 for i in self.pg_interfaces[1:4]:
242 rx0 = i.get_capture(NUM_PKTS, timeout=1)
245 # use pg8 as the uu-fwd interface
247 self.vapi.sw_interface_set_l2_bridge(
248 rx_sw_if_index=self.pg8.sw_if_index, bd_id=1, shg=0,
249 port_type=L2_PORT_TYPE.UU_FWD)
252 # expect the UU packet on the uu-fwd interface and not be flooded
254 self.pg0.add_stream(p_uu*NUM_PKTS)
255 self.pg_enable_capture(self.pg_interfaces)
258 rx0 = self.pg8.get_capture(NUM_PKTS, timeout=1)
260 for i in self.pg_interfaces[0:4]:
261 i.assert_nothing_captured(remark="UU not flooded")
263 self.pg0.add_stream(p_bm*NUM_PKTS)
264 self.pg_enable_capture(self.pg_interfaces)
267 for i in self.pg_interfaces[1:4]:
268 rx0 = i.get_capture(NUM_PKTS, timeout=1)
271 # remove the uu-fwd interface and expect UU to be flooded again
273 self.vapi.sw_interface_set_l2_bridge(
274 rx_sw_if_index=self.pg8.sw_if_index, bd_id=1, shg=0,
275 port_type=L2_PORT_TYPE.UU_FWD, enable=0)
277 self.pg0.add_stream(p_uu*NUM_PKTS)
278 self.pg_enable_capture(self.pg_interfaces)
281 for i in self.pg_interfaces[1:4]:
282 rx0 = i.get_capture(NUM_PKTS, timeout=1)
285 # change the BD config to not support UU-flood
287 self.vapi.bridge_flags(bd_id=1, is_set=0, flags=BRIDGE_FLAGS.UU_FLOOD)
289 self.send_and_assert_no_replies(self.pg0, p_uu)
292 # re-add the uu-fwd interface
294 self.vapi.sw_interface_set_l2_bridge(
295 rx_sw_if_index=self.pg8.sw_if_index, bd_id=1, shg=0,
296 port_type=L2_PORT_TYPE.UU_FWD)
297 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
299 self.pg0.add_stream(p_uu*NUM_PKTS)
300 self.pg_enable_capture(self.pg_interfaces)
303 rx0 = self.pg8.get_capture(NUM_PKTS, timeout=1)
305 for i in self.pg_interfaces[0:4]:
306 i.assert_nothing_captured(remark="UU not flooded")
309 # remove the uu-fwd interface
311 self.vapi.sw_interface_set_l2_bridge(
312 rx_sw_if_index=self.pg8.sw_if_index, bd_id=1, shg=0,
313 port_type=L2_PORT_TYPE.UU_FWD, enable=0)
314 self.send_and_assert_no_replies(self.pg0, p_uu)
319 for i in self.pg_interfaces[:4]:
320 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
323 self.vapi.bridge_domain_add_del(bd_id=1, is_add=0)
326 if __name__ == '__main__':
327 unittest.main(testRunner=VppTestRunner)