blob: 09e47521ee04f8f9de8dbd2ac88a16b40c4295f7 [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
Neale Ranns8fe8cc22016-11-01 10:05:08 +000055 def setUp(self):
56 super(TestMPLS, self).setUp()
57
58 # create 2 pg interfaces
Neale Ranns0f26c5a2017-03-01 15:12:11 -080059 self.create_pg_interfaces(range(4))
Neale Ranns8fe8cc22016-11-01 10:05:08 +000060
61 # setup both interfaces
62 # assign them different tables.
63 table_id = 0
Neale Ranns15002542017-09-10 04:39:11 -070064 self.tables = []
65
66 tbl = VppMplsTable(self, 0)
67 tbl.add_vpp_config()
68 self.tables.append(tbl)
Neale Ranns8fe8cc22016-11-01 10:05:08 +000069
70 for i in self.pg_interfaces:
71 i.admin_up()
Neale Ranns15002542017-09-10 04:39:11 -070072
73 if table_id != 0:
74 tbl = VppIpTable(self, table_id)
75 tbl.add_vpp_config()
76 self.tables.append(tbl)
77 tbl = VppIpTable(self, table_id, is_ip6=1)
78 tbl.add_vpp_config()
79 self.tables.append(tbl)
80
Neale Ranns8fe8cc22016-11-01 10:05:08 +000081 i.set_table_ip4(table_id)
82 i.set_table_ip6(table_id)
83 i.config_ip4()
Neale Ranns8fe8cc22016-11-01 10:05:08 +000084 i.resolve_arp()
Neale Rannsad422ed2016-11-02 14:20:04 +000085 i.config_ip6()
Neale Ranns8fe8cc22016-11-01 10:05:08 +000086 i.resolve_ndp()
Neale Rannsad422ed2016-11-02 14:20:04 +000087 i.enable_mpls()
Neale Ranns8fe8cc22016-11-01 10:05:08 +000088 table_id += 1
89
90 def tearDown(self):
Neale Ranns4008ac92017-02-13 23:20:04 -080091 for i in self.pg_interfaces:
92 i.unconfig_ip4()
93 i.unconfig_ip6()
94 i.ip6_disable()
Neale Ranns15002542017-09-10 04:39:11 -070095 i.set_table_ip4(0)
96 i.set_table_ip6(0)
97 i.disable_mpls()
Neale Ranns4008ac92017-02-13 23:20:04 -080098 i.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -070099 super(TestMPLS, self).tearDown()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000100
Neale Rannsad422ed2016-11-02 14:20:04 +0000101 # the default of 64 matches the IP packet TTL default
Klement Sekeradab231a2016-12-21 08:50:14 +0100102 def create_stream_labelled_ip4(
103 self,
104 src_if,
105 mpls_labels,
Klement Sekeradab231a2016-12-21 08:50:14 +0100106 ping=0,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800107 ip_itf=None,
108 dst_ip=None,
Neale Ranns4c7c8e52017-10-21 09:37:55 -0700109 chksum=None,
Neale Ranns31ed7442018-02-23 05:29:09 -0800110 ip_ttl=64,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800111 n=257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100112 self.reset_packet_infos()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000113 pkts = []
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800114 for i in range(0, n):
Klement Sekeradab231a2016-12-21 08:50:14 +0100115 info = self.create_packet_info(src_if, src_if)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000116 payload = self.info_to_payload(info)
Neale Rannsad422ed2016-11-02 14:20:04 +0000117 p = Ether(dst=src_if.local_mac, src=src_if.remote_mac)
118
119 for ii in range(len(mpls_labels)):
Neale Ranns31ed7442018-02-23 05:29:09 -0800120 p = p / MPLS(label=mpls_labels[ii].value,
121 ttl=mpls_labels[ii].ttl,
122 cos=mpls_labels[ii].exp)
Neale Rannscb630ff2016-12-14 13:31:29 +0100123 if not ping:
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800124 if not dst_ip:
Neale Ranns31ed7442018-02-23 05:29:09 -0800125 p = (p / IP(src=src_if.local_ip4,
126 dst=src_if.remote_ip4,
127 ttl=ip_ttl) /
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800128 UDP(sport=1234, dport=1234) /
129 Raw(payload))
130 else:
Neale Ranns31ed7442018-02-23 05:29:09 -0800131 p = (p / IP(src=src_if.local_ip4, dst=dst_ip, ttl=ip_ttl) /
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800132 UDP(sport=1234, dport=1234) /
133 Raw(payload))
Neale Rannscb630ff2016-12-14 13:31:29 +0100134 else:
135 p = (p / IP(src=ip_itf.remote_ip4,
Neale Ranns31ed7442018-02-23 05:29:09 -0800136 dst=ip_itf.local_ip4,
137 ttl=ip_ttl) /
Neale Rannscb630ff2016-12-14 13:31:29 +0100138 ICMP())
139
Neale Ranns4c7c8e52017-10-21 09:37:55 -0700140 if chksum:
141 p[IP].chksum = chksum
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000142 info.data = p.copy()
143 pkts.append(p)
144 return pkts
145
Neale Ranns31ed7442018-02-23 05:29:09 -0800146 def create_stream_ip4(self, src_if, dst_ip, ip_ttl=64, ip_dscp=0):
Klement Sekeradab231a2016-12-21 08:50:14 +0100147 self.reset_packet_infos()
Neale Rannsad422ed2016-11-02 14:20:04 +0000148 pkts = []
149 for i in range(0, 257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100150 info = self.create_packet_info(src_if, src_if)
Neale Rannsad422ed2016-11-02 14:20:04 +0000151 payload = self.info_to_payload(info)
152 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
Neale Ranns31ed7442018-02-23 05:29:09 -0800153 IP(src=src_if.remote_ip4, dst=dst_ip,
154 ttl=ip_ttl, tos=ip_dscp) /
Neale Rannsad422ed2016-11-02 14:20:04 +0000155 UDP(sport=1234, dport=1234) /
156 Raw(payload))
157 info.data = p.copy()
158 pkts.append(p)
159 return pkts
160
Neale Ranns31ed7442018-02-23 05:29:09 -0800161 def create_stream_ip6(self, src_if, dst_ip, ip_ttl=64, ip_dscp=0):
162 self.reset_packet_infos()
163 pkts = []
164 for i in range(0, 257):
165 info = self.create_packet_info(src_if, src_if)
166 payload = self.info_to_payload(info)
167 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
168 IPv6(src=src_if.remote_ip6, dst=dst_ip,
169 hlim=ip_ttl, tc=ip_dscp) /
170 UDP(sport=1234, dport=1234) /
171 Raw(payload))
172 info.data = p.copy()
173 pkts.append(p)
174 return pkts
175
176 def create_stream_labelled_ip6(self, src_if, mpls_labels,
177 hlim=64, dst_ip=None):
Neale Ranns31426c62017-05-24 10:32:58 -0700178 if dst_ip is None:
179 dst_ip = src_if.remote_ip6
Klement Sekeradab231a2016-12-21 08:50:14 +0100180 self.reset_packet_infos()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000181 pkts = []
182 for i in range(0, 257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100183 info = self.create_packet_info(src_if, src_if)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000184 payload = self.info_to_payload(info)
Neale Ranns31ed7442018-02-23 05:29:09 -0800185 p = Ether(dst=src_if.local_mac, src=src_if.remote_mac)
186 for l in mpls_labels:
187 p = p / MPLS(label=l.value, ttl=l.ttl, cos=l.exp)
188
189 p = p / (IPv6(src=src_if.remote_ip6, dst=dst_ip, hlim=hlim) /
190 UDP(sport=1234, dport=1234) /
191 Raw(payload))
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000192 info.data = p.copy()
193 pkts.append(p)
194 return pkts
195
Neale Ranns31ed7442018-02-23 05:29:09 -0800196 def verify_capture_ip4(self, src_if, capture, sent, ping_resp=0,
197 ip_ttl=None, ip_dscp=0):
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000198 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700199 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000200
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000201 self.assertEqual(len(capture), len(sent))
202
203 for i in range(len(capture)):
204 tx = sent[i]
205 rx = capture[i]
206
207 # the rx'd packet has the MPLS label popped
Neale Rannsad422ed2016-11-02 14:20:04 +0000208 eth = rx[Ether]
209 self.assertEqual(eth.type, 0x800)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000210
211 tx_ip = tx[IP]
212 rx_ip = rx[IP]
213
Neale Rannscb630ff2016-12-14 13:31:29 +0100214 if not ping_resp:
215 self.assertEqual(rx_ip.src, tx_ip.src)
216 self.assertEqual(rx_ip.dst, tx_ip.dst)
Neale Ranns31ed7442018-02-23 05:29:09 -0800217 self.assertEqual(rx_ip.tos, ip_dscp)
218 if not ip_ttl:
219 # IP processing post pop has decremented the TTL
220 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
221 else:
222 self.assertEqual(rx_ip.ttl, ip_ttl)
Neale Rannscb630ff2016-12-14 13:31:29 +0100223 else:
224 self.assertEqual(rx_ip.src, tx_ip.dst)
225 self.assertEqual(rx_ip.dst, tx_ip.src)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000226
227 except:
Neale Rannsad422ed2016-11-02 14:20:04 +0000228 raise
229
Neale Rannsad422ed2016-11-02 14:20:04 +0000230 def verify_capture_labelled_ip4(self, src_if, capture, sent,
Neale Ranns31ed7442018-02-23 05:29:09 -0800231 mpls_labels, ip_ttl=None):
Neale Rannsad422ed2016-11-02 14:20:04 +0000232 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700233 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000234
235 self.assertEqual(len(capture), len(sent))
236
237 for i in range(len(capture)):
238 tx = sent[i]
239 rx = capture[i]
240 tx_ip = tx[IP]
241 rx_ip = rx[IP]
242
Neale Ranns31ed7442018-02-23 05:29:09 -0800243 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsad422ed2016-11-02 14:20:04 +0000244
245 self.assertEqual(rx_ip.src, tx_ip.src)
246 self.assertEqual(rx_ip.dst, tx_ip.dst)
Neale Ranns31ed7442018-02-23 05:29:09 -0800247 if not ip_ttl:
248 # IP processing post pop has decremented the TTL
249 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
250 else:
251 self.assertEqual(rx_ip.ttl, ip_ttl)
Neale Rannsad422ed2016-11-02 14:20:04 +0000252
253 except:
254 raise
255
Neale Ranns31ed7442018-02-23 05:29:09 -0800256 def verify_capture_labelled_ip6(self, src_if, capture, sent,
257 mpls_labels, ip_ttl=None):
258 try:
259 capture = verify_filter(capture, sent)
260
261 self.assertEqual(len(capture), len(sent))
262
263 for i in range(len(capture)):
264 tx = sent[i]
265 rx = capture[i]
266 tx_ip = tx[IPv6]
267 rx_ip = rx[IPv6]
268
269 verify_mpls_stack(self, rx, mpls_labels)
270
271 self.assertEqual(rx_ip.src, tx_ip.src)
272 self.assertEqual(rx_ip.dst, tx_ip.dst)
273 if not ip_ttl:
274 # IP processing post pop has decremented the TTL
275 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
276 else:
277 self.assertEqual(rx_ip.hlim, ip_ttl)
278
279 except:
280 raise
281
282 def verify_capture_tunneled_ip4(self, src_if, capture, sent, mpls_labels):
Neale Rannsad422ed2016-11-02 14:20:04 +0000283 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700284 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000285
286 self.assertEqual(len(capture), len(sent))
287
288 for i in range(len(capture)):
289 tx = sent[i]
290 rx = capture[i]
291 tx_ip = tx[IP]
292 rx_ip = rx[IP]
293
Neale Ranns31ed7442018-02-23 05:29:09 -0800294 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsad422ed2016-11-02 14:20:04 +0000295
296 self.assertEqual(rx_ip.src, tx_ip.src)
297 self.assertEqual(rx_ip.dst, tx_ip.dst)
298 # IP processing post pop has decremented the TTL
299 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
300
301 except:
302 raise
303
304 def verify_capture_labelled(self, src_if, capture, sent,
Neale Ranns31ed7442018-02-23 05:29:09 -0800305 mpls_labels):
Neale Rannsad422ed2016-11-02 14:20:04 +0000306 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700307 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000308
309 self.assertEqual(len(capture), len(sent))
310
311 for i in range(len(capture)):
312 rx = capture[i]
Neale Ranns31ed7442018-02-23 05:29:09 -0800313 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsad422ed2016-11-02 14:20:04 +0000314 except:
315 raise
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000316
Neale Ranns31ed7442018-02-23 05:29:09 -0800317 def verify_capture_ip6(self, src_if, capture, sent,
318 ip_hlim=None, ip_dscp=0):
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000319 try:
320 self.assertEqual(len(capture), len(sent))
321
322 for i in range(len(capture)):
323 tx = sent[i]
324 rx = capture[i]
325
326 # the rx'd packet has the MPLS label popped
Neale Rannsad422ed2016-11-02 14:20:04 +0000327 eth = rx[Ether]
328 self.assertEqual(eth.type, 0x86DD)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000329
330 tx_ip = tx[IPv6]
331 rx_ip = rx[IPv6]
332
333 self.assertEqual(rx_ip.src, tx_ip.src)
334 self.assertEqual(rx_ip.dst, tx_ip.dst)
Neale Ranns31ed7442018-02-23 05:29:09 -0800335 self.assertEqual(rx_ip.tc, ip_dscp)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000336 # IP processing post pop has decremented the TTL
Neale Ranns31ed7442018-02-23 05:29:09 -0800337 if not ip_hlim:
338 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
339 else:
340 self.assertEqual(rx_ip.hlim, ip_hlim)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000341
342 except:
Neale Rannsad422ed2016-11-02 14:20:04 +0000343 raise
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000344
Neale Ranns62fe07c2017-10-31 12:28:22 -0700345 def verify_capture_ip6_icmp(self, src_if, capture, sent):
346 try:
347 self.assertEqual(len(capture), len(sent))
348
349 for i in range(len(capture)):
350 tx = sent[i]
351 rx = capture[i]
352
353 # the rx'd packet has the MPLS label popped
354 eth = rx[Ether]
355 self.assertEqual(eth.type, 0x86DD)
356
357 tx_ip = tx[IPv6]
358 rx_ip = rx[IPv6]
359
360 self.assertEqual(rx_ip.dst, tx_ip.src)
361 # ICMP sourced from the interface's address
362 self.assertEqual(rx_ip.src, src_if.local_ip6)
363 # hop-limit reset to 255 for IMCP packet
Ole Troan282093f2018-09-19 12:38:51 +0200364 self.assertEqual(rx_ip.hlim, 255)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700365
366 icmp = rx[ICMPv6TimeExceeded]
367
368 except:
369 raise
370
Neale Rannsad422ed2016-11-02 14:20:04 +0000371 def test_swap(self):
372 """ MPLS label swap tests """
373
374 #
375 # A simple MPLS xconnect - eos label in label out
376 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800377 route_32_eos = VppMplsRoute(self, 32, 1,
378 [VppRoutePath(self.pg0.remote_ip4,
379 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800380 labels=[VppMplsLabel(33)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000381 route_32_eos.add_vpp_config()
382
Neale Ranns775f73c2018-12-20 03:01:49 -0800383 self.assertTrue(
384 find_mpls_route(self, 0, 32, 1,
385 [VppRoutePath(self.pg0.remote_ip4,
386 self.pg0.sw_if_index,
387 labels=[VppMplsLabel(33)])]))
388
Neale Rannsad422ed2016-11-02 14:20:04 +0000389 #
390 # a stream that matches the route for 10.0.0.1
391 # PG0 is in the default table
392 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800393 tx = self.create_stream_labelled_ip4(self.pg0,
394 [VppMplsLabel(32, ttl=32, exp=1)])
395 rx = self.send_and_expect(self.pg0, tx, self.pg0)
396 self.verify_capture_labelled(self.pg0, rx, tx,
397 [VppMplsLabel(33, ttl=31, exp=1)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000398
Neale Ranns008dbe12018-09-07 09:32:36 -0700399 self.assertEqual(route_32_eos.get_stats_to()['packets'], 257)
400
Neale Rannsad422ed2016-11-02 14:20:04 +0000401 #
402 # A simple MPLS xconnect - non-eos label in label out
403 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800404 route_32_neos = VppMplsRoute(self, 32, 0,
405 [VppRoutePath(self.pg0.remote_ip4,
406 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800407 labels=[VppMplsLabel(33)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000408 route_32_neos.add_vpp_config()
409
410 #
411 # a stream that matches the route for 10.0.0.1
412 # PG0 is in the default table
413 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800414 tx = self.create_stream_labelled_ip4(self.pg0,
415 [VppMplsLabel(32, ttl=21, exp=7),
416 VppMplsLabel(99)])
417 rx = self.send_and_expect(self.pg0, tx, self.pg0)
418 self.verify_capture_labelled(self.pg0, rx, tx,
419 [VppMplsLabel(33, ttl=20, exp=7),
420 VppMplsLabel(99)])
Neale Ranns008dbe12018-09-07 09:32:36 -0700421 self.assertEqual(route_32_neos.get_stats_to()['packets'], 257)
Neale Rannsad422ed2016-11-02 14:20:04 +0000422
Neale Ranns31ed7442018-02-23 05:29:09 -0800423 #
424 # A simple MPLS xconnect - non-eos label in label out, uniform mode
425 #
426 route_42_neos = VppMplsRoute(
427 self, 42, 0,
428 [VppRoutePath(self.pg0.remote_ip4,
429 self.pg0.sw_if_index,
430 labels=[VppMplsLabel(43, MplsLspMode.UNIFORM)])])
431 route_42_neos.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000432
Neale Ranns31ed7442018-02-23 05:29:09 -0800433 tx = self.create_stream_labelled_ip4(self.pg0,
434 [VppMplsLabel(42, ttl=21, exp=7),
435 VppMplsLabel(99)])
436 rx = self.send_and_expect(self.pg0, tx, self.pg0)
437 self.verify_capture_labelled(self.pg0, rx, tx,
438 [VppMplsLabel(43, ttl=20, exp=7),
439 VppMplsLabel(99)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000440
441 #
442 # An MPLS xconnect - EOS label in IP out
443 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800444 route_33_eos = VppMplsRoute(self, 33, 1,
445 [VppRoutePath(self.pg0.remote_ip4,
446 self.pg0.sw_if_index,
447 labels=[])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000448 route_33_eos.add_vpp_config()
449
Neale Ranns31ed7442018-02-23 05:29:09 -0800450 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(33)])
451 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Rannsad422ed2016-11-02 14:20:04 +0000452 self.verify_capture_ip4(self.pg0, rx, tx)
453
454 #
Neale Ranns62fe07c2017-10-31 12:28:22 -0700455 # disposed packets have an invalid IPv4 checkusm
456 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800457 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(33)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700458 dst_ip=self.pg0.remote_ip4,
459 n=65,
460 chksum=1)
461 self.send_and_assert_no_replies(self.pg0, tx, "Invalid Checksum")
462
463 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800464 # An MPLS xconnect - EOS label in IP out, uniform mode
465 #
466 route_3333_eos = VppMplsRoute(
467 self, 3333, 1,
468 [VppRoutePath(self.pg0.remote_ip4,
469 self.pg0.sw_if_index,
470 labels=[VppMplsLabel(3, MplsLspMode.UNIFORM)])])
471 route_3333_eos.add_vpp_config()
472
473 tx = self.create_stream_labelled_ip4(
474 self.pg0,
475 [VppMplsLabel(3333, ttl=55, exp=3)])
476 rx = self.send_and_expect(self.pg0, tx, self.pg0)
477 self.verify_capture_ip4(self.pg0, rx, tx, ip_ttl=54, ip_dscp=0x60)
478 tx = self.create_stream_labelled_ip4(
479 self.pg0,
480 [VppMplsLabel(3333, ttl=66, exp=4)])
481 rx = self.send_and_expect(self.pg0, tx, self.pg0)
482 self.verify_capture_ip4(self.pg0, rx, tx, ip_ttl=65, ip_dscp=0x80)
483
484 #
Neale Ranns62fe07c2017-10-31 12:28:22 -0700485 # An MPLS xconnect - EOS label in IPv6 out
486 #
487 route_333_eos = VppMplsRoute(
488 self, 333, 1,
489 [VppRoutePath(self.pg0.remote_ip6,
490 self.pg0.sw_if_index,
491 labels=[],
492 proto=DpoProto.DPO_PROTO_IP6)])
493 route_333_eos.add_vpp_config()
494
Neale Ranns31ed7442018-02-23 05:29:09 -0800495 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(333)])
496 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700497 self.verify_capture_ip6(self.pg0, rx, tx)
498
499 #
500 # disposed packets have an TTL expired
501 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800502 tx = self.create_stream_labelled_ip6(self.pg0,
503 [VppMplsLabel(333, ttl=64)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700504 dst_ip=self.pg1.remote_ip6,
505 hlim=1)
Neale Ranns31ed7442018-02-23 05:29:09 -0800506 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700507 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
508
509 #
510 # An MPLS xconnect - EOS label in IPv6 out w imp-null
511 #
512 route_334_eos = VppMplsRoute(
513 self, 334, 1,
514 [VppRoutePath(self.pg0.remote_ip6,
515 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800516 labels=[VppMplsLabel(3)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700517 proto=DpoProto.DPO_PROTO_IP6)])
518 route_334_eos.add_vpp_config()
519
Neale Ranns31ed7442018-02-23 05:29:09 -0800520 tx = self.create_stream_labelled_ip6(self.pg0,
521 [VppMplsLabel(334, ttl=64)])
522 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700523 self.verify_capture_ip6(self.pg0, rx, tx)
524
525 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800526 # An MPLS xconnect - EOS label in IPv6 out w imp-null in uniform mode
527 #
528 route_335_eos = VppMplsRoute(
529 self, 335, 1,
530 [VppRoutePath(self.pg0.remote_ip6,
531 self.pg0.sw_if_index,
532 labels=[VppMplsLabel(3, MplsLspMode.UNIFORM)],
533 proto=DpoProto.DPO_PROTO_IP6)])
534 route_335_eos.add_vpp_config()
535
536 tx = self.create_stream_labelled_ip6(
537 self.pg0,
538 [VppMplsLabel(335, ttl=27, exp=4)])
539 rx = self.send_and_expect(self.pg0, tx, self.pg0)
540 self.verify_capture_ip6(self.pg0, rx, tx, ip_hlim=26, ip_dscp=0x80)
541
542 #
Neale Ranns62fe07c2017-10-31 12:28:22 -0700543 # disposed packets have an TTL expired
544 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800545 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(334)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700546 dst_ip=self.pg1.remote_ip6,
547 hlim=0)
Neale Ranns31ed7442018-02-23 05:29:09 -0800548 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700549 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
550
551 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000552 # An MPLS xconnect - non-EOS label in IP out - an invalid configuration
553 # so this traffic should be dropped.
554 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800555 route_33_neos = VppMplsRoute(self, 33, 0,
556 [VppRoutePath(self.pg0.remote_ip4,
557 self.pg0.sw_if_index,
558 labels=[])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000559 route_33_neos.add_vpp_config()
560
Neale Ranns31ed7442018-02-23 05:29:09 -0800561 tx = self.create_stream_labelled_ip4(self.pg0,
562 [VppMplsLabel(33),
563 VppMplsLabel(99)])
564 self.send_and_assert_no_replies(
565 self.pg0, tx,
566 "MPLS non-EOS packets popped and forwarded")
Neale Rannsad422ed2016-11-02 14:20:04 +0000567
568 #
569 # A recursive EOS x-connect, which resolves through another x-connect
Neale Ranns31ed7442018-02-23 05:29:09 -0800570 # in pipe mode
Neale Rannsad422ed2016-11-02 14:20:04 +0000571 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800572 route_34_eos = VppMplsRoute(self, 34, 1,
573 [VppRoutePath("0.0.0.0",
574 0xffffffff,
575 nh_via_label=32,
Neale Ranns31ed7442018-02-23 05:29:09 -0800576 labels=[VppMplsLabel(44),
577 VppMplsLabel(45)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000578 route_34_eos.add_vpp_config()
579
Neale Ranns31ed7442018-02-23 05:29:09 -0800580 tx = self.create_stream_labelled_ip4(self.pg0,
581 [VppMplsLabel(34, ttl=3)])
582 rx = self.send_and_expect(self.pg0, tx, self.pg0)
583 self.verify_capture_labelled(self.pg0, rx, tx,
584 [VppMplsLabel(33),
585 VppMplsLabel(44),
586 VppMplsLabel(45, ttl=2)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000587
Neale Ranns008dbe12018-09-07 09:32:36 -0700588 self.assertEqual(route_34_eos.get_stats_to()['packets'], 257)
589 self.assertEqual(route_32_neos.get_stats_via()['packets'], 257)
590
Neale Ranns31ed7442018-02-23 05:29:09 -0800591 #
592 # A recursive EOS x-connect, which resolves through another x-connect
593 # in uniform mode
594 #
595 route_35_eos = VppMplsRoute(
596 self, 35, 1,
597 [VppRoutePath("0.0.0.0",
598 0xffffffff,
599 nh_via_label=42,
600 labels=[VppMplsLabel(44)])])
601 route_35_eos.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000602
Neale Ranns31ed7442018-02-23 05:29:09 -0800603 tx = self.create_stream_labelled_ip4(self.pg0,
604 [VppMplsLabel(35, ttl=3)])
605 rx = self.send_and_expect(self.pg0, tx, self.pg0)
606 self.verify_capture_labelled(self.pg0, rx, tx,
607 [VppMplsLabel(43, ttl=2),
608 VppMplsLabel(44, ttl=2)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000609
610 #
Matej Klottondeb69842016-12-09 15:05:46 +0100611 # A recursive non-EOS x-connect, which resolves through another
612 # x-connect
Neale Rannsad422ed2016-11-02 14:20:04 +0000613 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800614 route_34_neos = VppMplsRoute(self, 34, 0,
615 [VppRoutePath("0.0.0.0",
616 0xffffffff,
617 nh_via_label=32,
Neale Ranns31ed7442018-02-23 05:29:09 -0800618 labels=[VppMplsLabel(44),
619 VppMplsLabel(46)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000620 route_34_neos.add_vpp_config()
621
Neale Ranns31ed7442018-02-23 05:29:09 -0800622 tx = self.create_stream_labelled_ip4(self.pg0,
623 [VppMplsLabel(34, ttl=45),
624 VppMplsLabel(99)])
625 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Matej Klottondeb69842016-12-09 15:05:46 +0100626 # it's the 2nd (counting from 0) label in the stack that is swapped
Neale Ranns31ed7442018-02-23 05:29:09 -0800627 self.verify_capture_labelled(self.pg0, rx, tx,
628 [VppMplsLabel(33),
629 VppMplsLabel(44),
630 VppMplsLabel(46, ttl=44),
631 VppMplsLabel(99)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000632
633 #
Matej Klottondeb69842016-12-09 15:05:46 +0100634 # an recursive IP route that resolves through the recursive non-eos
635 # x-connect
Neale Rannsad422ed2016-11-02 14:20:04 +0000636 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800637 ip_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
638 [VppRoutePath("0.0.0.0",
639 0xffffffff,
640 nh_via_label=34,
Neale Ranns31ed7442018-02-23 05:29:09 -0800641 labels=[VppMplsLabel(55)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000642 ip_10_0_0_1.add_vpp_config()
643
Neale Rannsad422ed2016-11-02 14:20:04 +0000644 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800645 rx = self.send_and_expect(self.pg0, tx, self.pg0)
646 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
647 [VppMplsLabel(33),
648 VppMplsLabel(44),
649 VppMplsLabel(46),
650 VppMplsLabel(55)])
Neale Ranns008dbe12018-09-07 09:32:36 -0700651 self.assertEqual(ip_10_0_0_1.get_stats_to()['packets'], 257)
Neale Rannsad422ed2016-11-02 14:20:04 +0000652
653 ip_10_0_0_1.remove_vpp_config()
654 route_34_neos.remove_vpp_config()
655 route_34_eos.remove_vpp_config()
656 route_33_neos.remove_vpp_config()
657 route_33_eos.remove_vpp_config()
658 route_32_neos.remove_vpp_config()
659 route_32_eos.remove_vpp_config()
660
661 def test_bind(self):
662 """ MPLS Local Label Binding test """
663
664 #
665 # Add a non-recursive route with a single out label
666 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800667 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
668 [VppRoutePath(self.pg0.remote_ip4,
669 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800670 labels=[VppMplsLabel(45)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000671 route_10_0_0_1.add_vpp_config()
672
673 # bind a local label to the route
Neale Ranns5a8123b2017-01-26 01:18:23 -0800674 binding = VppMplsIpBind(self, 44, "10.0.0.1", 32)
Neale Rannsad422ed2016-11-02 14:20:04 +0000675 binding.add_vpp_config()
676
677 # non-EOS stream
Neale Ranns31ed7442018-02-23 05:29:09 -0800678 tx = self.create_stream_labelled_ip4(self.pg0,
679 [VppMplsLabel(44),
680 VppMplsLabel(99)])
681 rx = self.send_and_expect(self.pg0, tx, self.pg0)
682 self.verify_capture_labelled(self.pg0, rx, tx,
683 [VppMplsLabel(45, ttl=63),
684 VppMplsLabel(99)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000685
686 # EOS stream
Neale Ranns31ed7442018-02-23 05:29:09 -0800687 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(44)])
688 rx = self.send_and_expect(self.pg0, tx, self.pg0)
689 self.verify_capture_labelled(self.pg0, rx, tx,
690 [VppMplsLabel(45, ttl=63)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000691
692 # IP stream
Neale Rannsad422ed2016-11-02 14:20:04 +0000693 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800694 rx = self.send_and_expect(self.pg0, tx, self.pg0)
695 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [VppMplsLabel(45)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000696
697 #
698 # cleanup
699 #
700 binding.remove_vpp_config()
701 route_10_0_0_1.remove_vpp_config()
702
703 def test_imposition(self):
704 """ MPLS label imposition test """
705
706 #
707 # Add a non-recursive route with a single out label
708 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800709 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
710 [VppRoutePath(self.pg0.remote_ip4,
711 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800712 labels=[VppMplsLabel(32)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000713 route_10_0_0_1.add_vpp_config()
714
715 #
716 # a stream that matches the route for 10.0.0.1
717 # PG0 is in the default table
718 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000719 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800720 rx = self.send_and_expect(self.pg0, tx, self.pg0)
721 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [VppMplsLabel(32)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000722
723 #
724 # Add a non-recursive route with a 3 out labels
725 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800726 route_10_0_0_2 = VppIpRoute(self, "10.0.0.2", 32,
727 [VppRoutePath(self.pg0.remote_ip4,
728 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800729 labels=[VppMplsLabel(32),
730 VppMplsLabel(33),
731 VppMplsLabel(34)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000732 route_10_0_0_2.add_vpp_config()
733
Neale Ranns31ed7442018-02-23 05:29:09 -0800734 tx = self.create_stream_ip4(self.pg0, "10.0.0.2",
735 ip_ttl=44, ip_dscp=0xff)
736 rx = self.send_and_expect(self.pg0, tx, self.pg0)
737 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
738 [VppMplsLabel(32),
739 VppMplsLabel(33),
740 VppMplsLabel(34)],
741 ip_ttl=43)
Neale Rannsad422ed2016-11-02 14:20:04 +0000742
Neale Ranns31ed7442018-02-23 05:29:09 -0800743 #
744 # Add a non-recursive route with a single out label in uniform mode
745 #
746 route_10_0_0_3 = VppIpRoute(
747 self, "10.0.0.3", 32,
748 [VppRoutePath(self.pg0.remote_ip4,
749 self.pg0.sw_if_index,
750 labels=[VppMplsLabel(32,
751 mode=MplsLspMode.UNIFORM)])])
752 route_10_0_0_3.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000753
Neale Ranns31ed7442018-02-23 05:29:09 -0800754 tx = self.create_stream_ip4(self.pg0, "10.0.0.3",
755 ip_ttl=54, ip_dscp=0xbe)
756 rx = self.send_and_expect(self.pg0, tx, self.pg0)
757 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
758 [VppMplsLabel(32, ttl=53, exp=5)])
759
760 #
761 # Add a IPv6 non-recursive route with a single out label in
762 # uniform mode
763 #
764 route_2001_3 = VppIpRoute(
765 self, "2001::3", 128,
766 [VppRoutePath(self.pg0.remote_ip6,
767 self.pg0.sw_if_index,
768 proto=DpoProto.DPO_PROTO_IP6,
769 labels=[VppMplsLabel(32,
770 mode=MplsLspMode.UNIFORM)])],
771 is_ip6=1)
772 route_2001_3.add_vpp_config()
773
774 tx = self.create_stream_ip6(self.pg0, "2001::3",
775 ip_ttl=54, ip_dscp=0xbe)
776 rx = self.send_and_expect(self.pg0, tx, self.pg0)
777 self.verify_capture_labelled_ip6(self.pg0, rx, tx,
778 [VppMplsLabel(32, ttl=53, exp=5)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000779
780 #
Matej Klottondeb69842016-12-09 15:05:46 +0100781 # add a recursive path, with output label, via the 1 label route
Neale Rannsad422ed2016-11-02 14:20:04 +0000782 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800783 route_11_0_0_1 = VppIpRoute(self, "11.0.0.1", 32,
784 [VppRoutePath("10.0.0.1",
785 0xffffffff,
Neale Ranns31ed7442018-02-23 05:29:09 -0800786 labels=[VppMplsLabel(44)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000787 route_11_0_0_1.add_vpp_config()
788
789 #
790 # a stream that matches the route for 11.0.0.1, should pick up
791 # the label stack for 11.0.0.1 and 10.0.0.1
792 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000793 tx = self.create_stream_ip4(self.pg0, "11.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800794 rx = self.send_and_expect(self.pg0, tx, self.pg0)
795 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
796 [VppMplsLabel(32),
797 VppMplsLabel(44)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000798
Neale Ranns008dbe12018-09-07 09:32:36 -0700799 self.assertEqual(route_11_0_0_1.get_stats_to()['packets'], 257)
800
Neale Rannsad422ed2016-11-02 14:20:04 +0000801 #
802 # add a recursive path, with 2 labels, via the 3 label route
803 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800804 route_11_0_0_2 = VppIpRoute(self, "11.0.0.2", 32,
805 [VppRoutePath("10.0.0.2",
806 0xffffffff,
Neale Ranns31ed7442018-02-23 05:29:09 -0800807 labels=[VppMplsLabel(44),
808 VppMplsLabel(45)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000809 route_11_0_0_2.add_vpp_config()
810
811 #
812 # a stream that matches the route for 11.0.0.1, should pick up
813 # the label stack for 11.0.0.1 and 10.0.0.1
814 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000815 tx = self.create_stream_ip4(self.pg0, "11.0.0.2")
Neale Ranns31ed7442018-02-23 05:29:09 -0800816 rx = self.send_and_expect(self.pg0, tx, self.pg0)
817 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
818 [VppMplsLabel(32),
819 VppMplsLabel(33),
820 VppMplsLabel(34),
821 VppMplsLabel(44),
822 VppMplsLabel(45)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000823
Neale Ranns008dbe12018-09-07 09:32:36 -0700824 self.assertEqual(route_11_0_0_2.get_stats_to()['packets'], 257)
825
826 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)])
833
834 self.assertEqual(route_11_0_0_2.get_stats_to()['packets'], 514)
835
Neale Rannsad422ed2016-11-02 14:20:04 +0000836 #
837 # cleanup
838 #
839 route_11_0_0_2.remove_vpp_config()
840 route_11_0_0_1.remove_vpp_config()
841 route_10_0_0_2.remove_vpp_config()
842 route_10_0_0_1.remove_vpp_config()
843
Neale Ranns31ed7442018-02-23 05:29:09 -0800844 def test_tunnel_pipe(self):
845 """ MPLS Tunnel Tests - Pipe """
Neale Rannsad422ed2016-11-02 14:20:04 +0000846
847 #
848 # Create a tunnel with a single out label
849 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800850 mpls_tun = VppMPLSTunnelInterface(
851 self,
852 [VppRoutePath(self.pg0.remote_ip4,
853 self.pg0.sw_if_index,
854 labels=[VppMplsLabel(44),
855 VppMplsLabel(46)])])
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800856 mpls_tun.add_vpp_config()
857 mpls_tun.admin_up()
Neale Rannsad422ed2016-11-02 14:20:04 +0000858
859 #
860 # add an unlabelled route through the new tunnel
861 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800862 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
863 [VppRoutePath("0.0.0.0",
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800864 mpls_tun._sw_if_index)])
Neale Ranns5a8123b2017-01-26 01:18:23 -0800865 route_10_0_0_3.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000866
867 self.vapi.cli("clear trace")
868 tx = self.create_stream_ip4(self.pg0, "10.0.0.3")
869 self.pg0.add_stream(tx)
870
871 self.pg_enable_capture(self.pg_interfaces)
872 self.pg_start()
873
874 rx = self.pg0.get_capture()
Neale Ranns31ed7442018-02-23 05:29:09 -0800875 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
876 [VppMplsLabel(44),
877 VppMplsLabel(46)])
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000878
Neale Ranns8c4611b2017-05-23 03:43:47 -0700879 #
880 # add a labelled route through the new tunnel
881 #
882 route_10_0_0_4 = VppIpRoute(self, "10.0.0.4", 32,
883 [VppRoutePath("0.0.0.0",
884 mpls_tun._sw_if_index,
885 labels=[33])])
886 route_10_0_0_4.add_vpp_config()
887
888 self.vapi.cli("clear trace")
889 tx = self.create_stream_ip4(self.pg0, "10.0.0.4")
890 self.pg0.add_stream(tx)
891
892 self.pg_enable_capture(self.pg_interfaces)
893 self.pg_start()
894
895 rx = self.pg0.get_capture()
Neale Ranns31ed7442018-02-23 05:29:09 -0800896 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
897 [VppMplsLabel(44),
898 VppMplsLabel(46),
899 VppMplsLabel(33, ttl=255)])
900
901 def test_tunnel_uniform(self):
902 """ MPLS Tunnel Tests - Uniform """
903
904 #
905 # Create a tunnel with a single out label
906 # The label stack is specified here from outer to inner
907 #
908 mpls_tun = VppMPLSTunnelInterface(
909 self,
910 [VppRoutePath(self.pg0.remote_ip4,
911 self.pg0.sw_if_index,
912 labels=[VppMplsLabel(44, ttl=32),
913 VppMplsLabel(46, MplsLspMode.UNIFORM)])])
914 mpls_tun.add_vpp_config()
915 mpls_tun.admin_up()
916
917 #
918 # add an unlabelled route through the new tunnel
919 #
920 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
921 [VppRoutePath("0.0.0.0",
922 mpls_tun._sw_if_index)])
923 route_10_0_0_3.add_vpp_config()
924
925 self.vapi.cli("clear trace")
926 tx = self.create_stream_ip4(self.pg0, "10.0.0.3", ip_ttl=24)
927 self.pg0.add_stream(tx)
928
929 self.pg_enable_capture(self.pg_interfaces)
930 self.pg_start()
931
932 rx = self.pg0.get_capture()
933 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
934 [VppMplsLabel(44, ttl=32),
935 VppMplsLabel(46, ttl=23)])
936
937 #
938 # add a labelled route through the new tunnel
939 #
940 route_10_0_0_4 = VppIpRoute(
941 self, "10.0.0.4", 32,
942 [VppRoutePath("0.0.0.0",
943 mpls_tun._sw_if_index,
944 labels=[VppMplsLabel(33, ttl=47)])])
945 route_10_0_0_4.add_vpp_config()
946
947 self.vapi.cli("clear trace")
948 tx = self.create_stream_ip4(self.pg0, "10.0.0.4")
949 self.pg0.add_stream(tx)
950
951 self.pg_enable_capture(self.pg_interfaces)
952 self.pg_start()
953
954 rx = self.pg0.get_capture()
955 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
956 [VppMplsLabel(44, ttl=32),
957 VppMplsLabel(46, ttl=47),
958 VppMplsLabel(33, ttl=47)])
Neale Ranns8c4611b2017-05-23 03:43:47 -0700959
Neale Rannsf5fa5ae2018-09-26 05:07:25 -0700960 def test_mpls_tunnel_many(self):
961 """ Multiple Tunnels """
962
963 for ii in range(10):
964 mpls_tun = VppMPLSTunnelInterface(
965 self,
966 [VppRoutePath(self.pg0.remote_ip4,
967 self.pg0.sw_if_index,
968 labels=[VppMplsLabel(44, ttl=32),
969 VppMplsLabel(46, MplsLspMode.UNIFORM)])])
970 mpls_tun.add_vpp_config()
971 mpls_tun.admin_up()
972
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000973 def test_v4_exp_null(self):
974 """ MPLS V4 Explicit NULL test """
975
976 #
977 # The first test case has an MPLS TTL of 0
978 # all packet should be dropped
979 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800980 tx = self.create_stream_labelled_ip4(self.pg0,
981 [VppMplsLabel(0, ttl=0)])
982 self.send_and_assert_no_replies(self.pg0, tx,
983 "MPLS TTL=0 packets forwarded")
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000984
985 #
986 # a stream with a non-zero MPLS TTL
987 # PG0 is in the default table
988 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800989 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(0)])
990 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000991 self.verify_capture_ip4(self.pg0, rx, tx)
992
993 #
994 # a stream with a non-zero MPLS TTL
995 # PG1 is in table 1
996 # we are ensuring the post-pop lookup occurs in the VRF table
997 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800998 tx = self.create_stream_labelled_ip4(self.pg1, [VppMplsLabel(0)])
999 rx = self.send_and_expect(self.pg1, tx, self.pg1)
1000 self.verify_capture_ip4(self.pg1, rx, tx)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001001
1002 def test_v6_exp_null(self):
1003 """ MPLS V6 Explicit NULL test """
1004
1005 #
1006 # a stream with a non-zero MPLS TTL
1007 # PG0 is in the default table
1008 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001009 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(2)])
1010 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001011 self.verify_capture_ip6(self.pg0, rx, tx)
1012
1013 #
1014 # a stream with a non-zero MPLS TTL
1015 # PG1 is in table 1
1016 # we are ensuring the post-pop lookup occurs in the VRF table
1017 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001018 tx = self.create_stream_labelled_ip6(self.pg1, [VppMplsLabel(2)])
1019 rx = self.send_and_expect(self.pg1, tx, self.pg1)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001020 self.verify_capture_ip6(self.pg0, rx, tx)
1021
Neale Rannscb630ff2016-12-14 13:31:29 +01001022 def test_deag(self):
1023 """ MPLS Deagg """
1024
1025 #
1026 # A de-agg route - next-hop lookup in default table
1027 #
Neale Ranns5a8123b2017-01-26 01:18:23 -08001028 route_34_eos = VppMplsRoute(self, 34, 1,
1029 [VppRoutePath("0.0.0.0",
1030 0xffffffff,
1031 nh_table_id=0)])
Neale Rannscb630ff2016-12-14 13:31:29 +01001032 route_34_eos.add_vpp_config()
1033
1034 #
1035 # ping an interface in the default table
1036 # PG0 is in the default table
1037 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001038 tx = self.create_stream_labelled_ip4(self.pg0,
1039 [VppMplsLabel(34)],
1040 ping=1,
Neale Rannscb630ff2016-12-14 13:31:29 +01001041 ip_itf=self.pg0)
Neale Ranns31ed7442018-02-23 05:29:09 -08001042 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Rannscb630ff2016-12-14 13:31:29 +01001043 self.verify_capture_ip4(self.pg0, rx, tx, ping_resp=1)
1044
1045 #
1046 # A de-agg route - next-hop lookup in non-default table
1047 #
Neale Ranns5a8123b2017-01-26 01:18:23 -08001048 route_35_eos = VppMplsRoute(self, 35, 1,
1049 [VppRoutePath("0.0.0.0",
1050 0xffffffff,
1051 nh_table_id=1)])
Neale Rannscb630ff2016-12-14 13:31:29 +01001052 route_35_eos.add_vpp_config()
1053
1054 #
1055 # ping an interface in the non-default table
1056 # PG0 is in the default table. packet arrive labelled in the
1057 # default table and egress unlabelled in the non-default
1058 #
Klement Sekeradab231a2016-12-21 08:50:14 +01001059 tx = self.create_stream_labelled_ip4(
Neale Ranns31ed7442018-02-23 05:29:09 -08001060 self.pg0, [VppMplsLabel(35)], ping=1, ip_itf=self.pg1)
1061 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Rannscb630ff2016-12-14 13:31:29 +01001062 self.verify_capture_ip4(self.pg1, rx, tx, ping_resp=1)
1063
Neale Ranns6af1c042017-05-26 03:48:53 -07001064 #
1065 # Double pop
1066 #
1067 route_36_neos = VppMplsRoute(self, 36, 0,
1068 [VppRoutePath("0.0.0.0",
1069 0xffffffff)])
1070 route_36_neos.add_vpp_config()
1071
Neale Ranns31ed7442018-02-23 05:29:09 -08001072 tx = self.create_stream_labelled_ip4(self.pg0,
1073 [VppMplsLabel(36),
1074 VppMplsLabel(35)],
Neale Ranns6af1c042017-05-26 03:48:53 -07001075 ping=1, ip_itf=self.pg1)
Neale Ranns31ed7442018-02-23 05:29:09 -08001076 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns6af1c042017-05-26 03:48:53 -07001077 self.verify_capture_ip4(self.pg1, rx, tx, ping_resp=1)
1078
1079 route_36_neos.remove_vpp_config()
Neale Rannscb630ff2016-12-14 13:31:29 +01001080 route_35_eos.remove_vpp_config()
1081 route_34_eos.remove_vpp_config()
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001082
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001083 def test_interface_rx(self):
1084 """ MPLS Interface Receive """
1085
1086 #
1087 # Add a non-recursive route that will forward the traffic
1088 # post-interface-rx
1089 #
1090 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
1091 table_id=1,
1092 paths=[VppRoutePath(self.pg1.remote_ip4,
1093 self.pg1.sw_if_index)])
1094 route_10_0_0_1.add_vpp_config()
1095
1096 #
1097 # An interface receive label that maps traffic to RX on interface
1098 # pg1
1099 # by injecting the packet in on pg0, which is in table 0
1100 # doing an interface-rx on pg1 and matching a route in table 1
1101 # if the packet egresses, then we must have swapped to pg1
1102 # so as to have matched the route in table 1
1103 #
1104 route_34_eos = VppMplsRoute(self, 34, 1,
1105 [VppRoutePath("0.0.0.0",
1106 self.pg1.sw_if_index,
1107 is_interface_rx=1)])
1108 route_34_eos.add_vpp_config()
1109
1110 #
1111 # ping an interface in the default table
1112 # PG0 is in the default table
1113 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001114 tx = self.create_stream_labelled_ip4(self.pg0,
1115 [VppMplsLabel(34)],
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001116 dst_ip="10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -08001117 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001118 self.verify_capture_ip4(self.pg1, rx, tx)
1119
1120 def test_mcast_mid_point(self):
1121 """ MPLS Multicast Mid Point """
1122
1123 #
1124 # Add a non-recursive route that will forward the traffic
1125 # post-interface-rx
1126 #
1127 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
1128 table_id=1,
1129 paths=[VppRoutePath(self.pg1.remote_ip4,
1130 self.pg1.sw_if_index)])
1131 route_10_0_0_1.add_vpp_config()
1132
1133 #
1134 # Add a mcast entry that replicate to pg2 and pg3
1135 # and replicate to a interface-rx (like a bud node would)
1136 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001137 route_3400_eos = VppMplsRoute(
1138 self, 3400, 1,
1139 [VppRoutePath(self.pg2.remote_ip4,
1140 self.pg2.sw_if_index,
1141 labels=[VppMplsLabel(3401)]),
1142 VppRoutePath(self.pg3.remote_ip4,
1143 self.pg3.sw_if_index,
1144 labels=[VppMplsLabel(3402)]),
1145 VppRoutePath("0.0.0.0",
1146 self.pg1.sw_if_index,
1147 is_interface_rx=1)],
1148 is_multicast=1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001149 route_3400_eos.add_vpp_config()
1150
1151 #
1152 # ping an interface in the default table
1153 # PG0 is in the default table
1154 #
1155 self.vapi.cli("clear trace")
Neale Ranns31ed7442018-02-23 05:29:09 -08001156 tx = self.create_stream_labelled_ip4(self.pg0,
1157 [VppMplsLabel(3400, ttl=64)],
1158 n=257,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001159 dst_ip="10.0.0.1")
1160 self.pg0.add_stream(tx)
1161
1162 self.pg_enable_capture(self.pg_interfaces)
1163 self.pg_start()
1164
1165 rx = self.pg1.get_capture(257)
1166 self.verify_capture_ip4(self.pg1, rx, tx)
1167
1168 rx = self.pg2.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001169 self.verify_capture_labelled(self.pg2, rx, tx,
1170 [VppMplsLabel(3401, ttl=63)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001171 rx = self.pg3.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001172 self.verify_capture_labelled(self.pg3, rx, tx,
1173 [VppMplsLabel(3402, ttl=63)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001174
1175 def test_mcast_head(self):
1176 """ MPLS Multicast Head-end """
1177
1178 #
1179 # Create a multicast tunnel with two replications
1180 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001181 mpls_tun = VppMPLSTunnelInterface(
1182 self,
1183 [VppRoutePath(self.pg2.remote_ip4,
1184 self.pg2.sw_if_index,
1185 labels=[VppMplsLabel(42)]),
1186 VppRoutePath(self.pg3.remote_ip4,
1187 self.pg3.sw_if_index,
1188 labels=[VppMplsLabel(43)])],
1189 is_multicast=1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001190 mpls_tun.add_vpp_config()
1191 mpls_tun.admin_up()
1192
1193 #
1194 # add an unlabelled route through the new tunnel
1195 #
1196 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
1197 [VppRoutePath("0.0.0.0",
1198 mpls_tun._sw_if_index)])
1199 route_10_0_0_3.add_vpp_config()
1200
1201 self.vapi.cli("clear trace")
1202 tx = self.create_stream_ip4(self.pg0, "10.0.0.3")
1203 self.pg0.add_stream(tx)
1204
1205 self.pg_enable_capture(self.pg_interfaces)
1206 self.pg_start()
1207
1208 rx = self.pg2.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001209 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(42)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001210 rx = self.pg3.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001211 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(43)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001212
1213 #
1214 # An an IP multicast route via the tunnel
1215 # A (*,G).
1216 # one accepting interface, pg0, 1 forwarding interface via the tunnel
1217 #
1218 route_232_1_1_1 = VppIpMRoute(
1219 self,
1220 "0.0.0.0",
1221 "232.1.1.1", 32,
1222 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
1223 [VppMRoutePath(self.pg0.sw_if_index,
1224 MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
1225 VppMRoutePath(mpls_tun._sw_if_index,
1226 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
1227 route_232_1_1_1.add_vpp_config()
1228
1229 self.vapi.cli("clear trace")
1230 tx = self.create_stream_ip4(self.pg0, "232.1.1.1")
1231 self.pg0.add_stream(tx)
1232
1233 self.pg_enable_capture(self.pg_interfaces)
1234 self.pg_start()
1235
1236 rx = self.pg2.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001237 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(42)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001238 rx = self.pg3.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001239 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(43)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001240
Neale Ranns31426c62017-05-24 10:32:58 -07001241 def test_mcast_ip4_tail(self):
1242 """ MPLS IPv4 Multicast Tail """
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001243
1244 #
1245 # Add a multicast route that will forward the traffic
1246 # post-disposition
1247 #
1248 route_232_1_1_1 = VppIpMRoute(
1249 self,
1250 "0.0.0.0",
1251 "232.1.1.1", 32,
1252 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
1253 table_id=1,
1254 paths=[VppMRoutePath(self.pg1.sw_if_index,
1255 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
1256 route_232_1_1_1.add_vpp_config()
1257
1258 #
1259 # An interface receive label that maps traffic to RX on interface
1260 # pg1
1261 # by injecting the packet in on pg0, which is in table 0
1262 # doing an rpf-id and matching a route in table 1
1263 # if the packet egresses, then we must have matched the route in
1264 # table 1
1265 #
1266 route_34_eos = VppMplsRoute(self, 34, 1,
1267 [VppRoutePath("0.0.0.0",
1268 self.pg1.sw_if_index,
1269 nh_table_id=1,
1270 rpf_id=55)],
1271 is_multicast=1)
1272
1273 route_34_eos.add_vpp_config()
1274
1275 #
1276 # Drop due to interface lookup miss
1277 #
1278 self.vapi.cli("clear trace")
Neale Ranns31ed7442018-02-23 05:29:09 -08001279 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001280 dst_ip="232.1.1.1", n=1)
1281 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop none")
1282
1283 #
1284 # set the RPF-ID of the enrtry to match the input packet's
1285 #
1286 route_232_1_1_1.update_rpf_id(55)
1287
Neale Ranns31ed7442018-02-23 05:29:09 -08001288 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
1289 dst_ip="232.1.1.1")
1290 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001291 self.verify_capture_ip4(self.pg1, rx, tx)
1292
1293 #
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001294 # disposed packets have an invalid IPv4 checkusm
1295 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001296 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001297 dst_ip="232.1.1.1", n=65,
1298 chksum=1)
1299 self.send_and_assert_no_replies(self.pg0, tx, "Invalid Checksum")
1300
1301 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001302 # set the RPF-ID of the entry to not match the input packet's
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001303 #
1304 route_232_1_1_1.update_rpf_id(56)
Neale Ranns31ed7442018-02-23 05:29:09 -08001305 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001306 dst_ip="232.1.1.1")
1307 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop 56")
1308
Neale Ranns31426c62017-05-24 10:32:58 -07001309 def test_mcast_ip6_tail(self):
1310 """ MPLS IPv6 Multicast Tail """
1311
1312 #
1313 # Add a multicast route that will forward the traffic
1314 # post-disposition
1315 #
1316 route_ff = VppIpMRoute(
1317 self,
1318 "::",
1319 "ff01::1", 32,
1320 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
1321 table_id=1,
1322 paths=[VppMRoutePath(self.pg1.sw_if_index,
1323 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)],
1324 is_ip6=1)
1325 route_ff.add_vpp_config()
1326
1327 #
1328 # An interface receive label that maps traffic to RX on interface
1329 # pg1
1330 # by injecting the packet in on pg0, which is in table 0
1331 # doing an rpf-id and matching a route in table 1
1332 # if the packet egresses, then we must have matched the route in
1333 # table 1
1334 #
1335 route_34_eos = VppMplsRoute(
1336 self, 34, 1,
1337 [VppRoutePath("::",
1338 self.pg1.sw_if_index,
1339 nh_table_id=1,
1340 rpf_id=55,
Neale Rannsda78f952017-05-24 09:15:43 -07001341 proto=DpoProto.DPO_PROTO_IP6)],
Neale Ranns31426c62017-05-24 10:32:58 -07001342 is_multicast=1)
1343
1344 route_34_eos.add_vpp_config()
1345
1346 #
1347 # Drop due to interface lookup miss
1348 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001349 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(34)],
Neale Ranns31426c62017-05-24 10:32:58 -07001350 dst_ip="ff01::1")
Neale Ranns31ed7442018-02-23 05:29:09 -08001351 self.send_and_assert_no_replies(self.pg0, tx, "RPF Miss")
Neale Ranns31426c62017-05-24 10:32:58 -07001352
1353 #
1354 # set the RPF-ID of the enrtry to match the input packet's
1355 #
1356 route_ff.update_rpf_id(55)
1357
Neale Ranns31ed7442018-02-23 05:29:09 -08001358 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(34)],
Neale Ranns31426c62017-05-24 10:32:58 -07001359 dst_ip="ff01::1")
Neale Ranns31ed7442018-02-23 05:29:09 -08001360 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns31426c62017-05-24 10:32:58 -07001361 self.verify_capture_ip6(self.pg1, rx, tx)
1362
1363 #
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001364 # disposed packets have hop-limit = 1
1365 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001366 tx = self.create_stream_labelled_ip6(self.pg0,
1367 [VppMplsLabel(34)],
1368 dst_ip="ff01::1",
1369 hlim=1)
1370 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns52fae862018-01-08 04:41:42 -08001371 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001372
1373 #
Neale Ranns31426c62017-05-24 10:32:58 -07001374 # set the RPF-ID of the enrtry to not match the input packet's
1375 #
1376 route_ff.update_rpf_id(56)
Neale Ranns31ed7442018-02-23 05:29:09 -08001377 tx = self.create_stream_labelled_ip6(self.pg0,
1378 [VppMplsLabel(34)],
Neale Ranns31426c62017-05-24 10:32:58 -07001379 dst_ip="ff01::1")
1380 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop 56")
1381
Neale Ranns180279b2017-03-16 15:49:09 -04001382
1383class TestMPLSDisabled(VppTestCase):
1384 """ MPLS disabled """
1385
1386 def setUp(self):
1387 super(TestMPLSDisabled, self).setUp()
1388
1389 # create 2 pg interfaces
1390 self.create_pg_interfaces(range(2))
1391
Neale Ranns15002542017-09-10 04:39:11 -07001392 self.tbl = VppMplsTable(self, 0)
1393 self.tbl.add_vpp_config()
1394
Neale Ranns180279b2017-03-16 15:49:09 -04001395 # PG0 is MPLS enalbed
1396 self.pg0.admin_up()
1397 self.pg0.config_ip4()
1398 self.pg0.resolve_arp()
1399 self.pg0.enable_mpls()
1400
1401 # PG 1 is not MPLS enabled
1402 self.pg1.admin_up()
1403
1404 def tearDown(self):
Neale Ranns180279b2017-03-16 15:49:09 -04001405 for i in self.pg_interfaces:
1406 i.unconfig_ip4()
1407 i.admin_down()
1408
Neale Ranns15002542017-09-10 04:39:11 -07001409 self.pg0.disable_mpls()
1410 super(TestMPLSDisabled, self).tearDown()
1411
Neale Ranns180279b2017-03-16 15:49:09 -04001412 def test_mpls_disabled(self):
1413 """ MPLS Disabled """
1414
1415 tx = (Ether(src=self.pg1.remote_mac,
1416 dst=self.pg1.local_mac) /
1417 MPLS(label=32, ttl=64) /
1418 IPv6(src="2001::1", dst=self.pg0.remote_ip6) /
1419 UDP(sport=1234, dport=1234) /
1420 Raw('\xa5' * 100))
1421
1422 #
1423 # A simple MPLS xconnect - eos label in label out
1424 #
1425 route_32_eos = VppMplsRoute(self, 32, 1,
1426 [VppRoutePath(self.pg0.remote_ip4,
1427 self.pg0.sw_if_index,
1428 labels=[33])])
1429 route_32_eos.add_vpp_config()
1430
1431 #
1432 # PG1 does not forward IP traffic
1433 #
1434 self.send_and_assert_no_replies(self.pg1, tx, "MPLS disabled")
1435
1436 #
1437 # MPLS enable PG1
1438 #
1439 self.pg1.enable_mpls()
1440
1441 #
1442 # Now we get packets through
1443 #
1444 self.pg1.add_stream(tx)
1445 self.pg_enable_capture(self.pg_interfaces)
1446 self.pg_start()
1447
1448 rx = self.pg0.get_capture(1)
1449
1450 #
1451 # Disable PG1
1452 #
1453 self.pg1.disable_mpls()
1454
1455 #
1456 # PG1 does not forward IP traffic
1457 #
1458 self.send_and_assert_no_replies(self.pg1, tx, "IPv6 disabled")
1459 self.send_and_assert_no_replies(self.pg1, tx, "IPv6 disabled")
1460
1461
Neale Rannsf12a83f2017-04-18 09:09:40 -07001462class TestMPLSPIC(VppTestCase):
1463 """ MPLS PIC edge convergence """
1464
1465 def setUp(self):
1466 super(TestMPLSPIC, self).setUp()
1467
1468 # create 2 pg interfaces
1469 self.create_pg_interfaces(range(4))
1470
Neale Ranns15002542017-09-10 04:39:11 -07001471 mpls_tbl = VppMplsTable(self, 0)
1472 mpls_tbl.add_vpp_config()
1473 tbl4 = VppIpTable(self, 1)
1474 tbl4.add_vpp_config()
1475 tbl6 = VppIpTable(self, 1, is_ip6=1)
1476 tbl6.add_vpp_config()
1477
Neale Rannsf12a83f2017-04-18 09:09:40 -07001478 # core links
1479 self.pg0.admin_up()
1480 self.pg0.config_ip4()
1481 self.pg0.resolve_arp()
1482 self.pg0.enable_mpls()
1483 self.pg1.admin_up()
1484 self.pg1.config_ip4()
1485 self.pg1.resolve_arp()
1486 self.pg1.enable_mpls()
1487
1488 # VRF (customer facing) link
1489 self.pg2.admin_up()
1490 self.pg2.set_table_ip4(1)
1491 self.pg2.config_ip4()
1492 self.pg2.resolve_arp()
1493 self.pg2.set_table_ip6(1)
1494 self.pg2.config_ip6()
1495 self.pg2.resolve_ndp()
1496 self.pg3.admin_up()
1497 self.pg3.set_table_ip4(1)
1498 self.pg3.config_ip4()
1499 self.pg3.resolve_arp()
1500 self.pg3.set_table_ip6(1)
1501 self.pg3.config_ip6()
1502 self.pg3.resolve_ndp()
1503
1504 def tearDown(self):
Neale Rannsf12a83f2017-04-18 09:09:40 -07001505 self.pg0.disable_mpls()
Neale Ranns15002542017-09-10 04:39:11 -07001506 self.pg1.disable_mpls()
Neale Rannsf12a83f2017-04-18 09:09:40 -07001507 for i in self.pg_interfaces:
1508 i.unconfig_ip4()
1509 i.unconfig_ip6()
1510 i.set_table_ip4(0)
1511 i.set_table_ip6(0)
1512 i.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -07001513 super(TestMPLSPIC, self).tearDown()
Neale Rannsf12a83f2017-04-18 09:09:40 -07001514
1515 def test_mpls_ibgp_pic(self):
1516 """ MPLS iBGP PIC edge convergence
1517
1518 1) setup many iBGP VPN routes via a pair of iBGP peers.
1519 2) Check EMCP forwarding to these peers
1520 3) withdraw the IGP route to one of these peers.
1521 4) check forwarding continues to the remaining peer
1522 """
1523
1524 #
1525 # IGP+LDP core routes
1526 #
1527 core_10_0_0_45 = VppIpRoute(self, "10.0.0.45", 32,
1528 [VppRoutePath(self.pg0.remote_ip4,
1529 self.pg0.sw_if_index,
1530 labels=[45])])
1531 core_10_0_0_45.add_vpp_config()
1532
1533 core_10_0_0_46 = VppIpRoute(self, "10.0.0.46", 32,
1534 [VppRoutePath(self.pg1.remote_ip4,
1535 self.pg1.sw_if_index,
1536 labels=[46])])
1537 core_10_0_0_46.add_vpp_config()
1538
1539 #
1540 # Lot's of VPN routes. We need more the 64 so VPP will build
1541 # the fast convergence indirection
1542 #
1543 vpn_routes = []
1544 pkts = []
1545 for ii in range(64):
1546 dst = "192.168.1.%d" % ii
1547 vpn_routes.append(VppIpRoute(self, dst, 32,
1548 [VppRoutePath("10.0.0.45",
1549 0xffffffff,
1550 labels=[145],
1551 is_resolve_host=1),
1552 VppRoutePath("10.0.0.46",
1553 0xffffffff,
1554 labels=[146],
1555 is_resolve_host=1)],
1556 table_id=1))
1557 vpn_routes[ii].add_vpp_config()
1558
1559 pkts.append(Ether(dst=self.pg2.local_mac,
1560 src=self.pg2.remote_mac) /
1561 IP(src=self.pg2.remote_ip4, dst=dst) /
1562 UDP(sport=1234, dport=1234) /
1563 Raw('\xa5' * 100))
1564
1565 #
1566 # Send the packet stream (one pkt to each VPN route)
1567 # - expect a 50-50 split of the traffic
1568 #
1569 self.pg2.add_stream(pkts)
1570 self.pg_enable_capture(self.pg_interfaces)
1571 self.pg_start()
1572
1573 rx0 = self.pg0._get_capture(1)
1574 rx1 = self.pg1._get_capture(1)
1575
1576 # not testig the LB hashing algorithm so we're not concerned
1577 # with the split ratio, just as long as neither is 0
1578 self.assertNotEqual(0, len(rx0))
1579 self.assertNotEqual(0, len(rx1))
1580
1581 #
1582 # use a test CLI command to stop the FIB walk process, this
1583 # will prevent the FIB converging the VPN routes and thus allow
1584 # us to probe the interim (psot-fail, pre-converge) state
1585 #
1586 self.vapi.ppcli("test fib-walk-process disable")
1587
1588 #
1589 # Withdraw one of the IGP routes
1590 #
1591 core_10_0_0_46.remove_vpp_config()
1592
1593 #
1594 # now all packets should be forwarded through the remaining peer
1595 #
1596 self.vapi.ppcli("clear trace")
1597 self.pg2.add_stream(pkts)
1598 self.pg_enable_capture(self.pg_interfaces)
1599 self.pg_start()
1600
1601 rx0 = self.pg0.get_capture(len(pkts))
1602
1603 #
1604 # enable the FIB walk process to converge the FIB
1605 #
1606 self.vapi.ppcli("test fib-walk-process enable")
1607
1608 #
1609 # packets should still be forwarded through the remaining peer
1610 #
1611 self.pg2.add_stream(pkts)
1612 self.pg_enable_capture(self.pg_interfaces)
1613 self.pg_start()
1614
1615 rx0 = self.pg0.get_capture(64)
1616
1617 #
1618 # Add the IGP route back and we return to load-balancing
1619 #
1620 core_10_0_0_46.add_vpp_config()
1621
1622 self.pg2.add_stream(pkts)
1623 self.pg_enable_capture(self.pg_interfaces)
1624 self.pg_start()
1625
1626 rx0 = self.pg0._get_capture(1)
1627 rx1 = self.pg1._get_capture(1)
1628 self.assertNotEqual(0, len(rx0))
1629 self.assertNotEqual(0, len(rx1))
1630
1631 def test_mpls_ebgp_pic(self):
1632 """ MPLS eBGP PIC edge convergence
1633
1634 1) setup many eBGP VPN routes via a pair of eBGP peers
1635 2) Check EMCP forwarding to these peers
1636 3) withdraw one eBGP path - expect LB across remaining eBGP
1637 """
1638
1639 #
1640 # Lot's of VPN routes. We need more the 64 so VPP will build
1641 # the fast convergence indirection
1642 #
1643 vpn_routes = []
1644 vpn_bindings = []
1645 pkts = []
1646 for ii in range(64):
1647 dst = "192.168.1.%d" % ii
1648 local_label = 1600 + ii
1649 vpn_routes.append(VppIpRoute(self, dst, 32,
1650 [VppRoutePath(self.pg2.remote_ip4,
1651 0xffffffff,
1652 nh_table_id=1,
1653 is_resolve_attached=1),
1654 VppRoutePath(self.pg3.remote_ip4,
1655 0xffffffff,
1656 nh_table_id=1,
1657 is_resolve_attached=1)],
1658 table_id=1))
1659 vpn_routes[ii].add_vpp_config()
1660
1661 vpn_bindings.append(VppMplsIpBind(self, local_label, dst, 32,
1662 ip_table_id=1))
1663 vpn_bindings[ii].add_vpp_config()
1664
1665 pkts.append(Ether(dst=self.pg0.local_mac,
1666 src=self.pg0.remote_mac) /
1667 MPLS(label=local_label, ttl=64) /
1668 IP(src=self.pg0.remote_ip4, dst=dst) /
1669 UDP(sport=1234, dport=1234) /
1670 Raw('\xa5' * 100))
1671
1672 self.pg0.add_stream(pkts)
1673 self.pg_enable_capture(self.pg_interfaces)
1674 self.pg_start()
1675
1676 rx0 = self.pg2._get_capture(1)
1677 rx1 = self.pg3._get_capture(1)
1678 self.assertNotEqual(0, len(rx0))
1679 self.assertNotEqual(0, len(rx1))
1680
1681 #
1682 # use a test CLI command to stop the FIB walk process, this
1683 # will prevent the FIB converging the VPN routes and thus allow
1684 # us to probe the interim (psot-fail, pre-converge) state
1685 #
1686 self.vapi.ppcli("test fib-walk-process disable")
1687
1688 #
1689 # withdraw the connected prefix on the interface.
1690 #
1691 self.pg2.unconfig_ip4()
1692
1693 #
1694 # now all packets should be forwarded through the remaining peer
1695 #
1696 self.pg0.add_stream(pkts)
1697 self.pg_enable_capture(self.pg_interfaces)
1698 self.pg_start()
1699
1700 rx0 = self.pg3.get_capture(len(pkts))
1701
1702 #
1703 # enable the FIB walk process to converge the FIB
1704 #
1705 self.vapi.ppcli("test fib-walk-process enable")
1706 self.pg0.add_stream(pkts)
1707 self.pg_enable_capture(self.pg_interfaces)
1708 self.pg_start()
1709
1710 rx0 = self.pg3.get_capture(len(pkts))
1711
1712 #
1713 # put the connecteds back
1714 #
1715 self.pg2.config_ip4()
1716
1717 self.pg0.add_stream(pkts)
1718 self.pg_enable_capture(self.pg_interfaces)
1719 self.pg_start()
1720
1721 rx0 = self.pg2._get_capture(1)
1722 rx1 = self.pg3._get_capture(1)
1723 self.assertNotEqual(0, len(rx0))
1724 self.assertNotEqual(0, len(rx1))
1725
1726 def test_mpls_v6_ebgp_pic(self):
1727 """ MPLSv6 eBGP PIC edge convergence
1728
1729 1) setup many eBGP VPNv6 routes via a pair of eBGP peers
1730 2) Check EMCP forwarding to these peers
1731 3) withdraw one eBGP path - expect LB across remaining eBGP
1732 """
1733
1734 #
1735 # Lot's of VPN routes. We need more the 64 so VPP will build
1736 # the fast convergence indirection
1737 #
1738 vpn_routes = []
1739 vpn_bindings = []
1740 pkts = []
1741 for ii in range(64):
1742 dst = "3000::%d" % ii
1743 local_label = 1600 + ii
Neale Rannsda78f952017-05-24 09:15:43 -07001744 vpn_routes.append(VppIpRoute(
1745 self, dst, 128,
1746 [VppRoutePath(self.pg2.remote_ip6,
1747 0xffffffff,
1748 nh_table_id=1,
1749 is_resolve_attached=1,
1750 proto=DpoProto.DPO_PROTO_IP6),
1751 VppRoutePath(self.pg3.remote_ip6,
1752 0xffffffff,
1753 nh_table_id=1,
1754 proto=DpoProto.DPO_PROTO_IP6,
1755 is_resolve_attached=1)],
1756 table_id=1,
1757 is_ip6=1))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001758 vpn_routes[ii].add_vpp_config()
1759
1760 vpn_bindings.append(VppMplsIpBind(self, local_label, dst, 128,
1761 ip_table_id=1,
1762 is_ip6=1))
1763 vpn_bindings[ii].add_vpp_config()
1764
1765 pkts.append(Ether(dst=self.pg0.local_mac,
1766 src=self.pg0.remote_mac) /
1767 MPLS(label=local_label, ttl=64) /
1768 IPv6(src=self.pg0.remote_ip6, dst=dst) /
1769 UDP(sport=1234, dport=1234) /
1770 Raw('\xa5' * 100))
1771
1772 self.pg0.add_stream(pkts)
1773 self.pg_enable_capture(self.pg_interfaces)
1774 self.pg_start()
1775
1776 rx0 = self.pg2._get_capture(1)
1777 rx1 = self.pg3._get_capture(1)
1778 self.assertNotEqual(0, len(rx0))
1779 self.assertNotEqual(0, len(rx1))
1780
1781 #
1782 # use a test CLI command to stop the FIB walk process, this
1783 # will prevent the FIB converging the VPN routes and thus allow
1784 # us to probe the interim (psot-fail, pre-converge) state
1785 #
1786 self.vapi.ppcli("test fib-walk-process disable")
1787
1788 #
1789 # withdraw the connected prefix on the interface.
1790 # and shutdown the interface so the ND cache is flushed.
1791 #
1792 self.pg2.unconfig_ip6()
1793 self.pg2.admin_down()
1794
1795 #
1796 # now all packets should be forwarded through the remaining peer
1797 #
1798 self.pg0.add_stream(pkts)
1799 self.pg_enable_capture(self.pg_interfaces)
1800 self.pg_start()
1801
1802 rx0 = self.pg3.get_capture(len(pkts))
1803
1804 #
1805 # enable the FIB walk process to converge the FIB
1806 #
1807 self.vapi.ppcli("test fib-walk-process enable")
1808 self.pg0.add_stream(pkts)
1809 self.pg_enable_capture(self.pg_interfaces)
1810 self.pg_start()
1811
1812 rx0 = self.pg3.get_capture(len(pkts))
1813
1814 #
1815 # put the connecteds back
1816 #
1817 self.pg2.admin_up()
1818 self.pg2.config_ip6()
1819
1820 self.pg0.add_stream(pkts)
1821 self.pg_enable_capture(self.pg_interfaces)
1822 self.pg_start()
1823
1824 rx0 = self.pg2._get_capture(1)
1825 rx1 = self.pg3._get_capture(1)
1826 self.assertNotEqual(0, len(rx0))
1827 self.assertNotEqual(0, len(rx1))
1828
1829
Neale Rannsda78f952017-05-24 09:15:43 -07001830class TestMPLSL2(VppTestCase):
1831 """ MPLS-L2 """
1832
1833 def setUp(self):
1834 super(TestMPLSL2, self).setUp()
1835
1836 # create 2 pg interfaces
1837 self.create_pg_interfaces(range(2))
1838
Neale Ranns15002542017-09-10 04:39:11 -07001839 # create the default MPLS table
1840 self.tables = []
1841 tbl = VppMplsTable(self, 0)
1842 tbl.add_vpp_config()
1843 self.tables.append(tbl)
1844
Neale Rannsda78f952017-05-24 09:15:43 -07001845 # use pg0 as the core facing interface
1846 self.pg0.admin_up()
1847 self.pg0.config_ip4()
1848 self.pg0.resolve_arp()
1849 self.pg0.enable_mpls()
1850
Neale Ranns15002542017-09-10 04:39:11 -07001851 # use the other 2 for customer facing L2 links
Neale Rannsda78f952017-05-24 09:15:43 -07001852 for i in self.pg_interfaces[1:]:
1853 i.admin_up()
1854
1855 def tearDown(self):
Neale Rannsda78f952017-05-24 09:15:43 -07001856 for i in self.pg_interfaces[1:]:
1857 i.admin_down()
1858
1859 self.pg0.disable_mpls()
1860 self.pg0.unconfig_ip4()
1861 self.pg0.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -07001862 super(TestMPLSL2, self).tearDown()
Neale Rannsda78f952017-05-24 09:15:43 -07001863
Neale Ranns31ed7442018-02-23 05:29:09 -08001864 def verify_capture_tunneled_ethernet(self, capture, sent, mpls_labels):
Neale Rannsda78f952017-05-24 09:15:43 -07001865 capture = verify_filter(capture, sent)
1866
1867 self.assertEqual(len(capture), len(sent))
1868
1869 for i in range(len(capture)):
1870 tx = sent[i]
1871 rx = capture[i]
1872
1873 # the MPLS TTL is 255 since it enters a new tunnel
Neale Ranns31ed7442018-02-23 05:29:09 -08001874 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsda78f952017-05-24 09:15:43 -07001875
1876 tx_eth = tx[Ether]
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -07001877 rx_eth = Ether(scapy.compat.raw(rx[MPLS].payload))
Neale Rannsda78f952017-05-24 09:15:43 -07001878
1879 self.assertEqual(rx_eth.src, tx_eth.src)
1880 self.assertEqual(rx_eth.dst, tx_eth.dst)
1881
1882 def test_vpws(self):
1883 """ Virtual Private Wire Service """
1884
1885 #
1886 # Create an MPLS tunnel that pushes 1 label
Neale Ranns31ed7442018-02-23 05:29:09 -08001887 # For Ethernet over MPLS the uniform mode is irrelevant since ttl/cos
1888 # information is not in the packet, but we test it works anyway
Neale Rannsda78f952017-05-24 09:15:43 -07001889 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001890 mpls_tun_1 = VppMPLSTunnelInterface(
1891 self,
1892 [VppRoutePath(self.pg0.remote_ip4,
1893 self.pg0.sw_if_index,
1894 labels=[VppMplsLabel(42, MplsLspMode.UNIFORM)])],
1895 is_l2=1)
Neale Rannsda78f952017-05-24 09:15:43 -07001896 mpls_tun_1.add_vpp_config()
1897 mpls_tun_1.admin_up()
1898
1899 #
1900 # Create a label entry to for 55 that does L2 input to the tunnel
1901 #
1902 route_55_eos = VppMplsRoute(
1903 self, 55, 1,
1904 [VppRoutePath("0.0.0.0",
1905 mpls_tun_1.sw_if_index,
1906 is_interface_rx=1,
1907 proto=DpoProto.DPO_PROTO_ETHERNET)])
1908 route_55_eos.add_vpp_config()
1909
1910 #
1911 # Cross-connect the tunnel with one of the customers L2 interfaces
1912 #
1913 self.vapi.sw_interface_set_l2_xconnect(self.pg1.sw_if_index,
1914 mpls_tun_1.sw_if_index,
1915 enable=1)
1916 self.vapi.sw_interface_set_l2_xconnect(mpls_tun_1.sw_if_index,
1917 self.pg1.sw_if_index,
1918 enable=1)
1919
1920 #
1921 # inject a packet from the core
1922 #
1923 pcore = (Ether(dst=self.pg0.local_mac,
1924 src=self.pg0.remote_mac) /
1925 MPLS(label=55, ttl=64) /
1926 Ether(dst="00:00:de:ad:ba:be",
1927 src="00:00:de:ad:be:ef") /
1928 IP(src="10.10.10.10", dst="11.11.11.11") /
1929 UDP(sport=1234, dport=1234) /
1930 Raw('\xa5' * 100))
1931
Neale Ranns31ed7442018-02-23 05:29:09 -08001932 tx0 = pcore * 65
1933 rx0 = self.send_and_expect(self.pg0, tx0, self.pg1)
1934 payload = pcore[MPLS].payload
Neale Rannsda78f952017-05-24 09:15:43 -07001935
Neale Ranns31ed7442018-02-23 05:29:09 -08001936 self.assertEqual(rx0[0][Ether].dst, payload[Ether].dst)
1937 self.assertEqual(rx0[0][Ether].src, payload[Ether].src)
Neale Rannsda78f952017-05-24 09:15:43 -07001938
1939 #
1940 # Inject a packet from the custoer/L2 side
1941 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001942 tx1 = pcore[MPLS].payload * 65
1943 rx1 = self.send_and_expect(self.pg1, tx1, self.pg0)
Neale Rannsda78f952017-05-24 09:15:43 -07001944
Neale Ranns31ed7442018-02-23 05:29:09 -08001945 self.verify_capture_tunneled_ethernet(rx1, tx1, [VppMplsLabel(42)])
Neale Rannsda78f952017-05-24 09:15:43 -07001946
1947 def test_vpls(self):
1948 """ Virtual Private LAN Service """
1949 #
1950 # Create an L2 MPLS tunnel
1951 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001952 mpls_tun = VppMPLSTunnelInterface(
1953 self,
1954 [VppRoutePath(self.pg0.remote_ip4,
1955 self.pg0.sw_if_index,
1956 labels=[VppMplsLabel(42)])],
1957 is_l2=1)
Neale Rannsda78f952017-05-24 09:15:43 -07001958 mpls_tun.add_vpp_config()
1959 mpls_tun.admin_up()
1960
1961 #
1962 # Create a label entry to for 55 that does L2 input to the tunnel
1963 #
1964 route_55_eos = VppMplsRoute(
1965 self, 55, 1,
1966 [VppRoutePath("0.0.0.0",
1967 mpls_tun.sw_if_index,
1968 is_interface_rx=1,
1969 proto=DpoProto.DPO_PROTO_ETHERNET)])
1970 route_55_eos.add_vpp_config()
1971
1972 #
1973 # add to tunnel to the customers bridge-domain
1974 #
Ole Troana5b2eec2019-03-11 19:23:25 +01001975 self.vapi.sw_interface_set_l2_bridge(
1976 rx_sw_if_index=mpls_tun.sw_if_index, bd_id=1)
1977 self.vapi.sw_interface_set_l2_bridge(
1978 rx_sw_if_index=self.pg1.sw_if_index, bd_id=1)
Neale Rannsda78f952017-05-24 09:15:43 -07001979
1980 #
1981 # Packet from the customer interface and from the core
1982 #
1983 p_cust = (Ether(dst="00:00:de:ad:ba:be",
1984 src="00:00:de:ad:be:ef") /
1985 IP(src="10.10.10.10", dst="11.11.11.11") /
1986 UDP(sport=1234, dport=1234) /
1987 Raw('\xa5' * 100))
1988 p_core = (Ether(src="00:00:de:ad:ba:be",
1989 dst="00:00:de:ad:be:ef") /
1990 IP(dst="10.10.10.10", src="11.11.11.11") /
1991 UDP(sport=1234, dport=1234) /
1992 Raw('\xa5' * 100))
1993
1994 #
1995 # The BD is learning, so send in one of each packet to learn
1996 #
1997 p_core_encap = (Ether(dst=self.pg0.local_mac,
1998 src=self.pg0.remote_mac) /
1999 MPLS(label=55, ttl=64) /
2000 p_core)
2001
2002 self.pg1.add_stream(p_cust)
2003 self.pg_enable_capture(self.pg_interfaces)
2004 self.pg_start()
2005 self.pg0.add_stream(p_core_encap)
2006 self.pg_enable_capture(self.pg_interfaces)
2007 self.pg_start()
2008
2009 # we've learnt this so expect it be be forwarded
2010 rx0 = self.pg1.get_capture(1)
2011
2012 self.assertEqual(rx0[0][Ether].dst, p_core[Ether].dst)
2013 self.assertEqual(rx0[0][Ether].src, p_core[Ether].src)
2014
2015 #
2016 # now a stream in each direction
2017 #
2018 self.pg1.add_stream(p_cust * 65)
2019 self.pg_enable_capture(self.pg_interfaces)
2020 self.pg_start()
2021
2022 rx0 = self.pg0.get_capture(65)
2023
Neale Ranns31ed7442018-02-23 05:29:09 -08002024 self.verify_capture_tunneled_ethernet(rx0, p_cust*65,
2025 [VppMplsLabel(42)])
Neale Rannsda78f952017-05-24 09:15:43 -07002026
2027 #
2028 # remove interfaces from customers bridge-domain
2029 #
Ole Troana5b2eec2019-03-11 19:23:25 +01002030 self.vapi.sw_interface_set_l2_bridge(
2031 rx_sw_if_index=mpls_tun.sw_if_index, bd_id=1, enable=0)
2032 self.vapi.sw_interface_set_l2_bridge(
2033 rx_sw_if_index=self.pg1.sw_if_index, bd_id=1, enable=0)
Neale Rannsda78f952017-05-24 09:15:43 -07002034
Neale Ranns8fe8cc22016-11-01 10:05:08 +00002035if __name__ == '__main__':
2036 unittest.main(testRunner=VppTestRunner)