blob: f0c3b0f3b952b410974a08cc9979a2742fcf1819 [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
Gabriel Gannea9b2d582016-12-06 10:25:34 +01004import socket
Neale Ranns8fe8cc22016-11-01 10:05:08 +00005
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +00006from framework import tag_fixme_vpp_workers
Neale Ranns8fe8cc22016-11-01 10:05:08 +00007from framework import VppTestCase, VppTestRunner
Neale Rannsd5d7b962019-08-04 03:30:56 -07008from vpp_ip import DpoProto, INVALID_INDEX
Neale Ranns5a8123b2017-01-26 01:18:23 -08009from vpp_ip_route import VppIpRoute, VppRoutePath, VppMplsRoute, \
Neale Ranns0f26c5a2017-03-01 15:12:11 -080010 VppMplsIpBind, VppIpMRoute, VppMRoutePath, \
Neale Ranns990f6942020-10-20 07:20:17 +000011 VppIpTable, VppMplsTable, \
Neale Ranns097fa662018-05-01 05:17:55 -070012 VppMplsLabel, MplsLspMode, find_mpls_route, \
13 FibPathProto, FibPathType, FibPathFlags, VppMplsLabel, MplsLspMode
Neale Ranns0f26c5a2017-03-01 15:12:11 -080014from vpp_mpls_tunnel_interface import VppMPLSTunnelInterface
Neale Ranns990f6942020-10-20 07:20:17 +000015from vpp_papi import VppEnum
Neale Ranns8fe8cc22016-11-01 10:05:08 +000016
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -070017import scapy.compat
Neale Ranns8fe8cc22016-11-01 10:05:08 +000018from scapy.packet import Raw
Neale Ranns1976f362019-11-06 13:13:01 +000019from scapy.layers.l2 import Ether, ARP
Neale Rannscb630ff2016-12-14 13:31:29 +010020from scapy.layers.inet import IP, UDP, ICMP
Neale Ranns62fe07c2017-10-31 12:28:22 -070021from scapy.layers.inet6 import IPv6, ICMPv6TimeExceeded
Neale Ranns8fe8cc22016-11-01 10:05:08 +000022from scapy.contrib.mpls import MPLS
23
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -040024NUM_PKTS = 67
25
Neale Ranns1976f362019-11-06 13:13:01 +000026# scapy removed these attributes.
27# we asked that they be restored: https://github.com/secdev/scapy/pull/1878
28# semantic names have more meaning than numbers. so here they are.
29ARP.who_has = 1
30ARP.is_at = 2
31
Klement Sekeradab231a2016-12-21 08:50:14 +010032
Neale Rannsda78f952017-05-24 09:15:43 -070033def verify_filter(capture, sent):
34 if not len(capture) == len(sent):
35 # filter out any IPv6 RAs from the capture
36 for p in capture:
37 if p.haslayer(IPv6):
38 capture.remove(p)
39 return capture
40
41
Neale Ranns31ed7442018-02-23 05:29:09 -080042def verify_mpls_stack(tst, rx, mpls_labels):
Neale Rannsda78f952017-05-24 09:15:43 -070043 # the rx'd packet has the MPLS label popped
44 eth = rx[Ether]
45 tst.assertEqual(eth.type, 0x8847)
46
47 rx_mpls = rx[MPLS]
48
49 for ii in range(len(mpls_labels)):
Neale Ranns31ed7442018-02-23 05:29:09 -080050 tst.assertEqual(rx_mpls.label, mpls_labels[ii].value)
51 tst.assertEqual(rx_mpls.cos, mpls_labels[ii].exp)
52 tst.assertEqual(rx_mpls.ttl, mpls_labels[ii].ttl)
53
Neale Rannsda78f952017-05-24 09:15:43 -070054 if ii == len(mpls_labels) - 1:
55 tst.assertEqual(rx_mpls.s, 1)
56 else:
57 # not end of stack
58 tst.assertEqual(rx_mpls.s, 0)
59 # pop the label to expose the next
60 rx_mpls = rx_mpls[MPLS].payload
61
62
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +000063@tag_fixme_vpp_workers
Neale Ranns8fe8cc22016-11-01 10:05:08 +000064class TestMPLS(VppTestCase):
65 """ MPLS Test Case """
66
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -070067 @classmethod
68 def setUpClass(cls):
69 super(TestMPLS, cls).setUpClass()
70
71 @classmethod
72 def tearDownClass(cls):
73 super(TestMPLS, cls).tearDownClass()
74
Neale Ranns8fe8cc22016-11-01 10:05:08 +000075 def setUp(self):
76 super(TestMPLS, self).setUp()
77
78 # create 2 pg interfaces
Neale Ranns0f26c5a2017-03-01 15:12:11 -080079 self.create_pg_interfaces(range(4))
Neale Ranns8fe8cc22016-11-01 10:05:08 +000080
81 # setup both interfaces
82 # assign them different tables.
83 table_id = 0
Neale Ranns15002542017-09-10 04:39:11 -070084 self.tables = []
85
86 tbl = VppMplsTable(self, 0)
87 tbl.add_vpp_config()
88 self.tables.append(tbl)
Neale Ranns8fe8cc22016-11-01 10:05:08 +000089
90 for i in self.pg_interfaces:
91 i.admin_up()
Neale Ranns15002542017-09-10 04:39:11 -070092
93 if table_id != 0:
94 tbl = VppIpTable(self, table_id)
95 tbl.add_vpp_config()
96 self.tables.append(tbl)
97 tbl = VppIpTable(self, table_id, is_ip6=1)
98 tbl.add_vpp_config()
99 self.tables.append(tbl)
100
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000101 i.set_table_ip4(table_id)
102 i.set_table_ip6(table_id)
103 i.config_ip4()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000104 i.resolve_arp()
Neale Rannsad422ed2016-11-02 14:20:04 +0000105 i.config_ip6()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000106 i.resolve_ndp()
Neale Rannsad422ed2016-11-02 14:20:04 +0000107 i.enable_mpls()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000108 table_id += 1
109
110 def tearDown(self):
Neale Ranns4008ac92017-02-13 23:20:04 -0800111 for i in self.pg_interfaces:
112 i.unconfig_ip4()
113 i.unconfig_ip6()
Neale Ranns15002542017-09-10 04:39:11 -0700114 i.set_table_ip4(0)
115 i.set_table_ip6(0)
116 i.disable_mpls()
Neale Ranns4008ac92017-02-13 23:20:04 -0800117 i.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -0700118 super(TestMPLS, self).tearDown()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000119
Neale Rannsad422ed2016-11-02 14:20:04 +0000120 # the default of 64 matches the IP packet TTL default
Klement Sekeradab231a2016-12-21 08:50:14 +0100121 def create_stream_labelled_ip4(
122 self,
123 src_if,
124 mpls_labels,
Klement Sekeradab231a2016-12-21 08:50:14 +0100125 ping=0,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800126 ip_itf=None,
127 dst_ip=None,
Neale Ranns4c7c8e52017-10-21 09:37:55 -0700128 chksum=None,
Neale Ranns31ed7442018-02-23 05:29:09 -0800129 ip_ttl=64,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800130 n=257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100131 self.reset_packet_infos()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000132 pkts = []
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800133 for i in range(0, n):
Klement Sekeradab231a2016-12-21 08:50:14 +0100134 info = self.create_packet_info(src_if, src_if)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000135 payload = self.info_to_payload(info)
Neale Rannsad422ed2016-11-02 14:20:04 +0000136 p = Ether(dst=src_if.local_mac, src=src_if.remote_mac)
137
138 for ii in range(len(mpls_labels)):
Neale Ranns31ed7442018-02-23 05:29:09 -0800139 p = p / MPLS(label=mpls_labels[ii].value,
140 ttl=mpls_labels[ii].ttl,
141 cos=mpls_labels[ii].exp)
Neale Rannscb630ff2016-12-14 13:31:29 +0100142 if not ping:
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800143 if not dst_ip:
Neale Ranns31ed7442018-02-23 05:29:09 -0800144 p = (p / IP(src=src_if.local_ip4,
145 dst=src_if.remote_ip4,
146 ttl=ip_ttl) /
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800147 UDP(sport=1234, dport=1234) /
148 Raw(payload))
149 else:
Neale Ranns31ed7442018-02-23 05:29:09 -0800150 p = (p / IP(src=src_if.local_ip4, dst=dst_ip, ttl=ip_ttl) /
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800151 UDP(sport=1234, dport=1234) /
152 Raw(payload))
Neale Rannscb630ff2016-12-14 13:31:29 +0100153 else:
154 p = (p / IP(src=ip_itf.remote_ip4,
Neale Ranns31ed7442018-02-23 05:29:09 -0800155 dst=ip_itf.local_ip4,
156 ttl=ip_ttl) /
Neale Rannscb630ff2016-12-14 13:31:29 +0100157 ICMP())
158
Neale Ranns4c7c8e52017-10-21 09:37:55 -0700159 if chksum:
160 p[IP].chksum = chksum
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000161 info.data = p.copy()
162 pkts.append(p)
163 return pkts
164
Ole Troaneb284a12019-10-09 13:33:19 +0200165 def create_stream_ip4(self, src_if, dst_ip, ip_ttl=64,
166 ip_dscp=0, payload_size=None):
Klement Sekeradab231a2016-12-21 08:50:14 +0100167 self.reset_packet_infos()
Neale Rannsad422ed2016-11-02 14:20:04 +0000168 pkts = []
169 for i in range(0, 257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100170 info = self.create_packet_info(src_if, src_if)
Neale Rannsad422ed2016-11-02 14:20:04 +0000171 payload = self.info_to_payload(info)
172 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
Neale Ranns31ed7442018-02-23 05:29:09 -0800173 IP(src=src_if.remote_ip4, dst=dst_ip,
174 ttl=ip_ttl, tos=ip_dscp) /
Neale Rannsad422ed2016-11-02 14:20:04 +0000175 UDP(sport=1234, dport=1234) /
176 Raw(payload))
177 info.data = p.copy()
Ole Troaneb284a12019-10-09 13:33:19 +0200178 if payload_size:
179 self.extend_packet(p, payload_size)
Neale Rannsad422ed2016-11-02 14:20:04 +0000180 pkts.append(p)
181 return pkts
182
Neale Ranns31ed7442018-02-23 05:29:09 -0800183 def create_stream_ip6(self, src_if, dst_ip, ip_ttl=64, ip_dscp=0):
184 self.reset_packet_infos()
185 pkts = []
186 for i in range(0, 257):
187 info = self.create_packet_info(src_if, src_if)
188 payload = self.info_to_payload(info)
189 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
190 IPv6(src=src_if.remote_ip6, dst=dst_ip,
191 hlim=ip_ttl, tc=ip_dscp) /
192 UDP(sport=1234, dport=1234) /
193 Raw(payload))
194 info.data = p.copy()
195 pkts.append(p)
196 return pkts
197
198 def create_stream_labelled_ip6(self, src_if, mpls_labels,
199 hlim=64, dst_ip=None):
Neale Ranns31426c62017-05-24 10:32:58 -0700200 if dst_ip is None:
201 dst_ip = src_if.remote_ip6
Klement Sekeradab231a2016-12-21 08:50:14 +0100202 self.reset_packet_infos()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000203 pkts = []
204 for i in range(0, 257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100205 info = self.create_packet_info(src_if, src_if)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000206 payload = self.info_to_payload(info)
Neale Ranns31ed7442018-02-23 05:29:09 -0800207 p = Ether(dst=src_if.local_mac, src=src_if.remote_mac)
208 for l in mpls_labels:
209 p = p / MPLS(label=l.value, ttl=l.ttl, cos=l.exp)
210
211 p = p / (IPv6(src=src_if.remote_ip6, dst=dst_ip, hlim=hlim) /
212 UDP(sport=1234, dport=1234) /
213 Raw(payload))
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000214 info.data = p.copy()
215 pkts.append(p)
216 return pkts
217
Neale Ranns31ed7442018-02-23 05:29:09 -0800218 def verify_capture_ip4(self, src_if, capture, sent, ping_resp=0,
219 ip_ttl=None, ip_dscp=0):
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000220 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700221 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000222
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000223 self.assertEqual(len(capture), len(sent))
224
225 for i in range(len(capture)):
226 tx = sent[i]
227 rx = capture[i]
228
229 # the rx'd packet has the MPLS label popped
Neale Rannsad422ed2016-11-02 14:20:04 +0000230 eth = rx[Ether]
231 self.assertEqual(eth.type, 0x800)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000232
233 tx_ip = tx[IP]
234 rx_ip = rx[IP]
235
Neale Rannscb630ff2016-12-14 13:31:29 +0100236 if not ping_resp:
237 self.assertEqual(rx_ip.src, tx_ip.src)
238 self.assertEqual(rx_ip.dst, tx_ip.dst)
Neale Ranns31ed7442018-02-23 05:29:09 -0800239 self.assertEqual(rx_ip.tos, ip_dscp)
240 if not ip_ttl:
241 # IP processing post pop has decremented the TTL
242 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
243 else:
244 self.assertEqual(rx_ip.ttl, ip_ttl)
Neale Rannscb630ff2016-12-14 13:31:29 +0100245 else:
246 self.assertEqual(rx_ip.src, tx_ip.dst)
247 self.assertEqual(rx_ip.dst, tx_ip.src)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000248
249 except:
Neale Rannsad422ed2016-11-02 14:20:04 +0000250 raise
251
Neale Rannsad422ed2016-11-02 14:20:04 +0000252 def verify_capture_labelled_ip4(self, src_if, capture, sent,
Neale Ranns31ed7442018-02-23 05:29:09 -0800253 mpls_labels, ip_ttl=None):
Neale Rannsad422ed2016-11-02 14:20:04 +0000254 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700255 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000256
257 self.assertEqual(len(capture), len(sent))
258
259 for i in range(len(capture)):
260 tx = sent[i]
261 rx = capture[i]
262 tx_ip = tx[IP]
263 rx_ip = rx[IP]
264
Neale Ranns31ed7442018-02-23 05:29:09 -0800265 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsad422ed2016-11-02 14:20:04 +0000266
267 self.assertEqual(rx_ip.src, tx_ip.src)
268 self.assertEqual(rx_ip.dst, tx_ip.dst)
Neale Ranns31ed7442018-02-23 05:29:09 -0800269 if not ip_ttl:
270 # IP processing post pop has decremented the TTL
271 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
272 else:
273 self.assertEqual(rx_ip.ttl, ip_ttl)
Neale Rannsad422ed2016-11-02 14:20:04 +0000274
275 except:
276 raise
277
Neale Ranns31ed7442018-02-23 05:29:09 -0800278 def verify_capture_labelled_ip6(self, src_if, capture, sent,
279 mpls_labels, ip_ttl=None):
280 try:
281 capture = verify_filter(capture, sent)
282
283 self.assertEqual(len(capture), len(sent))
284
285 for i in range(len(capture)):
286 tx = sent[i]
287 rx = capture[i]
288 tx_ip = tx[IPv6]
289 rx_ip = rx[IPv6]
290
291 verify_mpls_stack(self, rx, mpls_labels)
292
293 self.assertEqual(rx_ip.src, tx_ip.src)
294 self.assertEqual(rx_ip.dst, tx_ip.dst)
295 if not ip_ttl:
296 # IP processing post pop has decremented the TTL
297 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
298 else:
299 self.assertEqual(rx_ip.hlim, ip_ttl)
300
301 except:
302 raise
303
304 def verify_capture_tunneled_ip4(self, src_if, capture, sent, mpls_labels):
Neale Rannsad422ed2016-11-02 14:20:04 +0000305 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700306 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000307
308 self.assertEqual(len(capture), len(sent))
309
310 for i in range(len(capture)):
311 tx = sent[i]
312 rx = capture[i]
313 tx_ip = tx[IP]
314 rx_ip = rx[IP]
315
Neale Ranns31ed7442018-02-23 05:29:09 -0800316 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsad422ed2016-11-02 14:20:04 +0000317
318 self.assertEqual(rx_ip.src, tx_ip.src)
319 self.assertEqual(rx_ip.dst, tx_ip.dst)
320 # IP processing post pop has decremented the TTL
321 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
322
323 except:
324 raise
325
326 def verify_capture_labelled(self, src_if, capture, sent,
Neale Ranns31ed7442018-02-23 05:29:09 -0800327 mpls_labels):
Neale Rannsad422ed2016-11-02 14:20:04 +0000328 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700329 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000330
331 self.assertEqual(len(capture), len(sent))
332
333 for i in range(len(capture)):
334 rx = capture[i]
Neale Ranns31ed7442018-02-23 05:29:09 -0800335 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsad422ed2016-11-02 14:20:04 +0000336 except:
337 raise
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000338
Neale Ranns31ed7442018-02-23 05:29:09 -0800339 def verify_capture_ip6(self, src_if, capture, sent,
340 ip_hlim=None, ip_dscp=0):
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000341 try:
342 self.assertEqual(len(capture), len(sent))
343
344 for i in range(len(capture)):
345 tx = sent[i]
346 rx = capture[i]
347
348 # the rx'd packet has the MPLS label popped
Neale Rannsad422ed2016-11-02 14:20:04 +0000349 eth = rx[Ether]
350 self.assertEqual(eth.type, 0x86DD)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000351
352 tx_ip = tx[IPv6]
353 rx_ip = rx[IPv6]
354
355 self.assertEqual(rx_ip.src, tx_ip.src)
356 self.assertEqual(rx_ip.dst, tx_ip.dst)
Neale Ranns31ed7442018-02-23 05:29:09 -0800357 self.assertEqual(rx_ip.tc, ip_dscp)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000358 # IP processing post pop has decremented the TTL
Neale Ranns31ed7442018-02-23 05:29:09 -0800359 if not ip_hlim:
360 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
361 else:
362 self.assertEqual(rx_ip.hlim, ip_hlim)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000363
364 except:
Neale Rannsad422ed2016-11-02 14:20:04 +0000365 raise
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000366
Neale Ranns62fe07c2017-10-31 12:28:22 -0700367 def verify_capture_ip6_icmp(self, src_if, capture, sent):
368 try:
369 self.assertEqual(len(capture), len(sent))
370
371 for i in range(len(capture)):
372 tx = sent[i]
373 rx = capture[i]
374
375 # the rx'd packet has the MPLS label popped
376 eth = rx[Ether]
377 self.assertEqual(eth.type, 0x86DD)
378
379 tx_ip = tx[IPv6]
380 rx_ip = rx[IPv6]
381
382 self.assertEqual(rx_ip.dst, tx_ip.src)
383 # ICMP sourced from the interface's address
384 self.assertEqual(rx_ip.src, src_if.local_ip6)
385 # hop-limit reset to 255 for IMCP packet
Ole Troan282093f2018-09-19 12:38:51 +0200386 self.assertEqual(rx_ip.hlim, 255)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700387
388 icmp = rx[ICMPv6TimeExceeded]
389
390 except:
391 raise
392
Rajesh Goeld6f1c9c2019-10-06 13:17:36 +0530393 def verify_capture_fragmented_labelled_ip4(self, src_if, capture, sent,
394 mpls_labels, ip_ttl=None):
395 try:
396 capture = verify_filter(capture, sent)
397
398 for i in range(len(capture)):
399 tx = sent[0]
400 rx = capture[i]
401 tx_ip = tx[IP]
402 rx_ip = rx[IP]
403
404 verify_mpls_stack(self, rx, mpls_labels)
405
406 self.assertEqual(rx_ip.src, tx_ip.src)
407 self.assertEqual(rx_ip.dst, tx_ip.dst)
408 if not ip_ttl:
409 # IP processing post pop has decremented the TTL
410 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
411 else:
412 self.assertEqual(rx_ip.ttl, ip_ttl)
413
414 except:
415 raise
416
Neale Rannsad422ed2016-11-02 14:20:04 +0000417 def test_swap(self):
418 """ MPLS label swap tests """
419
420 #
421 # A simple MPLS xconnect - eos label in label out
422 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800423 route_32_eos = VppMplsRoute(self, 32, 1,
424 [VppRoutePath(self.pg0.remote_ip4,
425 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800426 labels=[VppMplsLabel(33)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000427 route_32_eos.add_vpp_config()
428
Neale Ranns775f73c2018-12-20 03:01:49 -0800429 self.assertTrue(
430 find_mpls_route(self, 0, 32, 1,
431 [VppRoutePath(self.pg0.remote_ip4,
432 self.pg0.sw_if_index,
433 labels=[VppMplsLabel(33)])]))
434
Neale Rannsad422ed2016-11-02 14:20:04 +0000435 #
436 # a stream that matches the route for 10.0.0.1
437 # PG0 is in the default table
438 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800439 tx = self.create_stream_labelled_ip4(self.pg0,
440 [VppMplsLabel(32, ttl=32, exp=1)])
441 rx = self.send_and_expect(self.pg0, tx, self.pg0)
442 self.verify_capture_labelled(self.pg0, rx, tx,
443 [VppMplsLabel(33, ttl=31, exp=1)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000444
Neale Ranns008dbe12018-09-07 09:32:36 -0700445 self.assertEqual(route_32_eos.get_stats_to()['packets'], 257)
446
Neale Rannsad422ed2016-11-02 14:20:04 +0000447 #
448 # A simple MPLS xconnect - non-eos label in label out
449 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800450 route_32_neos = VppMplsRoute(self, 32, 0,
451 [VppRoutePath(self.pg0.remote_ip4,
452 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800453 labels=[VppMplsLabel(33)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000454 route_32_neos.add_vpp_config()
455
456 #
457 # a stream that matches the route for 10.0.0.1
458 # PG0 is in the default table
459 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800460 tx = self.create_stream_labelled_ip4(self.pg0,
461 [VppMplsLabel(32, ttl=21, exp=7),
462 VppMplsLabel(99)])
463 rx = self.send_and_expect(self.pg0, tx, self.pg0)
464 self.verify_capture_labelled(self.pg0, rx, tx,
465 [VppMplsLabel(33, ttl=20, exp=7),
466 VppMplsLabel(99)])
Neale Ranns008dbe12018-09-07 09:32:36 -0700467 self.assertEqual(route_32_neos.get_stats_to()['packets'], 257)
Neale Rannsad422ed2016-11-02 14:20:04 +0000468
Neale Ranns31ed7442018-02-23 05:29:09 -0800469 #
470 # A simple MPLS xconnect - non-eos label in label out, uniform mode
471 #
472 route_42_neos = VppMplsRoute(
473 self, 42, 0,
474 [VppRoutePath(self.pg0.remote_ip4,
475 self.pg0.sw_if_index,
476 labels=[VppMplsLabel(43, MplsLspMode.UNIFORM)])])
477 route_42_neos.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000478
Neale Ranns31ed7442018-02-23 05:29:09 -0800479 tx = self.create_stream_labelled_ip4(self.pg0,
480 [VppMplsLabel(42, ttl=21, exp=7),
481 VppMplsLabel(99)])
482 rx = self.send_and_expect(self.pg0, tx, self.pg0)
483 self.verify_capture_labelled(self.pg0, rx, tx,
484 [VppMplsLabel(43, ttl=20, exp=7),
485 VppMplsLabel(99)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000486
487 #
488 # An MPLS xconnect - EOS label in IP out
489 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800490 route_33_eos = VppMplsRoute(self, 33, 1,
491 [VppRoutePath(self.pg0.remote_ip4,
492 self.pg0.sw_if_index,
493 labels=[])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000494 route_33_eos.add_vpp_config()
495
Neale Ranns31ed7442018-02-23 05:29:09 -0800496 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(33)])
497 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Rannsad422ed2016-11-02 14:20:04 +0000498 self.verify_capture_ip4(self.pg0, rx, tx)
499
500 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700501 # disposed packets have an invalid IPv4 checksum
Neale Ranns62fe07c2017-10-31 12:28:22 -0700502 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800503 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(33)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700504 dst_ip=self.pg0.remote_ip4,
505 n=65,
506 chksum=1)
507 self.send_and_assert_no_replies(self.pg0, tx, "Invalid Checksum")
508
509 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800510 # An MPLS xconnect - EOS label in IP out, uniform mode
511 #
512 route_3333_eos = VppMplsRoute(
513 self, 3333, 1,
514 [VppRoutePath(self.pg0.remote_ip4,
515 self.pg0.sw_if_index,
516 labels=[VppMplsLabel(3, MplsLspMode.UNIFORM)])])
517 route_3333_eos.add_vpp_config()
518
519 tx = self.create_stream_labelled_ip4(
520 self.pg0,
521 [VppMplsLabel(3333, ttl=55, exp=3)])
522 rx = self.send_and_expect(self.pg0, tx, self.pg0)
523 self.verify_capture_ip4(self.pg0, rx, tx, ip_ttl=54, ip_dscp=0x60)
524 tx = self.create_stream_labelled_ip4(
525 self.pg0,
526 [VppMplsLabel(3333, ttl=66, exp=4)])
527 rx = self.send_and_expect(self.pg0, tx, self.pg0)
528 self.verify_capture_ip4(self.pg0, rx, tx, ip_ttl=65, ip_dscp=0x80)
529
530 #
Neale Ranns62fe07c2017-10-31 12:28:22 -0700531 # An MPLS xconnect - EOS label in IPv6 out
532 #
533 route_333_eos = VppMplsRoute(
534 self, 333, 1,
535 [VppRoutePath(self.pg0.remote_ip6,
536 self.pg0.sw_if_index,
Neale Ranns097fa662018-05-01 05:17:55 -0700537 labels=[])],
538 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700539 route_333_eos.add_vpp_config()
540
Neale Ranns31ed7442018-02-23 05:29:09 -0800541 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(333)])
542 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700543 self.verify_capture_ip6(self.pg0, rx, tx)
544
545 #
546 # disposed packets have an TTL expired
547 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800548 tx = self.create_stream_labelled_ip6(self.pg0,
549 [VppMplsLabel(333, ttl=64)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700550 dst_ip=self.pg1.remote_ip6,
551 hlim=1)
Neale Ranns31ed7442018-02-23 05:29:09 -0800552 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700553 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
554
555 #
556 # An MPLS xconnect - EOS label in IPv6 out w imp-null
557 #
558 route_334_eos = VppMplsRoute(
559 self, 334, 1,
560 [VppRoutePath(self.pg0.remote_ip6,
561 self.pg0.sw_if_index,
Neale Ranns097fa662018-05-01 05:17:55 -0700562 labels=[VppMplsLabel(3)])],
563 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700564 route_334_eos.add_vpp_config()
565
Neale Ranns31ed7442018-02-23 05:29:09 -0800566 tx = self.create_stream_labelled_ip6(self.pg0,
567 [VppMplsLabel(334, ttl=64)])
568 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700569 self.verify_capture_ip6(self.pg0, rx, tx)
570
571 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800572 # An MPLS xconnect - EOS label in IPv6 out w imp-null in uniform mode
573 #
574 route_335_eos = VppMplsRoute(
575 self, 335, 1,
576 [VppRoutePath(self.pg0.remote_ip6,
577 self.pg0.sw_if_index,
Neale Ranns097fa662018-05-01 05:17:55 -0700578 labels=[VppMplsLabel(3, MplsLspMode.UNIFORM)])],
579 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)
Neale Ranns31ed7442018-02-23 05:29:09 -0800580 route_335_eos.add_vpp_config()
581
582 tx = self.create_stream_labelled_ip6(
583 self.pg0,
584 [VppMplsLabel(335, ttl=27, exp=4)])
585 rx = self.send_and_expect(self.pg0, tx, self.pg0)
586 self.verify_capture_ip6(self.pg0, rx, tx, ip_hlim=26, ip_dscp=0x80)
587
588 #
Neale Ranns62fe07c2017-10-31 12:28:22 -0700589 # disposed packets have an TTL expired
590 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800591 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(334)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700592 dst_ip=self.pg1.remote_ip6,
593 hlim=0)
Neale Ranns31ed7442018-02-23 05:29:09 -0800594 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700595 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
596
597 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000598 # An MPLS xconnect - non-EOS label in IP out - an invalid configuration
599 # so this traffic should be dropped.
600 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800601 route_33_neos = VppMplsRoute(self, 33, 0,
602 [VppRoutePath(self.pg0.remote_ip4,
603 self.pg0.sw_if_index,
604 labels=[])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000605 route_33_neos.add_vpp_config()
606
Neale Ranns31ed7442018-02-23 05:29:09 -0800607 tx = self.create_stream_labelled_ip4(self.pg0,
608 [VppMplsLabel(33),
609 VppMplsLabel(99)])
610 self.send_and_assert_no_replies(
611 self.pg0, tx,
612 "MPLS non-EOS packets popped and forwarded")
Neale Rannsad422ed2016-11-02 14:20:04 +0000613
614 #
615 # A recursive EOS x-connect, which resolves through another x-connect
Neale Ranns31ed7442018-02-23 05:29:09 -0800616 # in pipe mode
Neale Rannsad422ed2016-11-02 14:20:04 +0000617 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800618 route_34_eos = VppMplsRoute(self, 34, 1,
619 [VppRoutePath("0.0.0.0",
620 0xffffffff,
621 nh_via_label=32,
Neale Ranns31ed7442018-02-23 05:29:09 -0800622 labels=[VppMplsLabel(44),
623 VppMplsLabel(45)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000624 route_34_eos.add_vpp_config()
Neale Ranns097fa662018-05-01 05:17:55 -0700625 self.logger.info(self.vapi.cli("sh mpls fib 34"))
Neale Rannsad422ed2016-11-02 14:20:04 +0000626
Neale Ranns31ed7442018-02-23 05:29:09 -0800627 tx = self.create_stream_labelled_ip4(self.pg0,
628 [VppMplsLabel(34, ttl=3)])
629 rx = self.send_and_expect(self.pg0, tx, self.pg0)
630 self.verify_capture_labelled(self.pg0, rx, tx,
631 [VppMplsLabel(33),
632 VppMplsLabel(44),
633 VppMplsLabel(45, ttl=2)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000634
Neale Ranns008dbe12018-09-07 09:32:36 -0700635 self.assertEqual(route_34_eos.get_stats_to()['packets'], 257)
636 self.assertEqual(route_32_neos.get_stats_via()['packets'], 257)
637
Neale Ranns31ed7442018-02-23 05:29:09 -0800638 #
639 # A recursive EOS x-connect, which resolves through another x-connect
640 # in uniform mode
641 #
642 route_35_eos = VppMplsRoute(
643 self, 35, 1,
644 [VppRoutePath("0.0.0.0",
645 0xffffffff,
646 nh_via_label=42,
647 labels=[VppMplsLabel(44)])])
648 route_35_eos.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000649
Neale Ranns31ed7442018-02-23 05:29:09 -0800650 tx = self.create_stream_labelled_ip4(self.pg0,
651 [VppMplsLabel(35, ttl=3)])
652 rx = self.send_and_expect(self.pg0, tx, self.pg0)
653 self.verify_capture_labelled(self.pg0, rx, tx,
654 [VppMplsLabel(43, ttl=2),
655 VppMplsLabel(44, ttl=2)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000656
657 #
Matej Klottondeb69842016-12-09 15:05:46 +0100658 # A recursive non-EOS x-connect, which resolves through another
659 # x-connect
Neale Rannsad422ed2016-11-02 14:20:04 +0000660 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800661 route_34_neos = VppMplsRoute(self, 34, 0,
662 [VppRoutePath("0.0.0.0",
663 0xffffffff,
664 nh_via_label=32,
Neale Ranns31ed7442018-02-23 05:29:09 -0800665 labels=[VppMplsLabel(44),
666 VppMplsLabel(46)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000667 route_34_neos.add_vpp_config()
668
Neale Ranns31ed7442018-02-23 05:29:09 -0800669 tx = self.create_stream_labelled_ip4(self.pg0,
670 [VppMplsLabel(34, ttl=45),
671 VppMplsLabel(99)])
672 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Matej Klottondeb69842016-12-09 15:05:46 +0100673 # it's the 2nd (counting from 0) label in the stack that is swapped
Neale Ranns31ed7442018-02-23 05:29:09 -0800674 self.verify_capture_labelled(self.pg0, rx, tx,
675 [VppMplsLabel(33),
676 VppMplsLabel(44),
677 VppMplsLabel(46, ttl=44),
678 VppMplsLabel(99)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000679
680 #
Matej Klottondeb69842016-12-09 15:05:46 +0100681 # an recursive IP route that resolves through the recursive non-eos
682 # x-connect
Neale Rannsad422ed2016-11-02 14:20:04 +0000683 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800684 ip_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
685 [VppRoutePath("0.0.0.0",
686 0xffffffff,
687 nh_via_label=34,
Neale Ranns31ed7442018-02-23 05:29:09 -0800688 labels=[VppMplsLabel(55)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000689 ip_10_0_0_1.add_vpp_config()
690
Neale Rannsad422ed2016-11-02 14:20:04 +0000691 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800692 rx = self.send_and_expect(self.pg0, tx, self.pg0)
693 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
694 [VppMplsLabel(33),
695 VppMplsLabel(44),
696 VppMplsLabel(46),
697 VppMplsLabel(55)])
Neale Ranns008dbe12018-09-07 09:32:36 -0700698 self.assertEqual(ip_10_0_0_1.get_stats_to()['packets'], 257)
Neale Rannsad422ed2016-11-02 14:20:04 +0000699
700 ip_10_0_0_1.remove_vpp_config()
701 route_34_neos.remove_vpp_config()
702 route_34_eos.remove_vpp_config()
703 route_33_neos.remove_vpp_config()
704 route_33_eos.remove_vpp_config()
705 route_32_neos.remove_vpp_config()
706 route_32_eos.remove_vpp_config()
707
708 def test_bind(self):
709 """ MPLS Local Label Binding test """
710
711 #
712 # Add a non-recursive route with a single out label
713 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800714 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
715 [VppRoutePath(self.pg0.remote_ip4,
716 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800717 labels=[VppMplsLabel(45)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000718 route_10_0_0_1.add_vpp_config()
719
720 # bind a local label to the route
Neale Ranns5a8123b2017-01-26 01:18:23 -0800721 binding = VppMplsIpBind(self, 44, "10.0.0.1", 32)
Neale Rannsad422ed2016-11-02 14:20:04 +0000722 binding.add_vpp_config()
723
724 # non-EOS stream
Neale Ranns31ed7442018-02-23 05:29:09 -0800725 tx = self.create_stream_labelled_ip4(self.pg0,
726 [VppMplsLabel(44),
727 VppMplsLabel(99)])
728 rx = self.send_and_expect(self.pg0, tx, self.pg0)
729 self.verify_capture_labelled(self.pg0, rx, tx,
730 [VppMplsLabel(45, ttl=63),
731 VppMplsLabel(99)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000732
733 # EOS stream
Neale Ranns31ed7442018-02-23 05:29:09 -0800734 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(44)])
735 rx = self.send_and_expect(self.pg0, tx, self.pg0)
736 self.verify_capture_labelled(self.pg0, rx, tx,
737 [VppMplsLabel(45, ttl=63)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000738
739 # IP stream
Neale Rannsad422ed2016-11-02 14:20:04 +0000740 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800741 rx = self.send_and_expect(self.pg0, tx, self.pg0)
742 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [VppMplsLabel(45)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000743
744 #
745 # cleanup
746 #
747 binding.remove_vpp_config()
748 route_10_0_0_1.remove_vpp_config()
749
750 def test_imposition(self):
751 """ MPLS label imposition test """
752
753 #
754 # Add a non-recursive route with a single out label
755 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800756 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
757 [VppRoutePath(self.pg0.remote_ip4,
758 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800759 labels=[VppMplsLabel(32)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000760 route_10_0_0_1.add_vpp_config()
761
762 #
763 # a stream that matches the route for 10.0.0.1
764 # PG0 is in the default table
765 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000766 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800767 rx = self.send_and_expect(self.pg0, tx, self.pg0)
768 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [VppMplsLabel(32)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000769
770 #
771 # Add a non-recursive route with a 3 out labels
772 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800773 route_10_0_0_2 = VppIpRoute(self, "10.0.0.2", 32,
774 [VppRoutePath(self.pg0.remote_ip4,
775 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800776 labels=[VppMplsLabel(32),
777 VppMplsLabel(33),
778 VppMplsLabel(34)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000779 route_10_0_0_2.add_vpp_config()
780
Neale Ranns31ed7442018-02-23 05:29:09 -0800781 tx = self.create_stream_ip4(self.pg0, "10.0.0.2",
782 ip_ttl=44, ip_dscp=0xff)
783 rx = self.send_and_expect(self.pg0, tx, self.pg0)
784 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
785 [VppMplsLabel(32),
786 VppMplsLabel(33),
787 VppMplsLabel(34)],
788 ip_ttl=43)
Neale Rannsad422ed2016-11-02 14:20:04 +0000789
Neale Ranns31ed7442018-02-23 05:29:09 -0800790 #
791 # Add a non-recursive route with a single out label in uniform mode
792 #
793 route_10_0_0_3 = VppIpRoute(
794 self, "10.0.0.3", 32,
795 [VppRoutePath(self.pg0.remote_ip4,
796 self.pg0.sw_if_index,
797 labels=[VppMplsLabel(32,
798 mode=MplsLspMode.UNIFORM)])])
799 route_10_0_0_3.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000800
Neale Ranns31ed7442018-02-23 05:29:09 -0800801 tx = self.create_stream_ip4(self.pg0, "10.0.0.3",
802 ip_ttl=54, ip_dscp=0xbe)
803 rx = self.send_and_expect(self.pg0, tx, self.pg0)
804 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
805 [VppMplsLabel(32, ttl=53, exp=5)])
806
807 #
808 # Add a IPv6 non-recursive route with a single out label in
809 # uniform mode
810 #
811 route_2001_3 = VppIpRoute(
812 self, "2001::3", 128,
813 [VppRoutePath(self.pg0.remote_ip6,
814 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800815 labels=[VppMplsLabel(32,
Neale Ranns097fa662018-05-01 05:17:55 -0700816 mode=MplsLspMode.UNIFORM)])])
Neale Ranns31ed7442018-02-23 05:29:09 -0800817 route_2001_3.add_vpp_config()
818
819 tx = self.create_stream_ip6(self.pg0, "2001::3",
820 ip_ttl=54, ip_dscp=0xbe)
821 rx = self.send_and_expect(self.pg0, tx, self.pg0)
822 self.verify_capture_labelled_ip6(self.pg0, rx, tx,
823 [VppMplsLabel(32, ttl=53, exp=5)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000824
825 #
Matej Klottondeb69842016-12-09 15:05:46 +0100826 # add a recursive path, with output label, via the 1 label route
Neale Rannsad422ed2016-11-02 14:20:04 +0000827 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800828 route_11_0_0_1 = VppIpRoute(self, "11.0.0.1", 32,
829 [VppRoutePath("10.0.0.1",
830 0xffffffff,
Neale Ranns31ed7442018-02-23 05:29:09 -0800831 labels=[VppMplsLabel(44)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000832 route_11_0_0_1.add_vpp_config()
833
834 #
835 # a stream that matches the route for 11.0.0.1, should pick up
836 # the label stack for 11.0.0.1 and 10.0.0.1
837 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000838 tx = self.create_stream_ip4(self.pg0, "11.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800839 rx = self.send_and_expect(self.pg0, tx, self.pg0)
840 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
841 [VppMplsLabel(32),
842 VppMplsLabel(44)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000843
Neale Ranns008dbe12018-09-07 09:32:36 -0700844 self.assertEqual(route_11_0_0_1.get_stats_to()['packets'], 257)
845
Neale Rannsad422ed2016-11-02 14:20:04 +0000846 #
847 # add a recursive path, with 2 labels, via the 3 label route
848 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800849 route_11_0_0_2 = VppIpRoute(self, "11.0.0.2", 32,
850 [VppRoutePath("10.0.0.2",
851 0xffffffff,
Neale Ranns31ed7442018-02-23 05:29:09 -0800852 labels=[VppMplsLabel(44),
853 VppMplsLabel(45)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000854 route_11_0_0_2.add_vpp_config()
855
856 #
857 # a stream that matches the route for 11.0.0.1, should pick up
858 # the label stack for 11.0.0.1 and 10.0.0.1
859 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000860 tx = self.create_stream_ip4(self.pg0, "11.0.0.2")
Neale Ranns31ed7442018-02-23 05:29:09 -0800861 rx = self.send_and_expect(self.pg0, tx, self.pg0)
862 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
863 [VppMplsLabel(32),
864 VppMplsLabel(33),
865 VppMplsLabel(34),
866 VppMplsLabel(44),
867 VppMplsLabel(45)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000868
Neale Ranns008dbe12018-09-07 09:32:36 -0700869 self.assertEqual(route_11_0_0_2.get_stats_to()['packets'], 257)
870
871 rx = self.send_and_expect(self.pg0, tx, self.pg0)
872 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
873 [VppMplsLabel(32),
874 VppMplsLabel(33),
875 VppMplsLabel(34),
876 VppMplsLabel(44),
877 VppMplsLabel(45)])
878
879 self.assertEqual(route_11_0_0_2.get_stats_to()['packets'], 514)
880
Neale Rannsad422ed2016-11-02 14:20:04 +0000881 #
882 # cleanup
883 #
884 route_11_0_0_2.remove_vpp_config()
885 route_11_0_0_1.remove_vpp_config()
886 route_10_0_0_2.remove_vpp_config()
887 route_10_0_0_1.remove_vpp_config()
888
Rajesh Goeld6f1c9c2019-10-06 13:17:36 +0530889 def test_imposition_fragmentation(self):
890 """ MPLS label imposition fragmentation test """
891
892 #
893 # Add a ipv4 non-recursive route with a single out label
894 #
895 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
896 [VppRoutePath(self.pg0.remote_ip4,
897 self.pg0.sw_if_index,
898 labels=[VppMplsLabel(32)])])
899 route_10_0_0_1.add_vpp_config()
900
901 #
902 # a stream that matches the route for 10.0.0.1
903 # PG0 is in the default table
904 #
905 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
906 for i in range(0, 257):
907 self.extend_packet(tx[i], 10000)
908
909 #
910 # 5 fragments per packet (257*5=1285)
911 #
912 rx = self.send_and_expect(self.pg0, tx, self.pg0, 1285)
913 self.verify_capture_fragmented_labelled_ip4(self.pg0, rx, tx,
914 [VppMplsLabel(32)])
915
916 #
917 # cleanup
918 #
919 route_10_0_0_1.remove_vpp_config()
920
Neale Ranns31ed7442018-02-23 05:29:09 -0800921 def test_tunnel_pipe(self):
922 """ MPLS Tunnel Tests - Pipe """
Neale Rannsad422ed2016-11-02 14:20:04 +0000923
924 #
Ole Troaneb284a12019-10-09 13:33:19 +0200925 # Create a tunnel with two out labels
Neale Rannsad422ed2016-11-02 14:20:04 +0000926 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800927 mpls_tun = VppMPLSTunnelInterface(
928 self,
929 [VppRoutePath(self.pg0.remote_ip4,
930 self.pg0.sw_if_index,
931 labels=[VppMplsLabel(44),
932 VppMplsLabel(46)])])
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800933 mpls_tun.add_vpp_config()
934 mpls_tun.admin_up()
Neale Rannsad422ed2016-11-02 14:20:04 +0000935
936 #
937 # add an unlabelled route through the new tunnel
938 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800939 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
940 [VppRoutePath("0.0.0.0",
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800941 mpls_tun._sw_if_index)])
Neale Ranns5a8123b2017-01-26 01:18:23 -0800942 route_10_0_0_3.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000943
944 self.vapi.cli("clear trace")
945 tx = self.create_stream_ip4(self.pg0, "10.0.0.3")
946 self.pg0.add_stream(tx)
947
948 self.pg_enable_capture(self.pg_interfaces)
949 self.pg_start()
950
951 rx = self.pg0.get_capture()
Neale Ranns31ed7442018-02-23 05:29:09 -0800952 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
953 [VppMplsLabel(44),
954 VppMplsLabel(46)])
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000955
Neale Ranns8c4611b2017-05-23 03:43:47 -0700956 #
957 # add a labelled route through the new tunnel
958 #
959 route_10_0_0_4 = VppIpRoute(self, "10.0.0.4", 32,
960 [VppRoutePath("0.0.0.0",
961 mpls_tun._sw_if_index,
962 labels=[33])])
963 route_10_0_0_4.add_vpp_config()
964
965 self.vapi.cli("clear trace")
966 tx = self.create_stream_ip4(self.pg0, "10.0.0.4")
967 self.pg0.add_stream(tx)
968
969 self.pg_enable_capture(self.pg_interfaces)
970 self.pg_start()
971
972 rx = self.pg0.get_capture()
Neale Ranns31ed7442018-02-23 05:29:09 -0800973 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
974 [VppMplsLabel(44),
975 VppMplsLabel(46),
976 VppMplsLabel(33, ttl=255)])
977
Ole Troaneb284a12019-10-09 13:33:19 +0200978 #
979 # change tunnel's MTU to a low value
980 #
981 mpls_tun.set_l3_mtu(1200)
982
983 # send IP into the tunnel to be fragmented
984 tx = self.create_stream_ip4(self.pg0, "10.0.0.3",
985 payload_size=1500)
986 rx = self.send_and_expect(self.pg0, tx, self.pg0, len(tx)*2)
987
988 fake_tx = []
989 for p in tx:
990 fake_tx.append(p)
991 fake_tx.append(p)
992 self.verify_capture_tunneled_ip4(self.pg0, rx, fake_tx,
993 [VppMplsLabel(44),
994 VppMplsLabel(46)])
995
996 # send MPLS into the tunnel to be fragmented
997 tx = self.create_stream_ip4(self.pg0, "10.0.0.4",
998 payload_size=1500)
999 rx = self.send_and_expect(self.pg0, tx, self.pg0, len(tx)*2)
1000
1001 fake_tx = []
1002 for p in tx:
1003 fake_tx.append(p)
1004 fake_tx.append(p)
1005 self.verify_capture_tunneled_ip4(self.pg0, rx, fake_tx,
1006 [VppMplsLabel(44),
1007 VppMplsLabel(46),
1008 VppMplsLabel(33, ttl=255)])
1009
Neale Ranns31ed7442018-02-23 05:29:09 -08001010 def test_tunnel_uniform(self):
1011 """ MPLS Tunnel Tests - Uniform """
1012
1013 #
1014 # Create a tunnel with a single out label
1015 # The label stack is specified here from outer to inner
1016 #
1017 mpls_tun = VppMPLSTunnelInterface(
1018 self,
1019 [VppRoutePath(self.pg0.remote_ip4,
1020 self.pg0.sw_if_index,
1021 labels=[VppMplsLabel(44, ttl=32),
1022 VppMplsLabel(46, MplsLspMode.UNIFORM)])])
1023 mpls_tun.add_vpp_config()
1024 mpls_tun.admin_up()
1025
1026 #
1027 # add an unlabelled route through the new tunnel
1028 #
1029 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
1030 [VppRoutePath("0.0.0.0",
1031 mpls_tun._sw_if_index)])
1032 route_10_0_0_3.add_vpp_config()
1033
1034 self.vapi.cli("clear trace")
1035 tx = self.create_stream_ip4(self.pg0, "10.0.0.3", ip_ttl=24)
1036 self.pg0.add_stream(tx)
1037
1038 self.pg_enable_capture(self.pg_interfaces)
1039 self.pg_start()
1040
1041 rx = self.pg0.get_capture()
1042 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
1043 [VppMplsLabel(44, ttl=32),
1044 VppMplsLabel(46, ttl=23)])
1045
1046 #
1047 # add a labelled route through the new tunnel
1048 #
1049 route_10_0_0_4 = VppIpRoute(
1050 self, "10.0.0.4", 32,
1051 [VppRoutePath("0.0.0.0",
1052 mpls_tun._sw_if_index,
1053 labels=[VppMplsLabel(33, ttl=47)])])
1054 route_10_0_0_4.add_vpp_config()
1055
1056 self.vapi.cli("clear trace")
1057 tx = self.create_stream_ip4(self.pg0, "10.0.0.4")
1058 self.pg0.add_stream(tx)
1059
1060 self.pg_enable_capture(self.pg_interfaces)
1061 self.pg_start()
1062
1063 rx = self.pg0.get_capture()
1064 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
1065 [VppMplsLabel(44, ttl=32),
1066 VppMplsLabel(46, ttl=47),
1067 VppMplsLabel(33, ttl=47)])
Neale Ranns8c4611b2017-05-23 03:43:47 -07001068
Neale Rannsf5fa5ae2018-09-26 05:07:25 -07001069 def test_mpls_tunnel_many(self):
Neale Ranns097fa662018-05-01 05:17:55 -07001070 """ MPLS Multiple Tunnels """
Neale Rannsf5fa5ae2018-09-26 05:07:25 -07001071
1072 for ii in range(10):
1073 mpls_tun = VppMPLSTunnelInterface(
1074 self,
1075 [VppRoutePath(self.pg0.remote_ip4,
1076 self.pg0.sw_if_index,
1077 labels=[VppMplsLabel(44, ttl=32),
1078 VppMplsLabel(46, MplsLspMode.UNIFORM)])])
1079 mpls_tun.add_vpp_config()
1080 mpls_tun.admin_up()
1081
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001082 def test_v4_exp_null(self):
1083 """ MPLS V4 Explicit NULL test """
1084
1085 #
1086 # The first test case has an MPLS TTL of 0
1087 # all packet should be dropped
1088 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001089 tx = self.create_stream_labelled_ip4(self.pg0,
1090 [VppMplsLabel(0, ttl=0)])
1091 self.send_and_assert_no_replies(self.pg0, tx,
1092 "MPLS TTL=0 packets forwarded")
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001093
1094 #
1095 # a stream with a non-zero MPLS TTL
1096 # PG0 is in the default table
1097 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001098 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(0)])
1099 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001100 self.verify_capture_ip4(self.pg0, rx, tx)
1101
1102 #
1103 # a stream with a non-zero MPLS TTL
1104 # PG1 is in table 1
1105 # we are ensuring the post-pop lookup occurs in the VRF table
1106 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001107 tx = self.create_stream_labelled_ip4(self.pg1, [VppMplsLabel(0)])
1108 rx = self.send_and_expect(self.pg1, tx, self.pg1)
1109 self.verify_capture_ip4(self.pg1, rx, tx)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001110
1111 def test_v6_exp_null(self):
1112 """ MPLS V6 Explicit NULL test """
1113
1114 #
1115 # a stream with a non-zero MPLS TTL
1116 # PG0 is in the default table
1117 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001118 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(2)])
1119 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001120 self.verify_capture_ip6(self.pg0, rx, tx)
1121
1122 #
1123 # a stream with a non-zero MPLS TTL
1124 # PG1 is in table 1
1125 # we are ensuring the post-pop lookup occurs in the VRF table
1126 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001127 tx = self.create_stream_labelled_ip6(self.pg1, [VppMplsLabel(2)])
1128 rx = self.send_and_expect(self.pg1, tx, self.pg1)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001129 self.verify_capture_ip6(self.pg0, rx, tx)
1130
Neale Rannscb630ff2016-12-14 13:31:29 +01001131 def test_deag(self):
1132 """ MPLS Deagg """
1133
1134 #
1135 # A de-agg route - next-hop lookup in default table
1136 #
Neale Ranns5a8123b2017-01-26 01:18:23 -08001137 route_34_eos = VppMplsRoute(self, 34, 1,
1138 [VppRoutePath("0.0.0.0",
1139 0xffffffff,
1140 nh_table_id=0)])
Neale Rannscb630ff2016-12-14 13:31:29 +01001141 route_34_eos.add_vpp_config()
1142
1143 #
1144 # ping an interface in the default table
1145 # PG0 is in the default table
1146 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001147 tx = self.create_stream_labelled_ip4(self.pg0,
1148 [VppMplsLabel(34)],
1149 ping=1,
Neale Rannscb630ff2016-12-14 13:31:29 +01001150 ip_itf=self.pg0)
Neale Ranns31ed7442018-02-23 05:29:09 -08001151 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Rannscb630ff2016-12-14 13:31:29 +01001152 self.verify_capture_ip4(self.pg0, rx, tx, ping_resp=1)
1153
1154 #
1155 # A de-agg route - next-hop lookup in non-default table
1156 #
Neale Ranns5a8123b2017-01-26 01:18:23 -08001157 route_35_eos = VppMplsRoute(self, 35, 1,
1158 [VppRoutePath("0.0.0.0",
1159 0xffffffff,
1160 nh_table_id=1)])
Neale Rannscb630ff2016-12-14 13:31:29 +01001161 route_35_eos.add_vpp_config()
1162
1163 #
1164 # ping an interface in the non-default table
1165 # PG0 is in the default table. packet arrive labelled in the
1166 # default table and egress unlabelled in the non-default
1167 #
Klement Sekeradab231a2016-12-21 08:50:14 +01001168 tx = self.create_stream_labelled_ip4(
Neale Ranns31ed7442018-02-23 05:29:09 -08001169 self.pg0, [VppMplsLabel(35)], ping=1, ip_itf=self.pg1)
1170 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Rannscb630ff2016-12-14 13:31:29 +01001171 self.verify_capture_ip4(self.pg1, rx, tx, ping_resp=1)
1172
Neale Ranns6af1c042017-05-26 03:48:53 -07001173 #
1174 # Double pop
1175 #
1176 route_36_neos = VppMplsRoute(self, 36, 0,
1177 [VppRoutePath("0.0.0.0",
1178 0xffffffff)])
1179 route_36_neos.add_vpp_config()
1180
Neale Ranns31ed7442018-02-23 05:29:09 -08001181 tx = self.create_stream_labelled_ip4(self.pg0,
1182 [VppMplsLabel(36),
1183 VppMplsLabel(35)],
Neale Ranns6af1c042017-05-26 03:48:53 -07001184 ping=1, ip_itf=self.pg1)
Neale Ranns31ed7442018-02-23 05:29:09 -08001185 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns6af1c042017-05-26 03:48:53 -07001186 self.verify_capture_ip4(self.pg1, rx, tx, ping_resp=1)
1187
1188 route_36_neos.remove_vpp_config()
Neale Rannscb630ff2016-12-14 13:31:29 +01001189 route_35_eos.remove_vpp_config()
1190 route_34_eos.remove_vpp_config()
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001191
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001192 def test_interface_rx(self):
1193 """ MPLS Interface Receive """
1194
1195 #
1196 # Add a non-recursive route that will forward the traffic
1197 # post-interface-rx
1198 #
1199 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
1200 table_id=1,
1201 paths=[VppRoutePath(self.pg1.remote_ip4,
1202 self.pg1.sw_if_index)])
1203 route_10_0_0_1.add_vpp_config()
1204
1205 #
1206 # An interface receive label that maps traffic to RX on interface
1207 # pg1
1208 # by injecting the packet in on pg0, which is in table 0
1209 # doing an interface-rx on pg1 and matching a route in table 1
1210 # if the packet egresses, then we must have swapped to pg1
1211 # so as to have matched the route in table 1
1212 #
Neale Ranns097fa662018-05-01 05:17:55 -07001213 route_34_eos = VppMplsRoute(
1214 self, 34, 1,
1215 [VppRoutePath("0.0.0.0",
1216 self.pg1.sw_if_index,
1217 type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001218 route_34_eos.add_vpp_config()
1219
1220 #
1221 # ping an interface in the default table
1222 # PG0 is in the default table
1223 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001224 tx = self.create_stream_labelled_ip4(self.pg0,
1225 [VppMplsLabel(34)],
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001226 dst_ip="10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -08001227 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001228 self.verify_capture_ip4(self.pg1, rx, tx)
1229
1230 def test_mcast_mid_point(self):
1231 """ MPLS Multicast Mid Point """
1232
1233 #
1234 # Add a non-recursive route that will forward the traffic
1235 # post-interface-rx
1236 #
1237 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
1238 table_id=1,
1239 paths=[VppRoutePath(self.pg1.remote_ip4,
1240 self.pg1.sw_if_index)])
1241 route_10_0_0_1.add_vpp_config()
1242
1243 #
1244 # Add a mcast entry that replicate to pg2 and pg3
1245 # and replicate to a interface-rx (like a bud node would)
1246 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001247 route_3400_eos = VppMplsRoute(
1248 self, 3400, 1,
1249 [VppRoutePath(self.pg2.remote_ip4,
1250 self.pg2.sw_if_index,
1251 labels=[VppMplsLabel(3401)]),
1252 VppRoutePath(self.pg3.remote_ip4,
1253 self.pg3.sw_if_index,
1254 labels=[VppMplsLabel(3402)]),
1255 VppRoutePath("0.0.0.0",
1256 self.pg1.sw_if_index,
Neale Ranns097fa662018-05-01 05:17:55 -07001257 type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX)],
Neale Ranns31ed7442018-02-23 05:29:09 -08001258 is_multicast=1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001259 route_3400_eos.add_vpp_config()
1260
1261 #
1262 # ping an interface in the default table
1263 # PG0 is in the default table
1264 #
1265 self.vapi.cli("clear trace")
Neale Ranns31ed7442018-02-23 05:29:09 -08001266 tx = self.create_stream_labelled_ip4(self.pg0,
1267 [VppMplsLabel(3400, ttl=64)],
1268 n=257,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001269 dst_ip="10.0.0.1")
1270 self.pg0.add_stream(tx)
1271
1272 self.pg_enable_capture(self.pg_interfaces)
1273 self.pg_start()
1274
1275 rx = self.pg1.get_capture(257)
1276 self.verify_capture_ip4(self.pg1, rx, tx)
1277
1278 rx = self.pg2.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001279 self.verify_capture_labelled(self.pg2, rx, tx,
1280 [VppMplsLabel(3401, ttl=63)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001281 rx = self.pg3.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001282 self.verify_capture_labelled(self.pg3, rx, tx,
1283 [VppMplsLabel(3402, ttl=63)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001284
1285 def test_mcast_head(self):
1286 """ MPLS Multicast Head-end """
1287
Neale Ranns990f6942020-10-20 07:20:17 +00001288 MRouteItfFlags = VppEnum.vl_api_mfib_itf_flags_t
1289 MRouteEntryFlags = VppEnum.vl_api_mfib_entry_flags_t
1290
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001291 #
1292 # Create a multicast tunnel with two replications
1293 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001294 mpls_tun = VppMPLSTunnelInterface(
1295 self,
1296 [VppRoutePath(self.pg2.remote_ip4,
1297 self.pg2.sw_if_index,
1298 labels=[VppMplsLabel(42)]),
1299 VppRoutePath(self.pg3.remote_ip4,
1300 self.pg3.sw_if_index,
1301 labels=[VppMplsLabel(43)])],
1302 is_multicast=1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001303 mpls_tun.add_vpp_config()
1304 mpls_tun.admin_up()
1305
1306 #
1307 # add an unlabelled route through the new tunnel
1308 #
1309 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
1310 [VppRoutePath("0.0.0.0",
1311 mpls_tun._sw_if_index)])
1312 route_10_0_0_3.add_vpp_config()
1313
1314 self.vapi.cli("clear trace")
1315 tx = self.create_stream_ip4(self.pg0, "10.0.0.3")
1316 self.pg0.add_stream(tx)
1317
1318 self.pg_enable_capture(self.pg_interfaces)
1319 self.pg_start()
1320
1321 rx = self.pg2.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001322 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(42)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001323 rx = self.pg3.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001324 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(43)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001325
1326 #
1327 # An an IP multicast route via the tunnel
1328 # A (*,G).
1329 # one accepting interface, pg0, 1 forwarding interface via the tunnel
1330 #
1331 route_232_1_1_1 = VppIpMRoute(
1332 self,
1333 "0.0.0.0",
1334 "232.1.1.1", 32,
Neale Ranns990f6942020-10-20 07:20:17 +00001335 MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001336 [VppMRoutePath(self.pg0.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +00001337 MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT),
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001338 VppMRoutePath(mpls_tun._sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +00001339 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001340 route_232_1_1_1.add_vpp_config()
Neale Ranns097fa662018-05-01 05:17:55 -07001341 self.logger.info(self.vapi.cli("sh ip mfib index 0"))
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001342
1343 self.vapi.cli("clear trace")
1344 tx = self.create_stream_ip4(self.pg0, "232.1.1.1")
1345 self.pg0.add_stream(tx)
1346
1347 self.pg_enable_capture(self.pg_interfaces)
1348 self.pg_start()
1349
1350 rx = self.pg2.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001351 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(42)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001352 rx = self.pg3.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001353 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(43)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001354
Neale Ranns31426c62017-05-24 10:32:58 -07001355 def test_mcast_ip4_tail(self):
1356 """ MPLS IPv4 Multicast Tail """
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001357
Neale Ranns990f6942020-10-20 07:20:17 +00001358 MRouteItfFlags = VppEnum.vl_api_mfib_itf_flags_t
1359 MRouteEntryFlags = VppEnum.vl_api_mfib_entry_flags_t
1360
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001361 #
1362 # Add a multicast route that will forward the traffic
1363 # post-disposition
1364 #
1365 route_232_1_1_1 = VppIpMRoute(
1366 self,
1367 "0.0.0.0",
1368 "232.1.1.1", 32,
Neale Ranns990f6942020-10-20 07:20:17 +00001369 MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001370 table_id=1,
1371 paths=[VppMRoutePath(self.pg1.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +00001372 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001373 route_232_1_1_1.add_vpp_config()
1374
1375 #
1376 # An interface receive label that maps traffic to RX on interface
1377 # pg1
1378 # by injecting the packet in on pg0, which is in table 0
1379 # doing an rpf-id and matching a route in table 1
1380 # if the packet egresses, then we must have matched the route in
1381 # table 1
1382 #
Neale Ranns097fa662018-05-01 05:17:55 -07001383 route_34_eos = VppMplsRoute(
1384 self, 34, 1,
1385 [VppRoutePath("0.0.0.0",
1386 0xffffffff,
1387 nh_table_id=1,
1388 rpf_id=55)],
1389 is_multicast=1,
1390 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP4)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001391
1392 route_34_eos.add_vpp_config()
1393
1394 #
1395 # Drop due to interface lookup miss
1396 #
1397 self.vapi.cli("clear trace")
Neale Ranns31ed7442018-02-23 05:29:09 -08001398 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001399 dst_ip="232.1.1.1", n=1)
1400 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop none")
1401
1402 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001403 # set the RPF-ID of the entry to match the input packet's
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001404 #
1405 route_232_1_1_1.update_rpf_id(55)
Neale Ranns097fa662018-05-01 05:17:55 -07001406 self.logger.info(self.vapi.cli("sh ip mfib index 1 232.1.1.1"))
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001407
Neale Ranns31ed7442018-02-23 05:29:09 -08001408 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
1409 dst_ip="232.1.1.1")
1410 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001411 self.verify_capture_ip4(self.pg1, rx, tx)
1412
1413 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001414 # disposed packets have an invalid IPv4 checksum
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001415 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001416 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001417 dst_ip="232.1.1.1", n=65,
1418 chksum=1)
1419 self.send_and_assert_no_replies(self.pg0, tx, "Invalid Checksum")
1420
1421 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001422 # set the RPF-ID of the entry to not match the input packet's
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001423 #
1424 route_232_1_1_1.update_rpf_id(56)
Neale Ranns31ed7442018-02-23 05:29:09 -08001425 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001426 dst_ip="232.1.1.1")
1427 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop 56")
1428
Neale Ranns31426c62017-05-24 10:32:58 -07001429 def test_mcast_ip6_tail(self):
1430 """ MPLS IPv6 Multicast Tail """
1431
Neale Ranns990f6942020-10-20 07:20:17 +00001432 MRouteItfFlags = VppEnum.vl_api_mfib_itf_flags_t
1433 MRouteEntryFlags = VppEnum.vl_api_mfib_entry_flags_t
1434
Neale Ranns31426c62017-05-24 10:32:58 -07001435 #
1436 # Add a multicast route that will forward the traffic
1437 # post-disposition
1438 #
1439 route_ff = VppIpMRoute(
1440 self,
1441 "::",
1442 "ff01::1", 32,
Neale Ranns990f6942020-10-20 07:20:17 +00001443 MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
Neale Ranns31426c62017-05-24 10:32:58 -07001444 table_id=1,
1445 paths=[VppMRoutePath(self.pg1.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +00001446 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD,
Neale Ranns097fa662018-05-01 05:17:55 -07001447 proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)])
Neale Ranns31426c62017-05-24 10:32:58 -07001448 route_ff.add_vpp_config()
1449
1450 #
1451 # An interface receive label that maps traffic to RX on interface
1452 # pg1
1453 # by injecting the packet in on pg0, which is in table 0
1454 # doing an rpf-id and matching a route in table 1
1455 # if the packet egresses, then we must have matched the route in
1456 # table 1
1457 #
1458 route_34_eos = VppMplsRoute(
1459 self, 34, 1,
1460 [VppRoutePath("::",
Neale Ranns097fa662018-05-01 05:17:55 -07001461 0xffffffff,
Neale Ranns31426c62017-05-24 10:32:58 -07001462 nh_table_id=1,
Neale Ranns097fa662018-05-01 05:17:55 -07001463 rpf_id=55)],
1464 is_multicast=1,
1465 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)
Neale Ranns31426c62017-05-24 10:32:58 -07001466
1467 route_34_eos.add_vpp_config()
1468
1469 #
1470 # Drop due to interface lookup miss
1471 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001472 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(34)],
Neale Ranns31426c62017-05-24 10:32:58 -07001473 dst_ip="ff01::1")
Neale Ranns31ed7442018-02-23 05:29:09 -08001474 self.send_and_assert_no_replies(self.pg0, tx, "RPF Miss")
Neale Ranns31426c62017-05-24 10:32:58 -07001475
1476 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001477 # set the RPF-ID of the entry to match the input packet's
Neale Ranns31426c62017-05-24 10:32:58 -07001478 #
1479 route_ff.update_rpf_id(55)
1480
Neale Ranns31ed7442018-02-23 05:29:09 -08001481 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(34)],
Neale Ranns31426c62017-05-24 10:32:58 -07001482 dst_ip="ff01::1")
Neale Ranns31ed7442018-02-23 05:29:09 -08001483 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns31426c62017-05-24 10:32:58 -07001484 self.verify_capture_ip6(self.pg1, rx, tx)
1485
1486 #
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001487 # disposed packets have hop-limit = 1
1488 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001489 tx = self.create_stream_labelled_ip6(self.pg0,
1490 [VppMplsLabel(34)],
1491 dst_ip="ff01::1",
1492 hlim=1)
1493 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns52fae862018-01-08 04:41:42 -08001494 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001495
1496 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001497 # set the RPF-ID of the entry to not match the input packet's
Neale Ranns31426c62017-05-24 10:32:58 -07001498 #
1499 route_ff.update_rpf_id(56)
Neale Ranns31ed7442018-02-23 05:29:09 -08001500 tx = self.create_stream_labelled_ip6(self.pg0,
1501 [VppMplsLabel(34)],
Neale Ranns31426c62017-05-24 10:32:58 -07001502 dst_ip="ff01::1")
1503 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop 56")
1504
Neale Rannsd5d7b962019-08-04 03:30:56 -07001505 def test_6pe(self):
1506 """ MPLS 6PE """
1507
1508 #
1509 # Add a non-recursive route with a single out label
1510 #
1511 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
1512 [VppRoutePath(self.pg0.remote_ip4,
1513 self.pg0.sw_if_index,
1514 labels=[VppMplsLabel(45)])])
1515 route_10_0_0_1.add_vpp_config()
1516
1517 # bind a local label to the route
1518 binding = VppMplsIpBind(self, 44, "10.0.0.1", 32)
1519 binding.add_vpp_config()
1520
1521 #
1522 # a labelled v6 route that resolves through the v4
1523 #
1524 route_2001_3 = VppIpRoute(
1525 self, "2001::3", 128,
1526 [VppRoutePath("10.0.0.1",
1527 INVALID_INDEX,
1528 labels=[VppMplsLabel(32)])])
1529 route_2001_3.add_vpp_config()
1530
1531 tx = self.create_stream_ip6(self.pg0, "2001::3")
1532 rx = self.send_and_expect(self.pg0, tx, self.pg0)
1533
1534 self.verify_capture_labelled_ip6(self.pg0, rx, tx,
1535 [VppMplsLabel(45),
1536 VppMplsLabel(32)])
1537
1538 #
1539 # and a v4 recursive via the v6
1540 #
1541 route_20_3 = VppIpRoute(
1542 self, "20.0.0.3", 32,
1543 [VppRoutePath("2001::3",
1544 INVALID_INDEX,
1545 labels=[VppMplsLabel(99)])])
1546 route_20_3.add_vpp_config()
1547
1548 tx = self.create_stream_ip4(self.pg0, "20.0.0.3")
1549 rx = self.send_and_expect(self.pg0, tx, self.pg0)
1550
1551 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
1552 [VppMplsLabel(45),
1553 VppMplsLabel(32),
1554 VppMplsLabel(99)])
1555
Neale Ranns180279b2017-03-16 15:49:09 -04001556
1557class TestMPLSDisabled(VppTestCase):
1558 """ MPLS disabled """
1559
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -07001560 @classmethod
1561 def setUpClass(cls):
1562 super(TestMPLSDisabled, cls).setUpClass()
1563
1564 @classmethod
1565 def tearDownClass(cls):
1566 super(TestMPLSDisabled, cls).tearDownClass()
1567
Neale Ranns180279b2017-03-16 15:49:09 -04001568 def setUp(self):
1569 super(TestMPLSDisabled, self).setUp()
1570
1571 # create 2 pg interfaces
1572 self.create_pg_interfaces(range(2))
1573
Neale Ranns15002542017-09-10 04:39:11 -07001574 self.tbl = VppMplsTable(self, 0)
1575 self.tbl.add_vpp_config()
1576
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001577 # PG0 is MPLS enabled
Neale Ranns180279b2017-03-16 15:49:09 -04001578 self.pg0.admin_up()
1579 self.pg0.config_ip4()
1580 self.pg0.resolve_arp()
1581 self.pg0.enable_mpls()
1582
1583 # PG 1 is not MPLS enabled
1584 self.pg1.admin_up()
1585
1586 def tearDown(self):
Neale Ranns180279b2017-03-16 15:49:09 -04001587 for i in self.pg_interfaces:
1588 i.unconfig_ip4()
1589 i.admin_down()
1590
Neale Ranns15002542017-09-10 04:39:11 -07001591 self.pg0.disable_mpls()
1592 super(TestMPLSDisabled, self).tearDown()
1593
Neale Ranns180279b2017-03-16 15:49:09 -04001594 def test_mpls_disabled(self):
1595 """ MPLS Disabled """
1596
1597 tx = (Ether(src=self.pg1.remote_mac,
1598 dst=self.pg1.local_mac) /
1599 MPLS(label=32, ttl=64) /
1600 IPv6(src="2001::1", dst=self.pg0.remote_ip6) /
1601 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001602 Raw(b'\xa5' * 100))
Neale Ranns180279b2017-03-16 15:49:09 -04001603
1604 #
1605 # A simple MPLS xconnect - eos label in label out
1606 #
1607 route_32_eos = VppMplsRoute(self, 32, 1,
1608 [VppRoutePath(self.pg0.remote_ip4,
1609 self.pg0.sw_if_index,
1610 labels=[33])])
1611 route_32_eos.add_vpp_config()
1612
1613 #
1614 # PG1 does not forward IP traffic
1615 #
1616 self.send_and_assert_no_replies(self.pg1, tx, "MPLS disabled")
1617
1618 #
1619 # MPLS enable PG1
1620 #
1621 self.pg1.enable_mpls()
1622
1623 #
1624 # Now we get packets through
1625 #
1626 self.pg1.add_stream(tx)
1627 self.pg_enable_capture(self.pg_interfaces)
1628 self.pg_start()
1629
1630 rx = self.pg0.get_capture(1)
1631
1632 #
1633 # Disable PG1
1634 #
1635 self.pg1.disable_mpls()
1636
1637 #
1638 # PG1 does not forward IP traffic
1639 #
1640 self.send_and_assert_no_replies(self.pg1, tx, "IPv6 disabled")
1641 self.send_and_assert_no_replies(self.pg1, tx, "IPv6 disabled")
1642
1643
Neale Rannsf12a83f2017-04-18 09:09:40 -07001644class TestMPLSPIC(VppTestCase):
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001645 """ MPLS Prefix-Independent Convergence (PIC) edge convergence """
Neale Rannsf12a83f2017-04-18 09:09:40 -07001646
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -07001647 @classmethod
1648 def setUpClass(cls):
1649 super(TestMPLSPIC, cls).setUpClass()
1650
1651 @classmethod
1652 def tearDownClass(cls):
1653 super(TestMPLSPIC, cls).tearDownClass()
1654
Neale Rannsf12a83f2017-04-18 09:09:40 -07001655 def setUp(self):
1656 super(TestMPLSPIC, self).setUp()
1657
1658 # create 2 pg interfaces
1659 self.create_pg_interfaces(range(4))
1660
Neale Ranns15002542017-09-10 04:39:11 -07001661 mpls_tbl = VppMplsTable(self, 0)
1662 mpls_tbl.add_vpp_config()
1663 tbl4 = VppIpTable(self, 1)
1664 tbl4.add_vpp_config()
1665 tbl6 = VppIpTable(self, 1, is_ip6=1)
1666 tbl6.add_vpp_config()
1667
Neale Rannsf12a83f2017-04-18 09:09:40 -07001668 # core links
1669 self.pg0.admin_up()
1670 self.pg0.config_ip4()
1671 self.pg0.resolve_arp()
1672 self.pg0.enable_mpls()
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001673
Neale Rannsf12a83f2017-04-18 09:09:40 -07001674 self.pg1.admin_up()
1675 self.pg1.config_ip4()
1676 self.pg1.resolve_arp()
1677 self.pg1.enable_mpls()
1678
1679 # VRF (customer facing) link
1680 self.pg2.admin_up()
1681 self.pg2.set_table_ip4(1)
1682 self.pg2.config_ip4()
1683 self.pg2.resolve_arp()
1684 self.pg2.set_table_ip6(1)
1685 self.pg2.config_ip6()
1686 self.pg2.resolve_ndp()
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001687
Neale Rannsf12a83f2017-04-18 09:09:40 -07001688 self.pg3.admin_up()
1689 self.pg3.set_table_ip4(1)
1690 self.pg3.config_ip4()
1691 self.pg3.resolve_arp()
1692 self.pg3.set_table_ip6(1)
1693 self.pg3.config_ip6()
1694 self.pg3.resolve_ndp()
1695
1696 def tearDown(self):
Neale Rannsf12a83f2017-04-18 09:09:40 -07001697 self.pg0.disable_mpls()
Neale Ranns15002542017-09-10 04:39:11 -07001698 self.pg1.disable_mpls()
Neale Rannsf12a83f2017-04-18 09:09:40 -07001699 for i in self.pg_interfaces:
1700 i.unconfig_ip4()
1701 i.unconfig_ip6()
1702 i.set_table_ip4(0)
1703 i.set_table_ip6(0)
1704 i.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -07001705 super(TestMPLSPIC, self).tearDown()
Neale Rannsf12a83f2017-04-18 09:09:40 -07001706
1707 def test_mpls_ibgp_pic(self):
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001708 """ MPLS iBGP Prefix-Independent Convergence (PIC) edge convergence
Neale Rannsf12a83f2017-04-18 09:09:40 -07001709
1710 1) setup many iBGP VPN routes via a pair of iBGP peers.
1711 2) Check EMCP forwarding to these peers
1712 3) withdraw the IGP route to one of these peers.
1713 4) check forwarding continues to the remaining peer
1714 """
1715
1716 #
1717 # IGP+LDP core routes
1718 #
1719 core_10_0_0_45 = VppIpRoute(self, "10.0.0.45", 32,
1720 [VppRoutePath(self.pg0.remote_ip4,
1721 self.pg0.sw_if_index,
1722 labels=[45])])
1723 core_10_0_0_45.add_vpp_config()
1724
1725 core_10_0_0_46 = VppIpRoute(self, "10.0.0.46", 32,
1726 [VppRoutePath(self.pg1.remote_ip4,
1727 self.pg1.sw_if_index,
1728 labels=[46])])
1729 core_10_0_0_46.add_vpp_config()
1730
1731 #
1732 # Lot's of VPN routes. We need more the 64 so VPP will build
1733 # the fast convergence indirection
1734 #
1735 vpn_routes = []
1736 pkts = []
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001737 for ii in range(NUM_PKTS):
Neale Rannsf12a83f2017-04-18 09:09:40 -07001738 dst = "192.168.1.%d" % ii
Neale Ranns097fa662018-05-01 05:17:55 -07001739 vpn_routes.append(VppIpRoute(
1740 self, dst, 32,
1741 [VppRoutePath(
1742 "10.0.0.45",
1743 0xffffffff,
1744 labels=[145],
1745 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_HOST),
1746 VppRoutePath(
1747 "10.0.0.46",
1748 0xffffffff,
1749 labels=[146],
1750 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_HOST)],
1751 table_id=1))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001752 vpn_routes[ii].add_vpp_config()
1753
1754 pkts.append(Ether(dst=self.pg2.local_mac,
1755 src=self.pg2.remote_mac) /
1756 IP(src=self.pg2.remote_ip4, dst=dst) /
1757 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001758 Raw(b'\xa5' * 100))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001759
1760 #
1761 # Send the packet stream (one pkt to each VPN route)
1762 # - expect a 50-50 split of the traffic
1763 #
1764 self.pg2.add_stream(pkts)
1765 self.pg_enable_capture(self.pg_interfaces)
1766 self.pg_start()
1767
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001768 rx0 = self.pg0._get_capture(NUM_PKTS)
1769 rx1 = self.pg1._get_capture(NUM_PKTS)
Neale Rannsf12a83f2017-04-18 09:09:40 -07001770
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001771 # not testing the LB hashing algorithm so we're not concerned
Neale Rannsf12a83f2017-04-18 09:09:40 -07001772 # with the split ratio, just as long as neither is 0
1773 self.assertNotEqual(0, len(rx0))
1774 self.assertNotEqual(0, len(rx1))
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001775 self.assertEqual(len(pkts), len(rx0) + len(rx1),
1776 "Expected all (%s) packets across both ECMP paths. "
1777 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001778
1779 #
1780 # use a test CLI command to stop the FIB walk process, this
1781 # will prevent the FIB converging the VPN routes and thus allow
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001782 # us to probe the interim (post-fail, pre-converge) state
Neale Rannsf12a83f2017-04-18 09:09:40 -07001783 #
1784 self.vapi.ppcli("test fib-walk-process disable")
1785
1786 #
1787 # Withdraw one of the IGP routes
1788 #
1789 core_10_0_0_46.remove_vpp_config()
1790
1791 #
1792 # now all packets should be forwarded through the remaining peer
1793 #
1794 self.vapi.ppcli("clear trace")
1795 self.pg2.add_stream(pkts)
1796 self.pg_enable_capture(self.pg_interfaces)
1797 self.pg_start()
1798
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001799 rx0 = self.pg0.get_capture(NUM_PKTS)
1800 self.assertEqual(len(pkts), len(rx0),
1801 "Expected all (%s) packets across single path. "
1802 "rx0: %s." % (len(pkts), len(rx0)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001803
1804 #
1805 # enable the FIB walk process to converge the FIB
1806 #
1807 self.vapi.ppcli("test fib-walk-process enable")
1808
1809 #
1810 # packets should still be forwarded through the remaining peer
1811 #
1812 self.pg2.add_stream(pkts)
1813 self.pg_enable_capture(self.pg_interfaces)
1814 self.pg_start()
1815
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001816 rx0 = self.pg0.get_capture(NUM_PKTS)
1817 self.assertEqual(len(pkts), len(rx0),
1818 "Expected all (%s) packets across single path. "
1819 "rx0: %s." % (len(pkts), len(rx0)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001820
1821 #
1822 # Add the IGP route back and we return to load-balancing
1823 #
1824 core_10_0_0_46.add_vpp_config()
1825
1826 self.pg2.add_stream(pkts)
1827 self.pg_enable_capture(self.pg_interfaces)
1828 self.pg_start()
1829
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001830 rx0 = self.pg0._get_capture(NUM_PKTS)
1831 rx1 = self.pg1._get_capture(NUM_PKTS)
Neale Rannsf12a83f2017-04-18 09:09:40 -07001832 self.assertNotEqual(0, len(rx0))
1833 self.assertNotEqual(0, len(rx1))
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001834 self.assertEqual(len(pkts), len(rx0) + len(rx1),
1835 "Expected all (%s) packets across both ECMP paths. "
1836 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001837
1838 def test_mpls_ebgp_pic(self):
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001839 """ MPLS eBGP Prefix-Independent Convergence (PIC) edge convergence
Neale Rannsf12a83f2017-04-18 09:09:40 -07001840
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001841 1) setup many eBGP VPN routes via a pair of eBGP peers.
Neale Rannsf12a83f2017-04-18 09:09:40 -07001842 2) Check EMCP forwarding to these peers
1843 3) withdraw one eBGP path - expect LB across remaining eBGP
1844 """
1845
1846 #
1847 # Lot's of VPN routes. We need more the 64 so VPP will build
1848 # the fast convergence indirection
1849 #
1850 vpn_routes = []
1851 vpn_bindings = []
1852 pkts = []
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001853 for ii in range(NUM_PKTS):
Neale Rannsf12a83f2017-04-18 09:09:40 -07001854 dst = "192.168.1.%d" % ii
1855 local_label = 1600 + ii
Neale Ranns097fa662018-05-01 05:17:55 -07001856 vpn_routes.append(VppIpRoute(
1857 self, dst, 32,
1858 [VppRoutePath(
1859 self.pg2.remote_ip4,
1860 0xffffffff,
1861 nh_table_id=1,
1862 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_ATTACHED),
1863 VppRoutePath(
1864 self.pg3.remote_ip4,
1865 0xffffffff,
1866 nh_table_id=1,
1867 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_ATTACHED)],
1868 table_id=1))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001869 vpn_routes[ii].add_vpp_config()
1870
1871 vpn_bindings.append(VppMplsIpBind(self, local_label, dst, 32,
1872 ip_table_id=1))
1873 vpn_bindings[ii].add_vpp_config()
1874
1875 pkts.append(Ether(dst=self.pg0.local_mac,
1876 src=self.pg0.remote_mac) /
1877 MPLS(label=local_label, ttl=64) /
1878 IP(src=self.pg0.remote_ip4, dst=dst) /
1879 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001880 Raw(b'\xa5' * 100))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001881
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001882 #
1883 # Send the packet stream (one pkt to each VPN route)
1884 # - expect a 50-50 split of the traffic
1885 #
Neale Rannsf12a83f2017-04-18 09:09:40 -07001886 self.pg0.add_stream(pkts)
1887 self.pg_enable_capture(self.pg_interfaces)
1888 self.pg_start()
1889
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001890 rx0 = self.pg2._get_capture(NUM_PKTS)
1891 rx1 = self.pg3._get_capture(NUM_PKTS)
1892
1893 # not testing the LB hashing algorithm so we're not concerned
1894 # with the split ratio, just as long as neither is 0
Neale Rannsf12a83f2017-04-18 09:09:40 -07001895 self.assertNotEqual(0, len(rx0))
1896 self.assertNotEqual(0, len(rx1))
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001897 self.assertEqual(len(pkts), len(rx0) + len(rx1),
1898 "Expected all (%s) packets across both ECMP paths. "
1899 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001900
1901 #
1902 # use a test CLI command to stop the FIB walk process, this
1903 # will prevent the FIB converging the VPN routes and thus allow
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001904 # us to probe the interim (post-fail, pre-converge) state
Neale Rannsf12a83f2017-04-18 09:09:40 -07001905 #
1906 self.vapi.ppcli("test fib-walk-process disable")
1907
1908 #
1909 # withdraw the connected prefix on the interface.
1910 #
1911 self.pg2.unconfig_ip4()
1912
1913 #
1914 # now all packets should be forwarded through the remaining peer
1915 #
1916 self.pg0.add_stream(pkts)
1917 self.pg_enable_capture(self.pg_interfaces)
1918 self.pg_start()
1919
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001920 rx0 = self.pg3.get_capture(NUM_PKTS)
1921 self.assertEqual(len(pkts), len(rx0),
1922 "Expected all (%s) packets across single path. "
1923 "rx0: %s." % (len(pkts), len(rx0)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001924
1925 #
1926 # enable the FIB walk process to converge the FIB
1927 #
1928 self.vapi.ppcli("test fib-walk-process enable")
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001929
1930 #
1931 # packets should still be forwarded through the remaining peer
1932 #
Neale Rannsf12a83f2017-04-18 09:09:40 -07001933 self.pg0.add_stream(pkts)
1934 self.pg_enable_capture(self.pg_interfaces)
1935 self.pg_start()
1936
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001937 rx0 = self.pg3.get_capture(NUM_PKTS)
1938 self.assertEqual(len(pkts), len(rx0),
1939 "Expected all (%s) packets across single path. "
1940 "rx0: %s." % (len(pkts), len(rx0)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001941
1942 #
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001943 # put the connected routes back
Neale Rannsf12a83f2017-04-18 09:09:40 -07001944 #
1945 self.pg2.config_ip4()
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001946 self.pg2.resolve_arp()
Neale Rannsf12a83f2017-04-18 09:09:40 -07001947
1948 self.pg0.add_stream(pkts)
1949 self.pg_enable_capture(self.pg_interfaces)
1950 self.pg_start()
1951
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001952 rx0 = self.pg2._get_capture(NUM_PKTS)
1953 rx1 = self.pg3._get_capture(NUM_PKTS)
Neale Rannsf12a83f2017-04-18 09:09:40 -07001954 self.assertNotEqual(0, len(rx0))
1955 self.assertNotEqual(0, len(rx1))
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001956 self.assertEqual(len(pkts), len(rx0) + len(rx1),
1957 "Expected all (%s) packets across both ECMP paths. "
1958 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001959
1960 def test_mpls_v6_ebgp_pic(self):
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001961 """ MPLSv6 eBGP Prefix-Independent Convergence (PIC) edge convergence
Neale Rannsf12a83f2017-04-18 09:09:40 -07001962
1963 1) setup many eBGP VPNv6 routes via a pair of eBGP peers
1964 2) Check EMCP forwarding to these peers
1965 3) withdraw one eBGP path - expect LB across remaining eBGP
1966 """
1967
1968 #
1969 # Lot's of VPN routes. We need more the 64 so VPP will build
1970 # the fast convergence indirection
1971 #
1972 vpn_routes = []
1973 vpn_bindings = []
1974 pkts = []
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001975 for ii in range(NUM_PKTS):
Neale Rannsf12a83f2017-04-18 09:09:40 -07001976 dst = "3000::%d" % ii
1977 local_label = 1600 + ii
Neale Rannsda78f952017-05-24 09:15:43 -07001978 vpn_routes.append(VppIpRoute(
1979 self, dst, 128,
Neale Ranns097fa662018-05-01 05:17:55 -07001980 [VppRoutePath(
1981 self.pg2.remote_ip6,
1982 0xffffffff,
1983 nh_table_id=1,
1984 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_ATTACHED),
1985 VppRoutePath(
1986 self.pg3.remote_ip6,
1987 0xffffffff,
1988 nh_table_id=1,
1989 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_ATTACHED)],
1990 table_id=1))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001991 vpn_routes[ii].add_vpp_config()
1992
1993 vpn_bindings.append(VppMplsIpBind(self, local_label, dst, 128,
Neale Ranns097fa662018-05-01 05:17:55 -07001994 ip_table_id=1))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001995 vpn_bindings[ii].add_vpp_config()
1996
1997 pkts.append(Ether(dst=self.pg0.local_mac,
1998 src=self.pg0.remote_mac) /
1999 MPLS(label=local_label, ttl=64) /
2000 IPv6(src=self.pg0.remote_ip6, dst=dst) /
2001 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002002 Raw(b'\xa5' * 100))
Neale Ranns097fa662018-05-01 05:17:55 -07002003 self.logger.info(self.vapi.cli("sh ip6 fib %s" % dst))
Neale Rannsf12a83f2017-04-18 09:09:40 -07002004
2005 self.pg0.add_stream(pkts)
2006 self.pg_enable_capture(self.pg_interfaces)
2007 self.pg_start()
2008
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002009 rx0 = self.pg2._get_capture(NUM_PKTS)
2010 rx1 = self.pg3._get_capture(NUM_PKTS)
Neale Rannsf12a83f2017-04-18 09:09:40 -07002011 self.assertNotEqual(0, len(rx0))
2012 self.assertNotEqual(0, len(rx1))
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002013 self.assertEqual(len(pkts), len(rx0) + len(rx1),
2014 "Expected all (%s) packets across both ECMP paths. "
2015 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07002016
2017 #
2018 # use a test CLI command to stop the FIB walk process, this
2019 # will prevent the FIB converging the VPN routes and thus allow
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002020 # us to probe the interim (post-fail, pre-converge) state
Neale Rannsf12a83f2017-04-18 09:09:40 -07002021 #
2022 self.vapi.ppcli("test fib-walk-process disable")
2023
2024 #
2025 # withdraw the connected prefix on the interface.
2026 # and shutdown the interface so the ND cache is flushed.
2027 #
2028 self.pg2.unconfig_ip6()
2029 self.pg2.admin_down()
2030
2031 #
2032 # now all packets should be forwarded through the remaining peer
2033 #
2034 self.pg0.add_stream(pkts)
2035 self.pg_enable_capture(self.pg_interfaces)
2036 self.pg_start()
2037
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002038 rx0 = self.pg3.get_capture(NUM_PKTS)
2039 self.assertEqual(len(pkts), len(rx0),
2040 "Expected all (%s) packets across single path. "
2041 "rx0: %s." % (len(pkts), len(rx0)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07002042
2043 #
2044 # enable the FIB walk process to converge the FIB
2045 #
2046 self.vapi.ppcli("test fib-walk-process enable")
2047 self.pg0.add_stream(pkts)
2048 self.pg_enable_capture(self.pg_interfaces)
2049 self.pg_start()
2050
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002051 rx0 = self.pg3.get_capture(NUM_PKTS)
2052 self.assertEqual(len(pkts), len(rx0),
2053 "Expected all (%s) packets across single path. "
2054 "rx0: %s." % (len(pkts), len(rx0)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07002055
2056 #
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002057 # put the connected routes back
Neale Rannsf12a83f2017-04-18 09:09:40 -07002058 #
Paul Vinciguerraa42c6ee2019-12-27 00:17:01 -05002059 self.logger.info(self.vapi.cli("sh log"))
Neale Rannsf12a83f2017-04-18 09:09:40 -07002060 self.pg2.admin_up()
2061 self.pg2.config_ip6()
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002062 self.pg2.resolve_ndp()
Neale Rannsf12a83f2017-04-18 09:09:40 -07002063
2064 self.pg0.add_stream(pkts)
2065 self.pg_enable_capture(self.pg_interfaces)
2066 self.pg_start()
2067
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002068 rx0 = self.pg2._get_capture(NUM_PKTS)
2069 rx1 = self.pg3._get_capture(NUM_PKTS)
Neale Rannsf12a83f2017-04-18 09:09:40 -07002070 self.assertNotEqual(0, len(rx0))
2071 self.assertNotEqual(0, len(rx1))
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002072 self.assertEqual(len(pkts), len(rx0) + len(rx1),
2073 "Expected all (%s) packets across both ECMP paths. "
2074 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07002075
2076
Neale Rannsda78f952017-05-24 09:15:43 -07002077class TestMPLSL2(VppTestCase):
2078 """ MPLS-L2 """
2079
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -07002080 @classmethod
2081 def setUpClass(cls):
2082 super(TestMPLSL2, cls).setUpClass()
2083
2084 @classmethod
2085 def tearDownClass(cls):
2086 super(TestMPLSL2, cls).tearDownClass()
2087
Neale Rannsda78f952017-05-24 09:15:43 -07002088 def setUp(self):
2089 super(TestMPLSL2, self).setUp()
2090
2091 # create 2 pg interfaces
2092 self.create_pg_interfaces(range(2))
2093
Neale Ranns15002542017-09-10 04:39:11 -07002094 # create the default MPLS table
2095 self.tables = []
2096 tbl = VppMplsTable(self, 0)
2097 tbl.add_vpp_config()
2098 self.tables.append(tbl)
2099
Neale Ranns1976f362019-11-06 13:13:01 +00002100 # use pg0 as the core facing interface, don't resolve ARP
Neale Rannsda78f952017-05-24 09:15:43 -07002101 self.pg0.admin_up()
2102 self.pg0.config_ip4()
Neale Rannsda78f952017-05-24 09:15:43 -07002103 self.pg0.enable_mpls()
2104
Neale Ranns15002542017-09-10 04:39:11 -07002105 # use the other 2 for customer facing L2 links
Neale Rannsda78f952017-05-24 09:15:43 -07002106 for i in self.pg_interfaces[1:]:
2107 i.admin_up()
2108
2109 def tearDown(self):
Neale Rannsda78f952017-05-24 09:15:43 -07002110 for i in self.pg_interfaces[1:]:
2111 i.admin_down()
2112
2113 self.pg0.disable_mpls()
2114 self.pg0.unconfig_ip4()
2115 self.pg0.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -07002116 super(TestMPLSL2, self).tearDown()
Neale Rannsda78f952017-05-24 09:15:43 -07002117
Neale Ranns31ed7442018-02-23 05:29:09 -08002118 def verify_capture_tunneled_ethernet(self, capture, sent, mpls_labels):
Neale Rannsda78f952017-05-24 09:15:43 -07002119 capture = verify_filter(capture, sent)
2120
2121 self.assertEqual(len(capture), len(sent))
2122
2123 for i in range(len(capture)):
2124 tx = sent[i]
2125 rx = capture[i]
2126
2127 # the MPLS TTL is 255 since it enters a new tunnel
Neale Ranns31ed7442018-02-23 05:29:09 -08002128 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsda78f952017-05-24 09:15:43 -07002129
2130 tx_eth = tx[Ether]
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -07002131 rx_eth = Ether(scapy.compat.raw(rx[MPLS].payload))
Neale Rannsda78f952017-05-24 09:15:43 -07002132
2133 self.assertEqual(rx_eth.src, tx_eth.src)
2134 self.assertEqual(rx_eth.dst, tx_eth.dst)
2135
Neale Ranns1976f362019-11-06 13:13:01 +00002136 def verify_arp_req(self, rx, smac, sip, dip):
2137 ether = rx[Ether]
2138 self.assertEqual(ether.dst, "ff:ff:ff:ff:ff:ff")
2139 self.assertEqual(ether.src, smac)
2140
2141 arp = rx[ARP]
2142 self.assertEqual(arp.hwtype, 1)
2143 self.assertEqual(arp.ptype, 0x800)
2144 self.assertEqual(arp.hwlen, 6)
2145 self.assertEqual(arp.plen, 4)
2146 self.assertEqual(arp.op, ARP.who_has)
2147 self.assertEqual(arp.hwsrc, smac)
2148 self.assertEqual(arp.hwdst, "00:00:00:00:00:00")
2149 self.assertEqual(arp.psrc, sip)
2150 self.assertEqual(arp.pdst, dip)
2151
Neale Rannsda78f952017-05-24 09:15:43 -07002152 def test_vpws(self):
2153 """ Virtual Private Wire Service """
2154
2155 #
2156 # Create an MPLS tunnel that pushes 1 label
Neale Ranns31ed7442018-02-23 05:29:09 -08002157 # For Ethernet over MPLS the uniform mode is irrelevant since ttl/cos
2158 # information is not in the packet, but we test it works anyway
Neale Rannsda78f952017-05-24 09:15:43 -07002159 #
Neale Ranns31ed7442018-02-23 05:29:09 -08002160 mpls_tun_1 = VppMPLSTunnelInterface(
2161 self,
2162 [VppRoutePath(self.pg0.remote_ip4,
2163 self.pg0.sw_if_index,
2164 labels=[VppMplsLabel(42, MplsLspMode.UNIFORM)])],
2165 is_l2=1)
Neale Rannsda78f952017-05-24 09:15:43 -07002166 mpls_tun_1.add_vpp_config()
2167 mpls_tun_1.admin_up()
2168
2169 #
2170 # Create a label entry to for 55 that does L2 input to the tunnel
2171 #
2172 route_55_eos = VppMplsRoute(
2173 self, 55, 1,
2174 [VppRoutePath("0.0.0.0",
2175 mpls_tun_1.sw_if_index,
Neale Ranns097fa662018-05-01 05:17:55 -07002176 type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX,
2177 proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET)],
2178 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET)
Neale Rannsda78f952017-05-24 09:15:43 -07002179 route_55_eos.add_vpp_config()
2180
2181 #
2182 # Cross-connect the tunnel with one of the customers L2 interfaces
2183 #
2184 self.vapi.sw_interface_set_l2_xconnect(self.pg1.sw_if_index,
2185 mpls_tun_1.sw_if_index,
2186 enable=1)
2187 self.vapi.sw_interface_set_l2_xconnect(mpls_tun_1.sw_if_index,
2188 self.pg1.sw_if_index,
2189 enable=1)
2190
2191 #
2192 # inject a packet from the core
2193 #
2194 pcore = (Ether(dst=self.pg0.local_mac,
2195 src=self.pg0.remote_mac) /
2196 MPLS(label=55, ttl=64) /
2197 Ether(dst="00:00:de:ad:ba:be",
2198 src="00:00:de:ad:be:ef") /
2199 IP(src="10.10.10.10", dst="11.11.11.11") /
2200 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002201 Raw(b'\xa5' * 100))
Neale Rannsda78f952017-05-24 09:15:43 -07002202
Paul Vinciguerra4271c972019-05-14 13:25:49 -04002203 tx0 = pcore * NUM_PKTS
Neale Ranns31ed7442018-02-23 05:29:09 -08002204 rx0 = self.send_and_expect(self.pg0, tx0, self.pg1)
2205 payload = pcore[MPLS].payload
Neale Rannsda78f952017-05-24 09:15:43 -07002206
Neale Ranns31ed7442018-02-23 05:29:09 -08002207 self.assertEqual(rx0[0][Ether].dst, payload[Ether].dst)
2208 self.assertEqual(rx0[0][Ether].src, payload[Ether].src)
Neale Rannsda78f952017-05-24 09:15:43 -07002209
2210 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002211 # Inject a packet from the customer/L2 side
Neale Ranns1976f362019-11-06 13:13:01 +00002212 # there's no resolved ARP entry so the first packet we see should be
2213 # an ARP request
Neale Rannsda78f952017-05-24 09:15:43 -07002214 #
Neale Ranns1976f362019-11-06 13:13:01 +00002215 tx1 = pcore[MPLS].payload
2216 rx1 = self.send_and_expect(self.pg1, [tx1], self.pg0)
2217
2218 self.verify_arp_req(rx1[0],
2219 self.pg0.local_mac,
2220 self.pg0.local_ip4,
2221 self.pg0.remote_ip4)
2222
2223 #
2224 # resolve the ARP entries and send again
2225 #
2226 self.pg0.resolve_arp()
Paul Vinciguerra4271c972019-05-14 13:25:49 -04002227 tx1 = pcore[MPLS].payload * NUM_PKTS
Neale Ranns31ed7442018-02-23 05:29:09 -08002228 rx1 = self.send_and_expect(self.pg1, tx1, self.pg0)
Neale Rannsda78f952017-05-24 09:15:43 -07002229
Neale Ranns31ed7442018-02-23 05:29:09 -08002230 self.verify_capture_tunneled_ethernet(rx1, tx1, [VppMplsLabel(42)])
Neale Rannsda78f952017-05-24 09:15:43 -07002231
2232 def test_vpls(self):
2233 """ Virtual Private LAN Service """
Neale Ranns1976f362019-11-06 13:13:01 +00002234
2235 # we skipped this in the setup
2236 self.pg0.resolve_arp()
2237
Neale Rannsda78f952017-05-24 09:15:43 -07002238 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002239 # Create a L2 MPLS tunnels
Neale Rannsda78f952017-05-24 09:15:43 -07002240 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002241 mpls_tun1 = VppMPLSTunnelInterface(
Neale Ranns31ed7442018-02-23 05:29:09 -08002242 self,
2243 [VppRoutePath(self.pg0.remote_ip4,
2244 self.pg0.sw_if_index,
2245 labels=[VppMplsLabel(42)])],
2246 is_l2=1)
Neale Ranns1dbcf302019-07-19 11:44:53 +00002247 mpls_tun1.add_vpp_config()
2248 mpls_tun1.admin_up()
2249
2250 mpls_tun2 = VppMPLSTunnelInterface(
2251 self,
2252 [VppRoutePath(self.pg0.remote_ip4,
2253 self.pg0.sw_if_index,
2254 labels=[VppMplsLabel(43)])],
2255 is_l2=1)
2256 mpls_tun2.add_vpp_config()
2257 mpls_tun2.admin_up()
Neale Rannsda78f952017-05-24 09:15:43 -07002258
2259 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002260 # Create a label entries, 55 and 56, that do L2 input to the tunnel
2261 # the latter includes a Psuedo Wire Control Word
Neale Rannsda78f952017-05-24 09:15:43 -07002262 #
2263 route_55_eos = VppMplsRoute(
2264 self, 55, 1,
2265 [VppRoutePath("0.0.0.0",
Neale Ranns1dbcf302019-07-19 11:44:53 +00002266 mpls_tun1.sw_if_index,
Neale Ranns097fa662018-05-01 05:17:55 -07002267 type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX,
2268 proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET)],
2269 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET)
Neale Ranns1dbcf302019-07-19 11:44:53 +00002270
2271 route_56_eos = VppMplsRoute(
2272 self, 56, 1,
2273 [VppRoutePath("0.0.0.0",
2274 mpls_tun2.sw_if_index,
2275 type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX,
2276 flags=FibPathFlags.FIB_PATH_FLAG_POP_PW_CW,
2277 proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET)],
2278 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET)
2279
2280 # move me
2281 route_56_eos.add_vpp_config()
Neale Rannsda78f952017-05-24 09:15:43 -07002282 route_55_eos.add_vpp_config()
2283
Neale Ranns1dbcf302019-07-19 11:44:53 +00002284 self.logger.info(self.vapi.cli("sh mpls fib 56"))
2285
Neale Rannsda78f952017-05-24 09:15:43 -07002286 #
2287 # add to tunnel to the customers bridge-domain
2288 #
Ole Troana5b2eec2019-03-11 19:23:25 +01002289 self.vapi.sw_interface_set_l2_bridge(
Neale Ranns1dbcf302019-07-19 11:44:53 +00002290 rx_sw_if_index=mpls_tun1.sw_if_index, bd_id=1)
2291 self.vapi.sw_interface_set_l2_bridge(
2292 rx_sw_if_index=mpls_tun2.sw_if_index, bd_id=1)
Ole Troana5b2eec2019-03-11 19:23:25 +01002293 self.vapi.sw_interface_set_l2_bridge(
2294 rx_sw_if_index=self.pg1.sw_if_index, bd_id=1)
Neale Rannsda78f952017-05-24 09:15:43 -07002295
2296 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002297 # Packet from host on the customer interface to each host
2298 # reachable over the core, and vice-versa
Neale Rannsda78f952017-05-24 09:15:43 -07002299 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002300 p_cust1 = (Ether(dst="00:00:de:ad:ba:b1",
2301 src="00:00:de:ad:be:ef") /
2302 IP(src="10.10.10.10", dst="11.11.11.11") /
2303 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002304 Raw(b'\xa5' * 100))
Neale Ranns1dbcf302019-07-19 11:44:53 +00002305 p_cust2 = (Ether(dst="00:00:de:ad:ba:b2",
2306 src="00:00:de:ad:be:ef") /
2307 IP(src="10.10.10.10", dst="11.11.11.12") /
2308 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002309 Raw(b'\xa5' * 100))
Neale Ranns1dbcf302019-07-19 11:44:53 +00002310 p_core1 = (Ether(dst=self.pg0.local_mac,
2311 src=self.pg0.remote_mac) /
2312 MPLS(label=55, ttl=64) /
2313 Ether(src="00:00:de:ad:ba:b1",
2314 dst="00:00:de:ad:be:ef") /
2315 IP(dst="10.10.10.10", src="11.11.11.11") /
2316 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002317 Raw(b'\xa5' * 100))
Neale Ranns1dbcf302019-07-19 11:44:53 +00002318 p_core2 = (Ether(dst=self.pg0.local_mac,
2319 src=self.pg0.remote_mac) /
2320 MPLS(label=56, ttl=64) /
Ole Troan770a0de2019-11-07 13:52:21 +01002321 Raw(b'\x01' * 4) / # PW CW
Neale Ranns1dbcf302019-07-19 11:44:53 +00002322 Ether(src="00:00:de:ad:ba:b2",
2323 dst="00:00:de:ad:be:ef") /
2324 IP(dst="10.10.10.10", src="11.11.11.12") /
2325 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002326 Raw(b'\xa5' * 100))
Neale Rannsda78f952017-05-24 09:15:43 -07002327
2328 #
2329 # The BD is learning, so send in one of each packet to learn
2330 #
Neale Rannsda78f952017-05-24 09:15:43 -07002331
Neale Ranns1dbcf302019-07-19 11:44:53 +00002332 # 2 packets due to BD flooding
2333 rx = self.send_and_expect(self.pg1, p_cust1, self.pg0, n_rx=2)
2334 rx = self.send_and_expect(self.pg1, p_cust2, self.pg0, n_rx=2)
Neale Rannsda78f952017-05-24 09:15:43 -07002335
Neale Ranns1dbcf302019-07-19 11:44:53 +00002336 # we've learnt this so expect it be be forwarded not flooded
2337 rx = self.send_and_expect(self.pg0, [p_core1], self.pg1)
2338 self.assertEqual(rx[0][Ether].dst, p_cust1[Ether].src)
2339 self.assertEqual(rx[0][Ether].src, p_cust1[Ether].dst)
Neale Rannsda78f952017-05-24 09:15:43 -07002340
Neale Ranns1dbcf302019-07-19 11:44:53 +00002341 rx = self.send_and_expect(self.pg0, [p_core2], self.pg1)
2342 self.assertEqual(rx[0][Ether].dst, p_cust2[Ether].src)
2343 self.assertEqual(rx[0][Ether].src, p_cust2[Ether].dst)
Neale Rannsda78f952017-05-24 09:15:43 -07002344
2345 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002346 # now a stream in each direction from each host
Neale Rannsda78f952017-05-24 09:15:43 -07002347 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002348 rx = self.send_and_expect(self.pg1, p_cust1 * NUM_PKTS, self.pg0)
2349 self.verify_capture_tunneled_ethernet(rx, p_cust1 * NUM_PKTS,
Neale Ranns31ed7442018-02-23 05:29:09 -08002350 [VppMplsLabel(42)])
Neale Rannsda78f952017-05-24 09:15:43 -07002351
Neale Ranns1dbcf302019-07-19 11:44:53 +00002352 rx = self.send_and_expect(self.pg1, p_cust2 * NUM_PKTS, self.pg0)
2353 self.verify_capture_tunneled_ethernet(rx, p_cust2 * NUM_PKTS,
2354 [VppMplsLabel(43)])
2355
2356 rx = self.send_and_expect(self.pg0, p_core1 * NUM_PKTS, self.pg1)
2357 rx = self.send_and_expect(self.pg0, p_core2 * NUM_PKTS, self.pg1)
2358
Neale Rannsda78f952017-05-24 09:15:43 -07002359 #
2360 # remove interfaces from customers bridge-domain
2361 #
Ole Troana5b2eec2019-03-11 19:23:25 +01002362 self.vapi.sw_interface_set_l2_bridge(
Neale Ranns1dbcf302019-07-19 11:44:53 +00002363 rx_sw_if_index=mpls_tun1.sw_if_index, bd_id=1, enable=0)
2364 self.vapi.sw_interface_set_l2_bridge(
2365 rx_sw_if_index=mpls_tun2.sw_if_index, bd_id=1, enable=0)
Ole Troana5b2eec2019-03-11 19:23:25 +01002366 self.vapi.sw_interface_set_l2_bridge(
2367 rx_sw_if_index=self.pg1.sw_if_index, bd_id=1, enable=0)
Neale Rannsda78f952017-05-24 09:15:43 -07002368
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002369
Neale Ranns8fe8cc22016-11-01 10:05:08 +00002370if __name__ == '__main__':
2371 unittest.main(testRunner=VppTestRunner)