blob: 8ed047df5f49df9ab63893eb73e6b31a81a61a74 [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
Klement Sekera7bb873a2016-11-18 07:38:42 +010017from scapy.layers.l2 import Ether
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
Klement Sekeradab231a2016-12-21 08:50:14 +010024
Neale Rannsda78f952017-05-24 09:15:43 -070025def verify_filter(capture, sent):
26 if not len(capture) == len(sent):
27 # filter out any IPv6 RAs from the capture
28 for p in capture:
29 if p.haslayer(IPv6):
30 capture.remove(p)
31 return capture
32
33
Neale Ranns31ed7442018-02-23 05:29:09 -080034def verify_mpls_stack(tst, rx, mpls_labels):
Neale Rannsda78f952017-05-24 09:15:43 -070035 # the rx'd packet has the MPLS label popped
36 eth = rx[Ether]
37 tst.assertEqual(eth.type, 0x8847)
38
39 rx_mpls = rx[MPLS]
40
41 for ii in range(len(mpls_labels)):
Neale Ranns31ed7442018-02-23 05:29:09 -080042 tst.assertEqual(rx_mpls.label, mpls_labels[ii].value)
43 tst.assertEqual(rx_mpls.cos, mpls_labels[ii].exp)
44 tst.assertEqual(rx_mpls.ttl, mpls_labels[ii].ttl)
45
Neale Rannsda78f952017-05-24 09:15:43 -070046 if ii == len(mpls_labels) - 1:
47 tst.assertEqual(rx_mpls.s, 1)
48 else:
49 # not end of stack
50 tst.assertEqual(rx_mpls.s, 0)
51 # pop the label to expose the next
52 rx_mpls = rx_mpls[MPLS].payload
53
54
Neale Ranns8fe8cc22016-11-01 10:05:08 +000055class TestMPLS(VppTestCase):
56 """ MPLS Test Case """
57
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -070058 @classmethod
59 def setUpClass(cls):
60 super(TestMPLS, cls).setUpClass()
61
62 @classmethod
63 def tearDownClass(cls):
64 super(TestMPLS, cls).tearDownClass()
65
Neale Ranns8fe8cc22016-11-01 10:05:08 +000066 def setUp(self):
67 super(TestMPLS, self).setUp()
68
69 # create 2 pg interfaces
Neale Ranns0f26c5a2017-03-01 15:12:11 -080070 self.create_pg_interfaces(range(4))
Neale Ranns8fe8cc22016-11-01 10:05:08 +000071
72 # setup both interfaces
73 # assign them different tables.
74 table_id = 0
Neale Ranns15002542017-09-10 04:39:11 -070075 self.tables = []
76
77 tbl = VppMplsTable(self, 0)
78 tbl.add_vpp_config()
79 self.tables.append(tbl)
Neale Ranns8fe8cc22016-11-01 10:05:08 +000080
81 for i in self.pg_interfaces:
82 i.admin_up()
Neale Ranns15002542017-09-10 04:39:11 -070083
84 if table_id != 0:
85 tbl = VppIpTable(self, table_id)
86 tbl.add_vpp_config()
87 self.tables.append(tbl)
88 tbl = VppIpTable(self, table_id, is_ip6=1)
89 tbl.add_vpp_config()
90 self.tables.append(tbl)
91
Neale Ranns8fe8cc22016-11-01 10:05:08 +000092 i.set_table_ip4(table_id)
93 i.set_table_ip6(table_id)
94 i.config_ip4()
Neale Ranns8fe8cc22016-11-01 10:05:08 +000095 i.resolve_arp()
Neale Rannsad422ed2016-11-02 14:20:04 +000096 i.config_ip6()
Neale Ranns8fe8cc22016-11-01 10:05:08 +000097 i.resolve_ndp()
Neale Rannsad422ed2016-11-02 14:20:04 +000098 i.enable_mpls()
Neale Ranns8fe8cc22016-11-01 10:05:08 +000099 table_id += 1
100
101 def tearDown(self):
Neale Ranns4008ac92017-02-13 23:20:04 -0800102 for i in self.pg_interfaces:
103 i.unconfig_ip4()
104 i.unconfig_ip6()
105 i.ip6_disable()
Neale Ranns15002542017-09-10 04:39:11 -0700106 i.set_table_ip4(0)
107 i.set_table_ip6(0)
108 i.disable_mpls()
Neale Ranns4008ac92017-02-13 23:20:04 -0800109 i.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -0700110 super(TestMPLS, self).tearDown()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000111
Neale Rannsad422ed2016-11-02 14:20:04 +0000112 # the default of 64 matches the IP packet TTL default
Klement Sekeradab231a2016-12-21 08:50:14 +0100113 def create_stream_labelled_ip4(
114 self,
115 src_if,
116 mpls_labels,
Klement Sekeradab231a2016-12-21 08:50:14 +0100117 ping=0,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800118 ip_itf=None,
119 dst_ip=None,
Neale Ranns4c7c8e52017-10-21 09:37:55 -0700120 chksum=None,
Neale Ranns31ed7442018-02-23 05:29:09 -0800121 ip_ttl=64,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800122 n=257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100123 self.reset_packet_infos()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000124 pkts = []
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800125 for i in range(0, n):
Klement Sekeradab231a2016-12-21 08:50:14 +0100126 info = self.create_packet_info(src_if, src_if)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000127 payload = self.info_to_payload(info)
Neale Rannsad422ed2016-11-02 14:20:04 +0000128 p = Ether(dst=src_if.local_mac, src=src_if.remote_mac)
129
130 for ii in range(len(mpls_labels)):
Neale Ranns31ed7442018-02-23 05:29:09 -0800131 p = p / MPLS(label=mpls_labels[ii].value,
132 ttl=mpls_labels[ii].ttl,
133 cos=mpls_labels[ii].exp)
Neale Rannscb630ff2016-12-14 13:31:29 +0100134 if not ping:
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800135 if not dst_ip:
Neale Ranns31ed7442018-02-23 05:29:09 -0800136 p = (p / IP(src=src_if.local_ip4,
137 dst=src_if.remote_ip4,
138 ttl=ip_ttl) /
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800139 UDP(sport=1234, dport=1234) /
140 Raw(payload))
141 else:
Neale Ranns31ed7442018-02-23 05:29:09 -0800142 p = (p / IP(src=src_if.local_ip4, dst=dst_ip, ttl=ip_ttl) /
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800143 UDP(sport=1234, dport=1234) /
144 Raw(payload))
Neale Rannscb630ff2016-12-14 13:31:29 +0100145 else:
146 p = (p / IP(src=ip_itf.remote_ip4,
Neale Ranns31ed7442018-02-23 05:29:09 -0800147 dst=ip_itf.local_ip4,
148 ttl=ip_ttl) /
Neale Rannscb630ff2016-12-14 13:31:29 +0100149 ICMP())
150
Neale Ranns4c7c8e52017-10-21 09:37:55 -0700151 if chksum:
152 p[IP].chksum = chksum
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000153 info.data = p.copy()
154 pkts.append(p)
155 return pkts
156
Ole Troaneb284a12019-10-09 13:33:19 +0200157 def create_stream_ip4(self, src_if, dst_ip, ip_ttl=64,
158 ip_dscp=0, payload_size=None):
Klement Sekeradab231a2016-12-21 08:50:14 +0100159 self.reset_packet_infos()
Neale Rannsad422ed2016-11-02 14:20:04 +0000160 pkts = []
161 for i in range(0, 257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100162 info = self.create_packet_info(src_if, src_if)
Neale Rannsad422ed2016-11-02 14:20:04 +0000163 payload = self.info_to_payload(info)
164 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
Neale Ranns31ed7442018-02-23 05:29:09 -0800165 IP(src=src_if.remote_ip4, dst=dst_ip,
166 ttl=ip_ttl, tos=ip_dscp) /
Neale Rannsad422ed2016-11-02 14:20:04 +0000167 UDP(sport=1234, dport=1234) /
168 Raw(payload))
169 info.data = p.copy()
Ole Troaneb284a12019-10-09 13:33:19 +0200170 if payload_size:
171 self.extend_packet(p, payload_size)
Neale Rannsad422ed2016-11-02 14:20:04 +0000172 pkts.append(p)
173 return pkts
174
Neale Ranns31ed7442018-02-23 05:29:09 -0800175 def create_stream_ip6(self, src_if, dst_ip, ip_ttl=64, ip_dscp=0):
176 self.reset_packet_infos()
177 pkts = []
178 for i in range(0, 257):
179 info = self.create_packet_info(src_if, src_if)
180 payload = self.info_to_payload(info)
181 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
182 IPv6(src=src_if.remote_ip6, dst=dst_ip,
183 hlim=ip_ttl, tc=ip_dscp) /
184 UDP(sport=1234, dport=1234) /
185 Raw(payload))
186 info.data = p.copy()
187 pkts.append(p)
188 return pkts
189
190 def create_stream_labelled_ip6(self, src_if, mpls_labels,
191 hlim=64, dst_ip=None):
Neale Ranns31426c62017-05-24 10:32:58 -0700192 if dst_ip is None:
193 dst_ip = src_if.remote_ip6
Klement Sekeradab231a2016-12-21 08:50:14 +0100194 self.reset_packet_infos()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000195 pkts = []
196 for i in range(0, 257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100197 info = self.create_packet_info(src_if, src_if)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000198 payload = self.info_to_payload(info)
Neale Ranns31ed7442018-02-23 05:29:09 -0800199 p = Ether(dst=src_if.local_mac, src=src_if.remote_mac)
200 for l in mpls_labels:
201 p = p / MPLS(label=l.value, ttl=l.ttl, cos=l.exp)
202
203 p = p / (IPv6(src=src_if.remote_ip6, dst=dst_ip, hlim=hlim) /
204 UDP(sport=1234, dport=1234) /
205 Raw(payload))
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000206 info.data = p.copy()
207 pkts.append(p)
208 return pkts
209
Neale Ranns31ed7442018-02-23 05:29:09 -0800210 def verify_capture_ip4(self, src_if, capture, sent, ping_resp=0,
211 ip_ttl=None, ip_dscp=0):
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000212 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700213 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000214
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000215 self.assertEqual(len(capture), len(sent))
216
217 for i in range(len(capture)):
218 tx = sent[i]
219 rx = capture[i]
220
221 # the rx'd packet has the MPLS label popped
Neale Rannsad422ed2016-11-02 14:20:04 +0000222 eth = rx[Ether]
223 self.assertEqual(eth.type, 0x800)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000224
225 tx_ip = tx[IP]
226 rx_ip = rx[IP]
227
Neale Rannscb630ff2016-12-14 13:31:29 +0100228 if not ping_resp:
229 self.assertEqual(rx_ip.src, tx_ip.src)
230 self.assertEqual(rx_ip.dst, tx_ip.dst)
Neale Ranns31ed7442018-02-23 05:29:09 -0800231 self.assertEqual(rx_ip.tos, ip_dscp)
232 if not ip_ttl:
233 # IP processing post pop has decremented the TTL
234 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
235 else:
236 self.assertEqual(rx_ip.ttl, ip_ttl)
Neale Rannscb630ff2016-12-14 13:31:29 +0100237 else:
238 self.assertEqual(rx_ip.src, tx_ip.dst)
239 self.assertEqual(rx_ip.dst, tx_ip.src)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000240
241 except:
Neale Rannsad422ed2016-11-02 14:20:04 +0000242 raise
243
Neale Rannsad422ed2016-11-02 14:20:04 +0000244 def verify_capture_labelled_ip4(self, src_if, capture, sent,
Neale Ranns31ed7442018-02-23 05:29:09 -0800245 mpls_labels, ip_ttl=None):
Neale Rannsad422ed2016-11-02 14:20:04 +0000246 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700247 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000248
249 self.assertEqual(len(capture), len(sent))
250
251 for i in range(len(capture)):
252 tx = sent[i]
253 rx = capture[i]
254 tx_ip = tx[IP]
255 rx_ip = rx[IP]
256
Neale Ranns31ed7442018-02-23 05:29:09 -0800257 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsad422ed2016-11-02 14:20:04 +0000258
259 self.assertEqual(rx_ip.src, tx_ip.src)
260 self.assertEqual(rx_ip.dst, tx_ip.dst)
Neale Ranns31ed7442018-02-23 05:29:09 -0800261 if not ip_ttl:
262 # IP processing post pop has decremented the TTL
263 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
264 else:
265 self.assertEqual(rx_ip.ttl, ip_ttl)
Neale Rannsad422ed2016-11-02 14:20:04 +0000266
267 except:
268 raise
269
Neale Ranns31ed7442018-02-23 05:29:09 -0800270 def verify_capture_labelled_ip6(self, src_if, capture, sent,
271 mpls_labels, ip_ttl=None):
272 try:
273 capture = verify_filter(capture, sent)
274
275 self.assertEqual(len(capture), len(sent))
276
277 for i in range(len(capture)):
278 tx = sent[i]
279 rx = capture[i]
280 tx_ip = tx[IPv6]
281 rx_ip = rx[IPv6]
282
283 verify_mpls_stack(self, rx, mpls_labels)
284
285 self.assertEqual(rx_ip.src, tx_ip.src)
286 self.assertEqual(rx_ip.dst, tx_ip.dst)
287 if not ip_ttl:
288 # IP processing post pop has decremented the TTL
289 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
290 else:
291 self.assertEqual(rx_ip.hlim, ip_ttl)
292
293 except:
294 raise
295
296 def verify_capture_tunneled_ip4(self, src_if, capture, sent, mpls_labels):
Neale Rannsad422ed2016-11-02 14:20:04 +0000297 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700298 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000299
300 self.assertEqual(len(capture), len(sent))
301
302 for i in range(len(capture)):
303 tx = sent[i]
304 rx = capture[i]
305 tx_ip = tx[IP]
306 rx_ip = rx[IP]
307
Neale Ranns31ed7442018-02-23 05:29:09 -0800308 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsad422ed2016-11-02 14:20:04 +0000309
310 self.assertEqual(rx_ip.src, tx_ip.src)
311 self.assertEqual(rx_ip.dst, tx_ip.dst)
312 # IP processing post pop has decremented the TTL
313 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
314
315 except:
316 raise
317
318 def verify_capture_labelled(self, src_if, capture, sent,
Neale Ranns31ed7442018-02-23 05:29:09 -0800319 mpls_labels):
Neale Rannsad422ed2016-11-02 14:20:04 +0000320 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700321 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000322
323 self.assertEqual(len(capture), len(sent))
324
325 for i in range(len(capture)):
326 rx = capture[i]
Neale Ranns31ed7442018-02-23 05:29:09 -0800327 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsad422ed2016-11-02 14:20:04 +0000328 except:
329 raise
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000330
Neale Ranns31ed7442018-02-23 05:29:09 -0800331 def verify_capture_ip6(self, src_if, capture, sent,
332 ip_hlim=None, ip_dscp=0):
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000333 try:
334 self.assertEqual(len(capture), len(sent))
335
336 for i in range(len(capture)):
337 tx = sent[i]
338 rx = capture[i]
339
340 # the rx'd packet has the MPLS label popped
Neale Rannsad422ed2016-11-02 14:20:04 +0000341 eth = rx[Ether]
342 self.assertEqual(eth.type, 0x86DD)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000343
344 tx_ip = tx[IPv6]
345 rx_ip = rx[IPv6]
346
347 self.assertEqual(rx_ip.src, tx_ip.src)
348 self.assertEqual(rx_ip.dst, tx_ip.dst)
Neale Ranns31ed7442018-02-23 05:29:09 -0800349 self.assertEqual(rx_ip.tc, ip_dscp)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000350 # IP processing post pop has decremented the TTL
Neale Ranns31ed7442018-02-23 05:29:09 -0800351 if not ip_hlim:
352 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
353 else:
354 self.assertEqual(rx_ip.hlim, ip_hlim)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000355
356 except:
Neale Rannsad422ed2016-11-02 14:20:04 +0000357 raise
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000358
Neale Ranns62fe07c2017-10-31 12:28:22 -0700359 def verify_capture_ip6_icmp(self, src_if, capture, sent):
360 try:
361 self.assertEqual(len(capture), len(sent))
362
363 for i in range(len(capture)):
364 tx = sent[i]
365 rx = capture[i]
366
367 # the rx'd packet has the MPLS label popped
368 eth = rx[Ether]
369 self.assertEqual(eth.type, 0x86DD)
370
371 tx_ip = tx[IPv6]
372 rx_ip = rx[IPv6]
373
374 self.assertEqual(rx_ip.dst, tx_ip.src)
375 # ICMP sourced from the interface's address
376 self.assertEqual(rx_ip.src, src_if.local_ip6)
377 # hop-limit reset to 255 for IMCP packet
Ole Troan282093f2018-09-19 12:38:51 +0200378 self.assertEqual(rx_ip.hlim, 255)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700379
380 icmp = rx[ICMPv6TimeExceeded]
381
382 except:
383 raise
384
Rajesh Goeld6f1c9c2019-10-06 13:17:36 +0530385 def verify_capture_fragmented_labelled_ip4(self, src_if, capture, sent,
386 mpls_labels, ip_ttl=None):
387 try:
388 capture = verify_filter(capture, sent)
389
390 for i in range(len(capture)):
391 tx = sent[0]
392 rx = capture[i]
393 tx_ip = tx[IP]
394 rx_ip = rx[IP]
395
396 verify_mpls_stack(self, rx, mpls_labels)
397
398 self.assertEqual(rx_ip.src, tx_ip.src)
399 self.assertEqual(rx_ip.dst, tx_ip.dst)
400 if not ip_ttl:
401 # IP processing post pop has decremented the TTL
402 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
403 else:
404 self.assertEqual(rx_ip.ttl, ip_ttl)
405
406 except:
407 raise
408
Neale Rannsad422ed2016-11-02 14:20:04 +0000409 def test_swap(self):
410 """ MPLS label swap tests """
411
412 #
413 # A simple MPLS xconnect - eos label in label out
414 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800415 route_32_eos = VppMplsRoute(self, 32, 1,
416 [VppRoutePath(self.pg0.remote_ip4,
417 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800418 labels=[VppMplsLabel(33)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000419 route_32_eos.add_vpp_config()
420
Neale Ranns775f73c2018-12-20 03:01:49 -0800421 self.assertTrue(
422 find_mpls_route(self, 0, 32, 1,
423 [VppRoutePath(self.pg0.remote_ip4,
424 self.pg0.sw_if_index,
425 labels=[VppMplsLabel(33)])]))
426
Neale Rannsad422ed2016-11-02 14:20:04 +0000427 #
428 # a stream that matches the route for 10.0.0.1
429 # PG0 is in the default table
430 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800431 tx = self.create_stream_labelled_ip4(self.pg0,
432 [VppMplsLabel(32, ttl=32, exp=1)])
433 rx = self.send_and_expect(self.pg0, tx, self.pg0)
434 self.verify_capture_labelled(self.pg0, rx, tx,
435 [VppMplsLabel(33, ttl=31, exp=1)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000436
Neale Ranns008dbe12018-09-07 09:32:36 -0700437 self.assertEqual(route_32_eos.get_stats_to()['packets'], 257)
438
Neale Rannsad422ed2016-11-02 14:20:04 +0000439 #
440 # A simple MPLS xconnect - non-eos label in label out
441 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800442 route_32_neos = VppMplsRoute(self, 32, 0,
443 [VppRoutePath(self.pg0.remote_ip4,
444 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800445 labels=[VppMplsLabel(33)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000446 route_32_neos.add_vpp_config()
447
448 #
449 # a stream that matches the route for 10.0.0.1
450 # PG0 is in the default table
451 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800452 tx = self.create_stream_labelled_ip4(self.pg0,
453 [VppMplsLabel(32, ttl=21, exp=7),
454 VppMplsLabel(99)])
455 rx = self.send_and_expect(self.pg0, tx, self.pg0)
456 self.verify_capture_labelled(self.pg0, rx, tx,
457 [VppMplsLabel(33, ttl=20, exp=7),
458 VppMplsLabel(99)])
Neale Ranns008dbe12018-09-07 09:32:36 -0700459 self.assertEqual(route_32_neos.get_stats_to()['packets'], 257)
Neale Rannsad422ed2016-11-02 14:20:04 +0000460
Neale Ranns31ed7442018-02-23 05:29:09 -0800461 #
462 # A simple MPLS xconnect - non-eos label in label out, uniform mode
463 #
464 route_42_neos = VppMplsRoute(
465 self, 42, 0,
466 [VppRoutePath(self.pg0.remote_ip4,
467 self.pg0.sw_if_index,
468 labels=[VppMplsLabel(43, MplsLspMode.UNIFORM)])])
469 route_42_neos.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000470
Neale Ranns31ed7442018-02-23 05:29:09 -0800471 tx = self.create_stream_labelled_ip4(self.pg0,
472 [VppMplsLabel(42, ttl=21, exp=7),
473 VppMplsLabel(99)])
474 rx = self.send_and_expect(self.pg0, tx, self.pg0)
475 self.verify_capture_labelled(self.pg0, rx, tx,
476 [VppMplsLabel(43, ttl=20, exp=7),
477 VppMplsLabel(99)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000478
479 #
480 # An MPLS xconnect - EOS label in IP out
481 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800482 route_33_eos = VppMplsRoute(self, 33, 1,
483 [VppRoutePath(self.pg0.remote_ip4,
484 self.pg0.sw_if_index,
485 labels=[])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000486 route_33_eos.add_vpp_config()
487
Neale Ranns31ed7442018-02-23 05:29:09 -0800488 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(33)])
489 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Rannsad422ed2016-11-02 14:20:04 +0000490 self.verify_capture_ip4(self.pg0, rx, tx)
491
492 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700493 # disposed packets have an invalid IPv4 checksum
Neale Ranns62fe07c2017-10-31 12:28:22 -0700494 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800495 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(33)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700496 dst_ip=self.pg0.remote_ip4,
497 n=65,
498 chksum=1)
499 self.send_and_assert_no_replies(self.pg0, tx, "Invalid Checksum")
500
501 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800502 # An MPLS xconnect - EOS label in IP out, uniform mode
503 #
504 route_3333_eos = VppMplsRoute(
505 self, 3333, 1,
506 [VppRoutePath(self.pg0.remote_ip4,
507 self.pg0.sw_if_index,
508 labels=[VppMplsLabel(3, MplsLspMode.UNIFORM)])])
509 route_3333_eos.add_vpp_config()
510
511 tx = self.create_stream_labelled_ip4(
512 self.pg0,
513 [VppMplsLabel(3333, ttl=55, exp=3)])
514 rx = self.send_and_expect(self.pg0, tx, self.pg0)
515 self.verify_capture_ip4(self.pg0, rx, tx, ip_ttl=54, ip_dscp=0x60)
516 tx = self.create_stream_labelled_ip4(
517 self.pg0,
518 [VppMplsLabel(3333, ttl=66, exp=4)])
519 rx = self.send_and_expect(self.pg0, tx, self.pg0)
520 self.verify_capture_ip4(self.pg0, rx, tx, ip_ttl=65, ip_dscp=0x80)
521
522 #
Neale Ranns62fe07c2017-10-31 12:28:22 -0700523 # An MPLS xconnect - EOS label in IPv6 out
524 #
525 route_333_eos = VppMplsRoute(
526 self, 333, 1,
527 [VppRoutePath(self.pg0.remote_ip6,
528 self.pg0.sw_if_index,
Neale Ranns097fa662018-05-01 05:17:55 -0700529 labels=[])],
530 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700531 route_333_eos.add_vpp_config()
532
Neale Ranns31ed7442018-02-23 05:29:09 -0800533 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(333)])
534 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700535 self.verify_capture_ip6(self.pg0, rx, tx)
536
537 #
538 # disposed packets have an TTL expired
539 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800540 tx = self.create_stream_labelled_ip6(self.pg0,
541 [VppMplsLabel(333, ttl=64)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700542 dst_ip=self.pg1.remote_ip6,
543 hlim=1)
Neale Ranns31ed7442018-02-23 05:29:09 -0800544 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700545 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
546
547 #
548 # An MPLS xconnect - EOS label in IPv6 out w imp-null
549 #
550 route_334_eos = VppMplsRoute(
551 self, 334, 1,
552 [VppRoutePath(self.pg0.remote_ip6,
553 self.pg0.sw_if_index,
Neale Ranns097fa662018-05-01 05:17:55 -0700554 labels=[VppMplsLabel(3)])],
555 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700556 route_334_eos.add_vpp_config()
557
Neale Ranns31ed7442018-02-23 05:29:09 -0800558 tx = self.create_stream_labelled_ip6(self.pg0,
559 [VppMplsLabel(334, ttl=64)])
560 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700561 self.verify_capture_ip6(self.pg0, rx, tx)
562
563 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800564 # An MPLS xconnect - EOS label in IPv6 out w imp-null in uniform mode
565 #
566 route_335_eos = VppMplsRoute(
567 self, 335, 1,
568 [VppRoutePath(self.pg0.remote_ip6,
569 self.pg0.sw_if_index,
Neale Ranns097fa662018-05-01 05:17:55 -0700570 labels=[VppMplsLabel(3, MplsLspMode.UNIFORM)])],
571 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)
Neale Ranns31ed7442018-02-23 05:29:09 -0800572 route_335_eos.add_vpp_config()
573
574 tx = self.create_stream_labelled_ip6(
575 self.pg0,
576 [VppMplsLabel(335, ttl=27, exp=4)])
577 rx = self.send_and_expect(self.pg0, tx, self.pg0)
578 self.verify_capture_ip6(self.pg0, rx, tx, ip_hlim=26, ip_dscp=0x80)
579
580 #
Neale Ranns62fe07c2017-10-31 12:28:22 -0700581 # disposed packets have an TTL expired
582 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800583 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(334)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700584 dst_ip=self.pg1.remote_ip6,
585 hlim=0)
Neale Ranns31ed7442018-02-23 05:29:09 -0800586 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700587 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
588
589 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000590 # An MPLS xconnect - non-EOS label in IP out - an invalid configuration
591 # so this traffic should be dropped.
592 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800593 route_33_neos = VppMplsRoute(self, 33, 0,
594 [VppRoutePath(self.pg0.remote_ip4,
595 self.pg0.sw_if_index,
596 labels=[])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000597 route_33_neos.add_vpp_config()
598
Neale Ranns31ed7442018-02-23 05:29:09 -0800599 tx = self.create_stream_labelled_ip4(self.pg0,
600 [VppMplsLabel(33),
601 VppMplsLabel(99)])
602 self.send_and_assert_no_replies(
603 self.pg0, tx,
604 "MPLS non-EOS packets popped and forwarded")
Neale Rannsad422ed2016-11-02 14:20:04 +0000605
606 #
607 # A recursive EOS x-connect, which resolves through another x-connect
Neale Ranns31ed7442018-02-23 05:29:09 -0800608 # in pipe mode
Neale Rannsad422ed2016-11-02 14:20:04 +0000609 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800610 route_34_eos = VppMplsRoute(self, 34, 1,
611 [VppRoutePath("0.0.0.0",
612 0xffffffff,
613 nh_via_label=32,
Neale Ranns31ed7442018-02-23 05:29:09 -0800614 labels=[VppMplsLabel(44),
615 VppMplsLabel(45)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000616 route_34_eos.add_vpp_config()
Neale Ranns097fa662018-05-01 05:17:55 -0700617 self.logger.info(self.vapi.cli("sh mpls fib 34"))
Neale Rannsad422ed2016-11-02 14:20:04 +0000618
Neale Ranns31ed7442018-02-23 05:29:09 -0800619 tx = self.create_stream_labelled_ip4(self.pg0,
620 [VppMplsLabel(34, ttl=3)])
621 rx = self.send_and_expect(self.pg0, tx, self.pg0)
622 self.verify_capture_labelled(self.pg0, rx, tx,
623 [VppMplsLabel(33),
624 VppMplsLabel(44),
625 VppMplsLabel(45, ttl=2)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000626
Neale Ranns008dbe12018-09-07 09:32:36 -0700627 self.assertEqual(route_34_eos.get_stats_to()['packets'], 257)
628 self.assertEqual(route_32_neos.get_stats_via()['packets'], 257)
629
Neale Ranns31ed7442018-02-23 05:29:09 -0800630 #
631 # A recursive EOS x-connect, which resolves through another x-connect
632 # in uniform mode
633 #
634 route_35_eos = VppMplsRoute(
635 self, 35, 1,
636 [VppRoutePath("0.0.0.0",
637 0xffffffff,
638 nh_via_label=42,
639 labels=[VppMplsLabel(44)])])
640 route_35_eos.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000641
Neale Ranns31ed7442018-02-23 05:29:09 -0800642 tx = self.create_stream_labelled_ip4(self.pg0,
643 [VppMplsLabel(35, ttl=3)])
644 rx = self.send_and_expect(self.pg0, tx, self.pg0)
645 self.verify_capture_labelled(self.pg0, rx, tx,
646 [VppMplsLabel(43, ttl=2),
647 VppMplsLabel(44, ttl=2)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000648
649 #
Matej Klottondeb69842016-12-09 15:05:46 +0100650 # A recursive non-EOS x-connect, which resolves through another
651 # x-connect
Neale Rannsad422ed2016-11-02 14:20:04 +0000652 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800653 route_34_neos = VppMplsRoute(self, 34, 0,
654 [VppRoutePath("0.0.0.0",
655 0xffffffff,
656 nh_via_label=32,
Neale Ranns31ed7442018-02-23 05:29:09 -0800657 labels=[VppMplsLabel(44),
658 VppMplsLabel(46)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000659 route_34_neos.add_vpp_config()
660
Neale Ranns31ed7442018-02-23 05:29:09 -0800661 tx = self.create_stream_labelled_ip4(self.pg0,
662 [VppMplsLabel(34, ttl=45),
663 VppMplsLabel(99)])
664 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Matej Klottondeb69842016-12-09 15:05:46 +0100665 # it's the 2nd (counting from 0) label in the stack that is swapped
Neale Ranns31ed7442018-02-23 05:29:09 -0800666 self.verify_capture_labelled(self.pg0, rx, tx,
667 [VppMplsLabel(33),
668 VppMplsLabel(44),
669 VppMplsLabel(46, ttl=44),
670 VppMplsLabel(99)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000671
672 #
Matej Klottondeb69842016-12-09 15:05:46 +0100673 # an recursive IP route that resolves through the recursive non-eos
674 # x-connect
Neale Rannsad422ed2016-11-02 14:20:04 +0000675 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800676 ip_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
677 [VppRoutePath("0.0.0.0",
678 0xffffffff,
679 nh_via_label=34,
Neale Ranns31ed7442018-02-23 05:29:09 -0800680 labels=[VppMplsLabel(55)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000681 ip_10_0_0_1.add_vpp_config()
682
Neale Rannsad422ed2016-11-02 14:20:04 +0000683 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800684 rx = self.send_and_expect(self.pg0, tx, self.pg0)
685 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
686 [VppMplsLabel(33),
687 VppMplsLabel(44),
688 VppMplsLabel(46),
689 VppMplsLabel(55)])
Neale Ranns008dbe12018-09-07 09:32:36 -0700690 self.assertEqual(ip_10_0_0_1.get_stats_to()['packets'], 257)
Neale Rannsad422ed2016-11-02 14:20:04 +0000691
692 ip_10_0_0_1.remove_vpp_config()
693 route_34_neos.remove_vpp_config()
694 route_34_eos.remove_vpp_config()
695 route_33_neos.remove_vpp_config()
696 route_33_eos.remove_vpp_config()
697 route_32_neos.remove_vpp_config()
698 route_32_eos.remove_vpp_config()
699
700 def test_bind(self):
701 """ MPLS Local Label Binding test """
702
703 #
704 # Add a non-recursive route with a single out label
705 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800706 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
707 [VppRoutePath(self.pg0.remote_ip4,
708 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800709 labels=[VppMplsLabel(45)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000710 route_10_0_0_1.add_vpp_config()
711
712 # bind a local label to the route
Neale Ranns5a8123b2017-01-26 01:18:23 -0800713 binding = VppMplsIpBind(self, 44, "10.0.0.1", 32)
Neale Rannsad422ed2016-11-02 14:20:04 +0000714 binding.add_vpp_config()
715
716 # non-EOS stream
Neale Ranns31ed7442018-02-23 05:29:09 -0800717 tx = self.create_stream_labelled_ip4(self.pg0,
718 [VppMplsLabel(44),
719 VppMplsLabel(99)])
720 rx = self.send_and_expect(self.pg0, tx, self.pg0)
721 self.verify_capture_labelled(self.pg0, rx, tx,
722 [VppMplsLabel(45, ttl=63),
723 VppMplsLabel(99)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000724
725 # EOS stream
Neale Ranns31ed7442018-02-23 05:29:09 -0800726 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(44)])
727 rx = self.send_and_expect(self.pg0, tx, self.pg0)
728 self.verify_capture_labelled(self.pg0, rx, tx,
729 [VppMplsLabel(45, ttl=63)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000730
731 # IP stream
Neale Rannsad422ed2016-11-02 14:20:04 +0000732 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800733 rx = self.send_and_expect(self.pg0, tx, self.pg0)
734 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [VppMplsLabel(45)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000735
736 #
737 # cleanup
738 #
739 binding.remove_vpp_config()
740 route_10_0_0_1.remove_vpp_config()
741
742 def test_imposition(self):
743 """ MPLS label imposition test """
744
745 #
746 # Add a non-recursive route with a single out label
747 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800748 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
749 [VppRoutePath(self.pg0.remote_ip4,
750 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800751 labels=[VppMplsLabel(32)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000752 route_10_0_0_1.add_vpp_config()
753
754 #
755 # a stream that matches the route for 10.0.0.1
756 # PG0 is in the default table
757 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000758 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800759 rx = self.send_and_expect(self.pg0, tx, self.pg0)
760 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [VppMplsLabel(32)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000761
762 #
763 # Add a non-recursive route with a 3 out labels
764 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800765 route_10_0_0_2 = VppIpRoute(self, "10.0.0.2", 32,
766 [VppRoutePath(self.pg0.remote_ip4,
767 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800768 labels=[VppMplsLabel(32),
769 VppMplsLabel(33),
770 VppMplsLabel(34)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000771 route_10_0_0_2.add_vpp_config()
772
Neale Ranns31ed7442018-02-23 05:29:09 -0800773 tx = self.create_stream_ip4(self.pg0, "10.0.0.2",
774 ip_ttl=44, ip_dscp=0xff)
775 rx = self.send_and_expect(self.pg0, tx, self.pg0)
776 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
777 [VppMplsLabel(32),
778 VppMplsLabel(33),
779 VppMplsLabel(34)],
780 ip_ttl=43)
Neale Rannsad422ed2016-11-02 14:20:04 +0000781
Neale Ranns31ed7442018-02-23 05:29:09 -0800782 #
783 # Add a non-recursive route with a single out label in uniform mode
784 #
785 route_10_0_0_3 = VppIpRoute(
786 self, "10.0.0.3", 32,
787 [VppRoutePath(self.pg0.remote_ip4,
788 self.pg0.sw_if_index,
789 labels=[VppMplsLabel(32,
790 mode=MplsLspMode.UNIFORM)])])
791 route_10_0_0_3.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000792
Neale Ranns31ed7442018-02-23 05:29:09 -0800793 tx = self.create_stream_ip4(self.pg0, "10.0.0.3",
794 ip_ttl=54, ip_dscp=0xbe)
795 rx = self.send_and_expect(self.pg0, tx, self.pg0)
796 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
797 [VppMplsLabel(32, ttl=53, exp=5)])
798
799 #
800 # Add a IPv6 non-recursive route with a single out label in
801 # uniform mode
802 #
803 route_2001_3 = VppIpRoute(
804 self, "2001::3", 128,
805 [VppRoutePath(self.pg0.remote_ip6,
806 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800807 labels=[VppMplsLabel(32,
Neale Ranns097fa662018-05-01 05:17:55 -0700808 mode=MplsLspMode.UNIFORM)])])
Neale Ranns31ed7442018-02-23 05:29:09 -0800809 route_2001_3.add_vpp_config()
810
811 tx = self.create_stream_ip6(self.pg0, "2001::3",
812 ip_ttl=54, ip_dscp=0xbe)
813 rx = self.send_and_expect(self.pg0, tx, self.pg0)
814 self.verify_capture_labelled_ip6(self.pg0, rx, tx,
815 [VppMplsLabel(32, ttl=53, exp=5)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000816
817 #
Matej Klottondeb69842016-12-09 15:05:46 +0100818 # add a recursive path, with output label, via the 1 label route
Neale Rannsad422ed2016-11-02 14:20:04 +0000819 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800820 route_11_0_0_1 = VppIpRoute(self, "11.0.0.1", 32,
821 [VppRoutePath("10.0.0.1",
822 0xffffffff,
Neale Ranns31ed7442018-02-23 05:29:09 -0800823 labels=[VppMplsLabel(44)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000824 route_11_0_0_1.add_vpp_config()
825
826 #
827 # a stream that matches the route for 11.0.0.1, should pick up
828 # the label stack for 11.0.0.1 and 10.0.0.1
829 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000830 tx = self.create_stream_ip4(self.pg0, "11.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800831 rx = self.send_and_expect(self.pg0, tx, self.pg0)
832 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
833 [VppMplsLabel(32),
834 VppMplsLabel(44)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000835
Neale Ranns008dbe12018-09-07 09:32:36 -0700836 self.assertEqual(route_11_0_0_1.get_stats_to()['packets'], 257)
837
Neale Rannsad422ed2016-11-02 14:20:04 +0000838 #
839 # add a recursive path, with 2 labels, via the 3 label route
840 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800841 route_11_0_0_2 = VppIpRoute(self, "11.0.0.2", 32,
842 [VppRoutePath("10.0.0.2",
843 0xffffffff,
Neale Ranns31ed7442018-02-23 05:29:09 -0800844 labels=[VppMplsLabel(44),
845 VppMplsLabel(45)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000846 route_11_0_0_2.add_vpp_config()
847
848 #
849 # a stream that matches the route for 11.0.0.1, should pick up
850 # the label stack for 11.0.0.1 and 10.0.0.1
851 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000852 tx = self.create_stream_ip4(self.pg0, "11.0.0.2")
Neale Ranns31ed7442018-02-23 05:29:09 -0800853 rx = self.send_and_expect(self.pg0, tx, self.pg0)
854 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
855 [VppMplsLabel(32),
856 VppMplsLabel(33),
857 VppMplsLabel(34),
858 VppMplsLabel(44),
859 VppMplsLabel(45)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000860
Neale Ranns008dbe12018-09-07 09:32:36 -0700861 self.assertEqual(route_11_0_0_2.get_stats_to()['packets'], 257)
862
863 rx = self.send_and_expect(self.pg0, tx, self.pg0)
864 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
865 [VppMplsLabel(32),
866 VppMplsLabel(33),
867 VppMplsLabel(34),
868 VppMplsLabel(44),
869 VppMplsLabel(45)])
870
871 self.assertEqual(route_11_0_0_2.get_stats_to()['packets'], 514)
872
Neale Rannsad422ed2016-11-02 14:20:04 +0000873 #
874 # cleanup
875 #
876 route_11_0_0_2.remove_vpp_config()
877 route_11_0_0_1.remove_vpp_config()
878 route_10_0_0_2.remove_vpp_config()
879 route_10_0_0_1.remove_vpp_config()
880
Rajesh Goeld6f1c9c2019-10-06 13:17:36 +0530881 def test_imposition_fragmentation(self):
882 """ MPLS label imposition fragmentation test """
883
884 #
885 # Add a ipv4 non-recursive route with a single out label
886 #
887 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
888 [VppRoutePath(self.pg0.remote_ip4,
889 self.pg0.sw_if_index,
890 labels=[VppMplsLabel(32)])])
891 route_10_0_0_1.add_vpp_config()
892
893 #
894 # a stream that matches the route for 10.0.0.1
895 # PG0 is in the default table
896 #
897 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
898 for i in range(0, 257):
899 self.extend_packet(tx[i], 10000)
900
901 #
902 # 5 fragments per packet (257*5=1285)
903 #
904 rx = self.send_and_expect(self.pg0, tx, self.pg0, 1285)
905 self.verify_capture_fragmented_labelled_ip4(self.pg0, rx, tx,
906 [VppMplsLabel(32)])
907
908 #
909 # cleanup
910 #
911 route_10_0_0_1.remove_vpp_config()
912
Neale Ranns31ed7442018-02-23 05:29:09 -0800913 def test_tunnel_pipe(self):
914 """ MPLS Tunnel Tests - Pipe """
Neale Rannsad422ed2016-11-02 14:20:04 +0000915
916 #
Ole Troaneb284a12019-10-09 13:33:19 +0200917 # Create a tunnel with two out labels
Neale Rannsad422ed2016-11-02 14:20:04 +0000918 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800919 mpls_tun = VppMPLSTunnelInterface(
920 self,
921 [VppRoutePath(self.pg0.remote_ip4,
922 self.pg0.sw_if_index,
923 labels=[VppMplsLabel(44),
924 VppMplsLabel(46)])])
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800925 mpls_tun.add_vpp_config()
926 mpls_tun.admin_up()
Neale Rannsad422ed2016-11-02 14:20:04 +0000927
928 #
929 # add an unlabelled route through the new tunnel
930 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800931 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
932 [VppRoutePath("0.0.0.0",
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800933 mpls_tun._sw_if_index)])
Neale Ranns5a8123b2017-01-26 01:18:23 -0800934 route_10_0_0_3.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000935
936 self.vapi.cli("clear trace")
937 tx = self.create_stream_ip4(self.pg0, "10.0.0.3")
938 self.pg0.add_stream(tx)
939
940 self.pg_enable_capture(self.pg_interfaces)
941 self.pg_start()
942
943 rx = self.pg0.get_capture()
Neale Ranns31ed7442018-02-23 05:29:09 -0800944 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
945 [VppMplsLabel(44),
946 VppMplsLabel(46)])
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000947
Neale Ranns8c4611b2017-05-23 03:43:47 -0700948 #
949 # add a labelled route through the new tunnel
950 #
951 route_10_0_0_4 = VppIpRoute(self, "10.0.0.4", 32,
952 [VppRoutePath("0.0.0.0",
953 mpls_tun._sw_if_index,
954 labels=[33])])
955 route_10_0_0_4.add_vpp_config()
956
957 self.vapi.cli("clear trace")
958 tx = self.create_stream_ip4(self.pg0, "10.0.0.4")
959 self.pg0.add_stream(tx)
960
961 self.pg_enable_capture(self.pg_interfaces)
962 self.pg_start()
963
964 rx = self.pg0.get_capture()
Neale Ranns31ed7442018-02-23 05:29:09 -0800965 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
966 [VppMplsLabel(44),
967 VppMplsLabel(46),
968 VppMplsLabel(33, ttl=255)])
969
Ole Troaneb284a12019-10-09 13:33:19 +0200970 #
971 # change tunnel's MTU to a low value
972 #
973 mpls_tun.set_l3_mtu(1200)
974
975 # send IP into the tunnel to be fragmented
976 tx = self.create_stream_ip4(self.pg0, "10.0.0.3",
977 payload_size=1500)
978 rx = self.send_and_expect(self.pg0, tx, self.pg0, len(tx)*2)
979
980 fake_tx = []
981 for p in tx:
982 fake_tx.append(p)
983 fake_tx.append(p)
984 self.verify_capture_tunneled_ip4(self.pg0, rx, fake_tx,
985 [VppMplsLabel(44),
986 VppMplsLabel(46)])
987
988 # send MPLS into the tunnel to be fragmented
989 tx = self.create_stream_ip4(self.pg0, "10.0.0.4",
990 payload_size=1500)
991 rx = self.send_and_expect(self.pg0, tx, self.pg0, len(tx)*2)
992
993 fake_tx = []
994 for p in tx:
995 fake_tx.append(p)
996 fake_tx.append(p)
997 self.verify_capture_tunneled_ip4(self.pg0, rx, fake_tx,
998 [VppMplsLabel(44),
999 VppMplsLabel(46),
1000 VppMplsLabel(33, ttl=255)])
1001
Neale Ranns31ed7442018-02-23 05:29:09 -08001002 def test_tunnel_uniform(self):
1003 """ MPLS Tunnel Tests - Uniform """
1004
1005 #
1006 # Create a tunnel with a single out label
1007 # The label stack is specified here from outer to inner
1008 #
1009 mpls_tun = VppMPLSTunnelInterface(
1010 self,
1011 [VppRoutePath(self.pg0.remote_ip4,
1012 self.pg0.sw_if_index,
1013 labels=[VppMplsLabel(44, ttl=32),
1014 VppMplsLabel(46, MplsLspMode.UNIFORM)])])
1015 mpls_tun.add_vpp_config()
1016 mpls_tun.admin_up()
1017
1018 #
1019 # add an unlabelled route through the new tunnel
1020 #
1021 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
1022 [VppRoutePath("0.0.0.0",
1023 mpls_tun._sw_if_index)])
1024 route_10_0_0_3.add_vpp_config()
1025
1026 self.vapi.cli("clear trace")
1027 tx = self.create_stream_ip4(self.pg0, "10.0.0.3", ip_ttl=24)
1028 self.pg0.add_stream(tx)
1029
1030 self.pg_enable_capture(self.pg_interfaces)
1031 self.pg_start()
1032
1033 rx = self.pg0.get_capture()
1034 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
1035 [VppMplsLabel(44, ttl=32),
1036 VppMplsLabel(46, ttl=23)])
1037
1038 #
1039 # add a labelled route through the new tunnel
1040 #
1041 route_10_0_0_4 = VppIpRoute(
1042 self, "10.0.0.4", 32,
1043 [VppRoutePath("0.0.0.0",
1044 mpls_tun._sw_if_index,
1045 labels=[VppMplsLabel(33, ttl=47)])])
1046 route_10_0_0_4.add_vpp_config()
1047
1048 self.vapi.cli("clear trace")
1049 tx = self.create_stream_ip4(self.pg0, "10.0.0.4")
1050 self.pg0.add_stream(tx)
1051
1052 self.pg_enable_capture(self.pg_interfaces)
1053 self.pg_start()
1054
1055 rx = self.pg0.get_capture()
1056 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
1057 [VppMplsLabel(44, ttl=32),
1058 VppMplsLabel(46, ttl=47),
1059 VppMplsLabel(33, ttl=47)])
Neale Ranns8c4611b2017-05-23 03:43:47 -07001060
Neale Rannsf5fa5ae2018-09-26 05:07:25 -07001061 def test_mpls_tunnel_many(self):
Neale Ranns097fa662018-05-01 05:17:55 -07001062 """ MPLS Multiple Tunnels """
Neale Rannsf5fa5ae2018-09-26 05:07:25 -07001063
1064 for ii in range(10):
1065 mpls_tun = VppMPLSTunnelInterface(
1066 self,
1067 [VppRoutePath(self.pg0.remote_ip4,
1068 self.pg0.sw_if_index,
1069 labels=[VppMplsLabel(44, ttl=32),
1070 VppMplsLabel(46, MplsLspMode.UNIFORM)])])
1071 mpls_tun.add_vpp_config()
1072 mpls_tun.admin_up()
1073
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001074 def test_v4_exp_null(self):
1075 """ MPLS V4 Explicit NULL test """
1076
1077 #
1078 # The first test case has an MPLS TTL of 0
1079 # all packet should be dropped
1080 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001081 tx = self.create_stream_labelled_ip4(self.pg0,
1082 [VppMplsLabel(0, ttl=0)])
1083 self.send_and_assert_no_replies(self.pg0, tx,
1084 "MPLS TTL=0 packets forwarded")
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001085
1086 #
1087 # a stream with a non-zero MPLS TTL
1088 # PG0 is in the default table
1089 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001090 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(0)])
1091 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001092 self.verify_capture_ip4(self.pg0, rx, tx)
1093
1094 #
1095 # a stream with a non-zero MPLS TTL
1096 # PG1 is in table 1
1097 # we are ensuring the post-pop lookup occurs in the VRF table
1098 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001099 tx = self.create_stream_labelled_ip4(self.pg1, [VppMplsLabel(0)])
1100 rx = self.send_and_expect(self.pg1, tx, self.pg1)
1101 self.verify_capture_ip4(self.pg1, rx, tx)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001102
1103 def test_v6_exp_null(self):
1104 """ MPLS V6 Explicit NULL test """
1105
1106 #
1107 # a stream with a non-zero MPLS TTL
1108 # PG0 is in the default table
1109 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001110 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(2)])
1111 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001112 self.verify_capture_ip6(self.pg0, rx, tx)
1113
1114 #
1115 # a stream with a non-zero MPLS TTL
1116 # PG1 is in table 1
1117 # we are ensuring the post-pop lookup occurs in the VRF table
1118 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001119 tx = self.create_stream_labelled_ip6(self.pg1, [VppMplsLabel(2)])
1120 rx = self.send_and_expect(self.pg1, tx, self.pg1)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001121 self.verify_capture_ip6(self.pg0, rx, tx)
1122
Neale Rannscb630ff2016-12-14 13:31:29 +01001123 def test_deag(self):
1124 """ MPLS Deagg """
1125
1126 #
1127 # A de-agg route - next-hop lookup in default table
1128 #
Neale Ranns5a8123b2017-01-26 01:18:23 -08001129 route_34_eos = VppMplsRoute(self, 34, 1,
1130 [VppRoutePath("0.0.0.0",
1131 0xffffffff,
1132 nh_table_id=0)])
Neale Rannscb630ff2016-12-14 13:31:29 +01001133 route_34_eos.add_vpp_config()
1134
1135 #
1136 # ping an interface in the default table
1137 # PG0 is in the default table
1138 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001139 tx = self.create_stream_labelled_ip4(self.pg0,
1140 [VppMplsLabel(34)],
1141 ping=1,
Neale Rannscb630ff2016-12-14 13:31:29 +01001142 ip_itf=self.pg0)
Neale Ranns31ed7442018-02-23 05:29:09 -08001143 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Rannscb630ff2016-12-14 13:31:29 +01001144 self.verify_capture_ip4(self.pg0, rx, tx, ping_resp=1)
1145
1146 #
1147 # A de-agg route - next-hop lookup in non-default table
1148 #
Neale Ranns5a8123b2017-01-26 01:18:23 -08001149 route_35_eos = VppMplsRoute(self, 35, 1,
1150 [VppRoutePath("0.0.0.0",
1151 0xffffffff,
1152 nh_table_id=1)])
Neale Rannscb630ff2016-12-14 13:31:29 +01001153 route_35_eos.add_vpp_config()
1154
1155 #
1156 # ping an interface in the non-default table
1157 # PG0 is in the default table. packet arrive labelled in the
1158 # default table and egress unlabelled in the non-default
1159 #
Klement Sekeradab231a2016-12-21 08:50:14 +01001160 tx = self.create_stream_labelled_ip4(
Neale Ranns31ed7442018-02-23 05:29:09 -08001161 self.pg0, [VppMplsLabel(35)], ping=1, ip_itf=self.pg1)
1162 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Rannscb630ff2016-12-14 13:31:29 +01001163 self.verify_capture_ip4(self.pg1, rx, tx, ping_resp=1)
1164
Neale Ranns6af1c042017-05-26 03:48:53 -07001165 #
1166 # Double pop
1167 #
1168 route_36_neos = VppMplsRoute(self, 36, 0,
1169 [VppRoutePath("0.0.0.0",
1170 0xffffffff)])
1171 route_36_neos.add_vpp_config()
1172
Neale Ranns31ed7442018-02-23 05:29:09 -08001173 tx = self.create_stream_labelled_ip4(self.pg0,
1174 [VppMplsLabel(36),
1175 VppMplsLabel(35)],
Neale Ranns6af1c042017-05-26 03:48:53 -07001176 ping=1, ip_itf=self.pg1)
Neale Ranns31ed7442018-02-23 05:29:09 -08001177 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns6af1c042017-05-26 03:48:53 -07001178 self.verify_capture_ip4(self.pg1, rx, tx, ping_resp=1)
1179
1180 route_36_neos.remove_vpp_config()
Neale Rannscb630ff2016-12-14 13:31:29 +01001181 route_35_eos.remove_vpp_config()
1182 route_34_eos.remove_vpp_config()
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001183
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001184 def test_interface_rx(self):
1185 """ MPLS Interface Receive """
1186
1187 #
1188 # Add a non-recursive route that will forward the traffic
1189 # post-interface-rx
1190 #
1191 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
1192 table_id=1,
1193 paths=[VppRoutePath(self.pg1.remote_ip4,
1194 self.pg1.sw_if_index)])
1195 route_10_0_0_1.add_vpp_config()
1196
1197 #
1198 # An interface receive label that maps traffic to RX on interface
1199 # pg1
1200 # by injecting the packet in on pg0, which is in table 0
1201 # doing an interface-rx on pg1 and matching a route in table 1
1202 # if the packet egresses, then we must have swapped to pg1
1203 # so as to have matched the route in table 1
1204 #
Neale Ranns097fa662018-05-01 05:17:55 -07001205 route_34_eos = VppMplsRoute(
1206 self, 34, 1,
1207 [VppRoutePath("0.0.0.0",
1208 self.pg1.sw_if_index,
1209 type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001210 route_34_eos.add_vpp_config()
1211
1212 #
1213 # ping an interface in the default table
1214 # PG0 is in the default table
1215 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001216 tx = self.create_stream_labelled_ip4(self.pg0,
1217 [VppMplsLabel(34)],
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001218 dst_ip="10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -08001219 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001220 self.verify_capture_ip4(self.pg1, rx, tx)
1221
1222 def test_mcast_mid_point(self):
1223 """ MPLS Multicast Mid Point """
1224
1225 #
1226 # Add a non-recursive route that will forward the traffic
1227 # post-interface-rx
1228 #
1229 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
1230 table_id=1,
1231 paths=[VppRoutePath(self.pg1.remote_ip4,
1232 self.pg1.sw_if_index)])
1233 route_10_0_0_1.add_vpp_config()
1234
1235 #
1236 # Add a mcast entry that replicate to pg2 and pg3
1237 # and replicate to a interface-rx (like a bud node would)
1238 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001239 route_3400_eos = VppMplsRoute(
1240 self, 3400, 1,
1241 [VppRoutePath(self.pg2.remote_ip4,
1242 self.pg2.sw_if_index,
1243 labels=[VppMplsLabel(3401)]),
1244 VppRoutePath(self.pg3.remote_ip4,
1245 self.pg3.sw_if_index,
1246 labels=[VppMplsLabel(3402)]),
1247 VppRoutePath("0.0.0.0",
1248 self.pg1.sw_if_index,
Neale Ranns097fa662018-05-01 05:17:55 -07001249 type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX)],
Neale Ranns31ed7442018-02-23 05:29:09 -08001250 is_multicast=1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001251 route_3400_eos.add_vpp_config()
1252
1253 #
1254 # ping an interface in the default table
1255 # PG0 is in the default table
1256 #
1257 self.vapi.cli("clear trace")
Neale Ranns31ed7442018-02-23 05:29:09 -08001258 tx = self.create_stream_labelled_ip4(self.pg0,
1259 [VppMplsLabel(3400, ttl=64)],
1260 n=257,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001261 dst_ip="10.0.0.1")
1262 self.pg0.add_stream(tx)
1263
1264 self.pg_enable_capture(self.pg_interfaces)
1265 self.pg_start()
1266
1267 rx = self.pg1.get_capture(257)
1268 self.verify_capture_ip4(self.pg1, rx, tx)
1269
1270 rx = self.pg2.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001271 self.verify_capture_labelled(self.pg2, rx, tx,
1272 [VppMplsLabel(3401, ttl=63)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001273 rx = self.pg3.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001274 self.verify_capture_labelled(self.pg3, rx, tx,
1275 [VppMplsLabel(3402, ttl=63)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001276
1277 def test_mcast_head(self):
1278 """ MPLS Multicast Head-end """
1279
1280 #
1281 # Create a multicast tunnel with two replications
1282 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001283 mpls_tun = VppMPLSTunnelInterface(
1284 self,
1285 [VppRoutePath(self.pg2.remote_ip4,
1286 self.pg2.sw_if_index,
1287 labels=[VppMplsLabel(42)]),
1288 VppRoutePath(self.pg3.remote_ip4,
1289 self.pg3.sw_if_index,
1290 labels=[VppMplsLabel(43)])],
1291 is_multicast=1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001292 mpls_tun.add_vpp_config()
1293 mpls_tun.admin_up()
1294
1295 #
1296 # add an unlabelled route through the new tunnel
1297 #
1298 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
1299 [VppRoutePath("0.0.0.0",
1300 mpls_tun._sw_if_index)])
1301 route_10_0_0_3.add_vpp_config()
1302
1303 self.vapi.cli("clear trace")
1304 tx = self.create_stream_ip4(self.pg0, "10.0.0.3")
1305 self.pg0.add_stream(tx)
1306
1307 self.pg_enable_capture(self.pg_interfaces)
1308 self.pg_start()
1309
1310 rx = self.pg2.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001311 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(42)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001312 rx = self.pg3.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001313 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(43)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001314
1315 #
1316 # An an IP multicast route via the tunnel
1317 # A (*,G).
1318 # one accepting interface, pg0, 1 forwarding interface via the tunnel
1319 #
1320 route_232_1_1_1 = VppIpMRoute(
1321 self,
1322 "0.0.0.0",
1323 "232.1.1.1", 32,
1324 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
1325 [VppMRoutePath(self.pg0.sw_if_index,
1326 MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
1327 VppMRoutePath(mpls_tun._sw_if_index,
1328 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
1329 route_232_1_1_1.add_vpp_config()
Neale Ranns097fa662018-05-01 05:17:55 -07001330 self.logger.info(self.vapi.cli("sh ip mfib index 0"))
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001331
1332 self.vapi.cli("clear trace")
1333 tx = self.create_stream_ip4(self.pg0, "232.1.1.1")
1334 self.pg0.add_stream(tx)
1335
1336 self.pg_enable_capture(self.pg_interfaces)
1337 self.pg_start()
1338
1339 rx = self.pg2.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001340 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(42)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001341 rx = self.pg3.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001342 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(43)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001343
Neale Ranns31426c62017-05-24 10:32:58 -07001344 def test_mcast_ip4_tail(self):
1345 """ MPLS IPv4 Multicast Tail """
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001346
1347 #
1348 # Add a multicast route that will forward the traffic
1349 # post-disposition
1350 #
1351 route_232_1_1_1 = VppIpMRoute(
1352 self,
1353 "0.0.0.0",
1354 "232.1.1.1", 32,
1355 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
1356 table_id=1,
1357 paths=[VppMRoutePath(self.pg1.sw_if_index,
1358 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
1359 route_232_1_1_1.add_vpp_config()
1360
1361 #
1362 # An interface receive label that maps traffic to RX on interface
1363 # pg1
1364 # by injecting the packet in on pg0, which is in table 0
1365 # doing an rpf-id and matching a route in table 1
1366 # if the packet egresses, then we must have matched the route in
1367 # table 1
1368 #
Neale Ranns097fa662018-05-01 05:17:55 -07001369 route_34_eos = VppMplsRoute(
1370 self, 34, 1,
1371 [VppRoutePath("0.0.0.0",
1372 0xffffffff,
1373 nh_table_id=1,
1374 rpf_id=55)],
1375 is_multicast=1,
1376 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP4)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001377
1378 route_34_eos.add_vpp_config()
1379
1380 #
1381 # Drop due to interface lookup miss
1382 #
1383 self.vapi.cli("clear trace")
Neale Ranns31ed7442018-02-23 05:29:09 -08001384 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001385 dst_ip="232.1.1.1", n=1)
1386 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop none")
1387
1388 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001389 # set the RPF-ID of the entry to match the input packet's
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001390 #
1391 route_232_1_1_1.update_rpf_id(55)
Neale Ranns097fa662018-05-01 05:17:55 -07001392 self.logger.info(self.vapi.cli("sh ip mfib index 1 232.1.1.1"))
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001393
Neale Ranns31ed7442018-02-23 05:29:09 -08001394 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
1395 dst_ip="232.1.1.1")
1396 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001397 self.verify_capture_ip4(self.pg1, rx, tx)
1398
1399 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001400 # disposed packets have an invalid IPv4 checksum
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001401 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001402 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001403 dst_ip="232.1.1.1", n=65,
1404 chksum=1)
1405 self.send_and_assert_no_replies(self.pg0, tx, "Invalid Checksum")
1406
1407 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001408 # set the RPF-ID of the entry to not match the input packet's
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001409 #
1410 route_232_1_1_1.update_rpf_id(56)
Neale Ranns31ed7442018-02-23 05:29:09 -08001411 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001412 dst_ip="232.1.1.1")
1413 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop 56")
1414
Neale Ranns31426c62017-05-24 10:32:58 -07001415 def test_mcast_ip6_tail(self):
1416 """ MPLS IPv6 Multicast Tail """
1417
1418 #
1419 # Add a multicast route that will forward the traffic
1420 # post-disposition
1421 #
1422 route_ff = VppIpMRoute(
1423 self,
1424 "::",
1425 "ff01::1", 32,
1426 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
1427 table_id=1,
1428 paths=[VppMRoutePath(self.pg1.sw_if_index,
Neale Ranns097fa662018-05-01 05:17:55 -07001429 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD,
1430 proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)])
Neale Ranns31426c62017-05-24 10:32:58 -07001431 route_ff.add_vpp_config()
1432
1433 #
1434 # An interface receive label that maps traffic to RX on interface
1435 # pg1
1436 # by injecting the packet in on pg0, which is in table 0
1437 # doing an rpf-id and matching a route in table 1
1438 # if the packet egresses, then we must have matched the route in
1439 # table 1
1440 #
1441 route_34_eos = VppMplsRoute(
1442 self, 34, 1,
1443 [VppRoutePath("::",
Neale Ranns097fa662018-05-01 05:17:55 -07001444 0xffffffff,
Neale Ranns31426c62017-05-24 10:32:58 -07001445 nh_table_id=1,
Neale Ranns097fa662018-05-01 05:17:55 -07001446 rpf_id=55)],
1447 is_multicast=1,
1448 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)
Neale Ranns31426c62017-05-24 10:32:58 -07001449
1450 route_34_eos.add_vpp_config()
1451
1452 #
1453 # Drop due to interface lookup miss
1454 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001455 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(34)],
Neale Ranns31426c62017-05-24 10:32:58 -07001456 dst_ip="ff01::1")
Neale Ranns31ed7442018-02-23 05:29:09 -08001457 self.send_and_assert_no_replies(self.pg0, tx, "RPF Miss")
Neale Ranns31426c62017-05-24 10:32:58 -07001458
1459 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001460 # set the RPF-ID of the entry to match the input packet's
Neale Ranns31426c62017-05-24 10:32:58 -07001461 #
1462 route_ff.update_rpf_id(55)
1463
Neale Ranns31ed7442018-02-23 05:29:09 -08001464 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(34)],
Neale Ranns31426c62017-05-24 10:32:58 -07001465 dst_ip="ff01::1")
Neale Ranns31ed7442018-02-23 05:29:09 -08001466 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns31426c62017-05-24 10:32:58 -07001467 self.verify_capture_ip6(self.pg1, rx, tx)
1468
1469 #
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001470 # disposed packets have hop-limit = 1
1471 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001472 tx = self.create_stream_labelled_ip6(self.pg0,
1473 [VppMplsLabel(34)],
1474 dst_ip="ff01::1",
1475 hlim=1)
1476 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns52fae862018-01-08 04:41:42 -08001477 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001478
1479 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001480 # set the RPF-ID of the entry to not match the input packet's
Neale Ranns31426c62017-05-24 10:32:58 -07001481 #
1482 route_ff.update_rpf_id(56)
Neale Ranns31ed7442018-02-23 05:29:09 -08001483 tx = self.create_stream_labelled_ip6(self.pg0,
1484 [VppMplsLabel(34)],
Neale Ranns31426c62017-05-24 10:32:58 -07001485 dst_ip="ff01::1")
1486 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop 56")
1487
Neale Rannsd5d7b962019-08-04 03:30:56 -07001488 def test_6pe(self):
1489 """ MPLS 6PE """
1490
1491 #
1492 # Add a non-recursive route with a single out label
1493 #
1494 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
1495 [VppRoutePath(self.pg0.remote_ip4,
1496 self.pg0.sw_if_index,
1497 labels=[VppMplsLabel(45)])])
1498 route_10_0_0_1.add_vpp_config()
1499
1500 # bind a local label to the route
1501 binding = VppMplsIpBind(self, 44, "10.0.0.1", 32)
1502 binding.add_vpp_config()
1503
1504 #
1505 # a labelled v6 route that resolves through the v4
1506 #
1507 route_2001_3 = VppIpRoute(
1508 self, "2001::3", 128,
1509 [VppRoutePath("10.0.0.1",
1510 INVALID_INDEX,
1511 labels=[VppMplsLabel(32)])])
1512 route_2001_3.add_vpp_config()
1513
1514 tx = self.create_stream_ip6(self.pg0, "2001::3")
1515 rx = self.send_and_expect(self.pg0, tx, self.pg0)
1516
1517 self.verify_capture_labelled_ip6(self.pg0, rx, tx,
1518 [VppMplsLabel(45),
1519 VppMplsLabel(32)])
1520
1521 #
1522 # and a v4 recursive via the v6
1523 #
1524 route_20_3 = VppIpRoute(
1525 self, "20.0.0.3", 32,
1526 [VppRoutePath("2001::3",
1527 INVALID_INDEX,
1528 labels=[VppMplsLabel(99)])])
1529 route_20_3.add_vpp_config()
1530
1531 tx = self.create_stream_ip4(self.pg0, "20.0.0.3")
1532 rx = self.send_and_expect(self.pg0, tx, self.pg0)
1533
1534 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
1535 [VppMplsLabel(45),
1536 VppMplsLabel(32),
1537 VppMplsLabel(99)])
1538
Neale Ranns180279b2017-03-16 15:49:09 -04001539
1540class TestMPLSDisabled(VppTestCase):
1541 """ MPLS disabled """
1542
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -07001543 @classmethod
1544 def setUpClass(cls):
1545 super(TestMPLSDisabled, cls).setUpClass()
1546
1547 @classmethod
1548 def tearDownClass(cls):
1549 super(TestMPLSDisabled, cls).tearDownClass()
1550
Neale Ranns180279b2017-03-16 15:49:09 -04001551 def setUp(self):
1552 super(TestMPLSDisabled, self).setUp()
1553
1554 # create 2 pg interfaces
1555 self.create_pg_interfaces(range(2))
1556
Neale Ranns15002542017-09-10 04:39:11 -07001557 self.tbl = VppMplsTable(self, 0)
1558 self.tbl.add_vpp_config()
1559
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001560 # PG0 is MPLS enabled
Neale Ranns180279b2017-03-16 15:49:09 -04001561 self.pg0.admin_up()
1562 self.pg0.config_ip4()
1563 self.pg0.resolve_arp()
1564 self.pg0.enable_mpls()
1565
1566 # PG 1 is not MPLS enabled
1567 self.pg1.admin_up()
1568
1569 def tearDown(self):
Neale Ranns180279b2017-03-16 15:49:09 -04001570 for i in self.pg_interfaces:
1571 i.unconfig_ip4()
1572 i.admin_down()
1573
Neale Ranns15002542017-09-10 04:39:11 -07001574 self.pg0.disable_mpls()
1575 super(TestMPLSDisabled, self).tearDown()
1576
Neale Ranns180279b2017-03-16 15:49:09 -04001577 def test_mpls_disabled(self):
1578 """ MPLS Disabled """
1579
1580 tx = (Ether(src=self.pg1.remote_mac,
1581 dst=self.pg1.local_mac) /
1582 MPLS(label=32, ttl=64) /
1583 IPv6(src="2001::1", dst=self.pg0.remote_ip6) /
1584 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001585 Raw(b'\xa5' * 100))
Neale Ranns180279b2017-03-16 15:49:09 -04001586
1587 #
1588 # A simple MPLS xconnect - eos label in label out
1589 #
1590 route_32_eos = VppMplsRoute(self, 32, 1,
1591 [VppRoutePath(self.pg0.remote_ip4,
1592 self.pg0.sw_if_index,
1593 labels=[33])])
1594 route_32_eos.add_vpp_config()
1595
1596 #
1597 # PG1 does not forward IP traffic
1598 #
1599 self.send_and_assert_no_replies(self.pg1, tx, "MPLS disabled")
1600
1601 #
1602 # MPLS enable PG1
1603 #
1604 self.pg1.enable_mpls()
1605
1606 #
1607 # Now we get packets through
1608 #
1609 self.pg1.add_stream(tx)
1610 self.pg_enable_capture(self.pg_interfaces)
1611 self.pg_start()
1612
1613 rx = self.pg0.get_capture(1)
1614
1615 #
1616 # Disable PG1
1617 #
1618 self.pg1.disable_mpls()
1619
1620 #
1621 # PG1 does not forward IP traffic
1622 #
1623 self.send_and_assert_no_replies(self.pg1, tx, "IPv6 disabled")
1624 self.send_and_assert_no_replies(self.pg1, tx, "IPv6 disabled")
1625
1626
Neale Rannsf12a83f2017-04-18 09:09:40 -07001627class TestMPLSPIC(VppTestCase):
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001628 """ MPLS Prefix-Independent Convergence (PIC) edge convergence """
Neale Rannsf12a83f2017-04-18 09:09:40 -07001629
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -07001630 @classmethod
1631 def setUpClass(cls):
1632 super(TestMPLSPIC, cls).setUpClass()
1633
1634 @classmethod
1635 def tearDownClass(cls):
1636 super(TestMPLSPIC, cls).tearDownClass()
1637
Neale Rannsf12a83f2017-04-18 09:09:40 -07001638 def setUp(self):
1639 super(TestMPLSPIC, self).setUp()
1640
1641 # create 2 pg interfaces
1642 self.create_pg_interfaces(range(4))
1643
Neale Ranns15002542017-09-10 04:39:11 -07001644 mpls_tbl = VppMplsTable(self, 0)
1645 mpls_tbl.add_vpp_config()
1646 tbl4 = VppIpTable(self, 1)
1647 tbl4.add_vpp_config()
1648 tbl6 = VppIpTable(self, 1, is_ip6=1)
1649 tbl6.add_vpp_config()
1650
Neale Rannsf12a83f2017-04-18 09:09:40 -07001651 # core links
1652 self.pg0.admin_up()
1653 self.pg0.config_ip4()
1654 self.pg0.resolve_arp()
1655 self.pg0.enable_mpls()
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001656
Neale Rannsf12a83f2017-04-18 09:09:40 -07001657 self.pg1.admin_up()
1658 self.pg1.config_ip4()
1659 self.pg1.resolve_arp()
1660 self.pg1.enable_mpls()
1661
1662 # VRF (customer facing) link
1663 self.pg2.admin_up()
1664 self.pg2.set_table_ip4(1)
1665 self.pg2.config_ip4()
1666 self.pg2.resolve_arp()
1667 self.pg2.set_table_ip6(1)
1668 self.pg2.config_ip6()
1669 self.pg2.resolve_ndp()
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001670
Neale Rannsf12a83f2017-04-18 09:09:40 -07001671 self.pg3.admin_up()
1672 self.pg3.set_table_ip4(1)
1673 self.pg3.config_ip4()
1674 self.pg3.resolve_arp()
1675 self.pg3.set_table_ip6(1)
1676 self.pg3.config_ip6()
1677 self.pg3.resolve_ndp()
1678
1679 def tearDown(self):
Neale Rannsf12a83f2017-04-18 09:09:40 -07001680 self.pg0.disable_mpls()
Neale Ranns15002542017-09-10 04:39:11 -07001681 self.pg1.disable_mpls()
Neale Rannsf12a83f2017-04-18 09:09:40 -07001682 for i in self.pg_interfaces:
1683 i.unconfig_ip4()
1684 i.unconfig_ip6()
1685 i.set_table_ip4(0)
1686 i.set_table_ip6(0)
1687 i.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -07001688 super(TestMPLSPIC, self).tearDown()
Neale Rannsf12a83f2017-04-18 09:09:40 -07001689
1690 def test_mpls_ibgp_pic(self):
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001691 """ MPLS iBGP Prefix-Independent Convergence (PIC) edge convergence
Neale Rannsf12a83f2017-04-18 09:09:40 -07001692
1693 1) setup many iBGP VPN routes via a pair of iBGP peers.
1694 2) Check EMCP forwarding to these peers
1695 3) withdraw the IGP route to one of these peers.
1696 4) check forwarding continues to the remaining peer
1697 """
1698
1699 #
1700 # IGP+LDP core routes
1701 #
1702 core_10_0_0_45 = VppIpRoute(self, "10.0.0.45", 32,
1703 [VppRoutePath(self.pg0.remote_ip4,
1704 self.pg0.sw_if_index,
1705 labels=[45])])
1706 core_10_0_0_45.add_vpp_config()
1707
1708 core_10_0_0_46 = VppIpRoute(self, "10.0.0.46", 32,
1709 [VppRoutePath(self.pg1.remote_ip4,
1710 self.pg1.sw_if_index,
1711 labels=[46])])
1712 core_10_0_0_46.add_vpp_config()
1713
1714 #
1715 # Lot's of VPN routes. We need more the 64 so VPP will build
1716 # the fast convergence indirection
1717 #
1718 vpn_routes = []
1719 pkts = []
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001720 for ii in range(NUM_PKTS):
Neale Rannsf12a83f2017-04-18 09:09:40 -07001721 dst = "192.168.1.%d" % ii
Neale Ranns097fa662018-05-01 05:17:55 -07001722 vpn_routes.append(VppIpRoute(
1723 self, dst, 32,
1724 [VppRoutePath(
1725 "10.0.0.45",
1726 0xffffffff,
1727 labels=[145],
1728 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_HOST),
1729 VppRoutePath(
1730 "10.0.0.46",
1731 0xffffffff,
1732 labels=[146],
1733 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_HOST)],
1734 table_id=1))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001735 vpn_routes[ii].add_vpp_config()
1736
1737 pkts.append(Ether(dst=self.pg2.local_mac,
1738 src=self.pg2.remote_mac) /
1739 IP(src=self.pg2.remote_ip4, dst=dst) /
1740 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001741 Raw(b'\xa5' * 100))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001742
1743 #
1744 # Send the packet stream (one pkt to each VPN route)
1745 # - expect a 50-50 split of the traffic
1746 #
1747 self.pg2.add_stream(pkts)
1748 self.pg_enable_capture(self.pg_interfaces)
1749 self.pg_start()
1750
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001751 rx0 = self.pg0._get_capture(NUM_PKTS)
1752 rx1 = self.pg1._get_capture(NUM_PKTS)
Neale Rannsf12a83f2017-04-18 09:09:40 -07001753
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001754 # not testing the LB hashing algorithm so we're not concerned
Neale Rannsf12a83f2017-04-18 09:09:40 -07001755 # with the split ratio, just as long as neither is 0
1756 self.assertNotEqual(0, len(rx0))
1757 self.assertNotEqual(0, len(rx1))
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001758 self.assertEqual(len(pkts), len(rx0) + len(rx1),
1759 "Expected all (%s) packets across both ECMP paths. "
1760 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001761
1762 #
1763 # use a test CLI command to stop the FIB walk process, this
1764 # will prevent the FIB converging the VPN routes and thus allow
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001765 # us to probe the interim (post-fail, pre-converge) state
Neale Rannsf12a83f2017-04-18 09:09:40 -07001766 #
1767 self.vapi.ppcli("test fib-walk-process disable")
1768
1769 #
1770 # Withdraw one of the IGP routes
1771 #
1772 core_10_0_0_46.remove_vpp_config()
1773
1774 #
1775 # now all packets should be forwarded through the remaining peer
1776 #
1777 self.vapi.ppcli("clear trace")
1778 self.pg2.add_stream(pkts)
1779 self.pg_enable_capture(self.pg_interfaces)
1780 self.pg_start()
1781
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001782 rx0 = self.pg0.get_capture(NUM_PKTS)
1783 self.assertEqual(len(pkts), len(rx0),
1784 "Expected all (%s) packets across single path. "
1785 "rx0: %s." % (len(pkts), len(rx0)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001786
1787 #
1788 # enable the FIB walk process to converge the FIB
1789 #
1790 self.vapi.ppcli("test fib-walk-process enable")
1791
1792 #
1793 # packets should still be forwarded through the remaining peer
1794 #
1795 self.pg2.add_stream(pkts)
1796 self.pg_enable_capture(self.pg_interfaces)
1797 self.pg_start()
1798
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001799 rx0 = self.pg0.get_capture(NUM_PKTS)
1800 self.assertEqual(len(pkts), len(rx0),
1801 "Expected all (%s) packets across single path. "
1802 "rx0: %s." % (len(pkts), len(rx0)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001803
1804 #
1805 # Add the IGP route back and we return to load-balancing
1806 #
1807 core_10_0_0_46.add_vpp_config()
1808
1809 self.pg2.add_stream(pkts)
1810 self.pg_enable_capture(self.pg_interfaces)
1811 self.pg_start()
1812
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001813 rx0 = self.pg0._get_capture(NUM_PKTS)
1814 rx1 = self.pg1._get_capture(NUM_PKTS)
Neale Rannsf12a83f2017-04-18 09:09:40 -07001815 self.assertNotEqual(0, len(rx0))
1816 self.assertNotEqual(0, len(rx1))
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001817 self.assertEqual(len(pkts), len(rx0) + len(rx1),
1818 "Expected all (%s) packets across both ECMP paths. "
1819 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001820
1821 def test_mpls_ebgp_pic(self):
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001822 """ MPLS eBGP Prefix-Independent Convergence (PIC) edge convergence
Neale Rannsf12a83f2017-04-18 09:09:40 -07001823
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001824 1) setup many eBGP VPN routes via a pair of eBGP peers.
Neale Rannsf12a83f2017-04-18 09:09:40 -07001825 2) Check EMCP forwarding to these peers
1826 3) withdraw one eBGP path - expect LB across remaining eBGP
1827 """
1828
1829 #
1830 # Lot's of VPN routes. We need more the 64 so VPP will build
1831 # the fast convergence indirection
1832 #
1833 vpn_routes = []
1834 vpn_bindings = []
1835 pkts = []
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001836 for ii in range(NUM_PKTS):
Neale Rannsf12a83f2017-04-18 09:09:40 -07001837 dst = "192.168.1.%d" % ii
1838 local_label = 1600 + ii
Neale Ranns097fa662018-05-01 05:17:55 -07001839 vpn_routes.append(VppIpRoute(
1840 self, dst, 32,
1841 [VppRoutePath(
1842 self.pg2.remote_ip4,
1843 0xffffffff,
1844 nh_table_id=1,
1845 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_ATTACHED),
1846 VppRoutePath(
1847 self.pg3.remote_ip4,
1848 0xffffffff,
1849 nh_table_id=1,
1850 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_ATTACHED)],
1851 table_id=1))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001852 vpn_routes[ii].add_vpp_config()
1853
1854 vpn_bindings.append(VppMplsIpBind(self, local_label, dst, 32,
1855 ip_table_id=1))
1856 vpn_bindings[ii].add_vpp_config()
1857
1858 pkts.append(Ether(dst=self.pg0.local_mac,
1859 src=self.pg0.remote_mac) /
1860 MPLS(label=local_label, ttl=64) /
1861 IP(src=self.pg0.remote_ip4, dst=dst) /
1862 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001863 Raw(b'\xa5' * 100))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001864
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001865 #
1866 # Send the packet stream (one pkt to each VPN route)
1867 # - expect a 50-50 split of the traffic
1868 #
Neale Rannsf12a83f2017-04-18 09:09:40 -07001869 self.pg0.add_stream(pkts)
1870 self.pg_enable_capture(self.pg_interfaces)
1871 self.pg_start()
1872
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001873 rx0 = self.pg2._get_capture(NUM_PKTS)
1874 rx1 = self.pg3._get_capture(NUM_PKTS)
1875
1876 # not testing the LB hashing algorithm so we're not concerned
1877 # with the split ratio, just as long as neither is 0
Neale Rannsf12a83f2017-04-18 09:09:40 -07001878 self.assertNotEqual(0, len(rx0))
1879 self.assertNotEqual(0, len(rx1))
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001880 self.assertEqual(len(pkts), len(rx0) + len(rx1),
1881 "Expected all (%s) packets across both ECMP paths. "
1882 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001883
1884 #
1885 # use a test CLI command to stop the FIB walk process, this
1886 # will prevent the FIB converging the VPN routes and thus allow
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001887 # us to probe the interim (post-fail, pre-converge) state
Neale Rannsf12a83f2017-04-18 09:09:40 -07001888 #
1889 self.vapi.ppcli("test fib-walk-process disable")
1890
1891 #
1892 # withdraw the connected prefix on the interface.
1893 #
1894 self.pg2.unconfig_ip4()
1895
1896 #
1897 # now all packets should be forwarded through the remaining peer
1898 #
1899 self.pg0.add_stream(pkts)
1900 self.pg_enable_capture(self.pg_interfaces)
1901 self.pg_start()
1902
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001903 rx0 = self.pg3.get_capture(NUM_PKTS)
1904 self.assertEqual(len(pkts), len(rx0),
1905 "Expected all (%s) packets across single path. "
1906 "rx0: %s." % (len(pkts), len(rx0)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001907
1908 #
1909 # enable the FIB walk process to converge the FIB
1910 #
1911 self.vapi.ppcli("test fib-walk-process enable")
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001912
1913 #
1914 # packets should still be forwarded through the remaining peer
1915 #
Neale Rannsf12a83f2017-04-18 09:09:40 -07001916 self.pg0.add_stream(pkts)
1917 self.pg_enable_capture(self.pg_interfaces)
1918 self.pg_start()
1919
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001920 rx0 = self.pg3.get_capture(NUM_PKTS)
1921 self.assertEqual(len(pkts), len(rx0),
1922 "Expected all (%s) packets across single path. "
1923 "rx0: %s." % (len(pkts), len(rx0)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001924
1925 #
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001926 # put the connected routes back
Neale Rannsf12a83f2017-04-18 09:09:40 -07001927 #
1928 self.pg2.config_ip4()
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001929 self.pg2.resolve_arp()
Neale Rannsf12a83f2017-04-18 09:09:40 -07001930
1931 self.pg0.add_stream(pkts)
1932 self.pg_enable_capture(self.pg_interfaces)
1933 self.pg_start()
1934
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001935 rx0 = self.pg2._get_capture(NUM_PKTS)
1936 rx1 = self.pg3._get_capture(NUM_PKTS)
Neale Rannsf12a83f2017-04-18 09:09:40 -07001937 self.assertNotEqual(0, len(rx0))
1938 self.assertNotEqual(0, len(rx1))
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001939 self.assertEqual(len(pkts), len(rx0) + len(rx1),
1940 "Expected all (%s) packets across both ECMP paths. "
1941 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001942
1943 def test_mpls_v6_ebgp_pic(self):
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001944 """ MPLSv6 eBGP Prefix-Independent Convergence (PIC) edge convergence
Neale Rannsf12a83f2017-04-18 09:09:40 -07001945
1946 1) setup many eBGP VPNv6 routes via a pair of eBGP peers
1947 2) Check EMCP forwarding to these peers
1948 3) withdraw one eBGP path - expect LB across remaining eBGP
1949 """
1950
1951 #
1952 # Lot's of VPN routes. We need more the 64 so VPP will build
1953 # the fast convergence indirection
1954 #
1955 vpn_routes = []
1956 vpn_bindings = []
1957 pkts = []
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001958 for ii in range(NUM_PKTS):
Neale Rannsf12a83f2017-04-18 09:09:40 -07001959 dst = "3000::%d" % ii
1960 local_label = 1600 + ii
Neale Rannsda78f952017-05-24 09:15:43 -07001961 vpn_routes.append(VppIpRoute(
1962 self, dst, 128,
Neale Ranns097fa662018-05-01 05:17:55 -07001963 [VppRoutePath(
1964 self.pg2.remote_ip6,
1965 0xffffffff,
1966 nh_table_id=1,
1967 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_ATTACHED),
1968 VppRoutePath(
1969 self.pg3.remote_ip6,
1970 0xffffffff,
1971 nh_table_id=1,
1972 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_ATTACHED)],
1973 table_id=1))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001974 vpn_routes[ii].add_vpp_config()
1975
1976 vpn_bindings.append(VppMplsIpBind(self, local_label, dst, 128,
Neale Ranns097fa662018-05-01 05:17:55 -07001977 ip_table_id=1))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001978 vpn_bindings[ii].add_vpp_config()
1979
1980 pkts.append(Ether(dst=self.pg0.local_mac,
1981 src=self.pg0.remote_mac) /
1982 MPLS(label=local_label, ttl=64) /
1983 IPv6(src=self.pg0.remote_ip6, dst=dst) /
1984 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01001985 Raw(b'\xa5' * 100))
Neale Ranns097fa662018-05-01 05:17:55 -07001986 self.logger.info(self.vapi.cli("sh ip6 fib %s" % dst))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001987
1988 self.pg0.add_stream(pkts)
1989 self.pg_enable_capture(self.pg_interfaces)
1990 self.pg_start()
1991
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001992 rx0 = self.pg2._get_capture(NUM_PKTS)
1993 rx1 = self.pg3._get_capture(NUM_PKTS)
Neale Rannsf12a83f2017-04-18 09:09:40 -07001994 self.assertNotEqual(0, len(rx0))
1995 self.assertNotEqual(0, len(rx1))
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001996 self.assertEqual(len(pkts), len(rx0) + len(rx1),
1997 "Expected all (%s) packets across both ECMP paths. "
1998 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001999
2000 #
2001 # use a test CLI command to stop the FIB walk process, this
2002 # will prevent the FIB converging the VPN routes and thus allow
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002003 # us to probe the interim (post-fail, pre-converge) state
Neale Rannsf12a83f2017-04-18 09:09:40 -07002004 #
2005 self.vapi.ppcli("test fib-walk-process disable")
2006
2007 #
2008 # withdraw the connected prefix on the interface.
2009 # and shutdown the interface so the ND cache is flushed.
2010 #
2011 self.pg2.unconfig_ip6()
2012 self.pg2.admin_down()
2013
2014 #
2015 # now all packets should be forwarded through the remaining peer
2016 #
2017 self.pg0.add_stream(pkts)
2018 self.pg_enable_capture(self.pg_interfaces)
2019 self.pg_start()
2020
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002021 rx0 = self.pg3.get_capture(NUM_PKTS)
2022 self.assertEqual(len(pkts), len(rx0),
2023 "Expected all (%s) packets across single path. "
2024 "rx0: %s." % (len(pkts), len(rx0)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07002025
2026 #
2027 # enable the FIB walk process to converge the FIB
2028 #
2029 self.vapi.ppcli("test fib-walk-process enable")
2030 self.pg0.add_stream(pkts)
2031 self.pg_enable_capture(self.pg_interfaces)
2032 self.pg_start()
2033
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002034 rx0 = self.pg3.get_capture(NUM_PKTS)
2035 self.assertEqual(len(pkts), len(rx0),
2036 "Expected all (%s) packets across single path. "
2037 "rx0: %s." % (len(pkts), len(rx0)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07002038
2039 #
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002040 # put the connected routes back
Neale Rannsf12a83f2017-04-18 09:09:40 -07002041 #
2042 self.pg2.admin_up()
2043 self.pg2.config_ip6()
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002044 self.pg2.resolve_ndp()
Neale Rannsf12a83f2017-04-18 09:09:40 -07002045
2046 self.pg0.add_stream(pkts)
2047 self.pg_enable_capture(self.pg_interfaces)
2048 self.pg_start()
2049
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002050 rx0 = self.pg2._get_capture(NUM_PKTS)
2051 rx1 = self.pg3._get_capture(NUM_PKTS)
Neale Rannsf12a83f2017-04-18 09:09:40 -07002052 self.assertNotEqual(0, len(rx0))
2053 self.assertNotEqual(0, len(rx1))
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002054 self.assertEqual(len(pkts), len(rx0) + len(rx1),
2055 "Expected all (%s) packets across both ECMP paths. "
2056 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07002057
2058
Neale Rannsda78f952017-05-24 09:15:43 -07002059class TestMPLSL2(VppTestCase):
2060 """ MPLS-L2 """
2061
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -07002062 @classmethod
2063 def setUpClass(cls):
2064 super(TestMPLSL2, cls).setUpClass()
2065
2066 @classmethod
2067 def tearDownClass(cls):
2068 super(TestMPLSL2, cls).tearDownClass()
2069
Neale Rannsda78f952017-05-24 09:15:43 -07002070 def setUp(self):
2071 super(TestMPLSL2, self).setUp()
2072
2073 # create 2 pg interfaces
2074 self.create_pg_interfaces(range(2))
2075
Neale Ranns15002542017-09-10 04:39:11 -07002076 # create the default MPLS table
2077 self.tables = []
2078 tbl = VppMplsTable(self, 0)
2079 tbl.add_vpp_config()
2080 self.tables.append(tbl)
2081
Neale Rannsda78f952017-05-24 09:15:43 -07002082 # use pg0 as the core facing interface
2083 self.pg0.admin_up()
2084 self.pg0.config_ip4()
2085 self.pg0.resolve_arp()
2086 self.pg0.enable_mpls()
2087
Neale Ranns15002542017-09-10 04:39:11 -07002088 # use the other 2 for customer facing L2 links
Neale Rannsda78f952017-05-24 09:15:43 -07002089 for i in self.pg_interfaces[1:]:
2090 i.admin_up()
2091
2092 def tearDown(self):
Neale Rannsda78f952017-05-24 09:15:43 -07002093 for i in self.pg_interfaces[1:]:
2094 i.admin_down()
2095
2096 self.pg0.disable_mpls()
2097 self.pg0.unconfig_ip4()
2098 self.pg0.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -07002099 super(TestMPLSL2, self).tearDown()
Neale Rannsda78f952017-05-24 09:15:43 -07002100
Neale Ranns31ed7442018-02-23 05:29:09 -08002101 def verify_capture_tunneled_ethernet(self, capture, sent, mpls_labels):
Neale Rannsda78f952017-05-24 09:15:43 -07002102 capture = verify_filter(capture, sent)
2103
2104 self.assertEqual(len(capture), len(sent))
2105
2106 for i in range(len(capture)):
2107 tx = sent[i]
2108 rx = capture[i]
2109
2110 # the MPLS TTL is 255 since it enters a new tunnel
Neale Ranns31ed7442018-02-23 05:29:09 -08002111 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsda78f952017-05-24 09:15:43 -07002112
2113 tx_eth = tx[Ether]
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -07002114 rx_eth = Ether(scapy.compat.raw(rx[MPLS].payload))
Neale Rannsda78f952017-05-24 09:15:43 -07002115
2116 self.assertEqual(rx_eth.src, tx_eth.src)
2117 self.assertEqual(rx_eth.dst, tx_eth.dst)
2118
2119 def test_vpws(self):
2120 """ Virtual Private Wire Service """
2121
2122 #
2123 # Create an MPLS tunnel that pushes 1 label
Neale Ranns31ed7442018-02-23 05:29:09 -08002124 # For Ethernet over MPLS the uniform mode is irrelevant since ttl/cos
2125 # information is not in the packet, but we test it works anyway
Neale Rannsda78f952017-05-24 09:15:43 -07002126 #
Neale Ranns31ed7442018-02-23 05:29:09 -08002127 mpls_tun_1 = VppMPLSTunnelInterface(
2128 self,
2129 [VppRoutePath(self.pg0.remote_ip4,
2130 self.pg0.sw_if_index,
2131 labels=[VppMplsLabel(42, MplsLspMode.UNIFORM)])],
2132 is_l2=1)
Neale Rannsda78f952017-05-24 09:15:43 -07002133 mpls_tun_1.add_vpp_config()
2134 mpls_tun_1.admin_up()
2135
2136 #
2137 # Create a label entry to for 55 that does L2 input to the tunnel
2138 #
2139 route_55_eos = VppMplsRoute(
2140 self, 55, 1,
2141 [VppRoutePath("0.0.0.0",
2142 mpls_tun_1.sw_if_index,
Neale Ranns097fa662018-05-01 05:17:55 -07002143 type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX,
2144 proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET)],
2145 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET)
Neale Rannsda78f952017-05-24 09:15:43 -07002146 route_55_eos.add_vpp_config()
2147
2148 #
2149 # Cross-connect the tunnel with one of the customers L2 interfaces
2150 #
2151 self.vapi.sw_interface_set_l2_xconnect(self.pg1.sw_if_index,
2152 mpls_tun_1.sw_if_index,
2153 enable=1)
2154 self.vapi.sw_interface_set_l2_xconnect(mpls_tun_1.sw_if_index,
2155 self.pg1.sw_if_index,
2156 enable=1)
2157
2158 #
2159 # inject a packet from the core
2160 #
2161 pcore = (Ether(dst=self.pg0.local_mac,
2162 src=self.pg0.remote_mac) /
2163 MPLS(label=55, ttl=64) /
2164 Ether(dst="00:00:de:ad:ba:be",
2165 src="00:00:de:ad:be:ef") /
2166 IP(src="10.10.10.10", dst="11.11.11.11") /
2167 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002168 Raw(b'\xa5' * 100))
Neale Rannsda78f952017-05-24 09:15:43 -07002169
Paul Vinciguerra4271c972019-05-14 13:25:49 -04002170 tx0 = pcore * NUM_PKTS
Neale Ranns31ed7442018-02-23 05:29:09 -08002171 rx0 = self.send_and_expect(self.pg0, tx0, self.pg1)
2172 payload = pcore[MPLS].payload
Neale Rannsda78f952017-05-24 09:15:43 -07002173
Neale Ranns31ed7442018-02-23 05:29:09 -08002174 self.assertEqual(rx0[0][Ether].dst, payload[Ether].dst)
2175 self.assertEqual(rx0[0][Ether].src, payload[Ether].src)
Neale Rannsda78f952017-05-24 09:15:43 -07002176
2177 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002178 # Inject a packet from the customer/L2 side
Neale Rannsda78f952017-05-24 09:15:43 -07002179 #
Paul Vinciguerra4271c972019-05-14 13:25:49 -04002180 tx1 = pcore[MPLS].payload * NUM_PKTS
Neale Ranns31ed7442018-02-23 05:29:09 -08002181 rx1 = self.send_and_expect(self.pg1, tx1, self.pg0)
Neale Rannsda78f952017-05-24 09:15:43 -07002182
Neale Ranns31ed7442018-02-23 05:29:09 -08002183 self.verify_capture_tunneled_ethernet(rx1, tx1, [VppMplsLabel(42)])
Neale Rannsda78f952017-05-24 09:15:43 -07002184
2185 def test_vpls(self):
2186 """ Virtual Private LAN Service """
2187 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002188 # Create a L2 MPLS tunnels
Neale Rannsda78f952017-05-24 09:15:43 -07002189 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002190 mpls_tun1 = VppMPLSTunnelInterface(
Neale Ranns31ed7442018-02-23 05:29:09 -08002191 self,
2192 [VppRoutePath(self.pg0.remote_ip4,
2193 self.pg0.sw_if_index,
2194 labels=[VppMplsLabel(42)])],
2195 is_l2=1)
Neale Ranns1dbcf302019-07-19 11:44:53 +00002196 mpls_tun1.add_vpp_config()
2197 mpls_tun1.admin_up()
2198
2199 mpls_tun2 = VppMPLSTunnelInterface(
2200 self,
2201 [VppRoutePath(self.pg0.remote_ip4,
2202 self.pg0.sw_if_index,
2203 labels=[VppMplsLabel(43)])],
2204 is_l2=1)
2205 mpls_tun2.add_vpp_config()
2206 mpls_tun2.admin_up()
Neale Rannsda78f952017-05-24 09:15:43 -07002207
2208 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002209 # Create a label entries, 55 and 56, that do L2 input to the tunnel
2210 # the latter includes a Psuedo Wire Control Word
Neale Rannsda78f952017-05-24 09:15:43 -07002211 #
2212 route_55_eos = VppMplsRoute(
2213 self, 55, 1,
2214 [VppRoutePath("0.0.0.0",
Neale Ranns1dbcf302019-07-19 11:44:53 +00002215 mpls_tun1.sw_if_index,
Neale Ranns097fa662018-05-01 05:17:55 -07002216 type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX,
2217 proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET)],
2218 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET)
Neale Ranns1dbcf302019-07-19 11:44:53 +00002219
2220 route_56_eos = VppMplsRoute(
2221 self, 56, 1,
2222 [VppRoutePath("0.0.0.0",
2223 mpls_tun2.sw_if_index,
2224 type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX,
2225 flags=FibPathFlags.FIB_PATH_FLAG_POP_PW_CW,
2226 proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET)],
2227 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET)
2228
2229 # move me
2230 route_56_eos.add_vpp_config()
Neale Rannsda78f952017-05-24 09:15:43 -07002231 route_55_eos.add_vpp_config()
2232
Neale Ranns1dbcf302019-07-19 11:44:53 +00002233 self.logger.info(self.vapi.cli("sh mpls fib 56"))
2234
Neale Rannsda78f952017-05-24 09:15:43 -07002235 #
2236 # add to tunnel to the customers bridge-domain
2237 #
Ole Troana5b2eec2019-03-11 19:23:25 +01002238 self.vapi.sw_interface_set_l2_bridge(
Neale Ranns1dbcf302019-07-19 11:44:53 +00002239 rx_sw_if_index=mpls_tun1.sw_if_index, bd_id=1)
2240 self.vapi.sw_interface_set_l2_bridge(
2241 rx_sw_if_index=mpls_tun2.sw_if_index, bd_id=1)
Ole Troana5b2eec2019-03-11 19:23:25 +01002242 self.vapi.sw_interface_set_l2_bridge(
2243 rx_sw_if_index=self.pg1.sw_if_index, bd_id=1)
Neale Rannsda78f952017-05-24 09:15:43 -07002244
2245 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002246 # Packet from host on the customer interface to each host
2247 # reachable over the core, and vice-versa
Neale Rannsda78f952017-05-24 09:15:43 -07002248 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002249 p_cust1 = (Ether(dst="00:00:de:ad:ba:b1",
2250 src="00:00:de:ad:be:ef") /
2251 IP(src="10.10.10.10", dst="11.11.11.11") /
2252 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002253 Raw(b'\xa5' * 100))
Neale Ranns1dbcf302019-07-19 11:44:53 +00002254 p_cust2 = (Ether(dst="00:00:de:ad:ba:b2",
2255 src="00:00:de:ad:be:ef") /
2256 IP(src="10.10.10.10", dst="11.11.11.12") /
2257 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002258 Raw(b'\xa5' * 100))
Neale Ranns1dbcf302019-07-19 11:44:53 +00002259 p_core1 = (Ether(dst=self.pg0.local_mac,
2260 src=self.pg0.remote_mac) /
2261 MPLS(label=55, ttl=64) /
2262 Ether(src="00:00:de:ad:ba:b1",
2263 dst="00:00:de:ad:be:ef") /
2264 IP(dst="10.10.10.10", src="11.11.11.11") /
2265 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002266 Raw(b'\xa5' * 100))
Neale Ranns1dbcf302019-07-19 11:44:53 +00002267 p_core2 = (Ether(dst=self.pg0.local_mac,
2268 src=self.pg0.remote_mac) /
2269 MPLS(label=56, ttl=64) /
Ole Troan770a0de2019-11-07 13:52:21 +01002270 Raw(b'\x01' * 4) / # PW CW
Neale Ranns1dbcf302019-07-19 11:44:53 +00002271 Ether(src="00:00:de:ad:ba:b2",
2272 dst="00:00:de:ad:be:ef") /
2273 IP(dst="10.10.10.10", src="11.11.11.12") /
2274 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +01002275 Raw(b'\xa5' * 100))
Neale Rannsda78f952017-05-24 09:15:43 -07002276
2277 #
2278 # The BD is learning, so send in one of each packet to learn
2279 #
Neale Rannsda78f952017-05-24 09:15:43 -07002280
Neale Ranns1dbcf302019-07-19 11:44:53 +00002281 # 2 packets due to BD flooding
2282 rx = self.send_and_expect(self.pg1, p_cust1, self.pg0, n_rx=2)
2283 rx = self.send_and_expect(self.pg1, p_cust2, self.pg0, n_rx=2)
Neale Rannsda78f952017-05-24 09:15:43 -07002284
Neale Ranns1dbcf302019-07-19 11:44:53 +00002285 # we've learnt this so expect it be be forwarded not flooded
2286 rx = self.send_and_expect(self.pg0, [p_core1], self.pg1)
2287 self.assertEqual(rx[0][Ether].dst, p_cust1[Ether].src)
2288 self.assertEqual(rx[0][Ether].src, p_cust1[Ether].dst)
Neale Rannsda78f952017-05-24 09:15:43 -07002289
Neale Ranns1dbcf302019-07-19 11:44:53 +00002290 rx = self.send_and_expect(self.pg0, [p_core2], self.pg1)
2291 self.assertEqual(rx[0][Ether].dst, p_cust2[Ether].src)
2292 self.assertEqual(rx[0][Ether].src, p_cust2[Ether].dst)
Neale Rannsda78f952017-05-24 09:15:43 -07002293
2294 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002295 # now a stream in each direction from each host
Neale Rannsda78f952017-05-24 09:15:43 -07002296 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002297 rx = self.send_and_expect(self.pg1, p_cust1 * NUM_PKTS, self.pg0)
2298 self.verify_capture_tunneled_ethernet(rx, p_cust1 * NUM_PKTS,
Neale Ranns31ed7442018-02-23 05:29:09 -08002299 [VppMplsLabel(42)])
Neale Rannsda78f952017-05-24 09:15:43 -07002300
Neale Ranns1dbcf302019-07-19 11:44:53 +00002301 rx = self.send_and_expect(self.pg1, p_cust2 * NUM_PKTS, self.pg0)
2302 self.verify_capture_tunneled_ethernet(rx, p_cust2 * NUM_PKTS,
2303 [VppMplsLabel(43)])
2304
2305 rx = self.send_and_expect(self.pg0, p_core1 * NUM_PKTS, self.pg1)
2306 rx = self.send_and_expect(self.pg0, p_core2 * NUM_PKTS, self.pg1)
2307
Neale Rannsda78f952017-05-24 09:15:43 -07002308 #
2309 # remove interfaces from customers bridge-domain
2310 #
Ole Troana5b2eec2019-03-11 19:23:25 +01002311 self.vapi.sw_interface_set_l2_bridge(
Neale Ranns1dbcf302019-07-19 11:44:53 +00002312 rx_sw_if_index=mpls_tun1.sw_if_index, bd_id=1, enable=0)
2313 self.vapi.sw_interface_set_l2_bridge(
2314 rx_sw_if_index=mpls_tun2.sw_if_index, bd_id=1, enable=0)
Ole Troana5b2eec2019-03-11 19:23:25 +01002315 self.vapi.sw_interface_set_l2_bridge(
2316 rx_sw_if_index=self.pg1.sw_if_index, bd_id=1, enable=0)
Neale Rannsda78f952017-05-24 09:15:43 -07002317
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002318
Neale Ranns8fe8cc22016-11-01 10:05:08 +00002319if __name__ == '__main__':
2320 unittest.main(testRunner=VppTestRunner)