blob: d265e85ed5e0897167abe51a90bbbc9ae79682b6 [file] [log] [blame]
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001#!/usr/bin/env python
2
3import unittest
Gabriel Gannea9b2d582016-12-06 10:25:34 +01004import socket
Neale Ranns8fe8cc22016-11-01 10:05:08 +00005
6from framework import VppTestCase, VppTestRunner
Neale Ranns5a8123b2017-01-26 01:18:23 -08007from vpp_ip_route import VppIpRoute, VppRoutePath, VppMplsRoute, \
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008 VppMplsIpBind, VppIpMRoute, VppMRoutePath, \
Neale Ranns15002542017-09-10 04:39:11 -07009 MRouteItfFlags, MRouteEntryFlags, DpoProto, VppIpTable, VppMplsTable
Neale Ranns0f26c5a2017-03-01 15:12:11 -080010from vpp_mpls_tunnel_interface import VppMPLSTunnelInterface
Neale Ranns8fe8cc22016-11-01 10:05:08 +000011
12from scapy.packet import Raw
Klement Sekera7bb873a2016-11-18 07:38:42 +010013from scapy.layers.l2 import Ether
Neale Rannscb630ff2016-12-14 13:31:29 +010014from scapy.layers.inet import IP, UDP, ICMP
Klement Sekera7bb873a2016-11-18 07:38:42 +010015from scapy.layers.inet6 import IPv6
Neale Ranns8fe8cc22016-11-01 10:05:08 +000016from scapy.contrib.mpls import MPLS
17
Klement Sekeradab231a2016-12-21 08:50:14 +010018
Neale Rannsda78f952017-05-24 09:15:43 -070019def verify_filter(capture, sent):
20 if not len(capture) == len(sent):
21 # filter out any IPv6 RAs from the capture
22 for p in capture:
23 if p.haslayer(IPv6):
24 capture.remove(p)
25 return capture
26
27
28def verify_mpls_stack(tst, rx, mpls_labels, ttl=255, num=0):
29 # the rx'd packet has the MPLS label popped
30 eth = rx[Ether]
31 tst.assertEqual(eth.type, 0x8847)
32
33 rx_mpls = rx[MPLS]
34
35 for ii in range(len(mpls_labels)):
36 tst.assertEqual(rx_mpls.label, mpls_labels[ii])
37 tst.assertEqual(rx_mpls.cos, 0)
38 if ii == num:
39 tst.assertEqual(rx_mpls.ttl, ttl)
40 else:
41 tst.assertEqual(rx_mpls.ttl, 255)
42 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,
105 mpls_ttl=255,
106 ping=0,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800107 ip_itf=None,
108 dst_ip=None,
Neale Ranns4c7c8e52017-10-21 09:37:55 -0700109 chksum=None,
Neale 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)):
119 if ii == len(mpls_labels) - 1:
120 p = p / MPLS(label=mpls_labels[ii], ttl=mpls_ttl, s=1)
121 else:
122 p = p / MPLS(label=mpls_labels[ii], ttl=mpls_ttl, s=0)
Neale Rannscb630ff2016-12-14 13:31:29 +0100123 if not ping:
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800124 if not dst_ip:
125 p = (p / IP(src=src_if.local_ip4, dst=src_if.remote_ip4) /
126 UDP(sport=1234, dport=1234) /
127 Raw(payload))
128 else:
129 p = (p / IP(src=src_if.local_ip4, dst=dst_ip) /
130 UDP(sport=1234, dport=1234) /
131 Raw(payload))
Neale Rannscb630ff2016-12-14 13:31:29 +0100132 else:
133 p = (p / IP(src=ip_itf.remote_ip4,
134 dst=ip_itf.local_ip4) /
135 ICMP())
136
Neale Ranns4c7c8e52017-10-21 09:37:55 -0700137 if chksum:
138 p[IP].chksum = chksum
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000139 info.data = p.copy()
140 pkts.append(p)
141 return pkts
142
Neale Rannsad422ed2016-11-02 14:20:04 +0000143 def create_stream_ip4(self, src_if, dst_ip):
Klement Sekeradab231a2016-12-21 08:50:14 +0100144 self.reset_packet_infos()
Neale Rannsad422ed2016-11-02 14:20:04 +0000145 pkts = []
146 for i in range(0, 257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100147 info = self.create_packet_info(src_if, src_if)
Neale Rannsad422ed2016-11-02 14:20:04 +0000148 payload = self.info_to_payload(info)
149 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
150 IP(src=src_if.remote_ip4, dst=dst_ip) /
151 UDP(sport=1234, dport=1234) /
152 Raw(payload))
153 info.data = p.copy()
154 pkts.append(p)
155 return pkts
156
Neale Ranns31426c62017-05-24 10:32:58 -0700157 def create_stream_labelled_ip6(self, src_if, mpls_label, mpls_ttl,
Neale Ranns4c7c8e52017-10-21 09:37:55 -0700158 dst_ip=None, hlim=64):
Neale Ranns31426c62017-05-24 10:32:58 -0700159 if dst_ip is None:
160 dst_ip = src_if.remote_ip6
Klement Sekeradab231a2016-12-21 08:50:14 +0100161 self.reset_packet_infos()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000162 pkts = []
163 for i in range(0, 257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100164 info = self.create_packet_info(src_if, src_if)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000165 payload = self.info_to_payload(info)
166 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
167 MPLS(label=mpls_label, ttl=mpls_ttl) /
Neale Ranns4c7c8e52017-10-21 09:37:55 -0700168 IPv6(src=src_if.remote_ip6, dst=dst_ip, hlim=hlim) /
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000169 UDP(sport=1234, dport=1234) /
170 Raw(payload))
171 info.data = p.copy()
172 pkts.append(p)
173 return pkts
174
Neale Rannscb630ff2016-12-14 13:31:29 +0100175 def verify_capture_ip4(self, src_if, capture, sent, ping_resp=0):
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000176 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700177 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000178
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000179 self.assertEqual(len(capture), len(sent))
180
181 for i in range(len(capture)):
182 tx = sent[i]
183 rx = capture[i]
184
185 # the rx'd packet has the MPLS label popped
Neale Rannsad422ed2016-11-02 14:20:04 +0000186 eth = rx[Ether]
187 self.assertEqual(eth.type, 0x800)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000188
189 tx_ip = tx[IP]
190 rx_ip = rx[IP]
191
Neale Rannscb630ff2016-12-14 13:31:29 +0100192 if not ping_resp:
193 self.assertEqual(rx_ip.src, tx_ip.src)
194 self.assertEqual(rx_ip.dst, tx_ip.dst)
195 # IP processing post pop has decremented the TTL
196 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
197 else:
198 self.assertEqual(rx_ip.src, tx_ip.dst)
199 self.assertEqual(rx_ip.dst, tx_ip.src)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000200
201 except:
Neale Rannsad422ed2016-11-02 14:20:04 +0000202 raise
203
Neale Rannsad422ed2016-11-02 14:20:04 +0000204 def verify_capture_labelled_ip4(self, src_if, capture, sent,
205 mpls_labels):
206 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700207 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000208
209 self.assertEqual(len(capture), len(sent))
210
211 for i in range(len(capture)):
212 tx = sent[i]
213 rx = capture[i]
214 tx_ip = tx[IP]
215 rx_ip = rx[IP]
216
217 # the MPLS TTL is copied from the IP
Neale Rannsda78f952017-05-24 09:15:43 -0700218 verify_mpls_stack(self, rx, mpls_labels, rx_ip.ttl,
219 len(mpls_labels) - 1)
Neale Rannsad422ed2016-11-02 14:20:04 +0000220
221 self.assertEqual(rx_ip.src, tx_ip.src)
222 self.assertEqual(rx_ip.dst, tx_ip.dst)
223 # IP processing post pop has decremented the TTL
224 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
225
226 except:
227 raise
228
Neale Ranns8c4611b2017-05-23 03:43:47 -0700229 def verify_capture_tunneled_ip4(self, src_if, capture, sent, mpls_labels,
230 ttl=255, top=None):
231 if top is None:
232 top = len(mpls_labels) - 1
Neale Rannsad422ed2016-11-02 14:20:04 +0000233 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700234 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000235
236 self.assertEqual(len(capture), len(sent))
237
238 for i in range(len(capture)):
239 tx = sent[i]
240 rx = capture[i]
241 tx_ip = tx[IP]
242 rx_ip = rx[IP]
243
244 # the MPLS TTL is 255 since it enters a new tunnel
Neale Rannsda78f952017-05-24 09:15:43 -0700245 verify_mpls_stack(self, rx, mpls_labels, ttl, top)
Neale Rannsad422ed2016-11-02 14:20:04 +0000246
247 self.assertEqual(rx_ip.src, tx_ip.src)
248 self.assertEqual(rx_ip.dst, tx_ip.dst)
249 # IP processing post pop has decremented the TTL
250 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
251
252 except:
253 raise
254
255 def verify_capture_labelled(self, src_if, capture, sent,
256 mpls_labels, ttl=254, num=0):
257 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700258 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000259
260 self.assertEqual(len(capture), len(sent))
261
262 for i in range(len(capture)):
263 rx = capture[i]
Neale Rannsda78f952017-05-24 09:15:43 -0700264 verify_mpls_stack(self, rx, mpls_labels, ttl, num)
Neale Rannsad422ed2016-11-02 14:20:04 +0000265 except:
266 raise
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000267
268 def verify_capture_ip6(self, src_if, capture, sent):
269 try:
270 self.assertEqual(len(capture), len(sent))
271
272 for i in range(len(capture)):
273 tx = sent[i]
274 rx = capture[i]
275
276 # the rx'd packet has the MPLS label popped
Neale Rannsad422ed2016-11-02 14:20:04 +0000277 eth = rx[Ether]
278 self.assertEqual(eth.type, 0x86DD)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000279
280 tx_ip = tx[IPv6]
281 rx_ip = rx[IPv6]
282
283 self.assertEqual(rx_ip.src, tx_ip.src)
284 self.assertEqual(rx_ip.dst, tx_ip.dst)
285 # IP processing post pop has decremented the TTL
286 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
287
288 except:
Neale Rannsad422ed2016-11-02 14:20:04 +0000289 raise
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000290
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800291 def send_and_assert_no_replies(self, intf, pkts, remark):
292 intf.add_stream(pkts)
293 self.pg_enable_capture(self.pg_interfaces)
294 self.pg_start()
295 for i in self.pg_interfaces:
296 i.assert_nothing_captured(remark=remark)
297
Neale Rannsad422ed2016-11-02 14:20:04 +0000298 def test_swap(self):
299 """ MPLS label swap tests """
300
301 #
302 # A simple MPLS xconnect - eos label in label out
303 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800304 route_32_eos = VppMplsRoute(self, 32, 1,
305 [VppRoutePath(self.pg0.remote_ip4,
306 self.pg0.sw_if_index,
307 labels=[33])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000308 route_32_eos.add_vpp_config()
309
310 #
311 # a stream that matches the route for 10.0.0.1
312 # PG0 is in the default table
313 #
314 self.vapi.cli("clear trace")
315 tx = self.create_stream_labelled_ip4(self.pg0, [32])
316 self.pg0.add_stream(tx)
317
318 self.pg_enable_capture(self.pg_interfaces)
319 self.pg_start()
320
321 rx = self.pg0.get_capture()
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800322 self.verify_capture_labelled(self.pg0, rx, tx, [33])
Neale Rannsad422ed2016-11-02 14:20:04 +0000323
324 #
325 # A simple MPLS xconnect - non-eos label in label out
326 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800327 route_32_neos = VppMplsRoute(self, 32, 0,
328 [VppRoutePath(self.pg0.remote_ip4,
329 self.pg0.sw_if_index,
330 labels=[33])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000331 route_32_neos.add_vpp_config()
332
333 #
334 # a stream that matches the route for 10.0.0.1
335 # PG0 is in the default table
336 #
337 self.vapi.cli("clear trace")
338 tx = self.create_stream_labelled_ip4(self.pg0, [32, 99])
339 self.pg0.add_stream(tx)
340
341 self.pg_enable_capture(self.pg_interfaces)
342 self.pg_start()
343
344 rx = self.pg0.get_capture()
345 self.verify_capture_labelled(self.pg0, rx, tx, [33, 99])
346
347 #
348 # An MPLS xconnect - EOS label in IP out
349 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800350 route_33_eos = VppMplsRoute(self, 33, 1,
351 [VppRoutePath(self.pg0.remote_ip4,
352 self.pg0.sw_if_index,
353 labels=[])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000354 route_33_eos.add_vpp_config()
355
356 self.vapi.cli("clear trace")
357 tx = self.create_stream_labelled_ip4(self.pg0, [33])
358 self.pg0.add_stream(tx)
359
360 self.pg_enable_capture(self.pg_interfaces)
361 self.pg_start()
362
363 rx = self.pg0.get_capture()
364 self.verify_capture_ip4(self.pg0, rx, tx)
365
366 #
367 # An MPLS xconnect - non-EOS label in IP out - an invalid configuration
368 # so this traffic should be dropped.
369 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800370 route_33_neos = VppMplsRoute(self, 33, 0,
371 [VppRoutePath(self.pg0.remote_ip4,
372 self.pg0.sw_if_index,
373 labels=[])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000374 route_33_neos.add_vpp_config()
375
376 self.vapi.cli("clear trace")
377 tx = self.create_stream_labelled_ip4(self.pg0, [33, 99])
378 self.pg0.add_stream(tx)
379
380 self.pg_enable_capture(self.pg_interfaces)
381 self.pg_start()
Klement Sekera9225dee2016-12-12 08:36:58 +0100382 self.pg0.assert_nothing_captured(
383 remark="MPLS non-EOS packets popped and forwarded")
Neale Rannsad422ed2016-11-02 14:20:04 +0000384
385 #
386 # A recursive EOS x-connect, which resolves through another x-connect
387 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800388 route_34_eos = VppMplsRoute(self, 34, 1,
389 [VppRoutePath("0.0.0.0",
390 0xffffffff,
391 nh_via_label=32,
392 labels=[44, 45])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000393 route_34_eos.add_vpp_config()
394
Neale Rannsad422ed2016-11-02 14:20:04 +0000395 tx = self.create_stream_labelled_ip4(self.pg0, [34])
396 self.pg0.add_stream(tx)
397
398 self.pg_enable_capture(self.pg_interfaces)
399 self.pg_start()
400
401 rx = self.pg0.get_capture()
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800402 self.verify_capture_labelled(self.pg0, rx, tx, [33, 44, 45], num=2)
Neale Rannsad422ed2016-11-02 14:20:04 +0000403
404 #
Matej Klottondeb69842016-12-09 15:05:46 +0100405 # A recursive non-EOS x-connect, which resolves through another
406 # x-connect
Neale Rannsad422ed2016-11-02 14:20:04 +0000407 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800408 route_34_neos = VppMplsRoute(self, 34, 0,
409 [VppRoutePath("0.0.0.0",
410 0xffffffff,
411 nh_via_label=32,
412 labels=[44, 46])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000413 route_34_neos.add_vpp_config()
414
415 self.vapi.cli("clear trace")
416 tx = self.create_stream_labelled_ip4(self.pg0, [34, 99])
417 self.pg0.add_stream(tx)
418
419 self.pg_enable_capture(self.pg_interfaces)
420 self.pg_start()
421
422 rx = self.pg0.get_capture()
Matej Klottondeb69842016-12-09 15:05:46 +0100423 # it's the 2nd (counting from 0) label in the stack that is swapped
Neale Rannsad422ed2016-11-02 14:20:04 +0000424 self.verify_capture_labelled(self.pg0, rx, tx, [33, 44, 46, 99], num=2)
425
426 #
Matej Klottondeb69842016-12-09 15:05:46 +0100427 # an recursive IP route that resolves through the recursive non-eos
428 # x-connect
Neale Rannsad422ed2016-11-02 14:20:04 +0000429 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800430 ip_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
431 [VppRoutePath("0.0.0.0",
432 0xffffffff,
433 nh_via_label=34,
434 labels=[55])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000435 ip_10_0_0_1.add_vpp_config()
436
437 self.vapi.cli("clear trace")
438 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
439 self.pg0.add_stream(tx)
440
441 self.pg_enable_capture(self.pg_interfaces)
442 self.pg_start()
443
444 rx = self.pg0.get_capture()
445 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [33, 44, 46, 55])
446
447 ip_10_0_0_1.remove_vpp_config()
448 route_34_neos.remove_vpp_config()
449 route_34_eos.remove_vpp_config()
450 route_33_neos.remove_vpp_config()
451 route_33_eos.remove_vpp_config()
452 route_32_neos.remove_vpp_config()
453 route_32_eos.remove_vpp_config()
454
455 def test_bind(self):
456 """ MPLS Local Label Binding test """
457
458 #
459 # Add a non-recursive route with a single out label
460 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800461 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
462 [VppRoutePath(self.pg0.remote_ip4,
463 self.pg0.sw_if_index,
464 labels=[45])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000465 route_10_0_0_1.add_vpp_config()
466
467 # bind a local label to the route
Neale Ranns5a8123b2017-01-26 01:18:23 -0800468 binding = VppMplsIpBind(self, 44, "10.0.0.1", 32)
Neale Rannsad422ed2016-11-02 14:20:04 +0000469 binding.add_vpp_config()
470
471 # non-EOS stream
472 self.vapi.cli("clear trace")
473 tx = self.create_stream_labelled_ip4(self.pg0, [44, 99])
474 self.pg0.add_stream(tx)
475
476 self.pg_enable_capture(self.pg_interfaces)
477 self.pg_start()
478
479 rx = self.pg0.get_capture()
480 self.verify_capture_labelled(self.pg0, rx, tx, [45, 99])
481
482 # EOS stream
483 self.vapi.cli("clear trace")
484 tx = self.create_stream_labelled_ip4(self.pg0, [44])
485 self.pg0.add_stream(tx)
486
487 self.pg_enable_capture(self.pg_interfaces)
488 self.pg_start()
489
490 rx = self.pg0.get_capture()
491 self.verify_capture_labelled(self.pg0, rx, tx, [45])
492
493 # IP stream
494 self.vapi.cli("clear trace")
495 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
496 self.pg0.add_stream(tx)
497
498 self.pg_enable_capture(self.pg_interfaces)
499 self.pg_start()
500
501 rx = self.pg0.get_capture()
502 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [45])
503
504 #
505 # cleanup
506 #
507 binding.remove_vpp_config()
508 route_10_0_0_1.remove_vpp_config()
509
510 def test_imposition(self):
511 """ MPLS label imposition test """
512
513 #
514 # Add a non-recursive route with a single out label
515 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800516 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
517 [VppRoutePath(self.pg0.remote_ip4,
518 self.pg0.sw_if_index,
519 labels=[32])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000520 route_10_0_0_1.add_vpp_config()
521
522 #
523 # a stream that matches the route for 10.0.0.1
524 # PG0 is in the default table
525 #
526 self.vapi.cli("clear trace")
527 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
528 self.pg0.add_stream(tx)
529
530 self.pg_enable_capture(self.pg_interfaces)
531 self.pg_start()
532
533 rx = self.pg0.get_capture()
534 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [32])
535
536 #
537 # Add a non-recursive route with a 3 out labels
538 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800539 route_10_0_0_2 = VppIpRoute(self, "10.0.0.2", 32,
540 [VppRoutePath(self.pg0.remote_ip4,
541 self.pg0.sw_if_index,
542 labels=[32, 33, 34])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000543 route_10_0_0_2.add_vpp_config()
544
545 #
546 # a stream that matches the route for 10.0.0.1
547 # PG0 is in the default table
548 #
549 self.vapi.cli("clear trace")
550 tx = self.create_stream_ip4(self.pg0, "10.0.0.2")
551 self.pg0.add_stream(tx)
552
553 self.pg_enable_capture(self.pg_interfaces)
554 self.pg_start()
555
556 rx = self.pg0.get_capture()
557 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [32, 33, 34])
558
559 #
Matej Klottondeb69842016-12-09 15:05:46 +0100560 # add a recursive path, with output label, via the 1 label route
Neale Rannsad422ed2016-11-02 14:20:04 +0000561 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800562 route_11_0_0_1 = VppIpRoute(self, "11.0.0.1", 32,
563 [VppRoutePath("10.0.0.1",
564 0xffffffff,
565 labels=[44])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000566 route_11_0_0_1.add_vpp_config()
567
568 #
569 # a stream that matches the route for 11.0.0.1, should pick up
570 # the label stack for 11.0.0.1 and 10.0.0.1
571 #
572 self.vapi.cli("clear trace")
573 tx = self.create_stream_ip4(self.pg0, "11.0.0.1")
574 self.pg0.add_stream(tx)
575
576 self.pg_enable_capture(self.pg_interfaces)
577 self.pg_start()
578
579 rx = self.pg0.get_capture()
580 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [32, 44])
581
582 #
583 # add a recursive path, with 2 labels, via the 3 label route
584 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800585 route_11_0_0_2 = VppIpRoute(self, "11.0.0.2", 32,
586 [VppRoutePath("10.0.0.2",
587 0xffffffff,
588 labels=[44, 45])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000589 route_11_0_0_2.add_vpp_config()
590
591 #
592 # a stream that matches the route for 11.0.0.1, should pick up
593 # the label stack for 11.0.0.1 and 10.0.0.1
594 #
595 self.vapi.cli("clear trace")
596 tx = self.create_stream_ip4(self.pg0, "11.0.0.2")
597 self.pg0.add_stream(tx)
598
599 self.pg_enable_capture(self.pg_interfaces)
600 self.pg_start()
601
602 rx = self.pg0.get_capture()
603 self.verify_capture_labelled_ip4(
604 self.pg0, rx, tx, [32, 33, 34, 44, 45])
605
606 #
607 # cleanup
608 #
609 route_11_0_0_2.remove_vpp_config()
610 route_11_0_0_1.remove_vpp_config()
611 route_10_0_0_2.remove_vpp_config()
612 route_10_0_0_1.remove_vpp_config()
613
614 def test_tunnel(self):
615 """ MPLS Tunnel Tests """
616
617 #
618 # Create a tunnel with a single out label
619 #
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800620 mpls_tun = VppMPLSTunnelInterface(self,
621 [VppRoutePath(self.pg0.remote_ip4,
622 self.pg0.sw_if_index,
623 labels=[44, 46])])
624 mpls_tun.add_vpp_config()
625 mpls_tun.admin_up()
Neale Rannsad422ed2016-11-02 14:20:04 +0000626
627 #
628 # add an unlabelled route through the new tunnel
629 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800630 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
631 [VppRoutePath("0.0.0.0",
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800632 mpls_tun._sw_if_index)])
Neale Ranns5a8123b2017-01-26 01:18:23 -0800633 route_10_0_0_3.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000634
635 self.vapi.cli("clear trace")
636 tx = self.create_stream_ip4(self.pg0, "10.0.0.3")
637 self.pg0.add_stream(tx)
638
639 self.pg_enable_capture(self.pg_interfaces)
640 self.pg_start()
641
642 rx = self.pg0.get_capture()
643 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [44, 46])
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000644
Neale Ranns8c4611b2017-05-23 03:43:47 -0700645 #
646 # add a labelled route through the new tunnel
647 #
648 route_10_0_0_4 = VppIpRoute(self, "10.0.0.4", 32,
649 [VppRoutePath("0.0.0.0",
650 mpls_tun._sw_if_index,
651 labels=[33])])
652 route_10_0_0_4.add_vpp_config()
653
654 self.vapi.cli("clear trace")
655 tx = self.create_stream_ip4(self.pg0, "10.0.0.4")
656 self.pg0.add_stream(tx)
657
658 self.pg_enable_capture(self.pg_interfaces)
659 self.pg_start()
660
661 rx = self.pg0.get_capture()
662 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [44, 46, 33],
663 ttl=63, top=2)
664
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000665 def test_v4_exp_null(self):
666 """ MPLS V4 Explicit NULL test """
667
668 #
669 # The first test case has an MPLS TTL of 0
670 # all packet should be dropped
671 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000672 tx = self.create_stream_labelled_ip4(self.pg0, [0], 0)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000673 self.pg0.add_stream(tx)
674
675 self.pg_enable_capture(self.pg_interfaces)
676 self.pg_start()
677
Klement Sekera9225dee2016-12-12 08:36:58 +0100678 self.pg0.assert_nothing_captured(remark="MPLS TTL=0 packets forwarded")
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000679
680 #
681 # a stream with a non-zero MPLS TTL
682 # PG0 is in the default table
683 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000684 tx = self.create_stream_labelled_ip4(self.pg0, [0])
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000685 self.pg0.add_stream(tx)
686
687 self.pg_enable_capture(self.pg_interfaces)
688 self.pg_start()
689
690 rx = self.pg0.get_capture()
691 self.verify_capture_ip4(self.pg0, rx, tx)
692
693 #
694 # a stream with a non-zero MPLS TTL
695 # PG1 is in table 1
696 # we are ensuring the post-pop lookup occurs in the VRF table
697 #
698 self.vapi.cli("clear trace")
Neale Rannsad422ed2016-11-02 14:20:04 +0000699 tx = self.create_stream_labelled_ip4(self.pg1, [0])
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000700 self.pg1.add_stream(tx)
701
702 self.pg_enable_capture(self.pg_interfaces)
703 self.pg_start()
704
705 rx = self.pg1.get_capture()
706 self.verify_capture_ip4(self.pg0, rx, tx)
707
708 def test_v6_exp_null(self):
709 """ MPLS V6 Explicit NULL test """
710
711 #
712 # a stream with a non-zero MPLS TTL
713 # PG0 is in the default table
714 #
715 self.vapi.cli("clear trace")
Neale Rannsad422ed2016-11-02 14:20:04 +0000716 tx = self.create_stream_labelled_ip6(self.pg0, 2, 2)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000717 self.pg0.add_stream(tx)
718
719 self.pg_enable_capture(self.pg_interfaces)
720 self.pg_start()
721
722 rx = self.pg0.get_capture()
723 self.verify_capture_ip6(self.pg0, rx, tx)
724
725 #
726 # a stream with a non-zero MPLS TTL
727 # PG1 is in table 1
728 # we are ensuring the post-pop lookup occurs in the VRF table
729 #
730 self.vapi.cli("clear trace")
Neale Rannsad422ed2016-11-02 14:20:04 +0000731 tx = self.create_stream_labelled_ip6(self.pg1, 2, 2)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000732 self.pg1.add_stream(tx)
733
734 self.pg_enable_capture(self.pg_interfaces)
735 self.pg_start()
736
737 rx = self.pg1.get_capture()
738 self.verify_capture_ip6(self.pg0, rx, tx)
739
Neale Rannscb630ff2016-12-14 13:31:29 +0100740 def test_deag(self):
741 """ MPLS Deagg """
742
743 #
744 # A de-agg route - next-hop lookup in default table
745 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800746 route_34_eos = VppMplsRoute(self, 34, 1,
747 [VppRoutePath("0.0.0.0",
748 0xffffffff,
749 nh_table_id=0)])
Neale Rannscb630ff2016-12-14 13:31:29 +0100750 route_34_eos.add_vpp_config()
751
752 #
753 # ping an interface in the default table
754 # PG0 is in the default table
755 #
756 self.vapi.cli("clear trace")
757 tx = self.create_stream_labelled_ip4(self.pg0, [34], ping=1,
758 ip_itf=self.pg0)
759 self.pg0.add_stream(tx)
760
761 self.pg_enable_capture(self.pg_interfaces)
762 self.pg_start()
763
764 rx = self.pg0.get_capture()
765 self.verify_capture_ip4(self.pg0, rx, tx, ping_resp=1)
766
767 #
768 # A de-agg route - next-hop lookup in non-default table
769 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800770 route_35_eos = VppMplsRoute(self, 35, 1,
771 [VppRoutePath("0.0.0.0",
772 0xffffffff,
773 nh_table_id=1)])
Neale Rannscb630ff2016-12-14 13:31:29 +0100774 route_35_eos.add_vpp_config()
775
776 #
777 # ping an interface in the non-default table
778 # PG0 is in the default table. packet arrive labelled in the
779 # default table and egress unlabelled in the non-default
780 #
781 self.vapi.cli("clear trace")
Klement Sekeradab231a2016-12-21 08:50:14 +0100782 tx = self.create_stream_labelled_ip4(
783 self.pg0, [35], ping=1, ip_itf=self.pg1)
Neale Rannscb630ff2016-12-14 13:31:29 +0100784 self.pg0.add_stream(tx)
785
786 self.pg_enable_capture(self.pg_interfaces)
787 self.pg_start()
788
Klement Sekeradab231a2016-12-21 08:50:14 +0100789 packet_count = self.get_packet_count_for_if_idx(self.pg0.sw_if_index)
790 rx = self.pg1.get_capture(packet_count)
Neale Rannscb630ff2016-12-14 13:31:29 +0100791 self.verify_capture_ip4(self.pg1, rx, tx, ping_resp=1)
792
Neale Ranns6af1c042017-05-26 03:48:53 -0700793 #
794 # Double pop
795 #
796 route_36_neos = VppMplsRoute(self, 36, 0,
797 [VppRoutePath("0.0.0.0",
798 0xffffffff)])
799 route_36_neos.add_vpp_config()
800
801 self.vapi.cli("clear trace")
802 tx = self.create_stream_labelled_ip4(self.pg0, [36, 35],
803 ping=1, ip_itf=self.pg1)
804 self.pg0.add_stream(tx)
805
806 self.pg_enable_capture(self.pg_interfaces)
807 self.pg_start()
808
809 rx = self.pg1.get_capture(len(tx))
810 self.verify_capture_ip4(self.pg1, rx, tx, ping_resp=1)
811
812 route_36_neos.remove_vpp_config()
Neale Rannscb630ff2016-12-14 13:31:29 +0100813 route_35_eos.remove_vpp_config()
814 route_34_eos.remove_vpp_config()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000815
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800816 def test_interface_rx(self):
817 """ MPLS Interface Receive """
818
819 #
820 # Add a non-recursive route that will forward the traffic
821 # post-interface-rx
822 #
823 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
824 table_id=1,
825 paths=[VppRoutePath(self.pg1.remote_ip4,
826 self.pg1.sw_if_index)])
827 route_10_0_0_1.add_vpp_config()
828
829 #
830 # An interface receive label that maps traffic to RX on interface
831 # pg1
832 # by injecting the packet in on pg0, which is in table 0
833 # doing an interface-rx on pg1 and matching a route in table 1
834 # if the packet egresses, then we must have swapped to pg1
835 # so as to have matched the route in table 1
836 #
837 route_34_eos = VppMplsRoute(self, 34, 1,
838 [VppRoutePath("0.0.0.0",
839 self.pg1.sw_if_index,
840 is_interface_rx=1)])
841 route_34_eos.add_vpp_config()
842
843 #
844 # ping an interface in the default table
845 # PG0 is in the default table
846 #
847 self.vapi.cli("clear trace")
848 tx = self.create_stream_labelled_ip4(self.pg0, [34], n=257,
849 dst_ip="10.0.0.1")
850 self.pg0.add_stream(tx)
851
852 self.pg_enable_capture(self.pg_interfaces)
853 self.pg_start()
854
855 rx = self.pg1.get_capture(257)
856 self.verify_capture_ip4(self.pg1, rx, tx)
857
858 def test_mcast_mid_point(self):
859 """ MPLS Multicast Mid Point """
860
861 #
862 # Add a non-recursive route that will forward the traffic
863 # post-interface-rx
864 #
865 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
866 table_id=1,
867 paths=[VppRoutePath(self.pg1.remote_ip4,
868 self.pg1.sw_if_index)])
869 route_10_0_0_1.add_vpp_config()
870
871 #
872 # Add a mcast entry that replicate to pg2 and pg3
873 # and replicate to a interface-rx (like a bud node would)
874 #
875 route_3400_eos = VppMplsRoute(self, 3400, 1,
876 [VppRoutePath(self.pg2.remote_ip4,
877 self.pg2.sw_if_index,
878 labels=[3401]),
879 VppRoutePath(self.pg3.remote_ip4,
880 self.pg3.sw_if_index,
881 labels=[3402]),
882 VppRoutePath("0.0.0.0",
883 self.pg1.sw_if_index,
884 is_interface_rx=1)],
885 is_multicast=1)
886 route_3400_eos.add_vpp_config()
887
888 #
889 # ping an interface in the default table
890 # PG0 is in the default table
891 #
892 self.vapi.cli("clear trace")
893 tx = self.create_stream_labelled_ip4(self.pg0, [3400], n=257,
894 dst_ip="10.0.0.1")
895 self.pg0.add_stream(tx)
896
897 self.pg_enable_capture(self.pg_interfaces)
898 self.pg_start()
899
900 rx = self.pg1.get_capture(257)
901 self.verify_capture_ip4(self.pg1, rx, tx)
902
903 rx = self.pg2.get_capture(257)
904 self.verify_capture_labelled(self.pg2, rx, tx, [3401])
905 rx = self.pg3.get_capture(257)
906 self.verify_capture_labelled(self.pg3, rx, tx, [3402])
907
908 def test_mcast_head(self):
909 """ MPLS Multicast Head-end """
910
911 #
912 # Create a multicast tunnel with two replications
913 #
914 mpls_tun = VppMPLSTunnelInterface(self,
915 [VppRoutePath(self.pg2.remote_ip4,
916 self.pg2.sw_if_index,
917 labels=[42]),
918 VppRoutePath(self.pg3.remote_ip4,
919 self.pg3.sw_if_index,
920 labels=[43])],
921 is_multicast=1)
922 mpls_tun.add_vpp_config()
923 mpls_tun.admin_up()
924
925 #
926 # add an unlabelled route through the new tunnel
927 #
928 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
929 [VppRoutePath("0.0.0.0",
930 mpls_tun._sw_if_index)])
931 route_10_0_0_3.add_vpp_config()
932
933 self.vapi.cli("clear trace")
934 tx = self.create_stream_ip4(self.pg0, "10.0.0.3")
935 self.pg0.add_stream(tx)
936
937 self.pg_enable_capture(self.pg_interfaces)
938 self.pg_start()
939
940 rx = self.pg2.get_capture(257)
941 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [42])
942 rx = self.pg3.get_capture(257)
943 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [43])
944
945 #
946 # An an IP multicast route via the tunnel
947 # A (*,G).
948 # one accepting interface, pg0, 1 forwarding interface via the tunnel
949 #
950 route_232_1_1_1 = VppIpMRoute(
951 self,
952 "0.0.0.0",
953 "232.1.1.1", 32,
954 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
955 [VppMRoutePath(self.pg0.sw_if_index,
956 MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
957 VppMRoutePath(mpls_tun._sw_if_index,
958 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
959 route_232_1_1_1.add_vpp_config()
960
961 self.vapi.cli("clear trace")
962 tx = self.create_stream_ip4(self.pg0, "232.1.1.1")
963 self.pg0.add_stream(tx)
964
965 self.pg_enable_capture(self.pg_interfaces)
966 self.pg_start()
967
968 rx = self.pg2.get_capture(257)
969 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [42])
970 rx = self.pg3.get_capture(257)
971 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [43])
972
Neale Ranns31426c62017-05-24 10:32:58 -0700973 def test_mcast_ip4_tail(self):
974 """ MPLS IPv4 Multicast Tail """
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800975
976 #
977 # Add a multicast route that will forward the traffic
978 # post-disposition
979 #
980 route_232_1_1_1 = VppIpMRoute(
981 self,
982 "0.0.0.0",
983 "232.1.1.1", 32,
984 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
985 table_id=1,
986 paths=[VppMRoutePath(self.pg1.sw_if_index,
987 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
988 route_232_1_1_1.add_vpp_config()
989
990 #
991 # An interface receive label that maps traffic to RX on interface
992 # pg1
993 # by injecting the packet in on pg0, which is in table 0
994 # doing an rpf-id and matching a route in table 1
995 # if the packet egresses, then we must have matched the route in
996 # table 1
997 #
998 route_34_eos = VppMplsRoute(self, 34, 1,
999 [VppRoutePath("0.0.0.0",
1000 self.pg1.sw_if_index,
1001 nh_table_id=1,
1002 rpf_id=55)],
1003 is_multicast=1)
1004
1005 route_34_eos.add_vpp_config()
1006
1007 #
1008 # Drop due to interface lookup miss
1009 #
1010 self.vapi.cli("clear trace")
1011 tx = self.create_stream_labelled_ip4(self.pg0, [34],
1012 dst_ip="232.1.1.1", n=1)
1013 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop none")
1014
1015 #
1016 # set the RPF-ID of the enrtry to match the input packet's
1017 #
1018 route_232_1_1_1.update_rpf_id(55)
1019
1020 self.vapi.cli("clear trace")
1021 tx = self.create_stream_labelled_ip4(self.pg0, [34],
1022 dst_ip="232.1.1.1", n=257)
1023 self.pg0.add_stream(tx)
1024
1025 self.pg_enable_capture(self.pg_interfaces)
1026 self.pg_start()
1027
1028 rx = self.pg1.get_capture(257)
1029 self.verify_capture_ip4(self.pg1, rx, tx)
1030
1031 #
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001032 # disposed packets have an invalid IPv4 checkusm
1033 #
1034 tx = self.create_stream_labelled_ip4(self.pg0, [34],
1035 dst_ip="232.1.1.1", n=65,
1036 chksum=1)
1037 self.send_and_assert_no_replies(self.pg0, tx, "Invalid Checksum")
1038
1039 #
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001040 # set the RPF-ID of the enrtry to not match the input packet's
1041 #
1042 route_232_1_1_1.update_rpf_id(56)
1043 tx = self.create_stream_labelled_ip4(self.pg0, [34],
1044 dst_ip="232.1.1.1")
1045 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop 56")
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001046 self.logger.error(self.vapi.cli("sh error"))
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001047
Neale Ranns31426c62017-05-24 10:32:58 -07001048 def test_mcast_ip6_tail(self):
1049 """ MPLS IPv6 Multicast Tail """
1050
1051 #
1052 # Add a multicast route that will forward the traffic
1053 # post-disposition
1054 #
1055 route_ff = VppIpMRoute(
1056 self,
1057 "::",
1058 "ff01::1", 32,
1059 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
1060 table_id=1,
1061 paths=[VppMRoutePath(self.pg1.sw_if_index,
1062 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)],
1063 is_ip6=1)
1064 route_ff.add_vpp_config()
1065
1066 #
1067 # An interface receive label that maps traffic to RX on interface
1068 # pg1
1069 # by injecting the packet in on pg0, which is in table 0
1070 # doing an rpf-id and matching a route in table 1
1071 # if the packet egresses, then we must have matched the route in
1072 # table 1
1073 #
1074 route_34_eos = VppMplsRoute(
1075 self, 34, 1,
1076 [VppRoutePath("::",
1077 self.pg1.sw_if_index,
1078 nh_table_id=1,
1079 rpf_id=55,
Neale Rannsda78f952017-05-24 09:15:43 -07001080 proto=DpoProto.DPO_PROTO_IP6)],
Neale Ranns31426c62017-05-24 10:32:58 -07001081 is_multicast=1)
1082
1083 route_34_eos.add_vpp_config()
1084
1085 #
1086 # Drop due to interface lookup miss
1087 #
1088 tx = self.create_stream_labelled_ip6(self.pg0, [34], 255,
1089 dst_ip="ff01::1")
1090
1091 #
1092 # set the RPF-ID of the enrtry to match the input packet's
1093 #
1094 route_ff.update_rpf_id(55)
1095
1096 tx = self.create_stream_labelled_ip6(self.pg0, [34], 255,
1097 dst_ip="ff01::1")
1098 self.pg0.add_stream(tx)
1099
1100 self.pg_enable_capture(self.pg_interfaces)
1101 self.pg_start()
1102
1103 rx = self.pg1.get_capture(257)
1104 self.verify_capture_ip6(self.pg1, rx, tx)
1105
1106 #
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001107 # disposed packets have hop-limit = 1
1108 #
1109 tx = self.create_stream_labelled_ip6(self.pg0, [34], 255,
1110 dst_ip="ff01::1", hlim=1)
1111 self.send_and_assert_no_replies(self.pg0, tx, "Hop Limt Expired")
1112
1113 #
Neale Ranns31426c62017-05-24 10:32:58 -07001114 # set the RPF-ID of the enrtry to not match the input packet's
1115 #
1116 route_ff.update_rpf_id(56)
1117 tx = self.create_stream_labelled_ip6(self.pg0, [34], 225,
1118 dst_ip="ff01::1")
1119 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop 56")
1120
Neale Ranns180279b2017-03-16 15:49:09 -04001121
1122class TestMPLSDisabled(VppTestCase):
1123 """ MPLS disabled """
1124
1125 def setUp(self):
1126 super(TestMPLSDisabled, self).setUp()
1127
1128 # create 2 pg interfaces
1129 self.create_pg_interfaces(range(2))
1130
Neale Ranns15002542017-09-10 04:39:11 -07001131 self.tbl = VppMplsTable(self, 0)
1132 self.tbl.add_vpp_config()
1133
Neale Ranns180279b2017-03-16 15:49:09 -04001134 # PG0 is MPLS enalbed
1135 self.pg0.admin_up()
1136 self.pg0.config_ip4()
1137 self.pg0.resolve_arp()
1138 self.pg0.enable_mpls()
1139
1140 # PG 1 is not MPLS enabled
1141 self.pg1.admin_up()
1142
1143 def tearDown(self):
Neale Ranns180279b2017-03-16 15:49:09 -04001144 for i in self.pg_interfaces:
1145 i.unconfig_ip4()
1146 i.admin_down()
1147
Neale Ranns15002542017-09-10 04:39:11 -07001148 self.pg0.disable_mpls()
1149 super(TestMPLSDisabled, self).tearDown()
1150
Neale Ranns180279b2017-03-16 15:49:09 -04001151 def send_and_assert_no_replies(self, intf, pkts, remark):
1152 intf.add_stream(pkts)
1153 self.pg_enable_capture(self.pg_interfaces)
1154 self.pg_start()
1155 for i in self.pg_interfaces:
1156 i.get_capture(0)
1157 i.assert_nothing_captured(remark=remark)
1158
1159 def test_mpls_disabled(self):
1160 """ MPLS Disabled """
1161
1162 tx = (Ether(src=self.pg1.remote_mac,
1163 dst=self.pg1.local_mac) /
1164 MPLS(label=32, ttl=64) /
1165 IPv6(src="2001::1", dst=self.pg0.remote_ip6) /
1166 UDP(sport=1234, dport=1234) /
1167 Raw('\xa5' * 100))
1168
1169 #
1170 # A simple MPLS xconnect - eos label in label out
1171 #
1172 route_32_eos = VppMplsRoute(self, 32, 1,
1173 [VppRoutePath(self.pg0.remote_ip4,
1174 self.pg0.sw_if_index,
1175 labels=[33])])
1176 route_32_eos.add_vpp_config()
1177
1178 #
1179 # PG1 does not forward IP traffic
1180 #
1181 self.send_and_assert_no_replies(self.pg1, tx, "MPLS disabled")
1182
1183 #
1184 # MPLS enable PG1
1185 #
1186 self.pg1.enable_mpls()
1187
1188 #
1189 # Now we get packets through
1190 #
1191 self.pg1.add_stream(tx)
1192 self.pg_enable_capture(self.pg_interfaces)
1193 self.pg_start()
1194
1195 rx = self.pg0.get_capture(1)
1196
1197 #
1198 # Disable PG1
1199 #
1200 self.pg1.disable_mpls()
1201
1202 #
1203 # PG1 does not forward IP traffic
1204 #
1205 self.send_and_assert_no_replies(self.pg1, tx, "IPv6 disabled")
1206 self.send_and_assert_no_replies(self.pg1, tx, "IPv6 disabled")
1207
1208
Neale Rannsf12a83f2017-04-18 09:09:40 -07001209class TestMPLSPIC(VppTestCase):
1210 """ MPLS PIC edge convergence """
1211
1212 def setUp(self):
1213 super(TestMPLSPIC, self).setUp()
1214
1215 # create 2 pg interfaces
1216 self.create_pg_interfaces(range(4))
1217
Neale Ranns15002542017-09-10 04:39:11 -07001218 mpls_tbl = VppMplsTable(self, 0)
1219 mpls_tbl.add_vpp_config()
1220 tbl4 = VppIpTable(self, 1)
1221 tbl4.add_vpp_config()
1222 tbl6 = VppIpTable(self, 1, is_ip6=1)
1223 tbl6.add_vpp_config()
1224
Neale Rannsf12a83f2017-04-18 09:09:40 -07001225 # core links
1226 self.pg0.admin_up()
1227 self.pg0.config_ip4()
1228 self.pg0.resolve_arp()
1229 self.pg0.enable_mpls()
1230 self.pg1.admin_up()
1231 self.pg1.config_ip4()
1232 self.pg1.resolve_arp()
1233 self.pg1.enable_mpls()
1234
1235 # VRF (customer facing) link
1236 self.pg2.admin_up()
1237 self.pg2.set_table_ip4(1)
1238 self.pg2.config_ip4()
1239 self.pg2.resolve_arp()
1240 self.pg2.set_table_ip6(1)
1241 self.pg2.config_ip6()
1242 self.pg2.resolve_ndp()
1243 self.pg3.admin_up()
1244 self.pg3.set_table_ip4(1)
1245 self.pg3.config_ip4()
1246 self.pg3.resolve_arp()
1247 self.pg3.set_table_ip6(1)
1248 self.pg3.config_ip6()
1249 self.pg3.resolve_ndp()
1250
1251 def tearDown(self):
Neale Rannsf12a83f2017-04-18 09:09:40 -07001252 self.pg0.disable_mpls()
Neale Ranns15002542017-09-10 04:39:11 -07001253 self.pg1.disable_mpls()
Neale Rannsf12a83f2017-04-18 09:09:40 -07001254 for i in self.pg_interfaces:
1255 i.unconfig_ip4()
1256 i.unconfig_ip6()
1257 i.set_table_ip4(0)
1258 i.set_table_ip6(0)
1259 i.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -07001260 super(TestMPLSPIC, self).tearDown()
Neale Rannsf12a83f2017-04-18 09:09:40 -07001261
1262 def test_mpls_ibgp_pic(self):
1263 """ MPLS iBGP PIC edge convergence
1264
1265 1) setup many iBGP VPN routes via a pair of iBGP peers.
1266 2) Check EMCP forwarding to these peers
1267 3) withdraw the IGP route to one of these peers.
1268 4) check forwarding continues to the remaining peer
1269 """
1270
1271 #
1272 # IGP+LDP core routes
1273 #
1274 core_10_0_0_45 = VppIpRoute(self, "10.0.0.45", 32,
1275 [VppRoutePath(self.pg0.remote_ip4,
1276 self.pg0.sw_if_index,
1277 labels=[45])])
1278 core_10_0_0_45.add_vpp_config()
1279
1280 core_10_0_0_46 = VppIpRoute(self, "10.0.0.46", 32,
1281 [VppRoutePath(self.pg1.remote_ip4,
1282 self.pg1.sw_if_index,
1283 labels=[46])])
1284 core_10_0_0_46.add_vpp_config()
1285
1286 #
1287 # Lot's of VPN routes. We need more the 64 so VPP will build
1288 # the fast convergence indirection
1289 #
1290 vpn_routes = []
1291 pkts = []
1292 for ii in range(64):
1293 dst = "192.168.1.%d" % ii
1294 vpn_routes.append(VppIpRoute(self, dst, 32,
1295 [VppRoutePath("10.0.0.45",
1296 0xffffffff,
1297 labels=[145],
1298 is_resolve_host=1),
1299 VppRoutePath("10.0.0.46",
1300 0xffffffff,
1301 labels=[146],
1302 is_resolve_host=1)],
1303 table_id=1))
1304 vpn_routes[ii].add_vpp_config()
1305
1306 pkts.append(Ether(dst=self.pg2.local_mac,
1307 src=self.pg2.remote_mac) /
1308 IP(src=self.pg2.remote_ip4, dst=dst) /
1309 UDP(sport=1234, dport=1234) /
1310 Raw('\xa5' * 100))
1311
1312 #
1313 # Send the packet stream (one pkt to each VPN route)
1314 # - expect a 50-50 split of the traffic
1315 #
1316 self.pg2.add_stream(pkts)
1317 self.pg_enable_capture(self.pg_interfaces)
1318 self.pg_start()
1319
1320 rx0 = self.pg0._get_capture(1)
1321 rx1 = self.pg1._get_capture(1)
1322
1323 # not testig the LB hashing algorithm so we're not concerned
1324 # with the split ratio, just as long as neither is 0
1325 self.assertNotEqual(0, len(rx0))
1326 self.assertNotEqual(0, len(rx1))
1327
1328 #
1329 # use a test CLI command to stop the FIB walk process, this
1330 # will prevent the FIB converging the VPN routes and thus allow
1331 # us to probe the interim (psot-fail, pre-converge) state
1332 #
1333 self.vapi.ppcli("test fib-walk-process disable")
1334
1335 #
1336 # Withdraw one of the IGP routes
1337 #
1338 core_10_0_0_46.remove_vpp_config()
1339
1340 #
1341 # now all packets should be forwarded through the remaining peer
1342 #
1343 self.vapi.ppcli("clear trace")
1344 self.pg2.add_stream(pkts)
1345 self.pg_enable_capture(self.pg_interfaces)
1346 self.pg_start()
1347
1348 rx0 = self.pg0.get_capture(len(pkts))
1349
1350 #
1351 # enable the FIB walk process to converge the FIB
1352 #
1353 self.vapi.ppcli("test fib-walk-process enable")
1354
1355 #
1356 # packets should still be forwarded through the remaining peer
1357 #
1358 self.pg2.add_stream(pkts)
1359 self.pg_enable_capture(self.pg_interfaces)
1360 self.pg_start()
1361
1362 rx0 = self.pg0.get_capture(64)
1363
1364 #
1365 # Add the IGP route back and we return to load-balancing
1366 #
1367 core_10_0_0_46.add_vpp_config()
1368
1369 self.pg2.add_stream(pkts)
1370 self.pg_enable_capture(self.pg_interfaces)
1371 self.pg_start()
1372
1373 rx0 = self.pg0._get_capture(1)
1374 rx1 = self.pg1._get_capture(1)
1375 self.assertNotEqual(0, len(rx0))
1376 self.assertNotEqual(0, len(rx1))
1377
1378 def test_mpls_ebgp_pic(self):
1379 """ MPLS eBGP PIC edge convergence
1380
1381 1) setup many eBGP VPN routes via a pair of eBGP peers
1382 2) Check EMCP forwarding to these peers
1383 3) withdraw one eBGP path - expect LB across remaining eBGP
1384 """
1385
1386 #
1387 # Lot's of VPN routes. We need more the 64 so VPP will build
1388 # the fast convergence indirection
1389 #
1390 vpn_routes = []
1391 vpn_bindings = []
1392 pkts = []
1393 for ii in range(64):
1394 dst = "192.168.1.%d" % ii
1395 local_label = 1600 + ii
1396 vpn_routes.append(VppIpRoute(self, dst, 32,
1397 [VppRoutePath(self.pg2.remote_ip4,
1398 0xffffffff,
1399 nh_table_id=1,
1400 is_resolve_attached=1),
1401 VppRoutePath(self.pg3.remote_ip4,
1402 0xffffffff,
1403 nh_table_id=1,
1404 is_resolve_attached=1)],
1405 table_id=1))
1406 vpn_routes[ii].add_vpp_config()
1407
1408 vpn_bindings.append(VppMplsIpBind(self, local_label, dst, 32,
1409 ip_table_id=1))
1410 vpn_bindings[ii].add_vpp_config()
1411
1412 pkts.append(Ether(dst=self.pg0.local_mac,
1413 src=self.pg0.remote_mac) /
1414 MPLS(label=local_label, ttl=64) /
1415 IP(src=self.pg0.remote_ip4, dst=dst) /
1416 UDP(sport=1234, dport=1234) /
1417 Raw('\xa5' * 100))
1418
1419 self.pg0.add_stream(pkts)
1420 self.pg_enable_capture(self.pg_interfaces)
1421 self.pg_start()
1422
1423 rx0 = self.pg2._get_capture(1)
1424 rx1 = self.pg3._get_capture(1)
1425 self.assertNotEqual(0, len(rx0))
1426 self.assertNotEqual(0, len(rx1))
1427
1428 #
1429 # use a test CLI command to stop the FIB walk process, this
1430 # will prevent the FIB converging the VPN routes and thus allow
1431 # us to probe the interim (psot-fail, pre-converge) state
1432 #
1433 self.vapi.ppcli("test fib-walk-process disable")
1434
1435 #
1436 # withdraw the connected prefix on the interface.
1437 #
1438 self.pg2.unconfig_ip4()
1439
1440 #
1441 # now all packets should be forwarded through the remaining peer
1442 #
1443 self.pg0.add_stream(pkts)
1444 self.pg_enable_capture(self.pg_interfaces)
1445 self.pg_start()
1446
1447 rx0 = self.pg3.get_capture(len(pkts))
1448
1449 #
1450 # enable the FIB walk process to converge the FIB
1451 #
1452 self.vapi.ppcli("test fib-walk-process enable")
1453 self.pg0.add_stream(pkts)
1454 self.pg_enable_capture(self.pg_interfaces)
1455 self.pg_start()
1456
1457 rx0 = self.pg3.get_capture(len(pkts))
1458
1459 #
1460 # put the connecteds back
1461 #
1462 self.pg2.config_ip4()
1463
1464 self.pg0.add_stream(pkts)
1465 self.pg_enable_capture(self.pg_interfaces)
1466 self.pg_start()
1467
1468 rx0 = self.pg2._get_capture(1)
1469 rx1 = self.pg3._get_capture(1)
1470 self.assertNotEqual(0, len(rx0))
1471 self.assertNotEqual(0, len(rx1))
1472
1473 def test_mpls_v6_ebgp_pic(self):
1474 """ MPLSv6 eBGP PIC edge convergence
1475
1476 1) setup many eBGP VPNv6 routes via a pair of eBGP peers
1477 2) Check EMCP forwarding to these peers
1478 3) withdraw one eBGP path - expect LB across remaining eBGP
1479 """
1480
1481 #
1482 # Lot's of VPN routes. We need more the 64 so VPP will build
1483 # the fast convergence indirection
1484 #
1485 vpn_routes = []
1486 vpn_bindings = []
1487 pkts = []
1488 for ii in range(64):
1489 dst = "3000::%d" % ii
1490 local_label = 1600 + ii
Neale Rannsda78f952017-05-24 09:15:43 -07001491 vpn_routes.append(VppIpRoute(
1492 self, dst, 128,
1493 [VppRoutePath(self.pg2.remote_ip6,
1494 0xffffffff,
1495 nh_table_id=1,
1496 is_resolve_attached=1,
1497 proto=DpoProto.DPO_PROTO_IP6),
1498 VppRoutePath(self.pg3.remote_ip6,
1499 0xffffffff,
1500 nh_table_id=1,
1501 proto=DpoProto.DPO_PROTO_IP6,
1502 is_resolve_attached=1)],
1503 table_id=1,
1504 is_ip6=1))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001505 vpn_routes[ii].add_vpp_config()
1506
1507 vpn_bindings.append(VppMplsIpBind(self, local_label, dst, 128,
1508 ip_table_id=1,
1509 is_ip6=1))
1510 vpn_bindings[ii].add_vpp_config()
1511
1512 pkts.append(Ether(dst=self.pg0.local_mac,
1513 src=self.pg0.remote_mac) /
1514 MPLS(label=local_label, ttl=64) /
1515 IPv6(src=self.pg0.remote_ip6, dst=dst) /
1516 UDP(sport=1234, dport=1234) /
1517 Raw('\xa5' * 100))
1518
1519 self.pg0.add_stream(pkts)
1520 self.pg_enable_capture(self.pg_interfaces)
1521 self.pg_start()
1522
1523 rx0 = self.pg2._get_capture(1)
1524 rx1 = self.pg3._get_capture(1)
1525 self.assertNotEqual(0, len(rx0))
1526 self.assertNotEqual(0, len(rx1))
1527
1528 #
1529 # use a test CLI command to stop the FIB walk process, this
1530 # will prevent the FIB converging the VPN routes and thus allow
1531 # us to probe the interim (psot-fail, pre-converge) state
1532 #
1533 self.vapi.ppcli("test fib-walk-process disable")
1534
1535 #
1536 # withdraw the connected prefix on the interface.
1537 # and shutdown the interface so the ND cache is flushed.
1538 #
1539 self.pg2.unconfig_ip6()
1540 self.pg2.admin_down()
1541
1542 #
1543 # now all packets should be forwarded through the remaining peer
1544 #
1545 self.pg0.add_stream(pkts)
1546 self.pg_enable_capture(self.pg_interfaces)
1547 self.pg_start()
1548
1549 rx0 = self.pg3.get_capture(len(pkts))
1550
1551 #
1552 # enable the FIB walk process to converge the FIB
1553 #
1554 self.vapi.ppcli("test fib-walk-process enable")
1555 self.pg0.add_stream(pkts)
1556 self.pg_enable_capture(self.pg_interfaces)
1557 self.pg_start()
1558
1559 rx0 = self.pg3.get_capture(len(pkts))
1560
1561 #
1562 # put the connecteds back
1563 #
1564 self.pg2.admin_up()
1565 self.pg2.config_ip6()
1566
1567 self.pg0.add_stream(pkts)
1568 self.pg_enable_capture(self.pg_interfaces)
1569 self.pg_start()
1570
1571 rx0 = self.pg2._get_capture(1)
1572 rx1 = self.pg3._get_capture(1)
1573 self.assertNotEqual(0, len(rx0))
1574 self.assertNotEqual(0, len(rx1))
1575
1576
Neale Rannsda78f952017-05-24 09:15:43 -07001577class TestMPLSL2(VppTestCase):
1578 """ MPLS-L2 """
1579
1580 def setUp(self):
1581 super(TestMPLSL2, self).setUp()
1582
1583 # create 2 pg interfaces
1584 self.create_pg_interfaces(range(2))
1585
Neale Ranns15002542017-09-10 04:39:11 -07001586 # create the default MPLS table
1587 self.tables = []
1588 tbl = VppMplsTable(self, 0)
1589 tbl.add_vpp_config()
1590 self.tables.append(tbl)
1591
Neale Rannsda78f952017-05-24 09:15:43 -07001592 # use pg0 as the core facing interface
1593 self.pg0.admin_up()
1594 self.pg0.config_ip4()
1595 self.pg0.resolve_arp()
1596 self.pg0.enable_mpls()
1597
Neale Ranns15002542017-09-10 04:39:11 -07001598 # use the other 2 for customer facing L2 links
Neale Rannsda78f952017-05-24 09:15:43 -07001599 for i in self.pg_interfaces[1:]:
1600 i.admin_up()
1601
1602 def tearDown(self):
Neale Rannsda78f952017-05-24 09:15:43 -07001603 for i in self.pg_interfaces[1:]:
1604 i.admin_down()
1605
1606 self.pg0.disable_mpls()
1607 self.pg0.unconfig_ip4()
1608 self.pg0.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -07001609 super(TestMPLSL2, self).tearDown()
Neale Rannsda78f952017-05-24 09:15:43 -07001610
1611 def verify_capture_tunneled_ethernet(self, capture, sent, mpls_labels,
1612 ttl=255, top=None):
1613 if top is None:
1614 top = len(mpls_labels) - 1
1615
1616 capture = verify_filter(capture, sent)
1617
1618 self.assertEqual(len(capture), len(sent))
1619
1620 for i in range(len(capture)):
1621 tx = sent[i]
1622 rx = capture[i]
1623
1624 # the MPLS TTL is 255 since it enters a new tunnel
1625 verify_mpls_stack(self, rx, mpls_labels, ttl, top)
1626
1627 tx_eth = tx[Ether]
1628 rx_eth = Ether(str(rx[MPLS].payload))
1629
1630 self.assertEqual(rx_eth.src, tx_eth.src)
1631 self.assertEqual(rx_eth.dst, tx_eth.dst)
1632
1633 def test_vpws(self):
1634 """ Virtual Private Wire Service """
1635
1636 #
1637 # Create an MPLS tunnel that pushes 1 label
1638 #
1639 mpls_tun_1 = VppMPLSTunnelInterface(self,
1640 [VppRoutePath(self.pg0.remote_ip4,
1641 self.pg0.sw_if_index,
1642 labels=[42])],
1643 is_l2=1)
1644 mpls_tun_1.add_vpp_config()
1645 mpls_tun_1.admin_up()
1646
1647 #
1648 # Create a label entry to for 55 that does L2 input to the tunnel
1649 #
1650 route_55_eos = VppMplsRoute(
1651 self, 55, 1,
1652 [VppRoutePath("0.0.0.0",
1653 mpls_tun_1.sw_if_index,
1654 is_interface_rx=1,
1655 proto=DpoProto.DPO_PROTO_ETHERNET)])
1656 route_55_eos.add_vpp_config()
1657
1658 #
1659 # Cross-connect the tunnel with one of the customers L2 interfaces
1660 #
1661 self.vapi.sw_interface_set_l2_xconnect(self.pg1.sw_if_index,
1662 mpls_tun_1.sw_if_index,
1663 enable=1)
1664 self.vapi.sw_interface_set_l2_xconnect(mpls_tun_1.sw_if_index,
1665 self.pg1.sw_if_index,
1666 enable=1)
1667
1668 #
1669 # inject a packet from the core
1670 #
1671 pcore = (Ether(dst=self.pg0.local_mac,
1672 src=self.pg0.remote_mac) /
1673 MPLS(label=55, ttl=64) /
1674 Ether(dst="00:00:de:ad:ba:be",
1675 src="00:00:de:ad:be:ef") /
1676 IP(src="10.10.10.10", dst="11.11.11.11") /
1677 UDP(sport=1234, dport=1234) /
1678 Raw('\xa5' * 100))
1679
1680 self.pg0.add_stream(pcore * 65)
1681 self.pg_enable_capture(self.pg_interfaces)
1682 self.pg_start()
1683
1684 rx0 = self.pg1.get_capture(65)
1685 tx = pcore[MPLS].payload
1686
1687 self.assertEqual(rx0[0][Ether].dst, tx[Ether].dst)
1688 self.assertEqual(rx0[0][Ether].src, tx[Ether].src)
1689
1690 #
1691 # Inject a packet from the custoer/L2 side
1692 #
1693 self.pg1.add_stream(tx * 65)
1694 self.pg_enable_capture(self.pg_interfaces)
1695 self.pg_start()
1696
1697 rx0 = self.pg0.get_capture(65)
1698
1699 self.verify_capture_tunneled_ethernet(rx0, tx*65, [42])
1700
1701 def test_vpls(self):
1702 """ Virtual Private LAN Service """
1703 #
1704 # Create an L2 MPLS tunnel
1705 #
1706 mpls_tun = VppMPLSTunnelInterface(self,
1707 [VppRoutePath(self.pg0.remote_ip4,
1708 self.pg0.sw_if_index,
1709 labels=[42])],
1710 is_l2=1)
1711 mpls_tun.add_vpp_config()
1712 mpls_tun.admin_up()
1713
1714 #
1715 # Create a label entry to for 55 that does L2 input to the tunnel
1716 #
1717 route_55_eos = VppMplsRoute(
1718 self, 55, 1,
1719 [VppRoutePath("0.0.0.0",
1720 mpls_tun.sw_if_index,
1721 is_interface_rx=1,
1722 proto=DpoProto.DPO_PROTO_ETHERNET)])
1723 route_55_eos.add_vpp_config()
1724
1725 #
1726 # add to tunnel to the customers bridge-domain
1727 #
1728 self.vapi.sw_interface_set_l2_bridge(mpls_tun.sw_if_index,
1729 bd_id=1)
1730 self.vapi.sw_interface_set_l2_bridge(self.pg1.sw_if_index,
1731 bd_id=1)
1732
1733 #
1734 # Packet from the customer interface and from the core
1735 #
1736 p_cust = (Ether(dst="00:00:de:ad:ba:be",
1737 src="00:00:de:ad:be:ef") /
1738 IP(src="10.10.10.10", dst="11.11.11.11") /
1739 UDP(sport=1234, dport=1234) /
1740 Raw('\xa5' * 100))
1741 p_core = (Ether(src="00:00:de:ad:ba:be",
1742 dst="00:00:de:ad:be:ef") /
1743 IP(dst="10.10.10.10", src="11.11.11.11") /
1744 UDP(sport=1234, dport=1234) /
1745 Raw('\xa5' * 100))
1746
1747 #
1748 # The BD is learning, so send in one of each packet to learn
1749 #
1750 p_core_encap = (Ether(dst=self.pg0.local_mac,
1751 src=self.pg0.remote_mac) /
1752 MPLS(label=55, ttl=64) /
1753 p_core)
1754
1755 self.pg1.add_stream(p_cust)
1756 self.pg_enable_capture(self.pg_interfaces)
1757 self.pg_start()
1758 self.pg0.add_stream(p_core_encap)
1759 self.pg_enable_capture(self.pg_interfaces)
1760 self.pg_start()
1761
1762 # we've learnt this so expect it be be forwarded
1763 rx0 = self.pg1.get_capture(1)
1764
1765 self.assertEqual(rx0[0][Ether].dst, p_core[Ether].dst)
1766 self.assertEqual(rx0[0][Ether].src, p_core[Ether].src)
1767
1768 #
1769 # now a stream in each direction
1770 #
1771 self.pg1.add_stream(p_cust * 65)
1772 self.pg_enable_capture(self.pg_interfaces)
1773 self.pg_start()
1774
1775 rx0 = self.pg0.get_capture(65)
1776
1777 self.verify_capture_tunneled_ethernet(rx0, p_cust*65, [42])
1778
1779 #
1780 # remove interfaces from customers bridge-domain
1781 #
1782 self.vapi.sw_interface_set_l2_bridge(mpls_tun.sw_if_index,
1783 bd_id=1,
1784 enable=0)
1785 self.vapi.sw_interface_set_l2_bridge(self.pg1.sw_if_index,
1786 bd_id=1,
1787 enable=0)
1788
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001789if __name__ == '__main__':
1790 unittest.main(testRunner=VppTestRunner)