blob: 1efc8fc846b818a9193e5b3f5b654f766098947e [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
Dave Wallace8800f732023-08-31 00:47:44 -04005from framework import VppTestCase
6from asfframework import VppTestRunner
Neale Rannsccc70f62018-10-02 07:28:16 -07007from vpp_ip_route import VppIpTable
8
9from scapy.packet import Raw
10from scapy.layers.l2 import Ether
Dave Wallace8800f732023-08-31 00:47:44 -040011from scapy.layers.inet import IP, UDP
Neale Rannsccc70f62018-10-02 07:28:16 -070012from scapy.layers.inet6 import IPv6
13
Ole Troan0685da42018-10-16 14:42:50 +020014from vpp_papi import VppEnum
15
Paul Vinciguerra4271c972019-05-14 13:25:49 -040016NUM_PKTS = 67
17
Neale Rannsccc70f62018-10-02 07:28:16 -070018
19class TestSVS(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020020 """SVS Test Case"""
Neale Rannsccc70f62018-10-02 07:28:16 -070021
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -070022 @classmethod
23 def setUpClass(cls):
24 super(TestSVS, cls).setUpClass()
25
26 @classmethod
27 def tearDownClass(cls):
28 super(TestSVS, cls).tearDownClass()
29
Neale Rannsccc70f62018-10-02 07:28:16 -070030 def setUp(self):
31 super(TestSVS, self).setUp()
32
33 # create 2 pg interfaces
34 self.create_pg_interfaces(range(4))
35
36 table_id = 0
37
38 for i in self.pg_interfaces:
39 i.admin_up()
40
41 if table_id != 0:
42 tbl = VppIpTable(self, table_id)
43 tbl.add_vpp_config()
44 tbl = VppIpTable(self, table_id, is_ip6=1)
45 tbl.add_vpp_config()
46
47 i.set_table_ip4(table_id)
48 i.set_table_ip6(table_id)
49 i.config_ip4()
50 i.resolve_arp()
51 i.config_ip6()
52 i.resolve_ndp()
53 table_id += 1
54
55 def tearDown(self):
56 for i in self.pg_interfaces:
57 i.unconfig_ip4()
58 i.unconfig_ip6()
Neale Rannsccc70f62018-10-02 07:28:16 -070059 i.set_table_ip4(0)
60 i.set_table_ip6(0)
61 i.admin_down()
62 super(TestSVS, self).tearDown()
63
64 def test_svs4(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020065 """Source VRF Select IP4"""
Neale Rannsccc70f62018-10-02 07:28:16 -070066
67 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -070068 # packets destined out of the 3 non-default table interfaces
Neale Rannsccc70f62018-10-02 07:28:16 -070069 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020070 pkts_0 = [
71 (
72 Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
73 / IP(src="1.1.1.1", dst=self.pg1.remote_ip4)
74 / UDP(sport=1234, dport=1234)
75 / Raw(b"\xa5" * 100)
76 ),
77 (
78 Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
79 / IP(src="2.2.2.2", dst=self.pg2.remote_ip4)
80 / UDP(sport=1234, dport=1234)
81 / Raw(b"\xa5" * 100)
82 ),
83 (
84 Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
85 / IP(src="3.3.3.3", dst=self.pg3.remote_ip4)
86 / UDP(sport=1234, dport=1234)
87 / Raw(b"\xa5" * 100)
88 ),
89 ]
90 pkts_1 = [
91 (
92 Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac)
93 / IP(src="1.1.1.1", dst=self.pg1.remote_ip4)
94 / UDP(sport=1234, dport=1234)
95 / Raw(b"\xa5" * 100)
96 ),
97 (
98 Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac)
99 / IP(src="2.2.2.2", dst=self.pg2.remote_ip4)
100 / UDP(sport=1234, dport=1234)
101 / Raw(b"\xa5" * 100)
102 ),
103 (
104 Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac)
105 / IP(src="3.3.3.3", dst=self.pg3.remote_ip4)
106 / UDP(sport=1234, dport=1234)
107 / Raw(b"\xa5" * 100)
108 ),
109 ]
Neale Rannsccc70f62018-10-02 07:28:16 -0700110
111 #
112 # before adding the SVS config all these packets are dropped when
113 # ingressing on pg0 since pg0 is in the default table
114 #
115 for p in pkts_0:
116 self.send_and_assert_no_replies(self.pg0, p * 1)
117
118 #
119 # Add table 1001 & 1002 into which we'll add the routes
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700120 # determining the source VRF selection
Neale Rannsccc70f62018-10-02 07:28:16 -0700121 #
122 table_ids = [101, 102]
123
124 for table_id in table_ids:
Ole Troan0685da42018-10-16 14:42:50 +0200125 self.vapi.svs_table_add_del(
Ole Troan5c2a2372020-11-19 16:01:23 +0100126 is_add=1,
127 af=VppEnum.vl_api_address_family_t.ADDRESS_IP4,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200128 table_id=table_id,
129 )
Neale Rannsccc70f62018-10-02 07:28:16 -0700130
131 #
132 # map X.0.0.0/8 to each SVS table for lookup in table X
133 #
134 for i in range(1, 4):
135 self.vapi.svs_route_add_del(
Ole Troan5c2a2372020-11-19 16:01:23 +0100136 is_add=1,
137 prefix="%d.0.0.0/8" % i,
138 table_id=table_id,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200139 source_table_id=i,
140 )
Neale Rannsccc70f62018-10-02 07:28:16 -0700141
142 #
143 # Enable SVS on pg0/pg1 using table 1001/1002
144 #
Ole Troan0685da42018-10-16 14:42:50 +0200145 self.vapi.svs_enable_disable(
Ole Troan5c2a2372020-11-19 16:01:23 +0100146 is_enable=1,
147 af=VppEnum.vl_api_address_family_t.ADDRESS_IP4,
148 table_id=table_ids[0],
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200149 sw_if_index=self.pg0.sw_if_index,
150 )
Ole Troan0685da42018-10-16 14:42:50 +0200151 self.vapi.svs_enable_disable(
Ole Troan5c2a2372020-11-19 16:01:23 +0100152 is_enable=1,
153 af=VppEnum.vl_api_address_family_t.ADDRESS_IP4,
154 table_id=table_ids[1],
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200155 sw_if_index=self.pg1.sw_if_index,
156 )
Neale Rannsccc70f62018-10-02 07:28:16 -0700157
158 #
159 # now all the packets should be delivered out the respective interface
160 #
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400161 self.send_and_expect(self.pg0, pkts_0[0] * NUM_PKTS, self.pg1)
162 self.send_and_expect(self.pg0, pkts_0[1] * NUM_PKTS, self.pg2)
163 self.send_and_expect(self.pg0, pkts_0[2] * NUM_PKTS, self.pg3)
164 self.send_and_expect(self.pg1, pkts_1[0] * NUM_PKTS, self.pg1)
165 self.send_and_expect(self.pg1, pkts_1[1] * NUM_PKTS, self.pg2)
166 self.send_and_expect(self.pg1, pkts_1[2] * NUM_PKTS, self.pg3)
Neale Rannsccc70f62018-10-02 07:28:16 -0700167
168 #
169 # check that if the SVS lookup does not match a route the packet
170 # is forwarded using the interface's routing table
171 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200172 p = (
173 Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
174 / IP(src=self.pg0.remote_ip4, dst=self.pg0.remote_ip4)
175 / UDP(sport=1234, dport=1234)
176 / Raw(b"\xa5" * 100)
177 )
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400178 self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg0)
Neale Rannsccc70f62018-10-02 07:28:16 -0700179
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200180 p = (
181 Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac)
182 / IP(src=self.pg1.remote_ip4, dst=self.pg1.remote_ip4)
183 / UDP(sport=1234, dport=1234)
184 / Raw(b"\xa5" * 100)
185 )
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400186 self.send_and_expect(self.pg1, p * NUM_PKTS, self.pg1)
Neale Rannsccc70f62018-10-02 07:28:16 -0700187
188 #
189 # dump the SVS configs
190 #
191 ss = self.vapi.svs_dump()
192
193 self.assertEqual(ss[0].table_id, table_ids[0])
194 self.assertEqual(ss[0].sw_if_index, self.pg0.sw_if_index)
Ole Troan0685da42018-10-16 14:42:50 +0200195 self.assertEqual(ss[0].af, VppEnum.vl_api_address_family_t.ADDRESS_IP4)
Neale Rannsccc70f62018-10-02 07:28:16 -0700196 self.assertEqual(ss[1].table_id, table_ids[1])
197 self.assertEqual(ss[1].sw_if_index, self.pg1.sw_if_index)
Ole Troan0685da42018-10-16 14:42:50 +0200198 self.assertEqual(ss[1].af, VppEnum.vl_api_address_family_t.ADDRESS_IP4)
Neale Rannsccc70f62018-10-02 07:28:16 -0700199
200 #
201 # cleanup
202 #
Ole Troan0685da42018-10-16 14:42:50 +0200203 self.vapi.svs_enable_disable(
Ole Troan5c2a2372020-11-19 16:01:23 +0100204 is_enable=0,
205 af=VppEnum.vl_api_address_family_t.ADDRESS_IP4,
206 table_id=table_ids[0],
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200207 sw_if_index=self.pg0.sw_if_index,
208 )
Ole Troan0685da42018-10-16 14:42:50 +0200209 self.vapi.svs_enable_disable(
Ole Troan5c2a2372020-11-19 16:01:23 +0100210 is_enable=0,
211 af=VppEnum.vl_api_address_family_t.ADDRESS_IP4,
212 table_id=table_ids[1],
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200213 sw_if_index=self.pg1.sw_if_index,
214 )
Neale Rannsccc70f62018-10-02 07:28:16 -0700215
216 for table_id in table_ids:
217 for i in range(1, 4):
218 self.vapi.svs_route_add_del(
Ole Troan5c2a2372020-11-19 16:01:23 +0100219 is_add=0,
220 prefix="%d.0.0.0/8" % i,
221 table_id=table_id,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200222 source_table_id=0,
223 )
Ole Troan5c2a2372020-11-19 16:01:23 +0100224
Ole Troan0685da42018-10-16 14:42:50 +0200225 self.vapi.svs_table_add_del(
Ole Troan5c2a2372020-11-19 16:01:23 +0100226 is_add=0,
227 af=VppEnum.vl_api_address_family_t.ADDRESS_IP4,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200228 table_id=table_id,
229 )
Neale Rannsccc70f62018-10-02 07:28:16 -0700230
231 def test_svs6(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200232 """Source VRF Select IP6"""
Neale Rannsccc70f62018-10-02 07:28:16 -0700233
234 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700235 # packets destined out of the 3 non-default table interfaces
Neale Rannsccc70f62018-10-02 07:28:16 -0700236 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200237 pkts_0 = [
238 (
239 Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
240 / IPv6(src="2001:1::1", dst=self.pg1.remote_ip6)
241 / UDP(sport=1234, dport=1234)
242 / Raw(b"\xa5" * 100)
243 ),
244 (
245 Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
246 / IPv6(src="2001:2::1", dst=self.pg2.remote_ip6)
247 / UDP(sport=1234, dport=1234)
248 / Raw(b"\xa5" * 100)
249 ),
250 (
251 Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
252 / IPv6(src="2001:3::1", dst=self.pg3.remote_ip6)
253 / UDP(sport=1234, dport=1234)
254 / Raw(b"\xa5" * 100)
255 ),
256 ]
257 pkts_1 = [
258 (
259 Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac)
260 / IPv6(src="2001:1::1", dst=self.pg1.remote_ip6)
261 / UDP(sport=1234, dport=1234)
262 / Raw(b"\xa5" * 100)
263 ),
264 (
265 Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac)
266 / IPv6(src="2001:2::1", dst=self.pg2.remote_ip6)
267 / UDP(sport=1234, dport=1234)
268 / Raw(b"\xa5" * 100)
269 ),
270 (
271 Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac)
272 / IPv6(src="2001:3::1", dst=self.pg3.remote_ip6)
273 / UDP(sport=1234, dport=1234)
274 / Raw(b"\xa5" * 100)
275 ),
276 ]
Neale Rannsccc70f62018-10-02 07:28:16 -0700277
278 #
279 # before adding the SVS config all these packets are dropped when
280 # ingressing on pg0 since pg0 is in the default table
281 #
282 for p in pkts_0:
283 self.send_and_assert_no_replies(self.pg0, p * 1)
284
285 #
286 # Add table 1001 & 1002 into which we'll add the routes
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700287 # determining the source VRF selection
Neale Rannsccc70f62018-10-02 07:28:16 -0700288 #
289 table_ids = [101, 102]
290
291 for table_id in table_ids:
Ole Troan0685da42018-10-16 14:42:50 +0200292 self.vapi.svs_table_add_del(
Ole Troan5c2a2372020-11-19 16:01:23 +0100293 is_add=1,
294 af=VppEnum.vl_api_address_family_t.ADDRESS_IP6,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200295 table_id=table_id,
296 )
Neale Rannsccc70f62018-10-02 07:28:16 -0700297
298 #
299 # map X.0.0.0/8 to each SVS table for lookup in table X
300 #
301 for i in range(1, 4):
302 self.vapi.svs_route_add_del(
Ole Troan5c2a2372020-11-19 16:01:23 +0100303 is_add=1,
304 prefix="2001:%d::/32" % i,
305 table_id=table_id,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200306 source_table_id=i,
307 )
Neale Rannsccc70f62018-10-02 07:28:16 -0700308
309 #
310 # Enable SVS on pg0/pg1 using table 1001/1002
311 #
Ole Troan0685da42018-10-16 14:42:50 +0200312 self.vapi.svs_enable_disable(
Ole Troan5c2a2372020-11-19 16:01:23 +0100313 is_enable=1,
314 af=VppEnum.vl_api_address_family_t.ADDRESS_IP6,
315 table_id=table_ids[0],
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200316 sw_if_index=self.pg0.sw_if_index,
317 )
Ole Troan0685da42018-10-16 14:42:50 +0200318 self.vapi.svs_enable_disable(
Ole Troan5c2a2372020-11-19 16:01:23 +0100319 is_enable=1,
320 af=VppEnum.vl_api_address_family_t.ADDRESS_IP6,
321 table_id=table_ids[1],
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200322 sw_if_index=self.pg1.sw_if_index,
323 )
Neale Rannsccc70f62018-10-02 07:28:16 -0700324
325 #
326 # now all the packets should be delivered out the respective interface
327 #
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400328 self.send_and_expect(self.pg0, pkts_0[0] * NUM_PKTS, self.pg1)
329 self.send_and_expect(self.pg0, pkts_0[1] * NUM_PKTS, self.pg2)
330 self.send_and_expect(self.pg0, pkts_0[2] * NUM_PKTS, self.pg3)
331 self.send_and_expect(self.pg1, pkts_1[0] * NUM_PKTS, self.pg1)
332 self.send_and_expect(self.pg1, pkts_1[1] * NUM_PKTS, self.pg2)
333 self.send_and_expect(self.pg1, pkts_1[2] * NUM_PKTS, self.pg3)
Neale Rannsccc70f62018-10-02 07:28:16 -0700334
335 #
336 # check that if the SVS lookup does not match a route the packet
337 # is forwarded using the interface's routing table
338 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200339 p = (
340 Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
341 / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.remote_ip6)
342 / UDP(sport=1234, dport=1234)
343 / Raw(b"\xa5" * 100)
344 )
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400345 self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg0)
Neale Rannsccc70f62018-10-02 07:28:16 -0700346
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200347 p = (
348 Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac)
349 / IPv6(src=self.pg1.remote_ip6, dst=self.pg1.remote_ip6)
350 / UDP(sport=1234, dport=1234)
351 / Raw(b"\xa5" * 100)
352 )
Paul Vinciguerra4271c972019-05-14 13:25:49 -0400353 self.send_and_expect(self.pg1, p * NUM_PKTS, self.pg1)
Neale Rannsccc70f62018-10-02 07:28:16 -0700354
355 #
356 # dump the SVS configs
357 #
358 ss = self.vapi.svs_dump()
359
360 self.assertEqual(ss[0].table_id, table_ids[0])
361 self.assertEqual(ss[0].sw_if_index, self.pg0.sw_if_index)
Ole Troan0685da42018-10-16 14:42:50 +0200362 self.assertEqual(ss[0].af, VppEnum.vl_api_address_family_t.ADDRESS_IP6)
Neale Rannsccc70f62018-10-02 07:28:16 -0700363 self.assertEqual(ss[1].table_id, table_ids[1])
364 self.assertEqual(ss[1].sw_if_index, self.pg1.sw_if_index)
Ole Troan0685da42018-10-16 14:42:50 +0200365 self.assertEqual(ss[1].af, VppEnum.vl_api_address_family_t.ADDRESS_IP6)
Neale Rannsccc70f62018-10-02 07:28:16 -0700366
367 #
368 # cleanup
369 #
Ole Troan0685da42018-10-16 14:42:50 +0200370 self.vapi.svs_enable_disable(
Ole Troan5c2a2372020-11-19 16:01:23 +0100371 is_enable=0,
372 af=VppEnum.vl_api_address_family_t.ADDRESS_IP6,
373 table_id=table_ids[0],
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200374 sw_if_index=self.pg0.sw_if_index,
375 )
Ole Troan0685da42018-10-16 14:42:50 +0200376 self.vapi.svs_enable_disable(
Ole Troan5c2a2372020-11-19 16:01:23 +0100377 is_enable=0,
378 af=VppEnum.vl_api_address_family_t.ADDRESS_IP6,
379 table_id=table_ids[1],
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200380 sw_if_index=self.pg1.sw_if_index,
381 )
Ole Troan5c2a2372020-11-19 16:01:23 +0100382
Neale Rannsccc70f62018-10-02 07:28:16 -0700383 for table_id in table_ids:
384 for i in range(1, 4):
385 self.vapi.svs_route_add_del(
Ole Troan5c2a2372020-11-19 16:01:23 +0100386 is_add=0,
387 prefix="2001:%d::/32" % i,
388 table_id=table_id,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200389 source_table_id=0,
390 )
Ole Troan0685da42018-10-16 14:42:50 +0200391
Ole Troan5c2a2372020-11-19 16:01:23 +0100392 self.vapi.svs_table_add_del(
393 is_add=0,
394 af=VppEnum.vl_api_address_family_t.ADDRESS_IP6,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200395 table_id=table_id,
396 )
Neale Rannsccc70f62018-10-02 07:28:16 -0700397
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200398
399if __name__ == "__main__":
Neale Rannsccc70f62018-10-02 07:28:16 -0700400 unittest.main(testRunner=VppTestRunner)