blob: 33fed680dbeba797fae4e7267deae628a7fc4578 [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 Ranns5a8123b2017-01-26 01:18:23 -08007from vpp_ip_route import VppIpRoute, VppRoutePath, VppMplsRoute, \
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008 VppMplsIpBind, VppIpMRoute, VppMRoutePath, \
Neale Ranns31ed7442018-02-23 05:29:09 -08009 MRouteItfFlags, MRouteEntryFlags, DpoProto, VppIpTable, VppMplsTable, \
10 VppMplsLabel, MplsLspMode
Neale Ranns0f26c5a2017-03-01 15:12:11 -080011from vpp_mpls_tunnel_interface import VppMPLSTunnelInterface
Neale Ranns8fe8cc22016-11-01 10:05:08 +000012
13from scapy.packet import Raw
Klement Sekera7bb873a2016-11-18 07:38:42 +010014from scapy.layers.l2 import Ether
Neale Rannscb630ff2016-12-14 13:31:29 +010015from scapy.layers.inet import IP, UDP, ICMP
Neale Ranns62fe07c2017-10-31 12:28:22 -070016from scapy.layers.inet6 import IPv6, ICMPv6TimeExceeded
Neale Ranns8fe8cc22016-11-01 10:05:08 +000017from scapy.contrib.mpls import MPLS
18
Klement Sekeradab231a2016-12-21 08:50:14 +010019
Neale Rannsda78f952017-05-24 09:15:43 -070020def verify_filter(capture, sent):
21 if not len(capture) == len(sent):
22 # filter out any IPv6 RAs from the capture
23 for p in capture:
24 if p.haslayer(IPv6):
25 capture.remove(p)
26 return capture
27
28
Neale Ranns31ed7442018-02-23 05:29:09 -080029def verify_mpls_stack(tst, rx, mpls_labels):
Neale Rannsda78f952017-05-24 09:15:43 -070030 # the rx'd packet has the MPLS label popped
31 eth = rx[Ether]
32 tst.assertEqual(eth.type, 0x8847)
33
34 rx_mpls = rx[MPLS]
35
36 for ii in range(len(mpls_labels)):
Neale Ranns31ed7442018-02-23 05:29:09 -080037 tst.assertEqual(rx_mpls.label, mpls_labels[ii].value)
38 tst.assertEqual(rx_mpls.cos, mpls_labels[ii].exp)
39 tst.assertEqual(rx_mpls.ttl, mpls_labels[ii].ttl)
40
Neale Rannsda78f952017-05-24 09:15:43 -070041 if ii == len(mpls_labels) - 1:
42 tst.assertEqual(rx_mpls.s, 1)
43 else:
44 # not end of stack
45 tst.assertEqual(rx_mpls.s, 0)
46 # pop the label to expose the next
47 rx_mpls = rx_mpls[MPLS].payload
48
49
Neale Ranns8fe8cc22016-11-01 10:05:08 +000050class TestMPLS(VppTestCase):
51 """ MPLS Test Case """
52
Neale Ranns8fe8cc22016-11-01 10:05:08 +000053 def setUp(self):
54 super(TestMPLS, self).setUp()
55
56 # create 2 pg interfaces
Neale Ranns0f26c5a2017-03-01 15:12:11 -080057 self.create_pg_interfaces(range(4))
Neale Ranns8fe8cc22016-11-01 10:05:08 +000058
59 # setup both interfaces
60 # assign them different tables.
61 table_id = 0
Neale Ranns15002542017-09-10 04:39:11 -070062 self.tables = []
63
64 tbl = VppMplsTable(self, 0)
65 tbl.add_vpp_config()
66 self.tables.append(tbl)
Neale Ranns8fe8cc22016-11-01 10:05:08 +000067
68 for i in self.pg_interfaces:
69 i.admin_up()
Neale Ranns15002542017-09-10 04:39:11 -070070
71 if table_id != 0:
72 tbl = VppIpTable(self, table_id)
73 tbl.add_vpp_config()
74 self.tables.append(tbl)
75 tbl = VppIpTable(self, table_id, is_ip6=1)
76 tbl.add_vpp_config()
77 self.tables.append(tbl)
78
Neale Ranns8fe8cc22016-11-01 10:05:08 +000079 i.set_table_ip4(table_id)
80 i.set_table_ip6(table_id)
81 i.config_ip4()
Neale Ranns8fe8cc22016-11-01 10:05:08 +000082 i.resolve_arp()
Neale Rannsad422ed2016-11-02 14:20:04 +000083 i.config_ip6()
Neale Ranns8fe8cc22016-11-01 10:05:08 +000084 i.resolve_ndp()
Neale Rannsad422ed2016-11-02 14:20:04 +000085 i.enable_mpls()
Neale Ranns8fe8cc22016-11-01 10:05:08 +000086 table_id += 1
87
88 def tearDown(self):
Neale Ranns4008ac92017-02-13 23:20:04 -080089 for i in self.pg_interfaces:
90 i.unconfig_ip4()
91 i.unconfig_ip6()
92 i.ip6_disable()
Neale Ranns15002542017-09-10 04:39:11 -070093 i.set_table_ip4(0)
94 i.set_table_ip6(0)
95 i.disable_mpls()
Neale Ranns4008ac92017-02-13 23:20:04 -080096 i.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -070097 super(TestMPLS, self).tearDown()
Neale Ranns8fe8cc22016-11-01 10:05:08 +000098
Neale Rannsad422ed2016-11-02 14:20:04 +000099 # the default of 64 matches the IP packet TTL default
Klement Sekeradab231a2016-12-21 08:50:14 +0100100 def create_stream_labelled_ip4(
101 self,
102 src_if,
103 mpls_labels,
Klement Sekeradab231a2016-12-21 08:50:14 +0100104 ping=0,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800105 ip_itf=None,
106 dst_ip=None,
Neale Ranns4c7c8e52017-10-21 09:37:55 -0700107 chksum=None,
Neale Ranns31ed7442018-02-23 05:29:09 -0800108 ip_ttl=64,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800109 n=257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100110 self.reset_packet_infos()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000111 pkts = []
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800112 for i in range(0, n):
Klement Sekeradab231a2016-12-21 08:50:14 +0100113 info = self.create_packet_info(src_if, src_if)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000114 payload = self.info_to_payload(info)
Neale Rannsad422ed2016-11-02 14:20:04 +0000115 p = Ether(dst=src_if.local_mac, src=src_if.remote_mac)
116
117 for ii in range(len(mpls_labels)):
Neale Ranns31ed7442018-02-23 05:29:09 -0800118 p = p / MPLS(label=mpls_labels[ii].value,
119 ttl=mpls_labels[ii].ttl,
120 cos=mpls_labels[ii].exp)
Neale Rannscb630ff2016-12-14 13:31:29 +0100121 if not ping:
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800122 if not dst_ip:
Neale Ranns31ed7442018-02-23 05:29:09 -0800123 p = (p / IP(src=src_if.local_ip4,
124 dst=src_if.remote_ip4,
125 ttl=ip_ttl) /
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800126 UDP(sport=1234, dport=1234) /
127 Raw(payload))
128 else:
Neale Ranns31ed7442018-02-23 05:29:09 -0800129 p = (p / IP(src=src_if.local_ip4, dst=dst_ip, ttl=ip_ttl) /
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800130 UDP(sport=1234, dport=1234) /
131 Raw(payload))
Neale Rannscb630ff2016-12-14 13:31:29 +0100132 else:
133 p = (p / IP(src=ip_itf.remote_ip4,
Neale Ranns31ed7442018-02-23 05:29:09 -0800134 dst=ip_itf.local_ip4,
135 ttl=ip_ttl) /
Neale Rannscb630ff2016-12-14 13:31:29 +0100136 ICMP())
137
Neale Ranns4c7c8e52017-10-21 09:37:55 -0700138 if chksum:
139 p[IP].chksum = chksum
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000140 info.data = p.copy()
141 pkts.append(p)
142 return pkts
143
Neale Ranns31ed7442018-02-23 05:29:09 -0800144 def create_stream_ip4(self, src_if, dst_ip, ip_ttl=64, ip_dscp=0):
Klement Sekeradab231a2016-12-21 08:50:14 +0100145 self.reset_packet_infos()
Neale Rannsad422ed2016-11-02 14:20:04 +0000146 pkts = []
147 for i in range(0, 257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100148 info = self.create_packet_info(src_if, src_if)
Neale Rannsad422ed2016-11-02 14:20:04 +0000149 payload = self.info_to_payload(info)
150 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
Neale Ranns31ed7442018-02-23 05:29:09 -0800151 IP(src=src_if.remote_ip4, dst=dst_ip,
152 ttl=ip_ttl, tos=ip_dscp) /
Neale Rannsad422ed2016-11-02 14:20:04 +0000153 UDP(sport=1234, dport=1234) /
154 Raw(payload))
155 info.data = p.copy()
156 pkts.append(p)
157 return pkts
158
Neale Ranns31ed7442018-02-23 05:29:09 -0800159 def create_stream_ip6(self, src_if, dst_ip, ip_ttl=64, ip_dscp=0):
160 self.reset_packet_infos()
161 pkts = []
162 for i in range(0, 257):
163 info = self.create_packet_info(src_if, src_if)
164 payload = self.info_to_payload(info)
165 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
166 IPv6(src=src_if.remote_ip6, dst=dst_ip,
167 hlim=ip_ttl, tc=ip_dscp) /
168 UDP(sport=1234, dport=1234) /
169 Raw(payload))
170 info.data = p.copy()
171 pkts.append(p)
172 return pkts
173
174 def create_stream_labelled_ip6(self, src_if, mpls_labels,
175 hlim=64, dst_ip=None):
Neale Ranns31426c62017-05-24 10:32:58 -0700176 if dst_ip is None:
177 dst_ip = src_if.remote_ip6
Klement Sekeradab231a2016-12-21 08:50:14 +0100178 self.reset_packet_infos()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000179 pkts = []
180 for i in range(0, 257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100181 info = self.create_packet_info(src_if, src_if)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000182 payload = self.info_to_payload(info)
Neale Ranns31ed7442018-02-23 05:29:09 -0800183 p = Ether(dst=src_if.local_mac, src=src_if.remote_mac)
184 for l in mpls_labels:
185 p = p / MPLS(label=l.value, ttl=l.ttl, cos=l.exp)
186
187 p = p / (IPv6(src=src_if.remote_ip6, dst=dst_ip, hlim=hlim) /
188 UDP(sport=1234, dport=1234) /
189 Raw(payload))
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000190 info.data = p.copy()
191 pkts.append(p)
192 return pkts
193
Neale Ranns31ed7442018-02-23 05:29:09 -0800194 def verify_capture_ip4(self, src_if, capture, sent, ping_resp=0,
195 ip_ttl=None, ip_dscp=0):
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000196 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700197 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000198
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000199 self.assertEqual(len(capture), len(sent))
200
201 for i in range(len(capture)):
202 tx = sent[i]
203 rx = capture[i]
204
205 # the rx'd packet has the MPLS label popped
Neale Rannsad422ed2016-11-02 14:20:04 +0000206 eth = rx[Ether]
207 self.assertEqual(eth.type, 0x800)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000208
209 tx_ip = tx[IP]
210 rx_ip = rx[IP]
211
Neale Rannscb630ff2016-12-14 13:31:29 +0100212 if not ping_resp:
213 self.assertEqual(rx_ip.src, tx_ip.src)
214 self.assertEqual(rx_ip.dst, tx_ip.dst)
Neale Ranns31ed7442018-02-23 05:29:09 -0800215 self.assertEqual(rx_ip.tos, ip_dscp)
216 if not ip_ttl:
217 # IP processing post pop has decremented the TTL
218 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
219 else:
220 self.assertEqual(rx_ip.ttl, ip_ttl)
Neale Rannscb630ff2016-12-14 13:31:29 +0100221 else:
222 self.assertEqual(rx_ip.src, tx_ip.dst)
223 self.assertEqual(rx_ip.dst, tx_ip.src)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000224
225 except:
Neale Rannsad422ed2016-11-02 14:20:04 +0000226 raise
227
Neale Rannsad422ed2016-11-02 14:20:04 +0000228 def verify_capture_labelled_ip4(self, src_if, capture, sent,
Neale Ranns31ed7442018-02-23 05:29:09 -0800229 mpls_labels, ip_ttl=None):
Neale Rannsad422ed2016-11-02 14:20:04 +0000230 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700231 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000232
233 self.assertEqual(len(capture), len(sent))
234
235 for i in range(len(capture)):
236 tx = sent[i]
237 rx = capture[i]
238 tx_ip = tx[IP]
239 rx_ip = rx[IP]
240
Neale Ranns31ed7442018-02-23 05:29:09 -0800241 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsad422ed2016-11-02 14:20:04 +0000242
243 self.assertEqual(rx_ip.src, tx_ip.src)
244 self.assertEqual(rx_ip.dst, tx_ip.dst)
Neale Ranns31ed7442018-02-23 05:29:09 -0800245 if not ip_ttl:
246 # IP processing post pop has decremented the TTL
247 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
248 else:
249 self.assertEqual(rx_ip.ttl, ip_ttl)
Neale Rannsad422ed2016-11-02 14:20:04 +0000250
251 except:
252 raise
253
Neale Ranns31ed7442018-02-23 05:29:09 -0800254 def verify_capture_labelled_ip6(self, src_if, capture, sent,
255 mpls_labels, ip_ttl=None):
256 try:
257 capture = verify_filter(capture, sent)
258
259 self.assertEqual(len(capture), len(sent))
260
261 for i in range(len(capture)):
262 tx = sent[i]
263 rx = capture[i]
264 tx_ip = tx[IPv6]
265 rx_ip = rx[IPv6]
266
267 verify_mpls_stack(self, rx, mpls_labels)
268
269 self.assertEqual(rx_ip.src, tx_ip.src)
270 self.assertEqual(rx_ip.dst, tx_ip.dst)
271 if not ip_ttl:
272 # IP processing post pop has decremented the TTL
273 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
274 else:
275 self.assertEqual(rx_ip.hlim, ip_ttl)
276
277 except:
278 raise
279
280 def verify_capture_tunneled_ip4(self, src_if, capture, sent, mpls_labels):
Neale Rannsad422ed2016-11-02 14:20:04 +0000281 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700282 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000283
284 self.assertEqual(len(capture), len(sent))
285
286 for i in range(len(capture)):
287 tx = sent[i]
288 rx = capture[i]
289 tx_ip = tx[IP]
290 rx_ip = rx[IP]
291
Neale Ranns31ed7442018-02-23 05:29:09 -0800292 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsad422ed2016-11-02 14:20:04 +0000293
294 self.assertEqual(rx_ip.src, tx_ip.src)
295 self.assertEqual(rx_ip.dst, tx_ip.dst)
296 # IP processing post pop has decremented the TTL
297 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
298
299 except:
300 raise
301
302 def verify_capture_labelled(self, src_if, capture, sent,
Neale Ranns31ed7442018-02-23 05:29:09 -0800303 mpls_labels):
Neale Rannsad422ed2016-11-02 14:20:04 +0000304 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700305 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000306
307 self.assertEqual(len(capture), len(sent))
308
309 for i in range(len(capture)):
310 rx = capture[i]
Neale Ranns31ed7442018-02-23 05:29:09 -0800311 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsad422ed2016-11-02 14:20:04 +0000312 except:
313 raise
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000314
Neale Ranns31ed7442018-02-23 05:29:09 -0800315 def verify_capture_ip6(self, src_if, capture, sent,
316 ip_hlim=None, ip_dscp=0):
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000317 try:
318 self.assertEqual(len(capture), len(sent))
319
320 for i in range(len(capture)):
321 tx = sent[i]
322 rx = capture[i]
323
324 # the rx'd packet has the MPLS label popped
Neale Rannsad422ed2016-11-02 14:20:04 +0000325 eth = rx[Ether]
326 self.assertEqual(eth.type, 0x86DD)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000327
328 tx_ip = tx[IPv6]
329 rx_ip = rx[IPv6]
330
331 self.assertEqual(rx_ip.src, tx_ip.src)
332 self.assertEqual(rx_ip.dst, tx_ip.dst)
Neale Ranns31ed7442018-02-23 05:29:09 -0800333 self.assertEqual(rx_ip.tc, ip_dscp)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000334 # IP processing post pop has decremented the TTL
Neale Ranns31ed7442018-02-23 05:29:09 -0800335 if not ip_hlim:
336 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
337 else:
338 self.assertEqual(rx_ip.hlim, ip_hlim)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000339
340 except:
Neale Rannsad422ed2016-11-02 14:20:04 +0000341 raise
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000342
Neale Ranns62fe07c2017-10-31 12:28:22 -0700343 def verify_capture_ip6_icmp(self, src_if, capture, sent):
344 try:
345 self.assertEqual(len(capture), len(sent))
346
347 for i in range(len(capture)):
348 tx = sent[i]
349 rx = capture[i]
350
351 # the rx'd packet has the MPLS label popped
352 eth = rx[Ether]
353 self.assertEqual(eth.type, 0x86DD)
354
355 tx_ip = tx[IPv6]
356 rx_ip = rx[IPv6]
357
358 self.assertEqual(rx_ip.dst, tx_ip.src)
359 # ICMP sourced from the interface's address
360 self.assertEqual(rx_ip.src, src_if.local_ip6)
361 # hop-limit reset to 255 for IMCP packet
362 self.assertEqual(rx_ip.hlim, 254)
363
364 icmp = rx[ICMPv6TimeExceeded]
365
366 except:
367 raise
368
Neale Rannsad422ed2016-11-02 14:20:04 +0000369 def test_swap(self):
370 """ MPLS label swap tests """
371
372 #
373 # A simple MPLS xconnect - eos label in label out
374 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800375 route_32_eos = VppMplsRoute(self, 32, 1,
376 [VppRoutePath(self.pg0.remote_ip4,
377 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800378 labels=[VppMplsLabel(33)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000379 route_32_eos.add_vpp_config()
380
381 #
382 # a stream that matches the route for 10.0.0.1
383 # PG0 is in the default table
384 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800385 tx = self.create_stream_labelled_ip4(self.pg0,
386 [VppMplsLabel(32, ttl=32, exp=1)])
387 rx = self.send_and_expect(self.pg0, tx, self.pg0)
388 self.verify_capture_labelled(self.pg0, rx, tx,
389 [VppMplsLabel(33, ttl=31, exp=1)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000390
391 #
392 # A simple MPLS xconnect - non-eos label in label out
393 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800394 route_32_neos = VppMplsRoute(self, 32, 0,
395 [VppRoutePath(self.pg0.remote_ip4,
396 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800397 labels=[VppMplsLabel(33)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000398 route_32_neos.add_vpp_config()
399
400 #
401 # a stream that matches the route for 10.0.0.1
402 # PG0 is in the default table
403 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800404 tx = self.create_stream_labelled_ip4(self.pg0,
405 [VppMplsLabel(32, ttl=21, exp=7),
406 VppMplsLabel(99)])
407 rx = self.send_and_expect(self.pg0, tx, self.pg0)
408 self.verify_capture_labelled(self.pg0, rx, tx,
409 [VppMplsLabel(33, ttl=20, exp=7),
410 VppMplsLabel(99)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000411
Neale Ranns31ed7442018-02-23 05:29:09 -0800412 #
413 # A simple MPLS xconnect - non-eos label in label out, uniform mode
414 #
415 route_42_neos = VppMplsRoute(
416 self, 42, 0,
417 [VppRoutePath(self.pg0.remote_ip4,
418 self.pg0.sw_if_index,
419 labels=[VppMplsLabel(43, MplsLspMode.UNIFORM)])])
420 route_42_neos.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000421
Neale Ranns31ed7442018-02-23 05:29:09 -0800422 tx = self.create_stream_labelled_ip4(self.pg0,
423 [VppMplsLabel(42, 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(43, ttl=20, exp=7),
428 VppMplsLabel(99)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000429
430 #
431 # An MPLS xconnect - EOS label in IP out
432 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800433 route_33_eos = VppMplsRoute(self, 33, 1,
434 [VppRoutePath(self.pg0.remote_ip4,
435 self.pg0.sw_if_index,
436 labels=[])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000437 route_33_eos.add_vpp_config()
438
Neale Ranns31ed7442018-02-23 05:29:09 -0800439 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(33)])
440 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Rannsad422ed2016-11-02 14:20:04 +0000441 self.verify_capture_ip4(self.pg0, rx, tx)
442
443 #
Neale Ranns62fe07c2017-10-31 12:28:22 -0700444 # disposed packets have an invalid IPv4 checkusm
445 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800446 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(33)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700447 dst_ip=self.pg0.remote_ip4,
448 n=65,
449 chksum=1)
450 self.send_and_assert_no_replies(self.pg0, tx, "Invalid Checksum")
451
452 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800453 # An MPLS xconnect - EOS label in IP out, uniform mode
454 #
455 route_3333_eos = VppMplsRoute(
456 self, 3333, 1,
457 [VppRoutePath(self.pg0.remote_ip4,
458 self.pg0.sw_if_index,
459 labels=[VppMplsLabel(3, MplsLspMode.UNIFORM)])])
460 route_3333_eos.add_vpp_config()
461
462 tx = self.create_stream_labelled_ip4(
463 self.pg0,
464 [VppMplsLabel(3333, ttl=55, exp=3)])
465 rx = self.send_and_expect(self.pg0, tx, self.pg0)
466 self.verify_capture_ip4(self.pg0, rx, tx, ip_ttl=54, ip_dscp=0x60)
467 tx = self.create_stream_labelled_ip4(
468 self.pg0,
469 [VppMplsLabel(3333, ttl=66, exp=4)])
470 rx = self.send_and_expect(self.pg0, tx, self.pg0)
471 self.verify_capture_ip4(self.pg0, rx, tx, ip_ttl=65, ip_dscp=0x80)
472
473 #
Neale Ranns62fe07c2017-10-31 12:28:22 -0700474 # An MPLS xconnect - EOS label in IPv6 out
475 #
476 route_333_eos = VppMplsRoute(
477 self, 333, 1,
478 [VppRoutePath(self.pg0.remote_ip6,
479 self.pg0.sw_if_index,
480 labels=[],
481 proto=DpoProto.DPO_PROTO_IP6)])
482 route_333_eos.add_vpp_config()
483
Neale Ranns31ed7442018-02-23 05:29:09 -0800484 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(333)])
485 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700486 self.verify_capture_ip6(self.pg0, rx, tx)
487
488 #
489 # disposed packets have an TTL expired
490 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800491 tx = self.create_stream_labelled_ip6(self.pg0,
492 [VppMplsLabel(333, ttl=64)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700493 dst_ip=self.pg1.remote_ip6,
494 hlim=1)
Neale Ranns31ed7442018-02-23 05:29:09 -0800495 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700496 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
497
498 #
499 # An MPLS xconnect - EOS label in IPv6 out w imp-null
500 #
501 route_334_eos = VppMplsRoute(
502 self, 334, 1,
503 [VppRoutePath(self.pg0.remote_ip6,
504 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800505 labels=[VppMplsLabel(3)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700506 proto=DpoProto.DPO_PROTO_IP6)])
507 route_334_eos.add_vpp_config()
508
Neale Ranns31ed7442018-02-23 05:29:09 -0800509 tx = self.create_stream_labelled_ip6(self.pg0,
510 [VppMplsLabel(334, ttl=64)])
511 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700512 self.verify_capture_ip6(self.pg0, rx, tx)
513
514 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800515 # An MPLS xconnect - EOS label in IPv6 out w imp-null in uniform mode
516 #
517 route_335_eos = VppMplsRoute(
518 self, 335, 1,
519 [VppRoutePath(self.pg0.remote_ip6,
520 self.pg0.sw_if_index,
521 labels=[VppMplsLabel(3, MplsLspMode.UNIFORM)],
522 proto=DpoProto.DPO_PROTO_IP6)])
523 route_335_eos.add_vpp_config()
524
525 tx = self.create_stream_labelled_ip6(
526 self.pg0,
527 [VppMplsLabel(335, ttl=27, exp=4)])
528 rx = self.send_and_expect(self.pg0, tx, self.pg0)
529 self.verify_capture_ip6(self.pg0, rx, tx, ip_hlim=26, ip_dscp=0x80)
530
531 #
Neale Ranns62fe07c2017-10-31 12:28:22 -0700532 # disposed packets have an TTL expired
533 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800534 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(334)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700535 dst_ip=self.pg1.remote_ip6,
536 hlim=0)
Neale Ranns31ed7442018-02-23 05:29:09 -0800537 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700538 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
539
540 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000541 # An MPLS xconnect - non-EOS label in IP out - an invalid configuration
542 # so this traffic should be dropped.
543 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800544 route_33_neos = VppMplsRoute(self, 33, 0,
545 [VppRoutePath(self.pg0.remote_ip4,
546 self.pg0.sw_if_index,
547 labels=[])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000548 route_33_neos.add_vpp_config()
549
Neale Ranns31ed7442018-02-23 05:29:09 -0800550 tx = self.create_stream_labelled_ip4(self.pg0,
551 [VppMplsLabel(33),
552 VppMplsLabel(99)])
553 self.send_and_assert_no_replies(
554 self.pg0, tx,
555 "MPLS non-EOS packets popped and forwarded")
Neale Rannsad422ed2016-11-02 14:20:04 +0000556
557 #
558 # A recursive EOS x-connect, which resolves through another x-connect
Neale Ranns31ed7442018-02-23 05:29:09 -0800559 # in pipe mode
Neale Rannsad422ed2016-11-02 14:20:04 +0000560 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800561 route_34_eos = VppMplsRoute(self, 34, 1,
562 [VppRoutePath("0.0.0.0",
563 0xffffffff,
564 nh_via_label=32,
Neale Ranns31ed7442018-02-23 05:29:09 -0800565 labels=[VppMplsLabel(44),
566 VppMplsLabel(45)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000567 route_34_eos.add_vpp_config()
568
Neale Ranns31ed7442018-02-23 05:29:09 -0800569 tx = self.create_stream_labelled_ip4(self.pg0,
570 [VppMplsLabel(34, ttl=3)])
571 rx = self.send_and_expect(self.pg0, tx, self.pg0)
572 self.verify_capture_labelled(self.pg0, rx, tx,
573 [VppMplsLabel(33),
574 VppMplsLabel(44),
575 VppMplsLabel(45, ttl=2)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000576
Neale Ranns31ed7442018-02-23 05:29:09 -0800577 #
578 # A recursive EOS x-connect, which resolves through another x-connect
579 # in uniform mode
580 #
581 route_35_eos = VppMplsRoute(
582 self, 35, 1,
583 [VppRoutePath("0.0.0.0",
584 0xffffffff,
585 nh_via_label=42,
586 labels=[VppMplsLabel(44)])])
587 route_35_eos.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000588
Neale Ranns31ed7442018-02-23 05:29:09 -0800589 tx = self.create_stream_labelled_ip4(self.pg0,
590 [VppMplsLabel(35, ttl=3)])
591 rx = self.send_and_expect(self.pg0, tx, self.pg0)
592 self.verify_capture_labelled(self.pg0, rx, tx,
593 [VppMplsLabel(43, ttl=2),
594 VppMplsLabel(44, ttl=2)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000595
596 #
Matej Klottondeb69842016-12-09 15:05:46 +0100597 # A recursive non-EOS x-connect, which resolves through another
598 # x-connect
Neale Rannsad422ed2016-11-02 14:20:04 +0000599 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800600 route_34_neos = VppMplsRoute(self, 34, 0,
601 [VppRoutePath("0.0.0.0",
602 0xffffffff,
603 nh_via_label=32,
Neale Ranns31ed7442018-02-23 05:29:09 -0800604 labels=[VppMplsLabel(44),
605 VppMplsLabel(46)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000606 route_34_neos.add_vpp_config()
607
Neale Ranns31ed7442018-02-23 05:29:09 -0800608 tx = self.create_stream_labelled_ip4(self.pg0,
609 [VppMplsLabel(34, ttl=45),
610 VppMplsLabel(99)])
611 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Matej Klottondeb69842016-12-09 15:05:46 +0100612 # it's the 2nd (counting from 0) label in the stack that is swapped
Neale Ranns31ed7442018-02-23 05:29:09 -0800613 self.verify_capture_labelled(self.pg0, rx, tx,
614 [VppMplsLabel(33),
615 VppMplsLabel(44),
616 VppMplsLabel(46, ttl=44),
617 VppMplsLabel(99)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000618
619 #
Matej Klottondeb69842016-12-09 15:05:46 +0100620 # an recursive IP route that resolves through the recursive non-eos
621 # x-connect
Neale Rannsad422ed2016-11-02 14:20:04 +0000622 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800623 ip_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
624 [VppRoutePath("0.0.0.0",
625 0xffffffff,
626 nh_via_label=34,
Neale Ranns31ed7442018-02-23 05:29:09 -0800627 labels=[VppMplsLabel(55)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000628 ip_10_0_0_1.add_vpp_config()
629
Neale Rannsad422ed2016-11-02 14:20:04 +0000630 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800631 rx = self.send_and_expect(self.pg0, tx, self.pg0)
632 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
633 [VppMplsLabel(33),
634 VppMplsLabel(44),
635 VppMplsLabel(46),
636 VppMplsLabel(55)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000637
638 ip_10_0_0_1.remove_vpp_config()
639 route_34_neos.remove_vpp_config()
640 route_34_eos.remove_vpp_config()
641 route_33_neos.remove_vpp_config()
642 route_33_eos.remove_vpp_config()
643 route_32_neos.remove_vpp_config()
644 route_32_eos.remove_vpp_config()
645
646 def test_bind(self):
647 """ MPLS Local Label Binding test """
648
649 #
650 # Add a non-recursive route with a single out label
651 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800652 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
653 [VppRoutePath(self.pg0.remote_ip4,
654 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800655 labels=[VppMplsLabel(45)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000656 route_10_0_0_1.add_vpp_config()
657
658 # bind a local label to the route
Neale Ranns5a8123b2017-01-26 01:18:23 -0800659 binding = VppMplsIpBind(self, 44, "10.0.0.1", 32)
Neale Rannsad422ed2016-11-02 14:20:04 +0000660 binding.add_vpp_config()
661
662 # non-EOS stream
Neale Ranns31ed7442018-02-23 05:29:09 -0800663 tx = self.create_stream_labelled_ip4(self.pg0,
664 [VppMplsLabel(44),
665 VppMplsLabel(99)])
666 rx = self.send_and_expect(self.pg0, tx, self.pg0)
667 self.verify_capture_labelled(self.pg0, rx, tx,
668 [VppMplsLabel(45, ttl=63),
669 VppMplsLabel(99)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000670
671 # EOS stream
Neale Ranns31ed7442018-02-23 05:29:09 -0800672 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(44)])
673 rx = self.send_and_expect(self.pg0, tx, self.pg0)
674 self.verify_capture_labelled(self.pg0, rx, tx,
675 [VppMplsLabel(45, ttl=63)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000676
677 # IP stream
Neale Rannsad422ed2016-11-02 14:20:04 +0000678 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800679 rx = self.send_and_expect(self.pg0, tx, self.pg0)
680 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [VppMplsLabel(45)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000681
682 #
683 # cleanup
684 #
685 binding.remove_vpp_config()
686 route_10_0_0_1.remove_vpp_config()
687
688 def test_imposition(self):
689 """ MPLS label imposition test """
690
691 #
692 # Add a non-recursive route with a single out label
693 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800694 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
695 [VppRoutePath(self.pg0.remote_ip4,
696 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800697 labels=[VppMplsLabel(32)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000698 route_10_0_0_1.add_vpp_config()
699
700 #
701 # a stream that matches the route for 10.0.0.1
702 # PG0 is in the default table
703 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000704 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800705 rx = self.send_and_expect(self.pg0, tx, self.pg0)
706 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [VppMplsLabel(32)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000707
708 #
709 # Add a non-recursive route with a 3 out labels
710 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800711 route_10_0_0_2 = VppIpRoute(self, "10.0.0.2", 32,
712 [VppRoutePath(self.pg0.remote_ip4,
713 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800714 labels=[VppMplsLabel(32),
715 VppMplsLabel(33),
716 VppMplsLabel(34)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000717 route_10_0_0_2.add_vpp_config()
718
Neale Ranns31ed7442018-02-23 05:29:09 -0800719 tx = self.create_stream_ip4(self.pg0, "10.0.0.2",
720 ip_ttl=44, ip_dscp=0xff)
721 rx = self.send_and_expect(self.pg0, tx, self.pg0)
722 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
723 [VppMplsLabel(32),
724 VppMplsLabel(33),
725 VppMplsLabel(34)],
726 ip_ttl=43)
Neale Rannsad422ed2016-11-02 14:20:04 +0000727
Neale Ranns31ed7442018-02-23 05:29:09 -0800728 #
729 # Add a non-recursive route with a single out label in uniform mode
730 #
731 route_10_0_0_3 = VppIpRoute(
732 self, "10.0.0.3", 32,
733 [VppRoutePath(self.pg0.remote_ip4,
734 self.pg0.sw_if_index,
735 labels=[VppMplsLabel(32,
736 mode=MplsLspMode.UNIFORM)])])
737 route_10_0_0_3.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000738
Neale Ranns31ed7442018-02-23 05:29:09 -0800739 tx = self.create_stream_ip4(self.pg0, "10.0.0.3",
740 ip_ttl=54, ip_dscp=0xbe)
741 rx = self.send_and_expect(self.pg0, tx, self.pg0)
742 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
743 [VppMplsLabel(32, ttl=53, exp=5)])
744
745 #
746 # Add a IPv6 non-recursive route with a single out label in
747 # uniform mode
748 #
749 route_2001_3 = VppIpRoute(
750 self, "2001::3", 128,
751 [VppRoutePath(self.pg0.remote_ip6,
752 self.pg0.sw_if_index,
753 proto=DpoProto.DPO_PROTO_IP6,
754 labels=[VppMplsLabel(32,
755 mode=MplsLspMode.UNIFORM)])],
756 is_ip6=1)
757 route_2001_3.add_vpp_config()
758
759 tx = self.create_stream_ip6(self.pg0, "2001::3",
760 ip_ttl=54, ip_dscp=0xbe)
761 rx = self.send_and_expect(self.pg0, tx, self.pg0)
762 self.verify_capture_labelled_ip6(self.pg0, rx, tx,
763 [VppMplsLabel(32, ttl=53, exp=5)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000764
765 #
Matej Klottondeb69842016-12-09 15:05:46 +0100766 # add a recursive path, with output label, via the 1 label route
Neale Rannsad422ed2016-11-02 14:20:04 +0000767 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800768 route_11_0_0_1 = VppIpRoute(self, "11.0.0.1", 32,
769 [VppRoutePath("10.0.0.1",
770 0xffffffff,
Neale Ranns31ed7442018-02-23 05:29:09 -0800771 labels=[VppMplsLabel(44)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000772 route_11_0_0_1.add_vpp_config()
773
774 #
775 # a stream that matches the route for 11.0.0.1, should pick up
776 # the label stack for 11.0.0.1 and 10.0.0.1
777 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000778 tx = self.create_stream_ip4(self.pg0, "11.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800779 rx = self.send_and_expect(self.pg0, tx, self.pg0)
780 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
781 [VppMplsLabel(32),
782 VppMplsLabel(44)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000783
784 #
785 # add a recursive path, with 2 labels, via the 3 label route
786 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800787 route_11_0_0_2 = VppIpRoute(self, "11.0.0.2", 32,
788 [VppRoutePath("10.0.0.2",
789 0xffffffff,
Neale Ranns31ed7442018-02-23 05:29:09 -0800790 labels=[VppMplsLabel(44),
791 VppMplsLabel(45)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000792 route_11_0_0_2.add_vpp_config()
793
794 #
795 # a stream that matches the route for 11.0.0.1, should pick up
796 # the label stack for 11.0.0.1 and 10.0.0.1
797 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000798 tx = self.create_stream_ip4(self.pg0, "11.0.0.2")
Neale Ranns31ed7442018-02-23 05:29:09 -0800799 rx = self.send_and_expect(self.pg0, tx, self.pg0)
800 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
801 [VppMplsLabel(32),
802 VppMplsLabel(33),
803 VppMplsLabel(34),
804 VppMplsLabel(44),
805 VppMplsLabel(45)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000806
807 #
808 # cleanup
809 #
810 route_11_0_0_2.remove_vpp_config()
811 route_11_0_0_1.remove_vpp_config()
812 route_10_0_0_2.remove_vpp_config()
813 route_10_0_0_1.remove_vpp_config()
814
Neale Ranns31ed7442018-02-23 05:29:09 -0800815 def test_tunnel_pipe(self):
816 """ MPLS Tunnel Tests - Pipe """
Neale Rannsad422ed2016-11-02 14:20:04 +0000817
818 #
819 # Create a tunnel with a single out label
820 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800821 mpls_tun = VppMPLSTunnelInterface(
822 self,
823 [VppRoutePath(self.pg0.remote_ip4,
824 self.pg0.sw_if_index,
825 labels=[VppMplsLabel(44),
826 VppMplsLabel(46)])])
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800827 mpls_tun.add_vpp_config()
828 mpls_tun.admin_up()
Neale Rannsad422ed2016-11-02 14:20:04 +0000829
830 #
831 # add an unlabelled route through the new tunnel
832 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800833 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
834 [VppRoutePath("0.0.0.0",
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800835 mpls_tun._sw_if_index)])
Neale Ranns5a8123b2017-01-26 01:18:23 -0800836 route_10_0_0_3.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000837
838 self.vapi.cli("clear trace")
839 tx = self.create_stream_ip4(self.pg0, "10.0.0.3")
840 self.pg0.add_stream(tx)
841
842 self.pg_enable_capture(self.pg_interfaces)
843 self.pg_start()
844
845 rx = self.pg0.get_capture()
Neale Ranns31ed7442018-02-23 05:29:09 -0800846 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
847 [VppMplsLabel(44),
848 VppMplsLabel(46)])
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000849
Neale Ranns8c4611b2017-05-23 03:43:47 -0700850 #
851 # add a labelled route through the new tunnel
852 #
853 route_10_0_0_4 = VppIpRoute(self, "10.0.0.4", 32,
854 [VppRoutePath("0.0.0.0",
855 mpls_tun._sw_if_index,
856 labels=[33])])
857 route_10_0_0_4.add_vpp_config()
858
859 self.vapi.cli("clear trace")
860 tx = self.create_stream_ip4(self.pg0, "10.0.0.4")
861 self.pg0.add_stream(tx)
862
863 self.pg_enable_capture(self.pg_interfaces)
864 self.pg_start()
865
866 rx = self.pg0.get_capture()
Neale Ranns31ed7442018-02-23 05:29:09 -0800867 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
868 [VppMplsLabel(44),
869 VppMplsLabel(46),
870 VppMplsLabel(33, ttl=255)])
871
872 def test_tunnel_uniform(self):
873 """ MPLS Tunnel Tests - Uniform """
874
875 #
876 # Create a tunnel with a single out label
877 # The label stack is specified here from outer to inner
878 #
879 mpls_tun = VppMPLSTunnelInterface(
880 self,
881 [VppRoutePath(self.pg0.remote_ip4,
882 self.pg0.sw_if_index,
883 labels=[VppMplsLabel(44, ttl=32),
884 VppMplsLabel(46, MplsLspMode.UNIFORM)])])
885 mpls_tun.add_vpp_config()
886 mpls_tun.admin_up()
887
888 #
889 # add an unlabelled route through the new tunnel
890 #
891 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
892 [VppRoutePath("0.0.0.0",
893 mpls_tun._sw_if_index)])
894 route_10_0_0_3.add_vpp_config()
895
896 self.vapi.cli("clear trace")
897 tx = self.create_stream_ip4(self.pg0, "10.0.0.3", ip_ttl=24)
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()
904 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
905 [VppMplsLabel(44, ttl=32),
906 VppMplsLabel(46, ttl=23)])
907
908 #
909 # add a labelled route through the new tunnel
910 #
911 route_10_0_0_4 = VppIpRoute(
912 self, "10.0.0.4", 32,
913 [VppRoutePath("0.0.0.0",
914 mpls_tun._sw_if_index,
915 labels=[VppMplsLabel(33, ttl=47)])])
916 route_10_0_0_4.add_vpp_config()
917
918 self.vapi.cli("clear trace")
919 tx = self.create_stream_ip4(self.pg0, "10.0.0.4")
920 self.pg0.add_stream(tx)
921
922 self.pg_enable_capture(self.pg_interfaces)
923 self.pg_start()
924
925 rx = self.pg0.get_capture()
926 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
927 [VppMplsLabel(44, ttl=32),
928 VppMplsLabel(46, ttl=47),
929 VppMplsLabel(33, ttl=47)])
Neale Ranns8c4611b2017-05-23 03:43:47 -0700930
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000931 def test_v4_exp_null(self):
932 """ MPLS V4 Explicit NULL test """
933
934 #
935 # The first test case has an MPLS TTL of 0
936 # all packet should be dropped
937 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800938 tx = self.create_stream_labelled_ip4(self.pg0,
939 [VppMplsLabel(0, ttl=0)])
940 self.send_and_assert_no_replies(self.pg0, tx,
941 "MPLS TTL=0 packets forwarded")
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000942
943 #
944 # a stream with a non-zero MPLS TTL
945 # PG0 is in the default table
946 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800947 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(0)])
948 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000949 self.verify_capture_ip4(self.pg0, rx, tx)
950
951 #
952 # a stream with a non-zero MPLS TTL
953 # PG1 is in table 1
954 # we are ensuring the post-pop lookup occurs in the VRF table
955 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800956 tx = self.create_stream_labelled_ip4(self.pg1, [VppMplsLabel(0)])
957 rx = self.send_and_expect(self.pg1, tx, self.pg1)
958 self.verify_capture_ip4(self.pg1, rx, tx)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000959
960 def test_v6_exp_null(self):
961 """ MPLS V6 Explicit NULL test """
962
963 #
964 # a stream with a non-zero MPLS TTL
965 # PG0 is in the default table
966 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800967 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(2)])
968 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000969 self.verify_capture_ip6(self.pg0, rx, tx)
970
971 #
972 # a stream with a non-zero MPLS TTL
973 # PG1 is in table 1
974 # we are ensuring the post-pop lookup occurs in the VRF table
975 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800976 tx = self.create_stream_labelled_ip6(self.pg1, [VppMplsLabel(2)])
977 rx = self.send_and_expect(self.pg1, tx, self.pg1)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000978 self.verify_capture_ip6(self.pg0, rx, tx)
979
Neale Rannscb630ff2016-12-14 13:31:29 +0100980 def test_deag(self):
981 """ MPLS Deagg """
982
983 #
984 # A de-agg route - next-hop lookup in default table
985 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800986 route_34_eos = VppMplsRoute(self, 34, 1,
987 [VppRoutePath("0.0.0.0",
988 0xffffffff,
989 nh_table_id=0)])
Neale Rannscb630ff2016-12-14 13:31:29 +0100990 route_34_eos.add_vpp_config()
991
992 #
993 # ping an interface in the default table
994 # PG0 is in the default table
995 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800996 tx = self.create_stream_labelled_ip4(self.pg0,
997 [VppMplsLabel(34)],
998 ping=1,
Neale Rannscb630ff2016-12-14 13:31:29 +0100999 ip_itf=self.pg0)
Neale Ranns31ed7442018-02-23 05:29:09 -08001000 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Rannscb630ff2016-12-14 13:31:29 +01001001 self.verify_capture_ip4(self.pg0, rx, tx, ping_resp=1)
1002
1003 #
1004 # A de-agg route - next-hop lookup in non-default table
1005 #
Neale Ranns5a8123b2017-01-26 01:18:23 -08001006 route_35_eos = VppMplsRoute(self, 35, 1,
1007 [VppRoutePath("0.0.0.0",
1008 0xffffffff,
1009 nh_table_id=1)])
Neale Rannscb630ff2016-12-14 13:31:29 +01001010 route_35_eos.add_vpp_config()
1011
1012 #
1013 # ping an interface in the non-default table
1014 # PG0 is in the default table. packet arrive labelled in the
1015 # default table and egress unlabelled in the non-default
1016 #
Klement Sekeradab231a2016-12-21 08:50:14 +01001017 tx = self.create_stream_labelled_ip4(
Neale Ranns31ed7442018-02-23 05:29:09 -08001018 self.pg0, [VppMplsLabel(35)], ping=1, ip_itf=self.pg1)
1019 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Rannscb630ff2016-12-14 13:31:29 +01001020 self.verify_capture_ip4(self.pg1, rx, tx, ping_resp=1)
1021
Neale Ranns6af1c042017-05-26 03:48:53 -07001022 #
1023 # Double pop
1024 #
1025 route_36_neos = VppMplsRoute(self, 36, 0,
1026 [VppRoutePath("0.0.0.0",
1027 0xffffffff)])
1028 route_36_neos.add_vpp_config()
1029
Neale Ranns31ed7442018-02-23 05:29:09 -08001030 tx = self.create_stream_labelled_ip4(self.pg0,
1031 [VppMplsLabel(36),
1032 VppMplsLabel(35)],
Neale Ranns6af1c042017-05-26 03:48:53 -07001033 ping=1, ip_itf=self.pg1)
Neale Ranns31ed7442018-02-23 05:29:09 -08001034 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns6af1c042017-05-26 03:48:53 -07001035 self.verify_capture_ip4(self.pg1, rx, tx, ping_resp=1)
1036
1037 route_36_neos.remove_vpp_config()
Neale Rannscb630ff2016-12-14 13:31:29 +01001038 route_35_eos.remove_vpp_config()
1039 route_34_eos.remove_vpp_config()
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001040
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001041 def test_interface_rx(self):
1042 """ MPLS Interface Receive """
1043
1044 #
1045 # Add a non-recursive route that will forward the traffic
1046 # post-interface-rx
1047 #
1048 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
1049 table_id=1,
1050 paths=[VppRoutePath(self.pg1.remote_ip4,
1051 self.pg1.sw_if_index)])
1052 route_10_0_0_1.add_vpp_config()
1053
1054 #
1055 # An interface receive label that maps traffic to RX on interface
1056 # pg1
1057 # by injecting the packet in on pg0, which is in table 0
1058 # doing an interface-rx on pg1 and matching a route in table 1
1059 # if the packet egresses, then we must have swapped to pg1
1060 # so as to have matched the route in table 1
1061 #
1062 route_34_eos = VppMplsRoute(self, 34, 1,
1063 [VppRoutePath("0.0.0.0",
1064 self.pg1.sw_if_index,
1065 is_interface_rx=1)])
1066 route_34_eos.add_vpp_config()
1067
1068 #
1069 # ping an interface in the default table
1070 # PG0 is in the default table
1071 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001072 tx = self.create_stream_labelled_ip4(self.pg0,
1073 [VppMplsLabel(34)],
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001074 dst_ip="10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -08001075 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001076 self.verify_capture_ip4(self.pg1, rx, tx)
1077
1078 def test_mcast_mid_point(self):
1079 """ MPLS Multicast Mid Point """
1080
1081 #
1082 # Add a non-recursive route that will forward the traffic
1083 # post-interface-rx
1084 #
1085 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
1086 table_id=1,
1087 paths=[VppRoutePath(self.pg1.remote_ip4,
1088 self.pg1.sw_if_index)])
1089 route_10_0_0_1.add_vpp_config()
1090
1091 #
1092 # Add a mcast entry that replicate to pg2 and pg3
1093 # and replicate to a interface-rx (like a bud node would)
1094 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001095 route_3400_eos = VppMplsRoute(
1096 self, 3400, 1,
1097 [VppRoutePath(self.pg2.remote_ip4,
1098 self.pg2.sw_if_index,
1099 labels=[VppMplsLabel(3401)]),
1100 VppRoutePath(self.pg3.remote_ip4,
1101 self.pg3.sw_if_index,
1102 labels=[VppMplsLabel(3402)]),
1103 VppRoutePath("0.0.0.0",
1104 self.pg1.sw_if_index,
1105 is_interface_rx=1)],
1106 is_multicast=1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001107 route_3400_eos.add_vpp_config()
1108
1109 #
1110 # ping an interface in the default table
1111 # PG0 is in the default table
1112 #
1113 self.vapi.cli("clear trace")
Neale Ranns31ed7442018-02-23 05:29:09 -08001114 tx = self.create_stream_labelled_ip4(self.pg0,
1115 [VppMplsLabel(3400, ttl=64)],
1116 n=257,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001117 dst_ip="10.0.0.1")
1118 self.pg0.add_stream(tx)
1119
1120 self.pg_enable_capture(self.pg_interfaces)
1121 self.pg_start()
1122
1123 rx = self.pg1.get_capture(257)
1124 self.verify_capture_ip4(self.pg1, rx, tx)
1125
1126 rx = self.pg2.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001127 self.verify_capture_labelled(self.pg2, rx, tx,
1128 [VppMplsLabel(3401, ttl=63)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001129 rx = self.pg3.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001130 self.verify_capture_labelled(self.pg3, rx, tx,
1131 [VppMplsLabel(3402, ttl=63)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001132
1133 def test_mcast_head(self):
1134 """ MPLS Multicast Head-end """
1135
1136 #
1137 # Create a multicast tunnel with two replications
1138 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001139 mpls_tun = VppMPLSTunnelInterface(
1140 self,
1141 [VppRoutePath(self.pg2.remote_ip4,
1142 self.pg2.sw_if_index,
1143 labels=[VppMplsLabel(42)]),
1144 VppRoutePath(self.pg3.remote_ip4,
1145 self.pg3.sw_if_index,
1146 labels=[VppMplsLabel(43)])],
1147 is_multicast=1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001148 mpls_tun.add_vpp_config()
1149 mpls_tun.admin_up()
1150
1151 #
1152 # add an unlabelled route through the new tunnel
1153 #
1154 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
1155 [VppRoutePath("0.0.0.0",
1156 mpls_tun._sw_if_index)])
1157 route_10_0_0_3.add_vpp_config()
1158
1159 self.vapi.cli("clear trace")
1160 tx = self.create_stream_ip4(self.pg0, "10.0.0.3")
1161 self.pg0.add_stream(tx)
1162
1163 self.pg_enable_capture(self.pg_interfaces)
1164 self.pg_start()
1165
1166 rx = self.pg2.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001167 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(42)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001168 rx = self.pg3.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001169 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(43)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001170
1171 #
1172 # An an IP multicast route via the tunnel
1173 # A (*,G).
1174 # one accepting interface, pg0, 1 forwarding interface via the tunnel
1175 #
1176 route_232_1_1_1 = VppIpMRoute(
1177 self,
1178 "0.0.0.0",
1179 "232.1.1.1", 32,
1180 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
1181 [VppMRoutePath(self.pg0.sw_if_index,
1182 MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
1183 VppMRoutePath(mpls_tun._sw_if_index,
1184 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
1185 route_232_1_1_1.add_vpp_config()
1186
1187 self.vapi.cli("clear trace")
1188 tx = self.create_stream_ip4(self.pg0, "232.1.1.1")
1189 self.pg0.add_stream(tx)
1190
1191 self.pg_enable_capture(self.pg_interfaces)
1192 self.pg_start()
1193
1194 rx = self.pg2.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001195 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(42)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001196 rx = self.pg3.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001197 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(43)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001198
Neale Ranns31426c62017-05-24 10:32:58 -07001199 def test_mcast_ip4_tail(self):
1200 """ MPLS IPv4 Multicast Tail """
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001201
1202 #
1203 # Add a multicast route that will forward the traffic
1204 # post-disposition
1205 #
1206 route_232_1_1_1 = VppIpMRoute(
1207 self,
1208 "0.0.0.0",
1209 "232.1.1.1", 32,
1210 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
1211 table_id=1,
1212 paths=[VppMRoutePath(self.pg1.sw_if_index,
1213 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
1214 route_232_1_1_1.add_vpp_config()
1215
1216 #
1217 # An interface receive label that maps traffic to RX on interface
1218 # pg1
1219 # by injecting the packet in on pg0, which is in table 0
1220 # doing an rpf-id and matching a route in table 1
1221 # if the packet egresses, then we must have matched the route in
1222 # table 1
1223 #
1224 route_34_eos = VppMplsRoute(self, 34, 1,
1225 [VppRoutePath("0.0.0.0",
1226 self.pg1.sw_if_index,
1227 nh_table_id=1,
1228 rpf_id=55)],
1229 is_multicast=1)
1230
1231 route_34_eos.add_vpp_config()
1232
1233 #
1234 # Drop due to interface lookup miss
1235 #
1236 self.vapi.cli("clear trace")
Neale Ranns31ed7442018-02-23 05:29:09 -08001237 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001238 dst_ip="232.1.1.1", n=1)
1239 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop none")
1240
1241 #
1242 # set the RPF-ID of the enrtry to match the input packet's
1243 #
1244 route_232_1_1_1.update_rpf_id(55)
1245
Neale Ranns31ed7442018-02-23 05:29:09 -08001246 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
1247 dst_ip="232.1.1.1")
1248 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001249 self.verify_capture_ip4(self.pg1, rx, tx)
1250
1251 #
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001252 # disposed packets have an invalid IPv4 checkusm
1253 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001254 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001255 dst_ip="232.1.1.1", n=65,
1256 chksum=1)
1257 self.send_and_assert_no_replies(self.pg0, tx, "Invalid Checksum")
1258
1259 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001260 # set the RPF-ID of the entry to not match the input packet's
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001261 #
1262 route_232_1_1_1.update_rpf_id(56)
Neale Ranns31ed7442018-02-23 05:29:09 -08001263 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001264 dst_ip="232.1.1.1")
1265 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop 56")
1266
Neale Ranns31426c62017-05-24 10:32:58 -07001267 def test_mcast_ip6_tail(self):
1268 """ MPLS IPv6 Multicast Tail """
1269
1270 #
1271 # Add a multicast route that will forward the traffic
1272 # post-disposition
1273 #
1274 route_ff = VppIpMRoute(
1275 self,
1276 "::",
1277 "ff01::1", 32,
1278 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
1279 table_id=1,
1280 paths=[VppMRoutePath(self.pg1.sw_if_index,
1281 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)],
1282 is_ip6=1)
1283 route_ff.add_vpp_config()
1284
1285 #
1286 # An interface receive label that maps traffic to RX on interface
1287 # pg1
1288 # by injecting the packet in on pg0, which is in table 0
1289 # doing an rpf-id and matching a route in table 1
1290 # if the packet egresses, then we must have matched the route in
1291 # table 1
1292 #
1293 route_34_eos = VppMplsRoute(
1294 self, 34, 1,
1295 [VppRoutePath("::",
1296 self.pg1.sw_if_index,
1297 nh_table_id=1,
1298 rpf_id=55,
Neale Rannsda78f952017-05-24 09:15:43 -07001299 proto=DpoProto.DPO_PROTO_IP6)],
Neale Ranns31426c62017-05-24 10:32:58 -07001300 is_multicast=1)
1301
1302 route_34_eos.add_vpp_config()
1303
1304 #
1305 # Drop due to interface lookup miss
1306 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001307 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(34)],
Neale Ranns31426c62017-05-24 10:32:58 -07001308 dst_ip="ff01::1")
Neale Ranns31ed7442018-02-23 05:29:09 -08001309 self.send_and_assert_no_replies(self.pg0, tx, "RPF Miss")
Neale Ranns31426c62017-05-24 10:32:58 -07001310
1311 #
1312 # set the RPF-ID of the enrtry to match the input packet's
1313 #
1314 route_ff.update_rpf_id(55)
1315
Neale Ranns31ed7442018-02-23 05:29:09 -08001316 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(34)],
Neale Ranns31426c62017-05-24 10:32:58 -07001317 dst_ip="ff01::1")
Neale Ranns31ed7442018-02-23 05:29:09 -08001318 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns31426c62017-05-24 10:32:58 -07001319 self.verify_capture_ip6(self.pg1, rx, tx)
1320
1321 #
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001322 # disposed packets have hop-limit = 1
1323 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001324 tx = self.create_stream_labelled_ip6(self.pg0,
1325 [VppMplsLabel(34)],
1326 dst_ip="ff01::1",
1327 hlim=1)
1328 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns52fae862018-01-08 04:41:42 -08001329 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001330
1331 #
Neale Ranns31426c62017-05-24 10:32:58 -07001332 # set the RPF-ID of the enrtry to not match the input packet's
1333 #
1334 route_ff.update_rpf_id(56)
Neale Ranns31ed7442018-02-23 05:29:09 -08001335 tx = self.create_stream_labelled_ip6(self.pg0,
1336 [VppMplsLabel(34)],
Neale Ranns31426c62017-05-24 10:32:58 -07001337 dst_ip="ff01::1")
1338 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop 56")
1339
Neale Ranns180279b2017-03-16 15:49:09 -04001340
1341class TestMPLSDisabled(VppTestCase):
1342 """ MPLS disabled """
1343
1344 def setUp(self):
1345 super(TestMPLSDisabled, self).setUp()
1346
1347 # create 2 pg interfaces
1348 self.create_pg_interfaces(range(2))
1349
Neale Ranns15002542017-09-10 04:39:11 -07001350 self.tbl = VppMplsTable(self, 0)
1351 self.tbl.add_vpp_config()
1352
Neale Ranns180279b2017-03-16 15:49:09 -04001353 # PG0 is MPLS enalbed
1354 self.pg0.admin_up()
1355 self.pg0.config_ip4()
1356 self.pg0.resolve_arp()
1357 self.pg0.enable_mpls()
1358
1359 # PG 1 is not MPLS enabled
1360 self.pg1.admin_up()
1361
1362 def tearDown(self):
Neale Ranns180279b2017-03-16 15:49:09 -04001363 for i in self.pg_interfaces:
1364 i.unconfig_ip4()
1365 i.admin_down()
1366
Neale Ranns15002542017-09-10 04:39:11 -07001367 self.pg0.disable_mpls()
1368 super(TestMPLSDisabled, self).tearDown()
1369
Neale Ranns180279b2017-03-16 15:49:09 -04001370 def test_mpls_disabled(self):
1371 """ MPLS Disabled """
1372
1373 tx = (Ether(src=self.pg1.remote_mac,
1374 dst=self.pg1.local_mac) /
1375 MPLS(label=32, ttl=64) /
1376 IPv6(src="2001::1", dst=self.pg0.remote_ip6) /
1377 UDP(sport=1234, dport=1234) /
1378 Raw('\xa5' * 100))
1379
1380 #
1381 # A simple MPLS xconnect - eos label in label out
1382 #
1383 route_32_eos = VppMplsRoute(self, 32, 1,
1384 [VppRoutePath(self.pg0.remote_ip4,
1385 self.pg0.sw_if_index,
1386 labels=[33])])
1387 route_32_eos.add_vpp_config()
1388
1389 #
1390 # PG1 does not forward IP traffic
1391 #
1392 self.send_and_assert_no_replies(self.pg1, tx, "MPLS disabled")
1393
1394 #
1395 # MPLS enable PG1
1396 #
1397 self.pg1.enable_mpls()
1398
1399 #
1400 # Now we get packets through
1401 #
1402 self.pg1.add_stream(tx)
1403 self.pg_enable_capture(self.pg_interfaces)
1404 self.pg_start()
1405
1406 rx = self.pg0.get_capture(1)
1407
1408 #
1409 # Disable PG1
1410 #
1411 self.pg1.disable_mpls()
1412
1413 #
1414 # PG1 does not forward IP traffic
1415 #
1416 self.send_and_assert_no_replies(self.pg1, tx, "IPv6 disabled")
1417 self.send_and_assert_no_replies(self.pg1, tx, "IPv6 disabled")
1418
1419
Neale Rannsf12a83f2017-04-18 09:09:40 -07001420class TestMPLSPIC(VppTestCase):
1421 """ MPLS PIC edge convergence """
1422
1423 def setUp(self):
1424 super(TestMPLSPIC, self).setUp()
1425
1426 # create 2 pg interfaces
1427 self.create_pg_interfaces(range(4))
1428
Neale Ranns15002542017-09-10 04:39:11 -07001429 mpls_tbl = VppMplsTable(self, 0)
1430 mpls_tbl.add_vpp_config()
1431 tbl4 = VppIpTable(self, 1)
1432 tbl4.add_vpp_config()
1433 tbl6 = VppIpTable(self, 1, is_ip6=1)
1434 tbl6.add_vpp_config()
1435
Neale Rannsf12a83f2017-04-18 09:09:40 -07001436 # core links
1437 self.pg0.admin_up()
1438 self.pg0.config_ip4()
1439 self.pg0.resolve_arp()
1440 self.pg0.enable_mpls()
1441 self.pg1.admin_up()
1442 self.pg1.config_ip4()
1443 self.pg1.resolve_arp()
1444 self.pg1.enable_mpls()
1445
1446 # VRF (customer facing) link
1447 self.pg2.admin_up()
1448 self.pg2.set_table_ip4(1)
1449 self.pg2.config_ip4()
1450 self.pg2.resolve_arp()
1451 self.pg2.set_table_ip6(1)
1452 self.pg2.config_ip6()
1453 self.pg2.resolve_ndp()
1454 self.pg3.admin_up()
1455 self.pg3.set_table_ip4(1)
1456 self.pg3.config_ip4()
1457 self.pg3.resolve_arp()
1458 self.pg3.set_table_ip6(1)
1459 self.pg3.config_ip6()
1460 self.pg3.resolve_ndp()
1461
1462 def tearDown(self):
Neale Rannsf12a83f2017-04-18 09:09:40 -07001463 self.pg0.disable_mpls()
Neale Ranns15002542017-09-10 04:39:11 -07001464 self.pg1.disable_mpls()
Neale Rannsf12a83f2017-04-18 09:09:40 -07001465 for i in self.pg_interfaces:
1466 i.unconfig_ip4()
1467 i.unconfig_ip6()
1468 i.set_table_ip4(0)
1469 i.set_table_ip6(0)
1470 i.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -07001471 super(TestMPLSPIC, self).tearDown()
Neale Rannsf12a83f2017-04-18 09:09:40 -07001472
1473 def test_mpls_ibgp_pic(self):
1474 """ MPLS iBGP PIC edge convergence
1475
1476 1) setup many iBGP VPN routes via a pair of iBGP peers.
1477 2) Check EMCP forwarding to these peers
1478 3) withdraw the IGP route to one of these peers.
1479 4) check forwarding continues to the remaining peer
1480 """
1481
1482 #
1483 # IGP+LDP core routes
1484 #
1485 core_10_0_0_45 = VppIpRoute(self, "10.0.0.45", 32,
1486 [VppRoutePath(self.pg0.remote_ip4,
1487 self.pg0.sw_if_index,
1488 labels=[45])])
1489 core_10_0_0_45.add_vpp_config()
1490
1491 core_10_0_0_46 = VppIpRoute(self, "10.0.0.46", 32,
1492 [VppRoutePath(self.pg1.remote_ip4,
1493 self.pg1.sw_if_index,
1494 labels=[46])])
1495 core_10_0_0_46.add_vpp_config()
1496
1497 #
1498 # Lot's of VPN routes. We need more the 64 so VPP will build
1499 # the fast convergence indirection
1500 #
1501 vpn_routes = []
1502 pkts = []
1503 for ii in range(64):
1504 dst = "192.168.1.%d" % ii
1505 vpn_routes.append(VppIpRoute(self, dst, 32,
1506 [VppRoutePath("10.0.0.45",
1507 0xffffffff,
1508 labels=[145],
1509 is_resolve_host=1),
1510 VppRoutePath("10.0.0.46",
1511 0xffffffff,
1512 labels=[146],
1513 is_resolve_host=1)],
1514 table_id=1))
1515 vpn_routes[ii].add_vpp_config()
1516
1517 pkts.append(Ether(dst=self.pg2.local_mac,
1518 src=self.pg2.remote_mac) /
1519 IP(src=self.pg2.remote_ip4, dst=dst) /
1520 UDP(sport=1234, dport=1234) /
1521 Raw('\xa5' * 100))
1522
1523 #
1524 # Send the packet stream (one pkt to each VPN route)
1525 # - expect a 50-50 split of the traffic
1526 #
1527 self.pg2.add_stream(pkts)
1528 self.pg_enable_capture(self.pg_interfaces)
1529 self.pg_start()
1530
1531 rx0 = self.pg0._get_capture(1)
1532 rx1 = self.pg1._get_capture(1)
1533
1534 # not testig the LB hashing algorithm so we're not concerned
1535 # with the split ratio, just as long as neither is 0
1536 self.assertNotEqual(0, len(rx0))
1537 self.assertNotEqual(0, len(rx1))
1538
1539 #
1540 # use a test CLI command to stop the FIB walk process, this
1541 # will prevent the FIB converging the VPN routes and thus allow
1542 # us to probe the interim (psot-fail, pre-converge) state
1543 #
1544 self.vapi.ppcli("test fib-walk-process disable")
1545
1546 #
1547 # Withdraw one of the IGP routes
1548 #
1549 core_10_0_0_46.remove_vpp_config()
1550
1551 #
1552 # now all packets should be forwarded through the remaining peer
1553 #
1554 self.vapi.ppcli("clear trace")
1555 self.pg2.add_stream(pkts)
1556 self.pg_enable_capture(self.pg_interfaces)
1557 self.pg_start()
1558
1559 rx0 = self.pg0.get_capture(len(pkts))
1560
1561 #
1562 # enable the FIB walk process to converge the FIB
1563 #
1564 self.vapi.ppcli("test fib-walk-process enable")
1565
1566 #
1567 # packets should still be forwarded through the remaining peer
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(64)
1574
1575 #
1576 # Add the IGP route back and we return to load-balancing
1577 #
1578 core_10_0_0_46.add_vpp_config()
1579
1580 self.pg2.add_stream(pkts)
1581 self.pg_enable_capture(self.pg_interfaces)
1582 self.pg_start()
1583
1584 rx0 = self.pg0._get_capture(1)
1585 rx1 = self.pg1._get_capture(1)
1586 self.assertNotEqual(0, len(rx0))
1587 self.assertNotEqual(0, len(rx1))
1588
1589 def test_mpls_ebgp_pic(self):
1590 """ MPLS eBGP PIC edge convergence
1591
1592 1) setup many eBGP VPN routes via a pair of eBGP peers
1593 2) Check EMCP forwarding to these peers
1594 3) withdraw one eBGP path - expect LB across remaining eBGP
1595 """
1596
1597 #
1598 # Lot's of VPN routes. We need more the 64 so VPP will build
1599 # the fast convergence indirection
1600 #
1601 vpn_routes = []
1602 vpn_bindings = []
1603 pkts = []
1604 for ii in range(64):
1605 dst = "192.168.1.%d" % ii
1606 local_label = 1600 + ii
1607 vpn_routes.append(VppIpRoute(self, dst, 32,
1608 [VppRoutePath(self.pg2.remote_ip4,
1609 0xffffffff,
1610 nh_table_id=1,
1611 is_resolve_attached=1),
1612 VppRoutePath(self.pg3.remote_ip4,
1613 0xffffffff,
1614 nh_table_id=1,
1615 is_resolve_attached=1)],
1616 table_id=1))
1617 vpn_routes[ii].add_vpp_config()
1618
1619 vpn_bindings.append(VppMplsIpBind(self, local_label, dst, 32,
1620 ip_table_id=1))
1621 vpn_bindings[ii].add_vpp_config()
1622
1623 pkts.append(Ether(dst=self.pg0.local_mac,
1624 src=self.pg0.remote_mac) /
1625 MPLS(label=local_label, ttl=64) /
1626 IP(src=self.pg0.remote_ip4, dst=dst) /
1627 UDP(sport=1234, dport=1234) /
1628 Raw('\xa5' * 100))
1629
1630 self.pg0.add_stream(pkts)
1631 self.pg_enable_capture(self.pg_interfaces)
1632 self.pg_start()
1633
1634 rx0 = self.pg2._get_capture(1)
1635 rx1 = self.pg3._get_capture(1)
1636 self.assertNotEqual(0, len(rx0))
1637 self.assertNotEqual(0, len(rx1))
1638
1639 #
1640 # use a test CLI command to stop the FIB walk process, this
1641 # will prevent the FIB converging the VPN routes and thus allow
1642 # us to probe the interim (psot-fail, pre-converge) state
1643 #
1644 self.vapi.ppcli("test fib-walk-process disable")
1645
1646 #
1647 # withdraw the connected prefix on the interface.
1648 #
1649 self.pg2.unconfig_ip4()
1650
1651 #
1652 # now all packets should be forwarded through the remaining peer
1653 #
1654 self.pg0.add_stream(pkts)
1655 self.pg_enable_capture(self.pg_interfaces)
1656 self.pg_start()
1657
1658 rx0 = self.pg3.get_capture(len(pkts))
1659
1660 #
1661 # enable the FIB walk process to converge the FIB
1662 #
1663 self.vapi.ppcli("test fib-walk-process enable")
1664 self.pg0.add_stream(pkts)
1665 self.pg_enable_capture(self.pg_interfaces)
1666 self.pg_start()
1667
1668 rx0 = self.pg3.get_capture(len(pkts))
1669
1670 #
1671 # put the connecteds back
1672 #
1673 self.pg2.config_ip4()
1674
1675 self.pg0.add_stream(pkts)
1676 self.pg_enable_capture(self.pg_interfaces)
1677 self.pg_start()
1678
1679 rx0 = self.pg2._get_capture(1)
1680 rx1 = self.pg3._get_capture(1)
1681 self.assertNotEqual(0, len(rx0))
1682 self.assertNotEqual(0, len(rx1))
1683
1684 def test_mpls_v6_ebgp_pic(self):
1685 """ MPLSv6 eBGP PIC edge convergence
1686
1687 1) setup many eBGP VPNv6 routes via a pair of eBGP peers
1688 2) Check EMCP forwarding to these peers
1689 3) withdraw one eBGP path - expect LB across remaining eBGP
1690 """
1691
1692 #
1693 # Lot's of VPN routes. We need more the 64 so VPP will build
1694 # the fast convergence indirection
1695 #
1696 vpn_routes = []
1697 vpn_bindings = []
1698 pkts = []
1699 for ii in range(64):
1700 dst = "3000::%d" % ii
1701 local_label = 1600 + ii
Neale Rannsda78f952017-05-24 09:15:43 -07001702 vpn_routes.append(VppIpRoute(
1703 self, dst, 128,
1704 [VppRoutePath(self.pg2.remote_ip6,
1705 0xffffffff,
1706 nh_table_id=1,
1707 is_resolve_attached=1,
1708 proto=DpoProto.DPO_PROTO_IP6),
1709 VppRoutePath(self.pg3.remote_ip6,
1710 0xffffffff,
1711 nh_table_id=1,
1712 proto=DpoProto.DPO_PROTO_IP6,
1713 is_resolve_attached=1)],
1714 table_id=1,
1715 is_ip6=1))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001716 vpn_routes[ii].add_vpp_config()
1717
1718 vpn_bindings.append(VppMplsIpBind(self, local_label, dst, 128,
1719 ip_table_id=1,
1720 is_ip6=1))
1721 vpn_bindings[ii].add_vpp_config()
1722
1723 pkts.append(Ether(dst=self.pg0.local_mac,
1724 src=self.pg0.remote_mac) /
1725 MPLS(label=local_label, ttl=64) /
1726 IPv6(src=self.pg0.remote_ip6, dst=dst) /
1727 UDP(sport=1234, dport=1234) /
1728 Raw('\xa5' * 100))
1729
1730 self.pg0.add_stream(pkts)
1731 self.pg_enable_capture(self.pg_interfaces)
1732 self.pg_start()
1733
1734 rx0 = self.pg2._get_capture(1)
1735 rx1 = self.pg3._get_capture(1)
1736 self.assertNotEqual(0, len(rx0))
1737 self.assertNotEqual(0, len(rx1))
1738
1739 #
1740 # use a test CLI command to stop the FIB walk process, this
1741 # will prevent the FIB converging the VPN routes and thus allow
1742 # us to probe the interim (psot-fail, pre-converge) state
1743 #
1744 self.vapi.ppcli("test fib-walk-process disable")
1745
1746 #
1747 # withdraw the connected prefix on the interface.
1748 # and shutdown the interface so the ND cache is flushed.
1749 #
1750 self.pg2.unconfig_ip6()
1751 self.pg2.admin_down()
1752
1753 #
1754 # now all packets should be forwarded through the remaining peer
1755 #
1756 self.pg0.add_stream(pkts)
1757 self.pg_enable_capture(self.pg_interfaces)
1758 self.pg_start()
1759
1760 rx0 = self.pg3.get_capture(len(pkts))
1761
1762 #
1763 # enable the FIB walk process to converge the FIB
1764 #
1765 self.vapi.ppcli("test fib-walk-process enable")
1766 self.pg0.add_stream(pkts)
1767 self.pg_enable_capture(self.pg_interfaces)
1768 self.pg_start()
1769
1770 rx0 = self.pg3.get_capture(len(pkts))
1771
1772 #
1773 # put the connecteds back
1774 #
1775 self.pg2.admin_up()
1776 self.pg2.config_ip6()
1777
1778 self.pg0.add_stream(pkts)
1779 self.pg_enable_capture(self.pg_interfaces)
1780 self.pg_start()
1781
1782 rx0 = self.pg2._get_capture(1)
1783 rx1 = self.pg3._get_capture(1)
1784 self.assertNotEqual(0, len(rx0))
1785 self.assertNotEqual(0, len(rx1))
1786
1787
Neale Rannsda78f952017-05-24 09:15:43 -07001788class TestMPLSL2(VppTestCase):
1789 """ MPLS-L2 """
1790
1791 def setUp(self):
1792 super(TestMPLSL2, self).setUp()
1793
1794 # create 2 pg interfaces
1795 self.create_pg_interfaces(range(2))
1796
Neale Ranns15002542017-09-10 04:39:11 -07001797 # create the default MPLS table
1798 self.tables = []
1799 tbl = VppMplsTable(self, 0)
1800 tbl.add_vpp_config()
1801 self.tables.append(tbl)
1802
Neale Rannsda78f952017-05-24 09:15:43 -07001803 # use pg0 as the core facing interface
1804 self.pg0.admin_up()
1805 self.pg0.config_ip4()
1806 self.pg0.resolve_arp()
1807 self.pg0.enable_mpls()
1808
Neale Ranns15002542017-09-10 04:39:11 -07001809 # use the other 2 for customer facing L2 links
Neale Rannsda78f952017-05-24 09:15:43 -07001810 for i in self.pg_interfaces[1:]:
1811 i.admin_up()
1812
1813 def tearDown(self):
Neale Rannsda78f952017-05-24 09:15:43 -07001814 for i in self.pg_interfaces[1:]:
1815 i.admin_down()
1816
1817 self.pg0.disable_mpls()
1818 self.pg0.unconfig_ip4()
1819 self.pg0.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -07001820 super(TestMPLSL2, self).tearDown()
Neale Rannsda78f952017-05-24 09:15:43 -07001821
Neale Ranns31ed7442018-02-23 05:29:09 -08001822 def verify_capture_tunneled_ethernet(self, capture, sent, mpls_labels):
Neale Rannsda78f952017-05-24 09:15:43 -07001823 capture = verify_filter(capture, sent)
1824
1825 self.assertEqual(len(capture), len(sent))
1826
1827 for i in range(len(capture)):
1828 tx = sent[i]
1829 rx = capture[i]
1830
1831 # the MPLS TTL is 255 since it enters a new tunnel
Neale Ranns31ed7442018-02-23 05:29:09 -08001832 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsda78f952017-05-24 09:15:43 -07001833
1834 tx_eth = tx[Ether]
1835 rx_eth = Ether(str(rx[MPLS].payload))
1836
1837 self.assertEqual(rx_eth.src, tx_eth.src)
1838 self.assertEqual(rx_eth.dst, tx_eth.dst)
1839
1840 def test_vpws(self):
1841 """ Virtual Private Wire Service """
1842
1843 #
1844 # Create an MPLS tunnel that pushes 1 label
Neale Ranns31ed7442018-02-23 05:29:09 -08001845 # For Ethernet over MPLS the uniform mode is irrelevant since ttl/cos
1846 # information is not in the packet, but we test it works anyway
Neale Rannsda78f952017-05-24 09:15:43 -07001847 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001848 mpls_tun_1 = VppMPLSTunnelInterface(
1849 self,
1850 [VppRoutePath(self.pg0.remote_ip4,
1851 self.pg0.sw_if_index,
1852 labels=[VppMplsLabel(42, MplsLspMode.UNIFORM)])],
1853 is_l2=1)
Neale Rannsda78f952017-05-24 09:15:43 -07001854 mpls_tun_1.add_vpp_config()
1855 mpls_tun_1.admin_up()
1856
1857 #
1858 # Create a label entry to for 55 that does L2 input to the tunnel
1859 #
1860 route_55_eos = VppMplsRoute(
1861 self, 55, 1,
1862 [VppRoutePath("0.0.0.0",
1863 mpls_tun_1.sw_if_index,
1864 is_interface_rx=1,
1865 proto=DpoProto.DPO_PROTO_ETHERNET)])
1866 route_55_eos.add_vpp_config()
1867
1868 #
1869 # Cross-connect the tunnel with one of the customers L2 interfaces
1870 #
1871 self.vapi.sw_interface_set_l2_xconnect(self.pg1.sw_if_index,
1872 mpls_tun_1.sw_if_index,
1873 enable=1)
1874 self.vapi.sw_interface_set_l2_xconnect(mpls_tun_1.sw_if_index,
1875 self.pg1.sw_if_index,
1876 enable=1)
1877
1878 #
1879 # inject a packet from the core
1880 #
1881 pcore = (Ether(dst=self.pg0.local_mac,
1882 src=self.pg0.remote_mac) /
1883 MPLS(label=55, ttl=64) /
1884 Ether(dst="00:00:de:ad:ba:be",
1885 src="00:00:de:ad:be:ef") /
1886 IP(src="10.10.10.10", dst="11.11.11.11") /
1887 UDP(sport=1234, dport=1234) /
1888 Raw('\xa5' * 100))
1889
Neale Ranns31ed7442018-02-23 05:29:09 -08001890 tx0 = pcore * 65
1891 rx0 = self.send_and_expect(self.pg0, tx0, self.pg1)
1892 payload = pcore[MPLS].payload
Neale Rannsda78f952017-05-24 09:15:43 -07001893
Neale Ranns31ed7442018-02-23 05:29:09 -08001894 self.assertEqual(rx0[0][Ether].dst, payload[Ether].dst)
1895 self.assertEqual(rx0[0][Ether].src, payload[Ether].src)
Neale Rannsda78f952017-05-24 09:15:43 -07001896
1897 #
1898 # Inject a packet from the custoer/L2 side
1899 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001900 tx1 = pcore[MPLS].payload * 65
1901 rx1 = self.send_and_expect(self.pg1, tx1, self.pg0)
Neale Rannsda78f952017-05-24 09:15:43 -07001902
Neale Ranns31ed7442018-02-23 05:29:09 -08001903 self.verify_capture_tunneled_ethernet(rx1, tx1, [VppMplsLabel(42)])
Neale Rannsda78f952017-05-24 09:15:43 -07001904
1905 def test_vpls(self):
1906 """ Virtual Private LAN Service """
1907 #
1908 # Create an L2 MPLS tunnel
1909 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001910 mpls_tun = VppMPLSTunnelInterface(
1911 self,
1912 [VppRoutePath(self.pg0.remote_ip4,
1913 self.pg0.sw_if_index,
1914 labels=[VppMplsLabel(42)])],
1915 is_l2=1)
Neale Rannsda78f952017-05-24 09:15:43 -07001916 mpls_tun.add_vpp_config()
1917 mpls_tun.admin_up()
1918
1919 #
1920 # Create a label entry to for 55 that does L2 input to the tunnel
1921 #
1922 route_55_eos = VppMplsRoute(
1923 self, 55, 1,
1924 [VppRoutePath("0.0.0.0",
1925 mpls_tun.sw_if_index,
1926 is_interface_rx=1,
1927 proto=DpoProto.DPO_PROTO_ETHERNET)])
1928 route_55_eos.add_vpp_config()
1929
1930 #
1931 # add to tunnel to the customers bridge-domain
1932 #
1933 self.vapi.sw_interface_set_l2_bridge(mpls_tun.sw_if_index,
1934 bd_id=1)
1935 self.vapi.sw_interface_set_l2_bridge(self.pg1.sw_if_index,
1936 bd_id=1)
1937
1938 #
1939 # Packet from the customer interface and from the core
1940 #
1941 p_cust = (Ether(dst="00:00:de:ad:ba:be",
1942 src="00:00:de:ad:be:ef") /
1943 IP(src="10.10.10.10", dst="11.11.11.11") /
1944 UDP(sport=1234, dport=1234) /
1945 Raw('\xa5' * 100))
1946 p_core = (Ether(src="00:00:de:ad:ba:be",
1947 dst="00:00:de:ad:be:ef") /
1948 IP(dst="10.10.10.10", src="11.11.11.11") /
1949 UDP(sport=1234, dport=1234) /
1950 Raw('\xa5' * 100))
1951
1952 #
1953 # The BD is learning, so send in one of each packet to learn
1954 #
1955 p_core_encap = (Ether(dst=self.pg0.local_mac,
1956 src=self.pg0.remote_mac) /
1957 MPLS(label=55, ttl=64) /
1958 p_core)
1959
1960 self.pg1.add_stream(p_cust)
1961 self.pg_enable_capture(self.pg_interfaces)
1962 self.pg_start()
1963 self.pg0.add_stream(p_core_encap)
1964 self.pg_enable_capture(self.pg_interfaces)
1965 self.pg_start()
1966
1967 # we've learnt this so expect it be be forwarded
1968 rx0 = self.pg1.get_capture(1)
1969
1970 self.assertEqual(rx0[0][Ether].dst, p_core[Ether].dst)
1971 self.assertEqual(rx0[0][Ether].src, p_core[Ether].src)
1972
1973 #
1974 # now a stream in each direction
1975 #
1976 self.pg1.add_stream(p_cust * 65)
1977 self.pg_enable_capture(self.pg_interfaces)
1978 self.pg_start()
1979
1980 rx0 = self.pg0.get_capture(65)
1981
Neale Ranns31ed7442018-02-23 05:29:09 -08001982 self.verify_capture_tunneled_ethernet(rx0, p_cust*65,
1983 [VppMplsLabel(42)])
Neale Rannsda78f952017-05-24 09:15:43 -07001984
1985 #
1986 # remove interfaces from customers bridge-domain
1987 #
1988 self.vapi.sw_interface_set_l2_bridge(mpls_tun.sw_if_index,
1989 bd_id=1,
1990 enable=0)
1991 self.vapi.sw_interface_set_l2_bridge(self.pg1.sw_if_index,
1992 bd_id=1,
1993 enable=0)
1994
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001995if __name__ == '__main__':
1996 unittest.main(testRunner=VppTestRunner)