Tests Cleanup: Fix missing calls to setUpClass/tearDownClass.
[vpp.git] / test / test_svs.py
1 #!/usr/bin/env python
2
3 import unittest
4
5 from framework import VppTestCase, VppTestRunner
6 from vpp_ip_route import VppIpTable
7
8 from scapy.packet import Raw
9 from scapy.layers.l2 import Ether
10 from scapy.layers.inet import IP, UDP, ICMP
11 from scapy.layers.inet6 import IPv6
12
13 from vpp_papi import VppEnum
14
15
16 class TestSVS(VppTestCase):
17     """ SVS Test Case """
18
19     @classmethod
20     def setUpClass(cls):
21         super(TestSVS, cls).setUpClass()
22
23     @classmethod
24     def tearDownClass(cls):
25         super(TestSVS, cls).tearDownClass()
26
27     def setUp(self):
28         super(TestSVS, self).setUp()
29
30         # create 2 pg interfaces
31         self.create_pg_interfaces(range(4))
32
33         table_id = 0
34
35         for i in self.pg_interfaces:
36             i.admin_up()
37
38             if table_id != 0:
39                 tbl = VppIpTable(self, table_id)
40                 tbl.add_vpp_config()
41                 tbl = VppIpTable(self, table_id, is_ip6=1)
42                 tbl.add_vpp_config()
43
44             i.set_table_ip4(table_id)
45             i.set_table_ip6(table_id)
46             i.config_ip4()
47             i.resolve_arp()
48             i.config_ip6()
49             i.resolve_ndp()
50             table_id += 1
51
52     def tearDown(self):
53         for i in self.pg_interfaces:
54             i.unconfig_ip4()
55             i.unconfig_ip6()
56             i.ip6_disable()
57             i.set_table_ip4(0)
58             i.set_table_ip6(0)
59             i.admin_down()
60         super(TestSVS, self).tearDown()
61
62     def test_svs4(self):
63         """ Source VRF Select IP4 """
64
65         #
66         # packets destined out of the 3 non-default table interfaces
67         #
68         pkts_0 = [(Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
69                    IP(src="1.1.1.1", dst=self.pg1.remote_ip4) /
70                    UDP(sport=1234, dport=1234) /
71                    Raw('\xa5' * 100)),
72                   (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
73                    IP(src="2.2.2.2", dst=self.pg2.remote_ip4) /
74                    UDP(sport=1234, dport=1234) /
75                    Raw('\xa5' * 100)),
76                   (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
77                    IP(src="3.3.3.3", dst=self.pg3.remote_ip4) /
78                    UDP(sport=1234, dport=1234) /
79                    Raw('\xa5' * 100))]
80         pkts_1 = [(Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
81                    IP(src="1.1.1.1", dst=self.pg1.remote_ip4) /
82                    UDP(sport=1234, dport=1234) /
83                    Raw('\xa5' * 100)),
84                   (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
85                    IP(src="2.2.2.2", dst=self.pg2.remote_ip4) /
86                    UDP(sport=1234, dport=1234) /
87                    Raw('\xa5' * 100)),
88                   (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
89                    IP(src="3.3.3.3", dst=self.pg3.remote_ip4) /
90                    UDP(sport=1234, dport=1234) /
91                    Raw('\xa5' * 100))]
92
93         #
94         # before adding the SVS config all these packets are dropped when
95         # ingressing on pg0 since pg0 is in the default table
96         #
97         for p in pkts_0:
98             self.send_and_assert_no_replies(self.pg0, p * 1)
99
100         #
101         # Add table 1001 & 1002 into which we'll add the routes
102         # determining the source VRF selection
103         #
104         table_ids = [101, 102]
105
106         for table_id in table_ids:
107             self.vapi.svs_table_add_del(
108                 VppEnum.vl_api_address_family_t.ADDRESS_IP4, table_id)
109
110             #
111             # map X.0.0.0/8 to each SVS table for lookup in table X
112             #
113             for i in range(1, 4):
114                 self.vapi.svs_route_add_del(
115                     table_id, "%d.0.0.0/8" % i, i)
116
117         #
118         # Enable SVS on pg0/pg1 using table 1001/1002
119         #
120         self.vapi.svs_enable_disable(
121             VppEnum.vl_api_address_family_t.ADDRESS_IP4, table_ids[0],
122             self.pg0.sw_if_index)
123         self.vapi.svs_enable_disable(
124             VppEnum.vl_api_address_family_t.ADDRESS_IP4, table_ids[1],
125             self.pg1.sw_if_index)
126
127         #
128         # now all the packets should be delivered out the respective interface
129         #
130         self.send_and_expect(self.pg0, pkts_0[0] * 65, self.pg1)
131         self.send_and_expect(self.pg0, pkts_0[1] * 65, self.pg2)
132         self.send_and_expect(self.pg0, pkts_0[2] * 65, self.pg3)
133         self.send_and_expect(self.pg1, pkts_1[0] * 65, self.pg1)
134         self.send_and_expect(self.pg1, pkts_1[1] * 65, self.pg2)
135         self.send_and_expect(self.pg1, pkts_1[2] * 65, self.pg3)
136
137         #
138         # check that if the SVS lookup does not match a route the packet
139         # is forwarded using the interface's routing table
140         #
141         p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
142              IP(src=self.pg0.remote_ip4, dst=self.pg0.remote_ip4) /
143              UDP(sport=1234, dport=1234) /
144              Raw('\xa5' * 100))
145         self.send_and_expect(self.pg0, p * 65, self.pg0)
146
147         p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
148              IP(src=self.pg1.remote_ip4, dst=self.pg1.remote_ip4) /
149              UDP(sport=1234, dport=1234) /
150              Raw('\xa5' * 100))
151         self.send_and_expect(self.pg1, p * 65, self.pg1)
152
153         #
154         # dump the SVS configs
155         #
156         ss = self.vapi.svs_dump()
157
158         self.assertEqual(ss[0].table_id, table_ids[0])
159         self.assertEqual(ss[0].sw_if_index, self.pg0.sw_if_index)
160         self.assertEqual(ss[0].af, VppEnum.vl_api_address_family_t.ADDRESS_IP4)
161         self.assertEqual(ss[1].table_id, table_ids[1])
162         self.assertEqual(ss[1].sw_if_index, self.pg1.sw_if_index)
163         self.assertEqual(ss[1].af, VppEnum.vl_api_address_family_t.ADDRESS_IP4)
164
165         #
166         # cleanup
167         #
168         self.vapi.svs_enable_disable(
169             VppEnum.vl_api_address_family_t.ADDRESS_IP4,
170             table_ids[0],
171             self.pg0.sw_if_index,
172             is_enable=0)
173         self.vapi.svs_enable_disable(
174             VppEnum.vl_api_address_family_t.ADDRESS_IP4,
175             table_ids[1],
176             self.pg1.sw_if_index,
177             is_enable=0)
178
179         for table_id in table_ids:
180             for i in range(1, 4):
181                 self.vapi.svs_route_add_del(
182                     table_id, "%d.0.0.0/8" % i,
183                     0, is_add=0)
184             self.vapi.svs_table_add_del(
185                 VppEnum.vl_api_address_family_t.ADDRESS_IP4,
186                 table_id,
187                 is_add=0)
188
189     def test_svs6(self):
190         """ Source VRF Select IP6 """
191
192         #
193         # packets destined out of the 3 non-default table interfaces
194         #
195         pkts_0 = [(Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
196                    IPv6(src="2001:1::1", dst=self.pg1.remote_ip6) /
197                    UDP(sport=1234, dport=1234) /
198                    Raw('\xa5' * 100)),
199                   (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
200                    IPv6(src="2001:2::1", dst=self.pg2.remote_ip6) /
201                    UDP(sport=1234, dport=1234) /
202                    Raw('\xa5' * 100)),
203                   (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
204                    IPv6(src="2001:3::1", dst=self.pg3.remote_ip6) /
205                    UDP(sport=1234, dport=1234) /
206                    Raw('\xa5' * 100))]
207         pkts_1 = [(Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
208                    IPv6(src="2001:1::1", dst=self.pg1.remote_ip6) /
209                    UDP(sport=1234, dport=1234) /
210                    Raw('\xa5' * 100)),
211                   (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
212                    IPv6(src="2001:2::1", dst=self.pg2.remote_ip6) /
213                    UDP(sport=1234, dport=1234) /
214                    Raw('\xa5' * 100)),
215                   (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
216                    IPv6(src="2001:3::1", dst=self.pg3.remote_ip6) /
217                    UDP(sport=1234, dport=1234) /
218                    Raw('\xa5' * 100))]
219
220         #
221         # before adding the SVS config all these packets are dropped when
222         # ingressing on pg0 since pg0 is in the default table
223         #
224         for p in pkts_0:
225             self.send_and_assert_no_replies(self.pg0, p * 1)
226
227         #
228         # Add table 1001 & 1002 into which we'll add the routes
229         # determining the source VRF selection
230         #
231         table_ids = [101, 102]
232
233         for table_id in table_ids:
234             self.vapi.svs_table_add_del(
235                 VppEnum.vl_api_address_family_t.ADDRESS_IP6, table_id)
236
237             #
238             # map X.0.0.0/8 to each SVS table for lookup in table X
239             #
240             for i in range(1, 4):
241                 self.vapi.svs_route_add_del(
242                     table_id, "2001:%d::/32" % i,
243                     i)
244
245         #
246         # Enable SVS on pg0/pg1 using table 1001/1002
247         #
248         self.vapi.svs_enable_disable(
249             VppEnum.vl_api_address_family_t.ADDRESS_IP6,
250             table_ids[0],
251             self.pg0.sw_if_index)
252         self.vapi.svs_enable_disable(
253             VppEnum.vl_api_address_family_t.ADDRESS_IP6,
254             table_ids[1],
255             self.pg1.sw_if_index)
256
257         #
258         # now all the packets should be delivered out the respective interface
259         #
260         self.send_and_expect(self.pg0, pkts_0[0] * 65, self.pg1)
261         self.send_and_expect(self.pg0, pkts_0[1] * 65, self.pg2)
262         self.send_and_expect(self.pg0, pkts_0[2] * 65, self.pg3)
263         self.send_and_expect(self.pg1, pkts_1[0] * 65, self.pg1)
264         self.send_and_expect(self.pg1, pkts_1[1] * 65, self.pg2)
265         self.send_and_expect(self.pg1, pkts_1[2] * 65, self.pg3)
266
267         #
268         # check that if the SVS lookup does not match a route the packet
269         # is forwarded using the interface's routing table
270         #
271         p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
272              IPv6(src=self.pg0.remote_ip6, dst=self.pg0.remote_ip6) /
273              UDP(sport=1234, dport=1234) /
274              Raw('\xa5' * 100))
275         self.send_and_expect(self.pg0, p * 65, self.pg0)
276
277         p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
278              IPv6(src=self.pg1.remote_ip6, dst=self.pg1.remote_ip6) /
279              UDP(sport=1234, dport=1234) /
280              Raw('\xa5' * 100))
281         self.send_and_expect(self.pg1, p * 65, self.pg1)
282
283         #
284         # dump the SVS configs
285         #
286         ss = self.vapi.svs_dump()
287
288         self.assertEqual(ss[0].table_id, table_ids[0])
289         self.assertEqual(ss[0].sw_if_index, self.pg0.sw_if_index)
290         self.assertEqual(ss[0].af, VppEnum.vl_api_address_family_t.ADDRESS_IP6)
291         self.assertEqual(ss[1].table_id, table_ids[1])
292         self.assertEqual(ss[1].sw_if_index, self.pg1.sw_if_index)
293         self.assertEqual(ss[1].af, VppEnum.vl_api_address_family_t.ADDRESS_IP6)
294
295         #
296         # cleanup
297         #
298         self.vapi.svs_enable_disable(
299             VppEnum.vl_api_address_family_t.ADDRESS_IP6,
300             table_ids[0],
301             self.pg0.sw_if_index,
302             is_enable=0)
303         self.vapi.svs_enable_disable(
304             VppEnum.vl_api_address_family_t.ADDRESS_IP6,
305             table_ids[1],
306             self.pg1.sw_if_index,
307             is_enable=0)
308         for table_id in table_ids:
309             for i in range(1, 4):
310                 self.vapi.svs_route_add_del(
311                     table_id, "2001:%d::/32" % i,
312                     0, is_add=0)
313             self.vapi.svs_table_add_del(
314                 VppEnum.vl_api_address_family_t.ADDRESS_IP6,
315                 table_id,
316                 is_add=0)
317
318
319 if __name__ == '__main__':
320     unittest.main(testRunner=VppTestRunner)