blob: 916039664534bb1bd83cff535a93f8be6fa59ebc [file] [log] [blame]
Renato Botelho do Coutoead1e532019-10-31 13:31:07 -05001#!/usr/bin/env python3
Neale Rannsccc70f62018-10-02 07:28:16 -07002
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07003import unittest
4
Neale Rannsccc70f62018-10-02 07:28:16 -07005from framework import VppTestCase, VppTestRunner
Neale Rannsccc70f62018-10-02 07:28:16 -07006from vpp_ip_route import VppIpTable
7
8from scapy.packet import Raw
9from scapy.layers.l2 import Ether
10from scapy.layers.inet import IP, UDP, ICMP
11from scapy.layers.inet6 import IPv6
12
Ole Troan0685da42018-10-16 14:42:50 +020013from vpp_papi import VppEnum
14
Paul Vinciguerra4271c972019-05-14 13:25:49 -040015NUM_PKTS = 67
16
Neale Rannsccc70f62018-10-02 07:28:16 -070017
18class TestSVS(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020019 """SVS Test Case"""
Neale Rannsccc70f62018-10-02 07:28:16 -070020
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -070021 @classmethod
22 def setUpClass(cls):
23 super(TestSVS, cls).setUpClass()
24
25 @classmethod
26 def tearDownClass(cls):
27 super(TestSVS, cls).tearDownClass()
28
Neale Rannsccc70f62018-10-02 07:28:16 -070029 def setUp(self):
30 super(TestSVS, self).setUp()
31
32 # create 2 pg interfaces
33 self.create_pg_interfaces(range(4))
34
35 table_id = 0
36
37 for i in self.pg_interfaces:
38 i.admin_up()
39
40 if table_id != 0:
41 tbl = VppIpTable(self, table_id)
42 tbl.add_vpp_config()
43 tbl = VppIpTable(self, table_id, is_ip6=1)
44 tbl.add_vpp_config()
45
46 i.set_table_ip4(table_id)
47 i.set_table_ip6(table_id)
48 i.config_ip4()
49 i.resolve_arp()
50 i.config_ip6()
51 i.resolve_ndp()
52 table_id += 1
53
54 def tearDown(self):
55 for i in self.pg_interfaces:
56 i.unconfig_ip4()
57 i.unconfig_ip6()
Neale Rannsccc70f62018-10-02 07:28:16 -070058 i.set_table_ip4(0)
59 i.set_table_ip6(0)
60 i.admin_down()
61 super(TestSVS, self).tearDown()
62
63 def test_svs4(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020064 """Source VRF Select IP4"""
Neale Rannsccc70f62018-10-02 07:28:16 -070065
66 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -070067 # packets destined out of the 3 non-default table interfaces
Neale Rannsccc70f62018-10-02 07:28:16 -070068 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020069 pkts_0 = [
70 (
71 Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
72 / IP(src="1.1.1.1", dst=self.pg1.remote_ip4)
73 / UDP(sport=1234, dport=1234)
74 / Raw(b"\xa5" * 100)
75 ),
76 (
77 Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
78 / IP(src="2.2.2.2", dst=self.pg2.remote_ip4)
79 / UDP(sport=1234, dport=1234)
80 / Raw(b"\xa5" * 100)
81 ),
82 (
83 Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
84 / IP(src="3.3.3.3", dst=self.pg3.remote_ip4)
85 / UDP(sport=1234, dport=1234)
86 / Raw(b"\xa5" * 100)
87 ),
88 ]
89 pkts_1 = [
90 (
91 Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac)
92 / IP(src="1.1.1.1", dst=self.pg1.remote_ip4)
93 / UDP(sport=1234, dport=1234)
94 / Raw(b"\xa5" * 100)
95 ),
96 (
97 Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac)
98 / IP(src="2.2.2.2", dst=self.pg2.remote_ip4)
99 / UDP(sport=1234, dport=1234)
100 / Raw(b"\xa5" * 100)
101 ),
102 (
103 Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac)
104 / IP(src="3.3.3.3", dst=self.pg3.remote_ip4)
105 / UDP(sport=1234, dport=1234)
106 / Raw(b"\xa5" * 100)
107 ),
108 ]
Neale Rannsccc70f62018-10-02 07:28:16 -0700109
110 #
111 # before adding the SVS config all these packets are dropped when
112 # ingressing on pg0 since pg0 is in the default table
113 #
114 for p in pkts_0:
115 self.send_and_assert_no_replies(self.pg0, p * 1)
116
117 #
118 # Add table 1001 & 1002 into which we'll add the routes
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700119 # determining the source VRF selection
Neale Rannsccc70f62018-10-02 07:28:16 -0700120 #
121 table_ids = [101, 102]
122
123 for table_id in table_ids:
Ole Troan0685da42018-10-16 14:42:50 +0200124 self.vapi.svs_table_add_del(
Ole Troan5c2a2372020-11-19 16:01:23 +0100125 is_add=1,
126 af=VppEnum.vl_api_address_family_t.ADDRESS_IP4,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200127 table_id=table_id,
128 )
Neale Rannsccc70f62018-10-02 07:28:16 -0700129
130 #
131 # map X.0.0.0/8 to each SVS table for lookup in table X
132 #
133 for i in range(1, 4):
134 self.vapi.svs_route_add_del(
Ole Troan5c2a2372020-11-19 16:01:23 +0100135 is_add=1,
136 prefix="%d.0.0.0/8" % i,
137 table_id=table_id,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200138 source_table_id=i,
139 )
Neale Rannsccc70f62018-10-02 07:28:16 -0700140
141 #
142 # Enable SVS on pg0/pg1 using table 1001/1002
143 #
Ole Troan0685da42018-10-16 14:42:50 +0200144 self.vapi.svs_enable_disable(
Ole Troan5c2a2372020-11-19 16:01:23 +0100145 is_enable=1,
146 af=VppEnum.vl_api_address_family_t.ADDRESS_IP4,
147 table_id=table_ids[0],
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200148 sw_if_index=self.pg0.sw_if_index,
149 )
Ole Troan0685da42018-10-16 14:42:50 +0200150 self.vapi.svs_enable_disable(
Ole Troan5c2a2372020-11-19 16:01:23 +0100151 is_enable=1,
152 af=VppEnum.vl_api_address_family_t.ADDRESS_IP4,
153 table_id=table_ids[1],
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200154 sw_if_index=self.pg1.sw_if_index,
155 )
Neale Rannsccc70f62018-10-02 07:28:16 -0700156
157 #
158 # now all the packets should be delivered out the respective interface
159 #
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400160 self.send_and_expect(self.pg0, pkts_0[0] * NUM_PKTS, self.pg1)
161 self.send_and_expect(self.pg0, pkts_0[1] * NUM_PKTS, self.pg2)
162 self.send_and_expect(self.pg0, pkts_0[2] * NUM_PKTS, self.pg3)
163 self.send_and_expect(self.pg1, pkts_1[0] * NUM_PKTS, self.pg1)
164 self.send_and_expect(self.pg1, pkts_1[1] * NUM_PKTS, self.pg2)
165 self.send_and_expect(self.pg1, pkts_1[2] * NUM_PKTS, self.pg3)
Neale Rannsccc70f62018-10-02 07:28:16 -0700166
167 #
168 # check that if the SVS lookup does not match a route the packet
169 # is forwarded using the interface's routing table
170 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200171 p = (
172 Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
173 / IP(src=self.pg0.remote_ip4, dst=self.pg0.remote_ip4)
174 / UDP(sport=1234, dport=1234)
175 / Raw(b"\xa5" * 100)
176 )
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400177 self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg0)
Neale Rannsccc70f62018-10-02 07:28:16 -0700178
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200179 p = (
180 Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac)
181 / IP(src=self.pg1.remote_ip4, dst=self.pg1.remote_ip4)
182 / UDP(sport=1234, dport=1234)
183 / Raw(b"\xa5" * 100)
184 )
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400185 self.send_and_expect(self.pg1, p * NUM_PKTS, self.pg1)
Neale Rannsccc70f62018-10-02 07:28:16 -0700186
187 #
188 # dump the SVS configs
189 #
190 ss = self.vapi.svs_dump()
191
192 self.assertEqual(ss[0].table_id, table_ids[0])
193 self.assertEqual(ss[0].sw_if_index, self.pg0.sw_if_index)
Ole Troan0685da42018-10-16 14:42:50 +0200194 self.assertEqual(ss[0].af, VppEnum.vl_api_address_family_t.ADDRESS_IP4)
Neale Rannsccc70f62018-10-02 07:28:16 -0700195 self.assertEqual(ss[1].table_id, table_ids[1])
196 self.assertEqual(ss[1].sw_if_index, self.pg1.sw_if_index)
Ole Troan0685da42018-10-16 14:42:50 +0200197 self.assertEqual(ss[1].af, VppEnum.vl_api_address_family_t.ADDRESS_IP4)
Neale Rannsccc70f62018-10-02 07:28:16 -0700198
199 #
200 # cleanup
201 #
Ole Troan0685da42018-10-16 14:42:50 +0200202 self.vapi.svs_enable_disable(
Ole Troan5c2a2372020-11-19 16:01:23 +0100203 is_enable=0,
204 af=VppEnum.vl_api_address_family_t.ADDRESS_IP4,
205 table_id=table_ids[0],
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200206 sw_if_index=self.pg0.sw_if_index,
207 )
Ole Troan0685da42018-10-16 14:42:50 +0200208 self.vapi.svs_enable_disable(
Ole Troan5c2a2372020-11-19 16:01:23 +0100209 is_enable=0,
210 af=VppEnum.vl_api_address_family_t.ADDRESS_IP4,
211 table_id=table_ids[1],
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200212 sw_if_index=self.pg1.sw_if_index,
213 )
Neale Rannsccc70f62018-10-02 07:28:16 -0700214
215 for table_id in table_ids:
216 for i in range(1, 4):
217 self.vapi.svs_route_add_del(
Ole Troan5c2a2372020-11-19 16:01:23 +0100218 is_add=0,
219 prefix="%d.0.0.0/8" % i,
220 table_id=table_id,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200221 source_table_id=0,
222 )
Ole Troan5c2a2372020-11-19 16:01:23 +0100223
Ole Troan0685da42018-10-16 14:42:50 +0200224 self.vapi.svs_table_add_del(
Ole Troan5c2a2372020-11-19 16:01:23 +0100225 is_add=0,
226 af=VppEnum.vl_api_address_family_t.ADDRESS_IP4,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200227 table_id=table_id,
228 )
Neale Rannsccc70f62018-10-02 07:28:16 -0700229
230 def test_svs6(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200231 """Source VRF Select IP6"""
Neale Rannsccc70f62018-10-02 07:28:16 -0700232
233 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700234 # packets destined out of the 3 non-default table interfaces
Neale Rannsccc70f62018-10-02 07:28:16 -0700235 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200236 pkts_0 = [
237 (
238 Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
239 / IPv6(src="2001:1::1", dst=self.pg1.remote_ip6)
240 / UDP(sport=1234, dport=1234)
241 / Raw(b"\xa5" * 100)
242 ),
243 (
244 Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
245 / IPv6(src="2001:2::1", dst=self.pg2.remote_ip6)
246 / UDP(sport=1234, dport=1234)
247 / Raw(b"\xa5" * 100)
248 ),
249 (
250 Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
251 / IPv6(src="2001:3::1", dst=self.pg3.remote_ip6)
252 / UDP(sport=1234, dport=1234)
253 / Raw(b"\xa5" * 100)
254 ),
255 ]
256 pkts_1 = [
257 (
258 Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac)
259 / IPv6(src="2001:1::1", dst=self.pg1.remote_ip6)
260 / UDP(sport=1234, dport=1234)
261 / Raw(b"\xa5" * 100)
262 ),
263 (
264 Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac)
265 / IPv6(src="2001:2::1", dst=self.pg2.remote_ip6)
266 / UDP(sport=1234, dport=1234)
267 / Raw(b"\xa5" * 100)
268 ),
269 (
270 Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac)
271 / IPv6(src="2001:3::1", dst=self.pg3.remote_ip6)
272 / UDP(sport=1234, dport=1234)
273 / Raw(b"\xa5" * 100)
274 ),
275 ]
Neale Rannsccc70f62018-10-02 07:28:16 -0700276
277 #
278 # before adding the SVS config all these packets are dropped when
279 # ingressing on pg0 since pg0 is in the default table
280 #
281 for p in pkts_0:
282 self.send_and_assert_no_replies(self.pg0, p * 1)
283
284 #
285 # Add table 1001 & 1002 into which we'll add the routes
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700286 # determining the source VRF selection
Neale Rannsccc70f62018-10-02 07:28:16 -0700287 #
288 table_ids = [101, 102]
289
290 for table_id in table_ids:
Ole Troan0685da42018-10-16 14:42:50 +0200291 self.vapi.svs_table_add_del(
Ole Troan5c2a2372020-11-19 16:01:23 +0100292 is_add=1,
293 af=VppEnum.vl_api_address_family_t.ADDRESS_IP6,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200294 table_id=table_id,
295 )
Neale Rannsccc70f62018-10-02 07:28:16 -0700296
297 #
298 # map X.0.0.0/8 to each SVS table for lookup in table X
299 #
300 for i in range(1, 4):
301 self.vapi.svs_route_add_del(
Ole Troan5c2a2372020-11-19 16:01:23 +0100302 is_add=1,
303 prefix="2001:%d::/32" % i,
304 table_id=table_id,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200305 source_table_id=i,
306 )
Neale Rannsccc70f62018-10-02 07:28:16 -0700307
308 #
309 # Enable SVS on pg0/pg1 using table 1001/1002
310 #
Ole Troan0685da42018-10-16 14:42:50 +0200311 self.vapi.svs_enable_disable(
Ole Troan5c2a2372020-11-19 16:01:23 +0100312 is_enable=1,
313 af=VppEnum.vl_api_address_family_t.ADDRESS_IP6,
314 table_id=table_ids[0],
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200315 sw_if_index=self.pg0.sw_if_index,
316 )
Ole Troan0685da42018-10-16 14:42:50 +0200317 self.vapi.svs_enable_disable(
Ole Troan5c2a2372020-11-19 16:01:23 +0100318 is_enable=1,
319 af=VppEnum.vl_api_address_family_t.ADDRESS_IP6,
320 table_id=table_ids[1],
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200321 sw_if_index=self.pg1.sw_if_index,
322 )
Neale Rannsccc70f62018-10-02 07:28:16 -0700323
324 #
325 # now all the packets should be delivered out the respective interface
326 #
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400327 self.send_and_expect(self.pg0, pkts_0[0] * NUM_PKTS, self.pg1)
328 self.send_and_expect(self.pg0, pkts_0[1] * NUM_PKTS, self.pg2)
329 self.send_and_expect(self.pg0, pkts_0[2] * NUM_PKTS, self.pg3)
330 self.send_and_expect(self.pg1, pkts_1[0] * NUM_PKTS, self.pg1)
331 self.send_and_expect(self.pg1, pkts_1[1] * NUM_PKTS, self.pg2)
332 self.send_and_expect(self.pg1, pkts_1[2] * NUM_PKTS, self.pg3)
Neale Rannsccc70f62018-10-02 07:28:16 -0700333
334 #
335 # check that if the SVS lookup does not match a route the packet
336 # is forwarded using the interface's routing table
337 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200338 p = (
339 Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
340 / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.remote_ip6)
341 / UDP(sport=1234, dport=1234)
342 / Raw(b"\xa5" * 100)
343 )
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400344 self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg0)
Neale Rannsccc70f62018-10-02 07:28:16 -0700345
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200346 p = (
347 Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac)
348 / IPv6(src=self.pg1.remote_ip6, dst=self.pg1.remote_ip6)
349 / UDP(sport=1234, dport=1234)
350 / Raw(b"\xa5" * 100)
351 )
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400352 self.send_and_expect(self.pg1, p * NUM_PKTS, self.pg1)
Neale Rannsccc70f62018-10-02 07:28:16 -0700353
354 #
355 # dump the SVS configs
356 #
357 ss = self.vapi.svs_dump()
358
359 self.assertEqual(ss[0].table_id, table_ids[0])
360 self.assertEqual(ss[0].sw_if_index, self.pg0.sw_if_index)
Ole Troan0685da42018-10-16 14:42:50 +0200361 self.assertEqual(ss[0].af, VppEnum.vl_api_address_family_t.ADDRESS_IP6)
Neale Rannsccc70f62018-10-02 07:28:16 -0700362 self.assertEqual(ss[1].table_id, table_ids[1])
363 self.assertEqual(ss[1].sw_if_index, self.pg1.sw_if_index)
Ole Troan0685da42018-10-16 14:42:50 +0200364 self.assertEqual(ss[1].af, VppEnum.vl_api_address_family_t.ADDRESS_IP6)
Neale Rannsccc70f62018-10-02 07:28:16 -0700365
366 #
367 # cleanup
368 #
Ole Troan0685da42018-10-16 14:42:50 +0200369 self.vapi.svs_enable_disable(
Ole Troan5c2a2372020-11-19 16:01:23 +0100370 is_enable=0,
371 af=VppEnum.vl_api_address_family_t.ADDRESS_IP6,
372 table_id=table_ids[0],
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200373 sw_if_index=self.pg0.sw_if_index,
374 )
Ole Troan0685da42018-10-16 14:42:50 +0200375 self.vapi.svs_enable_disable(
Ole Troan5c2a2372020-11-19 16:01:23 +0100376 is_enable=0,
377 af=VppEnum.vl_api_address_family_t.ADDRESS_IP6,
378 table_id=table_ids[1],
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200379 sw_if_index=self.pg1.sw_if_index,
380 )
Ole Troan5c2a2372020-11-19 16:01:23 +0100381
Neale Rannsccc70f62018-10-02 07:28:16 -0700382 for table_id in table_ids:
383 for i in range(1, 4):
384 self.vapi.svs_route_add_del(
Ole Troan5c2a2372020-11-19 16:01:23 +0100385 is_add=0,
386 prefix="2001:%d::/32" % i,
387 table_id=table_id,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200388 source_table_id=0,
389 )
Ole Troan0685da42018-10-16 14:42:50 +0200390
Ole Troan5c2a2372020-11-19 16:01:23 +0100391 self.vapi.svs_table_add_del(
392 is_add=0,
393 af=VppEnum.vl_api_address_family_t.ADDRESS_IP6,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200394 table_id=table_id,
395 )
Neale Rannsccc70f62018-10-02 07:28:16 -0700396
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200397
398if __name__ == "__main__":
Neale Rannsccc70f62018-10-02 07:28:16 -0700399 unittest.main(testRunner=VppTestRunner)