blob: 7388cf46c7349dc4ff5951c4ad55b8623d7d5bbe [file] [log] [blame]
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001#!/usr/bin/env python
2
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
Neale Ranns31ed7442018-02-23 05:29:09 -0800157 def create_stream_ip4(self, src_if, dst_ip, ip_ttl=64, ip_dscp=0):
Klement Sekeradab231a2016-12-21 08:50:14 +0100158 self.reset_packet_infos()
Neale Rannsad422ed2016-11-02 14:20:04 +0000159 pkts = []
160 for i in range(0, 257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100161 info = self.create_packet_info(src_if, src_if)
Neale Rannsad422ed2016-11-02 14:20:04 +0000162 payload = self.info_to_payload(info)
163 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
Neale Ranns31ed7442018-02-23 05:29:09 -0800164 IP(src=src_if.remote_ip4, dst=dst_ip,
165 ttl=ip_ttl, tos=ip_dscp) /
Neale Rannsad422ed2016-11-02 14:20:04 +0000166 UDP(sport=1234, dport=1234) /
167 Raw(payload))
168 info.data = p.copy()
169 pkts.append(p)
170 return pkts
171
Neale Ranns31ed7442018-02-23 05:29:09 -0800172 def create_stream_ip6(self, src_if, dst_ip, ip_ttl=64, ip_dscp=0):
173 self.reset_packet_infos()
174 pkts = []
175 for i in range(0, 257):
176 info = self.create_packet_info(src_if, src_if)
177 payload = self.info_to_payload(info)
178 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
179 IPv6(src=src_if.remote_ip6, dst=dst_ip,
180 hlim=ip_ttl, tc=ip_dscp) /
181 UDP(sport=1234, dport=1234) /
182 Raw(payload))
183 info.data = p.copy()
184 pkts.append(p)
185 return pkts
186
187 def create_stream_labelled_ip6(self, src_if, mpls_labels,
188 hlim=64, dst_ip=None):
Neale Ranns31426c62017-05-24 10:32:58 -0700189 if dst_ip is None:
190 dst_ip = src_if.remote_ip6
Klement Sekeradab231a2016-12-21 08:50:14 +0100191 self.reset_packet_infos()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000192 pkts = []
193 for i in range(0, 257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100194 info = self.create_packet_info(src_if, src_if)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000195 payload = self.info_to_payload(info)
Neale Ranns31ed7442018-02-23 05:29:09 -0800196 p = Ether(dst=src_if.local_mac, src=src_if.remote_mac)
197 for l in mpls_labels:
198 p = p / MPLS(label=l.value, ttl=l.ttl, cos=l.exp)
199
200 p = p / (IPv6(src=src_if.remote_ip6, dst=dst_ip, hlim=hlim) /
201 UDP(sport=1234, dport=1234) /
202 Raw(payload))
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000203 info.data = p.copy()
204 pkts.append(p)
205 return pkts
206
Neale Ranns31ed7442018-02-23 05:29:09 -0800207 def verify_capture_ip4(self, src_if, capture, sent, ping_resp=0,
208 ip_ttl=None, ip_dscp=0):
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000209 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700210 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000211
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000212 self.assertEqual(len(capture), len(sent))
213
214 for i in range(len(capture)):
215 tx = sent[i]
216 rx = capture[i]
217
218 # the rx'd packet has the MPLS label popped
Neale Rannsad422ed2016-11-02 14:20:04 +0000219 eth = rx[Ether]
220 self.assertEqual(eth.type, 0x800)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000221
222 tx_ip = tx[IP]
223 rx_ip = rx[IP]
224
Neale Rannscb630ff2016-12-14 13:31:29 +0100225 if not ping_resp:
226 self.assertEqual(rx_ip.src, tx_ip.src)
227 self.assertEqual(rx_ip.dst, tx_ip.dst)
Neale Ranns31ed7442018-02-23 05:29:09 -0800228 self.assertEqual(rx_ip.tos, ip_dscp)
229 if not ip_ttl:
230 # IP processing post pop has decremented the TTL
231 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
232 else:
233 self.assertEqual(rx_ip.ttl, ip_ttl)
Neale Rannscb630ff2016-12-14 13:31:29 +0100234 else:
235 self.assertEqual(rx_ip.src, tx_ip.dst)
236 self.assertEqual(rx_ip.dst, tx_ip.src)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000237
238 except:
Neale Rannsad422ed2016-11-02 14:20:04 +0000239 raise
240
Neale Rannsad422ed2016-11-02 14:20:04 +0000241 def verify_capture_labelled_ip4(self, src_if, capture, sent,
Neale Ranns31ed7442018-02-23 05:29:09 -0800242 mpls_labels, ip_ttl=None):
Neale Rannsad422ed2016-11-02 14:20:04 +0000243 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700244 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000245
246 self.assertEqual(len(capture), len(sent))
247
248 for i in range(len(capture)):
249 tx = sent[i]
250 rx = capture[i]
251 tx_ip = tx[IP]
252 rx_ip = rx[IP]
253
Neale Ranns31ed7442018-02-23 05:29:09 -0800254 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsad422ed2016-11-02 14:20:04 +0000255
256 self.assertEqual(rx_ip.src, tx_ip.src)
257 self.assertEqual(rx_ip.dst, tx_ip.dst)
Neale Ranns31ed7442018-02-23 05:29:09 -0800258 if not ip_ttl:
259 # IP processing post pop has decremented the TTL
260 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
261 else:
262 self.assertEqual(rx_ip.ttl, ip_ttl)
Neale Rannsad422ed2016-11-02 14:20:04 +0000263
264 except:
265 raise
266
Neale Ranns31ed7442018-02-23 05:29:09 -0800267 def verify_capture_labelled_ip6(self, src_if, capture, sent,
268 mpls_labels, ip_ttl=None):
269 try:
270 capture = verify_filter(capture, sent)
271
272 self.assertEqual(len(capture), len(sent))
273
274 for i in range(len(capture)):
275 tx = sent[i]
276 rx = capture[i]
277 tx_ip = tx[IPv6]
278 rx_ip = rx[IPv6]
279
280 verify_mpls_stack(self, rx, mpls_labels)
281
282 self.assertEqual(rx_ip.src, tx_ip.src)
283 self.assertEqual(rx_ip.dst, tx_ip.dst)
284 if not ip_ttl:
285 # IP processing post pop has decremented the TTL
286 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
287 else:
288 self.assertEqual(rx_ip.hlim, ip_ttl)
289
290 except:
291 raise
292
293 def verify_capture_tunneled_ip4(self, src_if, capture, sent, mpls_labels):
Neale Rannsad422ed2016-11-02 14:20:04 +0000294 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700295 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000296
297 self.assertEqual(len(capture), len(sent))
298
299 for i in range(len(capture)):
300 tx = sent[i]
301 rx = capture[i]
302 tx_ip = tx[IP]
303 rx_ip = rx[IP]
304
Neale Ranns31ed7442018-02-23 05:29:09 -0800305 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsad422ed2016-11-02 14:20:04 +0000306
307 self.assertEqual(rx_ip.src, tx_ip.src)
308 self.assertEqual(rx_ip.dst, tx_ip.dst)
309 # IP processing post pop has decremented the TTL
310 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
311
312 except:
313 raise
314
315 def verify_capture_labelled(self, src_if, capture, sent,
Neale Ranns31ed7442018-02-23 05:29:09 -0800316 mpls_labels):
Neale Rannsad422ed2016-11-02 14:20:04 +0000317 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700318 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000319
320 self.assertEqual(len(capture), len(sent))
321
322 for i in range(len(capture)):
323 rx = capture[i]
Neale Ranns31ed7442018-02-23 05:29:09 -0800324 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsad422ed2016-11-02 14:20:04 +0000325 except:
326 raise
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000327
Neale Ranns31ed7442018-02-23 05:29:09 -0800328 def verify_capture_ip6(self, src_if, capture, sent,
329 ip_hlim=None, ip_dscp=0):
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000330 try:
331 self.assertEqual(len(capture), len(sent))
332
333 for i in range(len(capture)):
334 tx = sent[i]
335 rx = capture[i]
336
337 # the rx'd packet has the MPLS label popped
Neale Rannsad422ed2016-11-02 14:20:04 +0000338 eth = rx[Ether]
339 self.assertEqual(eth.type, 0x86DD)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000340
341 tx_ip = tx[IPv6]
342 rx_ip = rx[IPv6]
343
344 self.assertEqual(rx_ip.src, tx_ip.src)
345 self.assertEqual(rx_ip.dst, tx_ip.dst)
Neale Ranns31ed7442018-02-23 05:29:09 -0800346 self.assertEqual(rx_ip.tc, ip_dscp)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000347 # IP processing post pop has decremented the TTL
Neale Ranns31ed7442018-02-23 05:29:09 -0800348 if not ip_hlim:
349 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
350 else:
351 self.assertEqual(rx_ip.hlim, ip_hlim)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000352
353 except:
Neale Rannsad422ed2016-11-02 14:20:04 +0000354 raise
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000355
Neale Ranns62fe07c2017-10-31 12:28:22 -0700356 def verify_capture_ip6_icmp(self, src_if, capture, sent):
357 try:
358 self.assertEqual(len(capture), len(sent))
359
360 for i in range(len(capture)):
361 tx = sent[i]
362 rx = capture[i]
363
364 # the rx'd packet has the MPLS label popped
365 eth = rx[Ether]
366 self.assertEqual(eth.type, 0x86DD)
367
368 tx_ip = tx[IPv6]
369 rx_ip = rx[IPv6]
370
371 self.assertEqual(rx_ip.dst, tx_ip.src)
372 # ICMP sourced from the interface's address
373 self.assertEqual(rx_ip.src, src_if.local_ip6)
374 # hop-limit reset to 255 for IMCP packet
Ole Troan282093f2018-09-19 12:38:51 +0200375 self.assertEqual(rx_ip.hlim, 255)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700376
377 icmp = rx[ICMPv6TimeExceeded]
378
379 except:
380 raise
381
Neale Rannsad422ed2016-11-02 14:20:04 +0000382 def test_swap(self):
383 """ MPLS label swap tests """
384
385 #
386 # A simple MPLS xconnect - eos label in label out
387 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800388 route_32_eos = VppMplsRoute(self, 32, 1,
389 [VppRoutePath(self.pg0.remote_ip4,
390 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800391 labels=[VppMplsLabel(33)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000392 route_32_eos.add_vpp_config()
393
Neale Ranns775f73c2018-12-20 03:01:49 -0800394 self.assertTrue(
395 find_mpls_route(self, 0, 32, 1,
396 [VppRoutePath(self.pg0.remote_ip4,
397 self.pg0.sw_if_index,
398 labels=[VppMplsLabel(33)])]))
399
Neale Rannsad422ed2016-11-02 14:20:04 +0000400 #
401 # a stream that matches the route for 10.0.0.1
402 # PG0 is in the default table
403 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800404 tx = self.create_stream_labelled_ip4(self.pg0,
405 [VppMplsLabel(32, ttl=32, exp=1)])
406 rx = self.send_and_expect(self.pg0, tx, self.pg0)
407 self.verify_capture_labelled(self.pg0, rx, tx,
408 [VppMplsLabel(33, ttl=31, exp=1)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000409
Neale Ranns008dbe12018-09-07 09:32:36 -0700410 self.assertEqual(route_32_eos.get_stats_to()['packets'], 257)
411
Neale Rannsad422ed2016-11-02 14:20:04 +0000412 #
413 # A simple MPLS xconnect - non-eos label in label out
414 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800415 route_32_neos = VppMplsRoute(self, 32, 0,
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_neos.add_vpp_config()
420
421 #
422 # a stream that matches the route for 10.0.0.1
423 # PG0 is in the default table
424 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800425 tx = self.create_stream_labelled_ip4(self.pg0,
426 [VppMplsLabel(32, ttl=21, exp=7),
427 VppMplsLabel(99)])
428 rx = self.send_and_expect(self.pg0, tx, self.pg0)
429 self.verify_capture_labelled(self.pg0, rx, tx,
430 [VppMplsLabel(33, ttl=20, exp=7),
431 VppMplsLabel(99)])
Neale Ranns008dbe12018-09-07 09:32:36 -0700432 self.assertEqual(route_32_neos.get_stats_to()['packets'], 257)
Neale Rannsad422ed2016-11-02 14:20:04 +0000433
Neale Ranns31ed7442018-02-23 05:29:09 -0800434 #
435 # A simple MPLS xconnect - non-eos label in label out, uniform mode
436 #
437 route_42_neos = VppMplsRoute(
438 self, 42, 0,
439 [VppRoutePath(self.pg0.remote_ip4,
440 self.pg0.sw_if_index,
441 labels=[VppMplsLabel(43, MplsLspMode.UNIFORM)])])
442 route_42_neos.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000443
Neale Ranns31ed7442018-02-23 05:29:09 -0800444 tx = self.create_stream_labelled_ip4(self.pg0,
445 [VppMplsLabel(42, ttl=21, exp=7),
446 VppMplsLabel(99)])
447 rx = self.send_and_expect(self.pg0, tx, self.pg0)
448 self.verify_capture_labelled(self.pg0, rx, tx,
449 [VppMplsLabel(43, ttl=20, exp=7),
450 VppMplsLabel(99)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000451
452 #
453 # An MPLS xconnect - EOS label in IP out
454 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800455 route_33_eos = VppMplsRoute(self, 33, 1,
456 [VppRoutePath(self.pg0.remote_ip4,
457 self.pg0.sw_if_index,
458 labels=[])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000459 route_33_eos.add_vpp_config()
460
Neale Ranns31ed7442018-02-23 05:29:09 -0800461 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(33)])
462 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Rannsad422ed2016-11-02 14:20:04 +0000463 self.verify_capture_ip4(self.pg0, rx, tx)
464
465 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700466 # disposed packets have an invalid IPv4 checksum
Neale Ranns62fe07c2017-10-31 12:28:22 -0700467 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800468 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(33)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700469 dst_ip=self.pg0.remote_ip4,
470 n=65,
471 chksum=1)
472 self.send_and_assert_no_replies(self.pg0, tx, "Invalid Checksum")
473
474 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800475 # An MPLS xconnect - EOS label in IP out, uniform mode
476 #
477 route_3333_eos = VppMplsRoute(
478 self, 3333, 1,
479 [VppRoutePath(self.pg0.remote_ip4,
480 self.pg0.sw_if_index,
481 labels=[VppMplsLabel(3, MplsLspMode.UNIFORM)])])
482 route_3333_eos.add_vpp_config()
483
484 tx = self.create_stream_labelled_ip4(
485 self.pg0,
486 [VppMplsLabel(3333, ttl=55, exp=3)])
487 rx = self.send_and_expect(self.pg0, tx, self.pg0)
488 self.verify_capture_ip4(self.pg0, rx, tx, ip_ttl=54, ip_dscp=0x60)
489 tx = self.create_stream_labelled_ip4(
490 self.pg0,
491 [VppMplsLabel(3333, ttl=66, exp=4)])
492 rx = self.send_and_expect(self.pg0, tx, self.pg0)
493 self.verify_capture_ip4(self.pg0, rx, tx, ip_ttl=65, ip_dscp=0x80)
494
495 #
Neale Ranns62fe07c2017-10-31 12:28:22 -0700496 # An MPLS xconnect - EOS label in IPv6 out
497 #
498 route_333_eos = VppMplsRoute(
499 self, 333, 1,
500 [VppRoutePath(self.pg0.remote_ip6,
501 self.pg0.sw_if_index,
Neale Ranns097fa662018-05-01 05:17:55 -0700502 labels=[])],
503 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700504 route_333_eos.add_vpp_config()
505
Neale Ranns31ed7442018-02-23 05:29:09 -0800506 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(333)])
507 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700508 self.verify_capture_ip6(self.pg0, rx, tx)
509
510 #
511 # disposed packets have an TTL expired
512 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800513 tx = self.create_stream_labelled_ip6(self.pg0,
514 [VppMplsLabel(333, ttl=64)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700515 dst_ip=self.pg1.remote_ip6,
516 hlim=1)
Neale Ranns31ed7442018-02-23 05:29:09 -0800517 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700518 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
519
520 #
521 # An MPLS xconnect - EOS label in IPv6 out w imp-null
522 #
523 route_334_eos = VppMplsRoute(
524 self, 334, 1,
525 [VppRoutePath(self.pg0.remote_ip6,
526 self.pg0.sw_if_index,
Neale Ranns097fa662018-05-01 05:17:55 -0700527 labels=[VppMplsLabel(3)])],
528 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700529 route_334_eos.add_vpp_config()
530
Neale Ranns31ed7442018-02-23 05:29:09 -0800531 tx = self.create_stream_labelled_ip6(self.pg0,
532 [VppMplsLabel(334, ttl=64)])
533 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700534 self.verify_capture_ip6(self.pg0, rx, tx)
535
536 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800537 # An MPLS xconnect - EOS label in IPv6 out w imp-null in uniform mode
538 #
539 route_335_eos = VppMplsRoute(
540 self, 335, 1,
541 [VppRoutePath(self.pg0.remote_ip6,
542 self.pg0.sw_if_index,
Neale Ranns097fa662018-05-01 05:17:55 -0700543 labels=[VppMplsLabel(3, MplsLspMode.UNIFORM)])],
544 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)
Neale Ranns31ed7442018-02-23 05:29:09 -0800545 route_335_eos.add_vpp_config()
546
547 tx = self.create_stream_labelled_ip6(
548 self.pg0,
549 [VppMplsLabel(335, ttl=27, exp=4)])
550 rx = self.send_and_expect(self.pg0, tx, self.pg0)
551 self.verify_capture_ip6(self.pg0, rx, tx, ip_hlim=26, ip_dscp=0x80)
552
553 #
Neale Ranns62fe07c2017-10-31 12:28:22 -0700554 # disposed packets have an TTL expired
555 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800556 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(334)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700557 dst_ip=self.pg1.remote_ip6,
558 hlim=0)
Neale Ranns31ed7442018-02-23 05:29:09 -0800559 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700560 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
561
562 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000563 # An MPLS xconnect - non-EOS label in IP out - an invalid configuration
564 # so this traffic should be dropped.
565 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800566 route_33_neos = VppMplsRoute(self, 33, 0,
567 [VppRoutePath(self.pg0.remote_ip4,
568 self.pg0.sw_if_index,
569 labels=[])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000570 route_33_neos.add_vpp_config()
571
Neale Ranns31ed7442018-02-23 05:29:09 -0800572 tx = self.create_stream_labelled_ip4(self.pg0,
573 [VppMplsLabel(33),
574 VppMplsLabel(99)])
575 self.send_and_assert_no_replies(
576 self.pg0, tx,
577 "MPLS non-EOS packets popped and forwarded")
Neale Rannsad422ed2016-11-02 14:20:04 +0000578
579 #
580 # A recursive EOS x-connect, which resolves through another x-connect
Neale Ranns31ed7442018-02-23 05:29:09 -0800581 # in pipe mode
Neale Rannsad422ed2016-11-02 14:20:04 +0000582 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800583 route_34_eos = VppMplsRoute(self, 34, 1,
584 [VppRoutePath("0.0.0.0",
585 0xffffffff,
586 nh_via_label=32,
Neale Ranns31ed7442018-02-23 05:29:09 -0800587 labels=[VppMplsLabel(44),
588 VppMplsLabel(45)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000589 route_34_eos.add_vpp_config()
Neale Ranns097fa662018-05-01 05:17:55 -0700590 self.logger.info(self.vapi.cli("sh mpls fib 34"))
Neale Rannsad422ed2016-11-02 14:20:04 +0000591
Neale Ranns31ed7442018-02-23 05:29:09 -0800592 tx = self.create_stream_labelled_ip4(self.pg0,
593 [VppMplsLabel(34, ttl=3)])
594 rx = self.send_and_expect(self.pg0, tx, self.pg0)
595 self.verify_capture_labelled(self.pg0, rx, tx,
596 [VppMplsLabel(33),
597 VppMplsLabel(44),
598 VppMplsLabel(45, ttl=2)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000599
Neale Ranns008dbe12018-09-07 09:32:36 -0700600 self.assertEqual(route_34_eos.get_stats_to()['packets'], 257)
601 self.assertEqual(route_32_neos.get_stats_via()['packets'], 257)
602
Neale Ranns31ed7442018-02-23 05:29:09 -0800603 #
604 # A recursive EOS x-connect, which resolves through another x-connect
605 # in uniform mode
606 #
607 route_35_eos = VppMplsRoute(
608 self, 35, 1,
609 [VppRoutePath("0.0.0.0",
610 0xffffffff,
611 nh_via_label=42,
612 labels=[VppMplsLabel(44)])])
613 route_35_eos.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000614
Neale Ranns31ed7442018-02-23 05:29:09 -0800615 tx = self.create_stream_labelled_ip4(self.pg0,
616 [VppMplsLabel(35, ttl=3)])
617 rx = self.send_and_expect(self.pg0, tx, self.pg0)
618 self.verify_capture_labelled(self.pg0, rx, tx,
619 [VppMplsLabel(43, ttl=2),
620 VppMplsLabel(44, ttl=2)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000621
622 #
Matej Klottondeb69842016-12-09 15:05:46 +0100623 # A recursive non-EOS x-connect, which resolves through another
624 # x-connect
Neale Rannsad422ed2016-11-02 14:20:04 +0000625 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800626 route_34_neos = VppMplsRoute(self, 34, 0,
627 [VppRoutePath("0.0.0.0",
628 0xffffffff,
629 nh_via_label=32,
Neale Ranns31ed7442018-02-23 05:29:09 -0800630 labels=[VppMplsLabel(44),
631 VppMplsLabel(46)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000632 route_34_neos.add_vpp_config()
633
Neale Ranns31ed7442018-02-23 05:29:09 -0800634 tx = self.create_stream_labelled_ip4(self.pg0,
635 [VppMplsLabel(34, ttl=45),
636 VppMplsLabel(99)])
637 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Matej Klottondeb69842016-12-09 15:05:46 +0100638 # it's the 2nd (counting from 0) label in the stack that is swapped
Neale Ranns31ed7442018-02-23 05:29:09 -0800639 self.verify_capture_labelled(self.pg0, rx, tx,
640 [VppMplsLabel(33),
641 VppMplsLabel(44),
642 VppMplsLabel(46, ttl=44),
643 VppMplsLabel(99)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000644
645 #
Matej Klottondeb69842016-12-09 15:05:46 +0100646 # an recursive IP route that resolves through the recursive non-eos
647 # x-connect
Neale Rannsad422ed2016-11-02 14:20:04 +0000648 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800649 ip_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
650 [VppRoutePath("0.0.0.0",
651 0xffffffff,
652 nh_via_label=34,
Neale Ranns31ed7442018-02-23 05:29:09 -0800653 labels=[VppMplsLabel(55)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000654 ip_10_0_0_1.add_vpp_config()
655
Neale Rannsad422ed2016-11-02 14:20:04 +0000656 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800657 rx = self.send_and_expect(self.pg0, tx, self.pg0)
658 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
659 [VppMplsLabel(33),
660 VppMplsLabel(44),
661 VppMplsLabel(46),
662 VppMplsLabel(55)])
Neale Ranns008dbe12018-09-07 09:32:36 -0700663 self.assertEqual(ip_10_0_0_1.get_stats_to()['packets'], 257)
Neale Rannsad422ed2016-11-02 14:20:04 +0000664
665 ip_10_0_0_1.remove_vpp_config()
666 route_34_neos.remove_vpp_config()
667 route_34_eos.remove_vpp_config()
668 route_33_neos.remove_vpp_config()
669 route_33_eos.remove_vpp_config()
670 route_32_neos.remove_vpp_config()
671 route_32_eos.remove_vpp_config()
672
673 def test_bind(self):
674 """ MPLS Local Label Binding test """
675
676 #
677 # Add a non-recursive route with a single out label
678 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800679 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
680 [VppRoutePath(self.pg0.remote_ip4,
681 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800682 labels=[VppMplsLabel(45)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000683 route_10_0_0_1.add_vpp_config()
684
685 # bind a local label to the route
Neale Ranns5a8123b2017-01-26 01:18:23 -0800686 binding = VppMplsIpBind(self, 44, "10.0.0.1", 32)
Neale Rannsad422ed2016-11-02 14:20:04 +0000687 binding.add_vpp_config()
688
689 # non-EOS stream
Neale Ranns31ed7442018-02-23 05:29:09 -0800690 tx = self.create_stream_labelled_ip4(self.pg0,
691 [VppMplsLabel(44),
692 VppMplsLabel(99)])
693 rx = self.send_and_expect(self.pg0, tx, self.pg0)
694 self.verify_capture_labelled(self.pg0, rx, tx,
695 [VppMplsLabel(45, ttl=63),
696 VppMplsLabel(99)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000697
698 # EOS stream
Neale Ranns31ed7442018-02-23 05:29:09 -0800699 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(44)])
700 rx = self.send_and_expect(self.pg0, tx, self.pg0)
701 self.verify_capture_labelled(self.pg0, rx, tx,
702 [VppMplsLabel(45, ttl=63)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000703
704 # IP stream
Neale Rannsad422ed2016-11-02 14:20:04 +0000705 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800706 rx = self.send_and_expect(self.pg0, tx, self.pg0)
707 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [VppMplsLabel(45)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000708
709 #
710 # cleanup
711 #
712 binding.remove_vpp_config()
713 route_10_0_0_1.remove_vpp_config()
714
715 def test_imposition(self):
716 """ MPLS label imposition test """
717
718 #
719 # Add a non-recursive route with a single out label
720 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800721 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
722 [VppRoutePath(self.pg0.remote_ip4,
723 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800724 labels=[VppMplsLabel(32)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000725 route_10_0_0_1.add_vpp_config()
726
727 #
728 # a stream that matches the route for 10.0.0.1
729 # PG0 is in the default table
730 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000731 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800732 rx = self.send_and_expect(self.pg0, tx, self.pg0)
733 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [VppMplsLabel(32)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000734
735 #
736 # Add a non-recursive route with a 3 out labels
737 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800738 route_10_0_0_2 = VppIpRoute(self, "10.0.0.2", 32,
739 [VppRoutePath(self.pg0.remote_ip4,
740 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800741 labels=[VppMplsLabel(32),
742 VppMplsLabel(33),
743 VppMplsLabel(34)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000744 route_10_0_0_2.add_vpp_config()
745
Neale Ranns31ed7442018-02-23 05:29:09 -0800746 tx = self.create_stream_ip4(self.pg0, "10.0.0.2",
747 ip_ttl=44, ip_dscp=0xff)
748 rx = self.send_and_expect(self.pg0, tx, self.pg0)
749 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
750 [VppMplsLabel(32),
751 VppMplsLabel(33),
752 VppMplsLabel(34)],
753 ip_ttl=43)
Neale Rannsad422ed2016-11-02 14:20:04 +0000754
Neale Ranns31ed7442018-02-23 05:29:09 -0800755 #
756 # Add a non-recursive route with a single out label in uniform mode
757 #
758 route_10_0_0_3 = VppIpRoute(
759 self, "10.0.0.3", 32,
760 [VppRoutePath(self.pg0.remote_ip4,
761 self.pg0.sw_if_index,
762 labels=[VppMplsLabel(32,
763 mode=MplsLspMode.UNIFORM)])])
764 route_10_0_0_3.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000765
Neale Ranns31ed7442018-02-23 05:29:09 -0800766 tx = self.create_stream_ip4(self.pg0, "10.0.0.3",
767 ip_ttl=54, ip_dscp=0xbe)
768 rx = self.send_and_expect(self.pg0, tx, self.pg0)
769 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
770 [VppMplsLabel(32, ttl=53, exp=5)])
771
772 #
773 # Add a IPv6 non-recursive route with a single out label in
774 # uniform mode
775 #
776 route_2001_3 = VppIpRoute(
777 self, "2001::3", 128,
778 [VppRoutePath(self.pg0.remote_ip6,
779 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800780 labels=[VppMplsLabel(32,
Neale Ranns097fa662018-05-01 05:17:55 -0700781 mode=MplsLspMode.UNIFORM)])])
Neale Ranns31ed7442018-02-23 05:29:09 -0800782 route_2001_3.add_vpp_config()
783
784 tx = self.create_stream_ip6(self.pg0, "2001::3",
785 ip_ttl=54, ip_dscp=0xbe)
786 rx = self.send_and_expect(self.pg0, tx, self.pg0)
787 self.verify_capture_labelled_ip6(self.pg0, rx, tx,
788 [VppMplsLabel(32, ttl=53, exp=5)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000789
790 #
Matej Klottondeb69842016-12-09 15:05:46 +0100791 # add a recursive path, with output label, via the 1 label route
Neale Rannsad422ed2016-11-02 14:20:04 +0000792 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800793 route_11_0_0_1 = VppIpRoute(self, "11.0.0.1", 32,
794 [VppRoutePath("10.0.0.1",
795 0xffffffff,
Neale Ranns31ed7442018-02-23 05:29:09 -0800796 labels=[VppMplsLabel(44)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000797 route_11_0_0_1.add_vpp_config()
798
799 #
800 # a stream that matches the route for 11.0.0.1, should pick up
801 # the label stack for 11.0.0.1 and 10.0.0.1
802 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000803 tx = self.create_stream_ip4(self.pg0, "11.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800804 rx = self.send_and_expect(self.pg0, tx, self.pg0)
805 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
806 [VppMplsLabel(32),
807 VppMplsLabel(44)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000808
Neale Ranns008dbe12018-09-07 09:32:36 -0700809 self.assertEqual(route_11_0_0_1.get_stats_to()['packets'], 257)
810
Neale Rannsad422ed2016-11-02 14:20:04 +0000811 #
812 # add a recursive path, with 2 labels, via the 3 label route
813 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800814 route_11_0_0_2 = VppIpRoute(self, "11.0.0.2", 32,
815 [VppRoutePath("10.0.0.2",
816 0xffffffff,
Neale Ranns31ed7442018-02-23 05:29:09 -0800817 labels=[VppMplsLabel(44),
818 VppMplsLabel(45)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000819 route_11_0_0_2.add_vpp_config()
820
821 #
822 # a stream that matches the route for 11.0.0.1, should pick up
823 # the label stack for 11.0.0.1 and 10.0.0.1
824 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000825 tx = self.create_stream_ip4(self.pg0, "11.0.0.2")
Neale Ranns31ed7442018-02-23 05:29:09 -0800826 rx = self.send_and_expect(self.pg0, tx, self.pg0)
827 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
828 [VppMplsLabel(32),
829 VppMplsLabel(33),
830 VppMplsLabel(34),
831 VppMplsLabel(44),
832 VppMplsLabel(45)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000833
Neale Ranns008dbe12018-09-07 09:32:36 -0700834 self.assertEqual(route_11_0_0_2.get_stats_to()['packets'], 257)
835
836 rx = self.send_and_expect(self.pg0, tx, self.pg0)
837 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
838 [VppMplsLabel(32),
839 VppMplsLabel(33),
840 VppMplsLabel(34),
841 VppMplsLabel(44),
842 VppMplsLabel(45)])
843
844 self.assertEqual(route_11_0_0_2.get_stats_to()['packets'], 514)
845
Neale Rannsad422ed2016-11-02 14:20:04 +0000846 #
847 # cleanup
848 #
849 route_11_0_0_2.remove_vpp_config()
850 route_11_0_0_1.remove_vpp_config()
851 route_10_0_0_2.remove_vpp_config()
852 route_10_0_0_1.remove_vpp_config()
853
Neale Ranns31ed7442018-02-23 05:29:09 -0800854 def test_tunnel_pipe(self):
855 """ MPLS Tunnel Tests - Pipe """
Neale Rannsad422ed2016-11-02 14:20:04 +0000856
857 #
858 # Create a tunnel with a single out label
859 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800860 mpls_tun = VppMPLSTunnelInterface(
861 self,
862 [VppRoutePath(self.pg0.remote_ip4,
863 self.pg0.sw_if_index,
864 labels=[VppMplsLabel(44),
865 VppMplsLabel(46)])])
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800866 mpls_tun.add_vpp_config()
867 mpls_tun.admin_up()
Neale Rannsad422ed2016-11-02 14:20:04 +0000868
869 #
870 # add an unlabelled route through the new tunnel
871 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800872 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
873 [VppRoutePath("0.0.0.0",
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800874 mpls_tun._sw_if_index)])
Neale Ranns5a8123b2017-01-26 01:18:23 -0800875 route_10_0_0_3.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000876
877 self.vapi.cli("clear trace")
878 tx = self.create_stream_ip4(self.pg0, "10.0.0.3")
879 self.pg0.add_stream(tx)
880
881 self.pg_enable_capture(self.pg_interfaces)
882 self.pg_start()
883
884 rx = self.pg0.get_capture()
Neale Ranns31ed7442018-02-23 05:29:09 -0800885 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
886 [VppMplsLabel(44),
887 VppMplsLabel(46)])
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000888
Neale Ranns8c4611b2017-05-23 03:43:47 -0700889 #
890 # add a labelled route through the new tunnel
891 #
892 route_10_0_0_4 = VppIpRoute(self, "10.0.0.4", 32,
893 [VppRoutePath("0.0.0.0",
894 mpls_tun._sw_if_index,
895 labels=[33])])
896 route_10_0_0_4.add_vpp_config()
897
898 self.vapi.cli("clear trace")
899 tx = self.create_stream_ip4(self.pg0, "10.0.0.4")
900 self.pg0.add_stream(tx)
901
902 self.pg_enable_capture(self.pg_interfaces)
903 self.pg_start()
904
905 rx = self.pg0.get_capture()
Neale Ranns31ed7442018-02-23 05:29:09 -0800906 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
907 [VppMplsLabel(44),
908 VppMplsLabel(46),
909 VppMplsLabel(33, ttl=255)])
910
911 def test_tunnel_uniform(self):
912 """ MPLS Tunnel Tests - Uniform """
913
914 #
915 # Create a tunnel with a single out label
916 # The label stack is specified here from outer to inner
917 #
918 mpls_tun = VppMPLSTunnelInterface(
919 self,
920 [VppRoutePath(self.pg0.remote_ip4,
921 self.pg0.sw_if_index,
922 labels=[VppMplsLabel(44, ttl=32),
923 VppMplsLabel(46, MplsLspMode.UNIFORM)])])
924 mpls_tun.add_vpp_config()
925 mpls_tun.admin_up()
926
927 #
928 # add an unlabelled route through the new tunnel
929 #
930 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
931 [VppRoutePath("0.0.0.0",
932 mpls_tun._sw_if_index)])
933 route_10_0_0_3.add_vpp_config()
934
935 self.vapi.cli("clear trace")
936 tx = self.create_stream_ip4(self.pg0, "10.0.0.3", ip_ttl=24)
937 self.pg0.add_stream(tx)
938
939 self.pg_enable_capture(self.pg_interfaces)
940 self.pg_start()
941
942 rx = self.pg0.get_capture()
943 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
944 [VppMplsLabel(44, ttl=32),
945 VppMplsLabel(46, ttl=23)])
946
947 #
948 # add a labelled route through the new tunnel
949 #
950 route_10_0_0_4 = VppIpRoute(
951 self, "10.0.0.4", 32,
952 [VppRoutePath("0.0.0.0",
953 mpls_tun._sw_if_index,
954 labels=[VppMplsLabel(33, ttl=47)])])
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()
965 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
966 [VppMplsLabel(44, ttl=32),
967 VppMplsLabel(46, ttl=47),
968 VppMplsLabel(33, ttl=47)])
Neale Ranns8c4611b2017-05-23 03:43:47 -0700969
Neale Rannsf5fa5ae2018-09-26 05:07:25 -0700970 def test_mpls_tunnel_many(self):
Neale Ranns097fa662018-05-01 05:17:55 -0700971 """ MPLS Multiple Tunnels """
Neale Rannsf5fa5ae2018-09-26 05:07:25 -0700972
973 for ii in range(10):
974 mpls_tun = VppMPLSTunnelInterface(
975 self,
976 [VppRoutePath(self.pg0.remote_ip4,
977 self.pg0.sw_if_index,
978 labels=[VppMplsLabel(44, ttl=32),
979 VppMplsLabel(46, MplsLspMode.UNIFORM)])])
980 mpls_tun.add_vpp_config()
981 mpls_tun.admin_up()
982
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000983 def test_v4_exp_null(self):
984 """ MPLS V4 Explicit NULL test """
985
986 #
987 # The first test case has an MPLS TTL of 0
988 # all packet should be dropped
989 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800990 tx = self.create_stream_labelled_ip4(self.pg0,
991 [VppMplsLabel(0, ttl=0)])
992 self.send_and_assert_no_replies(self.pg0, tx,
993 "MPLS TTL=0 packets forwarded")
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000994
995 #
996 # a stream with a non-zero MPLS TTL
997 # PG0 is in the default table
998 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800999 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(0)])
1000 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001001 self.verify_capture_ip4(self.pg0, rx, tx)
1002
1003 #
1004 # a stream with a non-zero MPLS TTL
1005 # PG1 is in table 1
1006 # we are ensuring the post-pop lookup occurs in the VRF table
1007 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001008 tx = self.create_stream_labelled_ip4(self.pg1, [VppMplsLabel(0)])
1009 rx = self.send_and_expect(self.pg1, tx, self.pg1)
1010 self.verify_capture_ip4(self.pg1, rx, tx)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001011
1012 def test_v6_exp_null(self):
1013 """ MPLS V6 Explicit NULL test """
1014
1015 #
1016 # a stream with a non-zero MPLS TTL
1017 # PG0 is in the default table
1018 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001019 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(2)])
1020 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001021 self.verify_capture_ip6(self.pg0, rx, tx)
1022
1023 #
1024 # a stream with a non-zero MPLS TTL
1025 # PG1 is in table 1
1026 # we are ensuring the post-pop lookup occurs in the VRF table
1027 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001028 tx = self.create_stream_labelled_ip6(self.pg1, [VppMplsLabel(2)])
1029 rx = self.send_and_expect(self.pg1, tx, self.pg1)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001030 self.verify_capture_ip6(self.pg0, rx, tx)
1031
Neale Rannscb630ff2016-12-14 13:31:29 +01001032 def test_deag(self):
1033 """ MPLS Deagg """
1034
1035 #
1036 # A de-agg route - next-hop lookup in default table
1037 #
Neale Ranns5a8123b2017-01-26 01:18:23 -08001038 route_34_eos = VppMplsRoute(self, 34, 1,
1039 [VppRoutePath("0.0.0.0",
1040 0xffffffff,
1041 nh_table_id=0)])
Neale Rannscb630ff2016-12-14 13:31:29 +01001042 route_34_eos.add_vpp_config()
1043
1044 #
1045 # ping an interface in the default table
1046 # PG0 is in the default table
1047 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001048 tx = self.create_stream_labelled_ip4(self.pg0,
1049 [VppMplsLabel(34)],
1050 ping=1,
Neale Rannscb630ff2016-12-14 13:31:29 +01001051 ip_itf=self.pg0)
Neale Ranns31ed7442018-02-23 05:29:09 -08001052 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Rannscb630ff2016-12-14 13:31:29 +01001053 self.verify_capture_ip4(self.pg0, rx, tx, ping_resp=1)
1054
1055 #
1056 # A de-agg route - next-hop lookup in non-default table
1057 #
Neale Ranns5a8123b2017-01-26 01:18:23 -08001058 route_35_eos = VppMplsRoute(self, 35, 1,
1059 [VppRoutePath("0.0.0.0",
1060 0xffffffff,
1061 nh_table_id=1)])
Neale Rannscb630ff2016-12-14 13:31:29 +01001062 route_35_eos.add_vpp_config()
1063
1064 #
1065 # ping an interface in the non-default table
1066 # PG0 is in the default table. packet arrive labelled in the
1067 # default table and egress unlabelled in the non-default
1068 #
Klement Sekeradab231a2016-12-21 08:50:14 +01001069 tx = self.create_stream_labelled_ip4(
Neale Ranns31ed7442018-02-23 05:29:09 -08001070 self.pg0, [VppMplsLabel(35)], ping=1, ip_itf=self.pg1)
1071 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Rannscb630ff2016-12-14 13:31:29 +01001072 self.verify_capture_ip4(self.pg1, rx, tx, ping_resp=1)
1073
Neale Ranns6af1c042017-05-26 03:48:53 -07001074 #
1075 # Double pop
1076 #
1077 route_36_neos = VppMplsRoute(self, 36, 0,
1078 [VppRoutePath("0.0.0.0",
1079 0xffffffff)])
1080 route_36_neos.add_vpp_config()
1081
Neale Ranns31ed7442018-02-23 05:29:09 -08001082 tx = self.create_stream_labelled_ip4(self.pg0,
1083 [VppMplsLabel(36),
1084 VppMplsLabel(35)],
Neale Ranns6af1c042017-05-26 03:48:53 -07001085 ping=1, ip_itf=self.pg1)
Neale Ranns31ed7442018-02-23 05:29:09 -08001086 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns6af1c042017-05-26 03:48:53 -07001087 self.verify_capture_ip4(self.pg1, rx, tx, ping_resp=1)
1088
1089 route_36_neos.remove_vpp_config()
Neale Rannscb630ff2016-12-14 13:31:29 +01001090 route_35_eos.remove_vpp_config()
1091 route_34_eos.remove_vpp_config()
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001092
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001093 def test_interface_rx(self):
1094 """ MPLS Interface Receive """
1095
1096 #
1097 # Add a non-recursive route that will forward the traffic
1098 # post-interface-rx
1099 #
1100 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
1101 table_id=1,
1102 paths=[VppRoutePath(self.pg1.remote_ip4,
1103 self.pg1.sw_if_index)])
1104 route_10_0_0_1.add_vpp_config()
1105
1106 #
1107 # An interface receive label that maps traffic to RX on interface
1108 # pg1
1109 # by injecting the packet in on pg0, which is in table 0
1110 # doing an interface-rx on pg1 and matching a route in table 1
1111 # if the packet egresses, then we must have swapped to pg1
1112 # so as to have matched the route in table 1
1113 #
Neale Ranns097fa662018-05-01 05:17:55 -07001114 route_34_eos = VppMplsRoute(
1115 self, 34, 1,
1116 [VppRoutePath("0.0.0.0",
1117 self.pg1.sw_if_index,
1118 type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001119 route_34_eos.add_vpp_config()
1120
1121 #
1122 # ping an interface in the default table
1123 # PG0 is in the default table
1124 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001125 tx = self.create_stream_labelled_ip4(self.pg0,
1126 [VppMplsLabel(34)],
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001127 dst_ip="10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -08001128 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001129 self.verify_capture_ip4(self.pg1, rx, tx)
1130
1131 def test_mcast_mid_point(self):
1132 """ MPLS Multicast Mid Point """
1133
1134 #
1135 # Add a non-recursive route that will forward the traffic
1136 # post-interface-rx
1137 #
1138 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
1139 table_id=1,
1140 paths=[VppRoutePath(self.pg1.remote_ip4,
1141 self.pg1.sw_if_index)])
1142 route_10_0_0_1.add_vpp_config()
1143
1144 #
1145 # Add a mcast entry that replicate to pg2 and pg3
1146 # and replicate to a interface-rx (like a bud node would)
1147 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001148 route_3400_eos = VppMplsRoute(
1149 self, 3400, 1,
1150 [VppRoutePath(self.pg2.remote_ip4,
1151 self.pg2.sw_if_index,
1152 labels=[VppMplsLabel(3401)]),
1153 VppRoutePath(self.pg3.remote_ip4,
1154 self.pg3.sw_if_index,
1155 labels=[VppMplsLabel(3402)]),
1156 VppRoutePath("0.0.0.0",
1157 self.pg1.sw_if_index,
Neale Ranns097fa662018-05-01 05:17:55 -07001158 type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX)],
Neale Ranns31ed7442018-02-23 05:29:09 -08001159 is_multicast=1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001160 route_3400_eos.add_vpp_config()
1161
1162 #
1163 # ping an interface in the default table
1164 # PG0 is in the default table
1165 #
1166 self.vapi.cli("clear trace")
Neale Ranns31ed7442018-02-23 05:29:09 -08001167 tx = self.create_stream_labelled_ip4(self.pg0,
1168 [VppMplsLabel(3400, ttl=64)],
1169 n=257,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001170 dst_ip="10.0.0.1")
1171 self.pg0.add_stream(tx)
1172
1173 self.pg_enable_capture(self.pg_interfaces)
1174 self.pg_start()
1175
1176 rx = self.pg1.get_capture(257)
1177 self.verify_capture_ip4(self.pg1, rx, tx)
1178
1179 rx = self.pg2.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001180 self.verify_capture_labelled(self.pg2, rx, tx,
1181 [VppMplsLabel(3401, ttl=63)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001182 rx = self.pg3.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001183 self.verify_capture_labelled(self.pg3, rx, tx,
1184 [VppMplsLabel(3402, ttl=63)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001185
1186 def test_mcast_head(self):
1187 """ MPLS Multicast Head-end """
1188
1189 #
1190 # Create a multicast tunnel with two replications
1191 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001192 mpls_tun = VppMPLSTunnelInterface(
1193 self,
1194 [VppRoutePath(self.pg2.remote_ip4,
1195 self.pg2.sw_if_index,
1196 labels=[VppMplsLabel(42)]),
1197 VppRoutePath(self.pg3.remote_ip4,
1198 self.pg3.sw_if_index,
1199 labels=[VppMplsLabel(43)])],
1200 is_multicast=1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001201 mpls_tun.add_vpp_config()
1202 mpls_tun.admin_up()
1203
1204 #
1205 # add an unlabelled route through the new tunnel
1206 #
1207 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
1208 [VppRoutePath("0.0.0.0",
1209 mpls_tun._sw_if_index)])
1210 route_10_0_0_3.add_vpp_config()
1211
1212 self.vapi.cli("clear trace")
1213 tx = self.create_stream_ip4(self.pg0, "10.0.0.3")
1214 self.pg0.add_stream(tx)
1215
1216 self.pg_enable_capture(self.pg_interfaces)
1217 self.pg_start()
1218
1219 rx = self.pg2.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001220 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(42)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001221 rx = self.pg3.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001222 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(43)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001223
1224 #
1225 # An an IP multicast route via the tunnel
1226 # A (*,G).
1227 # one accepting interface, pg0, 1 forwarding interface via the tunnel
1228 #
1229 route_232_1_1_1 = VppIpMRoute(
1230 self,
1231 "0.0.0.0",
1232 "232.1.1.1", 32,
1233 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
1234 [VppMRoutePath(self.pg0.sw_if_index,
1235 MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
1236 VppMRoutePath(mpls_tun._sw_if_index,
1237 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
1238 route_232_1_1_1.add_vpp_config()
Neale Ranns097fa662018-05-01 05:17:55 -07001239 self.logger.info(self.vapi.cli("sh ip mfib index 0"))
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001240
1241 self.vapi.cli("clear trace")
1242 tx = self.create_stream_ip4(self.pg0, "232.1.1.1")
1243 self.pg0.add_stream(tx)
1244
1245 self.pg_enable_capture(self.pg_interfaces)
1246 self.pg_start()
1247
1248 rx = self.pg2.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001249 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(42)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001250 rx = self.pg3.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001251 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(43)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001252
Neale Ranns31426c62017-05-24 10:32:58 -07001253 def test_mcast_ip4_tail(self):
1254 """ MPLS IPv4 Multicast Tail """
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001255
1256 #
1257 # Add a multicast route that will forward the traffic
1258 # post-disposition
1259 #
1260 route_232_1_1_1 = VppIpMRoute(
1261 self,
1262 "0.0.0.0",
1263 "232.1.1.1", 32,
1264 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
1265 table_id=1,
1266 paths=[VppMRoutePath(self.pg1.sw_if_index,
1267 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
1268 route_232_1_1_1.add_vpp_config()
1269
1270 #
1271 # An interface receive label that maps traffic to RX on interface
1272 # pg1
1273 # by injecting the packet in on pg0, which is in table 0
1274 # doing an rpf-id and matching a route in table 1
1275 # if the packet egresses, then we must have matched the route in
1276 # table 1
1277 #
Neale Ranns097fa662018-05-01 05:17:55 -07001278 route_34_eos = VppMplsRoute(
1279 self, 34, 1,
1280 [VppRoutePath("0.0.0.0",
1281 0xffffffff,
1282 nh_table_id=1,
1283 rpf_id=55)],
1284 is_multicast=1,
1285 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP4)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001286
1287 route_34_eos.add_vpp_config()
1288
1289 #
1290 # Drop due to interface lookup miss
1291 #
1292 self.vapi.cli("clear trace")
Neale Ranns31ed7442018-02-23 05:29:09 -08001293 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001294 dst_ip="232.1.1.1", n=1)
1295 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop none")
1296
1297 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001298 # set the RPF-ID of the entry to match the input packet's
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001299 #
1300 route_232_1_1_1.update_rpf_id(55)
Neale Ranns097fa662018-05-01 05:17:55 -07001301 self.logger.info(self.vapi.cli("sh ip mfib index 1 232.1.1.1"))
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001302
Neale Ranns31ed7442018-02-23 05:29:09 -08001303 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
1304 dst_ip="232.1.1.1")
1305 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001306 self.verify_capture_ip4(self.pg1, rx, tx)
1307
1308 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001309 # disposed packets have an invalid IPv4 checksum
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001310 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001311 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001312 dst_ip="232.1.1.1", n=65,
1313 chksum=1)
1314 self.send_and_assert_no_replies(self.pg0, tx, "Invalid Checksum")
1315
1316 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001317 # set the RPF-ID of the entry to not match the input packet's
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001318 #
1319 route_232_1_1_1.update_rpf_id(56)
Neale Ranns31ed7442018-02-23 05:29:09 -08001320 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001321 dst_ip="232.1.1.1")
1322 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop 56")
1323
Neale Ranns31426c62017-05-24 10:32:58 -07001324 def test_mcast_ip6_tail(self):
1325 """ MPLS IPv6 Multicast Tail """
1326
1327 #
1328 # Add a multicast route that will forward the traffic
1329 # post-disposition
1330 #
1331 route_ff = VppIpMRoute(
1332 self,
1333 "::",
1334 "ff01::1", 32,
1335 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
1336 table_id=1,
1337 paths=[VppMRoutePath(self.pg1.sw_if_index,
Neale Ranns097fa662018-05-01 05:17:55 -07001338 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD,
1339 proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)])
Neale Ranns31426c62017-05-24 10:32:58 -07001340 route_ff.add_vpp_config()
1341
1342 #
1343 # An interface receive label that maps traffic to RX on interface
1344 # pg1
1345 # by injecting the packet in on pg0, which is in table 0
1346 # doing an rpf-id and matching a route in table 1
1347 # if the packet egresses, then we must have matched the route in
1348 # table 1
1349 #
1350 route_34_eos = VppMplsRoute(
1351 self, 34, 1,
1352 [VppRoutePath("::",
Neale Ranns097fa662018-05-01 05:17:55 -07001353 0xffffffff,
Neale Ranns31426c62017-05-24 10:32:58 -07001354 nh_table_id=1,
Neale Ranns097fa662018-05-01 05:17:55 -07001355 rpf_id=55)],
1356 is_multicast=1,
1357 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)
Neale Ranns31426c62017-05-24 10:32:58 -07001358
1359 route_34_eos.add_vpp_config()
1360
1361 #
1362 # Drop due to interface lookup miss
1363 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001364 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(34)],
Neale Ranns31426c62017-05-24 10:32:58 -07001365 dst_ip="ff01::1")
Neale Ranns31ed7442018-02-23 05:29:09 -08001366 self.send_and_assert_no_replies(self.pg0, tx, "RPF Miss")
Neale Ranns31426c62017-05-24 10:32:58 -07001367
1368 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001369 # set the RPF-ID of the entry to match the input packet's
Neale Ranns31426c62017-05-24 10:32:58 -07001370 #
1371 route_ff.update_rpf_id(55)
1372
Neale Ranns31ed7442018-02-23 05:29:09 -08001373 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(34)],
Neale Ranns31426c62017-05-24 10:32:58 -07001374 dst_ip="ff01::1")
Neale Ranns31ed7442018-02-23 05:29:09 -08001375 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns31426c62017-05-24 10:32:58 -07001376 self.verify_capture_ip6(self.pg1, rx, tx)
1377
1378 #
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001379 # disposed packets have hop-limit = 1
1380 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001381 tx = self.create_stream_labelled_ip6(self.pg0,
1382 [VppMplsLabel(34)],
1383 dst_ip="ff01::1",
1384 hlim=1)
1385 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns52fae862018-01-08 04:41:42 -08001386 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001387
1388 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001389 # set the RPF-ID of the entry to not match the input packet's
Neale Ranns31426c62017-05-24 10:32:58 -07001390 #
1391 route_ff.update_rpf_id(56)
Neale Ranns31ed7442018-02-23 05:29:09 -08001392 tx = self.create_stream_labelled_ip6(self.pg0,
1393 [VppMplsLabel(34)],
Neale Ranns31426c62017-05-24 10:32:58 -07001394 dst_ip="ff01::1")
1395 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop 56")
1396
Neale Rannsd5d7b962019-08-04 03:30:56 -07001397 def test_6pe(self):
1398 """ MPLS 6PE """
1399
1400 #
1401 # Add a non-recursive route with a single out label
1402 #
1403 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
1404 [VppRoutePath(self.pg0.remote_ip4,
1405 self.pg0.sw_if_index,
1406 labels=[VppMplsLabel(45)])])
1407 route_10_0_0_1.add_vpp_config()
1408
1409 # bind a local label to the route
1410 binding = VppMplsIpBind(self, 44, "10.0.0.1", 32)
1411 binding.add_vpp_config()
1412
1413 #
1414 # a labelled v6 route that resolves through the v4
1415 #
1416 route_2001_3 = VppIpRoute(
1417 self, "2001::3", 128,
1418 [VppRoutePath("10.0.0.1",
1419 INVALID_INDEX,
1420 labels=[VppMplsLabel(32)])])
1421 route_2001_3.add_vpp_config()
1422
1423 tx = self.create_stream_ip6(self.pg0, "2001::3")
1424 rx = self.send_and_expect(self.pg0, tx, self.pg0)
1425
1426 self.verify_capture_labelled_ip6(self.pg0, rx, tx,
1427 [VppMplsLabel(45),
1428 VppMplsLabel(32)])
1429
1430 #
1431 # and a v4 recursive via the v6
1432 #
1433 route_20_3 = VppIpRoute(
1434 self, "20.0.0.3", 32,
1435 [VppRoutePath("2001::3",
1436 INVALID_INDEX,
1437 labels=[VppMplsLabel(99)])])
1438 route_20_3.add_vpp_config()
1439
1440 tx = self.create_stream_ip4(self.pg0, "20.0.0.3")
1441 rx = self.send_and_expect(self.pg0, tx, self.pg0)
1442
1443 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
1444 [VppMplsLabel(45),
1445 VppMplsLabel(32),
1446 VppMplsLabel(99)])
1447
Neale Ranns180279b2017-03-16 15:49:09 -04001448
1449class TestMPLSDisabled(VppTestCase):
1450 """ MPLS disabled """
1451
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -07001452 @classmethod
1453 def setUpClass(cls):
1454 super(TestMPLSDisabled, cls).setUpClass()
1455
1456 @classmethod
1457 def tearDownClass(cls):
1458 super(TestMPLSDisabled, cls).tearDownClass()
1459
Neale Ranns180279b2017-03-16 15:49:09 -04001460 def setUp(self):
1461 super(TestMPLSDisabled, self).setUp()
1462
1463 # create 2 pg interfaces
1464 self.create_pg_interfaces(range(2))
1465
Neale Ranns15002542017-09-10 04:39:11 -07001466 self.tbl = VppMplsTable(self, 0)
1467 self.tbl.add_vpp_config()
1468
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001469 # PG0 is MPLS enabled
Neale Ranns180279b2017-03-16 15:49:09 -04001470 self.pg0.admin_up()
1471 self.pg0.config_ip4()
1472 self.pg0.resolve_arp()
1473 self.pg0.enable_mpls()
1474
1475 # PG 1 is not MPLS enabled
1476 self.pg1.admin_up()
1477
1478 def tearDown(self):
Neale Ranns180279b2017-03-16 15:49:09 -04001479 for i in self.pg_interfaces:
1480 i.unconfig_ip4()
1481 i.admin_down()
1482
Neale Ranns15002542017-09-10 04:39:11 -07001483 self.pg0.disable_mpls()
1484 super(TestMPLSDisabled, self).tearDown()
1485
Neale Ranns180279b2017-03-16 15:49:09 -04001486 def test_mpls_disabled(self):
1487 """ MPLS Disabled """
1488
1489 tx = (Ether(src=self.pg1.remote_mac,
1490 dst=self.pg1.local_mac) /
1491 MPLS(label=32, ttl=64) /
1492 IPv6(src="2001::1", dst=self.pg0.remote_ip6) /
1493 UDP(sport=1234, dport=1234) /
1494 Raw('\xa5' * 100))
1495
1496 #
1497 # A simple MPLS xconnect - eos label in label out
1498 #
1499 route_32_eos = VppMplsRoute(self, 32, 1,
1500 [VppRoutePath(self.pg0.remote_ip4,
1501 self.pg0.sw_if_index,
1502 labels=[33])])
1503 route_32_eos.add_vpp_config()
1504
1505 #
1506 # PG1 does not forward IP traffic
1507 #
1508 self.send_and_assert_no_replies(self.pg1, tx, "MPLS disabled")
1509
1510 #
1511 # MPLS enable PG1
1512 #
1513 self.pg1.enable_mpls()
1514
1515 #
1516 # Now we get packets through
1517 #
1518 self.pg1.add_stream(tx)
1519 self.pg_enable_capture(self.pg_interfaces)
1520 self.pg_start()
1521
1522 rx = self.pg0.get_capture(1)
1523
1524 #
1525 # Disable PG1
1526 #
1527 self.pg1.disable_mpls()
1528
1529 #
1530 # PG1 does not forward IP traffic
1531 #
1532 self.send_and_assert_no_replies(self.pg1, tx, "IPv6 disabled")
1533 self.send_and_assert_no_replies(self.pg1, tx, "IPv6 disabled")
1534
1535
Neale Rannsf12a83f2017-04-18 09:09:40 -07001536class TestMPLSPIC(VppTestCase):
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001537 """ MPLS Prefix-Independent Convergence (PIC) edge convergence """
Neale Rannsf12a83f2017-04-18 09:09:40 -07001538
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -07001539 @classmethod
1540 def setUpClass(cls):
1541 super(TestMPLSPIC, cls).setUpClass()
1542
1543 @classmethod
1544 def tearDownClass(cls):
1545 super(TestMPLSPIC, cls).tearDownClass()
1546
Neale Rannsf12a83f2017-04-18 09:09:40 -07001547 def setUp(self):
1548 super(TestMPLSPIC, self).setUp()
1549
1550 # create 2 pg interfaces
1551 self.create_pg_interfaces(range(4))
1552
Neale Ranns15002542017-09-10 04:39:11 -07001553 mpls_tbl = VppMplsTable(self, 0)
1554 mpls_tbl.add_vpp_config()
1555 tbl4 = VppIpTable(self, 1)
1556 tbl4.add_vpp_config()
1557 tbl6 = VppIpTable(self, 1, is_ip6=1)
1558 tbl6.add_vpp_config()
1559
Neale Rannsf12a83f2017-04-18 09:09:40 -07001560 # core links
1561 self.pg0.admin_up()
1562 self.pg0.config_ip4()
1563 self.pg0.resolve_arp()
1564 self.pg0.enable_mpls()
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001565
Neale Rannsf12a83f2017-04-18 09:09:40 -07001566 self.pg1.admin_up()
1567 self.pg1.config_ip4()
1568 self.pg1.resolve_arp()
1569 self.pg1.enable_mpls()
1570
1571 # VRF (customer facing) link
1572 self.pg2.admin_up()
1573 self.pg2.set_table_ip4(1)
1574 self.pg2.config_ip4()
1575 self.pg2.resolve_arp()
1576 self.pg2.set_table_ip6(1)
1577 self.pg2.config_ip6()
1578 self.pg2.resolve_ndp()
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001579
Neale Rannsf12a83f2017-04-18 09:09:40 -07001580 self.pg3.admin_up()
1581 self.pg3.set_table_ip4(1)
1582 self.pg3.config_ip4()
1583 self.pg3.resolve_arp()
1584 self.pg3.set_table_ip6(1)
1585 self.pg3.config_ip6()
1586 self.pg3.resolve_ndp()
1587
1588 def tearDown(self):
Neale Rannsf12a83f2017-04-18 09:09:40 -07001589 self.pg0.disable_mpls()
Neale Ranns15002542017-09-10 04:39:11 -07001590 self.pg1.disable_mpls()
Neale Rannsf12a83f2017-04-18 09:09:40 -07001591 for i in self.pg_interfaces:
1592 i.unconfig_ip4()
1593 i.unconfig_ip6()
1594 i.set_table_ip4(0)
1595 i.set_table_ip6(0)
1596 i.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -07001597 super(TestMPLSPIC, self).tearDown()
Neale Rannsf12a83f2017-04-18 09:09:40 -07001598
1599 def test_mpls_ibgp_pic(self):
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001600 """ MPLS iBGP Prefix-Independent Convergence (PIC) edge convergence
Neale Rannsf12a83f2017-04-18 09:09:40 -07001601
1602 1) setup many iBGP VPN routes via a pair of iBGP peers.
1603 2) Check EMCP forwarding to these peers
1604 3) withdraw the IGP route to one of these peers.
1605 4) check forwarding continues to the remaining peer
1606 """
1607
1608 #
1609 # IGP+LDP core routes
1610 #
1611 core_10_0_0_45 = VppIpRoute(self, "10.0.0.45", 32,
1612 [VppRoutePath(self.pg0.remote_ip4,
1613 self.pg0.sw_if_index,
1614 labels=[45])])
1615 core_10_0_0_45.add_vpp_config()
1616
1617 core_10_0_0_46 = VppIpRoute(self, "10.0.0.46", 32,
1618 [VppRoutePath(self.pg1.remote_ip4,
1619 self.pg1.sw_if_index,
1620 labels=[46])])
1621 core_10_0_0_46.add_vpp_config()
1622
1623 #
1624 # Lot's of VPN routes. We need more the 64 so VPP will build
1625 # the fast convergence indirection
1626 #
1627 vpn_routes = []
1628 pkts = []
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001629 for ii in range(NUM_PKTS):
Neale Rannsf12a83f2017-04-18 09:09:40 -07001630 dst = "192.168.1.%d" % ii
Neale Ranns097fa662018-05-01 05:17:55 -07001631 vpn_routes.append(VppIpRoute(
1632 self, dst, 32,
1633 [VppRoutePath(
1634 "10.0.0.45",
1635 0xffffffff,
1636 labels=[145],
1637 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_HOST),
1638 VppRoutePath(
1639 "10.0.0.46",
1640 0xffffffff,
1641 labels=[146],
1642 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_HOST)],
1643 table_id=1))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001644 vpn_routes[ii].add_vpp_config()
1645
1646 pkts.append(Ether(dst=self.pg2.local_mac,
1647 src=self.pg2.remote_mac) /
1648 IP(src=self.pg2.remote_ip4, dst=dst) /
1649 UDP(sport=1234, dport=1234) /
1650 Raw('\xa5' * 100))
1651
1652 #
1653 # Send the packet stream (one pkt to each VPN route)
1654 # - expect a 50-50 split of the traffic
1655 #
1656 self.pg2.add_stream(pkts)
1657 self.pg_enable_capture(self.pg_interfaces)
1658 self.pg_start()
1659
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001660 rx0 = self.pg0._get_capture(NUM_PKTS)
1661 rx1 = self.pg1._get_capture(NUM_PKTS)
Neale Rannsf12a83f2017-04-18 09:09:40 -07001662
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001663 # not testing the LB hashing algorithm so we're not concerned
Neale Rannsf12a83f2017-04-18 09:09:40 -07001664 # with the split ratio, just as long as neither is 0
1665 self.assertNotEqual(0, len(rx0))
1666 self.assertNotEqual(0, len(rx1))
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001667 self.assertEqual(len(pkts), len(rx0) + len(rx1),
1668 "Expected all (%s) packets across both ECMP paths. "
1669 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001670
1671 #
1672 # use a test CLI command to stop the FIB walk process, this
1673 # will prevent the FIB converging the VPN routes and thus allow
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001674 # us to probe the interim (post-fail, pre-converge) state
Neale Rannsf12a83f2017-04-18 09:09:40 -07001675 #
1676 self.vapi.ppcli("test fib-walk-process disable")
1677
1678 #
1679 # Withdraw one of the IGP routes
1680 #
1681 core_10_0_0_46.remove_vpp_config()
1682
1683 #
1684 # now all packets should be forwarded through the remaining peer
1685 #
1686 self.vapi.ppcli("clear trace")
1687 self.pg2.add_stream(pkts)
1688 self.pg_enable_capture(self.pg_interfaces)
1689 self.pg_start()
1690
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001691 rx0 = self.pg0.get_capture(NUM_PKTS)
1692 self.assertEqual(len(pkts), len(rx0),
1693 "Expected all (%s) packets across single path. "
1694 "rx0: %s." % (len(pkts), len(rx0)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001695
1696 #
1697 # enable the FIB walk process to converge the FIB
1698 #
1699 self.vapi.ppcli("test fib-walk-process enable")
1700
1701 #
1702 # packets should still be forwarded through the remaining peer
1703 #
1704 self.pg2.add_stream(pkts)
1705 self.pg_enable_capture(self.pg_interfaces)
1706 self.pg_start()
1707
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001708 rx0 = self.pg0.get_capture(NUM_PKTS)
1709 self.assertEqual(len(pkts), len(rx0),
1710 "Expected all (%s) packets across single path. "
1711 "rx0: %s." % (len(pkts), len(rx0)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001712
1713 #
1714 # Add the IGP route back and we return to load-balancing
1715 #
1716 core_10_0_0_46.add_vpp_config()
1717
1718 self.pg2.add_stream(pkts)
1719 self.pg_enable_capture(self.pg_interfaces)
1720 self.pg_start()
1721
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001722 rx0 = self.pg0._get_capture(NUM_PKTS)
1723 rx1 = self.pg1._get_capture(NUM_PKTS)
Neale Rannsf12a83f2017-04-18 09:09:40 -07001724 self.assertNotEqual(0, len(rx0))
1725 self.assertNotEqual(0, len(rx1))
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001726 self.assertEqual(len(pkts), len(rx0) + len(rx1),
1727 "Expected all (%s) packets across both ECMP paths. "
1728 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001729
1730 def test_mpls_ebgp_pic(self):
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001731 """ MPLS eBGP Prefix-Independent Convergence (PIC) edge convergence
Neale Rannsf12a83f2017-04-18 09:09:40 -07001732
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001733 1) setup many eBGP VPN routes via a pair of eBGP peers.
Neale Rannsf12a83f2017-04-18 09:09:40 -07001734 2) Check EMCP forwarding to these peers
1735 3) withdraw one eBGP path - expect LB across remaining eBGP
1736 """
1737
1738 #
1739 # Lot's of VPN routes. We need more the 64 so VPP will build
1740 # the fast convergence indirection
1741 #
1742 vpn_routes = []
1743 vpn_bindings = []
1744 pkts = []
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001745 for ii in range(NUM_PKTS):
Neale Rannsf12a83f2017-04-18 09:09:40 -07001746 dst = "192.168.1.%d" % ii
1747 local_label = 1600 + ii
Neale Ranns097fa662018-05-01 05:17:55 -07001748 vpn_routes.append(VppIpRoute(
1749 self, dst, 32,
1750 [VppRoutePath(
1751 self.pg2.remote_ip4,
1752 0xffffffff,
1753 nh_table_id=1,
1754 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_ATTACHED),
1755 VppRoutePath(
1756 self.pg3.remote_ip4,
1757 0xffffffff,
1758 nh_table_id=1,
1759 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_ATTACHED)],
1760 table_id=1))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001761 vpn_routes[ii].add_vpp_config()
1762
1763 vpn_bindings.append(VppMplsIpBind(self, local_label, dst, 32,
1764 ip_table_id=1))
1765 vpn_bindings[ii].add_vpp_config()
1766
1767 pkts.append(Ether(dst=self.pg0.local_mac,
1768 src=self.pg0.remote_mac) /
1769 MPLS(label=local_label, ttl=64) /
1770 IP(src=self.pg0.remote_ip4, dst=dst) /
1771 UDP(sport=1234, dport=1234) /
1772 Raw('\xa5' * 100))
1773
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001774 #
1775 # Send the packet stream (one pkt to each VPN route)
1776 # - expect a 50-50 split of the traffic
1777 #
Neale Rannsf12a83f2017-04-18 09:09:40 -07001778 self.pg0.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.pg2._get_capture(NUM_PKTS)
1783 rx1 = self.pg3._get_capture(NUM_PKTS)
1784
1785 # not testing the LB hashing algorithm so we're not concerned
1786 # with the split ratio, just as long as neither is 0
Neale Rannsf12a83f2017-04-18 09:09:40 -07001787 self.assertNotEqual(0, len(rx0))
1788 self.assertNotEqual(0, len(rx1))
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001789 self.assertEqual(len(pkts), len(rx0) + len(rx1),
1790 "Expected all (%s) packets across both ECMP paths. "
1791 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001792
1793 #
1794 # use a test CLI command to stop the FIB walk process, this
1795 # will prevent the FIB converging the VPN routes and thus allow
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001796 # us to probe the interim (post-fail, pre-converge) state
Neale Rannsf12a83f2017-04-18 09:09:40 -07001797 #
1798 self.vapi.ppcli("test fib-walk-process disable")
1799
1800 #
1801 # withdraw the connected prefix on the interface.
1802 #
1803 self.pg2.unconfig_ip4()
1804
1805 #
1806 # now all packets should be forwarded through the remaining peer
1807 #
1808 self.pg0.add_stream(pkts)
1809 self.pg_enable_capture(self.pg_interfaces)
1810 self.pg_start()
1811
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001812 rx0 = self.pg3.get_capture(NUM_PKTS)
1813 self.assertEqual(len(pkts), len(rx0),
1814 "Expected all (%s) packets across single path. "
1815 "rx0: %s." % (len(pkts), len(rx0)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001816
1817 #
1818 # enable the FIB walk process to converge the FIB
1819 #
1820 self.vapi.ppcli("test fib-walk-process enable")
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001821
1822 #
1823 # packets should still be forwarded through the remaining peer
1824 #
Neale Rannsf12a83f2017-04-18 09:09:40 -07001825 self.pg0.add_stream(pkts)
1826 self.pg_enable_capture(self.pg_interfaces)
1827 self.pg_start()
1828
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001829 rx0 = self.pg3.get_capture(NUM_PKTS)
1830 self.assertEqual(len(pkts), len(rx0),
1831 "Expected all (%s) packets across single path. "
1832 "rx0: %s." % (len(pkts), len(rx0)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001833
1834 #
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001835 # put the connected routes back
Neale Rannsf12a83f2017-04-18 09:09:40 -07001836 #
1837 self.pg2.config_ip4()
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001838 self.pg2.resolve_arp()
Neale Rannsf12a83f2017-04-18 09:09:40 -07001839
1840 self.pg0.add_stream(pkts)
1841 self.pg_enable_capture(self.pg_interfaces)
1842 self.pg_start()
1843
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001844 rx0 = self.pg2._get_capture(NUM_PKTS)
1845 rx1 = self.pg3._get_capture(NUM_PKTS)
Neale Rannsf12a83f2017-04-18 09:09:40 -07001846 self.assertNotEqual(0, len(rx0))
1847 self.assertNotEqual(0, len(rx1))
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001848 self.assertEqual(len(pkts), len(rx0) + len(rx1),
1849 "Expected all (%s) packets across both ECMP paths. "
1850 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001851
1852 def test_mpls_v6_ebgp_pic(self):
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001853 """ MPLSv6 eBGP Prefix-Independent Convergence (PIC) edge convergence
Neale Rannsf12a83f2017-04-18 09:09:40 -07001854
1855 1) setup many eBGP VPNv6 routes via a pair of eBGP peers
1856 2) Check EMCP forwarding to these peers
1857 3) withdraw one eBGP path - expect LB across remaining eBGP
1858 """
1859
1860 #
1861 # Lot's of VPN routes. We need more the 64 so VPP will build
1862 # the fast convergence indirection
1863 #
1864 vpn_routes = []
1865 vpn_bindings = []
1866 pkts = []
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001867 for ii in range(NUM_PKTS):
Neale Rannsf12a83f2017-04-18 09:09:40 -07001868 dst = "3000::%d" % ii
1869 local_label = 1600 + ii
Neale Rannsda78f952017-05-24 09:15:43 -07001870 vpn_routes.append(VppIpRoute(
1871 self, dst, 128,
Neale Ranns097fa662018-05-01 05:17:55 -07001872 [VppRoutePath(
1873 self.pg2.remote_ip6,
1874 0xffffffff,
1875 nh_table_id=1,
1876 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_ATTACHED),
1877 VppRoutePath(
1878 self.pg3.remote_ip6,
1879 0xffffffff,
1880 nh_table_id=1,
1881 flags=FibPathFlags.FIB_PATH_FLAG_RESOLVE_VIA_ATTACHED)],
1882 table_id=1))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001883 vpn_routes[ii].add_vpp_config()
1884
1885 vpn_bindings.append(VppMplsIpBind(self, local_label, dst, 128,
Neale Ranns097fa662018-05-01 05:17:55 -07001886 ip_table_id=1))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001887 vpn_bindings[ii].add_vpp_config()
1888
1889 pkts.append(Ether(dst=self.pg0.local_mac,
1890 src=self.pg0.remote_mac) /
1891 MPLS(label=local_label, ttl=64) /
1892 IPv6(src=self.pg0.remote_ip6, dst=dst) /
1893 UDP(sport=1234, dport=1234) /
1894 Raw('\xa5' * 100))
Neale Ranns097fa662018-05-01 05:17:55 -07001895 self.logger.info(self.vapi.cli("sh ip6 fib %s" % dst))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001896
1897 self.pg0.add_stream(pkts)
1898 self.pg_enable_capture(self.pg_interfaces)
1899 self.pg_start()
1900
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001901 rx0 = self.pg2._get_capture(NUM_PKTS)
1902 rx1 = self.pg3._get_capture(NUM_PKTS)
Neale Rannsf12a83f2017-04-18 09:09:40 -07001903 self.assertNotEqual(0, len(rx0))
1904 self.assertNotEqual(0, len(rx1))
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001905 self.assertEqual(len(pkts), len(rx0) + len(rx1),
1906 "Expected all (%s) packets across both ECMP paths. "
1907 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001908
1909 #
1910 # use a test CLI command to stop the FIB walk process, this
1911 # will prevent the FIB converging the VPN routes and thus allow
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001912 # us to probe the interim (post-fail, pre-converge) state
Neale Rannsf12a83f2017-04-18 09:09:40 -07001913 #
1914 self.vapi.ppcli("test fib-walk-process disable")
1915
1916 #
1917 # withdraw the connected prefix on the interface.
1918 # and shutdown the interface so the ND cache is flushed.
1919 #
1920 self.pg2.unconfig_ip6()
1921 self.pg2.admin_down()
1922
1923 #
1924 # now all packets should be forwarded through the remaining peer
1925 #
1926 self.pg0.add_stream(pkts)
1927 self.pg_enable_capture(self.pg_interfaces)
1928 self.pg_start()
1929
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001930 rx0 = self.pg3.get_capture(NUM_PKTS)
1931 self.assertEqual(len(pkts), len(rx0),
1932 "Expected all (%s) packets across single path. "
1933 "rx0: %s." % (len(pkts), len(rx0)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001934
1935 #
1936 # enable the FIB walk process to converge the FIB
1937 #
1938 self.vapi.ppcli("test fib-walk-process enable")
1939 self.pg0.add_stream(pkts)
1940 self.pg_enable_capture(self.pg_interfaces)
1941 self.pg_start()
1942
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001943 rx0 = self.pg3.get_capture(NUM_PKTS)
1944 self.assertEqual(len(pkts), len(rx0),
1945 "Expected all (%s) packets across single path. "
1946 "rx0: %s." % (len(pkts), len(rx0)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001947
1948 #
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001949 # put the connected routes back
Neale Rannsf12a83f2017-04-18 09:09:40 -07001950 #
1951 self.pg2.admin_up()
1952 self.pg2.config_ip6()
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001953 self.pg2.resolve_ndp()
Neale Rannsf12a83f2017-04-18 09:09:40 -07001954
1955 self.pg0.add_stream(pkts)
1956 self.pg_enable_capture(self.pg_interfaces)
1957 self.pg_start()
1958
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001959 rx0 = self.pg2._get_capture(NUM_PKTS)
1960 rx1 = self.pg3._get_capture(NUM_PKTS)
Neale Rannsf12a83f2017-04-18 09:09:40 -07001961 self.assertNotEqual(0, len(rx0))
1962 self.assertNotEqual(0, len(rx1))
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04001963 self.assertEqual(len(pkts), len(rx0) + len(rx1),
1964 "Expected all (%s) packets across both ECMP paths. "
1965 "rx0: %s rx1: %s." % (len(pkts), len(rx0), len(rx1)))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001966
1967
Neale Rannsda78f952017-05-24 09:15:43 -07001968class TestMPLSL2(VppTestCase):
1969 """ MPLS-L2 """
1970
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -07001971 @classmethod
1972 def setUpClass(cls):
1973 super(TestMPLSL2, cls).setUpClass()
1974
1975 @classmethod
1976 def tearDownClass(cls):
1977 super(TestMPLSL2, cls).tearDownClass()
1978
Neale Rannsda78f952017-05-24 09:15:43 -07001979 def setUp(self):
1980 super(TestMPLSL2, self).setUp()
1981
1982 # create 2 pg interfaces
1983 self.create_pg_interfaces(range(2))
1984
Neale Ranns15002542017-09-10 04:39:11 -07001985 # create the default MPLS table
1986 self.tables = []
1987 tbl = VppMplsTable(self, 0)
1988 tbl.add_vpp_config()
1989 self.tables.append(tbl)
1990
Neale Rannsda78f952017-05-24 09:15:43 -07001991 # use pg0 as the core facing interface
1992 self.pg0.admin_up()
1993 self.pg0.config_ip4()
1994 self.pg0.resolve_arp()
1995 self.pg0.enable_mpls()
1996
Neale Ranns15002542017-09-10 04:39:11 -07001997 # use the other 2 for customer facing L2 links
Neale Rannsda78f952017-05-24 09:15:43 -07001998 for i in self.pg_interfaces[1:]:
1999 i.admin_up()
2000
2001 def tearDown(self):
Neale Rannsda78f952017-05-24 09:15:43 -07002002 for i in self.pg_interfaces[1:]:
2003 i.admin_down()
2004
2005 self.pg0.disable_mpls()
2006 self.pg0.unconfig_ip4()
2007 self.pg0.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -07002008 super(TestMPLSL2, self).tearDown()
Neale Rannsda78f952017-05-24 09:15:43 -07002009
Neale Ranns31ed7442018-02-23 05:29:09 -08002010 def verify_capture_tunneled_ethernet(self, capture, sent, mpls_labels):
Neale Rannsda78f952017-05-24 09:15:43 -07002011 capture = verify_filter(capture, sent)
2012
2013 self.assertEqual(len(capture), len(sent))
2014
2015 for i in range(len(capture)):
2016 tx = sent[i]
2017 rx = capture[i]
2018
2019 # the MPLS TTL is 255 since it enters a new tunnel
Neale Ranns31ed7442018-02-23 05:29:09 -08002020 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsda78f952017-05-24 09:15:43 -07002021
2022 tx_eth = tx[Ether]
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -07002023 rx_eth = Ether(scapy.compat.raw(rx[MPLS].payload))
Neale Rannsda78f952017-05-24 09:15:43 -07002024
2025 self.assertEqual(rx_eth.src, tx_eth.src)
2026 self.assertEqual(rx_eth.dst, tx_eth.dst)
2027
2028 def test_vpws(self):
2029 """ Virtual Private Wire Service """
2030
2031 #
2032 # Create an MPLS tunnel that pushes 1 label
Neale Ranns31ed7442018-02-23 05:29:09 -08002033 # For Ethernet over MPLS the uniform mode is irrelevant since ttl/cos
2034 # information is not in the packet, but we test it works anyway
Neale Rannsda78f952017-05-24 09:15:43 -07002035 #
Neale Ranns31ed7442018-02-23 05:29:09 -08002036 mpls_tun_1 = VppMPLSTunnelInterface(
2037 self,
2038 [VppRoutePath(self.pg0.remote_ip4,
2039 self.pg0.sw_if_index,
2040 labels=[VppMplsLabel(42, MplsLspMode.UNIFORM)])],
2041 is_l2=1)
Neale Rannsda78f952017-05-24 09:15:43 -07002042 mpls_tun_1.add_vpp_config()
2043 mpls_tun_1.admin_up()
2044
2045 #
2046 # Create a label entry to for 55 that does L2 input to the tunnel
2047 #
2048 route_55_eos = VppMplsRoute(
2049 self, 55, 1,
2050 [VppRoutePath("0.0.0.0",
2051 mpls_tun_1.sw_if_index,
Neale Ranns097fa662018-05-01 05:17:55 -07002052 type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX,
2053 proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET)],
2054 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET)
Neale Rannsda78f952017-05-24 09:15:43 -07002055 route_55_eos.add_vpp_config()
2056
2057 #
2058 # Cross-connect the tunnel with one of the customers L2 interfaces
2059 #
2060 self.vapi.sw_interface_set_l2_xconnect(self.pg1.sw_if_index,
2061 mpls_tun_1.sw_if_index,
2062 enable=1)
2063 self.vapi.sw_interface_set_l2_xconnect(mpls_tun_1.sw_if_index,
2064 self.pg1.sw_if_index,
2065 enable=1)
2066
2067 #
2068 # inject a packet from the core
2069 #
2070 pcore = (Ether(dst=self.pg0.local_mac,
2071 src=self.pg0.remote_mac) /
2072 MPLS(label=55, ttl=64) /
2073 Ether(dst="00:00:de:ad:ba:be",
2074 src="00:00:de:ad:be:ef") /
2075 IP(src="10.10.10.10", dst="11.11.11.11") /
2076 UDP(sport=1234, dport=1234) /
2077 Raw('\xa5' * 100))
2078
Paul Vinciguerra4271c972019-05-14 13:25:49 -04002079 tx0 = pcore * NUM_PKTS
Neale Ranns31ed7442018-02-23 05:29:09 -08002080 rx0 = self.send_and_expect(self.pg0, tx0, self.pg1)
2081 payload = pcore[MPLS].payload
Neale Rannsda78f952017-05-24 09:15:43 -07002082
Neale Ranns31ed7442018-02-23 05:29:09 -08002083 self.assertEqual(rx0[0][Ether].dst, payload[Ether].dst)
2084 self.assertEqual(rx0[0][Ether].src, payload[Ether].src)
Neale Rannsda78f952017-05-24 09:15:43 -07002085
2086 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07002087 # Inject a packet from the customer/L2 side
Neale Rannsda78f952017-05-24 09:15:43 -07002088 #
Paul Vinciguerra4271c972019-05-14 13:25:49 -04002089 tx1 = pcore[MPLS].payload * NUM_PKTS
Neale Ranns31ed7442018-02-23 05:29:09 -08002090 rx1 = self.send_and_expect(self.pg1, tx1, self.pg0)
Neale Rannsda78f952017-05-24 09:15:43 -07002091
Neale Ranns31ed7442018-02-23 05:29:09 -08002092 self.verify_capture_tunneled_ethernet(rx1, tx1, [VppMplsLabel(42)])
Neale Rannsda78f952017-05-24 09:15:43 -07002093
2094 def test_vpls(self):
2095 """ Virtual Private LAN Service """
2096 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002097 # Create a L2 MPLS tunnels
Neale Rannsda78f952017-05-24 09:15:43 -07002098 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002099 mpls_tun1 = VppMPLSTunnelInterface(
Neale Ranns31ed7442018-02-23 05:29:09 -08002100 self,
2101 [VppRoutePath(self.pg0.remote_ip4,
2102 self.pg0.sw_if_index,
2103 labels=[VppMplsLabel(42)])],
2104 is_l2=1)
Neale Ranns1dbcf302019-07-19 11:44:53 +00002105 mpls_tun1.add_vpp_config()
2106 mpls_tun1.admin_up()
2107
2108 mpls_tun2 = VppMPLSTunnelInterface(
2109 self,
2110 [VppRoutePath(self.pg0.remote_ip4,
2111 self.pg0.sw_if_index,
2112 labels=[VppMplsLabel(43)])],
2113 is_l2=1)
2114 mpls_tun2.add_vpp_config()
2115 mpls_tun2.admin_up()
Neale Rannsda78f952017-05-24 09:15:43 -07002116
2117 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002118 # Create a label entries, 55 and 56, that do L2 input to the tunnel
2119 # the latter includes a Psuedo Wire Control Word
Neale Rannsda78f952017-05-24 09:15:43 -07002120 #
2121 route_55_eos = VppMplsRoute(
2122 self, 55, 1,
2123 [VppRoutePath("0.0.0.0",
Neale Ranns1dbcf302019-07-19 11:44:53 +00002124 mpls_tun1.sw_if_index,
Neale Ranns097fa662018-05-01 05:17:55 -07002125 type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX,
2126 proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET)],
2127 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET)
Neale Ranns1dbcf302019-07-19 11:44:53 +00002128
2129 route_56_eos = VppMplsRoute(
2130 self, 56, 1,
2131 [VppRoutePath("0.0.0.0",
2132 mpls_tun2.sw_if_index,
2133 type=FibPathType.FIB_PATH_TYPE_INTERFACE_RX,
2134 flags=FibPathFlags.FIB_PATH_FLAG_POP_PW_CW,
2135 proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET)],
2136 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_ETHERNET)
2137
2138 # move me
2139 route_56_eos.add_vpp_config()
Neale Rannsda78f952017-05-24 09:15:43 -07002140 route_55_eos.add_vpp_config()
2141
Neale Ranns1dbcf302019-07-19 11:44:53 +00002142 self.logger.info(self.vapi.cli("sh mpls fib 56"))
2143
Neale Rannsda78f952017-05-24 09:15:43 -07002144 #
2145 # add to tunnel to the customers bridge-domain
2146 #
Ole Troana5b2eec2019-03-11 19:23:25 +01002147 self.vapi.sw_interface_set_l2_bridge(
Neale Ranns1dbcf302019-07-19 11:44:53 +00002148 rx_sw_if_index=mpls_tun1.sw_if_index, bd_id=1)
2149 self.vapi.sw_interface_set_l2_bridge(
2150 rx_sw_if_index=mpls_tun2.sw_if_index, bd_id=1)
Ole Troana5b2eec2019-03-11 19:23:25 +01002151 self.vapi.sw_interface_set_l2_bridge(
2152 rx_sw_if_index=self.pg1.sw_if_index, bd_id=1)
Neale Rannsda78f952017-05-24 09:15:43 -07002153
2154 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002155 # Packet from host on the customer interface to each host
2156 # reachable over the core, and vice-versa
Neale Rannsda78f952017-05-24 09:15:43 -07002157 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002158 p_cust1 = (Ether(dst="00:00:de:ad:ba:b1",
2159 src="00:00:de:ad:be:ef") /
2160 IP(src="10.10.10.10", dst="11.11.11.11") /
2161 UDP(sport=1234, dport=1234) /
2162 Raw('\xa5' * 100))
2163 p_cust2 = (Ether(dst="00:00:de:ad:ba:b2",
2164 src="00:00:de:ad:be:ef") /
2165 IP(src="10.10.10.10", dst="11.11.11.12") /
2166 UDP(sport=1234, dport=1234) /
2167 Raw('\xa5' * 100))
2168 p_core1 = (Ether(dst=self.pg0.local_mac,
2169 src=self.pg0.remote_mac) /
2170 MPLS(label=55, ttl=64) /
2171 Ether(src="00:00:de:ad:ba:b1",
2172 dst="00:00:de:ad:be:ef") /
2173 IP(dst="10.10.10.10", src="11.11.11.11") /
2174 UDP(sport=1234, dport=1234) /
2175 Raw('\xa5' * 100))
2176 p_core2 = (Ether(dst=self.pg0.local_mac,
2177 src=self.pg0.remote_mac) /
2178 MPLS(label=56, ttl=64) /
2179 Raw('\x01' * 4) / # PW CW
2180 Ether(src="00:00:de:ad:ba:b2",
2181 dst="00:00:de:ad:be:ef") /
2182 IP(dst="10.10.10.10", src="11.11.11.12") /
2183 UDP(sport=1234, dport=1234) /
2184 Raw('\xa5' * 100))
Neale Rannsda78f952017-05-24 09:15:43 -07002185
2186 #
2187 # The BD is learning, so send in one of each packet to learn
2188 #
Neale Rannsda78f952017-05-24 09:15:43 -07002189
Neale Ranns1dbcf302019-07-19 11:44:53 +00002190 # 2 packets due to BD flooding
2191 rx = self.send_and_expect(self.pg1, p_cust1, self.pg0, n_rx=2)
2192 rx = self.send_and_expect(self.pg1, p_cust2, self.pg0, n_rx=2)
Neale Rannsda78f952017-05-24 09:15:43 -07002193
Neale Ranns1dbcf302019-07-19 11:44:53 +00002194 # we've learnt this so expect it be be forwarded not flooded
2195 rx = self.send_and_expect(self.pg0, [p_core1], self.pg1)
2196 self.assertEqual(rx[0][Ether].dst, p_cust1[Ether].src)
2197 self.assertEqual(rx[0][Ether].src, p_cust1[Ether].dst)
Neale Rannsda78f952017-05-24 09:15:43 -07002198
Neale Ranns1dbcf302019-07-19 11:44:53 +00002199 rx = self.send_and_expect(self.pg0, [p_core2], self.pg1)
2200 self.assertEqual(rx[0][Ether].dst, p_cust2[Ether].src)
2201 self.assertEqual(rx[0][Ether].src, p_cust2[Ether].dst)
Neale Rannsda78f952017-05-24 09:15:43 -07002202
2203 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002204 # now a stream in each direction from each host
Neale Rannsda78f952017-05-24 09:15:43 -07002205 #
Neale Ranns1dbcf302019-07-19 11:44:53 +00002206 rx = self.send_and_expect(self.pg1, p_cust1 * NUM_PKTS, self.pg0)
2207 self.verify_capture_tunneled_ethernet(rx, p_cust1 * NUM_PKTS,
Neale Ranns31ed7442018-02-23 05:29:09 -08002208 [VppMplsLabel(42)])
Neale Rannsda78f952017-05-24 09:15:43 -07002209
Neale Ranns1dbcf302019-07-19 11:44:53 +00002210 rx = self.send_and_expect(self.pg1, p_cust2 * NUM_PKTS, self.pg0)
2211 self.verify_capture_tunneled_ethernet(rx, p_cust2 * NUM_PKTS,
2212 [VppMplsLabel(43)])
2213
2214 rx = self.send_and_expect(self.pg0, p_core1 * NUM_PKTS, self.pg1)
2215 rx = self.send_and_expect(self.pg0, p_core2 * NUM_PKTS, self.pg1)
2216
Neale Rannsda78f952017-05-24 09:15:43 -07002217 #
2218 # remove interfaces from customers bridge-domain
2219 #
Ole Troana5b2eec2019-03-11 19:23:25 +01002220 self.vapi.sw_interface_set_l2_bridge(
Neale Ranns1dbcf302019-07-19 11:44:53 +00002221 rx_sw_if_index=mpls_tun1.sw_if_index, bd_id=1, enable=0)
2222 self.vapi.sw_interface_set_l2_bridge(
2223 rx_sw_if_index=mpls_tun2.sw_if_index, bd_id=1, enable=0)
Ole Troana5b2eec2019-03-11 19:23:25 +01002224 self.vapi.sw_interface_set_l2_bridge(
2225 rx_sw_if_index=self.pg1.sw_if_index, bd_id=1, enable=0)
Neale Rannsda78f952017-05-24 09:15:43 -07002226
Paul Vinciguerra80b5e4f2019-05-09 15:53:10 -04002227
Neale Ranns8fe8cc22016-11-01 10:05:08 +00002228if __name__ == '__main__':
2229 unittest.main(testRunner=VppTestRunner)