blob: 7fe5214dcde51d78cee6afe7308ae24e2cdbda27 [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
18 def setUp(self):
19 super(TestL2Flood, self).setUp()
20
21 # 12 l2 interface and one l3
22 self.create_pg_interfaces(range(13))
23 self.create_loopback_interfaces(1)
24
25 for i in self.pg_interfaces:
26 i.admin_up()
27 for i in self.lo_interfaces:
28 i.admin_up()
29
30 self.pg12.config_ip4()
31 self.pg12.resolve_arp()
32 self.loop0.config_ip4()
33
34 def tearDown(self):
35 self.pg12.unconfig_ip4()
36 self.loop0.unconfig_ip4()
37
38 for i in self.pg_interfaces:
39 i.admin_down()
40 for i in self.lo_interfaces:
41 i.admin_down()
42 super(TestL2Flood, self).tearDown()
43
44 def test_flood(self):
45 """ L2 Flood Tests """
46
47 #
48 # Create a single bridge Domain
49 #
Ole Troana5b2eec2019-03-11 19:23:25 +010050 self.vapi.bridge_domain_add_del(bd_id=1)
Neale Ranns055b2312018-07-20 01:16:04 -070051
52 #
53 # add each interface to the BD. 3 interfaces per split horizon group
54 #
55 for i in self.pg_interfaces[0:4]:
Ole Troana5b2eec2019-03-11 19:23:25 +010056 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
57 bd_id=1, shg=0)
Neale Ranns055b2312018-07-20 01:16:04 -070058 for i in self.pg_interfaces[4:8]:
Ole Troana5b2eec2019-03-11 19:23:25 +010059 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
60 bd_id=1, shg=1)
Neale Ranns055b2312018-07-20 01:16:04 -070061 for i in self.pg_interfaces[8:12]:
Ole Troana5b2eec2019-03-11 19:23:25 +010062 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
63 bd_id=1, shg=2)
Neale Ranns055b2312018-07-20 01:16:04 -070064 for i in self.lo_interfaces:
Ole Troana5b2eec2019-03-11 19:23:25 +010065 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
66 bd_id=1, shg=2,
Neale Rannsb4743802018-09-05 09:13:57 -070067 port_type=L2_PORT_TYPE.BVI)
Neale Ranns055b2312018-07-20 01:16:04 -070068
69 p = (Ether(dst="ff:ff:ff:ff:ff:ff",
70 src="00:00:de:ad:be:ef") /
71 IP(src="10.10.10.10", dst="1.1.1.1") /
72 UDP(sport=1234, dport=1234) /
73 Raw('\xa5' * 100))
74
75 #
76 # input on pg0 expect copies on pg1->11
77 # this is in SHG=0 so its flooded to all, expect the pg0 since that's
78 # the ingress link
79 #
80 self.pg0.add_stream(p*65)
81 self.pg_enable_capture(self.pg_interfaces)
82 self.pg_start()
83
84 for i in self.pg_interfaces[1:12]:
85 rx0 = i.get_capture(65, timeout=1)
86
Neale Ranns055b2312018-07-20 01:16:04 -070087 #
88 # input on pg4 (SHG=1) expect copies on pg0->3 (SHG=0)
89 # and pg8->11 (SHG=2)
90 #
91 self.pg4.add_stream(p*65)
92 self.pg_enable_capture(self.pg_interfaces)
93 self.pg_start()
94
95 for i in self.pg_interfaces[:4]:
96 rx0 = i.get_capture(65, timeout=1)
97 for i in self.pg_interfaces[8:12]:
98 rx0 = i.get_capture(65, timeout=1)
99 for i in self.pg_interfaces[4:8]:
100 i.assert_nothing_captured(remark="Different SH group")
101
102 #
103 # An IP route so the packet that hits the BVI is sent out of pg12
104 #
105 ip_route = VppIpRoute(self, "1.1.1.1", 32,
106 [VppRoutePath(self.pg12.remote_ip4,
107 self.pg12.sw_if_index)])
108 ip_route.add_vpp_config()
109
110 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
111
112 #
113 # input on pg0 expect copies on pg1->12
114 # this is in SHG=0 so its flooded to all, expect the pg0 since that's
115 # the ingress link
116 #
117 self.pg0.add_stream(p*65)
118 self.pg_enable_capture(self.pg_interfaces)
119 self.pg_start()
120
121 for i in self.pg_interfaces[1:]:
122 rx0 = i.get_capture(65, timeout=1)
123
124 #
125 # input on pg4 (SHG=1) expect copies on pg0->3 (SHG=0)
126 # and pg8->12 (SHG=2)
127 #
128 self.pg4.add_stream(p*65)
129 self.pg_enable_capture(self.pg_interfaces)
130 self.pg_start()
131
132 for i in self.pg_interfaces[:4]:
133 rx0 = i.get_capture(65, timeout=1)
134 for i in self.pg_interfaces[8:13]:
135 rx0 = i.get_capture(65, timeout=1)
136 for i in self.pg_interfaces[4:8]:
137 i.assert_nothing_captured(remark="Different SH group")
138
139 #
140 # cleanup
141 #
142 for i in self.pg_interfaces[:12]:
Ole Troana5b2eec2019-03-11 19:23:25 +0100143 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
144 bd_id=1, enable=0)
Neale Ranns055b2312018-07-20 01:16:04 -0700145 for i in self.lo_interfaces:
Ole Troana5b2eec2019-03-11 19:23:25 +0100146 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
147 bd_id=1, shg=2,
Neale Rannsb4743802018-09-05 09:13:57 -0700148 port_type=L2_PORT_TYPE.BVI,
149 enable=0)
150
Ole Troana5b2eec2019-03-11 19:23:25 +0100151 self.vapi.bridge_domain_add_del(bd_id=1, is_add=0)
Neale Rannsb4743802018-09-05 09:13:57 -0700152
Neale Rannsb9fa29d2018-10-02 07:27:02 -0700153 def test_flood_one(self):
154 """ L2 no-Flood Test """
155
156 #
157 # Create a single bridge Domain
158 #
Ole Troana5b2eec2019-03-11 19:23:25 +0100159 self.vapi.bridge_domain_add_del(bd_id=1)
Neale Rannsb9fa29d2018-10-02 07:27:02 -0700160
161 #
162 # add 2 interfaces to the BD. this means a flood goes to only
163 # one member
164 #
165 for i in self.pg_interfaces[:2]:
Ole Troana5b2eec2019-03-11 19:23:25 +0100166 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
167 bd_id=1, shg=0)
Neale Rannsb9fa29d2018-10-02 07:27:02 -0700168
169 p = (Ether(dst="ff:ff:ff:ff:ff:ff",
170 src="00:00:de:ad:be:ef") /
171 IP(src="10.10.10.10", dst="1.1.1.1") /
172 UDP(sport=1234, dport=1234) /
173 Raw('\xa5' * 100))
174
175 #
176 # input on pg0 expect copies on pg1
177 #
178 self.send_and_expect(self.pg0, p*65, self.pg1)
179
180 #
181 # cleanup
182 #
183 for i in self.pg_interfaces[:2]:
Ole Troana5b2eec2019-03-11 19:23:25 +0100184 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
185 bd_id=1, enable=0)
186 self.vapi.bridge_domain_add_del(bd_id=1, is_add=0)
Neale Rannsb9fa29d2018-10-02 07:27:02 -0700187
Neale Rannsb4743802018-09-05 09:13:57 -0700188 def test_uu_fwd(self):
189 """ UU Flood """
190
191 #
192 # Create a single bridge Domain
193 #
Ole Troana5b2eec2019-03-11 19:23:25 +0100194 self.vapi.bridge_domain_add_del(bd_id=1, uu_flood=1)
Neale Rannsb4743802018-09-05 09:13:57 -0700195
196 #
197 # add each interface to the BD. 3 interfaces per split horizon group
198 #
199 for i in self.pg_interfaces[0:4]:
Ole Troana5b2eec2019-03-11 19:23:25 +0100200 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
201 bd_id=1, shg=0)
Neale Rannsb4743802018-09-05 09:13:57 -0700202
203 #
Neale Rannsd29cc882018-10-10 15:55:01 +0000204 # an unknown unicast and braodcast packets
Neale Rannsb4743802018-09-05 09:13:57 -0700205 #
206 p_uu = (Ether(dst="00:00:00:c1:5c:00",
207 src="00:00:de:ad:be:ef") /
208 IP(src="10.10.10.10", dst="1.1.1.1") /
209 UDP(sport=1234, dport=1234) /
210 Raw('\xa5' * 100))
Neale Rannsd29cc882018-10-10 15:55:01 +0000211 p_bm = (Ether(dst="ff:ff:ff:ff:ff:ff",
212 src="00:00:de:ad:be:ef") /
213 IP(src="10.10.10.10", dst="1.1.1.1") /
214 UDP(sport=1234, dport=1234) /
215 Raw('\xa5' * 100))
Neale Rannsb4743802018-09-05 09:13:57 -0700216
217 #
218 # input on pg0, expected copies on pg1->4
219 #
220 self.pg0.add_stream(p_uu*65)
221 self.pg_enable_capture(self.pg_interfaces)
222 self.pg_start()
223
224 for i in self.pg_interfaces[1:4]:
225 rx0 = i.get_capture(65, timeout=1)
226
Neale Rannsd29cc882018-10-10 15:55:01 +0000227 self.pg0.add_stream(p_bm*65)
228 self.pg_enable_capture(self.pg_interfaces)
229 self.pg_start()
230
231 for i in self.pg_interfaces[1:4]:
232 rx0 = i.get_capture(65, timeout=1)
233
Neale Rannsb4743802018-09-05 09:13:57 -0700234 #
235 # use pg8 as the uu-fwd interface
236 #
Ole Troana5b2eec2019-03-11 19:23:25 +0100237 self.vapi.sw_interface_set_l2_bridge(
238 rx_sw_if_index=self.pg8.sw_if_index, bd_id=1, shg=0,
239 port_type=L2_PORT_TYPE.UU_FWD)
Neale Rannsb4743802018-09-05 09:13:57 -0700240
241 #
242 # expect the UU packet on the uu-fwd interface and not be flooded
243 #
244 self.pg0.add_stream(p_uu*65)
245 self.pg_enable_capture(self.pg_interfaces)
246 self.pg_start()
247
248 rx0 = self.pg8.get_capture(65, timeout=1)
249
250 for i in self.pg_interfaces[0:4]:
251 i.assert_nothing_captured(remark="UU not flooded")
252
Neale Rannsd29cc882018-10-10 15:55:01 +0000253 self.pg0.add_stream(p_bm*65)
254 self.pg_enable_capture(self.pg_interfaces)
255 self.pg_start()
256
257 for i in self.pg_interfaces[1:4]:
258 rx0 = i.get_capture(65, timeout=1)
259
Neale Rannsb4743802018-09-05 09:13:57 -0700260 #
261 # remove the uu-fwd interface and expect UU to be flooded again
262 #
Ole Troana5b2eec2019-03-11 19:23:25 +0100263 self.vapi.sw_interface_set_l2_bridge(
264 rx_sw_if_index=self.pg8.sw_if_index, bd_id=1, shg=0,
265 port_type=L2_PORT_TYPE.UU_FWD, enable=0)
Neale Rannsb4743802018-09-05 09:13:57 -0700266
267 self.pg0.add_stream(p_uu*65)
268 self.pg_enable_capture(self.pg_interfaces)
269 self.pg_start()
270
271 for i in self.pg_interfaces[1:4]:
272 rx0 = i.get_capture(65, timeout=1)
273
274 #
275 # change the BD config to not support UU-flood
276 #
Ole Troana5b2eec2019-03-11 19:23:25 +0100277 self.vapi.bridge_flags(bd_id=1, is_set=0, flags=BRIDGE_FLAGS.UU_FLOOD)
Neale Rannsb4743802018-09-05 09:13:57 -0700278
279 self.send_and_assert_no_replies(self.pg0, p_uu)
280
281 #
282 # re-add the uu-fwd interface
283 #
Ole Troana5b2eec2019-03-11 19:23:25 +0100284 self.vapi.sw_interface_set_l2_bridge(
285 rx_sw_if_index=self.pg8.sw_if_index, bd_id=1, shg=0,
286 port_type=L2_PORT_TYPE.UU_FWD)
Neale Rannsb4743802018-09-05 09:13:57 -0700287 self.logger.info(self.vapi.cli("sh bridge 1 detail"))
288
289 self.pg0.add_stream(p_uu*65)
290 self.pg_enable_capture(self.pg_interfaces)
291 self.pg_start()
292
293 rx0 = self.pg8.get_capture(65, timeout=1)
294
295 for i in self.pg_interfaces[0:4]:
296 i.assert_nothing_captured(remark="UU not flooded")
297
298 #
299 # remove the uu-fwd interface
300 #
Ole Troana5b2eec2019-03-11 19:23:25 +0100301 self.vapi.sw_interface_set_l2_bridge(
302 rx_sw_if_index=self.pg8.sw_if_index, bd_id=1, shg=0,
303 port_type=L2_PORT_TYPE.UU_FWD, enable=0)
Neale Rannsb4743802018-09-05 09:13:57 -0700304 self.send_and_assert_no_replies(self.pg0, p_uu)
305
306 #
307 # cleanup
308 #
309 for i in self.pg_interfaces[:4]:
Ole Troana5b2eec2019-03-11 19:23:25 +0100310 self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
311 bd_id=1, enable=0)
Neale Ranns055b2312018-07-20 01:16:04 -0700312
Ole Troana5b2eec2019-03-11 19:23:25 +0100313 self.vapi.bridge_domain_add_del(bd_id=1, is_add=0)
Neale Ranns055b2312018-07-20 01:16:04 -0700314
315
316if __name__ == '__main__':
317 unittest.main(testRunner=VppTestRunner)