blob: cd44f94d951d19a7ed2c576393501a77eb88a2ed [file] [log] [blame]
Renato Botelho do Coutoead1e532019-10-31 13:31:07 -05001#!/usr/bin/env python3
Neale Ranns8fe8cc22016-11-01 10:05:08 +00002
3import unittest
Neale Ranns8fe8cc22016-11-01 10:05:08 +00004
Dave Wallace8800f732023-08-31 00:47:44 -04005from framework import VppTestCase
6from asfframework import VppTestRunner, tag_fixme_vpp_workers
7from vpp_ip import INVALID_INDEX
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02008from vpp_ip_route import (
9 VppIpRoute,
10 VppRoutePath,
11 VppMplsRoute,
12 VppMplsIpBind,
13 VppIpMRoute,
14 VppMRoutePath,
15 VppIpTable,
16 VppMplsTable,
17 VppMplsLabel,
18 MplsLspMode,
19 find_mpls_route,
20 FibPathProto,
21 FibPathType,
22 FibPathFlags,
23 VppMplsLabel,
24 MplsLspMode,
25)
Neale Ranns0f26c5a2017-03-01 15:12:11 -080026from vpp_mpls_tunnel_interface import VppMPLSTunnelInterface
Neale Ranns990f6942020-10-20 07:20:17 +000027from vpp_papi import VppEnum
Neale Ranns8fe8cc22016-11-01 10:05:08 +000028
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -070029import scapy.compat
Neale Ranns8fe8cc22016-11-01 10:05:08 +000030from scapy.packet import Raw
Neale Ranns1976f362019-11-06 13:13:01 +000031from scapy.layers.l2 import Ether, ARP
Neale Rannsfbc633f2022-03-18 13:05:09 +000032from scapy.layers.inet import IP, UDP, ICMP, icmptypes, icmpcodes
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020033from scapy.layers.inet6 import (
34 IPv6,
35 ICMPv6TimeExceeded,
36 ICMPv6EchoRequest,
37 ICMPv6PacketTooBig,
38)
Neale Ranns8fe8cc22016-11-01 10:05:08 +000039from scapy.contrib.mpls import MPLS
40
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -040041NUM_PKTS = 67
42
Neale Ranns1976f362019-11-06 13:13:01 +000043# scapy removed these attributes.
44# we asked that they be restored: https://github.com/secdev/scapy/pull/1878
45# semantic names have more meaning than numbers. so here they are.
46ARP.who_has = 1
47ARP.is_at = 2
48
Klement Sekeradab231a2016-12-21 08:50:14 +010049
Neale Rannsda78f952017-05-24 09:15:43 -070050def verify_filter(capture, sent):
51 if not len(capture) == len(sent):
52 # filter out any IPv6 RAs from the capture
53 for p in capture:
54 if p.haslayer(IPv6):
55 capture.remove(p)
56 return capture
57
58
Neale Ranns31ed7442018-02-23 05:29:09 -080059def verify_mpls_stack(tst, rx, mpls_labels):
Neale Rannsda78f952017-05-24 09:15:43 -070060 # the rx'd packet has the MPLS label popped
61 eth = rx[Ether]
62 tst.assertEqual(eth.type, 0x8847)
63
64 rx_mpls = rx[MPLS]
65
66 for ii in range(len(mpls_labels)):
Neale Ranns31ed7442018-02-23 05:29:09 -080067 tst.assertEqual(rx_mpls.label, mpls_labels[ii].value)
68 tst.assertEqual(rx_mpls.cos, mpls_labels[ii].exp)
69 tst.assertEqual(rx_mpls.ttl, mpls_labels[ii].ttl)
70
Neale Rannsda78f952017-05-24 09:15:43 -070071 if ii == len(mpls_labels) - 1:
72 tst.assertEqual(rx_mpls.s, 1)
73 else:
74 # not end of stack
75 tst.assertEqual(rx_mpls.s, 0)
76 # pop the label to expose the next
77 rx_mpls = rx_mpls[MPLS].payload
78
79
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +000080@tag_fixme_vpp_workers
Neale Ranns8fe8cc22016-11-01 10:05:08 +000081class TestMPLS(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020082 """MPLS Test Case"""
Neale Ranns8fe8cc22016-11-01 10:05:08 +000083
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -070084 @classmethod
85 def setUpClass(cls):
86 super(TestMPLS, cls).setUpClass()
87
88 @classmethod
89 def tearDownClass(cls):
90 super(TestMPLS, cls).tearDownClass()
91
Neale Ranns8fe8cc22016-11-01 10:05:08 +000092 def setUp(self):
93 super(TestMPLS, self).setUp()
94
95 # create 2 pg interfaces
Neale Ranns0f26c5a2017-03-01 15:12:11 -080096 self.create_pg_interfaces(range(4))
Neale Ranns8fe8cc22016-11-01 10:05:08 +000097
98 # setup both interfaces
99 # assign them different tables.
100 table_id = 0
Neale Ranns15002542017-09-10 04:39:11 -0700101 self.tables = []
102
103 tbl = VppMplsTable(self, 0)
104 tbl.add_vpp_config()
105 self.tables.append(tbl)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000106
107 for i in self.pg_interfaces:
108 i.admin_up()
Neale Ranns15002542017-09-10 04:39:11 -0700109
110 if table_id != 0:
111 tbl = VppIpTable(self, table_id)
112 tbl.add_vpp_config()
113 self.tables.append(tbl)
114 tbl = VppIpTable(self, table_id, is_ip6=1)
115 tbl.add_vpp_config()
116 self.tables.append(tbl)
117
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000118 i.set_table_ip4(table_id)
119 i.set_table_ip6(table_id)
120 i.config_ip4()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000121 i.resolve_arp()
Neale Rannsad422ed2016-11-02 14:20:04 +0000122 i.config_ip6()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000123 i.resolve_ndp()
Neale Rannsad422ed2016-11-02 14:20:04 +0000124 i.enable_mpls()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000125 table_id += 1
126
127 def tearDown(self):
Neale Ranns4008ac92017-02-13 23:20:04 -0800128 for i in self.pg_interfaces:
129 i.unconfig_ip4()
130 i.unconfig_ip6()
Neale Ranns15002542017-09-10 04:39:11 -0700131 i.set_table_ip4(0)
132 i.set_table_ip6(0)
133 i.disable_mpls()
Neale Ranns4008ac92017-02-13 23:20:04 -0800134 i.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -0700135 super(TestMPLS, self).tearDown()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000136
Neale Rannsad422ed2016-11-02 14:20:04 +0000137 # the default of 64 matches the IP packet TTL default
Klement Sekeradab231a2016-12-21 08:50:14 +0100138 def create_stream_labelled_ip4(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200139 self,
140 src_if,
141 mpls_labels,
142 ping=0,
143 ip_itf=None,
144 dst_ip=None,
145 chksum=None,
146 ip_ttl=64,
147 n=257,
148 ):
Klement Sekeradab231a2016-12-21 08:50:14 +0100149 self.reset_packet_infos()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000150 pkts = []
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800151 for i in range(0, n):
Klement Sekeradab231a2016-12-21 08:50:14 +0100152 info = self.create_packet_info(src_if, src_if)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000153 payload = self.info_to_payload(info)
Neale Rannsad422ed2016-11-02 14:20:04 +0000154 p = Ether(dst=src_if.local_mac, src=src_if.remote_mac)
155
156 for ii in range(len(mpls_labels)):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200157 p = p / MPLS(
158 label=mpls_labels[ii].value,
159 ttl=mpls_labels[ii].ttl,
160 cos=mpls_labels[ii].exp,
161 )
Neale Rannscb630ff2016-12-14 13:31:29 +0100162 if not ping:
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800163 if not dst_ip:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200164 p = (
165 p
166 / IP(src=src_if.local_ip4, dst=src_if.remote_ip4, ttl=ip_ttl)
167 / UDP(sport=1234, dport=1234)
168 / Raw(payload)
169 )
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800170 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200171 p = (
172 p
173 / IP(src=src_if.local_ip4, dst=dst_ip, ttl=ip_ttl)
174 / UDP(sport=1234, dport=1234)
175 / Raw(payload)
176 )
Neale Rannscb630ff2016-12-14 13:31:29 +0100177 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200178 p = (
179 p
180 / IP(src=ip_itf.remote_ip4, dst=ip_itf.local_ip4, ttl=ip_ttl)
181 / ICMP()
182 )
Neale Rannscb630ff2016-12-14 13:31:29 +0100183
Neale Ranns4c7c8e52017-10-21 09:37:55 -0700184 if chksum:
185 p[IP].chksum = chksum
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000186 info.data = p.copy()
187 pkts.append(p)
188 return pkts
189
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200190 def create_stream_ip4(
191 self, src_if, dst_ip, ip_ttl=64, ip_dscp=0, payload_size=None
192 ):
Klement Sekeradab231a2016-12-21 08:50:14 +0100193 self.reset_packet_infos()
Neale Rannsad422ed2016-11-02 14:20:04 +0000194 pkts = []
195 for i in range(0, 257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100196 info = self.create_packet_info(src_if, src_if)
Neale Rannsad422ed2016-11-02 14:20:04 +0000197 payload = self.info_to_payload(info)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200198 p = (
199 Ether(dst=src_if.local_mac, src=src_if.remote_mac)
200 / IP(src=src_if.remote_ip4, dst=dst_ip, ttl=ip_ttl, tos=ip_dscp)
201 / UDP(sport=1234, dport=1234)
202 / Raw(payload)
203 )
Neale Rannsad422ed2016-11-02 14:20:04 +0000204 info.data = p.copy()
Ole Troaneb284a12019-10-09 13:33:19 +0200205 if payload_size:
206 self.extend_packet(p, payload_size)
Neale Rannsad422ed2016-11-02 14:20:04 +0000207 pkts.append(p)
208 return pkts
209
Neale Ranns31ed7442018-02-23 05:29:09 -0800210 def create_stream_ip6(self, src_if, dst_ip, ip_ttl=64, ip_dscp=0):
211 self.reset_packet_infos()
212 pkts = []
213 for i in range(0, 257):
214 info = self.create_packet_info(src_if, src_if)
215 payload = self.info_to_payload(info)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200216 p = (
217 Ether(dst=src_if.local_mac, src=src_if.remote_mac)
218 / IPv6(src=src_if.remote_ip6, dst=dst_ip, hlim=ip_ttl, tc=ip_dscp)
219 / UDP(sport=1234, dport=1234)
220 / Raw(payload)
221 )
Neale Ranns31ed7442018-02-23 05:29:09 -0800222 info.data = p.copy()
223 pkts.append(p)
224 return pkts
225
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200226 def create_stream_labelled_ip6(
227 self, src_if, mpls_labels, hlim=64, dst_ip=None, ping=0, ip_itf=None
228 ):
Neale Ranns31426c62017-05-24 10:32:58 -0700229 if dst_ip is None:
230 dst_ip = src_if.remote_ip6
Klement Sekeradab231a2016-12-21 08:50:14 +0100231 self.reset_packet_infos()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000232 pkts = []
233 for i in range(0, 257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100234 info = self.create_packet_info(src_if, src_if)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000235 payload = self.info_to_payload(info)
Neale Ranns31ed7442018-02-23 05:29:09 -0800236 p = Ether(dst=src_if.local_mac, src=src_if.remote_mac)
237 for l in mpls_labels:
238 p = p / MPLS(label=l.value, ttl=l.ttl, cos=l.exp)
239
Neale Rannsf478f752022-02-17 15:41:32 +0000240 if ping:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200241 p = p / (
242 IPv6(src=ip_itf.remote_ip6, dst=ip_itf.local_ip6)
243 / ICMPv6EchoRequest()
244 )
Neale Rannsf478f752022-02-17 15:41:32 +0000245 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200246 p = p / (
247 IPv6(src=src_if.remote_ip6, dst=dst_ip, hlim=hlim)
248 / UDP(sport=1234, dport=1234)
249 / Raw(payload)
250 )
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000251 info.data = p.copy()
252 pkts.append(p)
253 return pkts
254
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200255 def verify_capture_ip4(
256 self, src_if, capture, sent, ping_resp=0, ip_ttl=None, ip_dscp=0
257 ):
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000258 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700259 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000260
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000261 self.assertEqual(len(capture), len(sent))
262
263 for i in range(len(capture)):
264 tx = sent[i]
265 rx = capture[i]
266
267 # the rx'd packet has the MPLS label popped
Neale Rannsad422ed2016-11-02 14:20:04 +0000268 eth = rx[Ether]
269 self.assertEqual(eth.type, 0x800)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000270
271 tx_ip = tx[IP]
272 rx_ip = rx[IP]
273
Neale Rannscb630ff2016-12-14 13:31:29 +0100274 if not ping_resp:
275 self.assertEqual(rx_ip.src, tx_ip.src)
276 self.assertEqual(rx_ip.dst, tx_ip.dst)
Neale Ranns31ed7442018-02-23 05:29:09 -0800277 self.assertEqual(rx_ip.tos, ip_dscp)
278 if not ip_ttl:
279 # IP processing post pop has decremented the TTL
280 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
281 else:
282 self.assertEqual(rx_ip.ttl, ip_ttl)
Neale Rannscb630ff2016-12-14 13:31:29 +0100283 else:
284 self.assertEqual(rx_ip.src, tx_ip.dst)
285 self.assertEqual(rx_ip.dst, tx_ip.src)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000286
287 except:
Neale Rannsad422ed2016-11-02 14:20:04 +0000288 raise
289
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200290 def verify_capture_labelled_ip4(
291 self, src_if, capture, sent, mpls_labels, ip_ttl=None
292 ):
Neale Rannsad422ed2016-11-02 14:20:04 +0000293 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700294 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000295
296 self.assertEqual(len(capture), len(sent))
297
298 for i in range(len(capture)):
299 tx = sent[i]
300 rx = capture[i]
301 tx_ip = tx[IP]
302 rx_ip = rx[IP]
303
Neale Ranns31ed7442018-02-23 05:29:09 -0800304 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsad422ed2016-11-02 14:20:04 +0000305
306 self.assertEqual(rx_ip.src, tx_ip.src)
307 self.assertEqual(rx_ip.dst, tx_ip.dst)
Neale Ranns31ed7442018-02-23 05:29:09 -0800308 if not ip_ttl:
309 # IP processing post pop has decremented the TTL
310 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
311 else:
312 self.assertEqual(rx_ip.ttl, ip_ttl)
Neale Rannsad422ed2016-11-02 14:20:04 +0000313
314 except:
315 raise
316
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200317 def verify_capture_labelled_ip6(
318 self, src_if, capture, sent, mpls_labels, ip_ttl=None
319 ):
Neale Ranns31ed7442018-02-23 05:29:09 -0800320 try:
321 capture = verify_filter(capture, sent)
322
323 self.assertEqual(len(capture), len(sent))
324
325 for i in range(len(capture)):
326 tx = sent[i]
327 rx = capture[i]
328 tx_ip = tx[IPv6]
329 rx_ip = rx[IPv6]
330
331 verify_mpls_stack(self, rx, mpls_labels)
332
333 self.assertEqual(rx_ip.src, tx_ip.src)
334 self.assertEqual(rx_ip.dst, tx_ip.dst)
335 if not ip_ttl:
336 # IP processing post pop has decremented the TTL
337 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
338 else:
339 self.assertEqual(rx_ip.hlim, ip_ttl)
340
341 except:
342 raise
343
344 def verify_capture_tunneled_ip4(self, src_if, capture, sent, mpls_labels):
Neale Rannsad422ed2016-11-02 14:20:04 +0000345 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700346 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000347
348 self.assertEqual(len(capture), len(sent))
349
350 for i in range(len(capture)):
351 tx = sent[i]
352 rx = capture[i]
353 tx_ip = tx[IP]
354 rx_ip = rx[IP]
355
Neale Ranns31ed7442018-02-23 05:29:09 -0800356 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsad422ed2016-11-02 14:20:04 +0000357
358 self.assertEqual(rx_ip.src, tx_ip.src)
359 self.assertEqual(rx_ip.dst, tx_ip.dst)
360 # IP processing post pop has decremented the TTL
361 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
362
363 except:
364 raise
365
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200366 def verify_capture_labelled(self, src_if, capture, sent, mpls_labels):
Neale Rannsad422ed2016-11-02 14:20:04 +0000367 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700368 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000369
370 self.assertEqual(len(capture), len(sent))
371
372 for i in range(len(capture)):
373 rx = capture[i]
Neale Ranns31ed7442018-02-23 05:29:09 -0800374 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsad422ed2016-11-02 14:20:04 +0000375 except:
376 raise
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000377
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200378 def verify_capture_ip6(
379 self, src_if, capture, sent, ip_hlim=None, ip_dscp=0, ping_resp=0
380 ):
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000381 try:
382 self.assertEqual(len(capture), len(sent))
383
384 for i in range(len(capture)):
385 tx = sent[i]
386 rx = capture[i]
387
388 # the rx'd packet has the MPLS label popped
Neale Rannsad422ed2016-11-02 14:20:04 +0000389 eth = rx[Ether]
390 self.assertEqual(eth.type, 0x86DD)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000391
392 tx_ip = tx[IPv6]
393 rx_ip = rx[IPv6]
394
Neale Rannsf478f752022-02-17 15:41:32 +0000395 if not ping_resp:
396 self.assertEqual(rx_ip.src, tx_ip.src)
397 self.assertEqual(rx_ip.dst, tx_ip.dst)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200398 self.assertEqual(rx_ip.tc, ip_dscp)
Neale Rannsf478f752022-02-17 15:41:32 +0000399 # IP processing post pop has decremented the TTL
400 if not ip_hlim:
401 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
402 else:
403 self.assertEqual(rx_ip.hlim, ip_hlim)
Neale Ranns31ed7442018-02-23 05:29:09 -0800404 else:
Neale Rannsf478f752022-02-17 15:41:32 +0000405 self.assertEqual(rx_ip.src, tx_ip.dst)
406 self.assertEqual(rx_ip.dst, tx_ip.src)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000407 except:
Neale Rannsad422ed2016-11-02 14:20:04 +0000408 raise
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000409
Neale Ranns62fe07c2017-10-31 12:28:22 -0700410 def verify_capture_ip6_icmp(self, src_if, capture, sent):
411 try:
Neale Ranns5c6dd172022-02-17 09:08:47 +0000412 # rate limited ICMP
413 self.assertTrue(len(capture) <= len(sent))
Neale Ranns62fe07c2017-10-31 12:28:22 -0700414
415 for i in range(len(capture)):
416 tx = sent[i]
417 rx = capture[i]
418
419 # the rx'd packet has the MPLS label popped
420 eth = rx[Ether]
421 self.assertEqual(eth.type, 0x86DD)
422
423 tx_ip = tx[IPv6]
424 rx_ip = rx[IPv6]
425
426 self.assertEqual(rx_ip.dst, tx_ip.src)
427 # ICMP sourced from the interface's address
428 self.assertEqual(rx_ip.src, src_if.local_ip6)
429 # hop-limit reset to 255 for IMCP packet
Ole Troan282093f2018-09-19 12:38:51 +0200430 self.assertEqual(rx_ip.hlim, 255)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700431
432 icmp = rx[ICMPv6TimeExceeded]
433
434 except:
435 raise
436
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200437 def verify_capture_fragmented_labelled_ip4(
438 self, src_if, capture, sent, mpls_labels, ip_ttl=None
439 ):
Rajesh Goeld6f1c9c2019-10-06 13:17:36 +0530440 try:
441 capture = verify_filter(capture, sent)
442
443 for i in range(len(capture)):
444 tx = sent[0]
445 rx = capture[i]
446 tx_ip = tx[IP]
447 rx_ip = rx[IP]
448
449 verify_mpls_stack(self, rx, mpls_labels)
450
451 self.assertEqual(rx_ip.src, tx_ip.src)
452 self.assertEqual(rx_ip.dst, tx_ip.dst)
453 if not ip_ttl:
454 # IP processing post pop has decremented the TTL
455 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
456 else:
457 self.assertEqual(rx_ip.ttl, ip_ttl)
458
459 except:
460 raise
461
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200462 def verify_capture_fragmented_labelled_ip6(
463 self, src_if, capture, sent, mpls_labels, ip_ttl=None
464 ):
Neale Rannsec5371e2022-03-04 11:45:41 +0000465 try:
466 capture = verify_filter(capture, sent)
467
468 for i in range(len(capture)):
469 tx = sent[0]
470 rx = capture[i]
471 tx_ip = tx[IPv6]
472 rx.show()
473 rx_ip = IPv6(rx[MPLS].payload)
474 rx_ip.show()
475
476 verify_mpls_stack(self, rx, mpls_labels)
477
478 self.assertEqual(rx_ip.src, tx_ip.src)
479 self.assertEqual(rx_ip.dst, tx_ip.dst)
480 if not ip_ttl:
481 # IP processing post pop has decremented the hop-limit
482 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
483 else:
484 self.assertEqual(rx_ip.hlim, ip_ttl)
485 except:
486 raise
487
Neale Rannsad422ed2016-11-02 14:20:04 +0000488 def test_swap(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200489 """MPLS label swap tests"""
Neale Rannsad422ed2016-11-02 14:20:04 +0000490
491 #
492 # A simple MPLS xconnect - eos label in label out
493 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200494 route_32_eos = VppMplsRoute(
495 self,
496 32,
497 1,
498 [
499 VppRoutePath(
500 self.pg0.remote_ip4, self.pg0.sw_if_index, labels=[VppMplsLabel(33)]
501 )
502 ],
503 )
Neale Rannsad422ed2016-11-02 14:20:04 +0000504 route_32_eos.add_vpp_config()
505
Neale Ranns775f73c2018-12-20 03:01:49 -0800506 self.assertTrue(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200507 find_mpls_route(
508 self,
509 0,
510 32,
511 1,
512 [
513 VppRoutePath(
514 self.pg0.remote_ip4,
515 self.pg0.sw_if_index,
516 labels=[VppMplsLabel(33)],
517 )
518 ],
519 )
520 )
Neale Ranns775f73c2018-12-20 03:01:49 -0800521
Neale Rannsad422ed2016-11-02 14:20:04 +0000522 #
523 # a stream that matches the route for 10.0.0.1
524 # PG0 is in the default table
525 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200526 tx = self.create_stream_labelled_ip4(
527 self.pg0, [VppMplsLabel(32, ttl=32, exp=1)]
528 )
Neale Ranns31ed7442018-02-23 05:29:09 -0800529 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200530 self.verify_capture_labelled(
531 self.pg0, rx, tx, [VppMplsLabel(33, ttl=31, exp=1)]
532 )
Neale Rannsad422ed2016-11-02 14:20:04 +0000533
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200534 self.assertEqual(route_32_eos.get_stats_to()["packets"], 257)
Neale Ranns008dbe12018-09-07 09:32:36 -0700535
Neale Rannsad422ed2016-11-02 14:20:04 +0000536 #
537 # A simple MPLS xconnect - non-eos label in label out
538 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200539 route_32_neos = VppMplsRoute(
540 self,
541 32,
542 0,
543 [
544 VppRoutePath(
545 self.pg0.remote_ip4, self.pg0.sw_if_index, labels=[VppMplsLabel(33)]
546 )
547 ],
548 )
Neale Rannsad422ed2016-11-02 14:20:04 +0000549 route_32_neos.add_vpp_config()
550
551 #
552 # a stream that matches the route for 10.0.0.1
553 # PG0 is in the default table
554 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200555 tx = self.create_stream_labelled_ip4(
556 self.pg0, [VppMplsLabel(32, ttl=21, exp=7), VppMplsLabel(99)]
557 )
Neale Ranns31ed7442018-02-23 05:29:09 -0800558 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200559 self.verify_capture_labelled(
560 self.pg0, rx, tx, [VppMplsLabel(33, ttl=20, exp=7), VppMplsLabel(99)]
561 )
562 self.assertEqual(route_32_neos.get_stats_to()["packets"], 257)
Neale Rannsad422ed2016-11-02 14:20:04 +0000563
Neale Ranns31ed7442018-02-23 05:29:09 -0800564 #
565 # A simple MPLS xconnect - non-eos label in label out, uniform mode
566 #
567 route_42_neos = VppMplsRoute(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200568 self,
569 42,
570 0,
571 [
572 VppRoutePath(
573 self.pg0.remote_ip4,
574 self.pg0.sw_if_index,
575 labels=[VppMplsLabel(43, MplsLspMode.UNIFORM)],
576 )
577 ],
578 )
Neale Ranns31ed7442018-02-23 05:29:09 -0800579 route_42_neos.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000580
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200581 tx = self.create_stream_labelled_ip4(
582 self.pg0, [VppMplsLabel(42, ttl=21, exp=7), VppMplsLabel(99)]
583 )
Neale Ranns31ed7442018-02-23 05:29:09 -0800584 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200585 self.verify_capture_labelled(
586 self.pg0, rx, tx, [VppMplsLabel(43, ttl=20, exp=7), VppMplsLabel(99)]
587 )
Neale Rannsad422ed2016-11-02 14:20:04 +0000588
589 #
590 # An MPLS xconnect - EOS label in IP out
591 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200592 route_33_eos = VppMplsRoute(
593 self,
594 33,
595 1,
596 [VppRoutePath(self.pg0.remote_ip4, self.pg0.sw_if_index, labels=[])],
597 )
Neale Rannsad422ed2016-11-02 14:20:04 +0000598 route_33_eos.add_vpp_config()
599
Neale Ranns31ed7442018-02-23 05:29:09 -0800600 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(33)])
601 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Rannsad422ed2016-11-02 14:20:04 +0000602 self.verify_capture_ip4(self.pg0, rx, tx)
603
604 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700605 # disposed packets have an invalid IPv4 checksum
Neale Ranns62fe07c2017-10-31 12:28:22 -0700606 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200607 tx = self.create_stream_labelled_ip4(
608 self.pg0, [VppMplsLabel(33)], dst_ip=self.pg0.remote_ip4, n=65, chksum=1
609 )
Neale Ranns62fe07c2017-10-31 12:28:22 -0700610 self.send_and_assert_no_replies(self.pg0, tx, "Invalid Checksum")
611
612 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800613 # An MPLS xconnect - EOS label in IP out, uniform mode
614 #
615 route_3333_eos = VppMplsRoute(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200616 self,
617 3333,
618 1,
619 [
620 VppRoutePath(
621 self.pg0.remote_ip4,
622 self.pg0.sw_if_index,
623 labels=[VppMplsLabel(3, MplsLspMode.UNIFORM)],
624 )
625 ],
626 )
Neale Ranns31ed7442018-02-23 05:29:09 -0800627 route_3333_eos.add_vpp_config()
628
629 tx = self.create_stream_labelled_ip4(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200630 self.pg0, [VppMplsLabel(3333, ttl=55, exp=3)]
631 )
Neale Ranns31ed7442018-02-23 05:29:09 -0800632 rx = self.send_and_expect(self.pg0, tx, self.pg0)
633 self.verify_capture_ip4(self.pg0, rx, tx, ip_ttl=54, ip_dscp=0x60)
634 tx = self.create_stream_labelled_ip4(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200635 self.pg0, [VppMplsLabel(3333, ttl=66, exp=4)]
636 )
Neale Ranns31ed7442018-02-23 05:29:09 -0800637 rx = self.send_and_expect(self.pg0, tx, self.pg0)
638 self.verify_capture_ip4(self.pg0, rx, tx, ip_ttl=65, ip_dscp=0x80)
639
640 #
Neale Ranns62fe07c2017-10-31 12:28:22 -0700641 # An MPLS xconnect - EOS label in IPv6 out
642 #
643 route_333_eos = VppMplsRoute(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200644 self,
645 333,
646 1,
647 [VppRoutePath(self.pg0.remote_ip6, self.pg0.sw_if_index, labels=[])],
648 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP6,
649 )
Neale Ranns62fe07c2017-10-31 12:28:22 -0700650 route_333_eos.add_vpp_config()
651
Neale Ranns31ed7442018-02-23 05:29:09 -0800652 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(333)])
653 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700654 self.verify_capture_ip6(self.pg0, rx, tx)
655
656 #
657 # disposed packets have an TTL expired
658 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200659 tx = self.create_stream_labelled_ip6(
660 self.pg0, [VppMplsLabel(333, ttl=64)], dst_ip=self.pg1.remote_ip6, hlim=1
661 )
Neale Ranns5c6dd172022-02-17 09:08:47 +0000662 rx = self.send_and_expect_some(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700663 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
664
665 #
666 # An MPLS xconnect - EOS label in IPv6 out w imp-null
667 #
668 route_334_eos = VppMplsRoute(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200669 self,
670 334,
671 1,
672 [
673 VppRoutePath(
674 self.pg0.remote_ip6, self.pg0.sw_if_index, labels=[VppMplsLabel(3)]
675 )
676 ],
677 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP6,
678 )
Neale Ranns62fe07c2017-10-31 12:28:22 -0700679 route_334_eos.add_vpp_config()
680
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200681 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(334, ttl=64)])
Neale Ranns31ed7442018-02-23 05:29:09 -0800682 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700683 self.verify_capture_ip6(self.pg0, rx, tx)
684
685 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800686 # An MPLS xconnect - EOS label in IPv6 out w imp-null in uniform mode
687 #
688 route_335_eos = VppMplsRoute(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200689 self,
690 335,
691 1,
692 [
693 VppRoutePath(
694 self.pg0.remote_ip6,
695 self.pg0.sw_if_index,
696 labels=[VppMplsLabel(3, MplsLspMode.UNIFORM)],
697 )
698 ],
699 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP6,
700 )
Neale Ranns31ed7442018-02-23 05:29:09 -0800701 route_335_eos.add_vpp_config()
702
703 tx = self.create_stream_labelled_ip6(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200704 self.pg0, [VppMplsLabel(335, ttl=27, exp=4)]
705 )
Neale Ranns31ed7442018-02-23 05:29:09 -0800706 rx = self.send_and_expect(self.pg0, tx, self.pg0)
707 self.verify_capture_ip6(self.pg0, rx, tx, ip_hlim=26, ip_dscp=0x80)
708
709 #
Neale Ranns62fe07c2017-10-31 12:28:22 -0700710 # disposed packets have an TTL expired
711 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200712 tx = self.create_stream_labelled_ip6(
713 self.pg0, [VppMplsLabel(334)], dst_ip=self.pg1.remote_ip6, hlim=0
714 )
Neale Ranns5c6dd172022-02-17 09:08:47 +0000715 rx = self.send_and_expect_some(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700716 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
717
718 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000719 # An MPLS xconnect - non-EOS label in IP out - an invalid configuration
720 # so this traffic should be dropped.
721 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200722 route_33_neos = VppMplsRoute(
723 self,
724 33,
725 0,
726 [VppRoutePath(self.pg0.remote_ip4, self.pg0.sw_if_index, labels=[])],
727 )
Neale Rannsad422ed2016-11-02 14:20:04 +0000728 route_33_neos.add_vpp_config()
729
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200730 tx = self.create_stream_labelled_ip4(
731 self.pg0, [VppMplsLabel(33), VppMplsLabel(99)]
732 )
Neale Ranns31ed7442018-02-23 05:29:09 -0800733 self.send_and_assert_no_replies(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200734 self.pg0, tx, "MPLS non-EOS packets popped and forwarded"
735 )
Neale Rannsad422ed2016-11-02 14:20:04 +0000736
737 #
738 # A recursive EOS x-connect, which resolves through another x-connect
Neale Ranns31ed7442018-02-23 05:29:09 -0800739 # in pipe mode
Neale Rannsad422ed2016-11-02 14:20:04 +0000740 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200741 route_34_eos = VppMplsRoute(
742 self,
743 34,
744 1,
745 [
746 VppRoutePath(
747 "0.0.0.0",
748 0xFFFFFFFF,
749 nh_via_label=32,
750 labels=[VppMplsLabel(44), VppMplsLabel(45)],
751 )
752 ],
753 )
Neale Rannsad422ed2016-11-02 14:20:04 +0000754 route_34_eos.add_vpp_config()
Neale Ranns097fa662018-05-01 05:17:55 -0700755 self.logger.info(self.vapi.cli("sh mpls fib 34"))
Neale Rannsad422ed2016-11-02 14:20:04 +0000756
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200757 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34, ttl=3)])
Neale Ranns31ed7442018-02-23 05:29:09 -0800758 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200759 self.verify_capture_labelled(
760 self.pg0,
761 rx,
762 tx,
763 [VppMplsLabel(33), VppMplsLabel(44), VppMplsLabel(45, ttl=2)],
764 )
Neale Rannsad422ed2016-11-02 14:20:04 +0000765
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200766 self.assertEqual(route_34_eos.get_stats_to()["packets"], 257)
767 self.assertEqual(route_32_neos.get_stats_via()["packets"], 257)
Neale Ranns008dbe12018-09-07 09:32:36 -0700768
Neale Ranns31ed7442018-02-23 05:29:09 -0800769 #
770 # A recursive EOS x-connect, which resolves through another x-connect
771 # in uniform mode
772 #
773 route_35_eos = VppMplsRoute(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200774 self,
775 35,
776 1,
777 [
778 VppRoutePath(
779 "0.0.0.0", 0xFFFFFFFF, nh_via_label=42, labels=[VppMplsLabel(44)]
780 )
781 ],
782 )
Neale Ranns31ed7442018-02-23 05:29:09 -0800783 route_35_eos.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000784
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200785 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(35, ttl=3)])
Neale Ranns31ed7442018-02-23 05:29:09 -0800786 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200787 self.verify_capture_labelled(
788 self.pg0, rx, tx, [VppMplsLabel(43, ttl=2), VppMplsLabel(44, ttl=2)]
789 )
Neale Rannsad422ed2016-11-02 14:20:04 +0000790
791 #
Matej Klottondeb69842016-12-09 15:05:46 +0100792 # A recursive non-EOS x-connect, which resolves through another
793 # x-connect
Neale Rannsad422ed2016-11-02 14:20:04 +0000794 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200795 route_34_neos = VppMplsRoute(
796 self,
797 34,
798 0,
799 [
800 VppRoutePath(
801 "0.0.0.0",
802 0xFFFFFFFF,
803 nh_via_label=32,
804 labels=[VppMplsLabel(44), VppMplsLabel(46)],
805 )
806 ],
807 )
Neale Rannsad422ed2016-11-02 14:20:04 +0000808 route_34_neos.add_vpp_config()
809
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200810 tx = self.create_stream_labelled_ip4(
811 self.pg0, [VppMplsLabel(34, ttl=45), VppMplsLabel(99)]
812 )
Neale Ranns31ed7442018-02-23 05:29:09 -0800813 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Matej Klottondeb69842016-12-09 15:05:46 +0100814 # it's the 2nd (counting from 0) label in the stack that is swapped
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200815 self.verify_capture_labelled(
816 self.pg0,
817 rx,
818 tx,
819 [
820 VppMplsLabel(33),
821 VppMplsLabel(44),
822 VppMplsLabel(46, ttl=44),
823 VppMplsLabel(99),
824 ],
825 )
Neale Rannsad422ed2016-11-02 14:20:04 +0000826
827 #
Matej Klottondeb69842016-12-09 15:05:46 +0100828 # an recursive IP route that resolves through the recursive non-eos
829 # x-connect
Neale Rannsad422ed2016-11-02 14:20:04 +0000830 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200831 ip_10_0_0_1 = VppIpRoute(
832 self,
833 "10.0.0.1",
834 32,
835 [
836 VppRoutePath(
837 "0.0.0.0", 0xFFFFFFFF, nh_via_label=34, labels=[VppMplsLabel(55)]
838 )
839 ],
840 )
Neale Rannsad422ed2016-11-02 14:20:04 +0000841 ip_10_0_0_1.add_vpp_config()
842
Neale Rannsad422ed2016-11-02 14:20:04 +0000843 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800844 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200845 self.verify_capture_labelled_ip4(
846 self.pg0,
847 rx,
848 tx,
849 [VppMplsLabel(33), VppMplsLabel(44), VppMplsLabel(46), VppMplsLabel(55)],
850 )
851 self.assertEqual(ip_10_0_0_1.get_stats_to()["packets"], 257)
Neale Rannsad422ed2016-11-02 14:20:04 +0000852
853 ip_10_0_0_1.remove_vpp_config()
854 route_34_neos.remove_vpp_config()
855 route_34_eos.remove_vpp_config()
856 route_33_neos.remove_vpp_config()
857 route_33_eos.remove_vpp_config()
858 route_32_neos.remove_vpp_config()
859 route_32_eos.remove_vpp_config()
860
861 def test_bind(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200862 """MPLS Local Label Binding test"""
Neale Rannsad422ed2016-11-02 14:20:04 +0000863
864 #
865 # Add a non-recursive route with a single out label
866 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200867 route_10_0_0_1 = VppIpRoute(
868 self,
869 "10.0.0.1",
870 32,
871 [
872 VppRoutePath(
873 self.pg0.remote_ip4, self.pg0.sw_if_index, labels=[VppMplsLabel(45)]
874 )
875 ],
876 )
Neale Rannsad422ed2016-11-02 14:20:04 +0000877 route_10_0_0_1.add_vpp_config()
878
879 # bind a local label to the route
Neale Ranns5a8123b2017-01-26 01:18:23 -0800880 binding = VppMplsIpBind(self, 44, "10.0.0.1", 32)
Neale Rannsad422ed2016-11-02 14:20:04 +0000881 binding.add_vpp_config()
882
883 # non-EOS stream
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200884 tx = self.create_stream_labelled_ip4(
885 self.pg0, [VppMplsLabel(44), VppMplsLabel(99)]
886 )
Neale Ranns31ed7442018-02-23 05:29:09 -0800887 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200888 self.verify_capture_labelled(
889 self.pg0, rx, tx, [VppMplsLabel(45, ttl=63), VppMplsLabel(99)]
890 )
Neale Rannsad422ed2016-11-02 14:20:04 +0000891
892 # EOS stream
Neale Ranns31ed7442018-02-23 05:29:09 -0800893 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(44)])
894 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200895 self.verify_capture_labelled(self.pg0, rx, tx, [VppMplsLabel(45, ttl=63)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000896
897 # IP stream
Neale Rannsad422ed2016-11-02 14:20:04 +0000898 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800899 rx = self.send_and_expect(self.pg0, tx, self.pg0)
900 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [VppMplsLabel(45)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000901
902 #
903 # cleanup
904 #
905 binding.remove_vpp_config()
906 route_10_0_0_1.remove_vpp_config()
907
908 def test_imposition(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200909 """MPLS label imposition test"""
Neale Rannsad422ed2016-11-02 14:20:04 +0000910
911 #
912 # Add a non-recursive route with a single out label
913 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200914 route_10_0_0_1 = VppIpRoute(
915 self,
916 "10.0.0.1",
917 32,
918 [
919 VppRoutePath(
920 self.pg0.remote_ip4, self.pg0.sw_if_index, labels=[VppMplsLabel(32)]
921 )
922 ],
923 )
Neale Rannsad422ed2016-11-02 14:20:04 +0000924 route_10_0_0_1.add_vpp_config()
925
926 #
927 # a stream that matches the route for 10.0.0.1
928 # PG0 is in the default table
929 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000930 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800931 rx = self.send_and_expect(self.pg0, tx, self.pg0)
932 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [VppMplsLabel(32)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000933
934 #
935 # Add a non-recursive route with a 3 out labels
936 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200937 route_10_0_0_2 = VppIpRoute(
938 self,
939 "10.0.0.2",
940 32,
941 [
942 VppRoutePath(
943 self.pg0.remote_ip4,
944 self.pg0.sw_if_index,
945 labels=[VppMplsLabel(32), VppMplsLabel(33), VppMplsLabel(34)],
946 )
947 ],
948 )
Neale Rannsad422ed2016-11-02 14:20:04 +0000949 route_10_0_0_2.add_vpp_config()
950
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200951 tx = self.create_stream_ip4(self.pg0, "10.0.0.2", ip_ttl=44, ip_dscp=0xFF)
Neale Ranns31ed7442018-02-23 05:29:09 -0800952 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200953 self.verify_capture_labelled_ip4(
954 self.pg0,
955 rx,
956 tx,
957 [VppMplsLabel(32), VppMplsLabel(33), VppMplsLabel(34)],
958 ip_ttl=43,
959 )
Neale Rannsad422ed2016-11-02 14:20:04 +0000960
Neale Ranns31ed7442018-02-23 05:29:09 -0800961 #
962 # Add a non-recursive route with a single out label in uniform mode
963 #
964 route_10_0_0_3 = VppIpRoute(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200965 self,
966 "10.0.0.3",
967 32,
968 [
969 VppRoutePath(
970 self.pg0.remote_ip4,
971 self.pg0.sw_if_index,
972 labels=[VppMplsLabel(32, mode=MplsLspMode.UNIFORM)],
973 )
974 ],
975 )
Neale Ranns31ed7442018-02-23 05:29:09 -0800976 route_10_0_0_3.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000977
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200978 tx = self.create_stream_ip4(self.pg0, "10.0.0.3", ip_ttl=54, ip_dscp=0xBE)
Neale Ranns31ed7442018-02-23 05:29:09 -0800979 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200980 self.verify_capture_labelled_ip4(
981 self.pg0, rx, tx, [VppMplsLabel(32, ttl=53, exp=5)]
982 )
Neale Ranns31ed7442018-02-23 05:29:09 -0800983
984 #
985 # Add a IPv6 non-recursive route with a single out label in
986 # uniform mode
987 #
988 route_2001_3 = VppIpRoute(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200989 self,
990 "2001::3",
991 128,
992 [
993 VppRoutePath(
994 self.pg0.remote_ip6,
995 self.pg0.sw_if_index,
996 labels=[VppMplsLabel(32, mode=MplsLspMode.UNIFORM)],
997 )
998 ],
999 )
Neale Ranns31ed7442018-02-23 05:29:09 -08001000 route_2001_3.add_vpp_config()
1001
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001002 tx = self.create_stream_ip6(self.pg0, "2001::3", ip_ttl=54, ip_dscp=0xBE)
Neale Ranns31ed7442018-02-23 05:29:09 -08001003 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001004 self.verify_capture_labelled_ip6(
1005 self.pg0, rx, tx, [VppMplsLabel(32, ttl=53, exp=5)]
1006 )
Neale Rannsad422ed2016-11-02 14:20:04 +00001007
1008 #
Matej Klottondeb69842016-12-09 15:05:46 +01001009 # add a recursive path, with output label, via the 1 label route
Neale Rannsad422ed2016-11-02 14:20:04 +00001010 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001011 route_11_0_0_1 = VppIpRoute(
1012 self,
1013 "11.0.0.1",
1014 32,
1015 [VppRoutePath("10.0.0.1", 0xFFFFFFFF, labels=[VppMplsLabel(44)])],
1016 )
Neale Rannsad422ed2016-11-02 14:20:04 +00001017 route_11_0_0_1.add_vpp_config()
1018
1019 #
1020 # a stream that matches the route for 11.0.0.1, should pick up
1021 # the label stack for 11.0.0.1 and 10.0.0.1
1022 #
Neale Rannsad422ed2016-11-02 14:20:04 +00001023 tx = self.create_stream_ip4(self.pg0, "11.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -08001024 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001025 self.verify_capture_labelled_ip4(
1026 self.pg0, rx, tx, [VppMplsLabel(32), VppMplsLabel(44)]
1027 )
Neale Rannsad422ed2016-11-02 14:20:04 +00001028
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001029 self.assertEqual(route_11_0_0_1.get_stats_to()["packets"], 257)
Neale Ranns008dbe12018-09-07 09:32:36 -07001030
Neale Rannsad422ed2016-11-02 14:20:04 +00001031 #
1032 # add a recursive path, with 2 labels, via the 3 label route
1033 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001034 route_11_0_0_2 = VppIpRoute(
1035 self,
1036 "11.0.0.2",
1037 32,
1038 [
1039 VppRoutePath(
1040 "10.0.0.2", 0xFFFFFFFF, labels=[VppMplsLabel(44), VppMplsLabel(45)]
1041 )
1042 ],
1043 )
Neale Rannsad422ed2016-11-02 14:20:04 +00001044 route_11_0_0_2.add_vpp_config()
1045
1046 #
1047 # a stream that matches the route for 11.0.0.1, should pick up
1048 # the label stack for 11.0.0.1 and 10.0.0.1
1049 #
Neale Rannsad422ed2016-11-02 14:20:04 +00001050 tx = self.create_stream_ip4(self.pg0, "11.0.0.2")
Neale Ranns31ed7442018-02-23 05:29:09 -08001051 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001052 self.verify_capture_labelled_ip4(
1053 self.pg0,
1054 rx,
1055 tx,
1056 [
1057 VppMplsLabel(32),
1058 VppMplsLabel(33),
1059 VppMplsLabel(34),
1060 VppMplsLabel(44),
1061 VppMplsLabel(45),
1062 ],
1063 )
Neale Rannsad422ed2016-11-02 14:20:04 +00001064
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001065 self.assertEqual(route_11_0_0_2.get_stats_to()["packets"], 257)
Neale Ranns008dbe12018-09-07 09:32:36 -07001066
1067 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001068 self.verify_capture_labelled_ip4(
1069 self.pg0,
1070 rx,
1071 tx,
1072 [
1073 VppMplsLabel(32),
1074 VppMplsLabel(33),
1075 VppMplsLabel(34),
1076 VppMplsLabel(44),
1077 VppMplsLabel(45),
1078 ],
1079 )
Neale Ranns008dbe12018-09-07 09:32:36 -07001080
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001081 self.assertEqual(route_11_0_0_2.get_stats_to()["packets"], 514)
Neale Ranns008dbe12018-09-07 09:32:36 -07001082
Neale Rannsad422ed2016-11-02 14:20:04 +00001083 #
1084 # cleanup
1085 #
1086 route_11_0_0_2.remove_vpp_config()
1087 route_11_0_0_1.remove_vpp_config()
1088 route_10_0_0_2.remove_vpp_config()
1089 route_10_0_0_1.remove_vpp_config()
1090
Rajesh Goeld6f1c9c2019-10-06 13:17:36 +05301091 def test_imposition_fragmentation(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001092 """MPLS label imposition fragmentation test"""
Rajesh Goeld6f1c9c2019-10-06 13:17:36 +05301093
1094 #
1095 # Add a ipv4 non-recursive route with a single out label
1096 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001097 route_10_0_0_1 = VppIpRoute(
1098 self,
1099 "10.0.0.1",
1100 32,
1101 [
1102 VppRoutePath(
1103 self.pg0.remote_ip4, self.pg0.sw_if_index, labels=[VppMplsLabel(32)]
1104 )
1105 ],
1106 )
Rajesh Goeld6f1c9c2019-10-06 13:17:36 +05301107 route_10_0_0_1.add_vpp_config()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001108 route_1000_1 = VppIpRoute(
1109 self,
1110 "1000::1",
1111 128,
1112 [
1113 VppRoutePath(
1114 self.pg0.remote_ip6, self.pg0.sw_if_index, labels=[VppMplsLabel(32)]
1115 )
1116 ],
1117 )
Neale Rannsec5371e2022-03-04 11:45:41 +00001118 route_1000_1.add_vpp_config()
Rajesh Goeld6f1c9c2019-10-06 13:17:36 +05301119
1120 #
1121 # a stream that matches the route for 10.0.0.1
1122 # PG0 is in the default table
1123 #
1124 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
1125 for i in range(0, 257):
1126 self.extend_packet(tx[i], 10000)
1127
1128 #
1129 # 5 fragments per packet (257*5=1285)
1130 #
1131 rx = self.send_and_expect(self.pg0, tx, self.pg0, 1285)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001132 self.verify_capture_fragmented_labelled_ip4(
1133 self.pg0, rx, tx, [VppMplsLabel(32)]
1134 )
Rajesh Goeld6f1c9c2019-10-06 13:17:36 +05301135
Neale Rannsec5371e2022-03-04 11:45:41 +00001136 # packets with DF bit set generate ICMP
1137 for t in tx:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001138 t[IP].flags = "DF"
Neale Rannsec5371e2022-03-04 11:45:41 +00001139 rxs = self.send_and_expect_some(self.pg0, tx, self.pg0)
1140
1141 for rx in rxs:
Neale Rannsfbc633f2022-03-18 13:05:09 +00001142 self.assertEqual(icmptypes[rx[ICMP].type], "dest-unreach")
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001143 self.assertEqual(
1144 icmpcodes[rx[ICMP].type][rx[ICMP].code], "fragmentation-needed"
1145 )
Neale Rannsfbc633f2022-03-18 13:05:09 +00001146 # the link MTU is 9000, the MPLS over head is 4 bytes
1147 self.assertEqual(rx[ICMP].nexthopmtu, 9000 - 4)
Neale Rannsec5371e2022-03-04 11:45:41 +00001148
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001149 self.assertEqual(
Neale Rannse22a7042022-08-09 03:03:29 +00001150 self.statistics.get_err_counter("/err/mpls-frag/dont_fragment_set"),
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001151 len(tx),
1152 )
Neale Rannsec5371e2022-03-04 11:45:41 +00001153 #
1154 # a stream that matches the route for 1000::1/128
1155 # PG0 is in the default table
1156 #
1157 tx = self.create_stream_ip6(self.pg0, "1000::1")
1158 for i in range(0, 257):
1159 self.extend_packet(tx[i], 10000)
1160
1161 rxs = self.send_and_expect_some(self.pg0, tx, self.pg0)
1162 for rx in rxs:
Neale Rannsfbc633f2022-03-18 13:05:09 +00001163 self.assertEqual(rx[ICMPv6PacketTooBig].mtu, 9000 - 4)
Neale Rannsec5371e2022-03-04 11:45:41 +00001164
Rajesh Goeld6f1c9c2019-10-06 13:17:36 +05301165 #
1166 # cleanup
1167 #
1168 route_10_0_0_1.remove_vpp_config()
1169
Neale Ranns31ed7442018-02-23 05:29:09 -08001170 def test_tunnel_pipe(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001171 """MPLS Tunnel Tests - Pipe"""
Neale Rannsad422ed2016-11-02 14:20:04 +00001172
1173 #
Ole Troaneb284a12019-10-09 13:33:19 +02001174 # Create a tunnel with two out labels
Neale Rannsad422ed2016-11-02 14:20:04 +00001175 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001176 mpls_tun = VppMPLSTunnelInterface(
1177 self,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001178 [
1179 VppRoutePath(
1180 self.pg0.remote_ip4,
1181 self.pg0.sw_if_index,
1182 labels=[VppMplsLabel(44), VppMplsLabel(46)],
1183 )
1184 ],
1185 )
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001186 mpls_tun.add_vpp_config()
1187 mpls_tun.admin_up()
Neale Rannsad422ed2016-11-02 14:20:04 +00001188
1189 #
1190 # add an unlabelled route through the new tunnel
1191 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001192 route_10_0_0_3 = VppIpRoute(
1193 self, "10.0.0.3", 32, [VppRoutePath("0.0.0.0", mpls_tun._sw_if_index)]
1194 )
Neale Ranns5a8123b2017-01-26 01:18:23 -08001195 route_10_0_0_3.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +00001196
1197 self.vapi.cli("clear trace")
1198 tx = self.create_stream_ip4(self.pg0, "10.0.0.3")
1199 self.pg0.add_stream(tx)
1200
1201 self.pg_enable_capture(self.pg_interfaces)
1202 self.pg_start()
1203
1204 rx = self.pg0.get_capture()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001205 self.verify_capture_tunneled_ip4(
1206 self.pg0, rx, tx, [VppMplsLabel(44), VppMplsLabel(46)]
1207 )
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001208
Neale Ranns8c4611b2017-05-23 03:43:47 -07001209 #
1210 # add a labelled route through the new tunnel
1211 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001212 route_10_0_0_4 = VppIpRoute(
1213 self,
1214 "10.0.0.4",
1215 32,
1216 [VppRoutePath("0.0.0.0", mpls_tun._sw_if_index, labels=[33])],
1217 )
Neale Ranns8c4611b2017-05-23 03:43:47 -07001218 route_10_0_0_4.add_vpp_config()
1219
1220 self.vapi.cli("clear trace")
1221 tx = self.create_stream_ip4(self.pg0, "10.0.0.4")
1222 self.pg0.add_stream(tx)
1223
1224 self.pg_enable_capture(self.pg_interfaces)
1225 self.pg_start()
1226
1227 rx = self.pg0.get_capture()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001228 self.verify_capture_tunneled_ip4(
1229 self.pg0,
1230 rx,
1231 tx,
1232 [VppMplsLabel(44), VppMplsLabel(46), VppMplsLabel(33, ttl=255)],
1233 )
Neale Ranns31ed7442018-02-23 05:29:09 -08001234
Ole Troaneb284a12019-10-09 13:33:19 +02001235 #
1236 # change tunnel's MTU to a low value
1237 #
1238 mpls_tun.set_l3_mtu(1200)
1239
1240 # send IP into the tunnel to be fragmented
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001241 tx = self.create_stream_ip4(self.pg0, "10.0.0.3", payload_size=1500)
1242 rx = self.send_and_expect(self.pg0, tx, self.pg0, len(tx) * 2)
Ole Troaneb284a12019-10-09 13:33:19 +02001243
1244 fake_tx = []
1245 for p in tx:
1246 fake_tx.append(p)
1247 fake_tx.append(p)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001248 self.verify_capture_tunneled_ip4(
1249 self.pg0, rx, fake_tx, [VppMplsLabel(44), VppMplsLabel(46)]
1250 )
Ole Troaneb284a12019-10-09 13:33:19 +02001251
1252 # send MPLS into the tunnel to be fragmented
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001253 tx = self.create_stream_ip4(self.pg0, "10.0.0.4", payload_size=1500)
1254 rx = self.send_and_expect(self.pg0, tx, self.pg0, len(tx) * 2)
Ole Troaneb284a12019-10-09 13:33:19 +02001255
1256 fake_tx = []
1257 for p in tx:
1258 fake_tx.append(p)
1259 fake_tx.append(p)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001260 self.verify_capture_tunneled_ip4(
1261 self.pg0,
1262 rx,
1263 fake_tx,
1264 [VppMplsLabel(44), VppMplsLabel(46), VppMplsLabel(33, ttl=255)],
1265 )
Ole Troaneb284a12019-10-09 13:33:19 +02001266
Neale Ranns31ed7442018-02-23 05:29:09 -08001267 def test_tunnel_uniform(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001268 """MPLS Tunnel Tests - Uniform"""
Neale Ranns31ed7442018-02-23 05:29:09 -08001269
1270 #
1271 # Create a tunnel with a single out label
1272 # The label stack is specified here from outer to inner
1273 #
1274 mpls_tun = VppMPLSTunnelInterface(
1275 self,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001276 [
1277 VppRoutePath(
1278 self.pg0.remote_ip4,
1279 self.pg0.sw_if_index,
1280 labels=[
1281 VppMplsLabel(44, ttl=32),
1282 VppMplsLabel(46, MplsLspMode.UNIFORM),
1283 ],
1284 )
1285 ],
1286 )
Neale Ranns31ed7442018-02-23 05:29:09 -08001287 mpls_tun.add_vpp_config()
1288 mpls_tun.admin_up()
1289
1290 #
1291 # add an unlabelled route through the new tunnel
1292 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001293 route_10_0_0_3 = VppIpRoute(
1294 self, "10.0.0.3", 32, [VppRoutePath("0.0.0.0", mpls_tun._sw_if_index)]
1295 )
Neale Ranns31ed7442018-02-23 05:29:09 -08001296 route_10_0_0_3.add_vpp_config()
1297
1298 self.vapi.cli("clear trace")
1299 tx = self.create_stream_ip4(self.pg0, "10.0.0.3", ip_ttl=24)
1300 self.pg0.add_stream(tx)
1301
1302 self.pg_enable_capture(self.pg_interfaces)
1303 self.pg_start()
1304
1305 rx = self.pg0.get_capture()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001306 self.verify_capture_tunneled_ip4(
1307 self.pg0, rx, tx, [VppMplsLabel(44, ttl=32), VppMplsLabel(46, ttl=23)]
1308 )
Neale Ranns31ed7442018-02-23 05:29:09 -08001309
1310 #
1311 # add a labelled route through the new tunnel
1312 #
1313 route_10_0_0_4 = VppIpRoute(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001314 self,
1315 "10.0.0.4",
1316 32,
1317 [
1318 VppRoutePath(
1319 "0.0.0.0", mpls_tun._sw_if_index, labels=[VppMplsLabel(33, ttl=47)]
1320 )
1321 ],
1322 )
Neale Ranns31ed7442018-02-23 05:29:09 -08001323 route_10_0_0_4.add_vpp_config()
1324
1325 self.vapi.cli("clear trace")
1326 tx = self.create_stream_ip4(self.pg0, "10.0.0.4")
1327 self.pg0.add_stream(tx)
1328
1329 self.pg_enable_capture(self.pg_interfaces)
1330 self.pg_start()
1331
1332 rx = self.pg0.get_capture()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001333 self.verify_capture_tunneled_ip4(
1334 self.pg0,
1335 rx,
1336 tx,
1337 [
1338 VppMplsLabel(44, ttl=32),
1339 VppMplsLabel(46, ttl=47),
1340 VppMplsLabel(33, ttl=47),
1341 ],
1342 )
Neale Ranns8c4611b2017-05-23 03:43:47 -07001343
Neale Rannsf5fa5ae2018-09-26 05:07:25 -07001344 def test_mpls_tunnel_many(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001345 """MPLS Multiple Tunnels"""
Neale Rannsf5fa5ae2018-09-26 05:07:25 -07001346
Neale Ranns397228d2021-10-21 12:02:53 +00001347 for ii in range(100):
Neale Rannsf5fa5ae2018-09-26 05:07:25 -07001348 mpls_tun = VppMPLSTunnelInterface(
1349 self,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001350 [
1351 VppRoutePath(
1352 self.pg0.remote_ip4,
1353 self.pg0.sw_if_index,
1354 labels=[
1355 VppMplsLabel(44, ttl=32),
1356 VppMplsLabel(46, MplsLspMode.UNIFORM),
1357 ],
1358 )
1359 ],
1360 )
Neale Rannsf5fa5ae2018-09-26 05:07:25 -07001361 mpls_tun.add_vpp_config()
1362 mpls_tun.admin_up()
Neale Ranns397228d2021-10-21 12:02:53 +00001363 for ii in range(100):
1364 mpls_tun = VppMPLSTunnelInterface(
1365 self,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001366 [
1367 VppRoutePath(
1368 self.pg0.remote_ip4,
1369 self.pg0.sw_if_index,
1370 labels=[
1371 VppMplsLabel(44, ttl=32),
1372 VppMplsLabel(46, MplsLspMode.UNIFORM),
1373 ],
1374 )
1375 ],
1376 is_l2=1,
1377 )
Neale Ranns397228d2021-10-21 12:02:53 +00001378 mpls_tun.add_vpp_config()
1379 mpls_tun.admin_up()
Neale Rannsf5fa5ae2018-09-26 05:07:25 -07001380
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001381 def test_v4_exp_null(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001382 """MPLS V4 Explicit NULL test"""
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001383
1384 #
1385 # The first test case has an MPLS TTL of 0
1386 # all packet should be dropped
1387 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001388 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(0, ttl=0)])
1389 self.send_and_assert_no_replies(self.pg0, tx, "MPLS TTL=0 packets forwarded")
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001390
1391 #
1392 # a stream with a non-zero MPLS TTL
1393 # PG0 is in the default table
1394 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001395 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(0)])
1396 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001397 self.verify_capture_ip4(self.pg0, rx, tx)
1398
1399 #
1400 # a stream with a non-zero MPLS TTL
1401 # PG1 is in table 1
1402 # we are ensuring the post-pop lookup occurs in the VRF table
1403 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001404 tx = self.create_stream_labelled_ip4(self.pg1, [VppMplsLabel(0)])
1405 rx = self.send_and_expect(self.pg1, tx, self.pg1)
1406 self.verify_capture_ip4(self.pg1, rx, tx)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001407
1408 def test_v6_exp_null(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001409 """MPLS V6 Explicit NULL test"""
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001410
1411 #
1412 # a stream with a non-zero MPLS TTL
1413 # PG0 is in the default table
1414 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001415 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(2)])
1416 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001417 self.verify_capture_ip6(self.pg0, rx, tx)
1418
1419 #
1420 # a stream with a non-zero MPLS TTL
1421 # PG1 is in table 1
1422 # we are ensuring the post-pop lookup occurs in the VRF table
1423 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001424 tx = self.create_stream_labelled_ip6(self.pg1, [VppMplsLabel(2)])
1425 rx = self.send_and_expect(self.pg1, tx, self.pg1)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001426 self.verify_capture_ip6(self.pg0, rx, tx)
1427
Neale Rannscb630ff2016-12-14 13:31:29 +01001428 def test_deag(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001429 """MPLS Deagg"""
Neale Rannscb630ff2016-12-14 13:31:29 +01001430
1431 #
1432 # A de-agg route - next-hop lookup in default table
1433 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001434 route_34_eos = VppMplsRoute(
1435 self, 34, 1, [VppRoutePath("0.0.0.0", 0xFFFFFFFF, nh_table_id=0)]
1436 )
Neale Rannscb630ff2016-12-14 13:31:29 +01001437 route_34_eos.add_vpp_config()
1438
1439 #
1440 # ping an interface in the default table
1441 # PG0 is in the default table
1442 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001443 tx = self.create_stream_labelled_ip4(
1444 self.pg0, [VppMplsLabel(34)], ping=1, ip_itf=self.pg0
1445 )
Neale Ranns31ed7442018-02-23 05:29:09 -08001446 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Rannscb630ff2016-12-14 13:31:29 +01001447 self.verify_capture_ip4(self.pg0, rx, tx, ping_resp=1)
1448
1449 #
1450 # A de-agg route - next-hop lookup in non-default table
1451 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001452 route_35_eos = VppMplsRoute(
1453 self, 35, 1, [VppRoutePath("0.0.0.0", 0xFFFFFFFF, nh_table_id=1)]
1454 )
Neale Rannscb630ff2016-12-14 13:31:29 +01001455 route_35_eos.add_vpp_config()
Neale Rannsf478f752022-02-17 15:41:32 +00001456 route_356_eos = VppMplsRoute(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001457 self,
1458 356,
1459 1,
1460 [VppRoutePath("0::0", 0xFFFFFFFF, nh_table_id=1)],
1461 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP6,
1462 )
Neale Rannsf478f752022-02-17 15:41:32 +00001463 route_356_eos.add_vpp_config()
Neale Rannscb630ff2016-12-14 13:31:29 +01001464
1465 #
1466 # ping an interface in the non-default table
1467 # PG0 is in the default table. packet arrive labelled in the
1468 # default table and egress unlabelled in the non-default
1469 #
Klement Sekeradab231a2016-12-21 08:50:14 +01001470 tx = self.create_stream_labelled_ip4(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001471 self.pg0, [VppMplsLabel(35)], ping=1, ip_itf=self.pg1
1472 )
Neale Ranns31ed7442018-02-23 05:29:09 -08001473 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Rannscb630ff2016-12-14 13:31:29 +01001474 self.verify_capture_ip4(self.pg1, rx, tx, ping_resp=1)
Neale Rannsf478f752022-02-17 15:41:32 +00001475 tx = self.create_stream_labelled_ip6(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001476 self.pg0, [VppMplsLabel(356)], ping=1, ip_itf=self.pg1
1477 )
Neale Rannsf478f752022-02-17 15:41:32 +00001478 rx = self.send_and_expect(self.pg0, tx, self.pg1)
1479 self.verify_capture_ip6(self.pg1, rx, tx, ping_resp=1)
Neale Rannscb630ff2016-12-14 13:31:29 +01001480
Neale Ranns6af1c042017-05-26 03:48:53 -07001481 #
1482 # Double pop
1483 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001484 route_36_neos = VppMplsRoute(self, 36, 0, [VppRoutePath("0.0.0.0", 0xFFFFFFFF)])
Neale Ranns6af1c042017-05-26 03:48:53 -07001485 route_36_neos.add_vpp_config()
1486
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001487 tx = self.create_stream_labelled_ip4(
1488 self.pg0, [VppMplsLabel(36), VppMplsLabel(35)], ping=1, ip_itf=self.pg1
1489 )
Neale Ranns31ed7442018-02-23 05:29:09 -08001490 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns6af1c042017-05-26 03:48:53 -07001491 self.verify_capture_ip4(self.pg1, rx, tx, ping_resp=1)
1492
1493 route_36_neos.remove_vpp_config()
Neale Rannscb630ff2016-12-14 13:31:29 +01001494 route_35_eos.remove_vpp_config()
1495 route_34_eos.remove_vpp_config()
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001496
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001497 def test_interface_rx(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001498 """MPLS Interface Receive"""
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001499
1500 #
1501 # Add a non-recursive route that will forward the traffic
1502 # post-interface-rx
1503 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001504 route_10_0_0_1 = VppIpRoute(
1505 self,
1506 "10.0.0.1",
1507 32,
1508 table_id=1,
1509 paths=[VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index)],
1510 )
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001511 route_10_0_0_1.add_vpp_config()
1512
1513 #
1514 # An interface receive label that maps traffic to RX on interface
1515 # pg1
1516 # by injecting the packet in on pg0, which is in table 0
1517 # doing an interface-rx on pg1 and matching a route in table 1
1518 # if the packet egresses, then we must have swapped to pg1
1519 # so as to have matched the route in table 1
1520 #
Neale Ranns097fa662018-05-01 05:17:55 -07001521 route_34_eos = VppMplsRoute(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001522 self,
1523 34,
1524 1,
1525 [
1526 VppRoutePath(
1527 "0.0.0.0",
1528 self.pg1.sw_if_index,
1529 type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX,
1530 )
1531 ],
1532 )
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001533 route_34_eos.add_vpp_config()
1534
1535 #
1536 # ping an interface in the default table
1537 # PG0 is in the default table
1538 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001539 tx = self.create_stream_labelled_ip4(
1540 self.pg0, [VppMplsLabel(34)], dst_ip="10.0.0.1"
1541 )
Neale Ranns31ed7442018-02-23 05:29:09 -08001542 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001543 self.verify_capture_ip4(self.pg1, rx, tx)
1544
1545 def test_mcast_mid_point(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001546 """MPLS Multicast Mid Point"""
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001547
1548 #
1549 # Add a non-recursive route that will forward the traffic
1550 # post-interface-rx
1551 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001552 route_10_0_0_1 = VppIpRoute(
1553 self,
1554 "10.0.0.1",
1555 32,
1556 table_id=1,
1557 paths=[VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index)],
1558 )
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001559 route_10_0_0_1.add_vpp_config()
1560
1561 #
1562 # Add a mcast entry that replicate to pg2 and pg3
1563 # and replicate to a interface-rx (like a bud node would)
1564 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001565 route_3400_eos = VppMplsRoute(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001566 self,
1567 3400,
1568 1,
1569 [
1570 VppRoutePath(
1571 self.pg2.remote_ip4,
1572 self.pg2.sw_if_index,
1573 labels=[VppMplsLabel(3401)],
1574 ),
1575 VppRoutePath(
1576 self.pg3.remote_ip4,
1577 self.pg3.sw_if_index,
1578 labels=[VppMplsLabel(3402)],
1579 ),
1580 VppRoutePath(
1581 "0.0.0.0",
1582 self.pg1.sw_if_index,
1583 type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX,
1584 ),
1585 ],
1586 is_multicast=1,
1587 )
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001588 route_3400_eos.add_vpp_config()
1589
1590 #
1591 # ping an interface in the default table
1592 # PG0 is in the default table
1593 #
1594 self.vapi.cli("clear trace")
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001595 tx = self.create_stream_labelled_ip4(
1596 self.pg0, [VppMplsLabel(3400, ttl=64)], n=257, dst_ip="10.0.0.1"
1597 )
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001598 self.pg0.add_stream(tx)
1599
1600 self.pg_enable_capture(self.pg_interfaces)
1601 self.pg_start()
1602
1603 rx = self.pg1.get_capture(257)
1604 self.verify_capture_ip4(self.pg1, rx, tx)
1605
1606 rx = self.pg2.get_capture(257)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001607 self.verify_capture_labelled(self.pg2, rx, tx, [VppMplsLabel(3401, ttl=63)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001608 rx = self.pg3.get_capture(257)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001609 self.verify_capture_labelled(self.pg3, rx, tx, [VppMplsLabel(3402, ttl=63)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001610
1611 def test_mcast_head(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001612 """MPLS Multicast Head-end"""
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001613
Neale Ranns990f6942020-10-20 07:20:17 +00001614 MRouteItfFlags = VppEnum.vl_api_mfib_itf_flags_t
1615 MRouteEntryFlags = VppEnum.vl_api_mfib_entry_flags_t
1616
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001617 #
1618 # Create a multicast tunnel with two replications
1619 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001620 mpls_tun = VppMPLSTunnelInterface(
1621 self,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001622 [
1623 VppRoutePath(
1624 self.pg2.remote_ip4, self.pg2.sw_if_index, labels=[VppMplsLabel(42)]
1625 ),
1626 VppRoutePath(
1627 self.pg3.remote_ip4, self.pg3.sw_if_index, labels=[VppMplsLabel(43)]
1628 ),
1629 ],
1630 is_multicast=1,
1631 )
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001632 mpls_tun.add_vpp_config()
1633 mpls_tun.admin_up()
1634
1635 #
1636 # add an unlabelled route through the new tunnel
1637 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001638 route_10_0_0_3 = VppIpRoute(
1639 self, "10.0.0.3", 32, [VppRoutePath("0.0.0.0", mpls_tun._sw_if_index)]
1640 )
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001641 route_10_0_0_3.add_vpp_config()
1642
1643 self.vapi.cli("clear trace")
1644 tx = self.create_stream_ip4(self.pg0, "10.0.0.3")
1645 self.pg0.add_stream(tx)
1646
1647 self.pg_enable_capture(self.pg_interfaces)
1648 self.pg_start()
1649
1650 rx = self.pg2.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001651 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(42)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001652 rx = self.pg3.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001653 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(43)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001654
1655 #
1656 # An an IP multicast route via the tunnel
1657 # A (*,G).
1658 # one accepting interface, pg0, 1 forwarding interface via the tunnel
1659 #
1660 route_232_1_1_1 = VppIpMRoute(
1661 self,
1662 "0.0.0.0",
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001663 "232.1.1.1",
1664 32,
Neale Ranns990f6942020-10-20 07:20:17 +00001665 MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001666 [
1667 VppMRoutePath(
1668 self.pg0.sw_if_index, MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT
1669 ),
1670 VppMRoutePath(
1671 mpls_tun._sw_if_index, MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD
1672 ),
1673 ],
1674 )
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001675 route_232_1_1_1.add_vpp_config()
Neale Ranns097fa662018-05-01 05:17:55 -07001676 self.logger.info(self.vapi.cli("sh ip mfib index 0"))
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001677
1678 self.vapi.cli("clear trace")
1679 tx = self.create_stream_ip4(self.pg0, "232.1.1.1")
1680 self.pg0.add_stream(tx)
1681
1682 self.pg_enable_capture(self.pg_interfaces)
1683 self.pg_start()
1684
1685 rx = self.pg2.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001686 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(42)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001687 rx = self.pg3.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001688 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(43)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001689
Neale Ranns31426c62017-05-24 10:32:58 -07001690 def test_mcast_ip4_tail(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001691 """MPLS IPv4 Multicast Tail"""
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001692
Neale Ranns990f6942020-10-20 07:20:17 +00001693 MRouteItfFlags = VppEnum.vl_api_mfib_itf_flags_t
1694 MRouteEntryFlags = VppEnum.vl_api_mfib_entry_flags_t
1695
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001696 #
1697 # Add a multicast route that will forward the traffic
1698 # post-disposition
1699 #
1700 route_232_1_1_1 = VppIpMRoute(
1701 self,
1702 "0.0.0.0",
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001703 "232.1.1.1",
1704 32,
Neale Ranns990f6942020-10-20 07:20:17 +00001705 MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001706 table_id=1,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001707 paths=[
1708 VppMRoutePath(
1709 self.pg1.sw_if_index, MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD
1710 )
1711 ],
1712 )
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001713 route_232_1_1_1.add_vpp_config()
1714
1715 #
1716 # An interface receive label that maps traffic to RX on interface
1717 # pg1
1718 # by injecting the packet in on pg0, which is in table 0
1719 # doing an rpf-id and matching a route in table 1
1720 # if the packet egresses, then we must have matched the route in
1721 # table 1
1722 #
Neale Ranns097fa662018-05-01 05:17:55 -07001723 route_34_eos = VppMplsRoute(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001724 self,
1725 34,
1726 1,
1727 [VppRoutePath("0.0.0.0", 0xFFFFFFFF, nh_table_id=1, rpf_id=55)],
Neale Ranns097fa662018-05-01 05:17:55 -07001728 is_multicast=1,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001729 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP4,
1730 )
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001731
1732 route_34_eos.add_vpp_config()
1733
1734 #
1735 # Drop due to interface lookup miss
1736 #
1737 self.vapi.cli("clear trace")
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001738 tx = self.create_stream_labelled_ip4(
1739 self.pg0, [VppMplsLabel(34)], dst_ip="232.1.1.1", n=1
1740 )
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001741 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop none")
1742
1743 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001744 # set the RPF-ID of the entry to match the input packet's
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001745 #
1746 route_232_1_1_1.update_rpf_id(55)
Neale Ranns097fa662018-05-01 05:17:55 -07001747 self.logger.info(self.vapi.cli("sh ip mfib index 1 232.1.1.1"))
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001748
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001749 tx = self.create_stream_labelled_ip4(
1750 self.pg0, [VppMplsLabel(34)], dst_ip="232.1.1.1"
1751 )
Neale Ranns31ed7442018-02-23 05:29:09 -08001752 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001753 self.verify_capture_ip4(self.pg1, rx, tx)
1754
1755 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001756 # disposed packets have an invalid IPv4 checksum
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001757 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001758 tx = self.create_stream_labelled_ip4(
1759 self.pg0, [VppMplsLabel(34)], dst_ip="232.1.1.1", n=65, chksum=1
1760 )
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001761 self.send_and_assert_no_replies(self.pg0, tx, "Invalid Checksum")
1762
1763 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001764 # set the RPF-ID of the entry to not match the input packet's
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001765 #
1766 route_232_1_1_1.update_rpf_id(56)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001767 tx = self.create_stream_labelled_ip4(
1768 self.pg0, [VppMplsLabel(34)], dst_ip="232.1.1.1"
1769 )
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001770 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop 56")
1771
Neale Ranns31426c62017-05-24 10:32:58 -07001772 def test_mcast_ip6_tail(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001773 """MPLS IPv6 Multicast Tail"""
Neale Ranns31426c62017-05-24 10:32:58 -07001774
Neale Ranns990f6942020-10-20 07:20:17 +00001775 MRouteItfFlags = VppEnum.vl_api_mfib_itf_flags_t
1776 MRouteEntryFlags = VppEnum.vl_api_mfib_entry_flags_t
1777
Neale Ranns31426c62017-05-24 10:32:58 -07001778 #
1779 # Add a multicast route that will forward the traffic
1780 # post-disposition
1781 #
1782 route_ff = VppIpMRoute(
1783 self,
1784 "::",
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001785 "ff01::1",
1786 32,
Neale Ranns990f6942020-10-20 07:20:17 +00001787 MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
Neale Ranns31426c62017-05-24 10:32:58 -07001788 table_id=1,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001789 paths=[
1790 VppMRoutePath(
1791 self.pg1.sw_if_index,
1792 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD,
1793 proto=FibPathProto.FIB_PATH_NH_PROTO_IP6,
1794 )
1795 ],
1796 )
Neale Ranns31426c62017-05-24 10:32:58 -07001797 route_ff.add_vpp_config()
1798
1799 #
1800 # An interface receive label that maps traffic to RX on interface
1801 # pg1
1802 # by injecting the packet in on pg0, which is in table 0
1803 # doing an rpf-id and matching a route in table 1
1804 # if the packet egresses, then we must have matched the route in
1805 # table 1
1806 #
1807 route_34_eos = VppMplsRoute(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001808 self,
1809 34,
1810 1,
1811 [VppRoutePath("::", 0xFFFFFFFF, nh_table_id=1, rpf_id=55)],
Neale Ranns097fa662018-05-01 05:17:55 -07001812 is_multicast=1,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001813 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP6,
1814 )
Neale Ranns31426c62017-05-24 10:32:58 -07001815
1816 route_34_eos.add_vpp_config()
1817
1818 #
1819 # Drop due to interface lookup miss
1820 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001821 tx = self.create_stream_labelled_ip6(
1822 self.pg0, [VppMplsLabel(34)], dst_ip="ff01::1"
1823 )
Neale Ranns31ed7442018-02-23 05:29:09 -08001824 self.send_and_assert_no_replies(self.pg0, tx, "RPF Miss")
Neale Ranns31426c62017-05-24 10:32:58 -07001825
1826 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001827 # set the RPF-ID of the entry to match the input packet's
Neale Ranns31426c62017-05-24 10:32:58 -07001828 #
1829 route_ff.update_rpf_id(55)
1830
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001831 tx = self.create_stream_labelled_ip6(
1832 self.pg0, [VppMplsLabel(34)], dst_ip="ff01::1"
1833 )
Neale Ranns31ed7442018-02-23 05:29:09 -08001834 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns31426c62017-05-24 10:32:58 -07001835 self.verify_capture_ip6(self.pg1, rx, tx)
1836
1837 #
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001838 # disposed packets have hop-limit = 1
1839 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001840 tx = self.create_stream_labelled_ip6(
1841 self.pg0, [VppMplsLabel(34)], dst_ip="ff01::1", hlim=1
1842 )
Neale Ranns5c6dd172022-02-17 09:08:47 +00001843 rx = self.send_and_expect_some(self.pg0, tx, self.pg0)
Neale Ranns52fae862018-01-08 04:41:42 -08001844 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001845
1846 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001847 # set the RPF-ID of the entry to not match the input packet's
Neale Ranns31426c62017-05-24 10:32:58 -07001848 #
1849 route_ff.update_rpf_id(56)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001850 tx = self.create_stream_labelled_ip6(
1851 self.pg0, [VppMplsLabel(34)], dst_ip="ff01::1"
1852 )
Neale Ranns31426c62017-05-24 10:32:58 -07001853 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop 56")
1854
Neale Rannsd5d7b962019-08-04 03:30:56 -07001855 def test_6pe(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001856 """MPLS 6PE"""
Neale Rannsd5d7b962019-08-04 03:30:56 -07001857
1858 #
1859 # Add a non-recursive route with a single out label
1860 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001861 route_10_0_0_1 = VppIpRoute(
1862 self,
1863 "10.0.0.1",
1864 32,
1865 [
1866 VppRoutePath(
1867 self.pg0.remote_ip4, self.pg0.sw_if_index, labels=[VppMplsLabel(45)]
1868 )
1869 ],
1870 )
Neale Rannsd5d7b962019-08-04 03:30:56 -07001871 route_10_0_0_1.add_vpp_config()
1872
1873 # bind a local label to the route
1874 binding = VppMplsIpBind(self, 44, "10.0.0.1", 32)
1875 binding.add_vpp_config()
1876
1877 #
1878 # a labelled v6 route that resolves through the v4
1879 #
1880 route_2001_3 = VppIpRoute(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001881 self,
1882 "2001::3",
1883 128,
1884 [VppRoutePath("10.0.0.1", INVALID_INDEX, labels=[VppMplsLabel(32)])],
1885 )
Neale Rannsd5d7b962019-08-04 03:30:56 -07001886 route_2001_3.add_vpp_config()
1887
1888 tx = self.create_stream_ip6(self.pg0, "2001::3")
1889 rx = self.send_and_expect(self.pg0, tx, self.pg0)
1890
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001891 self.verify_capture_labelled_ip6(
1892 self.pg0, rx, tx, [VppMplsLabel(45), VppMplsLabel(32)]
1893 )
Neale Rannsd5d7b962019-08-04 03:30:56 -07001894
1895 #
1896 # and a v4 recursive via the v6
1897 #
1898 route_20_3 = VppIpRoute(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001899 self,
1900 "20.0.0.3",
1901 32,
1902 [VppRoutePath("2001::3", INVALID_INDEX, labels=[VppMplsLabel(99)])],
1903 )
Neale Rannsd5d7b962019-08-04 03:30:56 -07001904 route_20_3.add_vpp_config()
1905
1906 tx = self.create_stream_ip4(self.pg0, "20.0.0.3")
1907 rx = self.send_and_expect(self.pg0, tx, self.pg0)
1908
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001909 self.verify_capture_labelled_ip4(
1910 self.pg0, rx, tx, [VppMplsLabel(45), VppMplsLabel(32), VppMplsLabel(99)]
1911 )
Neale Rannsd5d7b962019-08-04 03:30:56 -07001912
Neale Ranns53962fb2021-12-20 18:18:42 +00001913 def test_attached(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001914 """Attach Routes with Local Label"""
Neale Ranns53962fb2021-12-20 18:18:42 +00001915
1916 #
1917 # test that if a local label is associated with an attached/connected
1918 # prefix, that we can reach hosts in the prefix.
1919 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001920 binding = VppMplsIpBind(
1921 self, 44, self.pg0._local_ip4_subnet, self.pg0.local_ip4_prefix_len
1922 )
Neale Ranns53962fb2021-12-20 18:18:42 +00001923 binding.add_vpp_config()
1924
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001925 tx = (
1926 Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac)
1927 / MPLS(label=44, ttl=64)
1928 / IP(src=self.pg0.remote_ip4, dst=self.pg0.remote_ip4)
1929 / UDP(sport=1234, dport=1234)
1930 / Raw(b"\xa5" * 100)
1931 )
Neale Ranns53962fb2021-12-20 18:18:42 +00001932 rxs = self.send_and_expect(self.pg0, [tx], self.pg0)
1933 for rx in rxs:
1934 # if there's an ARP then the label is linked to the glean
1935 # which is wrong.
1936 self.assertFalse(rx.haslayer(ARP))
1937 # it should be unicasted to the host
1938 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
1939 self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
1940
Neale Ranns180279b2017-03-16 15:49:09 -04001941
1942class TestMPLSDisabled(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001943 """MPLS disabled"""
Neale Ranns180279b2017-03-16 15:49:09 -04001944
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -07001945 @classmethod
1946 def setUpClass(cls):
1947 super(TestMPLSDisabled, cls).setUpClass()
1948
1949 @classmethod
1950 def tearDownClass(cls):
1951 super(TestMPLSDisabled, cls).tearDownClass()
1952
Neale Ranns180279b2017-03-16 15:49:09 -04001953 def setUp(self):
1954 super(TestMPLSDisabled, self).setUp()
1955
1956 # create 2 pg interfaces
1957 self.create_pg_interfaces(range(2))
1958
Neale Ranns15002542017-09-10 04:39:11 -07001959 self.tbl = VppMplsTable(self, 0)
1960 self.tbl.add_vpp_config()
1961
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001962 # PG0 is MPLS enabled
Neale Ranns180279b2017-03-16 15:49:09 -04001963 self.pg0.admin_up()
1964 self.pg0.config_ip4()
1965 self.pg0.resolve_arp()
1966 self.pg0.enable_mpls()
1967
1968 # PG 1 is not MPLS enabled
1969 self.pg1.admin_up()
1970
1971 def tearDown(self):
Neale Ranns180279b2017-03-16 15:49:09 -04001972 for i in self.pg_interfaces:
1973 i.unconfig_ip4()
1974 i.admin_down()
1975
Neale Ranns15002542017-09-10 04:39:11 -07001976 self.pg0.disable_mpls()
1977 super(TestMPLSDisabled, self).tearDown()
1978
Neale Ranns180279b2017-03-16 15:49:09 -04001979 def test_mpls_disabled(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001980 """MPLS Disabled"""
Neale Ranns180279b2017-03-16 15:49:09 -04001981
Neale Rannsde0b3b52021-06-15 12:43:12 +00001982 self.logger.info(self.vapi.cli("show mpls interface"))
1983 self.logger.info(self.vapi.cli("show mpls interface pg1"))
1984 self.logger.info(self.vapi.cli("show mpls interface pg0"))
1985
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001986 tx = (
1987 Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac)
1988 / MPLS(label=32, ttl=64)
1989 / IPv6(src="2001::1", dst=self.pg0.remote_ip6)
1990 / UDP(sport=1234, dport=1234)
1991 / Raw(b"\xa5" * 100)
1992 )
Neale Ranns180279b2017-03-16 15:49:09 -04001993
1994 #
1995 # A simple MPLS xconnect - eos label in label out
1996 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001997 route_32_eos = VppMplsRoute(
1998 self,
1999 32,
2000 1,
2001 [VppRoutePath(self.pg0.remote_ip4, self.pg0.sw_if_index, labels=[33])],
2002 )
Neale Ranns180279b2017-03-16 15:49:09 -04002003 route_32_eos.add_vpp_config()
2004
2005 #
2006 # PG1 does not forward IP traffic
2007 #
2008 self.send_and_assert_no_replies(self.pg1, tx, "MPLS disabled")
2009
2010 #
2011 # MPLS enable PG1
2012 #
2013 self.pg1.enable_mpls()
2014
Neale Rannsde0b3b52021-06-15 12:43:12 +00002015 self.logger.info(self.vapi.cli("show mpls interface"))
2016 self.logger.info(self.vapi.cli("show mpls interface pg1"))
2017
Neale Ranns180279b2017-03-16 15:49:09 -04002018 #
2019 # Now we get packets through
2020 #
2021 self.pg1.add_stream(tx)
2022 self.pg_enable_capture(self.pg_interfaces)
2023 self.pg_start()
2024
2025 rx = self.pg0.get_capture(1)
2026
2027 #
2028 # Disable PG1
2029 #
2030 self.pg1.disable_mpls()
2031
2032 #
2033 # PG1 does not forward IP traffic
2034 #
2035 self.send_and_assert_no_replies(self.pg1, tx, "IPv6 disabled")
2036 self.send_and_assert_no_replies(self.pg1, tx, "IPv6 disabled")
2037
2038
Neale Rannsf12a83f2017-04-18 09:09:40 -07002039class TestMPLSPIC(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002040 """MPLS Prefix-Independent Convergence (PIC) edge convergence"""
Neale Rannsf12a83f2017-04-18 09:09:40 -07002041
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -07002042 @classmethod
2043 def setUpClass(cls):
2044 super(TestMPLSPIC, cls).setUpClass()
2045
2046 @classmethod
2047 def tearDownClass(cls):
2048 super(TestMPLSPIC, cls).tearDownClass()
2049
Neale Rannsf12a83f2017-04-18 09:09:40 -07002050 def setUp(self):
2051 super(TestMPLSPIC, self).setUp()
2052
2053 # create 2 pg interfaces
2054 self.create_pg_interfaces(range(4))
2055
Neale Ranns15002542017-09-10 04:39:11 -07002056 mpls_tbl = VppMplsTable(self, 0)
2057 mpls_tbl.add_vpp_config()
2058 tbl4 = VppIpTable(self, 1)
2059 tbl4.add_vpp_config()
2060 tbl6 = VppIpTable(self, 1, is_ip6=1)
2061 tbl6.add_vpp_config()
2062
Neale Rannsf12a83f2017-04-18 09:09:40 -07002063 # core links
2064 self.pg0.admin_up()
2065 self.pg0.config_ip4()
2066 self.pg0.resolve_arp()
2067 self.pg0.enable_mpls()
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002068
Neale Rannsf12a83f2017-04-18 09:09:40 -07002069 self.pg1.admin_up()
2070 self.pg1.config_ip4()
2071 self.pg1.resolve_arp()
2072 self.pg1.enable_mpls()
2073
2074 # VRF (customer facing) link
2075 self.pg2.admin_up()
2076 self.pg2.set_table_ip4(1)
2077 self.pg2.config_ip4()
2078 self.pg2.resolve_arp()
2079 self.pg2.set_table_ip6(1)
2080 self.pg2.config_ip6()
2081 self.pg2.resolve_ndp()
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002082
Neale Rannsf12a83f2017-04-18 09:09:40 -07002083 self.pg3.admin_up()
2084 self.pg3.set_table_ip4(1)
2085 self.pg3.config_ip4()
2086 self.pg3.resolve_arp()
2087 self.pg3.set_table_ip6(1)
2088 self.pg3.config_ip6()
2089 self.pg3.resolve_ndp()
2090
2091 def tearDown(self):
Neale Rannsf12a83f2017-04-18 09:09:40 -07002092 self.pg0.disable_mpls()
Neale Ranns15002542017-09-10 04:39:11 -07002093 self.pg1.disable_mpls()
Neale Rannsf12a83f2017-04-18 09:09:40 -07002094 for i in self.pg_interfaces:
2095 i.unconfig_ip4()
2096 i.unconfig_ip6()
2097 i.set_table_ip4(0)
2098 i.set_table_ip6(0)
2099 i.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -07002100 super(TestMPLSPIC, self).tearDown()
Neale Rannsf12a83f2017-04-18 09:09:40 -07002101
2102 def test_mpls_ibgp_pic(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002103 """MPLS iBGP Prefix-Independent Convergence (PIC) edge convergence
Neale Rannsf12a83f2017-04-18 09:09:40 -07002104
2105 1) setup many iBGP VPN routes via a pair of iBGP peers.
2106 2) Check EMCP forwarding to these peers
2107 3) withdraw the IGP route to one of these peers.
2108 4) check forwarding continues to the remaining peer
2109 """
2110
2111 #
2112 # IGP+LDP core routes
2113 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002114 core_10_0_0_45 = VppIpRoute(
2115 self,
2116 "10.0.0.45",
2117 32,
2118 [VppRoutePath(self.pg0.remote_ip4, self.pg0.sw_if_index, labels=[45])],
2119 )
Neale Rannsf12a83f2017-04-18 09:09:40 -07002120 core_10_0_0_45.add_vpp_config()
2121
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002122 core_10_0_0_46 = VppIpRoute(
2123 self,
2124 "10.0.0.46",
2125 32,
2126 [VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index, labels=[46])],
2127 )
Neale Rannsf12a83f2017-04-18 09:09:40 -07002128 core_10_0_0_46.add_vpp_config()
2129
2130 #
2131 # Lot's of VPN routes. We need more the 64 so VPP will build
2132 # the fast convergence indirection
2133 #
2134 vpn_routes = []
2135 pkts = []
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002136 for ii in range(NUM_PKTS):
Neale Rannsf12a83f2017-04-18 09:09:40 -07002137 dst = "192.168.1.%d" % ii
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002138 vpn_routes.append(
2139 VppIpRoute(
2140 self,
2141 dst,
2142 32,
2143 [
2144 VppRoutePath(
2145 "10.0.0.45",
2146 0xFFFFFFFF,
2147 labels=[145],
2148 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_HOST,
2149 ),
2150 VppRoutePath(
2151 "10.0.0.46",
2152 0xFFFFFFFF,
2153 labels=[146],
2154 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_HOST,
2155 ),
2156 ],
2157 table_id=1,
2158 )
2159 )
Neale Rannsf12a83f2017-04-18 09:09:40 -07002160 vpn_routes[ii].add_vpp_config()
2161
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002162 pkts.append(
2163 Ether(dst=self.pg2.local_mac, src=self.pg2.remote_mac)
2164 / IP(src=self.pg2.remote_ip4, dst=dst)
2165 / UDP(sport=1234, dport=1234)
2166 / Raw(b"\xa5" * 100)
2167 )
Neale Rannsf12a83f2017-04-18 09:09:40 -07002168
2169 #
2170 # Send the packet stream (one pkt to each VPN route)
2171 # - expect a 50-50 split of the traffic
2172 #
2173 self.pg2.add_stream(pkts)
2174 self.pg_enable_capture(self.pg_interfaces)
2175 self.pg_start()
2176
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002177 rx0 = self.pg0._get_capture(NUM_PKTS)
2178 rx1 = self.pg1._get_capture(NUM_PKTS)
Neale Rannsf12a83f2017-04-18 09:09:40 -07002179
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002180 # not testing the LB hashing algorithm so we're not concerned
Neale Rannsf12a83f2017-04-18 09:09:40 -07002181 # with the split ratio, just as long as neither is 0
2182 self.assertNotEqual(0, len(rx0))
2183 self.assertNotEqual(0, len(rx1))
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002184 self.assertEqual(
2185 len(pkts),
2186 len(rx0) + len(rx1),
2187 "Expected all (%s) packets across both ECMP paths. "
2188 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)),
2189 )
Neale Rannsf12a83f2017-04-18 09:09:40 -07002190
2191 #
2192 # use a test CLI command to stop the FIB walk process, this
2193 # will prevent the FIB converging the VPN routes and thus allow
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002194 # us to probe the interim (post-fail, pre-converge) state
Neale Rannsf12a83f2017-04-18 09:09:40 -07002195 #
2196 self.vapi.ppcli("test fib-walk-process disable")
2197
2198 #
2199 # Withdraw one of the IGP routes
2200 #
2201 core_10_0_0_46.remove_vpp_config()
2202
2203 #
2204 # now all packets should be forwarded through the remaining peer
2205 #
2206 self.vapi.ppcli("clear trace")
2207 self.pg2.add_stream(pkts)
2208 self.pg_enable_capture(self.pg_interfaces)
2209 self.pg_start()
2210
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002211 rx0 = self.pg0.get_capture(NUM_PKTS)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002212 self.assertEqual(
2213 len(pkts),
2214 len(rx0),
2215 "Expected all (%s) packets across single path. "
2216 "rx0: %s." % (len(pkts), len(rx0)),
2217 )
Neale Rannsf12a83f2017-04-18 09:09:40 -07002218
2219 #
2220 # enable the FIB walk process to converge the FIB
2221 #
2222 self.vapi.ppcli("test fib-walk-process enable")
2223
2224 #
2225 # packets should still be forwarded through the remaining peer
2226 #
2227 self.pg2.add_stream(pkts)
2228 self.pg_enable_capture(self.pg_interfaces)
2229 self.pg_start()
2230
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002231 rx0 = self.pg0.get_capture(NUM_PKTS)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002232 self.assertEqual(
2233 len(pkts),
2234 len(rx0),
2235 "Expected all (%s) packets across single path. "
2236 "rx0: %s." % (len(pkts), len(rx0)),
2237 )
Neale Rannsf12a83f2017-04-18 09:09:40 -07002238
2239 #
2240 # Add the IGP route back and we return to load-balancing
2241 #
2242 core_10_0_0_46.add_vpp_config()
2243
2244 self.pg2.add_stream(pkts)
2245 self.pg_enable_capture(self.pg_interfaces)
2246 self.pg_start()
2247
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002248 rx0 = self.pg0._get_capture(NUM_PKTS)
2249 rx1 = self.pg1._get_capture(NUM_PKTS)
Neale Rannsf12a83f2017-04-18 09:09:40 -07002250 self.assertNotEqual(0, len(rx0))
2251 self.assertNotEqual(0, len(rx1))
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002252 self.assertEqual(
2253 len(pkts),
2254 len(rx0) + len(rx1),
2255 "Expected all (%s) packets across both ECMP paths. "
2256 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)),
2257 )
Neale Rannsf12a83f2017-04-18 09:09:40 -07002258
2259 def test_mpls_ebgp_pic(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002260 """MPLS eBGP Prefix-Independent Convergence (PIC) edge convergence
Neale Rannsf12a83f2017-04-18 09:09:40 -07002261
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002262 1) setup many eBGP VPN routes via a pair of eBGP peers.
Neale Rannsf12a83f2017-04-18 09:09:40 -07002263 2) Check EMCP forwarding to these peers
2264 3) withdraw one eBGP path - expect LB across remaining eBGP
2265 """
2266
2267 #
2268 # Lot's of VPN routes. We need more the 64 so VPP will build
2269 # the fast convergence indirection
2270 #
2271 vpn_routes = []
2272 vpn_bindings = []
2273 pkts = []
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002274 for ii in range(NUM_PKTS):
Neale Rannsf12a83f2017-04-18 09:09:40 -07002275 dst = "192.168.1.%d" % ii
2276 local_label = 1600 + ii
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002277 vpn_routes.append(
2278 VppIpRoute(
2279 self,
2280 dst,
2281 32,
2282 [
2283 VppRoutePath(
2284 self.pg2.remote_ip4,
2285 0xFFFFFFFF,
2286 nh_table_id=1,
2287 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_ATTACHED,
2288 ),
2289 VppRoutePath(
2290 self.pg3.remote_ip4,
2291 0xFFFFFFFF,
2292 nh_table_id=1,
2293 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_ATTACHED,
2294 ),
2295 ],
2296 table_id=1,
2297 )
2298 )
Neale Rannsf12a83f2017-04-18 09:09:40 -07002299 vpn_routes[ii].add_vpp_config()
2300
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002301 vpn_bindings.append(
2302 VppMplsIpBind(self, local_label, dst, 32, ip_table_id=1)
2303 )
Neale Rannsf12a83f2017-04-18 09:09:40 -07002304 vpn_bindings[ii].add_vpp_config()
2305
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002306 pkts.append(
2307 Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
2308 / MPLS(label=local_label, ttl=64)
2309 / IP(src=self.pg0.remote_ip4, dst=dst)
2310 / UDP(sport=1234, dport=1234)
2311 / Raw(b"\xa5" * 100)
2312 )
Neale Rannsf12a83f2017-04-18 09:09:40 -07002313
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002314 #
2315 # Send the packet stream (one pkt to each VPN route)
2316 # - expect a 50-50 split of the traffic
2317 #
Neale Rannsf12a83f2017-04-18 09:09:40 -07002318 self.pg0.add_stream(pkts)
2319 self.pg_enable_capture(self.pg_interfaces)
2320 self.pg_start()
2321
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002322 rx0 = self.pg2._get_capture(NUM_PKTS)
2323 rx1 = self.pg3._get_capture(NUM_PKTS)
2324
2325 # not testing the LB hashing algorithm so we're not concerned
2326 # with the split ratio, just as long as neither is 0
Neale Rannsf12a83f2017-04-18 09:09:40 -07002327 self.assertNotEqual(0, len(rx0))
2328 self.assertNotEqual(0, len(rx1))
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002329 self.assertEqual(
2330 len(pkts),
2331 len(rx0) + len(rx1),
2332 "Expected all (%s) packets across both ECMP paths. "
2333 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)),
2334 )
Neale Rannsf12a83f2017-04-18 09:09:40 -07002335
2336 #
2337 # use a test CLI command to stop the FIB walk process, this
2338 # will prevent the FIB converging the VPN routes and thus allow
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002339 # us to probe the interim (post-fail, pre-converge) state
Neale Rannsf12a83f2017-04-18 09:09:40 -07002340 #
2341 self.vapi.ppcli("test fib-walk-process disable")
2342
2343 #
2344 # withdraw the connected prefix on the interface.
2345 #
2346 self.pg2.unconfig_ip4()
2347
2348 #
2349 # now all packets should be forwarded through the remaining peer
2350 #
2351 self.pg0.add_stream(pkts)
2352 self.pg_enable_capture(self.pg_interfaces)
2353 self.pg_start()
2354
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002355 rx0 = self.pg3.get_capture(NUM_PKTS)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002356 self.assertEqual(
2357 len(pkts),
2358 len(rx0),
2359 "Expected all (%s) packets across single path. "
2360 "rx0: %s." % (len(pkts), len(rx0)),
2361 )
Neale Rannsf12a83f2017-04-18 09:09:40 -07002362
2363 #
2364 # enable the FIB walk process to converge the FIB
2365 #
2366 self.vapi.ppcli("test fib-walk-process enable")
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002367
2368 #
2369 # packets should still be forwarded through the remaining peer
2370 #
Neale Rannsf12a83f2017-04-18 09:09:40 -07002371 self.pg0.add_stream(pkts)
2372 self.pg_enable_capture(self.pg_interfaces)
2373 self.pg_start()
2374
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002375 rx0 = self.pg3.get_capture(NUM_PKTS)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002376 self.assertEqual(
2377 len(pkts),
2378 len(rx0),
2379 "Expected all (%s) packets across single path. "
2380 "rx0: %s." % (len(pkts), len(rx0)),
2381 )
Neale Rannsf12a83f2017-04-18 09:09:40 -07002382
2383 #
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002384 # put the connected routes back
Neale Rannsf12a83f2017-04-18 09:09:40 -07002385 #
2386 self.pg2.config_ip4()
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002387 self.pg2.resolve_arp()
Neale Rannsf12a83f2017-04-18 09:09:40 -07002388
2389 self.pg0.add_stream(pkts)
2390 self.pg_enable_capture(self.pg_interfaces)
2391 self.pg_start()
2392
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002393 rx0 = self.pg2._get_capture(NUM_PKTS)
2394 rx1 = self.pg3._get_capture(NUM_PKTS)
Neale Rannsf12a83f2017-04-18 09:09:40 -07002395 self.assertNotEqual(0, len(rx0))
2396 self.assertNotEqual(0, len(rx1))
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002397 self.assertEqual(
2398 len(pkts),
2399 len(rx0) + len(rx1),
2400 "Expected all (%s) packets across both ECMP paths. "
2401 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)),
2402 )
Neale Rannsf12a83f2017-04-18 09:09:40 -07002403
2404 def test_mpls_v6_ebgp_pic(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002405 """MPLSv6 eBGP Prefix-Independent Convergence (PIC) edge convergence
Neale Rannsf12a83f2017-04-18 09:09:40 -07002406
2407 1) setup many eBGP VPNv6 routes via a pair of eBGP peers
2408 2) Check EMCP forwarding to these peers
2409 3) withdraw one eBGP path - expect LB across remaining eBGP
2410 """
2411
2412 #
2413 # Lot's of VPN routes. We need more the 64 so VPP will build
2414 # the fast convergence indirection
2415 #
2416 vpn_routes = []
2417 vpn_bindings = []
2418 pkts = []
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002419 for ii in range(NUM_PKTS):
Neale Rannsf12a83f2017-04-18 09:09:40 -07002420 dst = "3000::%d" % ii
2421 local_label = 1600 + ii
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002422 vpn_routes.append(
2423 VppIpRoute(
2424 self,
2425 dst,
2426 128,
2427 [
2428 VppRoutePath(
2429 self.pg2.remote_ip6,
2430 0xFFFFFFFF,
2431 nh_table_id=1,
2432 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_ATTACHED,
2433 ),
2434 VppRoutePath(
2435 self.pg3.remote_ip6,
2436 0xFFFFFFFF,
2437 nh_table_id=1,
2438 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_ATTACHED,
2439 ),
2440 ],
2441 table_id=1,
2442 )
2443 )
Neale Rannsf12a83f2017-04-18 09:09:40 -07002444 vpn_routes[ii].add_vpp_config()
2445
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002446 vpn_bindings.append(
2447 VppMplsIpBind(self, local_label, dst, 128, ip_table_id=1)
2448 )
Neale Rannsf12a83f2017-04-18 09:09:40 -07002449 vpn_bindings[ii].add_vpp_config()
2450
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002451 pkts.append(
2452 Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
2453 / MPLS(label=local_label, ttl=64)
2454 / IPv6(src=self.pg0.remote_ip6, dst=dst)
2455 / UDP(sport=1234, dport=1234)
2456 / Raw(b"\xa5" * 100)
2457 )
Neale Ranns097fa662018-05-01 05:17:55 -07002458 self.logger.info(self.vapi.cli("sh ip6 fib %s" % dst))
Neale Rannsf12a83f2017-04-18 09:09:40 -07002459
2460 self.pg0.add_stream(pkts)
2461 self.pg_enable_capture(self.pg_interfaces)
2462 self.pg_start()
2463
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002464 rx0 = self.pg2._get_capture(NUM_PKTS)
2465 rx1 = self.pg3._get_capture(NUM_PKTS)
Neale Rannsf12a83f2017-04-18 09:09:40 -07002466 self.assertNotEqual(0, len(rx0))
2467 self.assertNotEqual(0, len(rx1))
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002468 self.assertEqual(
2469 len(pkts),
2470 len(rx0) + len(rx1),
2471 "Expected all (%s) packets across both ECMP paths. "
2472 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)),
2473 )
Neale Rannsf12a83f2017-04-18 09:09:40 -07002474
2475 #
2476 # use a test CLI command to stop the FIB walk process, this
2477 # will prevent the FIB converging the VPN routes and thus allow
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002478 # us to probe the interim (post-fail, pre-converge) state
Neale Rannsf12a83f2017-04-18 09:09:40 -07002479 #
2480 self.vapi.ppcli("test fib-walk-process disable")
2481
2482 #
2483 # withdraw the connected prefix on the interface.
2484 # and shutdown the interface so the ND cache is flushed.
2485 #
2486 self.pg2.unconfig_ip6()
2487 self.pg2.admin_down()
2488
2489 #
2490 # now all packets should be forwarded through the remaining peer
2491 #
2492 self.pg0.add_stream(pkts)
2493 self.pg_enable_capture(self.pg_interfaces)
2494 self.pg_start()
2495
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002496 rx0 = self.pg3.get_capture(NUM_PKTS)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002497 self.assertEqual(
2498 len(pkts),
2499 len(rx0),
2500 "Expected all (%s) packets across single path. "
2501 "rx0: %s." % (len(pkts), len(rx0)),
2502 )
Neale Rannsf12a83f2017-04-18 09:09:40 -07002503
2504 #
2505 # enable the FIB walk process to converge the FIB
2506 #
2507 self.vapi.ppcli("test fib-walk-process enable")
2508 self.pg0.add_stream(pkts)
2509 self.pg_enable_capture(self.pg_interfaces)
2510 self.pg_start()
2511
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002512 rx0 = self.pg3.get_capture(NUM_PKTS)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002513 self.assertEqual(
2514 len(pkts),
2515 len(rx0),
2516 "Expected all (%s) packets across single path. "
2517 "rx0: %s." % (len(pkts), len(rx0)),
2518 )
Neale Rannsf12a83f2017-04-18 09:09:40 -07002519
2520 #
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002521 # put the connected routes back
Neale Rannsf12a83f2017-04-18 09:09:40 -07002522 #
Paul Vinciguerraa42c6ee2019-12-27 00:17:01 -05002523 self.logger.info(self.vapi.cli("sh log"))
Neale Rannsf12a83f2017-04-18 09:09:40 -07002524 self.pg2.admin_up()
2525 self.pg2.config_ip6()
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002526 self.pg2.resolve_ndp()
Neale Rannsf12a83f2017-04-18 09:09:40 -07002527
2528 self.pg0.add_stream(pkts)
2529 self.pg_enable_capture(self.pg_interfaces)
2530 self.pg_start()
2531
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002532 rx0 = self.pg2._get_capture(NUM_PKTS)
2533 rx1 = self.pg3._get_capture(NUM_PKTS)
Neale Rannsf12a83f2017-04-18 09:09:40 -07002534 self.assertNotEqual(0, len(rx0))
2535 self.assertNotEqual(0, len(rx1))
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002536 self.assertEqual(
2537 len(pkts),
2538 len(rx0) + len(rx1),
2539 "Expected all (%s) packets across both ECMP paths. "
2540 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)),
2541 )
Neale Rannsf12a83f2017-04-18 09:09:40 -07002542
2543
Neale Rannsda78f952017-05-24 09:15:43 -07002544class TestMPLSL2(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002545 """MPLS-L2"""
Neale Rannsda78f952017-05-24 09:15:43 -07002546
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -07002547 @classmethod
2548 def setUpClass(cls):
2549 super(TestMPLSL2, cls).setUpClass()
2550
2551 @classmethod
2552 def tearDownClass(cls):
2553 super(TestMPLSL2, cls).tearDownClass()
2554
Neale Rannsda78f952017-05-24 09:15:43 -07002555 def setUp(self):
2556 super(TestMPLSL2, self).setUp()
2557
2558 # create 2 pg interfaces
2559 self.create_pg_interfaces(range(2))
2560
Neale Ranns15002542017-09-10 04:39:11 -07002561 # create the default MPLS table
2562 self.tables = []
2563 tbl = VppMplsTable(self, 0)
2564 tbl.add_vpp_config()
2565 self.tables.append(tbl)
2566
Neale Ranns1976f362019-11-06 13:13:01 +00002567 # use pg0 as the core facing interface, don't resolve ARP
Neale Rannsda78f952017-05-24 09:15:43 -07002568 self.pg0.admin_up()
2569 self.pg0.config_ip4()
Neale Rannsda78f952017-05-24 09:15:43 -07002570 self.pg0.enable_mpls()
2571
Neale Ranns15002542017-09-10 04:39:11 -07002572 # use the other 2 for customer facing L2 links
Neale Rannsda78f952017-05-24 09:15:43 -07002573 for i in self.pg_interfaces[1:]:
2574 i.admin_up()
2575
2576 def tearDown(self):
Neale Rannsda78f952017-05-24 09:15:43 -07002577 for i in self.pg_interfaces[1:]:
2578 i.admin_down()
2579
2580 self.pg0.disable_mpls()
2581 self.pg0.unconfig_ip4()
2582 self.pg0.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -07002583 super(TestMPLSL2, self).tearDown()
Neale Rannsda78f952017-05-24 09:15:43 -07002584
Neale Ranns31ed7442018-02-23 05:29:09 -08002585 def verify_capture_tunneled_ethernet(self, capture, sent, mpls_labels):
Neale Rannsda78f952017-05-24 09:15:43 -07002586 capture = verify_filter(capture, sent)
2587
2588 self.assertEqual(len(capture), len(sent))
2589
2590 for i in range(len(capture)):
2591 tx = sent[i]
2592 rx = capture[i]
2593
2594 # the MPLS TTL is 255 since it enters a new tunnel
Neale Ranns31ed7442018-02-23 05:29:09 -08002595 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsda78f952017-05-24 09:15:43 -07002596
2597 tx_eth = tx[Ether]
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -07002598 rx_eth = Ether(scapy.compat.raw(rx[MPLS].payload))
Neale Rannsda78f952017-05-24 09:15:43 -07002599
2600 self.assertEqual(rx_eth.src, tx_eth.src)
2601 self.assertEqual(rx_eth.dst, tx_eth.dst)
2602
Neale Ranns1976f362019-11-06 13:13:01 +00002603 def verify_arp_req(self, rx, smac, sip, dip):
2604 ether = rx[Ether]
2605 self.assertEqual(ether.dst, "ff:ff:ff:ff:ff:ff")
2606 self.assertEqual(ether.src, smac)
2607
2608 arp = rx[ARP]
2609 self.assertEqual(arp.hwtype, 1)
2610 self.assertEqual(arp.ptype, 0x800)
2611 self.assertEqual(arp.hwlen, 6)
2612 self.assertEqual(arp.plen, 4)
2613 self.assertEqual(arp.op, ARP.who_has)
2614 self.assertEqual(arp.hwsrc, smac)
2615 self.assertEqual(arp.hwdst, "00:00:00:00:00:00")
2616 self.assertEqual(arp.psrc, sip)
2617 self.assertEqual(arp.pdst, dip)
2618
Neale Rannsda78f952017-05-24 09:15:43 -07002619 def test_vpws(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002620 """Virtual Private Wire Service"""
Neale Rannsda78f952017-05-24 09:15:43 -07002621
2622 #
2623 # Create an MPLS tunnel that pushes 1 label
Neale Ranns31ed7442018-02-23 05:29:09 -08002624 # For Ethernet over MPLS the uniform mode is irrelevant since ttl/cos
2625 # information is not in the packet, but we test it works anyway
Neale Rannsda78f952017-05-24 09:15:43 -07002626 #
Neale Ranns31ed7442018-02-23 05:29:09 -08002627 mpls_tun_1 = VppMPLSTunnelInterface(
2628 self,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002629 [
2630 VppRoutePath(
2631 self.pg0.remote_ip4,
2632 self.pg0.sw_if_index,
2633 labels=[VppMplsLabel(42, MplsLspMode.UNIFORM)],
2634 )
2635 ],
2636 is_l2=1,
2637 )
Neale Rannsda78f952017-05-24 09:15:43 -07002638 mpls_tun_1.add_vpp_config()
2639 mpls_tun_1.admin_up()
2640
2641 #
2642 # Create a label entry to for 55 that does L2 input to the tunnel
2643 #
2644 route_55_eos = VppMplsRoute(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002645 self,
2646 55,
2647 1,
2648 [
2649 VppRoutePath(
2650 "0.0.0.0",
2651 mpls_tun_1.sw_if_index,
2652 type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX,
2653 proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET,
2654 )
2655 ],
2656 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET,
2657 )
Neale Rannsda78f952017-05-24 09:15:43 -07002658 route_55_eos.add_vpp_config()
2659
2660 #
2661 # Cross-connect the tunnel with one of the customers L2 interfaces
2662 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002663 self.vapi.sw_interface_set_l2_xconnect(
2664 self.pg1.sw_if_index, mpls_tun_1.sw_if_index, enable=1
2665 )
2666 self.vapi.sw_interface_set_l2_xconnect(
2667 mpls_tun_1.sw_if_index, self.pg1.sw_if_index, enable=1
2668 )
Neale Rannsda78f952017-05-24 09:15:43 -07002669
2670 #
2671 # inject a packet from the core
2672 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002673 pcore = (
2674 Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
2675 / MPLS(label=55, ttl=64)
2676 / Ether(dst="00:00:de:ad:ba:be", src="00:00:de:ad:be:ef")
2677 / IP(src="10.10.10.10", dst="11.11.11.11")
2678 / UDP(sport=1234, dport=1234)
2679 / Raw(b"\xa5" * 100)
2680 )
Neale Rannsda78f952017-05-24 09:15:43 -07002681
Paul Vinciguerra4271c972019-05-14 13:25:49 -04002682 tx0 = pcore * NUM_PKTS
Neale Ranns31ed7442018-02-23 05:29:09 -08002683 rx0 = self.send_and_expect(self.pg0, tx0, self.pg1)
2684 payload = pcore[MPLS].payload
Neale Rannsda78f952017-05-24 09:15:43 -07002685
Neale Ranns31ed7442018-02-23 05:29:09 -08002686 self.assertEqual(rx0[0][Ether].dst, payload[Ether].dst)
2687 self.assertEqual(rx0[0][Ether].src, payload[Ether].src)
Neale Rannsda78f952017-05-24 09:15:43 -07002688
2689 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002690 # Inject a packet from the customer/L2 side
Neale Ranns1976f362019-11-06 13:13:01 +00002691 # there's no resolved ARP entry so the first packet we see should be
2692 # an ARP request
Neale Rannsda78f952017-05-24 09:15:43 -07002693 #
Neale Ranns1976f362019-11-06 13:13:01 +00002694 tx1 = pcore[MPLS].payload
2695 rx1 = self.send_and_expect(self.pg1, [tx1], self.pg0)
2696
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002697 self.verify_arp_req(
2698 rx1[0], self.pg0.local_mac, self.pg0.local_ip4, self.pg0.remote_ip4
2699 )
Neale Ranns1976f362019-11-06 13:13:01 +00002700
2701 #
2702 # resolve the ARP entries and send again
2703 #
2704 self.pg0.resolve_arp()
Paul Vinciguerra4271c972019-05-14 13:25:49 -04002705 tx1 = pcore[MPLS].payload * NUM_PKTS
Neale Ranns31ed7442018-02-23 05:29:09 -08002706 rx1 = self.send_and_expect(self.pg1, tx1, self.pg0)
Neale Rannsda78f952017-05-24 09:15:43 -07002707
Neale Ranns31ed7442018-02-23 05:29:09 -08002708 self.verify_capture_tunneled_ethernet(rx1, tx1, [VppMplsLabel(42)])
Neale Rannsda78f952017-05-24 09:15:43 -07002709
2710 def test_vpls(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002711 """Virtual Private LAN Service"""
Neale Ranns1976f362019-11-06 13:13:01 +00002712
2713 # we skipped this in the setup
2714 self.pg0.resolve_arp()
2715
Neale Rannsda78f952017-05-24 09:15:43 -07002716 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002717 # Create a L2 MPLS tunnels
Neale Rannsda78f952017-05-24 09:15:43 -07002718 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002719 mpls_tun1 = VppMPLSTunnelInterface(
Neale Ranns31ed7442018-02-23 05:29:09 -08002720 self,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002721 [
2722 VppRoutePath(
2723 self.pg0.remote_ip4, self.pg0.sw_if_index, labels=[VppMplsLabel(42)]
2724 )
2725 ],
2726 is_l2=1,
2727 )
Neale Ranns1dbcf302019-07-19 11:44:53 +00002728 mpls_tun1.add_vpp_config()
2729 mpls_tun1.admin_up()
2730
2731 mpls_tun2 = VppMPLSTunnelInterface(
2732 self,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002733 [
2734 VppRoutePath(
2735 self.pg0.remote_ip4, self.pg0.sw_if_index, labels=[VppMplsLabel(43)]
2736 )
2737 ],
2738 is_l2=1,
2739 )
Neale Ranns1dbcf302019-07-19 11:44:53 +00002740 mpls_tun2.add_vpp_config()
2741 mpls_tun2.admin_up()
Neale Rannsda78f952017-05-24 09:15:43 -07002742
2743 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002744 # Create a label entries, 55 and 56, that do L2 input to the tunnel
2745 # the latter includes a Psuedo Wire Control Word
Neale Rannsda78f952017-05-24 09:15:43 -07002746 #
2747 route_55_eos = VppMplsRoute(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002748 self,
2749 55,
2750 1,
2751 [
2752 VppRoutePath(
2753 "0.0.0.0",
2754 mpls_tun1.sw_if_index,
2755 type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX,
2756 proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET,
2757 )
2758 ],
2759 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET,
2760 )
Neale Ranns1dbcf302019-07-19 11:44:53 +00002761
2762 route_56_eos = VppMplsRoute(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002763 self,
2764 56,
2765 1,
2766 [
2767 VppRoutePath(
2768 "0.0.0.0",
2769 mpls_tun2.sw_if_index,
2770 type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX,
2771 flags=FibPathFlags.FIB_PATH_FLAG_POP_PW_CW,
2772 proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET,
2773 )
2774 ],
2775 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET,
2776 )
Neale Ranns1dbcf302019-07-19 11:44:53 +00002777
2778 # move me
2779 route_56_eos.add_vpp_config()
Neale Rannsda78f952017-05-24 09:15:43 -07002780 route_55_eos.add_vpp_config()
2781
Neale Ranns1dbcf302019-07-19 11:44:53 +00002782 self.logger.info(self.vapi.cli("sh mpls fib 56"))
2783
Neale Rannsda78f952017-05-24 09:15:43 -07002784 #
2785 # add to tunnel to the customers bridge-domain
2786 #
Ole Troana5b2eec2019-03-11 19:23:25 +01002787 self.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002788 rx_sw_if_index=mpls_tun1.sw_if_index, bd_id=1
2789 )
Neale Ranns1dbcf302019-07-19 11:44:53 +00002790 self.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002791 rx_sw_if_index=mpls_tun2.sw_if_index, bd_id=1
2792 )
Ole Troana5b2eec2019-03-11 19:23:25 +01002793 self.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002794 rx_sw_if_index=self.pg1.sw_if_index, bd_id=1
2795 )
Neale Rannsda78f952017-05-24 09:15:43 -07002796
2797 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002798 # Packet from host on the customer interface to each host
2799 # reachable over the core, and vice-versa
Neale Rannsda78f952017-05-24 09:15:43 -07002800 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002801 p_cust1 = (
2802 Ether(dst="00:00:de:ad:ba:b1", src="00:00:de:ad:be:ef")
2803 / IP(src="10.10.10.10", dst="11.11.11.11")
2804 / UDP(sport=1234, dport=1234)
2805 / Raw(b"\xa5" * 100)
2806 )
2807 p_cust2 = (
2808 Ether(dst="00:00:de:ad:ba:b2", src="00:00:de:ad:be:ef")
2809 / IP(src="10.10.10.10", dst="11.11.11.12")
2810 / UDP(sport=1234, dport=1234)
2811 / Raw(b"\xa5" * 100)
2812 )
2813 p_core1 = (
2814 Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
2815 / MPLS(label=55, ttl=64)
2816 / Ether(src="00:00:de:ad:ba:b1", dst="00:00:de:ad:be:ef")
2817 / IP(dst="10.10.10.10", src="11.11.11.11")
2818 / UDP(sport=1234, dport=1234)
2819 / Raw(b"\xa5" * 100)
2820 )
2821 p_core2 = (
2822 Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
2823 / MPLS(label=56, ttl=64)
2824 / Raw(b"\x01" * 4)
2825 / Ether(src="00:00:de:ad:ba:b2", dst="00:00:de:ad:be:ef") # PW CW
2826 / IP(dst="10.10.10.10", src="11.11.11.12")
2827 / UDP(sport=1234, dport=1234)
2828 / Raw(b"\xa5" * 100)
2829 )
Neale Rannsda78f952017-05-24 09:15:43 -07002830
2831 #
2832 # The BD is learning, so send in one of each packet to learn
2833 #
Neale Rannsda78f952017-05-24 09:15:43 -07002834
Neale Ranns1dbcf302019-07-19 11:44:53 +00002835 # 2 packets due to BD flooding
2836 rx = self.send_and_expect(self.pg1, p_cust1, self.pg0, n_rx=2)
2837 rx = self.send_and_expect(self.pg1, p_cust2, self.pg0, n_rx=2)
Neale Rannsda78f952017-05-24 09:15:43 -07002838
Neale Ranns1dbcf302019-07-19 11:44:53 +00002839 # we've learnt this so expect it be be forwarded not flooded
2840 rx = self.send_and_expect(self.pg0, [p_core1], self.pg1)
2841 self.assertEqual(rx[0][Ether].dst, p_cust1[Ether].src)
2842 self.assertEqual(rx[0][Ether].src, p_cust1[Ether].dst)
Neale Rannsda78f952017-05-24 09:15:43 -07002843
Neale Ranns1dbcf302019-07-19 11:44:53 +00002844 rx = self.send_and_expect(self.pg0, [p_core2], self.pg1)
2845 self.assertEqual(rx[0][Ether].dst, p_cust2[Ether].src)
2846 self.assertEqual(rx[0][Ether].src, p_cust2[Ether].dst)
Neale Rannsda78f952017-05-24 09:15:43 -07002847
2848 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002849 # now a stream in each direction from each host
Neale Rannsda78f952017-05-24 09:15:43 -07002850 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002851 rx = self.send_and_expect(self.pg1, p_cust1 * NUM_PKTS, self.pg0)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002852 self.verify_capture_tunneled_ethernet(
2853 rx, p_cust1 * NUM_PKTS, [VppMplsLabel(42)]
2854 )
Neale Rannsda78f952017-05-24 09:15:43 -07002855
Neale Ranns1dbcf302019-07-19 11:44:53 +00002856 rx = self.send_and_expect(self.pg1, p_cust2 * NUM_PKTS, self.pg0)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002857 self.verify_capture_tunneled_ethernet(
2858 rx, p_cust2 * NUM_PKTS, [VppMplsLabel(43)]
2859 )
Neale Ranns1dbcf302019-07-19 11:44:53 +00002860
2861 rx = self.send_and_expect(self.pg0, p_core1 * NUM_PKTS, self.pg1)
2862 rx = self.send_and_expect(self.pg0, p_core2 * NUM_PKTS, self.pg1)
2863
Neale Rannsda78f952017-05-24 09:15:43 -07002864 #
2865 # remove interfaces from customers bridge-domain
2866 #
Ole Troana5b2eec2019-03-11 19:23:25 +01002867 self.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002868 rx_sw_if_index=mpls_tun1.sw_if_index, bd_id=1, enable=0
2869 )
Neale Ranns1dbcf302019-07-19 11:44:53 +00002870 self.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002871 rx_sw_if_index=mpls_tun2.sw_if_index, bd_id=1, enable=0
2872 )
Ole Troana5b2eec2019-03-11 19:23:25 +01002873 self.vapi.sw_interface_set_l2_bridge(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002874 rx_sw_if_index=self.pg1.sw_if_index, bd_id=1, enable=0
2875 )
Neale Rannsda78f952017-05-24 09:15:43 -07002876
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002877
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002878if __name__ == "__main__":
Neale Ranns8fe8cc22016-11-01 10:05:08 +00002879 unittest.main(testRunner=VppTestRunner)