blob: a5c6e19243401185168b734d8f612f7a1200f731 [file] [log] [blame]
Neale Ranns055b2312018-07-20 01:16:04 -07001#!/usr/bin/env python
2
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
14
15class TestL2Flood(VppTestCase):
16 """ L2-flood """
17
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -070018 @classmethod
19 def setUpClass(cls):
20 super(TestL2Flood, cls).setUpClass()
21
22 @classmethod
23 def tearDownClass(cls):
24 super(TestL2Flood, cls).tearDownClass()
25
Neale Ranns055b2312018-07-20 01:16:04 -070026 def setUp(self):
27 super(TestL2Flood, self).setUp()
28
29 # 12 l2 interface and one l3
30 self.create_pg_interfaces(range(13))
Neale Ranns192b13f2019-03-15 02:16:20 -070031 self.create_bvi_interfaces(1)
Neale Ranns055b2312018-07-20 01:16:04 -070032
33 for i in self.pg_interfaces:
34 i.admin_up()
Neale Ranns192b13f2019-03-15 02:16:20 -070035 for i in self.bvi_interfaces:
Neale Ranns055b2312018-07-20 01:16:04 -070036 i.admin_up()
37
38 self.pg12.config_ip4()
39 self.pg12.resolve_arp()
Neale Ranns192b13f2019-03-15 02:16:20 -070040 self.bvi0.config_ip4()
Neale Ranns055b2312018-07-20 01:16:04 -070041
42 def tearDown(self):
43 self.pg12.unconfig_ip4()
Neale Ranns192b13f2019-03-15 02:16:20 -070044 self.bvi0.unconfig_ip4()
Neale Ranns055b2312018-07-20 01:16:04 -070045
46 for i in self.pg_interfaces:
47 i.admin_down()
Neale Ranns192b13f2019-03-15 02:16:20 -070048 for i in self.bvi_interfaces:
Neale Ranns055b2312018-07-20 01:16:04 -070049 i.admin_down()
50 super(TestL2Flood, self).tearDown()
51
52 def test_flood(self):
53 """ L2 Flood Tests """
54
55 #
56 # Create a single bridge Domain
57 #
Ole Troana5b2eec2019-03-11 19:23:25 +010058 self.vapi.bridge_domain_add_del(bd_id=1)
Neale Ranns055b2312018-07-20 01:16:04 -070059
60 #
61 # add each interface to the BD. 3 interfaces per split horizon group
62 #
63 for i in self.pg_interfaces[0:4]:
Ole Troana5b2eec2019-03-11 19:23:25 +010064 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
65 bd_id=1, shg=0)
Neale Ranns055b2312018-07-20 01:16:04 -070066 for i in self.pg_interfaces[4:8]:
Ole Troana5b2eec2019-03-11 19:23:25 +010067 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
68 bd_id=1, shg=1)
Neale Ranns055b2312018-07-20 01:16:04 -070069 for i in self.pg_interfaces[8:12]:
Ole Troana5b2eec2019-03-11 19:23:25 +010070 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
71 bd_id=1, shg=2)
Neale Ranns192b13f2019-03-15 02:16:20 -070072 for i in self.bvi_interfaces:
Ole Troana5b2eec2019-03-11 19:23:25 +010073 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
74 bd_id=1, shg=2,
Neale Rannsb4743802018-09-05 09:13:57 -070075 port_type=L2_PORT_TYPE.BVI)
Neale Ranns055b2312018-07-20 01:16:04 -070076
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) /
81 Raw('\xa5' * 100))
82
83 #
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
86 # the ingress link
87 #
88 self.pg0.add_stream(p*65)
89 self.pg_enable_capture(self.pg_interfaces)
90 self.pg_start()
91
92 for i in self.pg_interfaces[1:12]:
93 rx0 = i.get_capture(65, timeout=1)
94
Neale Ranns055b2312018-07-20 01:16:04 -070095 #
96 # input on pg4 (SHG=1) expect copies on pg0->3 (SHG=0)
97 # and pg8->11 (SHG=2)
98 #
99 self.pg4.add_stream(p*65)
100 self.pg_enable_capture(self.pg_interfaces)
101 self.pg_start()
102
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")
109
110 #
111 # An IP route so the packet that hits the BVI is sent out of pg12
112 #
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()
117
118 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
119
120 #
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
123 # the ingress link
124 #
125 self.pg0.add_stream(p*65)
126 self.pg_enable_capture(self.pg_interfaces)
127 self.pg_start()
128
129 for i in self.pg_interfaces[1:]:
130 rx0 = i.get_capture(65, timeout=1)
131
132 #
133 # input on pg4 (SHG=1) expect copies on pg0->3 (SHG=0)
134 # and pg8->12 (SHG=2)
135 #
136 self.pg4.add_stream(p*65)
137 self.pg_enable_capture(self.pg_interfaces)
138 self.pg_start()
139
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")
146
147 #
148 # cleanup
149 #
150 for i in self.pg_interfaces[:12]:
Ole Troana5b2eec2019-03-11 19:23:25 +0100151 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
152 bd_id=1, enable=0)
Neale Ranns192b13f2019-03-15 02:16:20 -0700153 for i in self.bvi_interfaces:
Ole Troana5b2eec2019-03-11 19:23:25 +0100154 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
155 bd_id=1, shg=2,
Neale Rannsb4743802018-09-05 09:13:57 -0700156 port_type=L2_PORT_TYPE.BVI,
157 enable=0)
158
Ole Troana5b2eec2019-03-11 19:23:25 +0100159 self.vapi.bridge_domain_add_del(bd_id=1, is_add=0)
Neale Rannsb4743802018-09-05 09:13:57 -0700160
Neale Rannsb9fa29d2018-10-02 07:27:02 -0700161 def test_flood_one(self):
162 """ L2 no-Flood Test """
163
164 #
165 # Create a single bridge Domain
166 #
Ole Troana5b2eec2019-03-11 19:23:25 +0100167 self.vapi.bridge_domain_add_del(bd_id=1)
Neale Rannsb9fa29d2018-10-02 07:27:02 -0700168
169 #
170 # add 2 interfaces to the BD. this means a flood goes to only
171 # one member
172 #
173 for i in self.pg_interfaces[:2]:
Ole Troana5b2eec2019-03-11 19:23:25 +0100174 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
175 bd_id=1, shg=0)
Neale Rannsb9fa29d2018-10-02 07:27:02 -0700176
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) /
181 Raw('\xa5' * 100))
182
183 #
184 # input on pg0 expect copies on pg1
185 #
186 self.send_and_expect(self.pg0, p*65, self.pg1)
187
188 #
189 # cleanup
190 #
191 for i in self.pg_interfaces[:2]:
Ole Troana5b2eec2019-03-11 19:23:25 +0100192 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
193 bd_id=1, enable=0)
194 self.vapi.bridge_domain_add_del(bd_id=1, is_add=0)
Neale Rannsb9fa29d2018-10-02 07:27:02 -0700195
Neale Rannsb4743802018-09-05 09:13:57 -0700196 def test_uu_fwd(self):
197 """ UU Flood """
198
199 #
200 # Create a single bridge Domain
201 #
Ole Troana5b2eec2019-03-11 19:23:25 +0100202 self.vapi.bridge_domain_add_del(bd_id=1, uu_flood=1)
Neale Rannsb4743802018-09-05 09:13:57 -0700203
204 #
205 # add each interface to the BD. 3 interfaces per split horizon group
206 #
207 for i in self.pg_interfaces[0:4]:
Ole Troana5b2eec2019-03-11 19:23:25 +0100208 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
209 bd_id=1, shg=0)
Neale Rannsb4743802018-09-05 09:13:57 -0700210
211 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700212 # an unknown unicast and broadcast packets
Neale Rannsb4743802018-09-05 09:13:57 -0700213 #
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) /
218 Raw('\xa5' * 100))
Neale Rannsd29cc882018-10-10 15:55:01 +0000219 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) /
223 Raw('\xa5' * 100))
Neale Rannsb4743802018-09-05 09:13:57 -0700224
225 #
226 # input on pg0, expected copies on pg1->4
227 #
228 self.pg0.add_stream(p_uu*65)
229 self.pg_enable_capture(self.pg_interfaces)
230 self.pg_start()
231
232 for i in self.pg_interfaces[1:4]:
233 rx0 = i.get_capture(65, timeout=1)
234
Neale Rannsd29cc882018-10-10 15:55:01 +0000235 self.pg0.add_stream(p_bm*65)
236 self.pg_enable_capture(self.pg_interfaces)
237 self.pg_start()
238
239 for i in self.pg_interfaces[1:4]:
240 rx0 = i.get_capture(65, timeout=1)
241
Neale Rannsb4743802018-09-05 09:13:57 -0700242 #
243 # use pg8 as the uu-fwd interface
244 #
Ole Troana5b2eec2019-03-11 19:23:25 +0100245 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)
Neale Rannsb4743802018-09-05 09:13:57 -0700248
249 #
250 # expect the UU packet on the uu-fwd interface and not be flooded
251 #
252 self.pg0.add_stream(p_uu*65)
253 self.pg_enable_capture(self.pg_interfaces)
254 self.pg_start()
255
256 rx0 = self.pg8.get_capture(65, timeout=1)
257
258 for i in self.pg_interfaces[0:4]:
259 i.assert_nothing_captured(remark="UU not flooded")
260
Neale Rannsd29cc882018-10-10 15:55:01 +0000261 self.pg0.add_stream(p_bm*65)
262 self.pg_enable_capture(self.pg_interfaces)
263 self.pg_start()
264
265 for i in self.pg_interfaces[1:4]:
266 rx0 = i.get_capture(65, timeout=1)
267
Neale Rannsb4743802018-09-05 09:13:57 -0700268 #
269 # remove the uu-fwd interface and expect UU to be flooded again
270 #
Ole Troana5b2eec2019-03-11 19:23:25 +0100271 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)
Neale Rannsb4743802018-09-05 09:13:57 -0700274
275 self.pg0.add_stream(p_uu*65)
276 self.pg_enable_capture(self.pg_interfaces)
277 self.pg_start()
278
279 for i in self.pg_interfaces[1:4]:
280 rx0 = i.get_capture(65, timeout=1)
281
282 #
283 # change the BD config to not support UU-flood
284 #
Ole Troana5b2eec2019-03-11 19:23:25 +0100285 self.vapi.bridge_flags(bd_id=1, is_set=0, flags=BRIDGE_FLAGS.UU_FLOOD)
Neale Rannsb4743802018-09-05 09:13:57 -0700286
287 self.send_and_assert_no_replies(self.pg0, p_uu)
288
289 #
290 # re-add the uu-fwd interface
291 #
Ole Troana5b2eec2019-03-11 19:23:25 +0100292 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)
Neale Rannsb4743802018-09-05 09:13:57 -0700295 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
296
297 self.pg0.add_stream(p_uu*65)
298 self.pg_enable_capture(self.pg_interfaces)
299 self.pg_start()
300
301 rx0 = self.pg8.get_capture(65, timeout=1)
302
303 for i in self.pg_interfaces[0:4]:
304 i.assert_nothing_captured(remark="UU not flooded")
305
306 #
307 # remove the uu-fwd interface
308 #
Ole Troana5b2eec2019-03-11 19:23:25 +0100309 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)
Neale Rannsb4743802018-09-05 09:13:57 -0700312 self.send_and_assert_no_replies(self.pg0, p_uu)
313
314 #
315 # cleanup
316 #
317 for i in self.pg_interfaces[:4]:
Ole Troana5b2eec2019-03-11 19:23:25 +0100318 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
319 bd_id=1, enable=0)
Neale Ranns055b2312018-07-20 01:16:04 -0700320
Ole Troana5b2eec2019-03-11 19:23:25 +0100321 self.vapi.bridge_domain_add_del(bd_id=1, is_add=0)
Neale Ranns055b2312018-07-20 01:16:04 -0700322
323
324if __name__ == '__main__':
325 unittest.main(testRunner=VppTestRunner)