6 from framework import VppTestCase, VppTestRunner
7 from vpp_ip_route import VppIpRoute, VppRoutePath
8 from vpp_papi_provider 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):
19 super(TestL2Flood, self).setUp()
21 # 12 l2 interface and one l3
22 self.create_pg_interfaces(range(13))
23 self.create_loopback_interfaces(1)
25 for i in self.pg_interfaces:
27 for i in self.lo_interfaces:
30 self.pg12.config_ip4()
31 self.pg12.resolve_arp()
32 self.loop0.config_ip4()
35 self.pg12.unconfig_ip4()
36 self.loop0.unconfig_ip4()
38 for i in self.pg_interfaces:
40 for i in self.lo_interfaces:
42 super(TestL2Flood, self).tearDown()
45 """ L2 Flood Tests """
48 # Create a single bridge Domain
50 self.vapi.bridge_domain_add_del(1)
53 # add each interface to the BD. 3 interfaces per split horizon group
55 for i in self.pg_interfaces[0:4]:
56 self.vapi.sw_interface_set_l2_bridge(i.sw_if_index, 1, 0)
57 for i in self.pg_interfaces[4:8]:
58 self.vapi.sw_interface_set_l2_bridge(i.sw_if_index, 1, 1)
59 for i in self.pg_interfaces[8:12]:
60 self.vapi.sw_interface_set_l2_bridge(i.sw_if_index, 1, 2)
61 for i in self.lo_interfaces:
62 self.vapi.sw_interface_set_l2_bridge(i.sw_if_index, 1, 2,
63 port_type=L2_PORT_TYPE.BVI)
65 p = (Ether(dst="ff:ff:ff:ff:ff:ff",
66 src="00:00:de:ad:be:ef") /
67 IP(src="10.10.10.10", dst="1.1.1.1") /
68 UDP(sport=1234, dport=1234) /
72 # input on pg0 expect copies on pg1->11
73 # this is in SHG=0 so its flooded to all, expect the pg0 since that's
76 self.pg0.add_stream(p*65)
77 self.pg_enable_capture(self.pg_interfaces)
80 for i in self.pg_interfaces[1:12]:
81 rx0 = i.get_capture(65, timeout=1)
84 # input on pg4 (SHG=1) expect copies on pg0->3 (SHG=0)
87 self.pg4.add_stream(p*65)
88 self.pg_enable_capture(self.pg_interfaces)
91 for i in self.pg_interfaces[:4]:
92 rx0 = i.get_capture(65, timeout=1)
93 for i in self.pg_interfaces[8:12]:
94 rx0 = i.get_capture(65, timeout=1)
95 for i in self.pg_interfaces[4:8]:
96 i.assert_nothing_captured(remark="Different SH group")
99 # An IP route so the packet that hits the BVI is sent out of pg12
101 ip_route = VppIpRoute(self, "1.1.1.1", 32,
102 [VppRoutePath(self.pg12.remote_ip4,
103 self.pg12.sw_if_index)])
104 ip_route.add_vpp_config()
106 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
109 # input on pg0 expect copies on pg1->12
110 # this is in SHG=0 so its flooded to all, expect the pg0 since that's
113 self.pg0.add_stream(p*65)
114 self.pg_enable_capture(self.pg_interfaces)
117 for i in self.pg_interfaces[1:]:
118 rx0 = i.get_capture(65, timeout=1)
121 # input on pg4 (SHG=1) expect copies on pg0->3 (SHG=0)
122 # and pg8->12 (SHG=2)
124 self.pg4.add_stream(p*65)
125 self.pg_enable_capture(self.pg_interfaces)
128 for i in self.pg_interfaces[:4]:
129 rx0 = i.get_capture(65, timeout=1)
130 for i in self.pg_interfaces[8:13]:
131 rx0 = i.get_capture(65, timeout=1)
132 for i in self.pg_interfaces[4:8]:
133 i.assert_nothing_captured(remark="Different SH group")
138 for i in self.pg_interfaces[:12]:
139 self.vapi.sw_interface_set_l2_bridge(i.sw_if_index, 1, enable=0)
140 for i in self.lo_interfaces:
141 self.vapi.sw_interface_set_l2_bridge(i.sw_if_index, 1, 2,
142 port_type=L2_PORT_TYPE.BVI,
145 self.vapi.bridge_domain_add_del(1, is_add=0)
147 def test_uu_fwd(self):
151 # Create a single bridge Domain
153 self.vapi.bridge_domain_add_del(1, uu_flood=1)
156 # add each interface to the BD. 3 interfaces per split horizon group
158 for i in self.pg_interfaces[0:4]:
159 self.vapi.sw_interface_set_l2_bridge(i.sw_if_index, 1, 0)
162 # an unknown unicast packet
164 p_uu = (Ether(dst="00:00:00:c1:5c:00",
165 src="00:00:de:ad:be:ef") /
166 IP(src="10.10.10.10", dst="1.1.1.1") /
167 UDP(sport=1234, dport=1234) /
171 # input on pg0, expected copies on pg1->4
173 self.pg0.add_stream(p_uu*65)
174 self.pg_enable_capture(self.pg_interfaces)
177 for i in self.pg_interfaces[1:4]:
178 rx0 = i.get_capture(65, timeout=1)
181 # use pg8 as the uu-fwd interface
183 self.vapi.sw_interface_set_l2_bridge(self.pg8.sw_if_index, 1, 0,
184 port_type=L2_PORT_TYPE.UU_FWD)
187 # expect the UU packet on the uu-fwd interface and not be flooded
189 self.pg0.add_stream(p_uu*65)
190 self.pg_enable_capture(self.pg_interfaces)
193 rx0 = self.pg8.get_capture(65, timeout=1)
195 for i in self.pg_interfaces[0:4]:
196 i.assert_nothing_captured(remark="UU not flooded")
199 # remove the uu-fwd interface and expect UU to be flooded again
201 self.vapi.sw_interface_set_l2_bridge(self.pg8.sw_if_index, 1, 0,
202 port_type=L2_PORT_TYPE.UU_FWD,
205 self.pg0.add_stream(p_uu*65)
206 self.pg_enable_capture(self.pg_interfaces)
209 for i in self.pg_interfaces[1:4]:
210 rx0 = i.get_capture(65, timeout=1)
213 # change the BD config to not support UU-flood
215 self.vapi.bridge_flags(1, 0, BRIDGE_FLAGS.UU_FLOOD)
217 self.send_and_assert_no_replies(self.pg0, p_uu)
220 # re-add the uu-fwd interface
222 self.vapi.sw_interface_set_l2_bridge(self.pg8.sw_if_index, 1, 0,
223 port_type=L2_PORT_TYPE.UU_FWD)
224 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
226 self.pg0.add_stream(p_uu*65)
227 self.pg_enable_capture(self.pg_interfaces)
230 rx0 = self.pg8.get_capture(65, timeout=1)
232 for i in self.pg_interfaces[0:4]:
233 i.assert_nothing_captured(remark="UU not flooded")
236 # remove the uu-fwd interface
238 self.vapi.sw_interface_set_l2_bridge(self.pg8.sw_if_index, 1, 0,
239 port_type=L2_PORT_TYPE.UU_FWD,
241 self.send_and_assert_no_replies(self.pg0, p_uu)
246 for i in self.pg_interfaces[:4]:
247 self.vapi.sw_interface_set_l2_bridge(i.sw_if_index, 1, enable=0)
249 self.vapi.bridge_domain_add_del(1, is_add=0)
252 if __name__ == '__main__':
253 unittest.main(testRunner=VppTestRunner)