blob: 32868c691577af88a6bbe9dbbac72a345e1d08fe [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
6from framework import VppTestCase, VppTestRunner
Neale Rannsd5d7b962019-08-04 03:30:56 -07007from vpp_ip import DpoProto, INVALID_INDEX
Neale Ranns5a8123b2017-01-26 01:18:23 -08008from vpp_ip_route import VppIpRoute, VppRoutePath, VppMplsRoute, \
Neale Ranns0f26c5a2017-03-01 15:12:11 -08009 VppMplsIpBind, VppIpMRoute, VppMRoutePath, \
Neale Rannsc0a93142018-09-05 15:42:26 -070010 MRouteItfFlags, MRouteEntryFlags, VppIpTable, VppMplsTable, \
Neale Ranns097fa662018-05-01 05:17:55 -070011 VppMplsLabel, MplsLspMode, find_mpls_route, \
12 FibPathProto, FibPathType, FibPathFlags, VppMplsLabel, MplsLspMode
Neale Ranns0f26c5a2017-03-01 15:12:11 -080013from vpp_mpls_tunnel_interface import VppMPLSTunnelInterface
Neale Ranns8fe8cc22016-11-01 10:05:08 +000014
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -070015import scapy.compat
Neale Ranns8fe8cc22016-11-01 10:05:08 +000016from scapy.packet import Raw
Neale Ranns1976f362019-11-06 13:13:01 +000017from scapy.layers.l2 import Ether, ARP
Neale Rannscb630ff2016-12-14 13:31:29 +010018from scapy.layers.inet import IP, UDP, ICMP
Neale Ranns62fe07c2017-10-31 12:28:22 -070019from scapy.layers.inet6 import IPv6, ICMPv6TimeExceeded
Neale Ranns8fe8cc22016-11-01 10:05:08 +000020from scapy.contrib.mpls import MPLS
21
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -040022NUM_PKTS = 67
23
Neale Ranns1976f362019-11-06 13:13:01 +000024# scapy removed these attributes.
25# we asked that they be restored: https://github.com/secdev/scapy/pull/1878
26# semantic names have more meaning than numbers. so here they are.
27ARP.who_has = 1
28ARP.is_at = 2
29
Klement Sekeradab231a2016-12-21 08:50:14 +010030
Neale Rannsda78f952017-05-24 09:15:43 -070031def verify_filter(capture, sent):
32 if not len(capture) == len(sent):
33 # filter out any IPv6 RAs from the capture
34 for p in capture:
35 if p.haslayer(IPv6):
36 capture.remove(p)
37 return capture
38
39
Neale Ranns31ed7442018-02-23 05:29:09 -080040def verify_mpls_stack(tst, rx, mpls_labels):
Neale Rannsda78f952017-05-24 09:15:43 -070041 # the rx'd packet has the MPLS label popped
42 eth = rx[Ether]
43 tst.assertEqual(eth.type, 0x8847)
44
45 rx_mpls = rx[MPLS]
46
47 for ii in range(len(mpls_labels)):
Neale Ranns31ed7442018-02-23 05:29:09 -080048 tst.assertEqual(rx_mpls.label, mpls_labels[ii].value)
49 tst.assertEqual(rx_mpls.cos, mpls_labels[ii].exp)
50 tst.assertEqual(rx_mpls.ttl, mpls_labels[ii].ttl)
51
Neale Rannsda78f952017-05-24 09:15:43 -070052 if ii == len(mpls_labels) - 1:
53 tst.assertEqual(rx_mpls.s, 1)
54 else:
55 # not end of stack
56 tst.assertEqual(rx_mpls.s, 0)
57 # pop the label to expose the next
58 rx_mpls = rx_mpls[MPLS].payload
59
60
Neale Ranns8fe8cc22016-11-01 10:05:08 +000061class TestMPLS(VppTestCase):
62 """ MPLS Test Case """
63
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -070064 @classmethod
65 def setUpClass(cls):
66 super(TestMPLS, cls).setUpClass()
67
68 @classmethod
69 def tearDownClass(cls):
70 super(TestMPLS, cls).tearDownClass()
71
Neale Ranns8fe8cc22016-11-01 10:05:08 +000072 def setUp(self):
73 super(TestMPLS, self).setUp()
74
75 # create 2 pg interfaces
Neale Ranns0f26c5a2017-03-01 15:12:11 -080076 self.create_pg_interfaces(range(4))
Neale Ranns8fe8cc22016-11-01 10:05:08 +000077
78 # setup both interfaces
79 # assign them different tables.
80 table_id = 0
Neale Ranns15002542017-09-10 04:39:11 -070081 self.tables = []
82
83 tbl = VppMplsTable(self, 0)
84 tbl.add_vpp_config()
85 self.tables.append(tbl)
Neale Ranns8fe8cc22016-11-01 10:05:08 +000086
87 for i in self.pg_interfaces:
88 i.admin_up()
Neale Ranns15002542017-09-10 04:39:11 -070089
90 if table_id != 0:
91 tbl = VppIpTable(self, table_id)
92 tbl.add_vpp_config()
93 self.tables.append(tbl)
94 tbl = VppIpTable(self, table_id, is_ip6=1)
95 tbl.add_vpp_config()
96 self.tables.append(tbl)
97
Neale Ranns8fe8cc22016-11-01 10:05:08 +000098 i.set_table_ip4(table_id)
99 i.set_table_ip6(table_id)
100 i.config_ip4()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000101 i.resolve_arp()
Neale Rannsad422ed2016-11-02 14:20:04 +0000102 i.config_ip6()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000103 i.resolve_ndp()
Neale Rannsad422ed2016-11-02 14:20:04 +0000104 i.enable_mpls()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000105 table_id += 1
106
107 def tearDown(self):
Neale Ranns4008ac92017-02-13 23:20:04 -0800108 for i in self.pg_interfaces:
109 i.unconfig_ip4()
110 i.unconfig_ip6()
111 i.ip6_disable()
Neale Ranns15002542017-09-10 04:39:11 -0700112 i.set_table_ip4(0)
113 i.set_table_ip6(0)
114 i.disable_mpls()
Neale Ranns4008ac92017-02-13 23:20:04 -0800115 i.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -0700116 super(TestMPLS, self).tearDown()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000117
Neale Rannsad422ed2016-11-02 14:20:04 +0000118 # the default of 64 matches the IP packet TTL default
Klement Sekeradab231a2016-12-21 08:50:14 +0100119 def create_stream_labelled_ip4(
120 self,
121 src_if,
122 mpls_labels,
Klement Sekeradab231a2016-12-21 08:50:14 +0100123 ping=0,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800124 ip_itf=None,
125 dst_ip=None,
Neale Ranns4c7c8e52017-10-21 09:37:55 -0700126 chksum=None,
Neale Ranns31ed7442018-02-23 05:29:09 -0800127 ip_ttl=64,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800128 n=257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100129 self.reset_packet_infos()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000130 pkts = []
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800131 for i in range(0, n):
Klement Sekeradab231a2016-12-21 08:50:14 +0100132 info = self.create_packet_info(src_if, src_if)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000133 payload = self.info_to_payload(info)
Neale Rannsad422ed2016-11-02 14:20:04 +0000134 p = Ether(dst=src_if.local_mac, src=src_if.remote_mac)
135
136 for ii in range(len(mpls_labels)):
Neale Ranns31ed7442018-02-23 05:29:09 -0800137 p = p / MPLS(label=mpls_labels[ii].value,
138 ttl=mpls_labels[ii].ttl,
139 cos=mpls_labels[ii].exp)
Neale Rannscb630ff2016-12-14 13:31:29 +0100140 if not ping:
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800141 if not dst_ip:
Neale Ranns31ed7442018-02-23 05:29:09 -0800142 p = (p / IP(src=src_if.local_ip4,
143 dst=src_if.remote_ip4,
144 ttl=ip_ttl) /
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800145 UDP(sport=1234, dport=1234) /
146 Raw(payload))
147 else:
Neale Ranns31ed7442018-02-23 05:29:09 -0800148 p = (p / IP(src=src_if.local_ip4, dst=dst_ip, ttl=ip_ttl) /
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800149 UDP(sport=1234, dport=1234) /
150 Raw(payload))
Neale Rannscb630ff2016-12-14 13:31:29 +0100151 else:
152 p = (p / IP(src=ip_itf.remote_ip4,
Neale Ranns31ed7442018-02-23 05:29:09 -0800153 dst=ip_itf.local_ip4,
154 ttl=ip_ttl) /
Neale Rannscb630ff2016-12-14 13:31:29 +0100155 ICMP())
156
Neale Ranns4c7c8e52017-10-21 09:37:55 -0700157 if chksum:
158 p[IP].chksum = chksum
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000159 info.data = p.copy()
160 pkts.append(p)
161 return pkts
162
Ole Troaneb284a12019-10-09 13:33:19 +0200163 def create_stream_ip4(self, src_if, dst_ip, ip_ttl=64,
164 ip_dscp=0, payload_size=None):
Klement Sekeradab231a2016-12-21 08:50:14 +0100165 self.reset_packet_infos()
Neale Rannsad422ed2016-11-02 14:20:04 +0000166 pkts = []
167 for i in range(0, 257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100168 info = self.create_packet_info(src_if, src_if)
Neale Rannsad422ed2016-11-02 14:20:04 +0000169 payload = self.info_to_payload(info)
170 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
Neale Ranns31ed7442018-02-23 05:29:09 -0800171 IP(src=src_if.remote_ip4, dst=dst_ip,
172 ttl=ip_ttl, tos=ip_dscp) /
Neale Rannsad422ed2016-11-02 14:20:04 +0000173 UDP(sport=1234, dport=1234) /
174 Raw(payload))
175 info.data = p.copy()
Ole Troaneb284a12019-10-09 13:33:19 +0200176 if payload_size:
177 self.extend_packet(p, payload_size)
Neale Rannsad422ed2016-11-02 14:20:04 +0000178 pkts.append(p)
179 return pkts
180
Neale Ranns31ed7442018-02-23 05:29:09 -0800181 def create_stream_ip6(self, src_if, dst_ip, ip_ttl=64, ip_dscp=0):
182 self.reset_packet_infos()
183 pkts = []
184 for i in range(0, 257):
185 info = self.create_packet_info(src_if, src_if)
186 payload = self.info_to_payload(info)
187 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
188 IPv6(src=src_if.remote_ip6, dst=dst_ip,
189 hlim=ip_ttl, tc=ip_dscp) /
190 UDP(sport=1234, dport=1234) /
191 Raw(payload))
192 info.data = p.copy()
193 pkts.append(p)
194 return pkts
195
196 def create_stream_labelled_ip6(self, src_if, mpls_labels,
197 hlim=64, dst_ip=None):
Neale Ranns31426c62017-05-24 10:32:58 -0700198 if dst_ip is None:
199 dst_ip = src_if.remote_ip6
Klement Sekeradab231a2016-12-21 08:50:14 +0100200 self.reset_packet_infos()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000201 pkts = []
202 for i in range(0, 257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100203 info = self.create_packet_info(src_if, src_if)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000204 payload = self.info_to_payload(info)
Neale Ranns31ed7442018-02-23 05:29:09 -0800205 p = Ether(dst=src_if.local_mac, src=src_if.remote_mac)
206 for l in mpls_labels:
207 p = p / MPLS(label=l.value, ttl=l.ttl, cos=l.exp)
208
209 p = p / (IPv6(src=src_if.remote_ip6, dst=dst_ip, hlim=hlim) /
210 UDP(sport=1234, dport=1234) /
211 Raw(payload))
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000212 info.data = p.copy()
213 pkts.append(p)
214 return pkts
215
Neale Ranns31ed7442018-02-23 05:29:09 -0800216 def verify_capture_ip4(self, src_if, capture, sent, ping_resp=0,
217 ip_ttl=None, ip_dscp=0):
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000218 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700219 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000220
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000221 self.assertEqual(len(capture), len(sent))
222
223 for i in range(len(capture)):
224 tx = sent[i]
225 rx = capture[i]
226
227 # the rx'd packet has the MPLS label popped
Neale Rannsad422ed2016-11-02 14:20:04 +0000228 eth = rx[Ether]
229 self.assertEqual(eth.type, 0x800)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000230
231 tx_ip = tx[IP]
232 rx_ip = rx[IP]
233
Neale Rannscb630ff2016-12-14 13:31:29 +0100234 if not ping_resp:
235 self.assertEqual(rx_ip.src, tx_ip.src)
236 self.assertEqual(rx_ip.dst, tx_ip.dst)
Neale Ranns31ed7442018-02-23 05:29:09 -0800237 self.assertEqual(rx_ip.tos, ip_dscp)
238 if not ip_ttl:
239 # IP processing post pop has decremented the TTL
240 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
241 else:
242 self.assertEqual(rx_ip.ttl, ip_ttl)
Neale Rannscb630ff2016-12-14 13:31:29 +0100243 else:
244 self.assertEqual(rx_ip.src, tx_ip.dst)
245 self.assertEqual(rx_ip.dst, tx_ip.src)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000246
247 except:
Neale Rannsad422ed2016-11-02 14:20:04 +0000248 raise
249
Neale Rannsad422ed2016-11-02 14:20:04 +0000250 def verify_capture_labelled_ip4(self, src_if, capture, sent,
Neale Ranns31ed7442018-02-23 05:29:09 -0800251 mpls_labels, ip_ttl=None):
Neale Rannsad422ed2016-11-02 14:20:04 +0000252 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700253 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000254
255 self.assertEqual(len(capture), len(sent))
256
257 for i in range(len(capture)):
258 tx = sent[i]
259 rx = capture[i]
260 tx_ip = tx[IP]
261 rx_ip = rx[IP]
262
Neale Ranns31ed7442018-02-23 05:29:09 -0800263 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsad422ed2016-11-02 14:20:04 +0000264
265 self.assertEqual(rx_ip.src, tx_ip.src)
266 self.assertEqual(rx_ip.dst, tx_ip.dst)
Neale Ranns31ed7442018-02-23 05:29:09 -0800267 if not ip_ttl:
268 # IP processing post pop has decremented the TTL
269 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
270 else:
271 self.assertEqual(rx_ip.ttl, ip_ttl)
Neale Rannsad422ed2016-11-02 14:20:04 +0000272
273 except:
274 raise
275
Neale Ranns31ed7442018-02-23 05:29:09 -0800276 def verify_capture_labelled_ip6(self, src_if, capture, sent,
277 mpls_labels, ip_ttl=None):
278 try:
279 capture = verify_filter(capture, sent)
280
281 self.assertEqual(len(capture), len(sent))
282
283 for i in range(len(capture)):
284 tx = sent[i]
285 rx = capture[i]
286 tx_ip = tx[IPv6]
287 rx_ip = rx[IPv6]
288
289 verify_mpls_stack(self, rx, mpls_labels)
290
291 self.assertEqual(rx_ip.src, tx_ip.src)
292 self.assertEqual(rx_ip.dst, tx_ip.dst)
293 if not ip_ttl:
294 # IP processing post pop has decremented the TTL
295 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
296 else:
297 self.assertEqual(rx_ip.hlim, ip_ttl)
298
299 except:
300 raise
301
302 def verify_capture_tunneled_ip4(self, src_if, capture, sent, mpls_labels):
Neale Rannsad422ed2016-11-02 14:20:04 +0000303 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700304 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000305
306 self.assertEqual(len(capture), len(sent))
307
308 for i in range(len(capture)):
309 tx = sent[i]
310 rx = capture[i]
311 tx_ip = tx[IP]
312 rx_ip = rx[IP]
313
Neale Ranns31ed7442018-02-23 05:29:09 -0800314 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsad422ed2016-11-02 14:20:04 +0000315
316 self.assertEqual(rx_ip.src, tx_ip.src)
317 self.assertEqual(rx_ip.dst, tx_ip.dst)
318 # IP processing post pop has decremented the TTL
319 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
320
321 except:
322 raise
323
324 def verify_capture_labelled(self, src_if, capture, sent,
Neale Ranns31ed7442018-02-23 05:29:09 -0800325 mpls_labels):
Neale Rannsad422ed2016-11-02 14:20:04 +0000326 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700327 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000328
329 self.assertEqual(len(capture), len(sent))
330
331 for i in range(len(capture)):
332 rx = capture[i]
Neale Ranns31ed7442018-02-23 05:29:09 -0800333 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsad422ed2016-11-02 14:20:04 +0000334 except:
335 raise
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000336
Neale Ranns31ed7442018-02-23 05:29:09 -0800337 def verify_capture_ip6(self, src_if, capture, sent,
338 ip_hlim=None, ip_dscp=0):
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000339 try:
340 self.assertEqual(len(capture), len(sent))
341
342 for i in range(len(capture)):
343 tx = sent[i]
344 rx = capture[i]
345
346 # the rx'd packet has the MPLS label popped
Neale Rannsad422ed2016-11-02 14:20:04 +0000347 eth = rx[Ether]
348 self.assertEqual(eth.type, 0x86DD)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000349
350 tx_ip = tx[IPv6]
351 rx_ip = rx[IPv6]
352
353 self.assertEqual(rx_ip.src, tx_ip.src)
354 self.assertEqual(rx_ip.dst, tx_ip.dst)
Neale Ranns31ed7442018-02-23 05:29:09 -0800355 self.assertEqual(rx_ip.tc, ip_dscp)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000356 # IP processing post pop has decremented the TTL
Neale Ranns31ed7442018-02-23 05:29:09 -0800357 if not ip_hlim:
358 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
359 else:
360 self.assertEqual(rx_ip.hlim, ip_hlim)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000361
362 except:
Neale Rannsad422ed2016-11-02 14:20:04 +0000363 raise
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000364
Neale Ranns62fe07c2017-10-31 12:28:22 -0700365 def verify_capture_ip6_icmp(self, src_if, capture, sent):
366 try:
367 self.assertEqual(len(capture), len(sent))
368
369 for i in range(len(capture)):
370 tx = sent[i]
371 rx = capture[i]
372
373 # the rx'd packet has the MPLS label popped
374 eth = rx[Ether]
375 self.assertEqual(eth.type, 0x86DD)
376
377 tx_ip = tx[IPv6]
378 rx_ip = rx[IPv6]
379
380 self.assertEqual(rx_ip.dst, tx_ip.src)
381 # ICMP sourced from the interface's address
382 self.assertEqual(rx_ip.src, src_if.local_ip6)
383 # hop-limit reset to 255 for IMCP packet
Ole Troan282093f2018-09-19 12:38:51 +0200384 self.assertEqual(rx_ip.hlim, 255)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700385
386 icmp = rx[ICMPv6TimeExceeded]
387
388 except:
389 raise
390
Rajesh Goeld6f1c9c2019-10-06 13:17:36 +0530391 def verify_capture_fragmented_labelled_ip4(self, src_if, capture, sent,
392 mpls_labels, ip_ttl=None):
393 try:
394 capture = verify_filter(capture, sent)
395
396 for i in range(len(capture)):
397 tx = sent[0]
398 rx = capture[i]
399 tx_ip = tx[IP]
400 rx_ip = rx[IP]
401
402 verify_mpls_stack(self, rx, mpls_labels)
403
404 self.assertEqual(rx_ip.src, tx_ip.src)
405 self.assertEqual(rx_ip.dst, tx_ip.dst)
406 if not ip_ttl:
407 # IP processing post pop has decremented the TTL
408 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
409 else:
410 self.assertEqual(rx_ip.ttl, ip_ttl)
411
412 except:
413 raise
414
Neale Rannsad422ed2016-11-02 14:20:04 +0000415 def test_swap(self):
416 """ MPLS label swap tests """
417
418 #
419 # A simple MPLS xconnect - eos label in label out
420 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800421 route_32_eos = VppMplsRoute(self, 32, 1,
422 [VppRoutePath(self.pg0.remote_ip4,
423 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800424 labels=[VppMplsLabel(33)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000425 route_32_eos.add_vpp_config()
426
Neale Ranns775f73c2018-12-20 03:01:49 -0800427 self.assertTrue(
428 find_mpls_route(self, 0, 32, 1,
429 [VppRoutePath(self.pg0.remote_ip4,
430 self.pg0.sw_if_index,
431 labels=[VppMplsLabel(33)])]))
432
Neale Rannsad422ed2016-11-02 14:20:04 +0000433 #
434 # a stream that matches the route for 10.0.0.1
435 # PG0 is in the default table
436 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800437 tx = self.create_stream_labelled_ip4(self.pg0,
438 [VppMplsLabel(32, ttl=32, exp=1)])
439 rx = self.send_and_expect(self.pg0, tx, self.pg0)
440 self.verify_capture_labelled(self.pg0, rx, tx,
441 [VppMplsLabel(33, ttl=31, exp=1)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000442
Neale Ranns008dbe12018-09-07 09:32:36 -0700443 self.assertEqual(route_32_eos.get_stats_to()['packets'], 257)
444
Neale Rannsad422ed2016-11-02 14:20:04 +0000445 #
446 # A simple MPLS xconnect - non-eos label in label out
447 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800448 route_32_neos = VppMplsRoute(self, 32, 0,
449 [VppRoutePath(self.pg0.remote_ip4,
450 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800451 labels=[VppMplsLabel(33)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000452 route_32_neos.add_vpp_config()
453
454 #
455 # a stream that matches the route for 10.0.0.1
456 # PG0 is in the default table
457 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800458 tx = self.create_stream_labelled_ip4(self.pg0,
459 [VppMplsLabel(32, ttl=21, exp=7),
460 VppMplsLabel(99)])
461 rx = self.send_and_expect(self.pg0, tx, self.pg0)
462 self.verify_capture_labelled(self.pg0, rx, tx,
463 [VppMplsLabel(33, ttl=20, exp=7),
464 VppMplsLabel(99)])
Neale Ranns008dbe12018-09-07 09:32:36 -0700465 self.assertEqual(route_32_neos.get_stats_to()['packets'], 257)
Neale Rannsad422ed2016-11-02 14:20:04 +0000466
Neale Ranns31ed7442018-02-23 05:29:09 -0800467 #
468 # A simple MPLS xconnect - non-eos label in label out, uniform mode
469 #
470 route_42_neos = VppMplsRoute(
471 self, 42, 0,
472 [VppRoutePath(self.pg0.remote_ip4,
473 self.pg0.sw_if_index,
474 labels=[VppMplsLabel(43, MplsLspMode.UNIFORM)])])
475 route_42_neos.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000476
Neale Ranns31ed7442018-02-23 05:29:09 -0800477 tx = self.create_stream_labelled_ip4(self.pg0,
478 [VppMplsLabel(42, ttl=21, exp=7),
479 VppMplsLabel(99)])
480 rx = self.send_and_expect(self.pg0, tx, self.pg0)
481 self.verify_capture_labelled(self.pg0, rx, tx,
482 [VppMplsLabel(43, ttl=20, exp=7),
483 VppMplsLabel(99)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000484
485 #
486 # An MPLS xconnect - EOS label in IP out
487 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800488 route_33_eos = VppMplsRoute(self, 33, 1,
489 [VppRoutePath(self.pg0.remote_ip4,
490 self.pg0.sw_if_index,
491 labels=[])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000492 route_33_eos.add_vpp_config()
493
Neale Ranns31ed7442018-02-23 05:29:09 -0800494 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(33)])
495 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Rannsad422ed2016-11-02 14:20:04 +0000496 self.verify_capture_ip4(self.pg0, rx, tx)
497
498 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700499 # disposed packets have an invalid IPv4 checksum
Neale Ranns62fe07c2017-10-31 12:28:22 -0700500 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800501 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(33)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700502 dst_ip=self.pg0.remote_ip4,
503 n=65,
504 chksum=1)
505 self.send_and_assert_no_replies(self.pg0, tx, "Invalid Checksum")
506
507 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800508 # An MPLS xconnect - EOS label in IP out, uniform mode
509 #
510 route_3333_eos = VppMplsRoute(
511 self, 3333, 1,
512 [VppRoutePath(self.pg0.remote_ip4,
513 self.pg0.sw_if_index,
514 labels=[VppMplsLabel(3, MplsLspMode.UNIFORM)])])
515 route_3333_eos.add_vpp_config()
516
517 tx = self.create_stream_labelled_ip4(
518 self.pg0,
519 [VppMplsLabel(3333, ttl=55, exp=3)])
520 rx = self.send_and_expect(self.pg0, tx, self.pg0)
521 self.verify_capture_ip4(self.pg0, rx, tx, ip_ttl=54, ip_dscp=0x60)
522 tx = self.create_stream_labelled_ip4(
523 self.pg0,
524 [VppMplsLabel(3333, ttl=66, exp=4)])
525 rx = self.send_and_expect(self.pg0, tx, self.pg0)
526 self.verify_capture_ip4(self.pg0, rx, tx, ip_ttl=65, ip_dscp=0x80)
527
528 #
Neale Ranns62fe07c2017-10-31 12:28:22 -0700529 # An MPLS xconnect - EOS label in IPv6 out
530 #
531 route_333_eos = VppMplsRoute(
532 self, 333, 1,
533 [VppRoutePath(self.pg0.remote_ip6,
534 self.pg0.sw_if_index,
Neale Ranns097fa662018-05-01 05:17:55 -0700535 labels=[])],
536 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700537 route_333_eos.add_vpp_config()
538
Neale Ranns31ed7442018-02-23 05:29:09 -0800539 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(333)])
540 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700541 self.verify_capture_ip6(self.pg0, rx, tx)
542
543 #
544 # disposed packets have an TTL expired
545 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800546 tx = self.create_stream_labelled_ip6(self.pg0,
547 [VppMplsLabel(333, ttl=64)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700548 dst_ip=self.pg1.remote_ip6,
549 hlim=1)
Neale Ranns31ed7442018-02-23 05:29:09 -0800550 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700551 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
552
553 #
554 # An MPLS xconnect - EOS label in IPv6 out w imp-null
555 #
556 route_334_eos = VppMplsRoute(
557 self, 334, 1,
558 [VppRoutePath(self.pg0.remote_ip6,
559 self.pg0.sw_if_index,
Neale Ranns097fa662018-05-01 05:17:55 -0700560 labels=[VppMplsLabel(3)])],
561 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700562 route_334_eos.add_vpp_config()
563
Neale Ranns31ed7442018-02-23 05:29:09 -0800564 tx = self.create_stream_labelled_ip6(self.pg0,
565 [VppMplsLabel(334, ttl=64)])
566 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700567 self.verify_capture_ip6(self.pg0, rx, tx)
568
569 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800570 # An MPLS xconnect - EOS label in IPv6 out w imp-null in uniform mode
571 #
572 route_335_eos = VppMplsRoute(
573 self, 335, 1,
574 [VppRoutePath(self.pg0.remote_ip6,
575 self.pg0.sw_if_index,
Neale Ranns097fa662018-05-01 05:17:55 -0700576 labels=[VppMplsLabel(3, MplsLspMode.UNIFORM)])],
577 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)
Neale Ranns31ed7442018-02-23 05:29:09 -0800578 route_335_eos.add_vpp_config()
579
580 tx = self.create_stream_labelled_ip6(
581 self.pg0,
582 [VppMplsLabel(335, ttl=27, exp=4)])
583 rx = self.send_and_expect(self.pg0, tx, self.pg0)
584 self.verify_capture_ip6(self.pg0, rx, tx, ip_hlim=26, ip_dscp=0x80)
585
586 #
Neale Ranns62fe07c2017-10-31 12:28:22 -0700587 # disposed packets have an TTL expired
588 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800589 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(334)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700590 dst_ip=self.pg1.remote_ip6,
591 hlim=0)
Neale Ranns31ed7442018-02-23 05:29:09 -0800592 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700593 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
594
595 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000596 # An MPLS xconnect - non-EOS label in IP out - an invalid configuration
597 # so this traffic should be dropped.
598 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800599 route_33_neos = VppMplsRoute(self, 33, 0,
600 [VppRoutePath(self.pg0.remote_ip4,
601 self.pg0.sw_if_index,
602 labels=[])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000603 route_33_neos.add_vpp_config()
604
Neale Ranns31ed7442018-02-23 05:29:09 -0800605 tx = self.create_stream_labelled_ip4(self.pg0,
606 [VppMplsLabel(33),
607 VppMplsLabel(99)])
608 self.send_and_assert_no_replies(
609 self.pg0, tx,
610 "MPLS non-EOS packets popped and forwarded")
Neale Rannsad422ed2016-11-02 14:20:04 +0000611
612 #
613 # A recursive EOS x-connect, which resolves through another x-connect
Neale Ranns31ed7442018-02-23 05:29:09 -0800614 # in pipe mode
Neale Rannsad422ed2016-11-02 14:20:04 +0000615 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800616 route_34_eos = VppMplsRoute(self, 34, 1,
617 [VppRoutePath("0.0.0.0",
618 0xffffffff,
619 nh_via_label=32,
Neale Ranns31ed7442018-02-23 05:29:09 -0800620 labels=[VppMplsLabel(44),
621 VppMplsLabel(45)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000622 route_34_eos.add_vpp_config()
Neale Ranns097fa662018-05-01 05:17:55 -0700623 self.logger.info(self.vapi.cli("sh mpls fib 34"))
Neale Rannsad422ed2016-11-02 14:20:04 +0000624
Neale Ranns31ed7442018-02-23 05:29:09 -0800625 tx = self.create_stream_labelled_ip4(self.pg0,
626 [VppMplsLabel(34, ttl=3)])
627 rx = self.send_and_expect(self.pg0, tx, self.pg0)
628 self.verify_capture_labelled(self.pg0, rx, tx,
629 [VppMplsLabel(33),
630 VppMplsLabel(44),
631 VppMplsLabel(45, ttl=2)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000632
Neale Ranns008dbe12018-09-07 09:32:36 -0700633 self.assertEqual(route_34_eos.get_stats_to()['packets'], 257)
634 self.assertEqual(route_32_neos.get_stats_via()['packets'], 257)
635
Neale Ranns31ed7442018-02-23 05:29:09 -0800636 #
637 # A recursive EOS x-connect, which resolves through another x-connect
638 # in uniform mode
639 #
640 route_35_eos = VppMplsRoute(
641 self, 35, 1,
642 [VppRoutePath("0.0.0.0",
643 0xffffffff,
644 nh_via_label=42,
645 labels=[VppMplsLabel(44)])])
646 route_35_eos.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000647
Neale Ranns31ed7442018-02-23 05:29:09 -0800648 tx = self.create_stream_labelled_ip4(self.pg0,
649 [VppMplsLabel(35, ttl=3)])
650 rx = self.send_and_expect(self.pg0, tx, self.pg0)
651 self.verify_capture_labelled(self.pg0, rx, tx,
652 [VppMplsLabel(43, ttl=2),
653 VppMplsLabel(44, ttl=2)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000654
655 #
Matej Klottondeb69842016-12-09 15:05:46 +0100656 # A recursive non-EOS x-connect, which resolves through another
657 # x-connect
Neale Rannsad422ed2016-11-02 14:20:04 +0000658 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800659 route_34_neos = VppMplsRoute(self, 34, 0,
660 [VppRoutePath("0.0.0.0",
661 0xffffffff,
662 nh_via_label=32,
Neale Ranns31ed7442018-02-23 05:29:09 -0800663 labels=[VppMplsLabel(44),
664 VppMplsLabel(46)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000665 route_34_neos.add_vpp_config()
666
Neale Ranns31ed7442018-02-23 05:29:09 -0800667 tx = self.create_stream_labelled_ip4(self.pg0,
668 [VppMplsLabel(34, ttl=45),
669 VppMplsLabel(99)])
670 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Matej Klottondeb69842016-12-09 15:05:46 +0100671 # it's the 2nd (counting from 0) label in the stack that is swapped
Neale Ranns31ed7442018-02-23 05:29:09 -0800672 self.verify_capture_labelled(self.pg0, rx, tx,
673 [VppMplsLabel(33),
674 VppMplsLabel(44),
675 VppMplsLabel(46, ttl=44),
676 VppMplsLabel(99)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000677
678 #
Matej Klottondeb69842016-12-09 15:05:46 +0100679 # an recursive IP route that resolves through the recursive non-eos
680 # x-connect
Neale Rannsad422ed2016-11-02 14:20:04 +0000681 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800682 ip_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
683 [VppRoutePath("0.0.0.0",
684 0xffffffff,
685 nh_via_label=34,
Neale Ranns31ed7442018-02-23 05:29:09 -0800686 labels=[VppMplsLabel(55)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000687 ip_10_0_0_1.add_vpp_config()
688
Neale Rannsad422ed2016-11-02 14:20:04 +0000689 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800690 rx = self.send_and_expect(self.pg0, tx, self.pg0)
691 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
692 [VppMplsLabel(33),
693 VppMplsLabel(44),
694 VppMplsLabel(46),
695 VppMplsLabel(55)])
Neale Ranns008dbe12018-09-07 09:32:36 -0700696 self.assertEqual(ip_10_0_0_1.get_stats_to()['packets'], 257)
Neale Rannsad422ed2016-11-02 14:20:04 +0000697
698 ip_10_0_0_1.remove_vpp_config()
699 route_34_neos.remove_vpp_config()
700 route_34_eos.remove_vpp_config()
701 route_33_neos.remove_vpp_config()
702 route_33_eos.remove_vpp_config()
703 route_32_neos.remove_vpp_config()
704 route_32_eos.remove_vpp_config()
705
706 def test_bind(self):
707 """ MPLS Local Label Binding test """
708
709 #
710 # Add a non-recursive route with a single out label
711 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800712 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
713 [VppRoutePath(self.pg0.remote_ip4,
714 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800715 labels=[VppMplsLabel(45)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000716 route_10_0_0_1.add_vpp_config()
717
718 # bind a local label to the route
Neale Ranns5a8123b2017-01-26 01:18:23 -0800719 binding = VppMplsIpBind(self, 44, "10.0.0.1", 32)
Neale Rannsad422ed2016-11-02 14:20:04 +0000720 binding.add_vpp_config()
721
722 # non-EOS stream
Neale Ranns31ed7442018-02-23 05:29:09 -0800723 tx = self.create_stream_labelled_ip4(self.pg0,
724 [VppMplsLabel(44),
725 VppMplsLabel(99)])
726 rx = self.send_and_expect(self.pg0, tx, self.pg0)
727 self.verify_capture_labelled(self.pg0, rx, tx,
728 [VppMplsLabel(45, ttl=63),
729 VppMplsLabel(99)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000730
731 # EOS stream
Neale Ranns31ed7442018-02-23 05:29:09 -0800732 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(44)])
733 rx = self.send_and_expect(self.pg0, tx, self.pg0)
734 self.verify_capture_labelled(self.pg0, rx, tx,
735 [VppMplsLabel(45, ttl=63)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000736
737 # IP stream
Neale Rannsad422ed2016-11-02 14:20:04 +0000738 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800739 rx = self.send_and_expect(self.pg0, tx, self.pg0)
740 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [VppMplsLabel(45)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000741
742 #
743 # cleanup
744 #
745 binding.remove_vpp_config()
746 route_10_0_0_1.remove_vpp_config()
747
748 def test_imposition(self):
749 """ MPLS label imposition test """
750
751 #
752 # Add a non-recursive route with a single out label
753 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800754 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
755 [VppRoutePath(self.pg0.remote_ip4,
756 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800757 labels=[VppMplsLabel(32)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000758 route_10_0_0_1.add_vpp_config()
759
760 #
761 # a stream that matches the route for 10.0.0.1
762 # PG0 is in the default table
763 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000764 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800765 rx = self.send_and_expect(self.pg0, tx, self.pg0)
766 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [VppMplsLabel(32)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000767
768 #
769 # Add a non-recursive route with a 3 out labels
770 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800771 route_10_0_0_2 = VppIpRoute(self, "10.0.0.2", 32,
772 [VppRoutePath(self.pg0.remote_ip4,
773 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800774 labels=[VppMplsLabel(32),
775 VppMplsLabel(33),
776 VppMplsLabel(34)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000777 route_10_0_0_2.add_vpp_config()
778
Neale Ranns31ed7442018-02-23 05:29:09 -0800779 tx = self.create_stream_ip4(self.pg0, "10.0.0.2",
780 ip_ttl=44, ip_dscp=0xff)
781 rx = self.send_and_expect(self.pg0, tx, self.pg0)
782 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
783 [VppMplsLabel(32),
784 VppMplsLabel(33),
785 VppMplsLabel(34)],
786 ip_ttl=43)
Neale Rannsad422ed2016-11-02 14:20:04 +0000787
Neale Ranns31ed7442018-02-23 05:29:09 -0800788 #
789 # Add a non-recursive route with a single out label in uniform mode
790 #
791 route_10_0_0_3 = VppIpRoute(
792 self, "10.0.0.3", 32,
793 [VppRoutePath(self.pg0.remote_ip4,
794 self.pg0.sw_if_index,
795 labels=[VppMplsLabel(32,
796 mode=MplsLspMode.UNIFORM)])])
797 route_10_0_0_3.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000798
Neale Ranns31ed7442018-02-23 05:29:09 -0800799 tx = self.create_stream_ip4(self.pg0, "10.0.0.3",
800 ip_ttl=54, ip_dscp=0xbe)
801 rx = self.send_and_expect(self.pg0, tx, self.pg0)
802 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
803 [VppMplsLabel(32, ttl=53, exp=5)])
804
805 #
806 # Add a IPv6 non-recursive route with a single out label in
807 # uniform mode
808 #
809 route_2001_3 = VppIpRoute(
810 self, "2001::3", 128,
811 [VppRoutePath(self.pg0.remote_ip6,
812 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800813 labels=[VppMplsLabel(32,
Neale Ranns097fa662018-05-01 05:17:55 -0700814 mode=MplsLspMode.UNIFORM)])])
Neale Ranns31ed7442018-02-23 05:29:09 -0800815 route_2001_3.add_vpp_config()
816
817 tx = self.create_stream_ip6(self.pg0, "2001::3",
818 ip_ttl=54, ip_dscp=0xbe)
819 rx = self.send_and_expect(self.pg0, tx, self.pg0)
820 self.verify_capture_labelled_ip6(self.pg0, rx, tx,
821 [VppMplsLabel(32, ttl=53, exp=5)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000822
823 #
Matej Klottondeb69842016-12-09 15:05:46 +0100824 # add a recursive path, with output label, via the 1 label route
Neale Rannsad422ed2016-11-02 14:20:04 +0000825 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800826 route_11_0_0_1 = VppIpRoute(self, "11.0.0.1", 32,
827 [VppRoutePath("10.0.0.1",
828 0xffffffff,
Neale Ranns31ed7442018-02-23 05:29:09 -0800829 labels=[VppMplsLabel(44)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000830 route_11_0_0_1.add_vpp_config()
831
832 #
833 # a stream that matches the route for 11.0.0.1, should pick up
834 # the label stack for 11.0.0.1 and 10.0.0.1
835 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000836 tx = self.create_stream_ip4(self.pg0, "11.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800837 rx = self.send_and_expect(self.pg0, tx, self.pg0)
838 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
839 [VppMplsLabel(32),
840 VppMplsLabel(44)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000841
Neale Ranns008dbe12018-09-07 09:32:36 -0700842 self.assertEqual(route_11_0_0_1.get_stats_to()['packets'], 257)
843
Neale Rannsad422ed2016-11-02 14:20:04 +0000844 #
845 # add a recursive path, with 2 labels, via the 3 label route
846 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800847 route_11_0_0_2 = VppIpRoute(self, "11.0.0.2", 32,
848 [VppRoutePath("10.0.0.2",
849 0xffffffff,
Neale Ranns31ed7442018-02-23 05:29:09 -0800850 labels=[VppMplsLabel(44),
851 VppMplsLabel(45)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000852 route_11_0_0_2.add_vpp_config()
853
854 #
855 # a stream that matches the route for 11.0.0.1, should pick up
856 # the label stack for 11.0.0.1 and 10.0.0.1
857 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000858 tx = self.create_stream_ip4(self.pg0, "11.0.0.2")
Neale Ranns31ed7442018-02-23 05:29:09 -0800859 rx = self.send_and_expect(self.pg0, tx, self.pg0)
860 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
861 [VppMplsLabel(32),
862 VppMplsLabel(33),
863 VppMplsLabel(34),
864 VppMplsLabel(44),
865 VppMplsLabel(45)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000866
Neale Ranns008dbe12018-09-07 09:32:36 -0700867 self.assertEqual(route_11_0_0_2.get_stats_to()['packets'], 257)
868
869 rx = self.send_and_expect(self.pg0, tx, self.pg0)
870 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
871 [VppMplsLabel(32),
872 VppMplsLabel(33),
873 VppMplsLabel(34),
874 VppMplsLabel(44),
875 VppMplsLabel(45)])
876
877 self.assertEqual(route_11_0_0_2.get_stats_to()['packets'], 514)
878
Neale Rannsad422ed2016-11-02 14:20:04 +0000879 #
880 # cleanup
881 #
882 route_11_0_0_2.remove_vpp_config()
883 route_11_0_0_1.remove_vpp_config()
884 route_10_0_0_2.remove_vpp_config()
885 route_10_0_0_1.remove_vpp_config()
886
Rajesh Goeld6f1c9c2019-10-06 13:17:36 +0530887 def test_imposition_fragmentation(self):
888 """ MPLS label imposition fragmentation test """
889
890 #
891 # Add a ipv4 non-recursive route with a single out label
892 #
893 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
894 [VppRoutePath(self.pg0.remote_ip4,
895 self.pg0.sw_if_index,
896 labels=[VppMplsLabel(32)])])
897 route_10_0_0_1.add_vpp_config()
898
899 #
900 # a stream that matches the route for 10.0.0.1
901 # PG0 is in the default table
902 #
903 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
904 for i in range(0, 257):
905 self.extend_packet(tx[i], 10000)
906
907 #
908 # 5 fragments per packet (257*5=1285)
909 #
910 rx = self.send_and_expect(self.pg0, tx, self.pg0, 1285)
911 self.verify_capture_fragmented_labelled_ip4(self.pg0, rx, tx,
912 [VppMplsLabel(32)])
913
914 #
915 # cleanup
916 #
917 route_10_0_0_1.remove_vpp_config()
918
Neale Ranns31ed7442018-02-23 05:29:09 -0800919 def test_tunnel_pipe(self):
920 """ MPLS Tunnel Tests - Pipe """
Neale Rannsad422ed2016-11-02 14:20:04 +0000921
922 #
Ole Troaneb284a12019-10-09 13:33:19 +0200923 # Create a tunnel with two out labels
Neale Rannsad422ed2016-11-02 14:20:04 +0000924 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800925 mpls_tun = VppMPLSTunnelInterface(
926 self,
927 [VppRoutePath(self.pg0.remote_ip4,
928 self.pg0.sw_if_index,
929 labels=[VppMplsLabel(44),
930 VppMplsLabel(46)])])
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800931 mpls_tun.add_vpp_config()
932 mpls_tun.admin_up()
Neale Rannsad422ed2016-11-02 14:20:04 +0000933
934 #
935 # add an unlabelled route through the new tunnel
936 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800937 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
938 [VppRoutePath("0.0.0.0",
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800939 mpls_tun._sw_if_index)])
Neale Ranns5a8123b2017-01-26 01:18:23 -0800940 route_10_0_0_3.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000941
942 self.vapi.cli("clear trace")
943 tx = self.create_stream_ip4(self.pg0, "10.0.0.3")
944 self.pg0.add_stream(tx)
945
946 self.pg_enable_capture(self.pg_interfaces)
947 self.pg_start()
948
949 rx = self.pg0.get_capture()
Neale Ranns31ed7442018-02-23 05:29:09 -0800950 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
951 [VppMplsLabel(44),
952 VppMplsLabel(46)])
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000953
Neale Ranns8c4611b2017-05-23 03:43:47 -0700954 #
955 # add a labelled route through the new tunnel
956 #
957 route_10_0_0_4 = VppIpRoute(self, "10.0.0.4", 32,
958 [VppRoutePath("0.0.0.0",
959 mpls_tun._sw_if_index,
960 labels=[33])])
961 route_10_0_0_4.add_vpp_config()
962
963 self.vapi.cli("clear trace")
964 tx = self.create_stream_ip4(self.pg0, "10.0.0.4")
965 self.pg0.add_stream(tx)
966
967 self.pg_enable_capture(self.pg_interfaces)
968 self.pg_start()
969
970 rx = self.pg0.get_capture()
Neale Ranns31ed7442018-02-23 05:29:09 -0800971 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
972 [VppMplsLabel(44),
973 VppMplsLabel(46),
974 VppMplsLabel(33, ttl=255)])
975
Ole Troaneb284a12019-10-09 13:33:19 +0200976 #
977 # change tunnel's MTU to a low value
978 #
979 mpls_tun.set_l3_mtu(1200)
980
981 # send IP into the tunnel to be fragmented
982 tx = self.create_stream_ip4(self.pg0, "10.0.0.3",
983 payload_size=1500)
984 rx = self.send_and_expect(self.pg0, tx, self.pg0, len(tx)*2)
985
986 fake_tx = []
987 for p in tx:
988 fake_tx.append(p)
989 fake_tx.append(p)
990 self.verify_capture_tunneled_ip4(self.pg0, rx, fake_tx,
991 [VppMplsLabel(44),
992 VppMplsLabel(46)])
993
994 # send MPLS into the tunnel to be fragmented
995 tx = self.create_stream_ip4(self.pg0, "10.0.0.4",
996 payload_size=1500)
997 rx = self.send_and_expect(self.pg0, tx, self.pg0, len(tx)*2)
998
999 fake_tx = []
1000 for p in tx:
1001 fake_tx.append(p)
1002 fake_tx.append(p)
1003 self.verify_capture_tunneled_ip4(self.pg0, rx, fake_tx,
1004 [VppMplsLabel(44),
1005 VppMplsLabel(46),
1006 VppMplsLabel(33, ttl=255)])
1007
Neale Ranns31ed7442018-02-23 05:29:09 -08001008 def test_tunnel_uniform(self):
1009 """ MPLS Tunnel Tests - Uniform """
1010
1011 #
1012 # Create a tunnel with a single out label
1013 # The label stack is specified here from outer to inner
1014 #
1015 mpls_tun = VppMPLSTunnelInterface(
1016 self,
1017 [VppRoutePath(self.pg0.remote_ip4,
1018 self.pg0.sw_if_index,
1019 labels=[VppMplsLabel(44, ttl=32),
1020 VppMplsLabel(46, MplsLspMode.UNIFORM)])])
1021 mpls_tun.add_vpp_config()
1022 mpls_tun.admin_up()
1023
1024 #
1025 # add an unlabelled route through the new tunnel
1026 #
1027 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
1028 [VppRoutePath("0.0.0.0",
1029 mpls_tun._sw_if_index)])
1030 route_10_0_0_3.add_vpp_config()
1031
1032 self.vapi.cli("clear trace")
1033 tx = self.create_stream_ip4(self.pg0, "10.0.0.3", ip_ttl=24)
1034 self.pg0.add_stream(tx)
1035
1036 self.pg_enable_capture(self.pg_interfaces)
1037 self.pg_start()
1038
1039 rx = self.pg0.get_capture()
1040 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
1041 [VppMplsLabel(44, ttl=32),
1042 VppMplsLabel(46, ttl=23)])
1043
1044 #
1045 # add a labelled route through the new tunnel
1046 #
1047 route_10_0_0_4 = VppIpRoute(
1048 self, "10.0.0.4", 32,
1049 [VppRoutePath("0.0.0.0",
1050 mpls_tun._sw_if_index,
1051 labels=[VppMplsLabel(33, ttl=47)])])
1052 route_10_0_0_4.add_vpp_config()
1053
1054 self.vapi.cli("clear trace")
1055 tx = self.create_stream_ip4(self.pg0, "10.0.0.4")
1056 self.pg0.add_stream(tx)
1057
1058 self.pg_enable_capture(self.pg_interfaces)
1059 self.pg_start()
1060
1061 rx = self.pg0.get_capture()
1062 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
1063 [VppMplsLabel(44, ttl=32),
1064 VppMplsLabel(46, ttl=47),
1065 VppMplsLabel(33, ttl=47)])
Neale Ranns8c4611b2017-05-23 03:43:47 -07001066
Neale Rannsf5fa5ae2018-09-26 05:07:25 -07001067 def test_mpls_tunnel_many(self):
Neale Ranns097fa662018-05-01 05:17:55 -07001068 """ MPLS Multiple Tunnels """
Neale Rannsf5fa5ae2018-09-26 05:07:25 -07001069
1070 for ii in range(10):
1071 mpls_tun = VppMPLSTunnelInterface(
1072 self,
1073 [VppRoutePath(self.pg0.remote_ip4,
1074 self.pg0.sw_if_index,
1075 labels=[VppMplsLabel(44, ttl=32),
1076 VppMplsLabel(46, MplsLspMode.UNIFORM)])])
1077 mpls_tun.add_vpp_config()
1078 mpls_tun.admin_up()
1079
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001080 def test_v4_exp_null(self):
1081 """ MPLS V4 Explicit NULL test """
1082
1083 #
1084 # The first test case has an MPLS TTL of 0
1085 # all packet should be dropped
1086 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001087 tx = self.create_stream_labelled_ip4(self.pg0,
1088 [VppMplsLabel(0, ttl=0)])
1089 self.send_and_assert_no_replies(self.pg0, tx,
1090 "MPLS TTL=0 packets forwarded")
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001091
1092 #
1093 # a stream with a non-zero MPLS TTL
1094 # PG0 is in the default table
1095 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001096 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(0)])
1097 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001098 self.verify_capture_ip4(self.pg0, rx, tx)
1099
1100 #
1101 # a stream with a non-zero MPLS TTL
1102 # PG1 is in table 1
1103 # we are ensuring the post-pop lookup occurs in the VRF table
1104 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001105 tx = self.create_stream_labelled_ip4(self.pg1, [VppMplsLabel(0)])
1106 rx = self.send_and_expect(self.pg1, tx, self.pg1)
1107 self.verify_capture_ip4(self.pg1, rx, tx)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001108
1109 def test_v6_exp_null(self):
1110 """ MPLS V6 Explicit NULL test """
1111
1112 #
1113 # a stream with a non-zero MPLS TTL
1114 # PG0 is in the default table
1115 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001116 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(2)])
1117 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001118 self.verify_capture_ip6(self.pg0, rx, tx)
1119
1120 #
1121 # a stream with a non-zero MPLS TTL
1122 # PG1 is in table 1
1123 # we are ensuring the post-pop lookup occurs in the VRF table
1124 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001125 tx = self.create_stream_labelled_ip6(self.pg1, [VppMplsLabel(2)])
1126 rx = self.send_and_expect(self.pg1, tx, self.pg1)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001127 self.verify_capture_ip6(self.pg0, rx, tx)
1128
Neale Rannscb630ff2016-12-14 13:31:29 +01001129 def test_deag(self):
1130 """ MPLS Deagg """
1131
1132 #
1133 # A de-agg route - next-hop lookup in default table
1134 #
Neale Ranns5a8123b2017-01-26 01:18:23 -08001135 route_34_eos = VppMplsRoute(self, 34, 1,
1136 [VppRoutePath("0.0.0.0",
1137 0xffffffff,
1138 nh_table_id=0)])
Neale Rannscb630ff2016-12-14 13:31:29 +01001139 route_34_eos.add_vpp_config()
1140
1141 #
1142 # ping an interface in the default table
1143 # PG0 is in the default table
1144 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001145 tx = self.create_stream_labelled_ip4(self.pg0,
1146 [VppMplsLabel(34)],
1147 ping=1,
Neale Rannscb630ff2016-12-14 13:31:29 +01001148 ip_itf=self.pg0)
Neale Ranns31ed7442018-02-23 05:29:09 -08001149 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Rannscb630ff2016-12-14 13:31:29 +01001150 self.verify_capture_ip4(self.pg0, rx, tx, ping_resp=1)
1151
1152 #
1153 # A de-agg route - next-hop lookup in non-default table
1154 #
Neale Ranns5a8123b2017-01-26 01:18:23 -08001155 route_35_eos = VppMplsRoute(self, 35, 1,
1156 [VppRoutePath("0.0.0.0",
1157 0xffffffff,
1158 nh_table_id=1)])
Neale Rannscb630ff2016-12-14 13:31:29 +01001159 route_35_eos.add_vpp_config()
1160
1161 #
1162 # ping an interface in the non-default table
1163 # PG0 is in the default table. packet arrive labelled in the
1164 # default table and egress unlabelled in the non-default
1165 #
Klement Sekeradab231a2016-12-21 08:50:14 +01001166 tx = self.create_stream_labelled_ip4(
Neale Ranns31ed7442018-02-23 05:29:09 -08001167 self.pg0, [VppMplsLabel(35)], ping=1, ip_itf=self.pg1)
1168 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Rannscb630ff2016-12-14 13:31:29 +01001169 self.verify_capture_ip4(self.pg1, rx, tx, ping_resp=1)
1170
Neale Ranns6af1c042017-05-26 03:48:53 -07001171 #
1172 # Double pop
1173 #
1174 route_36_neos = VppMplsRoute(self, 36, 0,
1175 [VppRoutePath("0.0.0.0",
1176 0xffffffff)])
1177 route_36_neos.add_vpp_config()
1178
Neale Ranns31ed7442018-02-23 05:29:09 -08001179 tx = self.create_stream_labelled_ip4(self.pg0,
1180 [VppMplsLabel(36),
1181 VppMplsLabel(35)],
Neale Ranns6af1c042017-05-26 03:48:53 -07001182 ping=1, ip_itf=self.pg1)
Neale Ranns31ed7442018-02-23 05:29:09 -08001183 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns6af1c042017-05-26 03:48:53 -07001184 self.verify_capture_ip4(self.pg1, rx, tx, ping_resp=1)
1185
1186 route_36_neos.remove_vpp_config()
Neale Rannscb630ff2016-12-14 13:31:29 +01001187 route_35_eos.remove_vpp_config()
1188 route_34_eos.remove_vpp_config()
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001189
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001190 def test_interface_rx(self):
1191 """ MPLS Interface Receive """
1192
1193 #
1194 # Add a non-recursive route that will forward the traffic
1195 # post-interface-rx
1196 #
1197 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
1198 table_id=1,
1199 paths=[VppRoutePath(self.pg1.remote_ip4,
1200 self.pg1.sw_if_index)])
1201 route_10_0_0_1.add_vpp_config()
1202
1203 #
1204 # An interface receive label that maps traffic to RX on interface
1205 # pg1
1206 # by injecting the packet in on pg0, which is in table 0
1207 # doing an interface-rx on pg1 and matching a route in table 1
1208 # if the packet egresses, then we must have swapped to pg1
1209 # so as to have matched the route in table 1
1210 #
Neale Ranns097fa662018-05-01 05:17:55 -07001211 route_34_eos = VppMplsRoute(
1212 self, 34, 1,
1213 [VppRoutePath("0.0.0.0",
1214 self.pg1.sw_if_index,
1215 type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001216 route_34_eos.add_vpp_config()
1217
1218 #
1219 # ping an interface in the default table
1220 # PG0 is in the default table
1221 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001222 tx = self.create_stream_labelled_ip4(self.pg0,
1223 [VppMplsLabel(34)],
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001224 dst_ip="10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -08001225 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001226 self.verify_capture_ip4(self.pg1, rx, tx)
1227
1228 def test_mcast_mid_point(self):
1229 """ MPLS Multicast Mid Point """
1230
1231 #
1232 # Add a non-recursive route that will forward the traffic
1233 # post-interface-rx
1234 #
1235 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
1236 table_id=1,
1237 paths=[VppRoutePath(self.pg1.remote_ip4,
1238 self.pg1.sw_if_index)])
1239 route_10_0_0_1.add_vpp_config()
1240
1241 #
1242 # Add a mcast entry that replicate to pg2 and pg3
1243 # and replicate to a interface-rx (like a bud node would)
1244 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001245 route_3400_eos = VppMplsRoute(
1246 self, 3400, 1,
1247 [VppRoutePath(self.pg2.remote_ip4,
1248 self.pg2.sw_if_index,
1249 labels=[VppMplsLabel(3401)]),
1250 VppRoutePath(self.pg3.remote_ip4,
1251 self.pg3.sw_if_index,
1252 labels=[VppMplsLabel(3402)]),
1253 VppRoutePath("0.0.0.0",
1254 self.pg1.sw_if_index,
Neale Ranns097fa662018-05-01 05:17:55 -07001255 type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX)],
Neale Ranns31ed7442018-02-23 05:29:09 -08001256 is_multicast=1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001257 route_3400_eos.add_vpp_config()
1258
1259 #
1260 # ping an interface in the default table
1261 # PG0 is in the default table
1262 #
1263 self.vapi.cli("clear trace")
Neale Ranns31ed7442018-02-23 05:29:09 -08001264 tx = self.create_stream_labelled_ip4(self.pg0,
1265 [VppMplsLabel(3400, ttl=64)],
1266 n=257,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001267 dst_ip="10.0.0.1")
1268 self.pg0.add_stream(tx)
1269
1270 self.pg_enable_capture(self.pg_interfaces)
1271 self.pg_start()
1272
1273 rx = self.pg1.get_capture(257)
1274 self.verify_capture_ip4(self.pg1, rx, tx)
1275
1276 rx = self.pg2.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001277 self.verify_capture_labelled(self.pg2, rx, tx,
1278 [VppMplsLabel(3401, ttl=63)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001279 rx = self.pg3.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001280 self.verify_capture_labelled(self.pg3, rx, tx,
1281 [VppMplsLabel(3402, ttl=63)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001282
1283 def test_mcast_head(self):
1284 """ MPLS Multicast Head-end """
1285
1286 #
1287 # Create a multicast tunnel with two replications
1288 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001289 mpls_tun = VppMPLSTunnelInterface(
1290 self,
1291 [VppRoutePath(self.pg2.remote_ip4,
1292 self.pg2.sw_if_index,
1293 labels=[VppMplsLabel(42)]),
1294 VppRoutePath(self.pg3.remote_ip4,
1295 self.pg3.sw_if_index,
1296 labels=[VppMplsLabel(43)])],
1297 is_multicast=1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001298 mpls_tun.add_vpp_config()
1299 mpls_tun.admin_up()
1300
1301 #
1302 # add an unlabelled route through the new tunnel
1303 #
1304 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
1305 [VppRoutePath("0.0.0.0",
1306 mpls_tun._sw_if_index)])
1307 route_10_0_0_3.add_vpp_config()
1308
1309 self.vapi.cli("clear trace")
1310 tx = self.create_stream_ip4(self.pg0, "10.0.0.3")
1311 self.pg0.add_stream(tx)
1312
1313 self.pg_enable_capture(self.pg_interfaces)
1314 self.pg_start()
1315
1316 rx = self.pg2.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001317 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(42)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001318 rx = self.pg3.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001319 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(43)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001320
1321 #
1322 # An an IP multicast route via the tunnel
1323 # A (*,G).
1324 # one accepting interface, pg0, 1 forwarding interface via the tunnel
1325 #
1326 route_232_1_1_1 = VppIpMRoute(
1327 self,
1328 "0.0.0.0",
1329 "232.1.1.1", 32,
1330 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
1331 [VppMRoutePath(self.pg0.sw_if_index,
1332 MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
1333 VppMRoutePath(mpls_tun._sw_if_index,
1334 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
1335 route_232_1_1_1.add_vpp_config()
Neale Ranns097fa662018-05-01 05:17:55 -07001336 self.logger.info(self.vapi.cli("sh ip mfib index 0"))
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001337
1338 self.vapi.cli("clear trace")
1339 tx = self.create_stream_ip4(self.pg0, "232.1.1.1")
1340 self.pg0.add_stream(tx)
1341
1342 self.pg_enable_capture(self.pg_interfaces)
1343 self.pg_start()
1344
1345 rx = self.pg2.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001346 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(42)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001347 rx = self.pg3.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001348 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(43)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001349
Neale Ranns31426c62017-05-24 10:32:58 -07001350 def test_mcast_ip4_tail(self):
1351 """ MPLS IPv4 Multicast Tail """
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001352
1353 #
1354 # Add a multicast route that will forward the traffic
1355 # post-disposition
1356 #
1357 route_232_1_1_1 = VppIpMRoute(
1358 self,
1359 "0.0.0.0",
1360 "232.1.1.1", 32,
1361 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
1362 table_id=1,
1363 paths=[VppMRoutePath(self.pg1.sw_if_index,
1364 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
1365 route_232_1_1_1.add_vpp_config()
1366
1367 #
1368 # An interface receive label that maps traffic to RX on interface
1369 # pg1
1370 # by injecting the packet in on pg0, which is in table 0
1371 # doing an rpf-id and matching a route in table 1
1372 # if the packet egresses, then we must have matched the route in
1373 # table 1
1374 #
Neale Ranns097fa662018-05-01 05:17:55 -07001375 route_34_eos = VppMplsRoute(
1376 self, 34, 1,
1377 [VppRoutePath("0.0.0.0",
1378 0xffffffff,
1379 nh_table_id=1,
1380 rpf_id=55)],
1381 is_multicast=1,
1382 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP4)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001383
1384 route_34_eos.add_vpp_config()
1385
1386 #
1387 # Drop due to interface lookup miss
1388 #
1389 self.vapi.cli("clear trace")
Neale Ranns31ed7442018-02-23 05:29:09 -08001390 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001391 dst_ip="232.1.1.1", n=1)
1392 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop none")
1393
1394 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001395 # set the RPF-ID of the entry to match the input packet's
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001396 #
1397 route_232_1_1_1.update_rpf_id(55)
Neale Ranns097fa662018-05-01 05:17:55 -07001398 self.logger.info(self.vapi.cli("sh ip mfib index 1 232.1.1.1"))
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001399
Neale Ranns31ed7442018-02-23 05:29:09 -08001400 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
1401 dst_ip="232.1.1.1")
1402 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001403 self.verify_capture_ip4(self.pg1, rx, tx)
1404
1405 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001406 # disposed packets have an invalid IPv4 checksum
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001407 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001408 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001409 dst_ip="232.1.1.1", n=65,
1410 chksum=1)
1411 self.send_and_assert_no_replies(self.pg0, tx, "Invalid Checksum")
1412
1413 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001414 # set the RPF-ID of the entry to not match the input packet's
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001415 #
1416 route_232_1_1_1.update_rpf_id(56)
Neale Ranns31ed7442018-02-23 05:29:09 -08001417 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001418 dst_ip="232.1.1.1")
1419 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop 56")
1420
Neale Ranns31426c62017-05-24 10:32:58 -07001421 def test_mcast_ip6_tail(self):
1422 """ MPLS IPv6 Multicast Tail """
1423
1424 #
1425 # Add a multicast route that will forward the traffic
1426 # post-disposition
1427 #
1428 route_ff = VppIpMRoute(
1429 self,
1430 "::",
1431 "ff01::1", 32,
1432 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
1433 table_id=1,
1434 paths=[VppMRoutePath(self.pg1.sw_if_index,
Neale Ranns097fa662018-05-01 05:17:55 -07001435 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD,
1436 proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)])
Neale Ranns31426c62017-05-24 10:32:58 -07001437 route_ff.add_vpp_config()
1438
1439 #
1440 # An interface receive label that maps traffic to RX on interface
1441 # pg1
1442 # by injecting the packet in on pg0, which is in table 0
1443 # doing an rpf-id and matching a route in table 1
1444 # if the packet egresses, then we must have matched the route in
1445 # table 1
1446 #
1447 route_34_eos = VppMplsRoute(
1448 self, 34, 1,
1449 [VppRoutePath("::",
Neale Ranns097fa662018-05-01 05:17:55 -07001450 0xffffffff,
Neale Ranns31426c62017-05-24 10:32:58 -07001451 nh_table_id=1,
Neale Ranns097fa662018-05-01 05:17:55 -07001452 rpf_id=55)],
1453 is_multicast=1,
1454 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)
Neale Ranns31426c62017-05-24 10:32:58 -07001455
1456 route_34_eos.add_vpp_config()
1457
1458 #
1459 # Drop due to interface lookup miss
1460 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001461 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(34)],
Neale Ranns31426c62017-05-24 10:32:58 -07001462 dst_ip="ff01::1")
Neale Ranns31ed7442018-02-23 05:29:09 -08001463 self.send_and_assert_no_replies(self.pg0, tx, "RPF Miss")
Neale Ranns31426c62017-05-24 10:32:58 -07001464
1465 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001466 # set the RPF-ID of the entry to match the input packet's
Neale Ranns31426c62017-05-24 10:32:58 -07001467 #
1468 route_ff.update_rpf_id(55)
1469
Neale Ranns31ed7442018-02-23 05:29:09 -08001470 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(34)],
Neale Ranns31426c62017-05-24 10:32:58 -07001471 dst_ip="ff01::1")
Neale Ranns31ed7442018-02-23 05:29:09 -08001472 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns31426c62017-05-24 10:32:58 -07001473 self.verify_capture_ip6(self.pg1, rx, tx)
1474
1475 #
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001476 # disposed packets have hop-limit = 1
1477 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001478 tx = self.create_stream_labelled_ip6(self.pg0,
1479 [VppMplsLabel(34)],
1480 dst_ip="ff01::1",
1481 hlim=1)
1482 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns52fae862018-01-08 04:41:42 -08001483 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001484
1485 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001486 # set the RPF-ID of the entry to not match the input packet's
Neale Ranns31426c62017-05-24 10:32:58 -07001487 #
1488 route_ff.update_rpf_id(56)
Neale Ranns31ed7442018-02-23 05:29:09 -08001489 tx = self.create_stream_labelled_ip6(self.pg0,
1490 [VppMplsLabel(34)],
Neale Ranns31426c62017-05-24 10:32:58 -07001491 dst_ip="ff01::1")
1492 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop 56")
1493
Neale Rannsd5d7b962019-08-04 03:30:56 -07001494 def test_6pe(self):
1495 """ MPLS 6PE """
1496
1497 #
1498 # Add a non-recursive route with a single out label
1499 #
1500 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
1501 [VppRoutePath(self.pg0.remote_ip4,
1502 self.pg0.sw_if_index,
1503 labels=[VppMplsLabel(45)])])
1504 route_10_0_0_1.add_vpp_config()
1505
1506 # bind a local label to the route
1507 binding = VppMplsIpBind(self, 44, "10.0.0.1", 32)
1508 binding.add_vpp_config()
1509
1510 #
1511 # a labelled v6 route that resolves through the v4
1512 #
1513 route_2001_3 = VppIpRoute(
1514 self, "2001::3", 128,
1515 [VppRoutePath("10.0.0.1",
1516 INVALID_INDEX,
1517 labels=[VppMplsLabel(32)])])
1518 route_2001_3.add_vpp_config()
1519
1520 tx = self.create_stream_ip6(self.pg0, "2001::3")
1521 rx = self.send_and_expect(self.pg0, tx, self.pg0)
1522
1523 self.verify_capture_labelled_ip6(self.pg0, rx, tx,
1524 [VppMplsLabel(45),
1525 VppMplsLabel(32)])
1526
1527 #
1528 # and a v4 recursive via the v6
1529 #
1530 route_20_3 = VppIpRoute(
1531 self, "20.0.0.3", 32,
1532 [VppRoutePath("2001::3",
1533 INVALID_INDEX,
1534 labels=[VppMplsLabel(99)])])
1535 route_20_3.add_vpp_config()
1536
1537 tx = self.create_stream_ip4(self.pg0, "20.0.0.3")
1538 rx = self.send_and_expect(self.pg0, tx, self.pg0)
1539
1540 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
1541 [VppMplsLabel(45),
1542 VppMplsLabel(32),
1543 VppMplsLabel(99)])
1544
Neale Ranns180279b2017-03-16 15:49:09 -04001545
1546class TestMPLSDisabled(VppTestCase):
1547 """ MPLS disabled """
1548
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -07001549 @classmethod
1550 def setUpClass(cls):
1551 super(TestMPLSDisabled, cls).setUpClass()
1552
1553 @classmethod
1554 def tearDownClass(cls):
1555 super(TestMPLSDisabled, cls).tearDownClass()
1556
Neale Ranns180279b2017-03-16 15:49:09 -04001557 def setUp(self):
1558 super(TestMPLSDisabled, self).setUp()
1559
1560 # create 2 pg interfaces
1561 self.create_pg_interfaces(range(2))
1562
Neale Ranns15002542017-09-10 04:39:11 -07001563 self.tbl = VppMplsTable(self, 0)
1564 self.tbl.add_vpp_config()
1565
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001566 # PG0 is MPLS enabled
Neale Ranns180279b2017-03-16 15:49:09 -04001567 self.pg0.admin_up()
1568 self.pg0.config_ip4()
1569 self.pg0.resolve_arp()
1570 self.pg0.enable_mpls()
1571
1572 # PG 1 is not MPLS enabled
1573 self.pg1.admin_up()
1574
1575 def tearDown(self):
Neale Ranns180279b2017-03-16 15:49:09 -04001576 for i in self.pg_interfaces:
1577 i.unconfig_ip4()
1578 i.admin_down()
1579
Neale Ranns15002542017-09-10 04:39:11 -07001580 self.pg0.disable_mpls()
1581 super(TestMPLSDisabled, self).tearDown()
1582
Neale Ranns180279b2017-03-16 15:49:09 -04001583 def test_mpls_disabled(self):
1584 """ MPLS Disabled """
1585
1586 tx = (Ether(src=self.pg1.remote_mac,
1587 dst=self.pg1.local_mac) /
1588 MPLS(label=32, ttl=64) /
1589 IPv6(src="2001::1", dst=self.pg0.remote_ip6) /
1590 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001591 Raw(b'\xa5' * 100))
Neale Ranns180279b2017-03-16 15:49:09 -04001592
1593 #
1594 # A simple MPLS xconnect - eos label in label out
1595 #
1596 route_32_eos = VppMplsRoute(self, 32, 1,
1597 [VppRoutePath(self.pg0.remote_ip4,
1598 self.pg0.sw_if_index,
1599 labels=[33])])
1600 route_32_eos.add_vpp_config()
1601
1602 #
1603 # PG1 does not forward IP traffic
1604 #
1605 self.send_and_assert_no_replies(self.pg1, tx, "MPLS disabled")
1606
1607 #
1608 # MPLS enable PG1
1609 #
1610 self.pg1.enable_mpls()
1611
1612 #
1613 # Now we get packets through
1614 #
1615 self.pg1.add_stream(tx)
1616 self.pg_enable_capture(self.pg_interfaces)
1617 self.pg_start()
1618
1619 rx = self.pg0.get_capture(1)
1620
1621 #
1622 # Disable PG1
1623 #
1624 self.pg1.disable_mpls()
1625
1626 #
1627 # PG1 does not forward IP traffic
1628 #
1629 self.send_and_assert_no_replies(self.pg1, tx, "IPv6 disabled")
1630 self.send_and_assert_no_replies(self.pg1, tx, "IPv6 disabled")
1631
1632
Neale Rannsf12a83f2017-04-18 09:09:40 -07001633class TestMPLSPIC(VppTestCase):
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001634 """ MPLS Prefix-Independent Convergence (PIC) edge convergence """
Neale Rannsf12a83f2017-04-18 09:09:40 -07001635
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -07001636 @classmethod
1637 def setUpClass(cls):
1638 super(TestMPLSPIC, cls).setUpClass()
1639
1640 @classmethod
1641 def tearDownClass(cls):
1642 super(TestMPLSPIC, cls).tearDownClass()
1643
Neale Rannsf12a83f2017-04-18 09:09:40 -07001644 def setUp(self):
1645 super(TestMPLSPIC, self).setUp()
1646
1647 # create 2 pg interfaces
1648 self.create_pg_interfaces(range(4))
1649
Neale Ranns15002542017-09-10 04:39:11 -07001650 mpls_tbl = VppMplsTable(self, 0)
1651 mpls_tbl.add_vpp_config()
1652 tbl4 = VppIpTable(self, 1)
1653 tbl4.add_vpp_config()
1654 tbl6 = VppIpTable(self, 1, is_ip6=1)
1655 tbl6.add_vpp_config()
1656
Neale Rannsf12a83f2017-04-18 09:09:40 -07001657 # core links
1658 self.pg0.admin_up()
1659 self.pg0.config_ip4()
1660 self.pg0.resolve_arp()
1661 self.pg0.enable_mpls()
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001662
Neale Rannsf12a83f2017-04-18 09:09:40 -07001663 self.pg1.admin_up()
1664 self.pg1.config_ip4()
1665 self.pg1.resolve_arp()
1666 self.pg1.enable_mpls()
1667
1668 # VRF (customer facing) link
1669 self.pg2.admin_up()
1670 self.pg2.set_table_ip4(1)
1671 self.pg2.config_ip4()
1672 self.pg2.resolve_arp()
1673 self.pg2.set_table_ip6(1)
1674 self.pg2.config_ip6()
1675 self.pg2.resolve_ndp()
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001676
Neale Rannsf12a83f2017-04-18 09:09:40 -07001677 self.pg3.admin_up()
1678 self.pg3.set_table_ip4(1)
1679 self.pg3.config_ip4()
1680 self.pg3.resolve_arp()
1681 self.pg3.set_table_ip6(1)
1682 self.pg3.config_ip6()
1683 self.pg3.resolve_ndp()
1684
1685 def tearDown(self):
Neale Rannsf12a83f2017-04-18 09:09:40 -07001686 self.pg0.disable_mpls()
Neale Ranns15002542017-09-10 04:39:11 -07001687 self.pg1.disable_mpls()
Neale Rannsf12a83f2017-04-18 09:09:40 -07001688 for i in self.pg_interfaces:
1689 i.unconfig_ip4()
1690 i.unconfig_ip6()
1691 i.set_table_ip4(0)
1692 i.set_table_ip6(0)
1693 i.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -07001694 super(TestMPLSPIC, self).tearDown()
Neale Rannsf12a83f2017-04-18 09:09:40 -07001695
1696 def test_mpls_ibgp_pic(self):
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001697 """ MPLS iBGP Prefix-Independent Convergence (PIC) edge convergence
Neale Rannsf12a83f2017-04-18 09:09:40 -07001698
1699 1) setup many iBGP VPN routes via a pair of iBGP peers.
1700 2) Check EMCP forwarding to these peers
1701 3) withdraw the IGP route to one of these peers.
1702 4) check forwarding continues to the remaining peer
1703 """
1704
1705 #
1706 # IGP+LDP core routes
1707 #
1708 core_10_0_0_45 = VppIpRoute(self, "10.0.0.45", 32,
1709 [VppRoutePath(self.pg0.remote_ip4,
1710 self.pg0.sw_if_index,
1711 labels=[45])])
1712 core_10_0_0_45.add_vpp_config()
1713
1714 core_10_0_0_46 = VppIpRoute(self, "10.0.0.46", 32,
1715 [VppRoutePath(self.pg1.remote_ip4,
1716 self.pg1.sw_if_index,
1717 labels=[46])])
1718 core_10_0_0_46.add_vpp_config()
1719
1720 #
1721 # Lot's of VPN routes. We need more the 64 so VPP will build
1722 # the fast convergence indirection
1723 #
1724 vpn_routes = []
1725 pkts = []
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001726 for ii in range(NUM_PKTS):
Neale Rannsf12a83f2017-04-18 09:09:40 -07001727 dst = "192.168.1.%d" % ii
Neale Ranns097fa662018-05-01 05:17:55 -07001728 vpn_routes.append(VppIpRoute(
1729 self, dst, 32,
1730 [VppRoutePath(
1731 "10.0.0.45",
1732 0xffffffff,
1733 labels=[145],
1734 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_HOST),
1735 VppRoutePath(
1736 "10.0.0.46",
1737 0xffffffff,
1738 labels=[146],
1739 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_HOST)],
1740 table_id=1))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001741 vpn_routes[ii].add_vpp_config()
1742
1743 pkts.append(Ether(dst=self.pg2.local_mac,
1744 src=self.pg2.remote_mac) /
1745 IP(src=self.pg2.remote_ip4, dst=dst) /
1746 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001747 Raw(b'\xa5' * 100))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001748
1749 #
1750 # Send the packet stream (one pkt to each VPN route)
1751 # - expect a 50-50 split of the traffic
1752 #
1753 self.pg2.add_stream(pkts)
1754 self.pg_enable_capture(self.pg_interfaces)
1755 self.pg_start()
1756
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001757 rx0 = self.pg0._get_capture(NUM_PKTS)
1758 rx1 = self.pg1._get_capture(NUM_PKTS)
Neale Rannsf12a83f2017-04-18 09:09:40 -07001759
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001760 # not testing the LB hashing algorithm so we're not concerned
Neale Rannsf12a83f2017-04-18 09:09:40 -07001761 # with the split ratio, just as long as neither is 0
1762 self.assertNotEqual(0, len(rx0))
1763 self.assertNotEqual(0, len(rx1))
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001764 self.assertEqual(len(pkts), len(rx0) + len(rx1),
1765 "Expected all (%s) packets across both ECMP paths. "
1766 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001767
1768 #
1769 # use a test CLI command to stop the FIB walk process, this
1770 # will prevent the FIB converging the VPN routes and thus allow
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001771 # us to probe the interim (post-fail, pre-converge) state
Neale Rannsf12a83f2017-04-18 09:09:40 -07001772 #
1773 self.vapi.ppcli("test fib-walk-process disable")
1774
1775 #
1776 # Withdraw one of the IGP routes
1777 #
1778 core_10_0_0_46.remove_vpp_config()
1779
1780 #
1781 # now all packets should be forwarded through the remaining peer
1782 #
1783 self.vapi.ppcli("clear trace")
1784 self.pg2.add_stream(pkts)
1785 self.pg_enable_capture(self.pg_interfaces)
1786 self.pg_start()
1787
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001788 rx0 = self.pg0.get_capture(NUM_PKTS)
1789 self.assertEqual(len(pkts), len(rx0),
1790 "Expected all (%s) packets across single path. "
1791 "rx0: %s." % (len(pkts), len(rx0)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001792
1793 #
1794 # enable the FIB walk process to converge the FIB
1795 #
1796 self.vapi.ppcli("test fib-walk-process enable")
1797
1798 #
1799 # packets should still be forwarded through the remaining peer
1800 #
1801 self.pg2.add_stream(pkts)
1802 self.pg_enable_capture(self.pg_interfaces)
1803 self.pg_start()
1804
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001805 rx0 = self.pg0.get_capture(NUM_PKTS)
1806 self.assertEqual(len(pkts), len(rx0),
1807 "Expected all (%s) packets across single path. "
1808 "rx0: %s." % (len(pkts), len(rx0)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001809
1810 #
1811 # Add the IGP route back and we return to load-balancing
1812 #
1813 core_10_0_0_46.add_vpp_config()
1814
1815 self.pg2.add_stream(pkts)
1816 self.pg_enable_capture(self.pg_interfaces)
1817 self.pg_start()
1818
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001819 rx0 = self.pg0._get_capture(NUM_PKTS)
1820 rx1 = self.pg1._get_capture(NUM_PKTS)
Neale Rannsf12a83f2017-04-18 09:09:40 -07001821 self.assertNotEqual(0, len(rx0))
1822 self.assertNotEqual(0, len(rx1))
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001823 self.assertEqual(len(pkts), len(rx0) + len(rx1),
1824 "Expected all (%s) packets across both ECMP paths. "
1825 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001826
1827 def test_mpls_ebgp_pic(self):
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001828 """ MPLS eBGP Prefix-Independent Convergence (PIC) edge convergence
Neale Rannsf12a83f2017-04-18 09:09:40 -07001829
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001830 1) setup many eBGP VPN routes via a pair of eBGP peers.
Neale Rannsf12a83f2017-04-18 09:09:40 -07001831 2) Check EMCP forwarding to these peers
1832 3) withdraw one eBGP path - expect LB across remaining eBGP
1833 """
1834
1835 #
1836 # Lot's of VPN routes. We need more the 64 so VPP will build
1837 # the fast convergence indirection
1838 #
1839 vpn_routes = []
1840 vpn_bindings = []
1841 pkts = []
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001842 for ii in range(NUM_PKTS):
Neale Rannsf12a83f2017-04-18 09:09:40 -07001843 dst = "192.168.1.%d" % ii
1844 local_label = 1600 + ii
Neale Ranns097fa662018-05-01 05:17:55 -07001845 vpn_routes.append(VppIpRoute(
1846 self, dst, 32,
1847 [VppRoutePath(
1848 self.pg2.remote_ip4,
1849 0xffffffff,
1850 nh_table_id=1,
1851 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_ATTACHED),
1852 VppRoutePath(
1853 self.pg3.remote_ip4,
1854 0xffffffff,
1855 nh_table_id=1,
1856 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_ATTACHED)],
1857 table_id=1))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001858 vpn_routes[ii].add_vpp_config()
1859
1860 vpn_bindings.append(VppMplsIpBind(self, local_label, dst, 32,
1861 ip_table_id=1))
1862 vpn_bindings[ii].add_vpp_config()
1863
1864 pkts.append(Ether(dst=self.pg0.local_mac,
1865 src=self.pg0.remote_mac) /
1866 MPLS(label=local_label, ttl=64) /
1867 IP(src=self.pg0.remote_ip4, dst=dst) /
1868 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001869 Raw(b'\xa5' * 100))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001870
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001871 #
1872 # Send the packet stream (one pkt to each VPN route)
1873 # - expect a 50-50 split of the traffic
1874 #
Neale Rannsf12a83f2017-04-18 09:09:40 -07001875 self.pg0.add_stream(pkts)
1876 self.pg_enable_capture(self.pg_interfaces)
1877 self.pg_start()
1878
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001879 rx0 = self.pg2._get_capture(NUM_PKTS)
1880 rx1 = self.pg3._get_capture(NUM_PKTS)
1881
1882 # not testing the LB hashing algorithm so we're not concerned
1883 # with the split ratio, just as long as neither is 0
Neale Rannsf12a83f2017-04-18 09:09:40 -07001884 self.assertNotEqual(0, len(rx0))
1885 self.assertNotEqual(0, len(rx1))
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001886 self.assertEqual(len(pkts), len(rx0) + len(rx1),
1887 "Expected all (%s) packets across both ECMP paths. "
1888 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001889
1890 #
1891 # use a test CLI command to stop the FIB walk process, this
1892 # will prevent the FIB converging the VPN routes and thus allow
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001893 # us to probe the interim (post-fail, pre-converge) state
Neale Rannsf12a83f2017-04-18 09:09:40 -07001894 #
1895 self.vapi.ppcli("test fib-walk-process disable")
1896
1897 #
1898 # withdraw the connected prefix on the interface.
1899 #
1900 self.pg2.unconfig_ip4()
1901
1902 #
1903 # now all packets should be forwarded through the remaining peer
1904 #
1905 self.pg0.add_stream(pkts)
1906 self.pg_enable_capture(self.pg_interfaces)
1907 self.pg_start()
1908
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001909 rx0 = self.pg3.get_capture(NUM_PKTS)
1910 self.assertEqual(len(pkts), len(rx0),
1911 "Expected all (%s) packets across single path. "
1912 "rx0: %s." % (len(pkts), len(rx0)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001913
1914 #
1915 # enable the FIB walk process to converge the FIB
1916 #
1917 self.vapi.ppcli("test fib-walk-process enable")
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001918
1919 #
1920 # packets should still be forwarded through the remaining peer
1921 #
Neale Rannsf12a83f2017-04-18 09:09:40 -07001922 self.pg0.add_stream(pkts)
1923 self.pg_enable_capture(self.pg_interfaces)
1924 self.pg_start()
1925
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001926 rx0 = self.pg3.get_capture(NUM_PKTS)
1927 self.assertEqual(len(pkts), len(rx0),
1928 "Expected all (%s) packets across single path. "
1929 "rx0: %s." % (len(pkts), len(rx0)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001930
1931 #
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001932 # put the connected routes back
Neale Rannsf12a83f2017-04-18 09:09:40 -07001933 #
1934 self.pg2.config_ip4()
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001935 self.pg2.resolve_arp()
Neale Rannsf12a83f2017-04-18 09:09:40 -07001936
1937 self.pg0.add_stream(pkts)
1938 self.pg_enable_capture(self.pg_interfaces)
1939 self.pg_start()
1940
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001941 rx0 = self.pg2._get_capture(NUM_PKTS)
1942 rx1 = self.pg3._get_capture(NUM_PKTS)
Neale Rannsf12a83f2017-04-18 09:09:40 -07001943 self.assertNotEqual(0, len(rx0))
1944 self.assertNotEqual(0, len(rx1))
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001945 self.assertEqual(len(pkts), len(rx0) + len(rx1),
1946 "Expected all (%s) packets across both ECMP paths. "
1947 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001948
1949 def test_mpls_v6_ebgp_pic(self):
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001950 """ MPLSv6 eBGP Prefix-Independent Convergence (PIC) edge convergence
Neale Rannsf12a83f2017-04-18 09:09:40 -07001951
1952 1) setup many eBGP VPNv6 routes via a pair of eBGP peers
1953 2) Check EMCP forwarding to these peers
1954 3) withdraw one eBGP path - expect LB across remaining eBGP
1955 """
1956
1957 #
1958 # Lot's of VPN routes. We need more the 64 so VPP will build
1959 # the fast convergence indirection
1960 #
1961 vpn_routes = []
1962 vpn_bindings = []
1963 pkts = []
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001964 for ii in range(NUM_PKTS):
Neale Rannsf12a83f2017-04-18 09:09:40 -07001965 dst = "3000::%d" % ii
1966 local_label = 1600 + ii
Neale Rannsda78f952017-05-24 09:15:43 -07001967 vpn_routes.append(VppIpRoute(
1968 self, dst, 128,
Neale Ranns097fa662018-05-01 05:17:55 -07001969 [VppRoutePath(
1970 self.pg2.remote_ip6,
1971 0xffffffff,
1972 nh_table_id=1,
1973 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_ATTACHED),
1974 VppRoutePath(
1975 self.pg3.remote_ip6,
1976 0xffffffff,
1977 nh_table_id=1,
1978 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_ATTACHED)],
1979 table_id=1))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001980 vpn_routes[ii].add_vpp_config()
1981
1982 vpn_bindings.append(VppMplsIpBind(self, local_label, dst, 128,
Neale Ranns097fa662018-05-01 05:17:55 -07001983 ip_table_id=1))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001984 vpn_bindings[ii].add_vpp_config()
1985
1986 pkts.append(Ether(dst=self.pg0.local_mac,
1987 src=self.pg0.remote_mac) /
1988 MPLS(label=local_label, ttl=64) /
1989 IPv6(src=self.pg0.remote_ip6, dst=dst) /
1990 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001991 Raw(b'\xa5' * 100))
Neale Ranns097fa662018-05-01 05:17:55 -07001992 self.logger.info(self.vapi.cli("sh ip6 fib %s" % dst))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001993
1994 self.pg0.add_stream(pkts)
1995 self.pg_enable_capture(self.pg_interfaces)
1996 self.pg_start()
1997
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001998 rx0 = self.pg2._get_capture(NUM_PKTS)
1999 rx1 = self.pg3._get_capture(NUM_PKTS)
Neale Rannsf12a83f2017-04-18 09:09:40 -07002000 self.assertNotEqual(0, len(rx0))
2001 self.assertNotEqual(0, len(rx1))
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002002 self.assertEqual(len(pkts), len(rx0) + len(rx1),
2003 "Expected all (%s) packets across both ECMP paths. "
2004 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07002005
2006 #
2007 # use a test CLI command to stop the FIB walk process, this
2008 # will prevent the FIB converging the VPN routes and thus allow
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002009 # us to probe the interim (post-fail, pre-converge) state
Neale Rannsf12a83f2017-04-18 09:09:40 -07002010 #
2011 self.vapi.ppcli("test fib-walk-process disable")
2012
2013 #
2014 # withdraw the connected prefix on the interface.
2015 # and shutdown the interface so the ND cache is flushed.
2016 #
2017 self.pg2.unconfig_ip6()
2018 self.pg2.admin_down()
2019
2020 #
2021 # now all packets should be forwarded through the remaining peer
2022 #
2023 self.pg0.add_stream(pkts)
2024 self.pg_enable_capture(self.pg_interfaces)
2025 self.pg_start()
2026
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002027 rx0 = self.pg3.get_capture(NUM_PKTS)
2028 self.assertEqual(len(pkts), len(rx0),
2029 "Expected all (%s) packets across single path. "
2030 "rx0: %s." % (len(pkts), len(rx0)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07002031
2032 #
2033 # enable the FIB walk process to converge the FIB
2034 #
2035 self.vapi.ppcli("test fib-walk-process enable")
2036 self.pg0.add_stream(pkts)
2037 self.pg_enable_capture(self.pg_interfaces)
2038 self.pg_start()
2039
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002040 rx0 = self.pg3.get_capture(NUM_PKTS)
2041 self.assertEqual(len(pkts), len(rx0),
2042 "Expected all (%s) packets across single path. "
2043 "rx0: %s." % (len(pkts), len(rx0)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07002044
2045 #
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002046 # put the connected routes back
Neale Rannsf12a83f2017-04-18 09:09:40 -07002047 #
2048 self.pg2.admin_up()
2049 self.pg2.config_ip6()
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002050 self.pg2.resolve_ndp()
Neale Rannsf12a83f2017-04-18 09:09:40 -07002051
2052 self.pg0.add_stream(pkts)
2053 self.pg_enable_capture(self.pg_interfaces)
2054 self.pg_start()
2055
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002056 rx0 = self.pg2._get_capture(NUM_PKTS)
2057 rx1 = self.pg3._get_capture(NUM_PKTS)
Neale Rannsf12a83f2017-04-18 09:09:40 -07002058 self.assertNotEqual(0, len(rx0))
2059 self.assertNotEqual(0, len(rx1))
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002060 self.assertEqual(len(pkts), len(rx0) + len(rx1),
2061 "Expected all (%s) packets across both ECMP paths. "
2062 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07002063
2064
Neale Rannsda78f952017-05-24 09:15:43 -07002065class TestMPLSL2(VppTestCase):
2066 """ MPLS-L2 """
2067
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -07002068 @classmethod
2069 def setUpClass(cls):
2070 super(TestMPLSL2, cls).setUpClass()
2071
2072 @classmethod
2073 def tearDownClass(cls):
2074 super(TestMPLSL2, cls).tearDownClass()
2075
Neale Rannsda78f952017-05-24 09:15:43 -07002076 def setUp(self):
2077 super(TestMPLSL2, self).setUp()
2078
2079 # create 2 pg interfaces
2080 self.create_pg_interfaces(range(2))
2081
Neale Ranns15002542017-09-10 04:39:11 -07002082 # create the default MPLS table
2083 self.tables = []
2084 tbl = VppMplsTable(self, 0)
2085 tbl.add_vpp_config()
2086 self.tables.append(tbl)
2087
Neale Ranns1976f362019-11-06 13:13:01 +00002088 # use pg0 as the core facing interface, don't resolve ARP
Neale Rannsda78f952017-05-24 09:15:43 -07002089 self.pg0.admin_up()
2090 self.pg0.config_ip4()
Neale Rannsda78f952017-05-24 09:15:43 -07002091 self.pg0.enable_mpls()
2092
Neale Ranns15002542017-09-10 04:39:11 -07002093 # use the other 2 for customer facing L2 links
Neale Rannsda78f952017-05-24 09:15:43 -07002094 for i in self.pg_interfaces[1:]:
2095 i.admin_up()
2096
2097 def tearDown(self):
Neale Rannsda78f952017-05-24 09:15:43 -07002098 for i in self.pg_interfaces[1:]:
2099 i.admin_down()
2100
2101 self.pg0.disable_mpls()
2102 self.pg0.unconfig_ip4()
2103 self.pg0.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -07002104 super(TestMPLSL2, self).tearDown()
Neale Rannsda78f952017-05-24 09:15:43 -07002105
Neale Ranns31ed7442018-02-23 05:29:09 -08002106 def verify_capture_tunneled_ethernet(self, capture, sent, mpls_labels):
Neale Rannsda78f952017-05-24 09:15:43 -07002107 capture = verify_filter(capture, sent)
2108
2109 self.assertEqual(len(capture), len(sent))
2110
2111 for i in range(len(capture)):
2112 tx = sent[i]
2113 rx = capture[i]
2114
2115 # the MPLS TTL is 255 since it enters a new tunnel
Neale Ranns31ed7442018-02-23 05:29:09 -08002116 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsda78f952017-05-24 09:15:43 -07002117
2118 tx_eth = tx[Ether]
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -07002119 rx_eth = Ether(scapy.compat.raw(rx[MPLS].payload))
Neale Rannsda78f952017-05-24 09:15:43 -07002120
2121 self.assertEqual(rx_eth.src, tx_eth.src)
2122 self.assertEqual(rx_eth.dst, tx_eth.dst)
2123
Neale Ranns1976f362019-11-06 13:13:01 +00002124 def verify_arp_req(self, rx, smac, sip, dip):
2125 ether = rx[Ether]
2126 self.assertEqual(ether.dst, "ff:ff:ff:ff:ff:ff")
2127 self.assertEqual(ether.src, smac)
2128
2129 arp = rx[ARP]
2130 self.assertEqual(arp.hwtype, 1)
2131 self.assertEqual(arp.ptype, 0x800)
2132 self.assertEqual(arp.hwlen, 6)
2133 self.assertEqual(arp.plen, 4)
2134 self.assertEqual(arp.op, ARP.who_has)
2135 self.assertEqual(arp.hwsrc, smac)
2136 self.assertEqual(arp.hwdst, "00:00:00:00:00:00")
2137 self.assertEqual(arp.psrc, sip)
2138 self.assertEqual(arp.pdst, dip)
2139
Neale Rannsda78f952017-05-24 09:15:43 -07002140 def test_vpws(self):
2141 """ Virtual Private Wire Service """
2142
2143 #
2144 # Create an MPLS tunnel that pushes 1 label
Neale Ranns31ed7442018-02-23 05:29:09 -08002145 # For Ethernet over MPLS the uniform mode is irrelevant since ttl/cos
2146 # information is not in the packet, but we test it works anyway
Neale Rannsda78f952017-05-24 09:15:43 -07002147 #
Neale Ranns31ed7442018-02-23 05:29:09 -08002148 mpls_tun_1 = VppMPLSTunnelInterface(
2149 self,
2150 [VppRoutePath(self.pg0.remote_ip4,
2151 self.pg0.sw_if_index,
2152 labels=[VppMplsLabel(42, MplsLspMode.UNIFORM)])],
2153 is_l2=1)
Neale Rannsda78f952017-05-24 09:15:43 -07002154 mpls_tun_1.add_vpp_config()
2155 mpls_tun_1.admin_up()
2156
2157 #
2158 # Create a label entry to for 55 that does L2 input to the tunnel
2159 #
2160 route_55_eos = VppMplsRoute(
2161 self, 55, 1,
2162 [VppRoutePath("0.0.0.0",
2163 mpls_tun_1.sw_if_index,
Neale Ranns097fa662018-05-01 05:17:55 -07002164 type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX,
2165 proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET)],
2166 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET)
Neale Rannsda78f952017-05-24 09:15:43 -07002167 route_55_eos.add_vpp_config()
2168
2169 #
2170 # Cross-connect the tunnel with one of the customers L2 interfaces
2171 #
2172 self.vapi.sw_interface_set_l2_xconnect(self.pg1.sw_if_index,
2173 mpls_tun_1.sw_if_index,
2174 enable=1)
2175 self.vapi.sw_interface_set_l2_xconnect(mpls_tun_1.sw_if_index,
2176 self.pg1.sw_if_index,
2177 enable=1)
2178
2179 #
2180 # inject a packet from the core
2181 #
2182 pcore = (Ether(dst=self.pg0.local_mac,
2183 src=self.pg0.remote_mac) /
2184 MPLS(label=55, ttl=64) /
2185 Ether(dst="00:00:de:ad:ba:be",
2186 src="00:00:de:ad:be:ef") /
2187 IP(src="10.10.10.10", dst="11.11.11.11") /
2188 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002189 Raw(b'\xa5' * 100))
Neale Rannsda78f952017-05-24 09:15:43 -07002190
Paul Vinciguerra4271c972019-05-14 13:25:49 -04002191 tx0 = pcore * NUM_PKTS
Neale Ranns31ed7442018-02-23 05:29:09 -08002192 rx0 = self.send_and_expect(self.pg0, tx0, self.pg1)
2193 payload = pcore[MPLS].payload
Neale Rannsda78f952017-05-24 09:15:43 -07002194
Neale Ranns31ed7442018-02-23 05:29:09 -08002195 self.assertEqual(rx0[0][Ether].dst, payload[Ether].dst)
2196 self.assertEqual(rx0[0][Ether].src, payload[Ether].src)
Neale Rannsda78f952017-05-24 09:15:43 -07002197
2198 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002199 # Inject a packet from the customer/L2 side
Neale Ranns1976f362019-11-06 13:13:01 +00002200 # there's no resolved ARP entry so the first packet we see should be
2201 # an ARP request
Neale Rannsda78f952017-05-24 09:15:43 -07002202 #
Neale Ranns1976f362019-11-06 13:13:01 +00002203 tx1 = pcore[MPLS].payload
2204 rx1 = self.send_and_expect(self.pg1, [tx1], self.pg0)
2205
2206 self.verify_arp_req(rx1[0],
2207 self.pg0.local_mac,
2208 self.pg0.local_ip4,
2209 self.pg0.remote_ip4)
2210
2211 #
2212 # resolve the ARP entries and send again
2213 #
2214 self.pg0.resolve_arp()
Paul Vinciguerra4271c972019-05-14 13:25:49 -04002215 tx1 = pcore[MPLS].payload * NUM_PKTS
Neale Ranns31ed7442018-02-23 05:29:09 -08002216 rx1 = self.send_and_expect(self.pg1, tx1, self.pg0)
Neale Rannsda78f952017-05-24 09:15:43 -07002217
Neale Ranns31ed7442018-02-23 05:29:09 -08002218 self.verify_capture_tunneled_ethernet(rx1, tx1, [VppMplsLabel(42)])
Neale Rannsda78f952017-05-24 09:15:43 -07002219
2220 def test_vpls(self):
2221 """ Virtual Private LAN Service """
Neale Ranns1976f362019-11-06 13:13:01 +00002222
2223 # we skipped this in the setup
2224 self.pg0.resolve_arp()
2225
Neale Rannsda78f952017-05-24 09:15:43 -07002226 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002227 # Create a L2 MPLS tunnels
Neale Rannsda78f952017-05-24 09:15:43 -07002228 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002229 mpls_tun1 = VppMPLSTunnelInterface(
Neale Ranns31ed7442018-02-23 05:29:09 -08002230 self,
2231 [VppRoutePath(self.pg0.remote_ip4,
2232 self.pg0.sw_if_index,
2233 labels=[VppMplsLabel(42)])],
2234 is_l2=1)
Neale Ranns1dbcf302019-07-19 11:44:53 +00002235 mpls_tun1.add_vpp_config()
2236 mpls_tun1.admin_up()
2237
2238 mpls_tun2 = VppMPLSTunnelInterface(
2239 self,
2240 [VppRoutePath(self.pg0.remote_ip4,
2241 self.pg0.sw_if_index,
2242 labels=[VppMplsLabel(43)])],
2243 is_l2=1)
2244 mpls_tun2.add_vpp_config()
2245 mpls_tun2.admin_up()
Neale Rannsda78f952017-05-24 09:15:43 -07002246
2247 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002248 # Create a label entries, 55 and 56, that do L2 input to the tunnel
2249 # the latter includes a Psuedo Wire Control Word
Neale Rannsda78f952017-05-24 09:15:43 -07002250 #
2251 route_55_eos = VppMplsRoute(
2252 self, 55, 1,
2253 [VppRoutePath("0.0.0.0",
Neale Ranns1dbcf302019-07-19 11:44:53 +00002254 mpls_tun1.sw_if_index,
Neale Ranns097fa662018-05-01 05:17:55 -07002255 type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX,
2256 proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET)],
2257 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET)
Neale Ranns1dbcf302019-07-19 11:44:53 +00002258
2259 route_56_eos = VppMplsRoute(
2260 self, 56, 1,
2261 [VppRoutePath("0.0.0.0",
2262 mpls_tun2.sw_if_index,
2263 type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX,
2264 flags=FibPathFlags.FIB_PATH_FLAG_POP_PW_CW,
2265 proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET)],
2266 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET)
2267
2268 # move me
2269 route_56_eos.add_vpp_config()
Neale Rannsda78f952017-05-24 09:15:43 -07002270 route_55_eos.add_vpp_config()
2271
Neale Ranns1dbcf302019-07-19 11:44:53 +00002272 self.logger.info(self.vapi.cli("sh mpls fib 56"))
2273
Neale Rannsda78f952017-05-24 09:15:43 -07002274 #
2275 # add to tunnel to the customers bridge-domain
2276 #
Ole Troana5b2eec2019-03-11 19:23:25 +01002277 self.vapi.sw_interface_set_l2_bridge(
Neale Ranns1dbcf302019-07-19 11:44:53 +00002278 rx_sw_if_index=mpls_tun1.sw_if_index, bd_id=1)
2279 self.vapi.sw_interface_set_l2_bridge(
2280 rx_sw_if_index=mpls_tun2.sw_if_index, bd_id=1)
Ole Troana5b2eec2019-03-11 19:23:25 +01002281 self.vapi.sw_interface_set_l2_bridge(
2282 rx_sw_if_index=self.pg1.sw_if_index, bd_id=1)
Neale Rannsda78f952017-05-24 09:15:43 -07002283
2284 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002285 # Packet from host on the customer interface to each host
2286 # reachable over the core, and vice-versa
Neale Rannsda78f952017-05-24 09:15:43 -07002287 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002288 p_cust1 = (Ether(dst="00:00:de:ad:ba:b1",
2289 src="00:00:de:ad:be:ef") /
2290 IP(src="10.10.10.10", dst="11.11.11.11") /
2291 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002292 Raw(b'\xa5' * 100))
Neale Ranns1dbcf302019-07-19 11:44:53 +00002293 p_cust2 = (Ether(dst="00:00:de:ad:ba:b2",
2294 src="00:00:de:ad:be:ef") /
2295 IP(src="10.10.10.10", dst="11.11.11.12") /
2296 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002297 Raw(b'\xa5' * 100))
Neale Ranns1dbcf302019-07-19 11:44:53 +00002298 p_core1 = (Ether(dst=self.pg0.local_mac,
2299 src=self.pg0.remote_mac) /
2300 MPLS(label=55, ttl=64) /
2301 Ether(src="00:00:de:ad:ba:b1",
2302 dst="00:00:de:ad:be:ef") /
2303 IP(dst="10.10.10.10", src="11.11.11.11") /
2304 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002305 Raw(b'\xa5' * 100))
Neale Ranns1dbcf302019-07-19 11:44:53 +00002306 p_core2 = (Ether(dst=self.pg0.local_mac,
2307 src=self.pg0.remote_mac) /
2308 MPLS(label=56, ttl=64) /
Ole Troan770a0de2019-11-07 13:52:21 +01002309 Raw(b'\x01' * 4) / # PW CW
Neale Ranns1dbcf302019-07-19 11:44:53 +00002310 Ether(src="00:00:de:ad:ba:b2",
2311 dst="00:00:de:ad:be:ef") /
2312 IP(dst="10.10.10.10", src="11.11.11.12") /
2313 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002314 Raw(b'\xa5' * 100))
Neale Rannsda78f952017-05-24 09:15:43 -07002315
2316 #
2317 # The BD is learning, so send in one of each packet to learn
2318 #
Neale Rannsda78f952017-05-24 09:15:43 -07002319
Neale Ranns1dbcf302019-07-19 11:44:53 +00002320 # 2 packets due to BD flooding
2321 rx = self.send_and_expect(self.pg1, p_cust1, self.pg0, n_rx=2)
2322 rx = self.send_and_expect(self.pg1, p_cust2, self.pg0, n_rx=2)
Neale Rannsda78f952017-05-24 09:15:43 -07002323
Neale Ranns1dbcf302019-07-19 11:44:53 +00002324 # we've learnt this so expect it be be forwarded not flooded
2325 rx = self.send_and_expect(self.pg0, [p_core1], self.pg1)
2326 self.assertEqual(rx[0][Ether].dst, p_cust1[Ether].src)
2327 self.assertEqual(rx[0][Ether].src, p_cust1[Ether].dst)
Neale Rannsda78f952017-05-24 09:15:43 -07002328
Neale Ranns1dbcf302019-07-19 11:44:53 +00002329 rx = self.send_and_expect(self.pg0, [p_core2], self.pg1)
2330 self.assertEqual(rx[0][Ether].dst, p_cust2[Ether].src)
2331 self.assertEqual(rx[0][Ether].src, p_cust2[Ether].dst)
Neale Rannsda78f952017-05-24 09:15:43 -07002332
2333 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002334 # now a stream in each direction from each host
Neale Rannsda78f952017-05-24 09:15:43 -07002335 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002336 rx = self.send_and_expect(self.pg1, p_cust1 * NUM_PKTS, self.pg0)
2337 self.verify_capture_tunneled_ethernet(rx, p_cust1 * NUM_PKTS,
Neale Ranns31ed7442018-02-23 05:29:09 -08002338 [VppMplsLabel(42)])
Neale Rannsda78f952017-05-24 09:15:43 -07002339
Neale Ranns1dbcf302019-07-19 11:44:53 +00002340 rx = self.send_and_expect(self.pg1, p_cust2 * NUM_PKTS, self.pg0)
2341 self.verify_capture_tunneled_ethernet(rx, p_cust2 * NUM_PKTS,
2342 [VppMplsLabel(43)])
2343
2344 rx = self.send_and_expect(self.pg0, p_core1 * NUM_PKTS, self.pg1)
2345 rx = self.send_and_expect(self.pg0, p_core2 * NUM_PKTS, self.pg1)
2346
Neale Rannsda78f952017-05-24 09:15:43 -07002347 #
2348 # remove interfaces from customers bridge-domain
2349 #
Ole Troana5b2eec2019-03-11 19:23:25 +01002350 self.vapi.sw_interface_set_l2_bridge(
Neale Ranns1dbcf302019-07-19 11:44:53 +00002351 rx_sw_if_index=mpls_tun1.sw_if_index, bd_id=1, enable=0)
2352 self.vapi.sw_interface_set_l2_bridge(
2353 rx_sw_if_index=mpls_tun2.sw_if_index, bd_id=1, enable=0)
Ole Troana5b2eec2019-03-11 19:23:25 +01002354 self.vapi.sw_interface_set_l2_bridge(
2355 rx_sw_if_index=self.pg1.sw_if_index, bd_id=1, enable=0)
Neale Rannsda78f952017-05-24 09:15:43 -07002356
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002357
Neale Ranns8fe8cc22016-11-01 10:05:08 +00002358if __name__ == '__main__':
2359 unittest.main(testRunner=VppTestRunner)