Tests Cleanup: Fix missing calls to setUpClass/tearDownClass.
[vpp.git] / test / test_l2_flood.py
1 #!/usr/bin/env python
2
3 import unittest
4 import socket
5
6 from framework import VppTestCase, VppTestRunner
7 from vpp_ip_route import VppIpRoute, VppRoutePath
8 from vpp_l2 import L2_PORT_TYPE, BRIDGE_FLAGS
9
10 from scapy.packet import Raw
11 from scapy.layers.l2 import Ether
12 from scapy.layers.inet import IP, UDP
13
14
15 class TestL2Flood(VppTestCase):
16     """ L2-flood """
17
18     @classmethod
19     def setUpClass(cls):
20         super(TestL2Flood, cls).setUpClass()
21
22     @classmethod
23     def tearDownClass(cls):
24         super(TestL2Flood, cls).tearDownClass()
25
26     def setUp(self):
27         super(TestL2Flood, self).setUp()
28
29         # 12 l2 interface and one l3
30         self.create_pg_interfaces(range(13))
31         self.create_bvi_interfaces(1)
32
33         for i in self.pg_interfaces:
34             i.admin_up()
35         for i in self.bvi_interfaces:
36             i.admin_up()
37
38         self.pg12.config_ip4()
39         self.pg12.resolve_arp()
40         self.bvi0.config_ip4()
41
42     def tearDown(self):
43         self.pg12.unconfig_ip4()
44         self.bvi0.unconfig_ip4()
45
46         for i in self.pg_interfaces:
47             i.admin_down()
48         for i in self.bvi_interfaces:
49             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         #
58         self.vapi.bridge_domain_add_del(bd_id=1)
59
60         #
61         # add each interface to the BD. 3 interfaces per split horizon group
62         #
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,
65                                                  bd_id=1, shg=0)
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,
68                                                  bd_id=1, shg=1)
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,
71                                                  bd_id=1, shg=2)
72         for i in self.bvi_interfaces:
73             self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
74                                                  bd_id=1, shg=2,
75                                                  port_type=L2_PORT_TYPE.BVI)
76
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
95         #
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]:
151             self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
152                                                  bd_id=1, enable=0)
153         for i in self.bvi_interfaces:
154             self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
155                                                  bd_id=1, shg=2,
156                                                  port_type=L2_PORT_TYPE.BVI,
157                                                  enable=0)
158
159         self.vapi.bridge_domain_add_del(bd_id=1, is_add=0)
160
161     def test_flood_one(self):
162         """ L2 no-Flood Test """
163
164         #
165         # Create a single bridge Domain
166         #
167         self.vapi.bridge_domain_add_del(bd_id=1)
168
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]:
174             self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
175                                                  bd_id=1, shg=0)
176
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]:
192             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)
195
196     def test_uu_fwd(self):
197         """ UU Flood """
198
199         #
200         # Create a single bridge Domain
201         #
202         self.vapi.bridge_domain_add_del(bd_id=1, uu_flood=1)
203
204         #
205         # add each interface to the BD. 3 interfaces per split horizon group
206         #
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,
209                                                  bd_id=1, shg=0)
210
211         #
212         # an unknown unicast and broadcast packets
213         #
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))
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) /
223                 Raw('\xa5' * 100))
224
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
235         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
242         #
243         # use pg8 as the uu-fwd interface
244         #
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)
248
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
261         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
268         #
269         # remove the uu-fwd interface and expect UU to be flooded again
270         #
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)
274
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         #
285         self.vapi.bridge_flags(bd_id=1, is_set=0, flags=BRIDGE_FLAGS.UU_FLOOD)
286
287         self.send_and_assert_no_replies(self.pg0, p_uu)
288
289         #
290         # re-add the uu-fwd interface
291         #
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"))
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         #
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)
313
314         #
315         # cleanup
316         #
317         for i in self.pg_interfaces[:4]:
318             self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
319                                                  bd_id=1, enable=0)
320
321         self.vapi.bridge_domain_add_del(bd_id=1, is_add=0)
322
323
324 if __name__ == '__main__':
325     unittest.main(testRunner=VppTestRunner)