blob: ad2620b1b50bd9b712e6f1fb20ae481745c926b6 [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 Ranns31ed7442018-02-23 05:29:09 -080011 VppMplsLabel, MplsLspMode
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012from vpp_mpls_tunnel_interface import VppMPLSTunnelInterface
Neale Ranns8fe8cc22016-11-01 10:05:08 +000013
14from scapy.packet import Raw
Klement Sekera7bb873a2016-11-18 07:38:42 +010015from scapy.layers.l2 import Ether
Neale Rannscb630ff2016-12-14 13:31:29 +010016from scapy.layers.inet import IP, UDP, ICMP
Neale Ranns62fe07c2017-10-31 12:28:22 -070017from scapy.layers.inet6 import IPv6, ICMPv6TimeExceeded
Neale Ranns8fe8cc22016-11-01 10:05:08 +000018from scapy.contrib.mpls import MPLS
19
Klement Sekeradab231a2016-12-21 08:50:14 +010020
Neale Rannsda78f952017-05-24 09:15:43 -070021def verify_filter(capture, sent):
22 if not len(capture) == len(sent):
23 # filter out any IPv6 RAs from the capture
24 for p in capture:
25 if p.haslayer(IPv6):
26 capture.remove(p)
27 return capture
28
29
Neale Ranns31ed7442018-02-23 05:29:09 -080030def verify_mpls_stack(tst, rx, mpls_labels):
Neale Rannsda78f952017-05-24 09:15:43 -070031 # the rx'd packet has the MPLS label popped
32 eth = rx[Ether]
33 tst.assertEqual(eth.type, 0x8847)
34
35 rx_mpls = rx[MPLS]
36
37 for ii in range(len(mpls_labels)):
Neale Ranns31ed7442018-02-23 05:29:09 -080038 tst.assertEqual(rx_mpls.label, mpls_labels[ii].value)
39 tst.assertEqual(rx_mpls.cos, mpls_labels[ii].exp)
40 tst.assertEqual(rx_mpls.ttl, mpls_labels[ii].ttl)
41
Neale Rannsda78f952017-05-24 09:15:43 -070042 if ii == len(mpls_labels) - 1:
43 tst.assertEqual(rx_mpls.s, 1)
44 else:
45 # not end of stack
46 tst.assertEqual(rx_mpls.s, 0)
47 # pop the label to expose the next
48 rx_mpls = rx_mpls[MPLS].payload
49
50
Neale Ranns8fe8cc22016-11-01 10:05:08 +000051class TestMPLS(VppTestCase):
52 """ MPLS Test Case """
53
Neale Ranns8fe8cc22016-11-01 10:05:08 +000054 def setUp(self):
55 super(TestMPLS, self).setUp()
56
57 # create 2 pg interfaces
Neale Ranns0f26c5a2017-03-01 15:12:11 -080058 self.create_pg_interfaces(range(4))
Neale Ranns8fe8cc22016-11-01 10:05:08 +000059
60 # setup both interfaces
61 # assign them different tables.
62 table_id = 0
Neale Ranns15002542017-09-10 04:39:11 -070063 self.tables = []
64
65 tbl = VppMplsTable(self, 0)
66 tbl.add_vpp_config()
67 self.tables.append(tbl)
Neale Ranns8fe8cc22016-11-01 10:05:08 +000068
69 for i in self.pg_interfaces:
70 i.admin_up()
Neale Ranns15002542017-09-10 04:39:11 -070071
72 if table_id != 0:
73 tbl = VppIpTable(self, table_id)
74 tbl.add_vpp_config()
75 self.tables.append(tbl)
76 tbl = VppIpTable(self, table_id, is_ip6=1)
77 tbl.add_vpp_config()
78 self.tables.append(tbl)
79
Neale Ranns8fe8cc22016-11-01 10:05:08 +000080 i.set_table_ip4(table_id)
81 i.set_table_ip6(table_id)
82 i.config_ip4()
Neale Ranns8fe8cc22016-11-01 10:05:08 +000083 i.resolve_arp()
Neale Rannsad422ed2016-11-02 14:20:04 +000084 i.config_ip6()
Neale Ranns8fe8cc22016-11-01 10:05:08 +000085 i.resolve_ndp()
Neale Rannsad422ed2016-11-02 14:20:04 +000086 i.enable_mpls()
Neale Ranns8fe8cc22016-11-01 10:05:08 +000087 table_id += 1
88
89 def tearDown(self):
Neale Ranns4008ac92017-02-13 23:20:04 -080090 for i in self.pg_interfaces:
91 i.unconfig_ip4()
92 i.unconfig_ip6()
93 i.ip6_disable()
Neale Ranns15002542017-09-10 04:39:11 -070094 i.set_table_ip4(0)
95 i.set_table_ip6(0)
96 i.disable_mpls()
Neale Ranns4008ac92017-02-13 23:20:04 -080097 i.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -070098 super(TestMPLS, self).tearDown()
Neale Ranns8fe8cc22016-11-01 10:05:08 +000099
Neale Rannsad422ed2016-11-02 14:20:04 +0000100 # the default of 64 matches the IP packet TTL default
Klement Sekeradab231a2016-12-21 08:50:14 +0100101 def create_stream_labelled_ip4(
102 self,
103 src_if,
104 mpls_labels,
Klement Sekeradab231a2016-12-21 08:50:14 +0100105 ping=0,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800106 ip_itf=None,
107 dst_ip=None,
Neale Ranns4c7c8e52017-10-21 09:37:55 -0700108 chksum=None,
Neale Ranns31ed7442018-02-23 05:29:09 -0800109 ip_ttl=64,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800110 n=257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100111 self.reset_packet_infos()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000112 pkts = []
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800113 for i in range(0, n):
Klement Sekeradab231a2016-12-21 08:50:14 +0100114 info = self.create_packet_info(src_if, src_if)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000115 payload = self.info_to_payload(info)
Neale Rannsad422ed2016-11-02 14:20:04 +0000116 p = Ether(dst=src_if.local_mac, src=src_if.remote_mac)
117
118 for ii in range(len(mpls_labels)):
Neale Ranns31ed7442018-02-23 05:29:09 -0800119 p = p / MPLS(label=mpls_labels[ii].value,
120 ttl=mpls_labels[ii].ttl,
121 cos=mpls_labels[ii].exp)
Neale Rannscb630ff2016-12-14 13:31:29 +0100122 if not ping:
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800123 if not dst_ip:
Neale Ranns31ed7442018-02-23 05:29:09 -0800124 p = (p / IP(src=src_if.local_ip4,
125 dst=src_if.remote_ip4,
126 ttl=ip_ttl) /
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800127 UDP(sport=1234, dport=1234) /
128 Raw(payload))
129 else:
Neale Ranns31ed7442018-02-23 05:29:09 -0800130 p = (p / IP(src=src_if.local_ip4, dst=dst_ip, ttl=ip_ttl) /
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800131 UDP(sport=1234, dport=1234) /
132 Raw(payload))
Neale Rannscb630ff2016-12-14 13:31:29 +0100133 else:
134 p = (p / IP(src=ip_itf.remote_ip4,
Neale Ranns31ed7442018-02-23 05:29:09 -0800135 dst=ip_itf.local_ip4,
136 ttl=ip_ttl) /
Neale Rannscb630ff2016-12-14 13:31:29 +0100137 ICMP())
138
Neale Ranns4c7c8e52017-10-21 09:37:55 -0700139 if chksum:
140 p[IP].chksum = chksum
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000141 info.data = p.copy()
142 pkts.append(p)
143 return pkts
144
Neale Ranns31ed7442018-02-23 05:29:09 -0800145 def create_stream_ip4(self, src_if, dst_ip, ip_ttl=64, ip_dscp=0):
Klement Sekeradab231a2016-12-21 08:50:14 +0100146 self.reset_packet_infos()
Neale Rannsad422ed2016-11-02 14:20:04 +0000147 pkts = []
148 for i in range(0, 257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100149 info = self.create_packet_info(src_if, src_if)
Neale Rannsad422ed2016-11-02 14:20:04 +0000150 payload = self.info_to_payload(info)
151 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
Neale Ranns31ed7442018-02-23 05:29:09 -0800152 IP(src=src_if.remote_ip4, dst=dst_ip,
153 ttl=ip_ttl, tos=ip_dscp) /
Neale Rannsad422ed2016-11-02 14:20:04 +0000154 UDP(sport=1234, dport=1234) /
155 Raw(payload))
156 info.data = p.copy()
157 pkts.append(p)
158 return pkts
159
Neale Ranns31ed7442018-02-23 05:29:09 -0800160 def create_stream_ip6(self, src_if, dst_ip, ip_ttl=64, ip_dscp=0):
161 self.reset_packet_infos()
162 pkts = []
163 for i in range(0, 257):
164 info = self.create_packet_info(src_if, src_if)
165 payload = self.info_to_payload(info)
166 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
167 IPv6(src=src_if.remote_ip6, dst=dst_ip,
168 hlim=ip_ttl, tc=ip_dscp) /
169 UDP(sport=1234, dport=1234) /
170 Raw(payload))
171 info.data = p.copy()
172 pkts.append(p)
173 return pkts
174
175 def create_stream_labelled_ip6(self, src_if, mpls_labels,
176 hlim=64, dst_ip=None):
Neale Ranns31426c62017-05-24 10:32:58 -0700177 if dst_ip is None:
178 dst_ip = src_if.remote_ip6
Klement Sekeradab231a2016-12-21 08:50:14 +0100179 self.reset_packet_infos()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000180 pkts = []
181 for i in range(0, 257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100182 info = self.create_packet_info(src_if, src_if)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000183 payload = self.info_to_payload(info)
Neale Ranns31ed7442018-02-23 05:29:09 -0800184 p = Ether(dst=src_if.local_mac, src=src_if.remote_mac)
185 for l in mpls_labels:
186 p = p / MPLS(label=l.value, ttl=l.ttl, cos=l.exp)
187
188 p = p / (IPv6(src=src_if.remote_ip6, dst=dst_ip, hlim=hlim) /
189 UDP(sport=1234, dport=1234) /
190 Raw(payload))
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000191 info.data = p.copy()
192 pkts.append(p)
193 return pkts
194
Neale Ranns31ed7442018-02-23 05:29:09 -0800195 def verify_capture_ip4(self, src_if, capture, sent, ping_resp=0,
196 ip_ttl=None, ip_dscp=0):
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000197 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700198 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000199
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000200 self.assertEqual(len(capture), len(sent))
201
202 for i in range(len(capture)):
203 tx = sent[i]
204 rx = capture[i]
205
206 # the rx'd packet has the MPLS label popped
Neale Rannsad422ed2016-11-02 14:20:04 +0000207 eth = rx[Ether]
208 self.assertEqual(eth.type, 0x800)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000209
210 tx_ip = tx[IP]
211 rx_ip = rx[IP]
212
Neale Rannscb630ff2016-12-14 13:31:29 +0100213 if not ping_resp:
214 self.assertEqual(rx_ip.src, tx_ip.src)
215 self.assertEqual(rx_ip.dst, tx_ip.dst)
Neale Ranns31ed7442018-02-23 05:29:09 -0800216 self.assertEqual(rx_ip.tos, ip_dscp)
217 if not ip_ttl:
218 # IP processing post pop has decremented the TTL
219 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
220 else:
221 self.assertEqual(rx_ip.ttl, ip_ttl)
Neale Rannscb630ff2016-12-14 13:31:29 +0100222 else:
223 self.assertEqual(rx_ip.src, tx_ip.dst)
224 self.assertEqual(rx_ip.dst, tx_ip.src)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000225
226 except:
Neale Rannsad422ed2016-11-02 14:20:04 +0000227 raise
228
Neale Rannsad422ed2016-11-02 14:20:04 +0000229 def verify_capture_labelled_ip4(self, src_if, capture, sent,
Neale Ranns31ed7442018-02-23 05:29:09 -0800230 mpls_labels, ip_ttl=None):
Neale Rannsad422ed2016-11-02 14:20:04 +0000231 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700232 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000233
234 self.assertEqual(len(capture), len(sent))
235
236 for i in range(len(capture)):
237 tx = sent[i]
238 rx = capture[i]
239 tx_ip = tx[IP]
240 rx_ip = rx[IP]
241
Neale Ranns31ed7442018-02-23 05:29:09 -0800242 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsad422ed2016-11-02 14:20:04 +0000243
244 self.assertEqual(rx_ip.src, tx_ip.src)
245 self.assertEqual(rx_ip.dst, tx_ip.dst)
Neale Ranns31ed7442018-02-23 05:29:09 -0800246 if not ip_ttl:
247 # IP processing post pop has decremented the TTL
248 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
249 else:
250 self.assertEqual(rx_ip.ttl, ip_ttl)
Neale Rannsad422ed2016-11-02 14:20:04 +0000251
252 except:
253 raise
254
Neale Ranns31ed7442018-02-23 05:29:09 -0800255 def verify_capture_labelled_ip6(self, src_if, capture, sent,
256 mpls_labels, ip_ttl=None):
257 try:
258 capture = verify_filter(capture, sent)
259
260 self.assertEqual(len(capture), len(sent))
261
262 for i in range(len(capture)):
263 tx = sent[i]
264 rx = capture[i]
265 tx_ip = tx[IPv6]
266 rx_ip = rx[IPv6]
267
268 verify_mpls_stack(self, rx, mpls_labels)
269
270 self.assertEqual(rx_ip.src, tx_ip.src)
271 self.assertEqual(rx_ip.dst, tx_ip.dst)
272 if not ip_ttl:
273 # IP processing post pop has decremented the TTL
274 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
275 else:
276 self.assertEqual(rx_ip.hlim, ip_ttl)
277
278 except:
279 raise
280
281 def verify_capture_tunneled_ip4(self, src_if, capture, sent, mpls_labels):
Neale Rannsad422ed2016-11-02 14:20:04 +0000282 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700283 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000284
285 self.assertEqual(len(capture), len(sent))
286
287 for i in range(len(capture)):
288 tx = sent[i]
289 rx = capture[i]
290 tx_ip = tx[IP]
291 rx_ip = rx[IP]
292
Neale Ranns31ed7442018-02-23 05:29:09 -0800293 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsad422ed2016-11-02 14:20:04 +0000294
295 self.assertEqual(rx_ip.src, tx_ip.src)
296 self.assertEqual(rx_ip.dst, tx_ip.dst)
297 # IP processing post pop has decremented the TTL
298 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
299
300 except:
301 raise
302
303 def verify_capture_labelled(self, src_if, capture, sent,
Neale Ranns31ed7442018-02-23 05:29:09 -0800304 mpls_labels):
Neale Rannsad422ed2016-11-02 14:20:04 +0000305 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700306 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000307
308 self.assertEqual(len(capture), len(sent))
309
310 for i in range(len(capture)):
311 rx = capture[i]
Neale Ranns31ed7442018-02-23 05:29:09 -0800312 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsad422ed2016-11-02 14:20:04 +0000313 except:
314 raise
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000315
Neale Ranns31ed7442018-02-23 05:29:09 -0800316 def verify_capture_ip6(self, src_if, capture, sent,
317 ip_hlim=None, ip_dscp=0):
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000318 try:
319 self.assertEqual(len(capture), len(sent))
320
321 for i in range(len(capture)):
322 tx = sent[i]
323 rx = capture[i]
324
325 # the rx'd packet has the MPLS label popped
Neale Rannsad422ed2016-11-02 14:20:04 +0000326 eth = rx[Ether]
327 self.assertEqual(eth.type, 0x86DD)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000328
329 tx_ip = tx[IPv6]
330 rx_ip = rx[IPv6]
331
332 self.assertEqual(rx_ip.src, tx_ip.src)
333 self.assertEqual(rx_ip.dst, tx_ip.dst)
Neale Ranns31ed7442018-02-23 05:29:09 -0800334 self.assertEqual(rx_ip.tc, ip_dscp)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000335 # IP processing post pop has decremented the TTL
Neale Ranns31ed7442018-02-23 05:29:09 -0800336 if not ip_hlim:
337 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
338 else:
339 self.assertEqual(rx_ip.hlim, ip_hlim)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000340
341 except:
Neale Rannsad422ed2016-11-02 14:20:04 +0000342 raise
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000343
Neale Ranns62fe07c2017-10-31 12:28:22 -0700344 def verify_capture_ip6_icmp(self, src_if, capture, sent):
345 try:
346 self.assertEqual(len(capture), len(sent))
347
348 for i in range(len(capture)):
349 tx = sent[i]
350 rx = capture[i]
351
352 # the rx'd packet has the MPLS label popped
353 eth = rx[Ether]
354 self.assertEqual(eth.type, 0x86DD)
355
356 tx_ip = tx[IPv6]
357 rx_ip = rx[IPv6]
358
359 self.assertEqual(rx_ip.dst, tx_ip.src)
360 # ICMP sourced from the interface's address
361 self.assertEqual(rx_ip.src, src_if.local_ip6)
362 # hop-limit reset to 255 for IMCP packet
Ole Troan282093f2018-09-19 12:38:51 +0200363 self.assertEqual(rx_ip.hlim, 255)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700364
365 icmp = rx[ICMPv6TimeExceeded]
366
367 except:
368 raise
369
Neale Rannsad422ed2016-11-02 14:20:04 +0000370 def test_swap(self):
371 """ MPLS label swap tests """
372
373 #
374 # A simple MPLS xconnect - eos label in label out
375 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800376 route_32_eos = VppMplsRoute(self, 32, 1,
377 [VppRoutePath(self.pg0.remote_ip4,
378 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800379 labels=[VppMplsLabel(33)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000380 route_32_eos.add_vpp_config()
381
382 #
383 # a stream that matches the route for 10.0.0.1
384 # PG0 is in the default table
385 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800386 tx = self.create_stream_labelled_ip4(self.pg0,
387 [VppMplsLabel(32, ttl=32, exp=1)])
388 rx = self.send_and_expect(self.pg0, tx, self.pg0)
389 self.verify_capture_labelled(self.pg0, rx, tx,
390 [VppMplsLabel(33, ttl=31, exp=1)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000391
Neale Ranns008dbe12018-09-07 09:32:36 -0700392 self.assertEqual(route_32_eos.get_stats_to()['packets'], 257)
393
Neale Rannsad422ed2016-11-02 14:20:04 +0000394 #
395 # A simple MPLS xconnect - non-eos label in label out
396 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800397 route_32_neos = VppMplsRoute(self, 32, 0,
398 [VppRoutePath(self.pg0.remote_ip4,
399 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800400 labels=[VppMplsLabel(33)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000401 route_32_neos.add_vpp_config()
402
403 #
404 # a stream that matches the route for 10.0.0.1
405 # PG0 is in the default table
406 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800407 tx = self.create_stream_labelled_ip4(self.pg0,
408 [VppMplsLabel(32, ttl=21, exp=7),
409 VppMplsLabel(99)])
410 rx = self.send_and_expect(self.pg0, tx, self.pg0)
411 self.verify_capture_labelled(self.pg0, rx, tx,
412 [VppMplsLabel(33, ttl=20, exp=7),
413 VppMplsLabel(99)])
Neale Ranns008dbe12018-09-07 09:32:36 -0700414 self.assertEqual(route_32_neos.get_stats_to()['packets'], 257)
Neale Rannsad422ed2016-11-02 14:20:04 +0000415
Neale Ranns31ed7442018-02-23 05:29:09 -0800416 #
417 # A simple MPLS xconnect - non-eos label in label out, uniform mode
418 #
419 route_42_neos = VppMplsRoute(
420 self, 42, 0,
421 [VppRoutePath(self.pg0.remote_ip4,
422 self.pg0.sw_if_index,
423 labels=[VppMplsLabel(43, MplsLspMode.UNIFORM)])])
424 route_42_neos.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000425
Neale Ranns31ed7442018-02-23 05:29:09 -0800426 tx = self.create_stream_labelled_ip4(self.pg0,
427 [VppMplsLabel(42, ttl=21, exp=7),
428 VppMplsLabel(99)])
429 rx = self.send_and_expect(self.pg0, tx, self.pg0)
430 self.verify_capture_labelled(self.pg0, rx, tx,
431 [VppMplsLabel(43, ttl=20, exp=7),
432 VppMplsLabel(99)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000433
434 #
435 # An MPLS xconnect - EOS label in IP out
436 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800437 route_33_eos = VppMplsRoute(self, 33, 1,
438 [VppRoutePath(self.pg0.remote_ip4,
439 self.pg0.sw_if_index,
440 labels=[])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000441 route_33_eos.add_vpp_config()
442
Neale Ranns31ed7442018-02-23 05:29:09 -0800443 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(33)])
444 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Rannsad422ed2016-11-02 14:20:04 +0000445 self.verify_capture_ip4(self.pg0, rx, tx)
446
447 #
Neale Ranns62fe07c2017-10-31 12:28:22 -0700448 # disposed packets have an invalid IPv4 checkusm
449 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800450 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(33)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700451 dst_ip=self.pg0.remote_ip4,
452 n=65,
453 chksum=1)
454 self.send_and_assert_no_replies(self.pg0, tx, "Invalid Checksum")
455
456 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800457 # An MPLS xconnect - EOS label in IP out, uniform mode
458 #
459 route_3333_eos = VppMplsRoute(
460 self, 3333, 1,
461 [VppRoutePath(self.pg0.remote_ip4,
462 self.pg0.sw_if_index,
463 labels=[VppMplsLabel(3, MplsLspMode.UNIFORM)])])
464 route_3333_eos.add_vpp_config()
465
466 tx = self.create_stream_labelled_ip4(
467 self.pg0,
468 [VppMplsLabel(3333, ttl=55, exp=3)])
469 rx = self.send_and_expect(self.pg0, tx, self.pg0)
470 self.verify_capture_ip4(self.pg0, rx, tx, ip_ttl=54, ip_dscp=0x60)
471 tx = self.create_stream_labelled_ip4(
472 self.pg0,
473 [VppMplsLabel(3333, ttl=66, exp=4)])
474 rx = self.send_and_expect(self.pg0, tx, self.pg0)
475 self.verify_capture_ip4(self.pg0, rx, tx, ip_ttl=65, ip_dscp=0x80)
476
477 #
Neale Ranns62fe07c2017-10-31 12:28:22 -0700478 # An MPLS xconnect - EOS label in IPv6 out
479 #
480 route_333_eos = VppMplsRoute(
481 self, 333, 1,
482 [VppRoutePath(self.pg0.remote_ip6,
483 self.pg0.sw_if_index,
484 labels=[],
485 proto=DpoProto.DPO_PROTO_IP6)])
486 route_333_eos.add_vpp_config()
487
Neale Ranns31ed7442018-02-23 05:29:09 -0800488 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(333)])
489 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700490 self.verify_capture_ip6(self.pg0, rx, tx)
491
492 #
493 # disposed packets have an TTL expired
494 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800495 tx = self.create_stream_labelled_ip6(self.pg0,
496 [VppMplsLabel(333, ttl=64)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700497 dst_ip=self.pg1.remote_ip6,
498 hlim=1)
Neale Ranns31ed7442018-02-23 05:29:09 -0800499 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700500 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
501
502 #
503 # An MPLS xconnect - EOS label in IPv6 out w imp-null
504 #
505 route_334_eos = VppMplsRoute(
506 self, 334, 1,
507 [VppRoutePath(self.pg0.remote_ip6,
508 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800509 labels=[VppMplsLabel(3)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700510 proto=DpoProto.DPO_PROTO_IP6)])
511 route_334_eos.add_vpp_config()
512
Neale Ranns31ed7442018-02-23 05:29:09 -0800513 tx = self.create_stream_labelled_ip6(self.pg0,
514 [VppMplsLabel(334, ttl=64)])
515 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700516 self.verify_capture_ip6(self.pg0, rx, tx)
517
518 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800519 # An MPLS xconnect - EOS label in IPv6 out w imp-null in uniform mode
520 #
521 route_335_eos = VppMplsRoute(
522 self, 335, 1,
523 [VppRoutePath(self.pg0.remote_ip6,
524 self.pg0.sw_if_index,
525 labels=[VppMplsLabel(3, MplsLspMode.UNIFORM)],
526 proto=DpoProto.DPO_PROTO_IP6)])
527 route_335_eos.add_vpp_config()
528
529 tx = self.create_stream_labelled_ip6(
530 self.pg0,
531 [VppMplsLabel(335, ttl=27, exp=4)])
532 rx = self.send_and_expect(self.pg0, tx, self.pg0)
533 self.verify_capture_ip6(self.pg0, rx, tx, ip_hlim=26, ip_dscp=0x80)
534
535 #
Neale Ranns62fe07c2017-10-31 12:28:22 -0700536 # disposed packets have an TTL expired
537 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800538 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(334)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700539 dst_ip=self.pg1.remote_ip6,
540 hlim=0)
Neale Ranns31ed7442018-02-23 05:29:09 -0800541 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700542 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
543
544 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000545 # An MPLS xconnect - non-EOS label in IP out - an invalid configuration
546 # so this traffic should be dropped.
547 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800548 route_33_neos = VppMplsRoute(self, 33, 0,
549 [VppRoutePath(self.pg0.remote_ip4,
550 self.pg0.sw_if_index,
551 labels=[])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000552 route_33_neos.add_vpp_config()
553
Neale Ranns31ed7442018-02-23 05:29:09 -0800554 tx = self.create_stream_labelled_ip4(self.pg0,
555 [VppMplsLabel(33),
556 VppMplsLabel(99)])
557 self.send_and_assert_no_replies(
558 self.pg0, tx,
559 "MPLS non-EOS packets popped and forwarded")
Neale Rannsad422ed2016-11-02 14:20:04 +0000560
561 #
562 # A recursive EOS x-connect, which resolves through another x-connect
Neale Ranns31ed7442018-02-23 05:29:09 -0800563 # in pipe mode
Neale Rannsad422ed2016-11-02 14:20:04 +0000564 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800565 route_34_eos = VppMplsRoute(self, 34, 1,
566 [VppRoutePath("0.0.0.0",
567 0xffffffff,
568 nh_via_label=32,
Neale Ranns31ed7442018-02-23 05:29:09 -0800569 labels=[VppMplsLabel(44),
570 VppMplsLabel(45)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000571 route_34_eos.add_vpp_config()
572
Neale Ranns31ed7442018-02-23 05:29:09 -0800573 tx = self.create_stream_labelled_ip4(self.pg0,
574 [VppMplsLabel(34, ttl=3)])
575 rx = self.send_and_expect(self.pg0, tx, self.pg0)
576 self.verify_capture_labelled(self.pg0, rx, tx,
577 [VppMplsLabel(33),
578 VppMplsLabel(44),
579 VppMplsLabel(45, ttl=2)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000580
Neale Ranns008dbe12018-09-07 09:32:36 -0700581 self.assertEqual(route_34_eos.get_stats_to()['packets'], 257)
582 self.assertEqual(route_32_neos.get_stats_via()['packets'], 257)
583
Neale Ranns31ed7442018-02-23 05:29:09 -0800584 #
585 # A recursive EOS x-connect, which resolves through another x-connect
586 # in uniform mode
587 #
588 route_35_eos = VppMplsRoute(
589 self, 35, 1,
590 [VppRoutePath("0.0.0.0",
591 0xffffffff,
592 nh_via_label=42,
593 labels=[VppMplsLabel(44)])])
594 route_35_eos.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000595
Neale Ranns31ed7442018-02-23 05:29:09 -0800596 tx = self.create_stream_labelled_ip4(self.pg0,
597 [VppMplsLabel(35, ttl=3)])
598 rx = self.send_and_expect(self.pg0, tx, self.pg0)
599 self.verify_capture_labelled(self.pg0, rx, tx,
600 [VppMplsLabel(43, ttl=2),
601 VppMplsLabel(44, ttl=2)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000602
603 #
Matej Klottondeb69842016-12-09 15:05:46 +0100604 # A recursive non-EOS x-connect, which resolves through another
605 # x-connect
Neale Rannsad422ed2016-11-02 14:20:04 +0000606 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800607 route_34_neos = VppMplsRoute(self, 34, 0,
608 [VppRoutePath("0.0.0.0",
609 0xffffffff,
610 nh_via_label=32,
Neale Ranns31ed7442018-02-23 05:29:09 -0800611 labels=[VppMplsLabel(44),
612 VppMplsLabel(46)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000613 route_34_neos.add_vpp_config()
614
Neale Ranns31ed7442018-02-23 05:29:09 -0800615 tx = self.create_stream_labelled_ip4(self.pg0,
616 [VppMplsLabel(34, ttl=45),
617 VppMplsLabel(99)])
618 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Matej Klottondeb69842016-12-09 15:05:46 +0100619 # it's the 2nd (counting from 0) label in the stack that is swapped
Neale Ranns31ed7442018-02-23 05:29:09 -0800620 self.verify_capture_labelled(self.pg0, rx, tx,
621 [VppMplsLabel(33),
622 VppMplsLabel(44),
623 VppMplsLabel(46, ttl=44),
624 VppMplsLabel(99)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000625
626 #
Matej Klottondeb69842016-12-09 15:05:46 +0100627 # an recursive IP route that resolves through the recursive non-eos
628 # x-connect
Neale Rannsad422ed2016-11-02 14:20:04 +0000629 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800630 ip_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
631 [VppRoutePath("0.0.0.0",
632 0xffffffff,
633 nh_via_label=34,
Neale Ranns31ed7442018-02-23 05:29:09 -0800634 labels=[VppMplsLabel(55)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000635 ip_10_0_0_1.add_vpp_config()
636
Neale Rannsad422ed2016-11-02 14:20:04 +0000637 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800638 rx = self.send_and_expect(self.pg0, tx, self.pg0)
639 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
640 [VppMplsLabel(33),
641 VppMplsLabel(44),
642 VppMplsLabel(46),
643 VppMplsLabel(55)])
Neale Ranns008dbe12018-09-07 09:32:36 -0700644 self.assertEqual(ip_10_0_0_1.get_stats_to()['packets'], 257)
Neale Rannsad422ed2016-11-02 14:20:04 +0000645
646 ip_10_0_0_1.remove_vpp_config()
647 route_34_neos.remove_vpp_config()
648 route_34_eos.remove_vpp_config()
649 route_33_neos.remove_vpp_config()
650 route_33_eos.remove_vpp_config()
651 route_32_neos.remove_vpp_config()
652 route_32_eos.remove_vpp_config()
653
654 def test_bind(self):
655 """ MPLS Local Label Binding test """
656
657 #
658 # Add a non-recursive route with a single out label
659 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800660 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
661 [VppRoutePath(self.pg0.remote_ip4,
662 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800663 labels=[VppMplsLabel(45)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000664 route_10_0_0_1.add_vpp_config()
665
666 # bind a local label to the route
Neale Ranns5a8123b2017-01-26 01:18:23 -0800667 binding = VppMplsIpBind(self, 44, "10.0.0.1", 32)
Neale Rannsad422ed2016-11-02 14:20:04 +0000668 binding.add_vpp_config()
669
670 # non-EOS stream
Neale Ranns31ed7442018-02-23 05:29:09 -0800671 tx = self.create_stream_labelled_ip4(self.pg0,
672 [VppMplsLabel(44),
673 VppMplsLabel(99)])
674 rx = self.send_and_expect(self.pg0, tx, self.pg0)
675 self.verify_capture_labelled(self.pg0, rx, tx,
676 [VppMplsLabel(45, ttl=63),
677 VppMplsLabel(99)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000678
679 # EOS stream
Neale Ranns31ed7442018-02-23 05:29:09 -0800680 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(44)])
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)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000684
685 # IP stream
Neale Rannsad422ed2016-11-02 14:20:04 +0000686 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800687 rx = self.send_and_expect(self.pg0, tx, self.pg0)
688 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [VppMplsLabel(45)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000689
690 #
691 # cleanup
692 #
693 binding.remove_vpp_config()
694 route_10_0_0_1.remove_vpp_config()
695
696 def test_imposition(self):
697 """ MPLS label imposition test """
698
699 #
700 # Add a non-recursive route with a single out label
701 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800702 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
703 [VppRoutePath(self.pg0.remote_ip4,
704 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800705 labels=[VppMplsLabel(32)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000706 route_10_0_0_1.add_vpp_config()
707
708 #
709 # a stream that matches the route for 10.0.0.1
710 # PG0 is in the default table
711 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000712 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800713 rx = self.send_and_expect(self.pg0, tx, self.pg0)
714 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [VppMplsLabel(32)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000715
716 #
717 # Add a non-recursive route with a 3 out labels
718 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800719 route_10_0_0_2 = VppIpRoute(self, "10.0.0.2", 32,
720 [VppRoutePath(self.pg0.remote_ip4,
721 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800722 labels=[VppMplsLabel(32),
723 VppMplsLabel(33),
724 VppMplsLabel(34)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000725 route_10_0_0_2.add_vpp_config()
726
Neale Ranns31ed7442018-02-23 05:29:09 -0800727 tx = self.create_stream_ip4(self.pg0, "10.0.0.2",
728 ip_ttl=44, ip_dscp=0xff)
729 rx = self.send_and_expect(self.pg0, tx, self.pg0)
730 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
731 [VppMplsLabel(32),
732 VppMplsLabel(33),
733 VppMplsLabel(34)],
734 ip_ttl=43)
Neale Rannsad422ed2016-11-02 14:20:04 +0000735
Neale Ranns31ed7442018-02-23 05:29:09 -0800736 #
737 # Add a non-recursive route with a single out label in uniform mode
738 #
739 route_10_0_0_3 = VppIpRoute(
740 self, "10.0.0.3", 32,
741 [VppRoutePath(self.pg0.remote_ip4,
742 self.pg0.sw_if_index,
743 labels=[VppMplsLabel(32,
744 mode=MplsLspMode.UNIFORM)])])
745 route_10_0_0_3.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000746
Neale Ranns31ed7442018-02-23 05:29:09 -0800747 tx = self.create_stream_ip4(self.pg0, "10.0.0.3",
748 ip_ttl=54, ip_dscp=0xbe)
749 rx = self.send_and_expect(self.pg0, tx, self.pg0)
750 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
751 [VppMplsLabel(32, ttl=53, exp=5)])
752
753 #
754 # Add a IPv6 non-recursive route with a single out label in
755 # uniform mode
756 #
757 route_2001_3 = VppIpRoute(
758 self, "2001::3", 128,
759 [VppRoutePath(self.pg0.remote_ip6,
760 self.pg0.sw_if_index,
761 proto=DpoProto.DPO_PROTO_IP6,
762 labels=[VppMplsLabel(32,
763 mode=MplsLspMode.UNIFORM)])],
764 is_ip6=1)
765 route_2001_3.add_vpp_config()
766
767 tx = self.create_stream_ip6(self.pg0, "2001::3",
768 ip_ttl=54, ip_dscp=0xbe)
769 rx = self.send_and_expect(self.pg0, tx, self.pg0)
770 self.verify_capture_labelled_ip6(self.pg0, rx, tx,
771 [VppMplsLabel(32, ttl=53, exp=5)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000772
773 #
Matej Klottondeb69842016-12-09 15:05:46 +0100774 # add a recursive path, with output label, via the 1 label route
Neale Rannsad422ed2016-11-02 14:20:04 +0000775 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800776 route_11_0_0_1 = VppIpRoute(self, "11.0.0.1", 32,
777 [VppRoutePath("10.0.0.1",
778 0xffffffff,
Neale Ranns31ed7442018-02-23 05:29:09 -0800779 labels=[VppMplsLabel(44)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000780 route_11_0_0_1.add_vpp_config()
781
782 #
783 # a stream that matches the route for 11.0.0.1, should pick up
784 # the label stack for 11.0.0.1 and 10.0.0.1
785 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000786 tx = self.create_stream_ip4(self.pg0, "11.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800787 rx = self.send_and_expect(self.pg0, tx, self.pg0)
788 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
789 [VppMplsLabel(32),
790 VppMplsLabel(44)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000791
Neale Ranns008dbe12018-09-07 09:32:36 -0700792 self.assertEqual(route_11_0_0_1.get_stats_to()['packets'], 257)
793
Neale Rannsad422ed2016-11-02 14:20:04 +0000794 #
795 # add a recursive path, with 2 labels, via the 3 label route
796 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800797 route_11_0_0_2 = VppIpRoute(self, "11.0.0.2", 32,
798 [VppRoutePath("10.0.0.2",
799 0xffffffff,
Neale Ranns31ed7442018-02-23 05:29:09 -0800800 labels=[VppMplsLabel(44),
801 VppMplsLabel(45)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000802 route_11_0_0_2.add_vpp_config()
803
804 #
805 # a stream that matches the route for 11.0.0.1, should pick up
806 # the label stack for 11.0.0.1 and 10.0.0.1
807 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000808 tx = self.create_stream_ip4(self.pg0, "11.0.0.2")
Neale Ranns31ed7442018-02-23 05:29:09 -0800809 rx = self.send_and_expect(self.pg0, tx, self.pg0)
810 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
811 [VppMplsLabel(32),
812 VppMplsLabel(33),
813 VppMplsLabel(34),
814 VppMplsLabel(44),
815 VppMplsLabel(45)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000816
Neale Ranns008dbe12018-09-07 09:32:36 -0700817 self.assertEqual(route_11_0_0_2.get_stats_to()['packets'], 257)
818
819 rx = self.send_and_expect(self.pg0, tx, self.pg0)
820 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
821 [VppMplsLabel(32),
822 VppMplsLabel(33),
823 VppMplsLabel(34),
824 VppMplsLabel(44),
825 VppMplsLabel(45)])
826
827 self.assertEqual(route_11_0_0_2.get_stats_to()['packets'], 514)
828
Neale Rannsad422ed2016-11-02 14:20:04 +0000829 #
830 # cleanup
831 #
832 route_11_0_0_2.remove_vpp_config()
833 route_11_0_0_1.remove_vpp_config()
834 route_10_0_0_2.remove_vpp_config()
835 route_10_0_0_1.remove_vpp_config()
836
Neale Ranns31ed7442018-02-23 05:29:09 -0800837 def test_tunnel_pipe(self):
838 """ MPLS Tunnel Tests - Pipe """
Neale Rannsad422ed2016-11-02 14:20:04 +0000839
840 #
841 # Create a tunnel with a single out label
842 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800843 mpls_tun = VppMPLSTunnelInterface(
844 self,
845 [VppRoutePath(self.pg0.remote_ip4,
846 self.pg0.sw_if_index,
847 labels=[VppMplsLabel(44),
848 VppMplsLabel(46)])])
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800849 mpls_tun.add_vpp_config()
850 mpls_tun.admin_up()
Neale Rannsad422ed2016-11-02 14:20:04 +0000851
852 #
853 # add an unlabelled route through the new tunnel
854 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800855 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
856 [VppRoutePath("0.0.0.0",
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800857 mpls_tun._sw_if_index)])
Neale Ranns5a8123b2017-01-26 01:18:23 -0800858 route_10_0_0_3.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000859
860 self.vapi.cli("clear trace")
861 tx = self.create_stream_ip4(self.pg0, "10.0.0.3")
862 self.pg0.add_stream(tx)
863
864 self.pg_enable_capture(self.pg_interfaces)
865 self.pg_start()
866
867 rx = self.pg0.get_capture()
Neale Ranns31ed7442018-02-23 05:29:09 -0800868 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
869 [VppMplsLabel(44),
870 VppMplsLabel(46)])
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000871
Neale Ranns8c4611b2017-05-23 03:43:47 -0700872 #
873 # add a labelled route through the new tunnel
874 #
875 route_10_0_0_4 = VppIpRoute(self, "10.0.0.4", 32,
876 [VppRoutePath("0.0.0.0",
877 mpls_tun._sw_if_index,
878 labels=[33])])
879 route_10_0_0_4.add_vpp_config()
880
881 self.vapi.cli("clear trace")
882 tx = self.create_stream_ip4(self.pg0, "10.0.0.4")
883 self.pg0.add_stream(tx)
884
885 self.pg_enable_capture(self.pg_interfaces)
886 self.pg_start()
887
888 rx = self.pg0.get_capture()
Neale Ranns31ed7442018-02-23 05:29:09 -0800889 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
890 [VppMplsLabel(44),
891 VppMplsLabel(46),
892 VppMplsLabel(33, ttl=255)])
893
894 def test_tunnel_uniform(self):
895 """ MPLS Tunnel Tests - Uniform """
896
897 #
898 # Create a tunnel with a single out label
899 # The label stack is specified here from outer to inner
900 #
901 mpls_tun = VppMPLSTunnelInterface(
902 self,
903 [VppRoutePath(self.pg0.remote_ip4,
904 self.pg0.sw_if_index,
905 labels=[VppMplsLabel(44, ttl=32),
906 VppMplsLabel(46, MplsLspMode.UNIFORM)])])
907 mpls_tun.add_vpp_config()
908 mpls_tun.admin_up()
909
910 #
911 # add an unlabelled route through the new tunnel
912 #
913 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
914 [VppRoutePath("0.0.0.0",
915 mpls_tun._sw_if_index)])
916 route_10_0_0_3.add_vpp_config()
917
918 self.vapi.cli("clear trace")
919 tx = self.create_stream_ip4(self.pg0, "10.0.0.3", ip_ttl=24)
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=23)])
929
930 #
931 # add a labelled route through the new tunnel
932 #
933 route_10_0_0_4 = VppIpRoute(
934 self, "10.0.0.4", 32,
935 [VppRoutePath("0.0.0.0",
936 mpls_tun._sw_if_index,
937 labels=[VppMplsLabel(33, ttl=47)])])
938 route_10_0_0_4.add_vpp_config()
939
940 self.vapi.cli("clear trace")
941 tx = self.create_stream_ip4(self.pg0, "10.0.0.4")
942 self.pg0.add_stream(tx)
943
944 self.pg_enable_capture(self.pg_interfaces)
945 self.pg_start()
946
947 rx = self.pg0.get_capture()
948 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
949 [VppMplsLabel(44, ttl=32),
950 VppMplsLabel(46, ttl=47),
951 VppMplsLabel(33, ttl=47)])
Neale Ranns8c4611b2017-05-23 03:43:47 -0700952
Neale Rannsf5fa5ae2018-09-26 05:07:25 -0700953 def test_mpls_tunnel_many(self):
954 """ Multiple Tunnels """
955
956 for ii in range(10):
957 mpls_tun = VppMPLSTunnelInterface(
958 self,
959 [VppRoutePath(self.pg0.remote_ip4,
960 self.pg0.sw_if_index,
961 labels=[VppMplsLabel(44, ttl=32),
962 VppMplsLabel(46, MplsLspMode.UNIFORM)])])
963 mpls_tun.add_vpp_config()
964 mpls_tun.admin_up()
965
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000966 def test_v4_exp_null(self):
967 """ MPLS V4 Explicit NULL test """
968
969 #
970 # The first test case has an MPLS TTL of 0
971 # all packet should be dropped
972 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800973 tx = self.create_stream_labelled_ip4(self.pg0,
974 [VppMplsLabel(0, ttl=0)])
975 self.send_and_assert_no_replies(self.pg0, tx,
976 "MPLS TTL=0 packets forwarded")
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000977
978 #
979 # a stream with a non-zero MPLS TTL
980 # PG0 is in the default table
981 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800982 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(0)])
983 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000984 self.verify_capture_ip4(self.pg0, rx, tx)
985
986 #
987 # a stream with a non-zero MPLS TTL
988 # PG1 is in table 1
989 # we are ensuring the post-pop lookup occurs in the VRF table
990 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800991 tx = self.create_stream_labelled_ip4(self.pg1, [VppMplsLabel(0)])
992 rx = self.send_and_expect(self.pg1, tx, self.pg1)
993 self.verify_capture_ip4(self.pg1, rx, tx)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000994
995 def test_v6_exp_null(self):
996 """ MPLS V6 Explicit NULL test """
997
998 #
999 # a stream with a non-zero MPLS TTL
1000 # PG0 is in the default table
1001 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001002 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(2)])
1003 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001004 self.verify_capture_ip6(self.pg0, rx, tx)
1005
1006 #
1007 # a stream with a non-zero MPLS TTL
1008 # PG1 is in table 1
1009 # we are ensuring the post-pop lookup occurs in the VRF table
1010 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001011 tx = self.create_stream_labelled_ip6(self.pg1, [VppMplsLabel(2)])
1012 rx = self.send_and_expect(self.pg1, tx, self.pg1)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001013 self.verify_capture_ip6(self.pg0, rx, tx)
1014
Neale Rannscb630ff2016-12-14 13:31:29 +01001015 def test_deag(self):
1016 """ MPLS Deagg """
1017
1018 #
1019 # A de-agg route - next-hop lookup in default table
1020 #
Neale Ranns5a8123b2017-01-26 01:18:23 -08001021 route_34_eos = VppMplsRoute(self, 34, 1,
1022 [VppRoutePath("0.0.0.0",
1023 0xffffffff,
1024 nh_table_id=0)])
Neale Rannscb630ff2016-12-14 13:31:29 +01001025 route_34_eos.add_vpp_config()
1026
1027 #
1028 # ping an interface in the default table
1029 # PG0 is in the default table
1030 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001031 tx = self.create_stream_labelled_ip4(self.pg0,
1032 [VppMplsLabel(34)],
1033 ping=1,
Neale Rannscb630ff2016-12-14 13:31:29 +01001034 ip_itf=self.pg0)
Neale Ranns31ed7442018-02-23 05:29:09 -08001035 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Rannscb630ff2016-12-14 13:31:29 +01001036 self.verify_capture_ip4(self.pg0, rx, tx, ping_resp=1)
1037
1038 #
1039 # A de-agg route - next-hop lookup in non-default table
1040 #
Neale Ranns5a8123b2017-01-26 01:18:23 -08001041 route_35_eos = VppMplsRoute(self, 35, 1,
1042 [VppRoutePath("0.0.0.0",
1043 0xffffffff,
1044 nh_table_id=1)])
Neale Rannscb630ff2016-12-14 13:31:29 +01001045 route_35_eos.add_vpp_config()
1046
1047 #
1048 # ping an interface in the non-default table
1049 # PG0 is in the default table. packet arrive labelled in the
1050 # default table and egress unlabelled in the non-default
1051 #
Klement Sekeradab231a2016-12-21 08:50:14 +01001052 tx = self.create_stream_labelled_ip4(
Neale Ranns31ed7442018-02-23 05:29:09 -08001053 self.pg0, [VppMplsLabel(35)], ping=1, ip_itf=self.pg1)
1054 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Rannscb630ff2016-12-14 13:31:29 +01001055 self.verify_capture_ip4(self.pg1, rx, tx, ping_resp=1)
1056
Neale Ranns6af1c042017-05-26 03:48:53 -07001057 #
1058 # Double pop
1059 #
1060 route_36_neos = VppMplsRoute(self, 36, 0,
1061 [VppRoutePath("0.0.0.0",
1062 0xffffffff)])
1063 route_36_neos.add_vpp_config()
1064
Neale Ranns31ed7442018-02-23 05:29:09 -08001065 tx = self.create_stream_labelled_ip4(self.pg0,
1066 [VppMplsLabel(36),
1067 VppMplsLabel(35)],
Neale Ranns6af1c042017-05-26 03:48:53 -07001068 ping=1, ip_itf=self.pg1)
Neale Ranns31ed7442018-02-23 05:29:09 -08001069 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns6af1c042017-05-26 03:48:53 -07001070 self.verify_capture_ip4(self.pg1, rx, tx, ping_resp=1)
1071
1072 route_36_neos.remove_vpp_config()
Neale Rannscb630ff2016-12-14 13:31:29 +01001073 route_35_eos.remove_vpp_config()
1074 route_34_eos.remove_vpp_config()
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001075
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001076 def test_interface_rx(self):
1077 """ MPLS Interface Receive """
1078
1079 #
1080 # Add a non-recursive route that will forward the traffic
1081 # post-interface-rx
1082 #
1083 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
1084 table_id=1,
1085 paths=[VppRoutePath(self.pg1.remote_ip4,
1086 self.pg1.sw_if_index)])
1087 route_10_0_0_1.add_vpp_config()
1088
1089 #
1090 # An interface receive label that maps traffic to RX on interface
1091 # pg1
1092 # by injecting the packet in on pg0, which is in table 0
1093 # doing an interface-rx on pg1 and matching a route in table 1
1094 # if the packet egresses, then we must have swapped to pg1
1095 # so as to have matched the route in table 1
1096 #
1097 route_34_eos = VppMplsRoute(self, 34, 1,
1098 [VppRoutePath("0.0.0.0",
1099 self.pg1.sw_if_index,
1100 is_interface_rx=1)])
1101 route_34_eos.add_vpp_config()
1102
1103 #
1104 # ping an interface in the default table
1105 # PG0 is in the default table
1106 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001107 tx = self.create_stream_labelled_ip4(self.pg0,
1108 [VppMplsLabel(34)],
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001109 dst_ip="10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -08001110 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001111 self.verify_capture_ip4(self.pg1, rx, tx)
1112
1113 def test_mcast_mid_point(self):
1114 """ MPLS Multicast Mid Point """
1115
1116 #
1117 # Add a non-recursive route that will forward the traffic
1118 # post-interface-rx
1119 #
1120 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
1121 table_id=1,
1122 paths=[VppRoutePath(self.pg1.remote_ip4,
1123 self.pg1.sw_if_index)])
1124 route_10_0_0_1.add_vpp_config()
1125
1126 #
1127 # Add a mcast entry that replicate to pg2 and pg3
1128 # and replicate to a interface-rx (like a bud node would)
1129 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001130 route_3400_eos = VppMplsRoute(
1131 self, 3400, 1,
1132 [VppRoutePath(self.pg2.remote_ip4,
1133 self.pg2.sw_if_index,
1134 labels=[VppMplsLabel(3401)]),
1135 VppRoutePath(self.pg3.remote_ip4,
1136 self.pg3.sw_if_index,
1137 labels=[VppMplsLabel(3402)]),
1138 VppRoutePath("0.0.0.0",
1139 self.pg1.sw_if_index,
1140 is_interface_rx=1)],
1141 is_multicast=1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001142 route_3400_eos.add_vpp_config()
1143
1144 #
1145 # ping an interface in the default table
1146 # PG0 is in the default table
1147 #
1148 self.vapi.cli("clear trace")
Neale Ranns31ed7442018-02-23 05:29:09 -08001149 tx = self.create_stream_labelled_ip4(self.pg0,
1150 [VppMplsLabel(3400, ttl=64)],
1151 n=257,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001152 dst_ip="10.0.0.1")
1153 self.pg0.add_stream(tx)
1154
1155 self.pg_enable_capture(self.pg_interfaces)
1156 self.pg_start()
1157
1158 rx = self.pg1.get_capture(257)
1159 self.verify_capture_ip4(self.pg1, rx, tx)
1160
1161 rx = self.pg2.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001162 self.verify_capture_labelled(self.pg2, rx, tx,
1163 [VppMplsLabel(3401, ttl=63)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001164 rx = self.pg3.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001165 self.verify_capture_labelled(self.pg3, rx, tx,
1166 [VppMplsLabel(3402, ttl=63)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001167
1168 def test_mcast_head(self):
1169 """ MPLS Multicast Head-end """
1170
1171 #
1172 # Create a multicast tunnel with two replications
1173 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001174 mpls_tun = VppMPLSTunnelInterface(
1175 self,
1176 [VppRoutePath(self.pg2.remote_ip4,
1177 self.pg2.sw_if_index,
1178 labels=[VppMplsLabel(42)]),
1179 VppRoutePath(self.pg3.remote_ip4,
1180 self.pg3.sw_if_index,
1181 labels=[VppMplsLabel(43)])],
1182 is_multicast=1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001183 mpls_tun.add_vpp_config()
1184 mpls_tun.admin_up()
1185
1186 #
1187 # add an unlabelled route through the new tunnel
1188 #
1189 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
1190 [VppRoutePath("0.0.0.0",
1191 mpls_tun._sw_if_index)])
1192 route_10_0_0_3.add_vpp_config()
1193
1194 self.vapi.cli("clear trace")
1195 tx = self.create_stream_ip4(self.pg0, "10.0.0.3")
1196 self.pg0.add_stream(tx)
1197
1198 self.pg_enable_capture(self.pg_interfaces)
1199 self.pg_start()
1200
1201 rx = self.pg2.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001202 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(42)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001203 rx = self.pg3.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001204 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(43)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001205
1206 #
1207 # An an IP multicast route via the tunnel
1208 # A (*,G).
1209 # one accepting interface, pg0, 1 forwarding interface via the tunnel
1210 #
1211 route_232_1_1_1 = VppIpMRoute(
1212 self,
1213 "0.0.0.0",
1214 "232.1.1.1", 32,
1215 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
1216 [VppMRoutePath(self.pg0.sw_if_index,
1217 MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
1218 VppMRoutePath(mpls_tun._sw_if_index,
1219 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
1220 route_232_1_1_1.add_vpp_config()
1221
1222 self.vapi.cli("clear trace")
1223 tx = self.create_stream_ip4(self.pg0, "232.1.1.1")
1224 self.pg0.add_stream(tx)
1225
1226 self.pg_enable_capture(self.pg_interfaces)
1227 self.pg_start()
1228
1229 rx = self.pg2.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001230 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(42)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001231 rx = self.pg3.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001232 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(43)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001233
Neale Ranns31426c62017-05-24 10:32:58 -07001234 def test_mcast_ip4_tail(self):
1235 """ MPLS IPv4 Multicast Tail """
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001236
1237 #
1238 # Add a multicast route that will forward the traffic
1239 # post-disposition
1240 #
1241 route_232_1_1_1 = VppIpMRoute(
1242 self,
1243 "0.0.0.0",
1244 "232.1.1.1", 32,
1245 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
1246 table_id=1,
1247 paths=[VppMRoutePath(self.pg1.sw_if_index,
1248 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
1249 route_232_1_1_1.add_vpp_config()
1250
1251 #
1252 # An interface receive label that maps traffic to RX on interface
1253 # pg1
1254 # by injecting the packet in on pg0, which is in table 0
1255 # doing an rpf-id and matching a route in table 1
1256 # if the packet egresses, then we must have matched the route in
1257 # table 1
1258 #
1259 route_34_eos = VppMplsRoute(self, 34, 1,
1260 [VppRoutePath("0.0.0.0",
1261 self.pg1.sw_if_index,
1262 nh_table_id=1,
1263 rpf_id=55)],
1264 is_multicast=1)
1265
1266 route_34_eos.add_vpp_config()
1267
1268 #
1269 # Drop due to interface lookup miss
1270 #
1271 self.vapi.cli("clear trace")
Neale Ranns31ed7442018-02-23 05:29:09 -08001272 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001273 dst_ip="232.1.1.1", n=1)
1274 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop none")
1275
1276 #
1277 # set the RPF-ID of the enrtry to match the input packet's
1278 #
1279 route_232_1_1_1.update_rpf_id(55)
1280
Neale Ranns31ed7442018-02-23 05:29:09 -08001281 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
1282 dst_ip="232.1.1.1")
1283 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001284 self.verify_capture_ip4(self.pg1, rx, tx)
1285
1286 #
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001287 # disposed packets have an invalid IPv4 checkusm
1288 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001289 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001290 dst_ip="232.1.1.1", n=65,
1291 chksum=1)
1292 self.send_and_assert_no_replies(self.pg0, tx, "Invalid Checksum")
1293
1294 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001295 # set the RPF-ID of the entry to not match the input packet's
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001296 #
1297 route_232_1_1_1.update_rpf_id(56)
Neale Ranns31ed7442018-02-23 05:29:09 -08001298 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001299 dst_ip="232.1.1.1")
1300 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop 56")
1301
Neale Ranns31426c62017-05-24 10:32:58 -07001302 def test_mcast_ip6_tail(self):
1303 """ MPLS IPv6 Multicast Tail """
1304
1305 #
1306 # Add a multicast route that will forward the traffic
1307 # post-disposition
1308 #
1309 route_ff = VppIpMRoute(
1310 self,
1311 "::",
1312 "ff01::1", 32,
1313 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
1314 table_id=1,
1315 paths=[VppMRoutePath(self.pg1.sw_if_index,
1316 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)],
1317 is_ip6=1)
1318 route_ff.add_vpp_config()
1319
1320 #
1321 # An interface receive label that maps traffic to RX on interface
1322 # pg1
1323 # by injecting the packet in on pg0, which is in table 0
1324 # doing an rpf-id and matching a route in table 1
1325 # if the packet egresses, then we must have matched the route in
1326 # table 1
1327 #
1328 route_34_eos = VppMplsRoute(
1329 self, 34, 1,
1330 [VppRoutePath("::",
1331 self.pg1.sw_if_index,
1332 nh_table_id=1,
1333 rpf_id=55,
Neale Rannsda78f952017-05-24 09:15:43 -07001334 proto=DpoProto.DPO_PROTO_IP6)],
Neale Ranns31426c62017-05-24 10:32:58 -07001335 is_multicast=1)
1336
1337 route_34_eos.add_vpp_config()
1338
1339 #
1340 # Drop due to interface lookup miss
1341 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001342 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(34)],
Neale Ranns31426c62017-05-24 10:32:58 -07001343 dst_ip="ff01::1")
Neale Ranns31ed7442018-02-23 05:29:09 -08001344 self.send_and_assert_no_replies(self.pg0, tx, "RPF Miss")
Neale Ranns31426c62017-05-24 10:32:58 -07001345
1346 #
1347 # set the RPF-ID of the enrtry to match the input packet's
1348 #
1349 route_ff.update_rpf_id(55)
1350
Neale Ranns31ed7442018-02-23 05:29:09 -08001351 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(34)],
Neale Ranns31426c62017-05-24 10:32:58 -07001352 dst_ip="ff01::1")
Neale Ranns31ed7442018-02-23 05:29:09 -08001353 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns31426c62017-05-24 10:32:58 -07001354 self.verify_capture_ip6(self.pg1, rx, tx)
1355
1356 #
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001357 # disposed packets have hop-limit = 1
1358 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001359 tx = self.create_stream_labelled_ip6(self.pg0,
1360 [VppMplsLabel(34)],
1361 dst_ip="ff01::1",
1362 hlim=1)
1363 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns52fae862018-01-08 04:41:42 -08001364 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001365
1366 #
Neale Ranns31426c62017-05-24 10:32:58 -07001367 # set the RPF-ID of the enrtry to not match the input packet's
1368 #
1369 route_ff.update_rpf_id(56)
Neale Ranns31ed7442018-02-23 05:29:09 -08001370 tx = self.create_stream_labelled_ip6(self.pg0,
1371 [VppMplsLabel(34)],
Neale Ranns31426c62017-05-24 10:32:58 -07001372 dst_ip="ff01::1")
1373 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop 56")
1374
Neale Ranns180279b2017-03-16 15:49:09 -04001375
1376class TestMPLSDisabled(VppTestCase):
1377 """ MPLS disabled """
1378
1379 def setUp(self):
1380 super(TestMPLSDisabled, self).setUp()
1381
1382 # create 2 pg interfaces
1383 self.create_pg_interfaces(range(2))
1384
Neale Ranns15002542017-09-10 04:39:11 -07001385 self.tbl = VppMplsTable(self, 0)
1386 self.tbl.add_vpp_config()
1387
Neale Ranns180279b2017-03-16 15:49:09 -04001388 # PG0 is MPLS enalbed
1389 self.pg0.admin_up()
1390 self.pg0.config_ip4()
1391 self.pg0.resolve_arp()
1392 self.pg0.enable_mpls()
1393
1394 # PG 1 is not MPLS enabled
1395 self.pg1.admin_up()
1396
1397 def tearDown(self):
Neale Ranns180279b2017-03-16 15:49:09 -04001398 for i in self.pg_interfaces:
1399 i.unconfig_ip4()
1400 i.admin_down()
1401
Neale Ranns15002542017-09-10 04:39:11 -07001402 self.pg0.disable_mpls()
1403 super(TestMPLSDisabled, self).tearDown()
1404
Neale Ranns180279b2017-03-16 15:49:09 -04001405 def test_mpls_disabled(self):
1406 """ MPLS Disabled """
1407
1408 tx = (Ether(src=self.pg1.remote_mac,
1409 dst=self.pg1.local_mac) /
1410 MPLS(label=32, ttl=64) /
1411 IPv6(src="2001::1", dst=self.pg0.remote_ip6) /
1412 UDP(sport=1234, dport=1234) /
1413 Raw('\xa5' * 100))
1414
1415 #
1416 # A simple MPLS xconnect - eos label in label out
1417 #
1418 route_32_eos = VppMplsRoute(self, 32, 1,
1419 [VppRoutePath(self.pg0.remote_ip4,
1420 self.pg0.sw_if_index,
1421 labels=[33])])
1422 route_32_eos.add_vpp_config()
1423
1424 #
1425 # PG1 does not forward IP traffic
1426 #
1427 self.send_and_assert_no_replies(self.pg1, tx, "MPLS disabled")
1428
1429 #
1430 # MPLS enable PG1
1431 #
1432 self.pg1.enable_mpls()
1433
1434 #
1435 # Now we get packets through
1436 #
1437 self.pg1.add_stream(tx)
1438 self.pg_enable_capture(self.pg_interfaces)
1439 self.pg_start()
1440
1441 rx = self.pg0.get_capture(1)
1442
1443 #
1444 # Disable PG1
1445 #
1446 self.pg1.disable_mpls()
1447
1448 #
1449 # PG1 does not forward IP traffic
1450 #
1451 self.send_and_assert_no_replies(self.pg1, tx, "IPv6 disabled")
1452 self.send_and_assert_no_replies(self.pg1, tx, "IPv6 disabled")
1453
1454
Neale Rannsf12a83f2017-04-18 09:09:40 -07001455class TestMPLSPIC(VppTestCase):
1456 """ MPLS PIC edge convergence """
1457
1458 def setUp(self):
1459 super(TestMPLSPIC, self).setUp()
1460
1461 # create 2 pg interfaces
1462 self.create_pg_interfaces(range(4))
1463
Neale Ranns15002542017-09-10 04:39:11 -07001464 mpls_tbl = VppMplsTable(self, 0)
1465 mpls_tbl.add_vpp_config()
1466 tbl4 = VppIpTable(self, 1)
1467 tbl4.add_vpp_config()
1468 tbl6 = VppIpTable(self, 1, is_ip6=1)
1469 tbl6.add_vpp_config()
1470
Neale Rannsf12a83f2017-04-18 09:09:40 -07001471 # core links
1472 self.pg0.admin_up()
1473 self.pg0.config_ip4()
1474 self.pg0.resolve_arp()
1475 self.pg0.enable_mpls()
1476 self.pg1.admin_up()
1477 self.pg1.config_ip4()
1478 self.pg1.resolve_arp()
1479 self.pg1.enable_mpls()
1480
1481 # VRF (customer facing) link
1482 self.pg2.admin_up()
1483 self.pg2.set_table_ip4(1)
1484 self.pg2.config_ip4()
1485 self.pg2.resolve_arp()
1486 self.pg2.set_table_ip6(1)
1487 self.pg2.config_ip6()
1488 self.pg2.resolve_ndp()
1489 self.pg3.admin_up()
1490 self.pg3.set_table_ip4(1)
1491 self.pg3.config_ip4()
1492 self.pg3.resolve_arp()
1493 self.pg3.set_table_ip6(1)
1494 self.pg3.config_ip6()
1495 self.pg3.resolve_ndp()
1496
1497 def tearDown(self):
Neale Rannsf12a83f2017-04-18 09:09:40 -07001498 self.pg0.disable_mpls()
Neale Ranns15002542017-09-10 04:39:11 -07001499 self.pg1.disable_mpls()
Neale Rannsf12a83f2017-04-18 09:09:40 -07001500 for i in self.pg_interfaces:
1501 i.unconfig_ip4()
1502 i.unconfig_ip6()
1503 i.set_table_ip4(0)
1504 i.set_table_ip6(0)
1505 i.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -07001506 super(TestMPLSPIC, self).tearDown()
Neale Rannsf12a83f2017-04-18 09:09:40 -07001507
1508 def test_mpls_ibgp_pic(self):
1509 """ MPLS iBGP PIC edge convergence
1510
1511 1) setup many iBGP VPN routes via a pair of iBGP peers.
1512 2) Check EMCP forwarding to these peers
1513 3) withdraw the IGP route to one of these peers.
1514 4) check forwarding continues to the remaining peer
1515 """
1516
1517 #
1518 # IGP+LDP core routes
1519 #
1520 core_10_0_0_45 = VppIpRoute(self, "10.0.0.45", 32,
1521 [VppRoutePath(self.pg0.remote_ip4,
1522 self.pg0.sw_if_index,
1523 labels=[45])])
1524 core_10_0_0_45.add_vpp_config()
1525
1526 core_10_0_0_46 = VppIpRoute(self, "10.0.0.46", 32,
1527 [VppRoutePath(self.pg1.remote_ip4,
1528 self.pg1.sw_if_index,
1529 labels=[46])])
1530 core_10_0_0_46.add_vpp_config()
1531
1532 #
1533 # Lot's of VPN routes. We need more the 64 so VPP will build
1534 # the fast convergence indirection
1535 #
1536 vpn_routes = []
1537 pkts = []
1538 for ii in range(64):
1539 dst = "192.168.1.%d" % ii
1540 vpn_routes.append(VppIpRoute(self, dst, 32,
1541 [VppRoutePath("10.0.0.45",
1542 0xffffffff,
1543 labels=[145],
1544 is_resolve_host=1),
1545 VppRoutePath("10.0.0.46",
1546 0xffffffff,
1547 labels=[146],
1548 is_resolve_host=1)],
1549 table_id=1))
1550 vpn_routes[ii].add_vpp_config()
1551
1552 pkts.append(Ether(dst=self.pg2.local_mac,
1553 src=self.pg2.remote_mac) /
1554 IP(src=self.pg2.remote_ip4, dst=dst) /
1555 UDP(sport=1234, dport=1234) /
1556 Raw('\xa5' * 100))
1557
1558 #
1559 # Send the packet stream (one pkt to each VPN route)
1560 # - expect a 50-50 split of the traffic
1561 #
1562 self.pg2.add_stream(pkts)
1563 self.pg_enable_capture(self.pg_interfaces)
1564 self.pg_start()
1565
1566 rx0 = self.pg0._get_capture(1)
1567 rx1 = self.pg1._get_capture(1)
1568
1569 # not testig the LB hashing algorithm so we're not concerned
1570 # with the split ratio, just as long as neither is 0
1571 self.assertNotEqual(0, len(rx0))
1572 self.assertNotEqual(0, len(rx1))
1573
1574 #
1575 # use a test CLI command to stop the FIB walk process, this
1576 # will prevent the FIB converging the VPN routes and thus allow
1577 # us to probe the interim (psot-fail, pre-converge) state
1578 #
1579 self.vapi.ppcli("test fib-walk-process disable")
1580
1581 #
1582 # Withdraw one of the IGP routes
1583 #
1584 core_10_0_0_46.remove_vpp_config()
1585
1586 #
1587 # now all packets should be forwarded through the remaining peer
1588 #
1589 self.vapi.ppcli("clear trace")
1590 self.pg2.add_stream(pkts)
1591 self.pg_enable_capture(self.pg_interfaces)
1592 self.pg_start()
1593
1594 rx0 = self.pg0.get_capture(len(pkts))
1595
1596 #
1597 # enable the FIB walk process to converge the FIB
1598 #
1599 self.vapi.ppcli("test fib-walk-process enable")
1600
1601 #
1602 # packets should still be forwarded through the remaining peer
1603 #
1604 self.pg2.add_stream(pkts)
1605 self.pg_enable_capture(self.pg_interfaces)
1606 self.pg_start()
1607
1608 rx0 = self.pg0.get_capture(64)
1609
1610 #
1611 # Add the IGP route back and we return to load-balancing
1612 #
1613 core_10_0_0_46.add_vpp_config()
1614
1615 self.pg2.add_stream(pkts)
1616 self.pg_enable_capture(self.pg_interfaces)
1617 self.pg_start()
1618
1619 rx0 = self.pg0._get_capture(1)
1620 rx1 = self.pg1._get_capture(1)
1621 self.assertNotEqual(0, len(rx0))
1622 self.assertNotEqual(0, len(rx1))
1623
1624 def test_mpls_ebgp_pic(self):
1625 """ MPLS eBGP PIC edge convergence
1626
1627 1) setup many eBGP VPN routes via a pair of eBGP peers
1628 2) Check EMCP forwarding to these peers
1629 3) withdraw one eBGP path - expect LB across remaining eBGP
1630 """
1631
1632 #
1633 # Lot's of VPN routes. We need more the 64 so VPP will build
1634 # the fast convergence indirection
1635 #
1636 vpn_routes = []
1637 vpn_bindings = []
1638 pkts = []
1639 for ii in range(64):
1640 dst = "192.168.1.%d" % ii
1641 local_label = 1600 + ii
1642 vpn_routes.append(VppIpRoute(self, dst, 32,
1643 [VppRoutePath(self.pg2.remote_ip4,
1644 0xffffffff,
1645 nh_table_id=1,
1646 is_resolve_attached=1),
1647 VppRoutePath(self.pg3.remote_ip4,
1648 0xffffffff,
1649 nh_table_id=1,
1650 is_resolve_attached=1)],
1651 table_id=1))
1652 vpn_routes[ii].add_vpp_config()
1653
1654 vpn_bindings.append(VppMplsIpBind(self, local_label, dst, 32,
1655 ip_table_id=1))
1656 vpn_bindings[ii].add_vpp_config()
1657
1658 pkts.append(Ether(dst=self.pg0.local_mac,
1659 src=self.pg0.remote_mac) /
1660 MPLS(label=local_label, ttl=64) /
1661 IP(src=self.pg0.remote_ip4, dst=dst) /
1662 UDP(sport=1234, dport=1234) /
1663 Raw('\xa5' * 100))
1664
1665 self.pg0.add_stream(pkts)
1666 self.pg_enable_capture(self.pg_interfaces)
1667 self.pg_start()
1668
1669 rx0 = self.pg2._get_capture(1)
1670 rx1 = self.pg3._get_capture(1)
1671 self.assertNotEqual(0, len(rx0))
1672 self.assertNotEqual(0, len(rx1))
1673
1674 #
1675 # use a test CLI command to stop the FIB walk process, this
1676 # will prevent the FIB converging the VPN routes and thus allow
1677 # us to probe the interim (psot-fail, pre-converge) state
1678 #
1679 self.vapi.ppcli("test fib-walk-process disable")
1680
1681 #
1682 # withdraw the connected prefix on the interface.
1683 #
1684 self.pg2.unconfig_ip4()
1685
1686 #
1687 # now all packets should be forwarded through the remaining peer
1688 #
1689 self.pg0.add_stream(pkts)
1690 self.pg_enable_capture(self.pg_interfaces)
1691 self.pg_start()
1692
1693 rx0 = self.pg3.get_capture(len(pkts))
1694
1695 #
1696 # enable the FIB walk process to converge the FIB
1697 #
1698 self.vapi.ppcli("test fib-walk-process enable")
1699 self.pg0.add_stream(pkts)
1700 self.pg_enable_capture(self.pg_interfaces)
1701 self.pg_start()
1702
1703 rx0 = self.pg3.get_capture(len(pkts))
1704
1705 #
1706 # put the connecteds back
1707 #
1708 self.pg2.config_ip4()
1709
1710 self.pg0.add_stream(pkts)
1711 self.pg_enable_capture(self.pg_interfaces)
1712 self.pg_start()
1713
1714 rx0 = self.pg2._get_capture(1)
1715 rx1 = self.pg3._get_capture(1)
1716 self.assertNotEqual(0, len(rx0))
1717 self.assertNotEqual(0, len(rx1))
1718
1719 def test_mpls_v6_ebgp_pic(self):
1720 """ MPLSv6 eBGP PIC edge convergence
1721
1722 1) setup many eBGP VPNv6 routes via a pair of eBGP peers
1723 2) Check EMCP forwarding to these peers
1724 3) withdraw one eBGP path - expect LB across remaining eBGP
1725 """
1726
1727 #
1728 # Lot's of VPN routes. We need more the 64 so VPP will build
1729 # the fast convergence indirection
1730 #
1731 vpn_routes = []
1732 vpn_bindings = []
1733 pkts = []
1734 for ii in range(64):
1735 dst = "3000::%d" % ii
1736 local_label = 1600 + ii
Neale Rannsda78f952017-05-24 09:15:43 -07001737 vpn_routes.append(VppIpRoute(
1738 self, dst, 128,
1739 [VppRoutePath(self.pg2.remote_ip6,
1740 0xffffffff,
1741 nh_table_id=1,
1742 is_resolve_attached=1,
1743 proto=DpoProto.DPO_PROTO_IP6),
1744 VppRoutePath(self.pg3.remote_ip6,
1745 0xffffffff,
1746 nh_table_id=1,
1747 proto=DpoProto.DPO_PROTO_IP6,
1748 is_resolve_attached=1)],
1749 table_id=1,
1750 is_ip6=1))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001751 vpn_routes[ii].add_vpp_config()
1752
1753 vpn_bindings.append(VppMplsIpBind(self, local_label, dst, 128,
1754 ip_table_id=1,
1755 is_ip6=1))
1756 vpn_bindings[ii].add_vpp_config()
1757
1758 pkts.append(Ether(dst=self.pg0.local_mac,
1759 src=self.pg0.remote_mac) /
1760 MPLS(label=local_label, ttl=64) /
1761 IPv6(src=self.pg0.remote_ip6, dst=dst) /
1762 UDP(sport=1234, dport=1234) /
1763 Raw('\xa5' * 100))
1764
1765 self.pg0.add_stream(pkts)
1766 self.pg_enable_capture(self.pg_interfaces)
1767 self.pg_start()
1768
1769 rx0 = self.pg2._get_capture(1)
1770 rx1 = self.pg3._get_capture(1)
1771 self.assertNotEqual(0, len(rx0))
1772 self.assertNotEqual(0, len(rx1))
1773
1774 #
1775 # use a test CLI command to stop the FIB walk process, this
1776 # will prevent the FIB converging the VPN routes and thus allow
1777 # us to probe the interim (psot-fail, pre-converge) state
1778 #
1779 self.vapi.ppcli("test fib-walk-process disable")
1780
1781 #
1782 # withdraw the connected prefix on the interface.
1783 # and shutdown the interface so the ND cache is flushed.
1784 #
1785 self.pg2.unconfig_ip6()
1786 self.pg2.admin_down()
1787
1788 #
1789 # now all packets should be forwarded through the remaining peer
1790 #
1791 self.pg0.add_stream(pkts)
1792 self.pg_enable_capture(self.pg_interfaces)
1793 self.pg_start()
1794
1795 rx0 = self.pg3.get_capture(len(pkts))
1796
1797 #
1798 # enable the FIB walk process to converge the FIB
1799 #
1800 self.vapi.ppcli("test fib-walk-process enable")
1801 self.pg0.add_stream(pkts)
1802 self.pg_enable_capture(self.pg_interfaces)
1803 self.pg_start()
1804
1805 rx0 = self.pg3.get_capture(len(pkts))
1806
1807 #
1808 # put the connecteds back
1809 #
1810 self.pg2.admin_up()
1811 self.pg2.config_ip6()
1812
1813 self.pg0.add_stream(pkts)
1814 self.pg_enable_capture(self.pg_interfaces)
1815 self.pg_start()
1816
1817 rx0 = self.pg2._get_capture(1)
1818 rx1 = self.pg3._get_capture(1)
1819 self.assertNotEqual(0, len(rx0))
1820 self.assertNotEqual(0, len(rx1))
1821
1822
Neale Rannsda78f952017-05-24 09:15:43 -07001823class TestMPLSL2(VppTestCase):
1824 """ MPLS-L2 """
1825
1826 def setUp(self):
1827 super(TestMPLSL2, self).setUp()
1828
1829 # create 2 pg interfaces
1830 self.create_pg_interfaces(range(2))
1831
Neale Ranns15002542017-09-10 04:39:11 -07001832 # create the default MPLS table
1833 self.tables = []
1834 tbl = VppMplsTable(self, 0)
1835 tbl.add_vpp_config()
1836 self.tables.append(tbl)
1837
Neale Rannsda78f952017-05-24 09:15:43 -07001838 # use pg0 as the core facing interface
1839 self.pg0.admin_up()
1840 self.pg0.config_ip4()
1841 self.pg0.resolve_arp()
1842 self.pg0.enable_mpls()
1843
Neale Ranns15002542017-09-10 04:39:11 -07001844 # use the other 2 for customer facing L2 links
Neale Rannsda78f952017-05-24 09:15:43 -07001845 for i in self.pg_interfaces[1:]:
1846 i.admin_up()
1847
1848 def tearDown(self):
Neale Rannsda78f952017-05-24 09:15:43 -07001849 for i in self.pg_interfaces[1:]:
1850 i.admin_down()
1851
1852 self.pg0.disable_mpls()
1853 self.pg0.unconfig_ip4()
1854 self.pg0.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -07001855 super(TestMPLSL2, self).tearDown()
Neale Rannsda78f952017-05-24 09:15:43 -07001856
Neale Ranns31ed7442018-02-23 05:29:09 -08001857 def verify_capture_tunneled_ethernet(self, capture, sent, mpls_labels):
Neale Rannsda78f952017-05-24 09:15:43 -07001858 capture = verify_filter(capture, sent)
1859
1860 self.assertEqual(len(capture), len(sent))
1861
1862 for i in range(len(capture)):
1863 tx = sent[i]
1864 rx = capture[i]
1865
1866 # the MPLS TTL is 255 since it enters a new tunnel
Neale Ranns31ed7442018-02-23 05:29:09 -08001867 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsda78f952017-05-24 09:15:43 -07001868
1869 tx_eth = tx[Ether]
1870 rx_eth = Ether(str(rx[MPLS].payload))
1871
1872 self.assertEqual(rx_eth.src, tx_eth.src)
1873 self.assertEqual(rx_eth.dst, tx_eth.dst)
1874
1875 def test_vpws(self):
1876 """ Virtual Private Wire Service """
1877
1878 #
1879 # Create an MPLS tunnel that pushes 1 label
Neale Ranns31ed7442018-02-23 05:29:09 -08001880 # For Ethernet over MPLS the uniform mode is irrelevant since ttl/cos
1881 # information is not in the packet, but we test it works anyway
Neale Rannsda78f952017-05-24 09:15:43 -07001882 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001883 mpls_tun_1 = VppMPLSTunnelInterface(
1884 self,
1885 [VppRoutePath(self.pg0.remote_ip4,
1886 self.pg0.sw_if_index,
1887 labels=[VppMplsLabel(42, MplsLspMode.UNIFORM)])],
1888 is_l2=1)
Neale Rannsda78f952017-05-24 09:15:43 -07001889 mpls_tun_1.add_vpp_config()
1890 mpls_tun_1.admin_up()
1891
1892 #
1893 # Create a label entry to for 55 that does L2 input to the tunnel
1894 #
1895 route_55_eos = VppMplsRoute(
1896 self, 55, 1,
1897 [VppRoutePath("0.0.0.0",
1898 mpls_tun_1.sw_if_index,
1899 is_interface_rx=1,
1900 proto=DpoProto.DPO_PROTO_ETHERNET)])
1901 route_55_eos.add_vpp_config()
1902
1903 #
1904 # Cross-connect the tunnel with one of the customers L2 interfaces
1905 #
1906 self.vapi.sw_interface_set_l2_xconnect(self.pg1.sw_if_index,
1907 mpls_tun_1.sw_if_index,
1908 enable=1)
1909 self.vapi.sw_interface_set_l2_xconnect(mpls_tun_1.sw_if_index,
1910 self.pg1.sw_if_index,
1911 enable=1)
1912
1913 #
1914 # inject a packet from the core
1915 #
1916 pcore = (Ether(dst=self.pg0.local_mac,
1917 src=self.pg0.remote_mac) /
1918 MPLS(label=55, ttl=64) /
1919 Ether(dst="00:00:de:ad:ba:be",
1920 src="00:00:de:ad:be:ef") /
1921 IP(src="10.10.10.10", dst="11.11.11.11") /
1922 UDP(sport=1234, dport=1234) /
1923 Raw('\xa5' * 100))
1924
Neale Ranns31ed7442018-02-23 05:29:09 -08001925 tx0 = pcore * 65
1926 rx0 = self.send_and_expect(self.pg0, tx0, self.pg1)
1927 payload = pcore[MPLS].payload
Neale Rannsda78f952017-05-24 09:15:43 -07001928
Neale Ranns31ed7442018-02-23 05:29:09 -08001929 self.assertEqual(rx0[0][Ether].dst, payload[Ether].dst)
1930 self.assertEqual(rx0[0][Ether].src, payload[Ether].src)
Neale Rannsda78f952017-05-24 09:15:43 -07001931
1932 #
1933 # Inject a packet from the custoer/L2 side
1934 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001935 tx1 = pcore[MPLS].payload * 65
1936 rx1 = self.send_and_expect(self.pg1, tx1, self.pg0)
Neale Rannsda78f952017-05-24 09:15:43 -07001937
Neale Ranns31ed7442018-02-23 05:29:09 -08001938 self.verify_capture_tunneled_ethernet(rx1, tx1, [VppMplsLabel(42)])
Neale Rannsda78f952017-05-24 09:15:43 -07001939
1940 def test_vpls(self):
1941 """ Virtual Private LAN Service """
1942 #
1943 # Create an L2 MPLS tunnel
1944 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001945 mpls_tun = VppMPLSTunnelInterface(
1946 self,
1947 [VppRoutePath(self.pg0.remote_ip4,
1948 self.pg0.sw_if_index,
1949 labels=[VppMplsLabel(42)])],
1950 is_l2=1)
Neale Rannsda78f952017-05-24 09:15:43 -07001951 mpls_tun.add_vpp_config()
1952 mpls_tun.admin_up()
1953
1954 #
1955 # Create a label entry to for 55 that does L2 input to the tunnel
1956 #
1957 route_55_eos = VppMplsRoute(
1958 self, 55, 1,
1959 [VppRoutePath("0.0.0.0",
1960 mpls_tun.sw_if_index,
1961 is_interface_rx=1,
1962 proto=DpoProto.DPO_PROTO_ETHERNET)])
1963 route_55_eos.add_vpp_config()
1964
1965 #
1966 # add to tunnel to the customers bridge-domain
1967 #
1968 self.vapi.sw_interface_set_l2_bridge(mpls_tun.sw_if_index,
1969 bd_id=1)
1970 self.vapi.sw_interface_set_l2_bridge(self.pg1.sw_if_index,
1971 bd_id=1)
1972
1973 #
1974 # Packet from the customer interface and from the core
1975 #
1976 p_cust = (Ether(dst="00:00:de:ad:ba:be",
1977 src="00:00:de:ad:be:ef") /
1978 IP(src="10.10.10.10", dst="11.11.11.11") /
1979 UDP(sport=1234, dport=1234) /
1980 Raw('\xa5' * 100))
1981 p_core = (Ether(src="00:00:de:ad:ba:be",
1982 dst="00:00:de:ad:be:ef") /
1983 IP(dst="10.10.10.10", src="11.11.11.11") /
1984 UDP(sport=1234, dport=1234) /
1985 Raw('\xa5' * 100))
1986
1987 #
1988 # The BD is learning, so send in one of each packet to learn
1989 #
1990 p_core_encap = (Ether(dst=self.pg0.local_mac,
1991 src=self.pg0.remote_mac) /
1992 MPLS(label=55, ttl=64) /
1993 p_core)
1994
1995 self.pg1.add_stream(p_cust)
1996 self.pg_enable_capture(self.pg_interfaces)
1997 self.pg_start()
1998 self.pg0.add_stream(p_core_encap)
1999 self.pg_enable_capture(self.pg_interfaces)
2000 self.pg_start()
2001
2002 # we've learnt this so expect it be be forwarded
2003 rx0 = self.pg1.get_capture(1)
2004
2005 self.assertEqual(rx0[0][Ether].dst, p_core[Ether].dst)
2006 self.assertEqual(rx0[0][Ether].src, p_core[Ether].src)
2007
2008 #
2009 # now a stream in each direction
2010 #
2011 self.pg1.add_stream(p_cust * 65)
2012 self.pg_enable_capture(self.pg_interfaces)
2013 self.pg_start()
2014
2015 rx0 = self.pg0.get_capture(65)
2016
Neale Ranns31ed7442018-02-23 05:29:09 -08002017 self.verify_capture_tunneled_ethernet(rx0, p_cust*65,
2018 [VppMplsLabel(42)])
Neale Rannsda78f952017-05-24 09:15:43 -07002019
2020 #
2021 # remove interfaces from customers bridge-domain
2022 #
2023 self.vapi.sw_interface_set_l2_bridge(mpls_tun.sw_if_index,
2024 bd_id=1,
2025 enable=0)
2026 self.vapi.sw_interface_set_l2_bridge(self.pg1.sw_if_index,
2027 bd_id=1,
2028 enable=0)
2029
Neale Ranns8fe8cc22016-11-01 10:05:08 +00002030if __name__ == '__main__':
2031 unittest.main(testRunner=VppTestRunner)