blob: 4a1c663c444f3c59c2622dc50b138baa975a23c2 [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 Rannsc0a93142018-09-05 15:42:26 -07007from vpp_ip import DpoProto
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 Ranns775f73c2018-12-20 03:01:49 -080011 VppMplsLabel, MplsLspMode, find_mpls_route
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012from vpp_mpls_tunnel_interface import VppMPLSTunnelInterface
Neale Ranns8fe8cc22016-11-01 10:05:08 +000013
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -070014import scapy.compat
Neale Ranns8fe8cc22016-11-01 10:05:08 +000015from scapy.packet import Raw
Klement Sekera7bb873a2016-11-18 07:38:42 +010016from scapy.layers.l2 import Ether
Neale Rannscb630ff2016-12-14 13:31:29 +010017from scapy.layers.inet import IP, UDP, ICMP
Neale Ranns62fe07c2017-10-31 12:28:22 -070018from scapy.layers.inet6 import IPv6, ICMPv6TimeExceeded
Neale Ranns8fe8cc22016-11-01 10:05:08 +000019from scapy.contrib.mpls import MPLS
20
Klement Sekeradab231a2016-12-21 08:50:14 +010021
Neale Rannsda78f952017-05-24 09:15:43 -070022def verify_filter(capture, sent):
23 if not len(capture) == len(sent):
24 # filter out any IPv6 RAs from the capture
25 for p in capture:
26 if p.haslayer(IPv6):
27 capture.remove(p)
28 return capture
29
30
Neale Ranns31ed7442018-02-23 05:29:09 -080031def verify_mpls_stack(tst, rx, mpls_labels):
Neale Rannsda78f952017-05-24 09:15:43 -070032 # the rx'd packet has the MPLS label popped
33 eth = rx[Ether]
34 tst.assertEqual(eth.type, 0x8847)
35
36 rx_mpls = rx[MPLS]
37
38 for ii in range(len(mpls_labels)):
Neale Ranns31ed7442018-02-23 05:29:09 -080039 tst.assertEqual(rx_mpls.label, mpls_labels[ii].value)
40 tst.assertEqual(rx_mpls.cos, mpls_labels[ii].exp)
41 tst.assertEqual(rx_mpls.ttl, mpls_labels[ii].ttl)
42
Neale Rannsda78f952017-05-24 09:15:43 -070043 if ii == len(mpls_labels) - 1:
44 tst.assertEqual(rx_mpls.s, 1)
45 else:
46 # not end of stack
47 tst.assertEqual(rx_mpls.s, 0)
48 # pop the label to expose the next
49 rx_mpls = rx_mpls[MPLS].payload
50
51
Neale Ranns8fe8cc22016-11-01 10:05:08 +000052class TestMPLS(VppTestCase):
53 """ MPLS Test Case """
54
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -070055 @classmethod
56 def setUpClass(cls):
57 super(TestMPLS, cls).setUpClass()
58
59 @classmethod
60 def tearDownClass(cls):
61 super(TestMPLS, cls).tearDownClass()
62
Neale Ranns8fe8cc22016-11-01 10:05:08 +000063 def setUp(self):
64 super(TestMPLS, self).setUp()
65
66 # create 2 pg interfaces
Neale Ranns0f26c5a2017-03-01 15:12:11 -080067 self.create_pg_interfaces(range(4))
Neale Ranns8fe8cc22016-11-01 10:05:08 +000068
69 # setup both interfaces
70 # assign them different tables.
71 table_id = 0
Neale Ranns15002542017-09-10 04:39:11 -070072 self.tables = []
73
74 tbl = VppMplsTable(self, 0)
75 tbl.add_vpp_config()
76 self.tables.append(tbl)
Neale Ranns8fe8cc22016-11-01 10:05:08 +000077
78 for i in self.pg_interfaces:
79 i.admin_up()
Neale Ranns15002542017-09-10 04:39:11 -070080
81 if table_id != 0:
82 tbl = VppIpTable(self, table_id)
83 tbl.add_vpp_config()
84 self.tables.append(tbl)
85 tbl = VppIpTable(self, table_id, is_ip6=1)
86 tbl.add_vpp_config()
87 self.tables.append(tbl)
88
Neale Ranns8fe8cc22016-11-01 10:05:08 +000089 i.set_table_ip4(table_id)
90 i.set_table_ip6(table_id)
91 i.config_ip4()
Neale Ranns8fe8cc22016-11-01 10:05:08 +000092 i.resolve_arp()
Neale Rannsad422ed2016-11-02 14:20:04 +000093 i.config_ip6()
Neale Ranns8fe8cc22016-11-01 10:05:08 +000094 i.resolve_ndp()
Neale Rannsad422ed2016-11-02 14:20:04 +000095 i.enable_mpls()
Neale Ranns8fe8cc22016-11-01 10:05:08 +000096 table_id += 1
97
98 def tearDown(self):
Neale Ranns4008ac92017-02-13 23:20:04 -080099 for i in self.pg_interfaces:
100 i.unconfig_ip4()
101 i.unconfig_ip6()
102 i.ip6_disable()
Neale Ranns15002542017-09-10 04:39:11 -0700103 i.set_table_ip4(0)
104 i.set_table_ip6(0)
105 i.disable_mpls()
Neale Ranns4008ac92017-02-13 23:20:04 -0800106 i.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -0700107 super(TestMPLS, self).tearDown()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000108
Neale Rannsad422ed2016-11-02 14:20:04 +0000109 # the default of 64 matches the IP packet TTL default
Klement Sekeradab231a2016-12-21 08:50:14 +0100110 def create_stream_labelled_ip4(
111 self,
112 src_if,
113 mpls_labels,
Klement Sekeradab231a2016-12-21 08:50:14 +0100114 ping=0,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800115 ip_itf=None,
116 dst_ip=None,
Neale Ranns4c7c8e52017-10-21 09:37:55 -0700117 chksum=None,
Neale Ranns31ed7442018-02-23 05:29:09 -0800118 ip_ttl=64,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800119 n=257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100120 self.reset_packet_infos()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000121 pkts = []
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800122 for i in range(0, n):
Klement Sekeradab231a2016-12-21 08:50:14 +0100123 info = self.create_packet_info(src_if, src_if)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000124 payload = self.info_to_payload(info)
Neale Rannsad422ed2016-11-02 14:20:04 +0000125 p = Ether(dst=src_if.local_mac, src=src_if.remote_mac)
126
127 for ii in range(len(mpls_labels)):
Neale Ranns31ed7442018-02-23 05:29:09 -0800128 p = p / MPLS(label=mpls_labels[ii].value,
129 ttl=mpls_labels[ii].ttl,
130 cos=mpls_labels[ii].exp)
Neale Rannscb630ff2016-12-14 13:31:29 +0100131 if not ping:
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800132 if not dst_ip:
Neale Ranns31ed7442018-02-23 05:29:09 -0800133 p = (p / IP(src=src_if.local_ip4,
134 dst=src_if.remote_ip4,
135 ttl=ip_ttl) /
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800136 UDP(sport=1234, dport=1234) /
137 Raw(payload))
138 else:
Neale Ranns31ed7442018-02-23 05:29:09 -0800139 p = (p / IP(src=src_if.local_ip4, dst=dst_ip, ttl=ip_ttl) /
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800140 UDP(sport=1234, dport=1234) /
141 Raw(payload))
Neale Rannscb630ff2016-12-14 13:31:29 +0100142 else:
143 p = (p / IP(src=ip_itf.remote_ip4,
Neale Ranns31ed7442018-02-23 05:29:09 -0800144 dst=ip_itf.local_ip4,
145 ttl=ip_ttl) /
Neale Rannscb630ff2016-12-14 13:31:29 +0100146 ICMP())
147
Neale Ranns4c7c8e52017-10-21 09:37:55 -0700148 if chksum:
149 p[IP].chksum = chksum
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000150 info.data = p.copy()
151 pkts.append(p)
152 return pkts
153
Neale Ranns31ed7442018-02-23 05:29:09 -0800154 def create_stream_ip4(self, src_if, dst_ip, ip_ttl=64, ip_dscp=0):
Klement Sekeradab231a2016-12-21 08:50:14 +0100155 self.reset_packet_infos()
Neale Rannsad422ed2016-11-02 14:20:04 +0000156 pkts = []
157 for i in range(0, 257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100158 info = self.create_packet_info(src_if, src_if)
Neale Rannsad422ed2016-11-02 14:20:04 +0000159 payload = self.info_to_payload(info)
160 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
Neale Ranns31ed7442018-02-23 05:29:09 -0800161 IP(src=src_if.remote_ip4, dst=dst_ip,
162 ttl=ip_ttl, tos=ip_dscp) /
Neale Rannsad422ed2016-11-02 14:20:04 +0000163 UDP(sport=1234, dport=1234) /
164 Raw(payload))
165 info.data = p.copy()
166 pkts.append(p)
167 return pkts
168
Neale Ranns31ed7442018-02-23 05:29:09 -0800169 def create_stream_ip6(self, src_if, dst_ip, ip_ttl=64, ip_dscp=0):
170 self.reset_packet_infos()
171 pkts = []
172 for i in range(0, 257):
173 info = self.create_packet_info(src_if, src_if)
174 payload = self.info_to_payload(info)
175 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
176 IPv6(src=src_if.remote_ip6, dst=dst_ip,
177 hlim=ip_ttl, tc=ip_dscp) /
178 UDP(sport=1234, dport=1234) /
179 Raw(payload))
180 info.data = p.copy()
181 pkts.append(p)
182 return pkts
183
184 def create_stream_labelled_ip6(self, src_if, mpls_labels,
185 hlim=64, dst_ip=None):
Neale Ranns31426c62017-05-24 10:32:58 -0700186 if dst_ip is None:
187 dst_ip = src_if.remote_ip6
Klement Sekeradab231a2016-12-21 08:50:14 +0100188 self.reset_packet_infos()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000189 pkts = []
190 for i in range(0, 257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100191 info = self.create_packet_info(src_if, src_if)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000192 payload = self.info_to_payload(info)
Neale Ranns31ed7442018-02-23 05:29:09 -0800193 p = Ether(dst=src_if.local_mac, src=src_if.remote_mac)
194 for l in mpls_labels:
195 p = p / MPLS(label=l.value, ttl=l.ttl, cos=l.exp)
196
197 p = p / (IPv6(src=src_if.remote_ip6, dst=dst_ip, hlim=hlim) /
198 UDP(sport=1234, dport=1234) /
199 Raw(payload))
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000200 info.data = p.copy()
201 pkts.append(p)
202 return pkts
203
Neale Ranns31ed7442018-02-23 05:29:09 -0800204 def verify_capture_ip4(self, src_if, capture, sent, ping_resp=0,
205 ip_ttl=None, ip_dscp=0):
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000206 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700207 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000208
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000209 self.assertEqual(len(capture), len(sent))
210
211 for i in range(len(capture)):
212 tx = sent[i]
213 rx = capture[i]
214
215 # the rx'd packet has the MPLS label popped
Neale Rannsad422ed2016-11-02 14:20:04 +0000216 eth = rx[Ether]
217 self.assertEqual(eth.type, 0x800)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000218
219 tx_ip = tx[IP]
220 rx_ip = rx[IP]
221
Neale Rannscb630ff2016-12-14 13:31:29 +0100222 if not ping_resp:
223 self.assertEqual(rx_ip.src, tx_ip.src)
224 self.assertEqual(rx_ip.dst, tx_ip.dst)
Neale Ranns31ed7442018-02-23 05:29:09 -0800225 self.assertEqual(rx_ip.tos, ip_dscp)
226 if not ip_ttl:
227 # IP processing post pop has decremented the TTL
228 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
229 else:
230 self.assertEqual(rx_ip.ttl, ip_ttl)
Neale Rannscb630ff2016-12-14 13:31:29 +0100231 else:
232 self.assertEqual(rx_ip.src, tx_ip.dst)
233 self.assertEqual(rx_ip.dst, tx_ip.src)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000234
235 except:
Neale Rannsad422ed2016-11-02 14:20:04 +0000236 raise
237
Neale Rannsad422ed2016-11-02 14:20:04 +0000238 def verify_capture_labelled_ip4(self, src_if, capture, sent,
Neale Ranns31ed7442018-02-23 05:29:09 -0800239 mpls_labels, ip_ttl=None):
Neale Rannsad422ed2016-11-02 14:20:04 +0000240 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700241 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000242
243 self.assertEqual(len(capture), len(sent))
244
245 for i in range(len(capture)):
246 tx = sent[i]
247 rx = capture[i]
248 tx_ip = tx[IP]
249 rx_ip = rx[IP]
250
Neale Ranns31ed7442018-02-23 05:29:09 -0800251 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsad422ed2016-11-02 14:20:04 +0000252
253 self.assertEqual(rx_ip.src, tx_ip.src)
254 self.assertEqual(rx_ip.dst, tx_ip.dst)
Neale Ranns31ed7442018-02-23 05:29:09 -0800255 if not ip_ttl:
256 # IP processing post pop has decremented the TTL
257 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
258 else:
259 self.assertEqual(rx_ip.ttl, ip_ttl)
Neale Rannsad422ed2016-11-02 14:20:04 +0000260
261 except:
262 raise
263
Neale Ranns31ed7442018-02-23 05:29:09 -0800264 def verify_capture_labelled_ip6(self, src_if, capture, sent,
265 mpls_labels, ip_ttl=None):
266 try:
267 capture = verify_filter(capture, sent)
268
269 self.assertEqual(len(capture), len(sent))
270
271 for i in range(len(capture)):
272 tx = sent[i]
273 rx = capture[i]
274 tx_ip = tx[IPv6]
275 rx_ip = rx[IPv6]
276
277 verify_mpls_stack(self, rx, mpls_labels)
278
279 self.assertEqual(rx_ip.src, tx_ip.src)
280 self.assertEqual(rx_ip.dst, tx_ip.dst)
281 if not ip_ttl:
282 # IP processing post pop has decremented the TTL
283 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
284 else:
285 self.assertEqual(rx_ip.hlim, ip_ttl)
286
287 except:
288 raise
289
290 def verify_capture_tunneled_ip4(self, src_if, capture, sent, mpls_labels):
Neale Rannsad422ed2016-11-02 14:20:04 +0000291 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700292 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000293
294 self.assertEqual(len(capture), len(sent))
295
296 for i in range(len(capture)):
297 tx = sent[i]
298 rx = capture[i]
299 tx_ip = tx[IP]
300 rx_ip = rx[IP]
301
Neale Ranns31ed7442018-02-23 05:29:09 -0800302 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsad422ed2016-11-02 14:20:04 +0000303
304 self.assertEqual(rx_ip.src, tx_ip.src)
305 self.assertEqual(rx_ip.dst, tx_ip.dst)
306 # IP processing post pop has decremented the TTL
307 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
308
309 except:
310 raise
311
312 def verify_capture_labelled(self, src_if, capture, sent,
Neale Ranns31ed7442018-02-23 05:29:09 -0800313 mpls_labels):
Neale Rannsad422ed2016-11-02 14:20:04 +0000314 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700315 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000316
317 self.assertEqual(len(capture), len(sent))
318
319 for i in range(len(capture)):
320 rx = capture[i]
Neale Ranns31ed7442018-02-23 05:29:09 -0800321 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsad422ed2016-11-02 14:20:04 +0000322 except:
323 raise
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000324
Neale Ranns31ed7442018-02-23 05:29:09 -0800325 def verify_capture_ip6(self, src_if, capture, sent,
326 ip_hlim=None, ip_dscp=0):
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000327 try:
328 self.assertEqual(len(capture), len(sent))
329
330 for i in range(len(capture)):
331 tx = sent[i]
332 rx = capture[i]
333
334 # the rx'd packet has the MPLS label popped
Neale Rannsad422ed2016-11-02 14:20:04 +0000335 eth = rx[Ether]
336 self.assertEqual(eth.type, 0x86DD)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000337
338 tx_ip = tx[IPv6]
339 rx_ip = rx[IPv6]
340
341 self.assertEqual(rx_ip.src, tx_ip.src)
342 self.assertEqual(rx_ip.dst, tx_ip.dst)
Neale Ranns31ed7442018-02-23 05:29:09 -0800343 self.assertEqual(rx_ip.tc, ip_dscp)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000344 # IP processing post pop has decremented the TTL
Neale Ranns31ed7442018-02-23 05:29:09 -0800345 if not ip_hlim:
346 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
347 else:
348 self.assertEqual(rx_ip.hlim, ip_hlim)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000349
350 except:
Neale Rannsad422ed2016-11-02 14:20:04 +0000351 raise
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000352
Neale Ranns62fe07c2017-10-31 12:28:22 -0700353 def verify_capture_ip6_icmp(self, src_if, capture, sent):
354 try:
355 self.assertEqual(len(capture), len(sent))
356
357 for i in range(len(capture)):
358 tx = sent[i]
359 rx = capture[i]
360
361 # the rx'd packet has the MPLS label popped
362 eth = rx[Ether]
363 self.assertEqual(eth.type, 0x86DD)
364
365 tx_ip = tx[IPv6]
366 rx_ip = rx[IPv6]
367
368 self.assertEqual(rx_ip.dst, tx_ip.src)
369 # ICMP sourced from the interface's address
370 self.assertEqual(rx_ip.src, src_if.local_ip6)
371 # hop-limit reset to 255 for IMCP packet
Ole Troan282093f2018-09-19 12:38:51 +0200372 self.assertEqual(rx_ip.hlim, 255)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700373
374 icmp = rx[ICMPv6TimeExceeded]
375
376 except:
377 raise
378
Neale Rannsad422ed2016-11-02 14:20:04 +0000379 def test_swap(self):
380 """ MPLS label swap tests """
381
382 #
383 # A simple MPLS xconnect - eos label in label out
384 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800385 route_32_eos = VppMplsRoute(self, 32, 1,
386 [VppRoutePath(self.pg0.remote_ip4,
387 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800388 labels=[VppMplsLabel(33)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000389 route_32_eos.add_vpp_config()
390
Neale Ranns775f73c2018-12-20 03:01:49 -0800391 self.assertTrue(
392 find_mpls_route(self, 0, 32, 1,
393 [VppRoutePath(self.pg0.remote_ip4,
394 self.pg0.sw_if_index,
395 labels=[VppMplsLabel(33)])]))
396
Neale Rannsad422ed2016-11-02 14:20:04 +0000397 #
398 # a stream that matches the route for 10.0.0.1
399 # PG0 is in the default table
400 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800401 tx = self.create_stream_labelled_ip4(self.pg0,
402 [VppMplsLabel(32, ttl=32, exp=1)])
403 rx = self.send_and_expect(self.pg0, tx, self.pg0)
404 self.verify_capture_labelled(self.pg0, rx, tx,
405 [VppMplsLabel(33, ttl=31, exp=1)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000406
Neale Ranns008dbe12018-09-07 09:32:36 -0700407 self.assertEqual(route_32_eos.get_stats_to()['packets'], 257)
408
Neale Rannsad422ed2016-11-02 14:20:04 +0000409 #
410 # A simple MPLS xconnect - non-eos label in label out
411 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800412 route_32_neos = VppMplsRoute(self, 32, 0,
413 [VppRoutePath(self.pg0.remote_ip4,
414 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800415 labels=[VppMplsLabel(33)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000416 route_32_neos.add_vpp_config()
417
418 #
419 # a stream that matches the route for 10.0.0.1
420 # PG0 is in the default table
421 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800422 tx = self.create_stream_labelled_ip4(self.pg0,
423 [VppMplsLabel(32, ttl=21, exp=7),
424 VppMplsLabel(99)])
425 rx = self.send_and_expect(self.pg0, tx, self.pg0)
426 self.verify_capture_labelled(self.pg0, rx, tx,
427 [VppMplsLabel(33, ttl=20, exp=7),
428 VppMplsLabel(99)])
Neale Ranns008dbe12018-09-07 09:32:36 -0700429 self.assertEqual(route_32_neos.get_stats_to()['packets'], 257)
Neale Rannsad422ed2016-11-02 14:20:04 +0000430
Neale Ranns31ed7442018-02-23 05:29:09 -0800431 #
432 # A simple MPLS xconnect - non-eos label in label out, uniform mode
433 #
434 route_42_neos = VppMplsRoute(
435 self, 42, 0,
436 [VppRoutePath(self.pg0.remote_ip4,
437 self.pg0.sw_if_index,
438 labels=[VppMplsLabel(43, MplsLspMode.UNIFORM)])])
439 route_42_neos.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000440
Neale Ranns31ed7442018-02-23 05:29:09 -0800441 tx = self.create_stream_labelled_ip4(self.pg0,
442 [VppMplsLabel(42, ttl=21, exp=7),
443 VppMplsLabel(99)])
444 rx = self.send_and_expect(self.pg0, tx, self.pg0)
445 self.verify_capture_labelled(self.pg0, rx, tx,
446 [VppMplsLabel(43, ttl=20, exp=7),
447 VppMplsLabel(99)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000448
449 #
450 # An MPLS xconnect - EOS label in IP out
451 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800452 route_33_eos = VppMplsRoute(self, 33, 1,
453 [VppRoutePath(self.pg0.remote_ip4,
454 self.pg0.sw_if_index,
455 labels=[])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000456 route_33_eos.add_vpp_config()
457
Neale Ranns31ed7442018-02-23 05:29:09 -0800458 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(33)])
459 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Rannsad422ed2016-11-02 14:20:04 +0000460 self.verify_capture_ip4(self.pg0, rx, tx)
461
462 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700463 # disposed packets have an invalid IPv4 checksum
Neale Ranns62fe07c2017-10-31 12:28:22 -0700464 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800465 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(33)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700466 dst_ip=self.pg0.remote_ip4,
467 n=65,
468 chksum=1)
469 self.send_and_assert_no_replies(self.pg0, tx, "Invalid Checksum")
470
471 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800472 # An MPLS xconnect - EOS label in IP out, uniform mode
473 #
474 route_3333_eos = VppMplsRoute(
475 self, 3333, 1,
476 [VppRoutePath(self.pg0.remote_ip4,
477 self.pg0.sw_if_index,
478 labels=[VppMplsLabel(3, MplsLspMode.UNIFORM)])])
479 route_3333_eos.add_vpp_config()
480
481 tx = self.create_stream_labelled_ip4(
482 self.pg0,
483 [VppMplsLabel(3333, ttl=55, exp=3)])
484 rx = self.send_and_expect(self.pg0, tx, self.pg0)
485 self.verify_capture_ip4(self.pg0, rx, tx, ip_ttl=54, ip_dscp=0x60)
486 tx = self.create_stream_labelled_ip4(
487 self.pg0,
488 [VppMplsLabel(3333, ttl=66, exp=4)])
489 rx = self.send_and_expect(self.pg0, tx, self.pg0)
490 self.verify_capture_ip4(self.pg0, rx, tx, ip_ttl=65, ip_dscp=0x80)
491
492 #
Neale Ranns62fe07c2017-10-31 12:28:22 -0700493 # An MPLS xconnect - EOS label in IPv6 out
494 #
495 route_333_eos = VppMplsRoute(
496 self, 333, 1,
497 [VppRoutePath(self.pg0.remote_ip6,
498 self.pg0.sw_if_index,
499 labels=[],
500 proto=DpoProto.DPO_PROTO_IP6)])
501 route_333_eos.add_vpp_config()
502
Neale Ranns31ed7442018-02-23 05:29:09 -0800503 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(333)])
504 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700505 self.verify_capture_ip6(self.pg0, rx, tx)
506
507 #
508 # disposed packets have an TTL expired
509 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800510 tx = self.create_stream_labelled_ip6(self.pg0,
511 [VppMplsLabel(333, ttl=64)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700512 dst_ip=self.pg1.remote_ip6,
513 hlim=1)
Neale Ranns31ed7442018-02-23 05:29:09 -0800514 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700515 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
516
517 #
518 # An MPLS xconnect - EOS label in IPv6 out w imp-null
519 #
520 route_334_eos = VppMplsRoute(
521 self, 334, 1,
522 [VppRoutePath(self.pg0.remote_ip6,
523 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800524 labels=[VppMplsLabel(3)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700525 proto=DpoProto.DPO_PROTO_IP6)])
526 route_334_eos.add_vpp_config()
527
Neale Ranns31ed7442018-02-23 05:29:09 -0800528 tx = self.create_stream_labelled_ip6(self.pg0,
529 [VppMplsLabel(334, ttl=64)])
530 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700531 self.verify_capture_ip6(self.pg0, rx, tx)
532
533 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800534 # An MPLS xconnect - EOS label in IPv6 out w imp-null in uniform mode
535 #
536 route_335_eos = VppMplsRoute(
537 self, 335, 1,
538 [VppRoutePath(self.pg0.remote_ip6,
539 self.pg0.sw_if_index,
540 labels=[VppMplsLabel(3, MplsLspMode.UNIFORM)],
541 proto=DpoProto.DPO_PROTO_IP6)])
542 route_335_eos.add_vpp_config()
543
544 tx = self.create_stream_labelled_ip6(
545 self.pg0,
546 [VppMplsLabel(335, ttl=27, exp=4)])
547 rx = self.send_and_expect(self.pg0, tx, self.pg0)
548 self.verify_capture_ip6(self.pg0, rx, tx, ip_hlim=26, ip_dscp=0x80)
549
550 #
Neale Ranns62fe07c2017-10-31 12:28:22 -0700551 # disposed packets have an TTL expired
552 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800553 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(334)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700554 dst_ip=self.pg1.remote_ip6,
555 hlim=0)
Neale Ranns31ed7442018-02-23 05:29:09 -0800556 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700557 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
558
559 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000560 # An MPLS xconnect - non-EOS label in IP out - an invalid configuration
561 # so this traffic should be dropped.
562 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800563 route_33_neos = VppMplsRoute(self, 33, 0,
564 [VppRoutePath(self.pg0.remote_ip4,
565 self.pg0.sw_if_index,
566 labels=[])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000567 route_33_neos.add_vpp_config()
568
Neale Ranns31ed7442018-02-23 05:29:09 -0800569 tx = self.create_stream_labelled_ip4(self.pg0,
570 [VppMplsLabel(33),
571 VppMplsLabel(99)])
572 self.send_and_assert_no_replies(
573 self.pg0, tx,
574 "MPLS non-EOS packets popped and forwarded")
Neale Rannsad422ed2016-11-02 14:20:04 +0000575
576 #
577 # A recursive EOS x-connect, which resolves through another x-connect
Neale Ranns31ed7442018-02-23 05:29:09 -0800578 # in pipe mode
Neale Rannsad422ed2016-11-02 14:20:04 +0000579 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800580 route_34_eos = VppMplsRoute(self, 34, 1,
581 [VppRoutePath("0.0.0.0",
582 0xffffffff,
583 nh_via_label=32,
Neale Ranns31ed7442018-02-23 05:29:09 -0800584 labels=[VppMplsLabel(44),
585 VppMplsLabel(45)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000586 route_34_eos.add_vpp_config()
587
Neale Ranns31ed7442018-02-23 05:29:09 -0800588 tx = self.create_stream_labelled_ip4(self.pg0,
589 [VppMplsLabel(34, ttl=3)])
590 rx = self.send_and_expect(self.pg0, tx, self.pg0)
591 self.verify_capture_labelled(self.pg0, rx, tx,
592 [VppMplsLabel(33),
593 VppMplsLabel(44),
594 VppMplsLabel(45, ttl=2)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000595
Neale Ranns008dbe12018-09-07 09:32:36 -0700596 self.assertEqual(route_34_eos.get_stats_to()['packets'], 257)
597 self.assertEqual(route_32_neos.get_stats_via()['packets'], 257)
598
Neale Ranns31ed7442018-02-23 05:29:09 -0800599 #
600 # A recursive EOS x-connect, which resolves through another x-connect
601 # in uniform mode
602 #
603 route_35_eos = VppMplsRoute(
604 self, 35, 1,
605 [VppRoutePath("0.0.0.0",
606 0xffffffff,
607 nh_via_label=42,
608 labels=[VppMplsLabel(44)])])
609 route_35_eos.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000610
Neale Ranns31ed7442018-02-23 05:29:09 -0800611 tx = self.create_stream_labelled_ip4(self.pg0,
612 [VppMplsLabel(35, ttl=3)])
613 rx = self.send_and_expect(self.pg0, tx, self.pg0)
614 self.verify_capture_labelled(self.pg0, rx, tx,
615 [VppMplsLabel(43, ttl=2),
616 VppMplsLabel(44, ttl=2)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000617
618 #
Matej Klottondeb69842016-12-09 15:05:46 +0100619 # A recursive non-EOS x-connect, which resolves through another
620 # x-connect
Neale Rannsad422ed2016-11-02 14:20:04 +0000621 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800622 route_34_neos = VppMplsRoute(self, 34, 0,
623 [VppRoutePath("0.0.0.0",
624 0xffffffff,
625 nh_via_label=32,
Neale Ranns31ed7442018-02-23 05:29:09 -0800626 labels=[VppMplsLabel(44),
627 VppMplsLabel(46)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000628 route_34_neos.add_vpp_config()
629
Neale Ranns31ed7442018-02-23 05:29:09 -0800630 tx = self.create_stream_labelled_ip4(self.pg0,
631 [VppMplsLabel(34, ttl=45),
632 VppMplsLabel(99)])
633 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Matej Klottondeb69842016-12-09 15:05:46 +0100634 # it's the 2nd (counting from 0) label in the stack that is swapped
Neale Ranns31ed7442018-02-23 05:29:09 -0800635 self.verify_capture_labelled(self.pg0, rx, tx,
636 [VppMplsLabel(33),
637 VppMplsLabel(44),
638 VppMplsLabel(46, ttl=44),
639 VppMplsLabel(99)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000640
641 #
Matej Klottondeb69842016-12-09 15:05:46 +0100642 # an recursive IP route that resolves through the recursive non-eos
643 # x-connect
Neale Rannsad422ed2016-11-02 14:20:04 +0000644 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800645 ip_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
646 [VppRoutePath("0.0.0.0",
647 0xffffffff,
648 nh_via_label=34,
Neale Ranns31ed7442018-02-23 05:29:09 -0800649 labels=[VppMplsLabel(55)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000650 ip_10_0_0_1.add_vpp_config()
651
Neale Rannsad422ed2016-11-02 14:20:04 +0000652 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800653 rx = self.send_and_expect(self.pg0, tx, self.pg0)
654 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
655 [VppMplsLabel(33),
656 VppMplsLabel(44),
657 VppMplsLabel(46),
658 VppMplsLabel(55)])
Neale Ranns008dbe12018-09-07 09:32:36 -0700659 self.assertEqual(ip_10_0_0_1.get_stats_to()['packets'], 257)
Neale Rannsad422ed2016-11-02 14:20:04 +0000660
661 ip_10_0_0_1.remove_vpp_config()
662 route_34_neos.remove_vpp_config()
663 route_34_eos.remove_vpp_config()
664 route_33_neos.remove_vpp_config()
665 route_33_eos.remove_vpp_config()
666 route_32_neos.remove_vpp_config()
667 route_32_eos.remove_vpp_config()
668
669 def test_bind(self):
670 """ MPLS Local Label Binding test """
671
672 #
673 # Add a non-recursive route with a single out label
674 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800675 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
676 [VppRoutePath(self.pg0.remote_ip4,
677 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800678 labels=[VppMplsLabel(45)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000679 route_10_0_0_1.add_vpp_config()
680
681 # bind a local label to the route
Neale Ranns5a8123b2017-01-26 01:18:23 -0800682 binding = VppMplsIpBind(self, 44, "10.0.0.1", 32)
Neale Rannsad422ed2016-11-02 14:20:04 +0000683 binding.add_vpp_config()
684
685 # non-EOS stream
Neale Ranns31ed7442018-02-23 05:29:09 -0800686 tx = self.create_stream_labelled_ip4(self.pg0,
687 [VppMplsLabel(44),
688 VppMplsLabel(99)])
689 rx = self.send_and_expect(self.pg0, tx, self.pg0)
690 self.verify_capture_labelled(self.pg0, rx, tx,
691 [VppMplsLabel(45, ttl=63),
692 VppMplsLabel(99)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000693
694 # EOS stream
Neale Ranns31ed7442018-02-23 05:29:09 -0800695 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(44)])
696 rx = self.send_and_expect(self.pg0, tx, self.pg0)
697 self.verify_capture_labelled(self.pg0, rx, tx,
698 [VppMplsLabel(45, ttl=63)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000699
700 # IP stream
Neale Rannsad422ed2016-11-02 14:20:04 +0000701 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800702 rx = self.send_and_expect(self.pg0, tx, self.pg0)
703 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [VppMplsLabel(45)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000704
705 #
706 # cleanup
707 #
708 binding.remove_vpp_config()
709 route_10_0_0_1.remove_vpp_config()
710
711 def test_imposition(self):
712 """ MPLS label imposition test """
713
714 #
715 # Add a non-recursive route with a single out label
716 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800717 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
718 [VppRoutePath(self.pg0.remote_ip4,
719 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800720 labels=[VppMplsLabel(32)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000721 route_10_0_0_1.add_vpp_config()
722
723 #
724 # a stream that matches the route for 10.0.0.1
725 # PG0 is in the default table
726 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000727 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800728 rx = self.send_and_expect(self.pg0, tx, self.pg0)
729 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [VppMplsLabel(32)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000730
731 #
732 # Add a non-recursive route with a 3 out labels
733 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800734 route_10_0_0_2 = VppIpRoute(self, "10.0.0.2", 32,
735 [VppRoutePath(self.pg0.remote_ip4,
736 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800737 labels=[VppMplsLabel(32),
738 VppMplsLabel(33),
739 VppMplsLabel(34)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000740 route_10_0_0_2.add_vpp_config()
741
Neale Ranns31ed7442018-02-23 05:29:09 -0800742 tx = self.create_stream_ip4(self.pg0, "10.0.0.2",
743 ip_ttl=44, ip_dscp=0xff)
744 rx = self.send_and_expect(self.pg0, tx, self.pg0)
745 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
746 [VppMplsLabel(32),
747 VppMplsLabel(33),
748 VppMplsLabel(34)],
749 ip_ttl=43)
Neale Rannsad422ed2016-11-02 14:20:04 +0000750
Neale Ranns31ed7442018-02-23 05:29:09 -0800751 #
752 # Add a non-recursive route with a single out label in uniform mode
753 #
754 route_10_0_0_3 = VppIpRoute(
755 self, "10.0.0.3", 32,
756 [VppRoutePath(self.pg0.remote_ip4,
757 self.pg0.sw_if_index,
758 labels=[VppMplsLabel(32,
759 mode=MplsLspMode.UNIFORM)])])
760 route_10_0_0_3.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000761
Neale Ranns31ed7442018-02-23 05:29:09 -0800762 tx = self.create_stream_ip4(self.pg0, "10.0.0.3",
763 ip_ttl=54, ip_dscp=0xbe)
764 rx = self.send_and_expect(self.pg0, tx, self.pg0)
765 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
766 [VppMplsLabel(32, ttl=53, exp=5)])
767
768 #
769 # Add a IPv6 non-recursive route with a single out label in
770 # uniform mode
771 #
772 route_2001_3 = VppIpRoute(
773 self, "2001::3", 128,
774 [VppRoutePath(self.pg0.remote_ip6,
775 self.pg0.sw_if_index,
776 proto=DpoProto.DPO_PROTO_IP6,
777 labels=[VppMplsLabel(32,
778 mode=MplsLspMode.UNIFORM)])],
779 is_ip6=1)
780 route_2001_3.add_vpp_config()
781
782 tx = self.create_stream_ip6(self.pg0, "2001::3",
783 ip_ttl=54, ip_dscp=0xbe)
784 rx = self.send_and_expect(self.pg0, tx, self.pg0)
785 self.verify_capture_labelled_ip6(self.pg0, rx, tx,
786 [VppMplsLabel(32, ttl=53, exp=5)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000787
788 #
Matej Klottondeb69842016-12-09 15:05:46 +0100789 # add a recursive path, with output label, via the 1 label route
Neale Rannsad422ed2016-11-02 14:20:04 +0000790 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800791 route_11_0_0_1 = VppIpRoute(self, "11.0.0.1", 32,
792 [VppRoutePath("10.0.0.1",
793 0xffffffff,
Neale Ranns31ed7442018-02-23 05:29:09 -0800794 labels=[VppMplsLabel(44)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000795 route_11_0_0_1.add_vpp_config()
796
797 #
798 # a stream that matches the route for 11.0.0.1, should pick up
799 # the label stack for 11.0.0.1 and 10.0.0.1
800 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000801 tx = self.create_stream_ip4(self.pg0, "11.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800802 rx = self.send_and_expect(self.pg0, tx, self.pg0)
803 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
804 [VppMplsLabel(32),
805 VppMplsLabel(44)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000806
Neale Ranns008dbe12018-09-07 09:32:36 -0700807 self.assertEqual(route_11_0_0_1.get_stats_to()['packets'], 257)
808
Neale Rannsad422ed2016-11-02 14:20:04 +0000809 #
810 # add a recursive path, with 2 labels, via the 3 label route
811 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800812 route_11_0_0_2 = VppIpRoute(self, "11.0.0.2", 32,
813 [VppRoutePath("10.0.0.2",
814 0xffffffff,
Neale Ranns31ed7442018-02-23 05:29:09 -0800815 labels=[VppMplsLabel(44),
816 VppMplsLabel(45)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000817 route_11_0_0_2.add_vpp_config()
818
819 #
820 # a stream that matches the route for 11.0.0.1, should pick up
821 # the label stack for 11.0.0.1 and 10.0.0.1
822 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000823 tx = self.create_stream_ip4(self.pg0, "11.0.0.2")
Neale Ranns31ed7442018-02-23 05:29:09 -0800824 rx = self.send_and_expect(self.pg0, tx, self.pg0)
825 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
826 [VppMplsLabel(32),
827 VppMplsLabel(33),
828 VppMplsLabel(34),
829 VppMplsLabel(44),
830 VppMplsLabel(45)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000831
Neale Ranns008dbe12018-09-07 09:32:36 -0700832 self.assertEqual(route_11_0_0_2.get_stats_to()['packets'], 257)
833
834 rx = self.send_and_expect(self.pg0, tx, self.pg0)
835 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
836 [VppMplsLabel(32),
837 VppMplsLabel(33),
838 VppMplsLabel(34),
839 VppMplsLabel(44),
840 VppMplsLabel(45)])
841
842 self.assertEqual(route_11_0_0_2.get_stats_to()['packets'], 514)
843
Neale Rannsad422ed2016-11-02 14:20:04 +0000844 #
845 # cleanup
846 #
847 route_11_0_0_2.remove_vpp_config()
848 route_11_0_0_1.remove_vpp_config()
849 route_10_0_0_2.remove_vpp_config()
850 route_10_0_0_1.remove_vpp_config()
851
Neale Ranns31ed7442018-02-23 05:29:09 -0800852 def test_tunnel_pipe(self):
853 """ MPLS Tunnel Tests - Pipe """
Neale Rannsad422ed2016-11-02 14:20:04 +0000854
855 #
856 # Create a tunnel with a single out label
857 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800858 mpls_tun = VppMPLSTunnelInterface(
859 self,
860 [VppRoutePath(self.pg0.remote_ip4,
861 self.pg0.sw_if_index,
862 labels=[VppMplsLabel(44),
863 VppMplsLabel(46)])])
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800864 mpls_tun.add_vpp_config()
865 mpls_tun.admin_up()
Neale Rannsad422ed2016-11-02 14:20:04 +0000866
867 #
868 # add an unlabelled route through the new tunnel
869 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800870 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
871 [VppRoutePath("0.0.0.0",
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800872 mpls_tun._sw_if_index)])
Neale Ranns5a8123b2017-01-26 01:18:23 -0800873 route_10_0_0_3.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000874
875 self.vapi.cli("clear trace")
876 tx = self.create_stream_ip4(self.pg0, "10.0.0.3")
877 self.pg0.add_stream(tx)
878
879 self.pg_enable_capture(self.pg_interfaces)
880 self.pg_start()
881
882 rx = self.pg0.get_capture()
Neale Ranns31ed7442018-02-23 05:29:09 -0800883 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
884 [VppMplsLabel(44),
885 VppMplsLabel(46)])
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000886
Neale Ranns8c4611b2017-05-23 03:43:47 -0700887 #
888 # add a labelled route through the new tunnel
889 #
890 route_10_0_0_4 = VppIpRoute(self, "10.0.0.4", 32,
891 [VppRoutePath("0.0.0.0",
892 mpls_tun._sw_if_index,
893 labels=[33])])
894 route_10_0_0_4.add_vpp_config()
895
896 self.vapi.cli("clear trace")
897 tx = self.create_stream_ip4(self.pg0, "10.0.0.4")
898 self.pg0.add_stream(tx)
899
900 self.pg_enable_capture(self.pg_interfaces)
901 self.pg_start()
902
903 rx = self.pg0.get_capture()
Neale Ranns31ed7442018-02-23 05:29:09 -0800904 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
905 [VppMplsLabel(44),
906 VppMplsLabel(46),
907 VppMplsLabel(33, ttl=255)])
908
909 def test_tunnel_uniform(self):
910 """ MPLS Tunnel Tests - Uniform """
911
912 #
913 # Create a tunnel with a single out label
914 # The label stack is specified here from outer to inner
915 #
916 mpls_tun = VppMPLSTunnelInterface(
917 self,
918 [VppRoutePath(self.pg0.remote_ip4,
919 self.pg0.sw_if_index,
920 labels=[VppMplsLabel(44, ttl=32),
921 VppMplsLabel(46, MplsLspMode.UNIFORM)])])
922 mpls_tun.add_vpp_config()
923 mpls_tun.admin_up()
924
925 #
926 # add an unlabelled route through the new tunnel
927 #
928 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
929 [VppRoutePath("0.0.0.0",
930 mpls_tun._sw_if_index)])
931 route_10_0_0_3.add_vpp_config()
932
933 self.vapi.cli("clear trace")
934 tx = self.create_stream_ip4(self.pg0, "10.0.0.3", ip_ttl=24)
935 self.pg0.add_stream(tx)
936
937 self.pg_enable_capture(self.pg_interfaces)
938 self.pg_start()
939
940 rx = self.pg0.get_capture()
941 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
942 [VppMplsLabel(44, ttl=32),
943 VppMplsLabel(46, ttl=23)])
944
945 #
946 # add a labelled route through the new tunnel
947 #
948 route_10_0_0_4 = VppIpRoute(
949 self, "10.0.0.4", 32,
950 [VppRoutePath("0.0.0.0",
951 mpls_tun._sw_if_index,
952 labels=[VppMplsLabel(33, ttl=47)])])
953 route_10_0_0_4.add_vpp_config()
954
955 self.vapi.cli("clear trace")
956 tx = self.create_stream_ip4(self.pg0, "10.0.0.4")
957 self.pg0.add_stream(tx)
958
959 self.pg_enable_capture(self.pg_interfaces)
960 self.pg_start()
961
962 rx = self.pg0.get_capture()
963 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
964 [VppMplsLabel(44, ttl=32),
965 VppMplsLabel(46, ttl=47),
966 VppMplsLabel(33, ttl=47)])
Neale Ranns8c4611b2017-05-23 03:43:47 -0700967
Neale Rannsf5fa5ae2018-09-26 05:07:25 -0700968 def test_mpls_tunnel_many(self):
969 """ Multiple Tunnels """
970
971 for ii in range(10):
972 mpls_tun = VppMPLSTunnelInterface(
973 self,
974 [VppRoutePath(self.pg0.remote_ip4,
975 self.pg0.sw_if_index,
976 labels=[VppMplsLabel(44, ttl=32),
977 VppMplsLabel(46, MplsLspMode.UNIFORM)])])
978 mpls_tun.add_vpp_config()
979 mpls_tun.admin_up()
980
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000981 def test_v4_exp_null(self):
982 """ MPLS V4 Explicit NULL test """
983
984 #
985 # The first test case has an MPLS TTL of 0
986 # all packet should be dropped
987 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800988 tx = self.create_stream_labelled_ip4(self.pg0,
989 [VppMplsLabel(0, ttl=0)])
990 self.send_and_assert_no_replies(self.pg0, tx,
991 "MPLS TTL=0 packets forwarded")
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000992
993 #
994 # a stream with a non-zero MPLS TTL
995 # PG0 is in the default table
996 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800997 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(0)])
998 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000999 self.verify_capture_ip4(self.pg0, rx, tx)
1000
1001 #
1002 # a stream with a non-zero MPLS TTL
1003 # PG1 is in table 1
1004 # we are ensuring the post-pop lookup occurs in the VRF table
1005 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001006 tx = self.create_stream_labelled_ip4(self.pg1, [VppMplsLabel(0)])
1007 rx = self.send_and_expect(self.pg1, tx, self.pg1)
1008 self.verify_capture_ip4(self.pg1, rx, tx)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001009
1010 def test_v6_exp_null(self):
1011 """ MPLS V6 Explicit NULL test """
1012
1013 #
1014 # a stream with a non-zero MPLS TTL
1015 # PG0 is in the default table
1016 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001017 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(2)])
1018 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001019 self.verify_capture_ip6(self.pg0, rx, tx)
1020
1021 #
1022 # a stream with a non-zero MPLS TTL
1023 # PG1 is in table 1
1024 # we are ensuring the post-pop lookup occurs in the VRF table
1025 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001026 tx = self.create_stream_labelled_ip6(self.pg1, [VppMplsLabel(2)])
1027 rx = self.send_and_expect(self.pg1, tx, self.pg1)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001028 self.verify_capture_ip6(self.pg0, rx, tx)
1029
Neale Rannscb630ff2016-12-14 13:31:29 +01001030 def test_deag(self):
1031 """ MPLS Deagg """
1032
1033 #
1034 # A de-agg route - next-hop lookup in default table
1035 #
Neale Ranns5a8123b2017-01-26 01:18:23 -08001036 route_34_eos = VppMplsRoute(self, 34, 1,
1037 [VppRoutePath("0.0.0.0",
1038 0xffffffff,
1039 nh_table_id=0)])
Neale Rannscb630ff2016-12-14 13:31:29 +01001040 route_34_eos.add_vpp_config()
1041
1042 #
1043 # ping an interface in the default table
1044 # PG0 is in the default table
1045 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001046 tx = self.create_stream_labelled_ip4(self.pg0,
1047 [VppMplsLabel(34)],
1048 ping=1,
Neale Rannscb630ff2016-12-14 13:31:29 +01001049 ip_itf=self.pg0)
Neale Ranns31ed7442018-02-23 05:29:09 -08001050 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Rannscb630ff2016-12-14 13:31:29 +01001051 self.verify_capture_ip4(self.pg0, rx, tx, ping_resp=1)
1052
1053 #
1054 # A de-agg route - next-hop lookup in non-default table
1055 #
Neale Ranns5a8123b2017-01-26 01:18:23 -08001056 route_35_eos = VppMplsRoute(self, 35, 1,
1057 [VppRoutePath("0.0.0.0",
1058 0xffffffff,
1059 nh_table_id=1)])
Neale Rannscb630ff2016-12-14 13:31:29 +01001060 route_35_eos.add_vpp_config()
1061
1062 #
1063 # ping an interface in the non-default table
1064 # PG0 is in the default table. packet arrive labelled in the
1065 # default table and egress unlabelled in the non-default
1066 #
Klement Sekeradab231a2016-12-21 08:50:14 +01001067 tx = self.create_stream_labelled_ip4(
Neale Ranns31ed7442018-02-23 05:29:09 -08001068 self.pg0, [VppMplsLabel(35)], ping=1, ip_itf=self.pg1)
1069 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Rannscb630ff2016-12-14 13:31:29 +01001070 self.verify_capture_ip4(self.pg1, rx, tx, ping_resp=1)
1071
Neale Ranns6af1c042017-05-26 03:48:53 -07001072 #
1073 # Double pop
1074 #
1075 route_36_neos = VppMplsRoute(self, 36, 0,
1076 [VppRoutePath("0.0.0.0",
1077 0xffffffff)])
1078 route_36_neos.add_vpp_config()
1079
Neale Ranns31ed7442018-02-23 05:29:09 -08001080 tx = self.create_stream_labelled_ip4(self.pg0,
1081 [VppMplsLabel(36),
1082 VppMplsLabel(35)],
Neale Ranns6af1c042017-05-26 03:48:53 -07001083 ping=1, ip_itf=self.pg1)
Neale Ranns31ed7442018-02-23 05:29:09 -08001084 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns6af1c042017-05-26 03:48:53 -07001085 self.verify_capture_ip4(self.pg1, rx, tx, ping_resp=1)
1086
1087 route_36_neos.remove_vpp_config()
Neale Rannscb630ff2016-12-14 13:31:29 +01001088 route_35_eos.remove_vpp_config()
1089 route_34_eos.remove_vpp_config()
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001090
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001091 def test_interface_rx(self):
1092 """ MPLS Interface Receive """
1093
1094 #
1095 # Add a non-recursive route that will forward the traffic
1096 # post-interface-rx
1097 #
1098 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
1099 table_id=1,
1100 paths=[VppRoutePath(self.pg1.remote_ip4,
1101 self.pg1.sw_if_index)])
1102 route_10_0_0_1.add_vpp_config()
1103
1104 #
1105 # An interface receive label that maps traffic to RX on interface
1106 # pg1
1107 # by injecting the packet in on pg0, which is in table 0
1108 # doing an interface-rx on pg1 and matching a route in table 1
1109 # if the packet egresses, then we must have swapped to pg1
1110 # so as to have matched the route in table 1
1111 #
1112 route_34_eos = VppMplsRoute(self, 34, 1,
1113 [VppRoutePath("0.0.0.0",
1114 self.pg1.sw_if_index,
1115 is_interface_rx=1)])
1116 route_34_eos.add_vpp_config()
1117
1118 #
1119 # ping an interface in the default table
1120 # PG0 is in the default table
1121 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001122 tx = self.create_stream_labelled_ip4(self.pg0,
1123 [VppMplsLabel(34)],
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001124 dst_ip="10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -08001125 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001126 self.verify_capture_ip4(self.pg1, rx, tx)
1127
1128 def test_mcast_mid_point(self):
1129 """ MPLS Multicast Mid Point """
1130
1131 #
1132 # Add a non-recursive route that will forward the traffic
1133 # post-interface-rx
1134 #
1135 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
1136 table_id=1,
1137 paths=[VppRoutePath(self.pg1.remote_ip4,
1138 self.pg1.sw_if_index)])
1139 route_10_0_0_1.add_vpp_config()
1140
1141 #
1142 # Add a mcast entry that replicate to pg2 and pg3
1143 # and replicate to a interface-rx (like a bud node would)
1144 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001145 route_3400_eos = VppMplsRoute(
1146 self, 3400, 1,
1147 [VppRoutePath(self.pg2.remote_ip4,
1148 self.pg2.sw_if_index,
1149 labels=[VppMplsLabel(3401)]),
1150 VppRoutePath(self.pg3.remote_ip4,
1151 self.pg3.sw_if_index,
1152 labels=[VppMplsLabel(3402)]),
1153 VppRoutePath("0.0.0.0",
1154 self.pg1.sw_if_index,
1155 is_interface_rx=1)],
1156 is_multicast=1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001157 route_3400_eos.add_vpp_config()
1158
1159 #
1160 # ping an interface in the default table
1161 # PG0 is in the default table
1162 #
1163 self.vapi.cli("clear trace")
Neale Ranns31ed7442018-02-23 05:29:09 -08001164 tx = self.create_stream_labelled_ip4(self.pg0,
1165 [VppMplsLabel(3400, ttl=64)],
1166 n=257,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001167 dst_ip="10.0.0.1")
1168 self.pg0.add_stream(tx)
1169
1170 self.pg_enable_capture(self.pg_interfaces)
1171 self.pg_start()
1172
1173 rx = self.pg1.get_capture(257)
1174 self.verify_capture_ip4(self.pg1, rx, tx)
1175
1176 rx = self.pg2.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001177 self.verify_capture_labelled(self.pg2, rx, tx,
1178 [VppMplsLabel(3401, ttl=63)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001179 rx = self.pg3.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001180 self.verify_capture_labelled(self.pg3, rx, tx,
1181 [VppMplsLabel(3402, ttl=63)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001182
1183 def test_mcast_head(self):
1184 """ MPLS Multicast Head-end """
1185
1186 #
1187 # Create a multicast tunnel with two replications
1188 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001189 mpls_tun = VppMPLSTunnelInterface(
1190 self,
1191 [VppRoutePath(self.pg2.remote_ip4,
1192 self.pg2.sw_if_index,
1193 labels=[VppMplsLabel(42)]),
1194 VppRoutePath(self.pg3.remote_ip4,
1195 self.pg3.sw_if_index,
1196 labels=[VppMplsLabel(43)])],
1197 is_multicast=1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001198 mpls_tun.add_vpp_config()
1199 mpls_tun.admin_up()
1200
1201 #
1202 # add an unlabelled route through the new tunnel
1203 #
1204 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
1205 [VppRoutePath("0.0.0.0",
1206 mpls_tun._sw_if_index)])
1207 route_10_0_0_3.add_vpp_config()
1208
1209 self.vapi.cli("clear trace")
1210 tx = self.create_stream_ip4(self.pg0, "10.0.0.3")
1211 self.pg0.add_stream(tx)
1212
1213 self.pg_enable_capture(self.pg_interfaces)
1214 self.pg_start()
1215
1216 rx = self.pg2.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001217 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(42)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001218 rx = self.pg3.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001219 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(43)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001220
1221 #
1222 # An an IP multicast route via the tunnel
1223 # A (*,G).
1224 # one accepting interface, pg0, 1 forwarding interface via the tunnel
1225 #
1226 route_232_1_1_1 = VppIpMRoute(
1227 self,
1228 "0.0.0.0",
1229 "232.1.1.1", 32,
1230 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
1231 [VppMRoutePath(self.pg0.sw_if_index,
1232 MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
1233 VppMRoutePath(mpls_tun._sw_if_index,
1234 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
1235 route_232_1_1_1.add_vpp_config()
1236
1237 self.vapi.cli("clear trace")
1238 tx = self.create_stream_ip4(self.pg0, "232.1.1.1")
1239 self.pg0.add_stream(tx)
1240
1241 self.pg_enable_capture(self.pg_interfaces)
1242 self.pg_start()
1243
1244 rx = self.pg2.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001245 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(42)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001246 rx = self.pg3.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001247 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(43)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001248
Neale Ranns31426c62017-05-24 10:32:58 -07001249 def test_mcast_ip4_tail(self):
1250 """ MPLS IPv4 Multicast Tail """
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001251
1252 #
1253 # Add a multicast route that will forward the traffic
1254 # post-disposition
1255 #
1256 route_232_1_1_1 = VppIpMRoute(
1257 self,
1258 "0.0.0.0",
1259 "232.1.1.1", 32,
1260 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
1261 table_id=1,
1262 paths=[VppMRoutePath(self.pg1.sw_if_index,
1263 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
1264 route_232_1_1_1.add_vpp_config()
1265
1266 #
1267 # An interface receive label that maps traffic to RX on interface
1268 # pg1
1269 # by injecting the packet in on pg0, which is in table 0
1270 # doing an rpf-id and matching a route in table 1
1271 # if the packet egresses, then we must have matched the route in
1272 # table 1
1273 #
1274 route_34_eos = VppMplsRoute(self, 34, 1,
1275 [VppRoutePath("0.0.0.0",
1276 self.pg1.sw_if_index,
1277 nh_table_id=1,
1278 rpf_id=55)],
1279 is_multicast=1)
1280
1281 route_34_eos.add_vpp_config()
1282
1283 #
1284 # Drop due to interface lookup miss
1285 #
1286 self.vapi.cli("clear trace")
Neale Ranns31ed7442018-02-23 05:29:09 -08001287 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001288 dst_ip="232.1.1.1", n=1)
1289 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop none")
1290
1291 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001292 # set the RPF-ID of the entry to match the input packet's
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001293 #
1294 route_232_1_1_1.update_rpf_id(55)
1295
Neale Ranns31ed7442018-02-23 05:29:09 -08001296 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
1297 dst_ip="232.1.1.1")
1298 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001299 self.verify_capture_ip4(self.pg1, rx, tx)
1300
1301 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001302 # disposed packets have an invalid IPv4 checksum
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001303 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001304 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001305 dst_ip="232.1.1.1", n=65,
1306 chksum=1)
1307 self.send_and_assert_no_replies(self.pg0, tx, "Invalid Checksum")
1308
1309 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001310 # set the RPF-ID of the entry to not match the input packet's
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001311 #
1312 route_232_1_1_1.update_rpf_id(56)
Neale Ranns31ed7442018-02-23 05:29:09 -08001313 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001314 dst_ip="232.1.1.1")
1315 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop 56")
1316
Neale Ranns31426c62017-05-24 10:32:58 -07001317 def test_mcast_ip6_tail(self):
1318 """ MPLS IPv6 Multicast Tail """
1319
1320 #
1321 # Add a multicast route that will forward the traffic
1322 # post-disposition
1323 #
1324 route_ff = VppIpMRoute(
1325 self,
1326 "::",
1327 "ff01::1", 32,
1328 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
1329 table_id=1,
1330 paths=[VppMRoutePath(self.pg1.sw_if_index,
1331 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)],
1332 is_ip6=1)
1333 route_ff.add_vpp_config()
1334
1335 #
1336 # An interface receive label that maps traffic to RX on interface
1337 # pg1
1338 # by injecting the packet in on pg0, which is in table 0
1339 # doing an rpf-id and matching a route in table 1
1340 # if the packet egresses, then we must have matched the route in
1341 # table 1
1342 #
1343 route_34_eos = VppMplsRoute(
1344 self, 34, 1,
1345 [VppRoutePath("::",
1346 self.pg1.sw_if_index,
1347 nh_table_id=1,
1348 rpf_id=55,
Neale Rannsda78f952017-05-24 09:15:43 -07001349 proto=DpoProto.DPO_PROTO_IP6)],
Neale Ranns31426c62017-05-24 10:32:58 -07001350 is_multicast=1)
1351
1352 route_34_eos.add_vpp_config()
1353
1354 #
1355 # Drop due to interface lookup miss
1356 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001357 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(34)],
Neale Ranns31426c62017-05-24 10:32:58 -07001358 dst_ip="ff01::1")
Neale Ranns31ed7442018-02-23 05:29:09 -08001359 self.send_and_assert_no_replies(self.pg0, tx, "RPF Miss")
Neale Ranns31426c62017-05-24 10:32:58 -07001360
1361 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001362 # set the RPF-ID of the entry to match the input packet's
Neale Ranns31426c62017-05-24 10:32:58 -07001363 #
1364 route_ff.update_rpf_id(55)
1365
Neale Ranns31ed7442018-02-23 05:29:09 -08001366 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(34)],
Neale Ranns31426c62017-05-24 10:32:58 -07001367 dst_ip="ff01::1")
Neale Ranns31ed7442018-02-23 05:29:09 -08001368 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns31426c62017-05-24 10:32:58 -07001369 self.verify_capture_ip6(self.pg1, rx, tx)
1370
1371 #
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001372 # disposed packets have hop-limit = 1
1373 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001374 tx = self.create_stream_labelled_ip6(self.pg0,
1375 [VppMplsLabel(34)],
1376 dst_ip="ff01::1",
1377 hlim=1)
1378 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns52fae862018-01-08 04:41:42 -08001379 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001380
1381 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001382 # set the RPF-ID of the entry to not match the input packet's
Neale Ranns31426c62017-05-24 10:32:58 -07001383 #
1384 route_ff.update_rpf_id(56)
Neale Ranns31ed7442018-02-23 05:29:09 -08001385 tx = self.create_stream_labelled_ip6(self.pg0,
1386 [VppMplsLabel(34)],
Neale Ranns31426c62017-05-24 10:32:58 -07001387 dst_ip="ff01::1")
1388 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop 56")
1389
Neale Ranns180279b2017-03-16 15:49:09 -04001390
1391class TestMPLSDisabled(VppTestCase):
1392 """ MPLS disabled """
1393
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -07001394 @classmethod
1395 def setUpClass(cls):
1396 super(TestMPLSDisabled, cls).setUpClass()
1397
1398 @classmethod
1399 def tearDownClass(cls):
1400 super(TestMPLSDisabled, cls).tearDownClass()
1401
Neale Ranns180279b2017-03-16 15:49:09 -04001402 def setUp(self):
1403 super(TestMPLSDisabled, self).setUp()
1404
1405 # create 2 pg interfaces
1406 self.create_pg_interfaces(range(2))
1407
Neale Ranns15002542017-09-10 04:39:11 -07001408 self.tbl = VppMplsTable(self, 0)
1409 self.tbl.add_vpp_config()
1410
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001411 # PG0 is MPLS enabled
Neale Ranns180279b2017-03-16 15:49:09 -04001412 self.pg0.admin_up()
1413 self.pg0.config_ip4()
1414 self.pg0.resolve_arp()
1415 self.pg0.enable_mpls()
1416
1417 # PG 1 is not MPLS enabled
1418 self.pg1.admin_up()
1419
1420 def tearDown(self):
Neale Ranns180279b2017-03-16 15:49:09 -04001421 for i in self.pg_interfaces:
1422 i.unconfig_ip4()
1423 i.admin_down()
1424
Neale Ranns15002542017-09-10 04:39:11 -07001425 self.pg0.disable_mpls()
1426 super(TestMPLSDisabled, self).tearDown()
1427
Neale Ranns180279b2017-03-16 15:49:09 -04001428 def test_mpls_disabled(self):
1429 """ MPLS Disabled """
1430
1431 tx = (Ether(src=self.pg1.remote_mac,
1432 dst=self.pg1.local_mac) /
1433 MPLS(label=32, ttl=64) /
1434 IPv6(src="2001::1", dst=self.pg0.remote_ip6) /
1435 UDP(sport=1234, dport=1234) /
1436 Raw('\xa5' * 100))
1437
1438 #
1439 # A simple MPLS xconnect - eos label in label out
1440 #
1441 route_32_eos = VppMplsRoute(self, 32, 1,
1442 [VppRoutePath(self.pg0.remote_ip4,
1443 self.pg0.sw_if_index,
1444 labels=[33])])
1445 route_32_eos.add_vpp_config()
1446
1447 #
1448 # PG1 does not forward IP traffic
1449 #
1450 self.send_and_assert_no_replies(self.pg1, tx, "MPLS disabled")
1451
1452 #
1453 # MPLS enable PG1
1454 #
1455 self.pg1.enable_mpls()
1456
1457 #
1458 # Now we get packets through
1459 #
1460 self.pg1.add_stream(tx)
1461 self.pg_enable_capture(self.pg_interfaces)
1462 self.pg_start()
1463
1464 rx = self.pg0.get_capture(1)
1465
1466 #
1467 # Disable PG1
1468 #
1469 self.pg1.disable_mpls()
1470
1471 #
1472 # PG1 does not forward IP traffic
1473 #
1474 self.send_and_assert_no_replies(self.pg1, tx, "IPv6 disabled")
1475 self.send_and_assert_no_replies(self.pg1, tx, "IPv6 disabled")
1476
1477
Neale Rannsf12a83f2017-04-18 09:09:40 -07001478class TestMPLSPIC(VppTestCase):
1479 """ MPLS PIC edge convergence """
1480
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -07001481 @classmethod
1482 def setUpClass(cls):
1483 super(TestMPLSPIC, cls).setUpClass()
1484
1485 @classmethod
1486 def tearDownClass(cls):
1487 super(TestMPLSPIC, cls).tearDownClass()
1488
Neale Rannsf12a83f2017-04-18 09:09:40 -07001489 def setUp(self):
1490 super(TestMPLSPIC, self).setUp()
1491
1492 # create 2 pg interfaces
1493 self.create_pg_interfaces(range(4))
1494
Neale Ranns15002542017-09-10 04:39:11 -07001495 mpls_tbl = VppMplsTable(self, 0)
1496 mpls_tbl.add_vpp_config()
1497 tbl4 = VppIpTable(self, 1)
1498 tbl4.add_vpp_config()
1499 tbl6 = VppIpTable(self, 1, is_ip6=1)
1500 tbl6.add_vpp_config()
1501
Neale Rannsf12a83f2017-04-18 09:09:40 -07001502 # core links
1503 self.pg0.admin_up()
1504 self.pg0.config_ip4()
1505 self.pg0.resolve_arp()
1506 self.pg0.enable_mpls()
1507 self.pg1.admin_up()
1508 self.pg1.config_ip4()
1509 self.pg1.resolve_arp()
1510 self.pg1.enable_mpls()
1511
1512 # VRF (customer facing) link
1513 self.pg2.admin_up()
1514 self.pg2.set_table_ip4(1)
1515 self.pg2.config_ip4()
1516 self.pg2.resolve_arp()
1517 self.pg2.set_table_ip6(1)
1518 self.pg2.config_ip6()
1519 self.pg2.resolve_ndp()
1520 self.pg3.admin_up()
1521 self.pg3.set_table_ip4(1)
1522 self.pg3.config_ip4()
1523 self.pg3.resolve_arp()
1524 self.pg3.set_table_ip6(1)
1525 self.pg3.config_ip6()
1526 self.pg3.resolve_ndp()
1527
1528 def tearDown(self):
Neale Rannsf12a83f2017-04-18 09:09:40 -07001529 self.pg0.disable_mpls()
Neale Ranns15002542017-09-10 04:39:11 -07001530 self.pg1.disable_mpls()
Neale Rannsf12a83f2017-04-18 09:09:40 -07001531 for i in self.pg_interfaces:
1532 i.unconfig_ip4()
1533 i.unconfig_ip6()
1534 i.set_table_ip4(0)
1535 i.set_table_ip6(0)
1536 i.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -07001537 super(TestMPLSPIC, self).tearDown()
Neale Rannsf12a83f2017-04-18 09:09:40 -07001538
1539 def test_mpls_ibgp_pic(self):
1540 """ MPLS iBGP PIC edge convergence
1541
1542 1) setup many iBGP VPN routes via a pair of iBGP peers.
1543 2) Check EMCP forwarding to these peers
1544 3) withdraw the IGP route to one of these peers.
1545 4) check forwarding continues to the remaining peer
1546 """
1547
1548 #
1549 # IGP+LDP core routes
1550 #
1551 core_10_0_0_45 = VppIpRoute(self, "10.0.0.45", 32,
1552 [VppRoutePath(self.pg0.remote_ip4,
1553 self.pg0.sw_if_index,
1554 labels=[45])])
1555 core_10_0_0_45.add_vpp_config()
1556
1557 core_10_0_0_46 = VppIpRoute(self, "10.0.0.46", 32,
1558 [VppRoutePath(self.pg1.remote_ip4,
1559 self.pg1.sw_if_index,
1560 labels=[46])])
1561 core_10_0_0_46.add_vpp_config()
1562
1563 #
1564 # Lot's of VPN routes. We need more the 64 so VPP will build
1565 # the fast convergence indirection
1566 #
1567 vpn_routes = []
1568 pkts = []
1569 for ii in range(64):
1570 dst = "192.168.1.%d" % ii
1571 vpn_routes.append(VppIpRoute(self, dst, 32,
1572 [VppRoutePath("10.0.0.45",
1573 0xffffffff,
1574 labels=[145],
1575 is_resolve_host=1),
1576 VppRoutePath("10.0.0.46",
1577 0xffffffff,
1578 labels=[146],
1579 is_resolve_host=1)],
1580 table_id=1))
1581 vpn_routes[ii].add_vpp_config()
1582
1583 pkts.append(Ether(dst=self.pg2.local_mac,
1584 src=self.pg2.remote_mac) /
1585 IP(src=self.pg2.remote_ip4, dst=dst) /
1586 UDP(sport=1234, dport=1234) /
1587 Raw('\xa5' * 100))
1588
1589 #
1590 # Send the packet stream (one pkt to each VPN route)
1591 # - expect a 50-50 split of the traffic
1592 #
1593 self.pg2.add_stream(pkts)
1594 self.pg_enable_capture(self.pg_interfaces)
1595 self.pg_start()
1596
1597 rx0 = self.pg0._get_capture(1)
1598 rx1 = self.pg1._get_capture(1)
1599
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001600 # not testing the LB hashing algorithm so we're not concerned
Neale Rannsf12a83f2017-04-18 09:09:40 -07001601 # with the split ratio, just as long as neither is 0
1602 self.assertNotEqual(0, len(rx0))
1603 self.assertNotEqual(0, len(rx1))
1604
1605 #
1606 # use a test CLI command to stop the FIB walk process, this
1607 # will prevent the FIB converging the VPN routes and thus allow
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001608 # us to probe the interim (post-fail, pre-converge) state
Neale Rannsf12a83f2017-04-18 09:09:40 -07001609 #
1610 self.vapi.ppcli("test fib-walk-process disable")
1611
1612 #
1613 # Withdraw one of the IGP routes
1614 #
1615 core_10_0_0_46.remove_vpp_config()
1616
1617 #
1618 # now all packets should be forwarded through the remaining peer
1619 #
1620 self.vapi.ppcli("clear trace")
1621 self.pg2.add_stream(pkts)
1622 self.pg_enable_capture(self.pg_interfaces)
1623 self.pg_start()
1624
1625 rx0 = self.pg0.get_capture(len(pkts))
1626
1627 #
1628 # enable the FIB walk process to converge the FIB
1629 #
1630 self.vapi.ppcli("test fib-walk-process enable")
1631
1632 #
1633 # packets should still be forwarded through the remaining peer
1634 #
1635 self.pg2.add_stream(pkts)
1636 self.pg_enable_capture(self.pg_interfaces)
1637 self.pg_start()
1638
1639 rx0 = self.pg0.get_capture(64)
1640
1641 #
1642 # Add the IGP route back and we return to load-balancing
1643 #
1644 core_10_0_0_46.add_vpp_config()
1645
1646 self.pg2.add_stream(pkts)
1647 self.pg_enable_capture(self.pg_interfaces)
1648 self.pg_start()
1649
1650 rx0 = self.pg0._get_capture(1)
1651 rx1 = self.pg1._get_capture(1)
1652 self.assertNotEqual(0, len(rx0))
1653 self.assertNotEqual(0, len(rx1))
1654
1655 def test_mpls_ebgp_pic(self):
1656 """ MPLS eBGP PIC edge convergence
1657
1658 1) setup many eBGP VPN routes via a pair of eBGP peers
1659 2) Check EMCP forwarding to these peers
1660 3) withdraw one eBGP path - expect LB across remaining eBGP
1661 """
1662
1663 #
1664 # Lot's of VPN routes. We need more the 64 so VPP will build
1665 # the fast convergence indirection
1666 #
1667 vpn_routes = []
1668 vpn_bindings = []
1669 pkts = []
1670 for ii in range(64):
1671 dst = "192.168.1.%d" % ii
1672 local_label = 1600 + ii
1673 vpn_routes.append(VppIpRoute(self, dst, 32,
1674 [VppRoutePath(self.pg2.remote_ip4,
1675 0xffffffff,
1676 nh_table_id=1,
1677 is_resolve_attached=1),
1678 VppRoutePath(self.pg3.remote_ip4,
1679 0xffffffff,
1680 nh_table_id=1,
1681 is_resolve_attached=1)],
1682 table_id=1))
1683 vpn_routes[ii].add_vpp_config()
1684
1685 vpn_bindings.append(VppMplsIpBind(self, local_label, dst, 32,
1686 ip_table_id=1))
1687 vpn_bindings[ii].add_vpp_config()
1688
1689 pkts.append(Ether(dst=self.pg0.local_mac,
1690 src=self.pg0.remote_mac) /
1691 MPLS(label=local_label, ttl=64) /
1692 IP(src=self.pg0.remote_ip4, dst=dst) /
1693 UDP(sport=1234, dport=1234) /
1694 Raw('\xa5' * 100))
1695
1696 self.pg0.add_stream(pkts)
1697 self.pg_enable_capture(self.pg_interfaces)
1698 self.pg_start()
1699
1700 rx0 = self.pg2._get_capture(1)
1701 rx1 = self.pg3._get_capture(1)
1702 self.assertNotEqual(0, len(rx0))
1703 self.assertNotEqual(0, len(rx1))
1704
1705 #
1706 # use a test CLI command to stop the FIB walk process, this
1707 # will prevent the FIB converging the VPN routes and thus allow
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001708 # us to probe the interim (post-fail, pre-converge) state
Neale Rannsf12a83f2017-04-18 09:09:40 -07001709 #
1710 self.vapi.ppcli("test fib-walk-process disable")
1711
1712 #
1713 # withdraw the connected prefix on the interface.
1714 #
1715 self.pg2.unconfig_ip4()
1716
1717 #
1718 # now all packets should be forwarded through the remaining peer
1719 #
1720 self.pg0.add_stream(pkts)
1721 self.pg_enable_capture(self.pg_interfaces)
1722 self.pg_start()
1723
1724 rx0 = self.pg3.get_capture(len(pkts))
1725
1726 #
1727 # enable the FIB walk process to converge the FIB
1728 #
1729 self.vapi.ppcli("test fib-walk-process enable")
1730 self.pg0.add_stream(pkts)
1731 self.pg_enable_capture(self.pg_interfaces)
1732 self.pg_start()
1733
1734 rx0 = self.pg3.get_capture(len(pkts))
1735
1736 #
1737 # put the connecteds back
1738 #
1739 self.pg2.config_ip4()
1740
1741 self.pg0.add_stream(pkts)
1742 self.pg_enable_capture(self.pg_interfaces)
1743 self.pg_start()
1744
1745 rx0 = self.pg2._get_capture(1)
1746 rx1 = self.pg3._get_capture(1)
1747 self.assertNotEqual(0, len(rx0))
1748 self.assertNotEqual(0, len(rx1))
1749
1750 def test_mpls_v6_ebgp_pic(self):
1751 """ MPLSv6 eBGP PIC edge convergence
1752
1753 1) setup many eBGP VPNv6 routes via a pair of eBGP peers
1754 2) Check EMCP forwarding to these peers
1755 3) withdraw one eBGP path - expect LB across remaining eBGP
1756 """
1757
1758 #
1759 # Lot's of VPN routes. We need more the 64 so VPP will build
1760 # the fast convergence indirection
1761 #
1762 vpn_routes = []
1763 vpn_bindings = []
1764 pkts = []
1765 for ii in range(64):
1766 dst = "3000::%d" % ii
1767 local_label = 1600 + ii
Neale Rannsda78f952017-05-24 09:15:43 -07001768 vpn_routes.append(VppIpRoute(
1769 self, dst, 128,
1770 [VppRoutePath(self.pg2.remote_ip6,
1771 0xffffffff,
1772 nh_table_id=1,
1773 is_resolve_attached=1,
1774 proto=DpoProto.DPO_PROTO_IP6),
1775 VppRoutePath(self.pg3.remote_ip6,
1776 0xffffffff,
1777 nh_table_id=1,
1778 proto=DpoProto.DPO_PROTO_IP6,
1779 is_resolve_attached=1)],
1780 table_id=1,
1781 is_ip6=1))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001782 vpn_routes[ii].add_vpp_config()
1783
1784 vpn_bindings.append(VppMplsIpBind(self, local_label, dst, 128,
1785 ip_table_id=1,
1786 is_ip6=1))
1787 vpn_bindings[ii].add_vpp_config()
1788
1789 pkts.append(Ether(dst=self.pg0.local_mac,
1790 src=self.pg0.remote_mac) /
1791 MPLS(label=local_label, ttl=64) /
1792 IPv6(src=self.pg0.remote_ip6, dst=dst) /
1793 UDP(sport=1234, dport=1234) /
1794 Raw('\xa5' * 100))
1795
1796 self.pg0.add_stream(pkts)
1797 self.pg_enable_capture(self.pg_interfaces)
1798 self.pg_start()
1799
1800 rx0 = self.pg2._get_capture(1)
1801 rx1 = self.pg3._get_capture(1)
1802 self.assertNotEqual(0, len(rx0))
1803 self.assertNotEqual(0, len(rx1))
1804
1805 #
1806 # use a test CLI command to stop the FIB walk process, this
1807 # will prevent the FIB converging the VPN routes and thus allow
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001808 # us to probe the interim (post-fail, pre-converge) state
Neale Rannsf12a83f2017-04-18 09:09:40 -07001809 #
1810 self.vapi.ppcli("test fib-walk-process disable")
1811
1812 #
1813 # withdraw the connected prefix on the interface.
1814 # and shutdown the interface so the ND cache is flushed.
1815 #
1816 self.pg2.unconfig_ip6()
1817 self.pg2.admin_down()
1818
1819 #
1820 # now all packets should be forwarded through the remaining peer
1821 #
1822 self.pg0.add_stream(pkts)
1823 self.pg_enable_capture(self.pg_interfaces)
1824 self.pg_start()
1825
1826 rx0 = self.pg3.get_capture(len(pkts))
1827
1828 #
1829 # enable the FIB walk process to converge the FIB
1830 #
1831 self.vapi.ppcli("test fib-walk-process enable")
1832 self.pg0.add_stream(pkts)
1833 self.pg_enable_capture(self.pg_interfaces)
1834 self.pg_start()
1835
1836 rx0 = self.pg3.get_capture(len(pkts))
1837
1838 #
1839 # put the connecteds back
1840 #
1841 self.pg2.admin_up()
1842 self.pg2.config_ip6()
1843
1844 self.pg0.add_stream(pkts)
1845 self.pg_enable_capture(self.pg_interfaces)
1846 self.pg_start()
1847
1848 rx0 = self.pg2._get_capture(1)
1849 rx1 = self.pg3._get_capture(1)
1850 self.assertNotEqual(0, len(rx0))
1851 self.assertNotEqual(0, len(rx1))
1852
1853
Neale Rannsda78f952017-05-24 09:15:43 -07001854class TestMPLSL2(VppTestCase):
1855 """ MPLS-L2 """
1856
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -07001857 @classmethod
1858 def setUpClass(cls):
1859 super(TestMPLSL2, cls).setUpClass()
1860
1861 @classmethod
1862 def tearDownClass(cls):
1863 super(TestMPLSL2, cls).tearDownClass()
1864
Neale Rannsda78f952017-05-24 09:15:43 -07001865 def setUp(self):
1866 super(TestMPLSL2, self).setUp()
1867
1868 # create 2 pg interfaces
1869 self.create_pg_interfaces(range(2))
1870
Neale Ranns15002542017-09-10 04:39:11 -07001871 # create the default MPLS table
1872 self.tables = []
1873 tbl = VppMplsTable(self, 0)
1874 tbl.add_vpp_config()
1875 self.tables.append(tbl)
1876
Neale Rannsda78f952017-05-24 09:15:43 -07001877 # use pg0 as the core facing interface
1878 self.pg0.admin_up()
1879 self.pg0.config_ip4()
1880 self.pg0.resolve_arp()
1881 self.pg0.enable_mpls()
1882
Neale Ranns15002542017-09-10 04:39:11 -07001883 # use the other 2 for customer facing L2 links
Neale Rannsda78f952017-05-24 09:15:43 -07001884 for i in self.pg_interfaces[1:]:
1885 i.admin_up()
1886
1887 def tearDown(self):
Neale Rannsda78f952017-05-24 09:15:43 -07001888 for i in self.pg_interfaces[1:]:
1889 i.admin_down()
1890
1891 self.pg0.disable_mpls()
1892 self.pg0.unconfig_ip4()
1893 self.pg0.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -07001894 super(TestMPLSL2, self).tearDown()
Neale Rannsda78f952017-05-24 09:15:43 -07001895
Neale Ranns31ed7442018-02-23 05:29:09 -08001896 def verify_capture_tunneled_ethernet(self, capture, sent, mpls_labels):
Neale Rannsda78f952017-05-24 09:15:43 -07001897 capture = verify_filter(capture, sent)
1898
1899 self.assertEqual(len(capture), len(sent))
1900
1901 for i in range(len(capture)):
1902 tx = sent[i]
1903 rx = capture[i]
1904
1905 # the MPLS TTL is 255 since it enters a new tunnel
Neale Ranns31ed7442018-02-23 05:29:09 -08001906 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsda78f952017-05-24 09:15:43 -07001907
1908 tx_eth = tx[Ether]
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -07001909 rx_eth = Ether(scapy.compat.raw(rx[MPLS].payload))
Neale Rannsda78f952017-05-24 09:15:43 -07001910
1911 self.assertEqual(rx_eth.src, tx_eth.src)
1912 self.assertEqual(rx_eth.dst, tx_eth.dst)
1913
1914 def test_vpws(self):
1915 """ Virtual Private Wire Service """
1916
1917 #
1918 # Create an MPLS tunnel that pushes 1 label
Neale Ranns31ed7442018-02-23 05:29:09 -08001919 # For Ethernet over MPLS the uniform mode is irrelevant since ttl/cos
1920 # information is not in the packet, but we test it works anyway
Neale Rannsda78f952017-05-24 09:15:43 -07001921 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001922 mpls_tun_1 = VppMPLSTunnelInterface(
1923 self,
1924 [VppRoutePath(self.pg0.remote_ip4,
1925 self.pg0.sw_if_index,
1926 labels=[VppMplsLabel(42, MplsLspMode.UNIFORM)])],
1927 is_l2=1)
Neale Rannsda78f952017-05-24 09:15:43 -07001928 mpls_tun_1.add_vpp_config()
1929 mpls_tun_1.admin_up()
1930
1931 #
1932 # Create a label entry to for 55 that does L2 input to the tunnel
1933 #
1934 route_55_eos = VppMplsRoute(
1935 self, 55, 1,
1936 [VppRoutePath("0.0.0.0",
1937 mpls_tun_1.sw_if_index,
1938 is_interface_rx=1,
1939 proto=DpoProto.DPO_PROTO_ETHERNET)])
1940 route_55_eos.add_vpp_config()
1941
1942 #
1943 # Cross-connect the tunnel with one of the customers L2 interfaces
1944 #
1945 self.vapi.sw_interface_set_l2_xconnect(self.pg1.sw_if_index,
1946 mpls_tun_1.sw_if_index,
1947 enable=1)
1948 self.vapi.sw_interface_set_l2_xconnect(mpls_tun_1.sw_if_index,
1949 self.pg1.sw_if_index,
1950 enable=1)
1951
1952 #
1953 # inject a packet from the core
1954 #
1955 pcore = (Ether(dst=self.pg0.local_mac,
1956 src=self.pg0.remote_mac) /
1957 MPLS(label=55, ttl=64) /
1958 Ether(dst="00:00:de:ad:ba:be",
1959 src="00:00:de:ad:be:ef") /
1960 IP(src="10.10.10.10", dst="11.11.11.11") /
1961 UDP(sport=1234, dport=1234) /
1962 Raw('\xa5' * 100))
1963
Neale Ranns31ed7442018-02-23 05:29:09 -08001964 tx0 = pcore * 65
1965 rx0 = self.send_and_expect(self.pg0, tx0, self.pg1)
1966 payload = pcore[MPLS].payload
Neale Rannsda78f952017-05-24 09:15:43 -07001967
Neale Ranns31ed7442018-02-23 05:29:09 -08001968 self.assertEqual(rx0[0][Ether].dst, payload[Ether].dst)
1969 self.assertEqual(rx0[0][Ether].src, payload[Ether].src)
Neale Rannsda78f952017-05-24 09:15:43 -07001970
1971 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -07001972 # Inject a packet from the customer/L2 side
Neale Rannsda78f952017-05-24 09:15:43 -07001973 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001974 tx1 = pcore[MPLS].payload * 65
1975 rx1 = self.send_and_expect(self.pg1, tx1, self.pg0)
Neale Rannsda78f952017-05-24 09:15:43 -07001976
Neale Ranns31ed7442018-02-23 05:29:09 -08001977 self.verify_capture_tunneled_ethernet(rx1, tx1, [VppMplsLabel(42)])
Neale Rannsda78f952017-05-24 09:15:43 -07001978
1979 def test_vpls(self):
1980 """ Virtual Private LAN Service """
1981 #
1982 # Create an L2 MPLS tunnel
1983 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001984 mpls_tun = VppMPLSTunnelInterface(
1985 self,
1986 [VppRoutePath(self.pg0.remote_ip4,
1987 self.pg0.sw_if_index,
1988 labels=[VppMplsLabel(42)])],
1989 is_l2=1)
Neale Rannsda78f952017-05-24 09:15:43 -07001990 mpls_tun.add_vpp_config()
1991 mpls_tun.admin_up()
1992
1993 #
1994 # Create a label entry to for 55 that does L2 input to the tunnel
1995 #
1996 route_55_eos = VppMplsRoute(
1997 self, 55, 1,
1998 [VppRoutePath("0.0.0.0",
1999 mpls_tun.sw_if_index,
2000 is_interface_rx=1,
2001 proto=DpoProto.DPO_PROTO_ETHERNET)])
2002 route_55_eos.add_vpp_config()
2003
2004 #
2005 # add to tunnel to the customers bridge-domain
2006 #
Ole Troana5b2eec2019-03-11 19:23:25 +01002007 self.vapi.sw_interface_set_l2_bridge(
2008 rx_sw_if_index=mpls_tun.sw_if_index, bd_id=1)
2009 self.vapi.sw_interface_set_l2_bridge(
2010 rx_sw_if_index=self.pg1.sw_if_index, bd_id=1)
Neale Rannsda78f952017-05-24 09:15:43 -07002011
2012 #
2013 # Packet from the customer interface and from the core
2014 #
2015 p_cust = (Ether(dst="00:00:de:ad:ba:be",
2016 src="00:00:de:ad:be:ef") /
2017 IP(src="10.10.10.10", dst="11.11.11.11") /
2018 UDP(sport=1234, dport=1234) /
2019 Raw('\xa5' * 100))
2020 p_core = (Ether(src="00:00:de:ad:ba:be",
2021 dst="00:00:de:ad:be:ef") /
2022 IP(dst="10.10.10.10", src="11.11.11.11") /
2023 UDP(sport=1234, dport=1234) /
2024 Raw('\xa5' * 100))
2025
2026 #
2027 # The BD is learning, so send in one of each packet to learn
2028 #
2029 p_core_encap = (Ether(dst=self.pg0.local_mac,
2030 src=self.pg0.remote_mac) /
2031 MPLS(label=55, ttl=64) /
2032 p_core)
2033
2034 self.pg1.add_stream(p_cust)
2035 self.pg_enable_capture(self.pg_interfaces)
2036 self.pg_start()
2037 self.pg0.add_stream(p_core_encap)
2038 self.pg_enable_capture(self.pg_interfaces)
2039 self.pg_start()
2040
2041 # we've learnt this so expect it be be forwarded
2042 rx0 = self.pg1.get_capture(1)
2043
2044 self.assertEqual(rx0[0][Ether].dst, p_core[Ether].dst)
2045 self.assertEqual(rx0[0][Ether].src, p_core[Ether].src)
2046
2047 #
2048 # now a stream in each direction
2049 #
2050 self.pg1.add_stream(p_cust * 65)
2051 self.pg_enable_capture(self.pg_interfaces)
2052 self.pg_start()
2053
2054 rx0 = self.pg0.get_capture(65)
2055
Neale Ranns31ed7442018-02-23 05:29:09 -08002056 self.verify_capture_tunneled_ethernet(rx0, p_cust*65,
2057 [VppMplsLabel(42)])
Neale Rannsda78f952017-05-24 09:15:43 -07002058
2059 #
2060 # remove interfaces from customers bridge-domain
2061 #
Ole Troana5b2eec2019-03-11 19:23:25 +01002062 self.vapi.sw_interface_set_l2_bridge(
2063 rx_sw_if_index=mpls_tun.sw_if_index, bd_id=1, enable=0)
2064 self.vapi.sw_interface_set_l2_bridge(
2065 rx_sw_if_index=self.pg1.sw_if_index, bd_id=1, enable=0)
Neale Rannsda78f952017-05-24 09:15:43 -07002066
Neale Ranns8fe8cc22016-11-01 10:05:08 +00002067if __name__ == '__main__':
2068 unittest.main(testRunner=VppTestRunner)