blob: e7fb288f8568fd7e664637985dbc7dad37504759 [file] [log] [blame]
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001#!/usr/bin/env python
2
3import unittest
Gabriel Gannea9b2d582016-12-06 10:25:34 +01004import socket
Neale Ranns8fe8cc22016-11-01 10:05:08 +00005
6from framework import VppTestCase, VppTestRunner
Neale Rannsc0a93142018-09-05 15:42:26 -07007from vpp_ip import DpoProto
Neale Ranns5a8123b2017-01-26 01:18:23 -08008from vpp_ip_route import VppIpRoute, VppRoutePath, VppMplsRoute, \
Neale Ranns0f26c5a2017-03-01 15:12:11 -08009 VppMplsIpBind, VppIpMRoute, VppMRoutePath, \
Neale Rannsc0a93142018-09-05 15:42:26 -070010 MRouteItfFlags, MRouteEntryFlags, VppIpTable, VppMplsTable, \
Neale Ranns775f73c2018-12-20 03:01:49 -080011 VppMplsLabel, MplsLspMode, find_mpls_route
Neale Ranns0f26c5a2017-03-01 15:12:11 -080012from vpp_mpls_tunnel_interface import VppMPLSTunnelInterface
Neale Ranns8fe8cc22016-11-01 10:05:08 +000013
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
Neale Ranns775f73c2018-12-20 03:01:49 -0800382 self.assertTrue(
383 find_mpls_route(self, 0, 32, 1,
384 [VppRoutePath(self.pg0.remote_ip4,
385 self.pg0.sw_if_index,
386 labels=[VppMplsLabel(33)])]))
387
Neale Rannsad422ed2016-11-02 14:20:04 +0000388 #
389 # a stream that matches the route for 10.0.0.1
390 # PG0 is in the default table
391 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800392 tx = self.create_stream_labelled_ip4(self.pg0,
393 [VppMplsLabel(32, ttl=32, exp=1)])
394 rx = self.send_and_expect(self.pg0, tx, self.pg0)
395 self.verify_capture_labelled(self.pg0, rx, tx,
396 [VppMplsLabel(33, ttl=31, exp=1)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000397
Neale Ranns008dbe12018-09-07 09:32:36 -0700398 self.assertEqual(route_32_eos.get_stats_to()['packets'], 257)
399
Neale Rannsad422ed2016-11-02 14:20:04 +0000400 #
401 # A simple MPLS xconnect - non-eos label in label out
402 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800403 route_32_neos = VppMplsRoute(self, 32, 0,
404 [VppRoutePath(self.pg0.remote_ip4,
405 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800406 labels=[VppMplsLabel(33)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000407 route_32_neos.add_vpp_config()
408
409 #
410 # a stream that matches the route for 10.0.0.1
411 # PG0 is in the default table
412 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800413 tx = self.create_stream_labelled_ip4(self.pg0,
414 [VppMplsLabel(32, ttl=21, exp=7),
415 VppMplsLabel(99)])
416 rx = self.send_and_expect(self.pg0, tx, self.pg0)
417 self.verify_capture_labelled(self.pg0, rx, tx,
418 [VppMplsLabel(33, ttl=20, exp=7),
419 VppMplsLabel(99)])
Neale Ranns008dbe12018-09-07 09:32:36 -0700420 self.assertEqual(route_32_neos.get_stats_to()['packets'], 257)
Neale Rannsad422ed2016-11-02 14:20:04 +0000421
Neale Ranns31ed7442018-02-23 05:29:09 -0800422 #
423 # A simple MPLS xconnect - non-eos label in label out, uniform mode
424 #
425 route_42_neos = VppMplsRoute(
426 self, 42, 0,
427 [VppRoutePath(self.pg0.remote_ip4,
428 self.pg0.sw_if_index,
429 labels=[VppMplsLabel(43, MplsLspMode.UNIFORM)])])
430 route_42_neos.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000431
Neale Ranns31ed7442018-02-23 05:29:09 -0800432 tx = self.create_stream_labelled_ip4(self.pg0,
433 [VppMplsLabel(42, ttl=21, exp=7),
434 VppMplsLabel(99)])
435 rx = self.send_and_expect(self.pg0, tx, self.pg0)
436 self.verify_capture_labelled(self.pg0, rx, tx,
437 [VppMplsLabel(43, ttl=20, exp=7),
438 VppMplsLabel(99)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000439
440 #
441 # An MPLS xconnect - EOS label in IP out
442 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800443 route_33_eos = VppMplsRoute(self, 33, 1,
444 [VppRoutePath(self.pg0.remote_ip4,
445 self.pg0.sw_if_index,
446 labels=[])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000447 route_33_eos.add_vpp_config()
448
Neale Ranns31ed7442018-02-23 05:29:09 -0800449 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(33)])
450 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Rannsad422ed2016-11-02 14:20:04 +0000451 self.verify_capture_ip4(self.pg0, rx, tx)
452
453 #
Neale Ranns62fe07c2017-10-31 12:28:22 -0700454 # disposed packets have an invalid IPv4 checkusm
455 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800456 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(33)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700457 dst_ip=self.pg0.remote_ip4,
458 n=65,
459 chksum=1)
460 self.send_and_assert_no_replies(self.pg0, tx, "Invalid Checksum")
461
462 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800463 # An MPLS xconnect - EOS label in IP out, uniform mode
464 #
465 route_3333_eos = VppMplsRoute(
466 self, 3333, 1,
467 [VppRoutePath(self.pg0.remote_ip4,
468 self.pg0.sw_if_index,
469 labels=[VppMplsLabel(3, MplsLspMode.UNIFORM)])])
470 route_3333_eos.add_vpp_config()
471
472 tx = self.create_stream_labelled_ip4(
473 self.pg0,
474 [VppMplsLabel(3333, ttl=55, exp=3)])
475 rx = self.send_and_expect(self.pg0, tx, self.pg0)
476 self.verify_capture_ip4(self.pg0, rx, tx, ip_ttl=54, ip_dscp=0x60)
477 tx = self.create_stream_labelled_ip4(
478 self.pg0,
479 [VppMplsLabel(3333, ttl=66, exp=4)])
480 rx = self.send_and_expect(self.pg0, tx, self.pg0)
481 self.verify_capture_ip4(self.pg0, rx, tx, ip_ttl=65, ip_dscp=0x80)
482
483 #
Neale Ranns62fe07c2017-10-31 12:28:22 -0700484 # An MPLS xconnect - EOS label in IPv6 out
485 #
486 route_333_eos = VppMplsRoute(
487 self, 333, 1,
488 [VppRoutePath(self.pg0.remote_ip6,
489 self.pg0.sw_if_index,
490 labels=[],
491 proto=DpoProto.DPO_PROTO_IP6)])
492 route_333_eos.add_vpp_config()
493
Neale Ranns31ed7442018-02-23 05:29:09 -0800494 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(333)])
495 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700496 self.verify_capture_ip6(self.pg0, rx, tx)
497
498 #
499 # disposed packets have an TTL expired
500 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800501 tx = self.create_stream_labelled_ip6(self.pg0,
502 [VppMplsLabel(333, ttl=64)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700503 dst_ip=self.pg1.remote_ip6,
504 hlim=1)
Neale Ranns31ed7442018-02-23 05:29:09 -0800505 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700506 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
507
508 #
509 # An MPLS xconnect - EOS label in IPv6 out w imp-null
510 #
511 route_334_eos = VppMplsRoute(
512 self, 334, 1,
513 [VppRoutePath(self.pg0.remote_ip6,
514 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800515 labels=[VppMplsLabel(3)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700516 proto=DpoProto.DPO_PROTO_IP6)])
517 route_334_eos.add_vpp_config()
518
Neale Ranns31ed7442018-02-23 05:29:09 -0800519 tx = self.create_stream_labelled_ip6(self.pg0,
520 [VppMplsLabel(334, ttl=64)])
521 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700522 self.verify_capture_ip6(self.pg0, rx, tx)
523
524 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800525 # An MPLS xconnect - EOS label in IPv6 out w imp-null in uniform mode
526 #
527 route_335_eos = VppMplsRoute(
528 self, 335, 1,
529 [VppRoutePath(self.pg0.remote_ip6,
530 self.pg0.sw_if_index,
531 labels=[VppMplsLabel(3, MplsLspMode.UNIFORM)],
532 proto=DpoProto.DPO_PROTO_IP6)])
533 route_335_eos.add_vpp_config()
534
535 tx = self.create_stream_labelled_ip6(
536 self.pg0,
537 [VppMplsLabel(335, ttl=27, exp=4)])
538 rx = self.send_and_expect(self.pg0, tx, self.pg0)
539 self.verify_capture_ip6(self.pg0, rx, tx, ip_hlim=26, ip_dscp=0x80)
540
541 #
Neale Ranns62fe07c2017-10-31 12:28:22 -0700542 # disposed packets have an TTL expired
543 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800544 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(334)],
Neale Ranns62fe07c2017-10-31 12:28:22 -0700545 dst_ip=self.pg1.remote_ip6,
546 hlim=0)
Neale Ranns31ed7442018-02-23 05:29:09 -0800547 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns62fe07c2017-10-31 12:28:22 -0700548 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
549
550 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000551 # An MPLS xconnect - non-EOS label in IP out - an invalid configuration
552 # so this traffic should be dropped.
553 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800554 route_33_neos = VppMplsRoute(self, 33, 0,
555 [VppRoutePath(self.pg0.remote_ip4,
556 self.pg0.sw_if_index,
557 labels=[])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000558 route_33_neos.add_vpp_config()
559
Neale Ranns31ed7442018-02-23 05:29:09 -0800560 tx = self.create_stream_labelled_ip4(self.pg0,
561 [VppMplsLabel(33),
562 VppMplsLabel(99)])
563 self.send_and_assert_no_replies(
564 self.pg0, tx,
565 "MPLS non-EOS packets popped and forwarded")
Neale Rannsad422ed2016-11-02 14:20:04 +0000566
567 #
568 # A recursive EOS x-connect, which resolves through another x-connect
Neale Ranns31ed7442018-02-23 05:29:09 -0800569 # in pipe mode
Neale Rannsad422ed2016-11-02 14:20:04 +0000570 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800571 route_34_eos = VppMplsRoute(self, 34, 1,
572 [VppRoutePath("0.0.0.0",
573 0xffffffff,
574 nh_via_label=32,
Neale Ranns31ed7442018-02-23 05:29:09 -0800575 labels=[VppMplsLabel(44),
576 VppMplsLabel(45)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000577 route_34_eos.add_vpp_config()
578
Neale Ranns31ed7442018-02-23 05:29:09 -0800579 tx = self.create_stream_labelled_ip4(self.pg0,
580 [VppMplsLabel(34, ttl=3)])
581 rx = self.send_and_expect(self.pg0, tx, self.pg0)
582 self.verify_capture_labelled(self.pg0, rx, tx,
583 [VppMplsLabel(33),
584 VppMplsLabel(44),
585 VppMplsLabel(45, ttl=2)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000586
Neale Ranns008dbe12018-09-07 09:32:36 -0700587 self.assertEqual(route_34_eos.get_stats_to()['packets'], 257)
588 self.assertEqual(route_32_neos.get_stats_via()['packets'], 257)
589
Neale Ranns31ed7442018-02-23 05:29:09 -0800590 #
591 # A recursive EOS x-connect, which resolves through another x-connect
592 # in uniform mode
593 #
594 route_35_eos = VppMplsRoute(
595 self, 35, 1,
596 [VppRoutePath("0.0.0.0",
597 0xffffffff,
598 nh_via_label=42,
599 labels=[VppMplsLabel(44)])])
600 route_35_eos.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000601
Neale Ranns31ed7442018-02-23 05:29:09 -0800602 tx = self.create_stream_labelled_ip4(self.pg0,
603 [VppMplsLabel(35, ttl=3)])
604 rx = self.send_and_expect(self.pg0, tx, self.pg0)
605 self.verify_capture_labelled(self.pg0, rx, tx,
606 [VppMplsLabel(43, ttl=2),
607 VppMplsLabel(44, ttl=2)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000608
609 #
Matej Klottondeb69842016-12-09 15:05:46 +0100610 # A recursive non-EOS x-connect, which resolves through another
611 # x-connect
Neale Rannsad422ed2016-11-02 14:20:04 +0000612 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800613 route_34_neos = VppMplsRoute(self, 34, 0,
614 [VppRoutePath("0.0.0.0",
615 0xffffffff,
616 nh_via_label=32,
Neale Ranns31ed7442018-02-23 05:29:09 -0800617 labels=[VppMplsLabel(44),
618 VppMplsLabel(46)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000619 route_34_neos.add_vpp_config()
620
Neale Ranns31ed7442018-02-23 05:29:09 -0800621 tx = self.create_stream_labelled_ip4(self.pg0,
622 [VppMplsLabel(34, ttl=45),
623 VppMplsLabel(99)])
624 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Matej Klottondeb69842016-12-09 15:05:46 +0100625 # it's the 2nd (counting from 0) label in the stack that is swapped
Neale Ranns31ed7442018-02-23 05:29:09 -0800626 self.verify_capture_labelled(self.pg0, rx, tx,
627 [VppMplsLabel(33),
628 VppMplsLabel(44),
629 VppMplsLabel(46, ttl=44),
630 VppMplsLabel(99)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000631
632 #
Matej Klottondeb69842016-12-09 15:05:46 +0100633 # an recursive IP route that resolves through the recursive non-eos
634 # x-connect
Neale Rannsad422ed2016-11-02 14:20:04 +0000635 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800636 ip_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
637 [VppRoutePath("0.0.0.0",
638 0xffffffff,
639 nh_via_label=34,
Neale Ranns31ed7442018-02-23 05:29:09 -0800640 labels=[VppMplsLabel(55)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000641 ip_10_0_0_1.add_vpp_config()
642
Neale Rannsad422ed2016-11-02 14:20:04 +0000643 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800644 rx = self.send_and_expect(self.pg0, tx, self.pg0)
645 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
646 [VppMplsLabel(33),
647 VppMplsLabel(44),
648 VppMplsLabel(46),
649 VppMplsLabel(55)])
Neale Ranns008dbe12018-09-07 09:32:36 -0700650 self.assertEqual(ip_10_0_0_1.get_stats_to()['packets'], 257)
Neale Rannsad422ed2016-11-02 14:20:04 +0000651
652 ip_10_0_0_1.remove_vpp_config()
653 route_34_neos.remove_vpp_config()
654 route_34_eos.remove_vpp_config()
655 route_33_neos.remove_vpp_config()
656 route_33_eos.remove_vpp_config()
657 route_32_neos.remove_vpp_config()
658 route_32_eos.remove_vpp_config()
659
660 def test_bind(self):
661 """ MPLS Local Label Binding test """
662
663 #
664 # Add a non-recursive route with a single out label
665 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800666 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
667 [VppRoutePath(self.pg0.remote_ip4,
668 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800669 labels=[VppMplsLabel(45)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000670 route_10_0_0_1.add_vpp_config()
671
672 # bind a local label to the route
Neale Ranns5a8123b2017-01-26 01:18:23 -0800673 binding = VppMplsIpBind(self, 44, "10.0.0.1", 32)
Neale Rannsad422ed2016-11-02 14:20:04 +0000674 binding.add_vpp_config()
675
676 # non-EOS stream
Neale Ranns31ed7442018-02-23 05:29:09 -0800677 tx = self.create_stream_labelled_ip4(self.pg0,
678 [VppMplsLabel(44),
679 VppMplsLabel(99)])
680 rx = self.send_and_expect(self.pg0, tx, self.pg0)
681 self.verify_capture_labelled(self.pg0, rx, tx,
682 [VppMplsLabel(45, ttl=63),
683 VppMplsLabel(99)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000684
685 # EOS stream
Neale Ranns31ed7442018-02-23 05:29:09 -0800686 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(44)])
687 rx = self.send_and_expect(self.pg0, tx, self.pg0)
688 self.verify_capture_labelled(self.pg0, rx, tx,
689 [VppMplsLabel(45, ttl=63)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000690
691 # IP stream
Neale Rannsad422ed2016-11-02 14:20:04 +0000692 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800693 rx = self.send_and_expect(self.pg0, tx, self.pg0)
694 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [VppMplsLabel(45)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000695
696 #
697 # cleanup
698 #
699 binding.remove_vpp_config()
700 route_10_0_0_1.remove_vpp_config()
701
702 def test_imposition(self):
703 """ MPLS label imposition test """
704
705 #
706 # Add a non-recursive route with a single out label
707 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800708 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
709 [VppRoutePath(self.pg0.remote_ip4,
710 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800711 labels=[VppMplsLabel(32)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000712 route_10_0_0_1.add_vpp_config()
713
714 #
715 # a stream that matches the route for 10.0.0.1
716 # PG0 is in the default table
717 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000718 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800719 rx = self.send_and_expect(self.pg0, tx, self.pg0)
720 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [VppMplsLabel(32)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000721
722 #
723 # Add a non-recursive route with a 3 out labels
724 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800725 route_10_0_0_2 = VppIpRoute(self, "10.0.0.2", 32,
726 [VppRoutePath(self.pg0.remote_ip4,
727 self.pg0.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800728 labels=[VppMplsLabel(32),
729 VppMplsLabel(33),
730 VppMplsLabel(34)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000731 route_10_0_0_2.add_vpp_config()
732
Neale Ranns31ed7442018-02-23 05:29:09 -0800733 tx = self.create_stream_ip4(self.pg0, "10.0.0.2",
734 ip_ttl=44, ip_dscp=0xff)
735 rx = self.send_and_expect(self.pg0, tx, self.pg0)
736 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
737 [VppMplsLabel(32),
738 VppMplsLabel(33),
739 VppMplsLabel(34)],
740 ip_ttl=43)
Neale Rannsad422ed2016-11-02 14:20:04 +0000741
Neale Ranns31ed7442018-02-23 05:29:09 -0800742 #
743 # Add a non-recursive route with a single out label in uniform mode
744 #
745 route_10_0_0_3 = VppIpRoute(
746 self, "10.0.0.3", 32,
747 [VppRoutePath(self.pg0.remote_ip4,
748 self.pg0.sw_if_index,
749 labels=[VppMplsLabel(32,
750 mode=MplsLspMode.UNIFORM)])])
751 route_10_0_0_3.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000752
Neale Ranns31ed7442018-02-23 05:29:09 -0800753 tx = self.create_stream_ip4(self.pg0, "10.0.0.3",
754 ip_ttl=54, ip_dscp=0xbe)
755 rx = self.send_and_expect(self.pg0, tx, self.pg0)
756 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
757 [VppMplsLabel(32, ttl=53, exp=5)])
758
759 #
760 # Add a IPv6 non-recursive route with a single out label in
761 # uniform mode
762 #
763 route_2001_3 = VppIpRoute(
764 self, "2001::3", 128,
765 [VppRoutePath(self.pg0.remote_ip6,
766 self.pg0.sw_if_index,
767 proto=DpoProto.DPO_PROTO_IP6,
768 labels=[VppMplsLabel(32,
769 mode=MplsLspMode.UNIFORM)])],
770 is_ip6=1)
771 route_2001_3.add_vpp_config()
772
773 tx = self.create_stream_ip6(self.pg0, "2001::3",
774 ip_ttl=54, ip_dscp=0xbe)
775 rx = self.send_and_expect(self.pg0, tx, self.pg0)
776 self.verify_capture_labelled_ip6(self.pg0, rx, tx,
777 [VppMplsLabel(32, ttl=53, exp=5)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000778
779 #
Matej Klottondeb69842016-12-09 15:05:46 +0100780 # add a recursive path, with output label, via the 1 label route
Neale Rannsad422ed2016-11-02 14:20:04 +0000781 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800782 route_11_0_0_1 = VppIpRoute(self, "11.0.0.1", 32,
783 [VppRoutePath("10.0.0.1",
784 0xffffffff,
Neale Ranns31ed7442018-02-23 05:29:09 -0800785 labels=[VppMplsLabel(44)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000786 route_11_0_0_1.add_vpp_config()
787
788 #
789 # a stream that matches the route for 11.0.0.1, should pick up
790 # the label stack for 11.0.0.1 and 10.0.0.1
791 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000792 tx = self.create_stream_ip4(self.pg0, "11.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -0800793 rx = self.send_and_expect(self.pg0, tx, self.pg0)
794 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
795 [VppMplsLabel(32),
796 VppMplsLabel(44)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000797
Neale Ranns008dbe12018-09-07 09:32:36 -0700798 self.assertEqual(route_11_0_0_1.get_stats_to()['packets'], 257)
799
Neale Rannsad422ed2016-11-02 14:20:04 +0000800 #
801 # add a recursive path, with 2 labels, via the 3 label route
802 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800803 route_11_0_0_2 = VppIpRoute(self, "11.0.0.2", 32,
804 [VppRoutePath("10.0.0.2",
805 0xffffffff,
Neale Ranns31ed7442018-02-23 05:29:09 -0800806 labels=[VppMplsLabel(44),
807 VppMplsLabel(45)])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000808 route_11_0_0_2.add_vpp_config()
809
810 #
811 # a stream that matches the route for 11.0.0.1, should pick up
812 # the label stack for 11.0.0.1 and 10.0.0.1
813 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000814 tx = self.create_stream_ip4(self.pg0, "11.0.0.2")
Neale Ranns31ed7442018-02-23 05:29:09 -0800815 rx = self.send_and_expect(self.pg0, tx, self.pg0)
816 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
817 [VppMplsLabel(32),
818 VppMplsLabel(33),
819 VppMplsLabel(34),
820 VppMplsLabel(44),
821 VppMplsLabel(45)])
Neale Rannsad422ed2016-11-02 14:20:04 +0000822
Neale Ranns008dbe12018-09-07 09:32:36 -0700823 self.assertEqual(route_11_0_0_2.get_stats_to()['packets'], 257)
824
825 rx = self.send_and_expect(self.pg0, tx, self.pg0)
826 self.verify_capture_labelled_ip4(self.pg0, rx, tx,
827 [VppMplsLabel(32),
828 VppMplsLabel(33),
829 VppMplsLabel(34),
830 VppMplsLabel(44),
831 VppMplsLabel(45)])
832
833 self.assertEqual(route_11_0_0_2.get_stats_to()['packets'], 514)
834
Neale Rannsad422ed2016-11-02 14:20:04 +0000835 #
836 # cleanup
837 #
838 route_11_0_0_2.remove_vpp_config()
839 route_11_0_0_1.remove_vpp_config()
840 route_10_0_0_2.remove_vpp_config()
841 route_10_0_0_1.remove_vpp_config()
842
Neale Ranns31ed7442018-02-23 05:29:09 -0800843 def test_tunnel_pipe(self):
844 """ MPLS Tunnel Tests - Pipe """
Neale Rannsad422ed2016-11-02 14:20:04 +0000845
846 #
847 # Create a tunnel with a single out label
848 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800849 mpls_tun = VppMPLSTunnelInterface(
850 self,
851 [VppRoutePath(self.pg0.remote_ip4,
852 self.pg0.sw_if_index,
853 labels=[VppMplsLabel(44),
854 VppMplsLabel(46)])])
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800855 mpls_tun.add_vpp_config()
856 mpls_tun.admin_up()
Neale Rannsad422ed2016-11-02 14:20:04 +0000857
858 #
859 # add an unlabelled route through the new tunnel
860 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800861 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
862 [VppRoutePath("0.0.0.0",
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800863 mpls_tun._sw_if_index)])
Neale Ranns5a8123b2017-01-26 01:18:23 -0800864 route_10_0_0_3.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000865
866 self.vapi.cli("clear trace")
867 tx = self.create_stream_ip4(self.pg0, "10.0.0.3")
868 self.pg0.add_stream(tx)
869
870 self.pg_enable_capture(self.pg_interfaces)
871 self.pg_start()
872
873 rx = self.pg0.get_capture()
Neale Ranns31ed7442018-02-23 05:29:09 -0800874 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
875 [VppMplsLabel(44),
876 VppMplsLabel(46)])
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000877
Neale Ranns8c4611b2017-05-23 03:43:47 -0700878 #
879 # add a labelled route through the new tunnel
880 #
881 route_10_0_0_4 = VppIpRoute(self, "10.0.0.4", 32,
882 [VppRoutePath("0.0.0.0",
883 mpls_tun._sw_if_index,
884 labels=[33])])
885 route_10_0_0_4.add_vpp_config()
886
887 self.vapi.cli("clear trace")
888 tx = self.create_stream_ip4(self.pg0, "10.0.0.4")
889 self.pg0.add_stream(tx)
890
891 self.pg_enable_capture(self.pg_interfaces)
892 self.pg_start()
893
894 rx = self.pg0.get_capture()
Neale Ranns31ed7442018-02-23 05:29:09 -0800895 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
896 [VppMplsLabel(44),
897 VppMplsLabel(46),
898 VppMplsLabel(33, ttl=255)])
899
900 def test_tunnel_uniform(self):
901 """ MPLS Tunnel Tests - Uniform """
902
903 #
904 # Create a tunnel with a single out label
905 # The label stack is specified here from outer to inner
906 #
907 mpls_tun = VppMPLSTunnelInterface(
908 self,
909 [VppRoutePath(self.pg0.remote_ip4,
910 self.pg0.sw_if_index,
911 labels=[VppMplsLabel(44, ttl=32),
912 VppMplsLabel(46, MplsLspMode.UNIFORM)])])
913 mpls_tun.add_vpp_config()
914 mpls_tun.admin_up()
915
916 #
917 # add an unlabelled route through the new tunnel
918 #
919 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
920 [VppRoutePath("0.0.0.0",
921 mpls_tun._sw_if_index)])
922 route_10_0_0_3.add_vpp_config()
923
924 self.vapi.cli("clear trace")
925 tx = self.create_stream_ip4(self.pg0, "10.0.0.3", ip_ttl=24)
926 self.pg0.add_stream(tx)
927
928 self.pg_enable_capture(self.pg_interfaces)
929 self.pg_start()
930
931 rx = self.pg0.get_capture()
932 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
933 [VppMplsLabel(44, ttl=32),
934 VppMplsLabel(46, ttl=23)])
935
936 #
937 # add a labelled route through the new tunnel
938 #
939 route_10_0_0_4 = VppIpRoute(
940 self, "10.0.0.4", 32,
941 [VppRoutePath("0.0.0.0",
942 mpls_tun._sw_if_index,
943 labels=[VppMplsLabel(33, ttl=47)])])
944 route_10_0_0_4.add_vpp_config()
945
946 self.vapi.cli("clear trace")
947 tx = self.create_stream_ip4(self.pg0, "10.0.0.4")
948 self.pg0.add_stream(tx)
949
950 self.pg_enable_capture(self.pg_interfaces)
951 self.pg_start()
952
953 rx = self.pg0.get_capture()
954 self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
955 [VppMplsLabel(44, ttl=32),
956 VppMplsLabel(46, ttl=47),
957 VppMplsLabel(33, ttl=47)])
Neale Ranns8c4611b2017-05-23 03:43:47 -0700958
Neale Rannsf5fa5ae2018-09-26 05:07:25 -0700959 def test_mpls_tunnel_many(self):
960 """ Multiple Tunnels """
961
962 for ii in range(10):
963 mpls_tun = VppMPLSTunnelInterface(
964 self,
965 [VppRoutePath(self.pg0.remote_ip4,
966 self.pg0.sw_if_index,
967 labels=[VppMplsLabel(44, ttl=32),
968 VppMplsLabel(46, MplsLspMode.UNIFORM)])])
969 mpls_tun.add_vpp_config()
970 mpls_tun.admin_up()
971
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000972 def test_v4_exp_null(self):
973 """ MPLS V4 Explicit NULL test """
974
975 #
976 # The first test case has an MPLS TTL of 0
977 # all packet should be dropped
978 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800979 tx = self.create_stream_labelled_ip4(self.pg0,
980 [VppMplsLabel(0, ttl=0)])
981 self.send_and_assert_no_replies(self.pg0, tx,
982 "MPLS TTL=0 packets forwarded")
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000983
984 #
985 # a stream with a non-zero MPLS TTL
986 # PG0 is in the default table
987 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800988 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(0)])
989 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000990 self.verify_capture_ip4(self.pg0, rx, tx)
991
992 #
993 # a stream with a non-zero MPLS TTL
994 # PG1 is in table 1
995 # we are ensuring the post-pop lookup occurs in the VRF table
996 #
Neale Ranns31ed7442018-02-23 05:29:09 -0800997 tx = self.create_stream_labelled_ip4(self.pg1, [VppMplsLabel(0)])
998 rx = self.send_and_expect(self.pg1, tx, self.pg1)
999 self.verify_capture_ip4(self.pg1, rx, tx)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001000
1001 def test_v6_exp_null(self):
1002 """ MPLS V6 Explicit NULL test """
1003
1004 #
1005 # a stream with a non-zero MPLS TTL
1006 # PG0 is in the default table
1007 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001008 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(2)])
1009 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001010 self.verify_capture_ip6(self.pg0, rx, tx)
1011
1012 #
1013 # a stream with a non-zero MPLS TTL
1014 # PG1 is in table 1
1015 # we are ensuring the post-pop lookup occurs in the VRF table
1016 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001017 tx = self.create_stream_labelled_ip6(self.pg1, [VppMplsLabel(2)])
1018 rx = self.send_and_expect(self.pg1, tx, self.pg1)
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001019 self.verify_capture_ip6(self.pg0, rx, tx)
1020
Neale Rannscb630ff2016-12-14 13:31:29 +01001021 def test_deag(self):
1022 """ MPLS Deagg """
1023
1024 #
1025 # A de-agg route - next-hop lookup in default table
1026 #
Neale Ranns5a8123b2017-01-26 01:18:23 -08001027 route_34_eos = VppMplsRoute(self, 34, 1,
1028 [VppRoutePath("0.0.0.0",
1029 0xffffffff,
1030 nh_table_id=0)])
Neale Rannscb630ff2016-12-14 13:31:29 +01001031 route_34_eos.add_vpp_config()
1032
1033 #
1034 # ping an interface in the default table
1035 # PG0 is in the default table
1036 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001037 tx = self.create_stream_labelled_ip4(self.pg0,
1038 [VppMplsLabel(34)],
1039 ping=1,
Neale Rannscb630ff2016-12-14 13:31:29 +01001040 ip_itf=self.pg0)
Neale Ranns31ed7442018-02-23 05:29:09 -08001041 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Rannscb630ff2016-12-14 13:31:29 +01001042 self.verify_capture_ip4(self.pg0, rx, tx, ping_resp=1)
1043
1044 #
1045 # A de-agg route - next-hop lookup in non-default table
1046 #
Neale Ranns5a8123b2017-01-26 01:18:23 -08001047 route_35_eos = VppMplsRoute(self, 35, 1,
1048 [VppRoutePath("0.0.0.0",
1049 0xffffffff,
1050 nh_table_id=1)])
Neale Rannscb630ff2016-12-14 13:31:29 +01001051 route_35_eos.add_vpp_config()
1052
1053 #
1054 # ping an interface in the non-default table
1055 # PG0 is in the default table. packet arrive labelled in the
1056 # default table and egress unlabelled in the non-default
1057 #
Klement Sekeradab231a2016-12-21 08:50:14 +01001058 tx = self.create_stream_labelled_ip4(
Neale Ranns31ed7442018-02-23 05:29:09 -08001059 self.pg0, [VppMplsLabel(35)], ping=1, ip_itf=self.pg1)
1060 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Rannscb630ff2016-12-14 13:31:29 +01001061 self.verify_capture_ip4(self.pg1, rx, tx, ping_resp=1)
1062
Neale Ranns6af1c042017-05-26 03:48:53 -07001063 #
1064 # Double pop
1065 #
1066 route_36_neos = VppMplsRoute(self, 36, 0,
1067 [VppRoutePath("0.0.0.0",
1068 0xffffffff)])
1069 route_36_neos.add_vpp_config()
1070
Neale Ranns31ed7442018-02-23 05:29:09 -08001071 tx = self.create_stream_labelled_ip4(self.pg0,
1072 [VppMplsLabel(36),
1073 VppMplsLabel(35)],
Neale Ranns6af1c042017-05-26 03:48:53 -07001074 ping=1, ip_itf=self.pg1)
Neale Ranns31ed7442018-02-23 05:29:09 -08001075 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns6af1c042017-05-26 03:48:53 -07001076 self.verify_capture_ip4(self.pg1, rx, tx, ping_resp=1)
1077
1078 route_36_neos.remove_vpp_config()
Neale Rannscb630ff2016-12-14 13:31:29 +01001079 route_35_eos.remove_vpp_config()
1080 route_34_eos.remove_vpp_config()
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001081
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001082 def test_interface_rx(self):
1083 """ MPLS Interface Receive """
1084
1085 #
1086 # Add a non-recursive route that will forward the traffic
1087 # post-interface-rx
1088 #
1089 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
1090 table_id=1,
1091 paths=[VppRoutePath(self.pg1.remote_ip4,
1092 self.pg1.sw_if_index)])
1093 route_10_0_0_1.add_vpp_config()
1094
1095 #
1096 # An interface receive label that maps traffic to RX on interface
1097 # pg1
1098 # by injecting the packet in on pg0, which is in table 0
1099 # doing an interface-rx on pg1 and matching a route in table 1
1100 # if the packet egresses, then we must have swapped to pg1
1101 # so as to have matched the route in table 1
1102 #
1103 route_34_eos = VppMplsRoute(self, 34, 1,
1104 [VppRoutePath("0.0.0.0",
1105 self.pg1.sw_if_index,
1106 is_interface_rx=1)])
1107 route_34_eos.add_vpp_config()
1108
1109 #
1110 # ping an interface in the default table
1111 # PG0 is in the default table
1112 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001113 tx = self.create_stream_labelled_ip4(self.pg0,
1114 [VppMplsLabel(34)],
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001115 dst_ip="10.0.0.1")
Neale Ranns31ed7442018-02-23 05:29:09 -08001116 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001117 self.verify_capture_ip4(self.pg1, rx, tx)
1118
1119 def test_mcast_mid_point(self):
1120 """ MPLS Multicast Mid Point """
1121
1122 #
1123 # Add a non-recursive route that will forward the traffic
1124 # post-interface-rx
1125 #
1126 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
1127 table_id=1,
1128 paths=[VppRoutePath(self.pg1.remote_ip4,
1129 self.pg1.sw_if_index)])
1130 route_10_0_0_1.add_vpp_config()
1131
1132 #
1133 # Add a mcast entry that replicate to pg2 and pg3
1134 # and replicate to a interface-rx (like a bud node would)
1135 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001136 route_3400_eos = VppMplsRoute(
1137 self, 3400, 1,
1138 [VppRoutePath(self.pg2.remote_ip4,
1139 self.pg2.sw_if_index,
1140 labels=[VppMplsLabel(3401)]),
1141 VppRoutePath(self.pg3.remote_ip4,
1142 self.pg3.sw_if_index,
1143 labels=[VppMplsLabel(3402)]),
1144 VppRoutePath("0.0.0.0",
1145 self.pg1.sw_if_index,
1146 is_interface_rx=1)],
1147 is_multicast=1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001148 route_3400_eos.add_vpp_config()
1149
1150 #
1151 # ping an interface in the default table
1152 # PG0 is in the default table
1153 #
1154 self.vapi.cli("clear trace")
Neale Ranns31ed7442018-02-23 05:29:09 -08001155 tx = self.create_stream_labelled_ip4(self.pg0,
1156 [VppMplsLabel(3400, ttl=64)],
1157 n=257,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001158 dst_ip="10.0.0.1")
1159 self.pg0.add_stream(tx)
1160
1161 self.pg_enable_capture(self.pg_interfaces)
1162 self.pg_start()
1163
1164 rx = self.pg1.get_capture(257)
1165 self.verify_capture_ip4(self.pg1, rx, tx)
1166
1167 rx = self.pg2.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001168 self.verify_capture_labelled(self.pg2, rx, tx,
1169 [VppMplsLabel(3401, ttl=63)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001170 rx = self.pg3.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001171 self.verify_capture_labelled(self.pg3, rx, tx,
1172 [VppMplsLabel(3402, ttl=63)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001173
1174 def test_mcast_head(self):
1175 """ MPLS Multicast Head-end """
1176
1177 #
1178 # Create a multicast tunnel with two replications
1179 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001180 mpls_tun = VppMPLSTunnelInterface(
1181 self,
1182 [VppRoutePath(self.pg2.remote_ip4,
1183 self.pg2.sw_if_index,
1184 labels=[VppMplsLabel(42)]),
1185 VppRoutePath(self.pg3.remote_ip4,
1186 self.pg3.sw_if_index,
1187 labels=[VppMplsLabel(43)])],
1188 is_multicast=1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001189 mpls_tun.add_vpp_config()
1190 mpls_tun.admin_up()
1191
1192 #
1193 # add an unlabelled route through the new tunnel
1194 #
1195 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
1196 [VppRoutePath("0.0.0.0",
1197 mpls_tun._sw_if_index)])
1198 route_10_0_0_3.add_vpp_config()
1199
1200 self.vapi.cli("clear trace")
1201 tx = self.create_stream_ip4(self.pg0, "10.0.0.3")
1202 self.pg0.add_stream(tx)
1203
1204 self.pg_enable_capture(self.pg_interfaces)
1205 self.pg_start()
1206
1207 rx = self.pg2.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001208 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(42)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001209 rx = self.pg3.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001210 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(43)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001211
1212 #
1213 # An an IP multicast route via the tunnel
1214 # A (*,G).
1215 # one accepting interface, pg0, 1 forwarding interface via the tunnel
1216 #
1217 route_232_1_1_1 = VppIpMRoute(
1218 self,
1219 "0.0.0.0",
1220 "232.1.1.1", 32,
1221 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
1222 [VppMRoutePath(self.pg0.sw_if_index,
1223 MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
1224 VppMRoutePath(mpls_tun._sw_if_index,
1225 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
1226 route_232_1_1_1.add_vpp_config()
1227
1228 self.vapi.cli("clear trace")
1229 tx = self.create_stream_ip4(self.pg0, "232.1.1.1")
1230 self.pg0.add_stream(tx)
1231
1232 self.pg_enable_capture(self.pg_interfaces)
1233 self.pg_start()
1234
1235 rx = self.pg2.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001236 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(42)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001237 rx = self.pg3.get_capture(257)
Neale Ranns31ed7442018-02-23 05:29:09 -08001238 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(43)])
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001239
Neale Ranns31426c62017-05-24 10:32:58 -07001240 def test_mcast_ip4_tail(self):
1241 """ MPLS IPv4 Multicast Tail """
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001242
1243 #
1244 # Add a multicast route that will forward the traffic
1245 # post-disposition
1246 #
1247 route_232_1_1_1 = VppIpMRoute(
1248 self,
1249 "0.0.0.0",
1250 "232.1.1.1", 32,
1251 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
1252 table_id=1,
1253 paths=[VppMRoutePath(self.pg1.sw_if_index,
1254 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
1255 route_232_1_1_1.add_vpp_config()
1256
1257 #
1258 # An interface receive label that maps traffic to RX on interface
1259 # pg1
1260 # by injecting the packet in on pg0, which is in table 0
1261 # doing an rpf-id and matching a route in table 1
1262 # if the packet egresses, then we must have matched the route in
1263 # table 1
1264 #
1265 route_34_eos = VppMplsRoute(self, 34, 1,
1266 [VppRoutePath("0.0.0.0",
1267 self.pg1.sw_if_index,
1268 nh_table_id=1,
1269 rpf_id=55)],
1270 is_multicast=1)
1271
1272 route_34_eos.add_vpp_config()
1273
1274 #
1275 # Drop due to interface lookup miss
1276 #
1277 self.vapi.cli("clear trace")
Neale Ranns31ed7442018-02-23 05:29:09 -08001278 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001279 dst_ip="232.1.1.1", n=1)
1280 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop none")
1281
1282 #
1283 # set the RPF-ID of the enrtry to match the input packet's
1284 #
1285 route_232_1_1_1.update_rpf_id(55)
1286
Neale Ranns31ed7442018-02-23 05:29:09 -08001287 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
1288 dst_ip="232.1.1.1")
1289 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001290 self.verify_capture_ip4(self.pg1, rx, tx)
1291
1292 #
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001293 # disposed packets have an invalid IPv4 checkusm
1294 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001295 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001296 dst_ip="232.1.1.1", n=65,
1297 chksum=1)
1298 self.send_and_assert_no_replies(self.pg0, tx, "Invalid Checksum")
1299
1300 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001301 # set the RPF-ID of the entry to not match the input packet's
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001302 #
1303 route_232_1_1_1.update_rpf_id(56)
Neale Ranns31ed7442018-02-23 05:29:09 -08001304 tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001305 dst_ip="232.1.1.1")
1306 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop 56")
1307
Neale Ranns31426c62017-05-24 10:32:58 -07001308 def test_mcast_ip6_tail(self):
1309 """ MPLS IPv6 Multicast Tail """
1310
1311 #
1312 # Add a multicast route that will forward the traffic
1313 # post-disposition
1314 #
1315 route_ff = VppIpMRoute(
1316 self,
1317 "::",
1318 "ff01::1", 32,
1319 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
1320 table_id=1,
1321 paths=[VppMRoutePath(self.pg1.sw_if_index,
1322 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)],
1323 is_ip6=1)
1324 route_ff.add_vpp_config()
1325
1326 #
1327 # An interface receive label that maps traffic to RX on interface
1328 # pg1
1329 # by injecting the packet in on pg0, which is in table 0
1330 # doing an rpf-id and matching a route in table 1
1331 # if the packet egresses, then we must have matched the route in
1332 # table 1
1333 #
1334 route_34_eos = VppMplsRoute(
1335 self, 34, 1,
1336 [VppRoutePath("::",
1337 self.pg1.sw_if_index,
1338 nh_table_id=1,
1339 rpf_id=55,
Neale Rannsda78f952017-05-24 09:15:43 -07001340 proto=DpoProto.DPO_PROTO_IP6)],
Neale Ranns31426c62017-05-24 10:32:58 -07001341 is_multicast=1)
1342
1343 route_34_eos.add_vpp_config()
1344
1345 #
1346 # Drop due to interface lookup miss
1347 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001348 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(34)],
Neale Ranns31426c62017-05-24 10:32:58 -07001349 dst_ip="ff01::1")
Neale Ranns31ed7442018-02-23 05:29:09 -08001350 self.send_and_assert_no_replies(self.pg0, tx, "RPF Miss")
Neale Ranns31426c62017-05-24 10:32:58 -07001351
1352 #
1353 # set the RPF-ID of the enrtry to match the input packet's
1354 #
1355 route_ff.update_rpf_id(55)
1356
Neale Ranns31ed7442018-02-23 05:29:09 -08001357 tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(34)],
Neale Ranns31426c62017-05-24 10:32:58 -07001358 dst_ip="ff01::1")
Neale Ranns31ed7442018-02-23 05:29:09 -08001359 rx = self.send_and_expect(self.pg0, tx, self.pg1)
Neale Ranns31426c62017-05-24 10:32:58 -07001360 self.verify_capture_ip6(self.pg1, rx, tx)
1361
1362 #
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001363 # disposed packets have hop-limit = 1
1364 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001365 tx = self.create_stream_labelled_ip6(self.pg0,
1366 [VppMplsLabel(34)],
1367 dst_ip="ff01::1",
1368 hlim=1)
1369 rx = self.send_and_expect(self.pg0, tx, self.pg0)
Neale Ranns52fae862018-01-08 04:41:42 -08001370 self.verify_capture_ip6_icmp(self.pg0, rx, tx)
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001371
1372 #
Neale Ranns31426c62017-05-24 10:32:58 -07001373 # set the RPF-ID of the enrtry to not match the input packet's
1374 #
1375 route_ff.update_rpf_id(56)
Neale Ranns31ed7442018-02-23 05:29:09 -08001376 tx = self.create_stream_labelled_ip6(self.pg0,
1377 [VppMplsLabel(34)],
Neale Ranns31426c62017-05-24 10:32:58 -07001378 dst_ip="ff01::1")
1379 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop 56")
1380
Neale Ranns180279b2017-03-16 15:49:09 -04001381
1382class TestMPLSDisabled(VppTestCase):
1383 """ MPLS disabled """
1384
1385 def setUp(self):
1386 super(TestMPLSDisabled, self).setUp()
1387
1388 # create 2 pg interfaces
1389 self.create_pg_interfaces(range(2))
1390
Neale Ranns15002542017-09-10 04:39:11 -07001391 self.tbl = VppMplsTable(self, 0)
1392 self.tbl.add_vpp_config()
1393
Neale Ranns180279b2017-03-16 15:49:09 -04001394 # PG0 is MPLS enalbed
1395 self.pg0.admin_up()
1396 self.pg0.config_ip4()
1397 self.pg0.resolve_arp()
1398 self.pg0.enable_mpls()
1399
1400 # PG 1 is not MPLS enabled
1401 self.pg1.admin_up()
1402
1403 def tearDown(self):
Neale Ranns180279b2017-03-16 15:49:09 -04001404 for i in self.pg_interfaces:
1405 i.unconfig_ip4()
1406 i.admin_down()
1407
Neale Ranns15002542017-09-10 04:39:11 -07001408 self.pg0.disable_mpls()
1409 super(TestMPLSDisabled, self).tearDown()
1410
Neale Ranns180279b2017-03-16 15:49:09 -04001411 def test_mpls_disabled(self):
1412 """ MPLS Disabled """
1413
1414 tx = (Ether(src=self.pg1.remote_mac,
1415 dst=self.pg1.local_mac) /
1416 MPLS(label=32, ttl=64) /
1417 IPv6(src="2001::1", dst=self.pg0.remote_ip6) /
1418 UDP(sport=1234, dport=1234) /
1419 Raw('\xa5' * 100))
1420
1421 #
1422 # A simple MPLS xconnect - eos label in label out
1423 #
1424 route_32_eos = VppMplsRoute(self, 32, 1,
1425 [VppRoutePath(self.pg0.remote_ip4,
1426 self.pg0.sw_if_index,
1427 labels=[33])])
1428 route_32_eos.add_vpp_config()
1429
1430 #
1431 # PG1 does not forward IP traffic
1432 #
1433 self.send_and_assert_no_replies(self.pg1, tx, "MPLS disabled")
1434
1435 #
1436 # MPLS enable PG1
1437 #
1438 self.pg1.enable_mpls()
1439
1440 #
1441 # Now we get packets through
1442 #
1443 self.pg1.add_stream(tx)
1444 self.pg_enable_capture(self.pg_interfaces)
1445 self.pg_start()
1446
1447 rx = self.pg0.get_capture(1)
1448
1449 #
1450 # Disable PG1
1451 #
1452 self.pg1.disable_mpls()
1453
1454 #
1455 # PG1 does not forward IP traffic
1456 #
1457 self.send_and_assert_no_replies(self.pg1, tx, "IPv6 disabled")
1458 self.send_and_assert_no_replies(self.pg1, tx, "IPv6 disabled")
1459
1460
Neale Rannsf12a83f2017-04-18 09:09:40 -07001461class TestMPLSPIC(VppTestCase):
1462 """ MPLS PIC edge convergence """
1463
1464 def setUp(self):
1465 super(TestMPLSPIC, self).setUp()
1466
1467 # create 2 pg interfaces
1468 self.create_pg_interfaces(range(4))
1469
Neale Ranns15002542017-09-10 04:39:11 -07001470 mpls_tbl = VppMplsTable(self, 0)
1471 mpls_tbl.add_vpp_config()
1472 tbl4 = VppIpTable(self, 1)
1473 tbl4.add_vpp_config()
1474 tbl6 = VppIpTable(self, 1, is_ip6=1)
1475 tbl6.add_vpp_config()
1476
Neale Rannsf12a83f2017-04-18 09:09:40 -07001477 # core links
1478 self.pg0.admin_up()
1479 self.pg0.config_ip4()
1480 self.pg0.resolve_arp()
1481 self.pg0.enable_mpls()
1482 self.pg1.admin_up()
1483 self.pg1.config_ip4()
1484 self.pg1.resolve_arp()
1485 self.pg1.enable_mpls()
1486
1487 # VRF (customer facing) link
1488 self.pg2.admin_up()
1489 self.pg2.set_table_ip4(1)
1490 self.pg2.config_ip4()
1491 self.pg2.resolve_arp()
1492 self.pg2.set_table_ip6(1)
1493 self.pg2.config_ip6()
1494 self.pg2.resolve_ndp()
1495 self.pg3.admin_up()
1496 self.pg3.set_table_ip4(1)
1497 self.pg3.config_ip4()
1498 self.pg3.resolve_arp()
1499 self.pg3.set_table_ip6(1)
1500 self.pg3.config_ip6()
1501 self.pg3.resolve_ndp()
1502
1503 def tearDown(self):
Neale Rannsf12a83f2017-04-18 09:09:40 -07001504 self.pg0.disable_mpls()
Neale Ranns15002542017-09-10 04:39:11 -07001505 self.pg1.disable_mpls()
Neale Rannsf12a83f2017-04-18 09:09:40 -07001506 for i in self.pg_interfaces:
1507 i.unconfig_ip4()
1508 i.unconfig_ip6()
1509 i.set_table_ip4(0)
1510 i.set_table_ip6(0)
1511 i.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -07001512 super(TestMPLSPIC, self).tearDown()
Neale Rannsf12a83f2017-04-18 09:09:40 -07001513
1514 def test_mpls_ibgp_pic(self):
1515 """ MPLS iBGP PIC edge convergence
1516
1517 1) setup many iBGP VPN routes via a pair of iBGP peers.
1518 2) Check EMCP forwarding to these peers
1519 3) withdraw the IGP route to one of these peers.
1520 4) check forwarding continues to the remaining peer
1521 """
1522
1523 #
1524 # IGP+LDP core routes
1525 #
1526 core_10_0_0_45 = VppIpRoute(self, "10.0.0.45", 32,
1527 [VppRoutePath(self.pg0.remote_ip4,
1528 self.pg0.sw_if_index,
1529 labels=[45])])
1530 core_10_0_0_45.add_vpp_config()
1531
1532 core_10_0_0_46 = VppIpRoute(self, "10.0.0.46", 32,
1533 [VppRoutePath(self.pg1.remote_ip4,
1534 self.pg1.sw_if_index,
1535 labels=[46])])
1536 core_10_0_0_46.add_vpp_config()
1537
1538 #
1539 # Lot's of VPN routes. We need more the 64 so VPP will build
1540 # the fast convergence indirection
1541 #
1542 vpn_routes = []
1543 pkts = []
1544 for ii in range(64):
1545 dst = "192.168.1.%d" % ii
1546 vpn_routes.append(VppIpRoute(self, dst, 32,
1547 [VppRoutePath("10.0.0.45",
1548 0xffffffff,
1549 labels=[145],
1550 is_resolve_host=1),
1551 VppRoutePath("10.0.0.46",
1552 0xffffffff,
1553 labels=[146],
1554 is_resolve_host=1)],
1555 table_id=1))
1556 vpn_routes[ii].add_vpp_config()
1557
1558 pkts.append(Ether(dst=self.pg2.local_mac,
1559 src=self.pg2.remote_mac) /
1560 IP(src=self.pg2.remote_ip4, dst=dst) /
1561 UDP(sport=1234, dport=1234) /
1562 Raw('\xa5' * 100))
1563
1564 #
1565 # Send the packet stream (one pkt to each VPN route)
1566 # - expect a 50-50 split of the traffic
1567 #
1568 self.pg2.add_stream(pkts)
1569 self.pg_enable_capture(self.pg_interfaces)
1570 self.pg_start()
1571
1572 rx0 = self.pg0._get_capture(1)
1573 rx1 = self.pg1._get_capture(1)
1574
1575 # not testig the LB hashing algorithm so we're not concerned
1576 # with the split ratio, just as long as neither is 0
1577 self.assertNotEqual(0, len(rx0))
1578 self.assertNotEqual(0, len(rx1))
1579
1580 #
1581 # use a test CLI command to stop the FIB walk process, this
1582 # will prevent the FIB converging the VPN routes and thus allow
1583 # us to probe the interim (psot-fail, pre-converge) state
1584 #
1585 self.vapi.ppcli("test fib-walk-process disable")
1586
1587 #
1588 # Withdraw one of the IGP routes
1589 #
1590 core_10_0_0_46.remove_vpp_config()
1591
1592 #
1593 # now all packets should be forwarded through the remaining peer
1594 #
1595 self.vapi.ppcli("clear trace")
1596 self.pg2.add_stream(pkts)
1597 self.pg_enable_capture(self.pg_interfaces)
1598 self.pg_start()
1599
1600 rx0 = self.pg0.get_capture(len(pkts))
1601
1602 #
1603 # enable the FIB walk process to converge the FIB
1604 #
1605 self.vapi.ppcli("test fib-walk-process enable")
1606
1607 #
1608 # packets should still be forwarded through the remaining peer
1609 #
1610 self.pg2.add_stream(pkts)
1611 self.pg_enable_capture(self.pg_interfaces)
1612 self.pg_start()
1613
1614 rx0 = self.pg0.get_capture(64)
1615
1616 #
1617 # Add the IGP route back and we return to load-balancing
1618 #
1619 core_10_0_0_46.add_vpp_config()
1620
1621 self.pg2.add_stream(pkts)
1622 self.pg_enable_capture(self.pg_interfaces)
1623 self.pg_start()
1624
1625 rx0 = self.pg0._get_capture(1)
1626 rx1 = self.pg1._get_capture(1)
1627 self.assertNotEqual(0, len(rx0))
1628 self.assertNotEqual(0, len(rx1))
1629
1630 def test_mpls_ebgp_pic(self):
1631 """ MPLS eBGP PIC edge convergence
1632
1633 1) setup many eBGP VPN routes via a pair of eBGP peers
1634 2) Check EMCP forwarding to these peers
1635 3) withdraw one eBGP path - expect LB across remaining eBGP
1636 """
1637
1638 #
1639 # Lot's of VPN routes. We need more the 64 so VPP will build
1640 # the fast convergence indirection
1641 #
1642 vpn_routes = []
1643 vpn_bindings = []
1644 pkts = []
1645 for ii in range(64):
1646 dst = "192.168.1.%d" % ii
1647 local_label = 1600 + ii
1648 vpn_routes.append(VppIpRoute(self, dst, 32,
1649 [VppRoutePath(self.pg2.remote_ip4,
1650 0xffffffff,
1651 nh_table_id=1,
1652 is_resolve_attached=1),
1653 VppRoutePath(self.pg3.remote_ip4,
1654 0xffffffff,
1655 nh_table_id=1,
1656 is_resolve_attached=1)],
1657 table_id=1))
1658 vpn_routes[ii].add_vpp_config()
1659
1660 vpn_bindings.append(VppMplsIpBind(self, local_label, dst, 32,
1661 ip_table_id=1))
1662 vpn_bindings[ii].add_vpp_config()
1663
1664 pkts.append(Ether(dst=self.pg0.local_mac,
1665 src=self.pg0.remote_mac) /
1666 MPLS(label=local_label, ttl=64) /
1667 IP(src=self.pg0.remote_ip4, dst=dst) /
1668 UDP(sport=1234, dport=1234) /
1669 Raw('\xa5' * 100))
1670
1671 self.pg0.add_stream(pkts)
1672 self.pg_enable_capture(self.pg_interfaces)
1673 self.pg_start()
1674
1675 rx0 = self.pg2._get_capture(1)
1676 rx1 = self.pg3._get_capture(1)
1677 self.assertNotEqual(0, len(rx0))
1678 self.assertNotEqual(0, len(rx1))
1679
1680 #
1681 # use a test CLI command to stop the FIB walk process, this
1682 # will prevent the FIB converging the VPN routes and thus allow
1683 # us to probe the interim (psot-fail, pre-converge) state
1684 #
1685 self.vapi.ppcli("test fib-walk-process disable")
1686
1687 #
1688 # withdraw the connected prefix on the interface.
1689 #
1690 self.pg2.unconfig_ip4()
1691
1692 #
1693 # now all packets should be forwarded through the remaining peer
1694 #
1695 self.pg0.add_stream(pkts)
1696 self.pg_enable_capture(self.pg_interfaces)
1697 self.pg_start()
1698
1699 rx0 = self.pg3.get_capture(len(pkts))
1700
1701 #
1702 # enable the FIB walk process to converge the FIB
1703 #
1704 self.vapi.ppcli("test fib-walk-process enable")
1705 self.pg0.add_stream(pkts)
1706 self.pg_enable_capture(self.pg_interfaces)
1707 self.pg_start()
1708
1709 rx0 = self.pg3.get_capture(len(pkts))
1710
1711 #
1712 # put the connecteds back
1713 #
1714 self.pg2.config_ip4()
1715
1716 self.pg0.add_stream(pkts)
1717 self.pg_enable_capture(self.pg_interfaces)
1718 self.pg_start()
1719
1720 rx0 = self.pg2._get_capture(1)
1721 rx1 = self.pg3._get_capture(1)
1722 self.assertNotEqual(0, len(rx0))
1723 self.assertNotEqual(0, len(rx1))
1724
1725 def test_mpls_v6_ebgp_pic(self):
1726 """ MPLSv6 eBGP PIC edge convergence
1727
1728 1) setup many eBGP VPNv6 routes via a pair of eBGP peers
1729 2) Check EMCP forwarding to these peers
1730 3) withdraw one eBGP path - expect LB across remaining eBGP
1731 """
1732
1733 #
1734 # Lot's of VPN routes. We need more the 64 so VPP will build
1735 # the fast convergence indirection
1736 #
1737 vpn_routes = []
1738 vpn_bindings = []
1739 pkts = []
1740 for ii in range(64):
1741 dst = "3000::%d" % ii
1742 local_label = 1600 + ii
Neale Rannsda78f952017-05-24 09:15:43 -07001743 vpn_routes.append(VppIpRoute(
1744 self, dst, 128,
1745 [VppRoutePath(self.pg2.remote_ip6,
1746 0xffffffff,
1747 nh_table_id=1,
1748 is_resolve_attached=1,
1749 proto=DpoProto.DPO_PROTO_IP6),
1750 VppRoutePath(self.pg3.remote_ip6,
1751 0xffffffff,
1752 nh_table_id=1,
1753 proto=DpoProto.DPO_PROTO_IP6,
1754 is_resolve_attached=1)],
1755 table_id=1,
1756 is_ip6=1))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001757 vpn_routes[ii].add_vpp_config()
1758
1759 vpn_bindings.append(VppMplsIpBind(self, local_label, dst, 128,
1760 ip_table_id=1,
1761 is_ip6=1))
1762 vpn_bindings[ii].add_vpp_config()
1763
1764 pkts.append(Ether(dst=self.pg0.local_mac,
1765 src=self.pg0.remote_mac) /
1766 MPLS(label=local_label, ttl=64) /
1767 IPv6(src=self.pg0.remote_ip6, dst=dst) /
1768 UDP(sport=1234, dport=1234) /
1769 Raw('\xa5' * 100))
1770
1771 self.pg0.add_stream(pkts)
1772 self.pg_enable_capture(self.pg_interfaces)
1773 self.pg_start()
1774
1775 rx0 = self.pg2._get_capture(1)
1776 rx1 = self.pg3._get_capture(1)
1777 self.assertNotEqual(0, len(rx0))
1778 self.assertNotEqual(0, len(rx1))
1779
1780 #
1781 # use a test CLI command to stop the FIB walk process, this
1782 # will prevent the FIB converging the VPN routes and thus allow
1783 # us to probe the interim (psot-fail, pre-converge) state
1784 #
1785 self.vapi.ppcli("test fib-walk-process disable")
1786
1787 #
1788 # withdraw the connected prefix on the interface.
1789 # and shutdown the interface so the ND cache is flushed.
1790 #
1791 self.pg2.unconfig_ip6()
1792 self.pg2.admin_down()
1793
1794 #
1795 # now all packets should be forwarded through the remaining peer
1796 #
1797 self.pg0.add_stream(pkts)
1798 self.pg_enable_capture(self.pg_interfaces)
1799 self.pg_start()
1800
1801 rx0 = self.pg3.get_capture(len(pkts))
1802
1803 #
1804 # enable the FIB walk process to converge the FIB
1805 #
1806 self.vapi.ppcli("test fib-walk-process enable")
1807 self.pg0.add_stream(pkts)
1808 self.pg_enable_capture(self.pg_interfaces)
1809 self.pg_start()
1810
1811 rx0 = self.pg3.get_capture(len(pkts))
1812
1813 #
1814 # put the connecteds back
1815 #
1816 self.pg2.admin_up()
1817 self.pg2.config_ip6()
1818
1819 self.pg0.add_stream(pkts)
1820 self.pg_enable_capture(self.pg_interfaces)
1821 self.pg_start()
1822
1823 rx0 = self.pg2._get_capture(1)
1824 rx1 = self.pg3._get_capture(1)
1825 self.assertNotEqual(0, len(rx0))
1826 self.assertNotEqual(0, len(rx1))
1827
1828
Neale Rannsda78f952017-05-24 09:15:43 -07001829class TestMPLSL2(VppTestCase):
1830 """ MPLS-L2 """
1831
1832 def setUp(self):
1833 super(TestMPLSL2, self).setUp()
1834
1835 # create 2 pg interfaces
1836 self.create_pg_interfaces(range(2))
1837
Neale Ranns15002542017-09-10 04:39:11 -07001838 # create the default MPLS table
1839 self.tables = []
1840 tbl = VppMplsTable(self, 0)
1841 tbl.add_vpp_config()
1842 self.tables.append(tbl)
1843
Neale Rannsda78f952017-05-24 09:15:43 -07001844 # use pg0 as the core facing interface
1845 self.pg0.admin_up()
1846 self.pg0.config_ip4()
1847 self.pg0.resolve_arp()
1848 self.pg0.enable_mpls()
1849
Neale Ranns15002542017-09-10 04:39:11 -07001850 # use the other 2 for customer facing L2 links
Neale Rannsda78f952017-05-24 09:15:43 -07001851 for i in self.pg_interfaces[1:]:
1852 i.admin_up()
1853
1854 def tearDown(self):
Neale Rannsda78f952017-05-24 09:15:43 -07001855 for i in self.pg_interfaces[1:]:
1856 i.admin_down()
1857
1858 self.pg0.disable_mpls()
1859 self.pg0.unconfig_ip4()
1860 self.pg0.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -07001861 super(TestMPLSL2, self).tearDown()
Neale Rannsda78f952017-05-24 09:15:43 -07001862
Neale Ranns31ed7442018-02-23 05:29:09 -08001863 def verify_capture_tunneled_ethernet(self, capture, sent, mpls_labels):
Neale Rannsda78f952017-05-24 09:15:43 -07001864 capture = verify_filter(capture, sent)
1865
1866 self.assertEqual(len(capture), len(sent))
1867
1868 for i in range(len(capture)):
1869 tx = sent[i]
1870 rx = capture[i]
1871
1872 # the MPLS TTL is 255 since it enters a new tunnel
Neale Ranns31ed7442018-02-23 05:29:09 -08001873 verify_mpls_stack(self, rx, mpls_labels)
Neale Rannsda78f952017-05-24 09:15:43 -07001874
1875 tx_eth = tx[Ether]
1876 rx_eth = Ether(str(rx[MPLS].payload))
1877
1878 self.assertEqual(rx_eth.src, tx_eth.src)
1879 self.assertEqual(rx_eth.dst, tx_eth.dst)
1880
1881 def test_vpws(self):
1882 """ Virtual Private Wire Service """
1883
1884 #
1885 # Create an MPLS tunnel that pushes 1 label
Neale Ranns31ed7442018-02-23 05:29:09 -08001886 # For Ethernet over MPLS the uniform mode is irrelevant since ttl/cos
1887 # information is not in the packet, but we test it works anyway
Neale Rannsda78f952017-05-24 09:15:43 -07001888 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001889 mpls_tun_1 = VppMPLSTunnelInterface(
1890 self,
1891 [VppRoutePath(self.pg0.remote_ip4,
1892 self.pg0.sw_if_index,
1893 labels=[VppMplsLabel(42, MplsLspMode.UNIFORM)])],
1894 is_l2=1)
Neale Rannsda78f952017-05-24 09:15:43 -07001895 mpls_tun_1.add_vpp_config()
1896 mpls_tun_1.admin_up()
1897
1898 #
1899 # Create a label entry to for 55 that does L2 input to the tunnel
1900 #
1901 route_55_eos = VppMplsRoute(
1902 self, 55, 1,
1903 [VppRoutePath("0.0.0.0",
1904 mpls_tun_1.sw_if_index,
1905 is_interface_rx=1,
1906 proto=DpoProto.DPO_PROTO_ETHERNET)])
1907 route_55_eos.add_vpp_config()
1908
1909 #
1910 # Cross-connect the tunnel with one of the customers L2 interfaces
1911 #
1912 self.vapi.sw_interface_set_l2_xconnect(self.pg1.sw_if_index,
1913 mpls_tun_1.sw_if_index,
1914 enable=1)
1915 self.vapi.sw_interface_set_l2_xconnect(mpls_tun_1.sw_if_index,
1916 self.pg1.sw_if_index,
1917 enable=1)
1918
1919 #
1920 # inject a packet from the core
1921 #
1922 pcore = (Ether(dst=self.pg0.local_mac,
1923 src=self.pg0.remote_mac) /
1924 MPLS(label=55, ttl=64) /
1925 Ether(dst="00:00:de:ad:ba:be",
1926 src="00:00:de:ad:be:ef") /
1927 IP(src="10.10.10.10", dst="11.11.11.11") /
1928 UDP(sport=1234, dport=1234) /
1929 Raw('\xa5' * 100))
1930
Neale Ranns31ed7442018-02-23 05:29:09 -08001931 tx0 = pcore * 65
1932 rx0 = self.send_and_expect(self.pg0, tx0, self.pg1)
1933 payload = pcore[MPLS].payload
Neale Rannsda78f952017-05-24 09:15:43 -07001934
Neale Ranns31ed7442018-02-23 05:29:09 -08001935 self.assertEqual(rx0[0][Ether].dst, payload[Ether].dst)
1936 self.assertEqual(rx0[0][Ether].src, payload[Ether].src)
Neale Rannsda78f952017-05-24 09:15:43 -07001937
1938 #
1939 # Inject a packet from the custoer/L2 side
1940 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001941 tx1 = pcore[MPLS].payload * 65
1942 rx1 = self.send_and_expect(self.pg1, tx1, self.pg0)
Neale Rannsda78f952017-05-24 09:15:43 -07001943
Neale Ranns31ed7442018-02-23 05:29:09 -08001944 self.verify_capture_tunneled_ethernet(rx1, tx1, [VppMplsLabel(42)])
Neale Rannsda78f952017-05-24 09:15:43 -07001945
1946 def test_vpls(self):
1947 """ Virtual Private LAN Service """
1948 #
1949 # Create an L2 MPLS tunnel
1950 #
Neale Ranns31ed7442018-02-23 05:29:09 -08001951 mpls_tun = VppMPLSTunnelInterface(
1952 self,
1953 [VppRoutePath(self.pg0.remote_ip4,
1954 self.pg0.sw_if_index,
1955 labels=[VppMplsLabel(42)])],
1956 is_l2=1)
Neale Rannsda78f952017-05-24 09:15:43 -07001957 mpls_tun.add_vpp_config()
1958 mpls_tun.admin_up()
1959
1960 #
1961 # Create a label entry to for 55 that does L2 input to the tunnel
1962 #
1963 route_55_eos = VppMplsRoute(
1964 self, 55, 1,
1965 [VppRoutePath("0.0.0.0",
1966 mpls_tun.sw_if_index,
1967 is_interface_rx=1,
1968 proto=DpoProto.DPO_PROTO_ETHERNET)])
1969 route_55_eos.add_vpp_config()
1970
1971 #
1972 # add to tunnel to the customers bridge-domain
1973 #
1974 self.vapi.sw_interface_set_l2_bridge(mpls_tun.sw_if_index,
1975 bd_id=1)
1976 self.vapi.sw_interface_set_l2_bridge(self.pg1.sw_if_index,
1977 bd_id=1)
1978
1979 #
1980 # Packet from the customer interface and from the core
1981 #
1982 p_cust = (Ether(dst="00:00:de:ad:ba:be",
1983 src="00:00:de:ad:be:ef") /
1984 IP(src="10.10.10.10", dst="11.11.11.11") /
1985 UDP(sport=1234, dport=1234) /
1986 Raw('\xa5' * 100))
1987 p_core = (Ether(src="00:00:de:ad:ba:be",
1988 dst="00:00:de:ad:be:ef") /
1989 IP(dst="10.10.10.10", src="11.11.11.11") /
1990 UDP(sport=1234, dport=1234) /
1991 Raw('\xa5' * 100))
1992
1993 #
1994 # The BD is learning, so send in one of each packet to learn
1995 #
1996 p_core_encap = (Ether(dst=self.pg0.local_mac,
1997 src=self.pg0.remote_mac) /
1998 MPLS(label=55, ttl=64) /
1999 p_core)
2000
2001 self.pg1.add_stream(p_cust)
2002 self.pg_enable_capture(self.pg_interfaces)
2003 self.pg_start()
2004 self.pg0.add_stream(p_core_encap)
2005 self.pg_enable_capture(self.pg_interfaces)
2006 self.pg_start()
2007
2008 # we've learnt this so expect it be be forwarded
2009 rx0 = self.pg1.get_capture(1)
2010
2011 self.assertEqual(rx0[0][Ether].dst, p_core[Ether].dst)
2012 self.assertEqual(rx0[0][Ether].src, p_core[Ether].src)
2013
2014 #
2015 # now a stream in each direction
2016 #
2017 self.pg1.add_stream(p_cust * 65)
2018 self.pg_enable_capture(self.pg_interfaces)
2019 self.pg_start()
2020
2021 rx0 = self.pg0.get_capture(65)
2022
Neale Ranns31ed7442018-02-23 05:29:09 -08002023 self.verify_capture_tunneled_ethernet(rx0, p_cust*65,
2024 [VppMplsLabel(42)])
Neale Rannsda78f952017-05-24 09:15:43 -07002025
2026 #
2027 # remove interfaces from customers bridge-domain
2028 #
2029 self.vapi.sw_interface_set_l2_bridge(mpls_tun.sw_if_index,
2030 bd_id=1,
2031 enable=0)
2032 self.vapi.sw_interface_set_l2_bridge(self.pg1.sw_if_index,
2033 bd_id=1,
2034 enable=0)
2035
Neale Ranns8fe8cc22016-11-01 10:05:08 +00002036if __name__ == '__main__':
2037 unittest.main(testRunner=VppTestRunner)