blob: 460a32d1fc122db4d8a1ec13f8fe6917b9ba36d2 [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,
109 n=257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100110 self.reset_packet_infos()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000111 pkts = []
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800112 for i in range(0, n):
Klement Sekeradab231a2016-12-21 08:50:14 +0100113 info = self.create_packet_info(src_if, src_if)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000114 payload = self.info_to_payload(info)
Neale Rannsad422ed2016-11-02 14:20:04 +0000115 p = Ether(dst=src_if.local_mac, src=src_if.remote_mac)
116
117 for ii in range(len(mpls_labels)):
118 if ii == len(mpls_labels) - 1:
119 p = p / MPLS(label=mpls_labels[ii], ttl=mpls_ttl, s=1)
120 else:
121 p = p / MPLS(label=mpls_labels[ii], ttl=mpls_ttl, s=0)
Neale Rannscb630ff2016-12-14 13:31:29 +0100122 if not ping:
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800123 if not dst_ip:
124 p = (p / IP(src=src_if.local_ip4, dst=src_if.remote_ip4) /
125 UDP(sport=1234, dport=1234) /
126 Raw(payload))
127 else:
128 p = (p / IP(src=src_if.local_ip4, dst=dst_ip) /
129 UDP(sport=1234, dport=1234) /
130 Raw(payload))
Neale Rannscb630ff2016-12-14 13:31:29 +0100131 else:
132 p = (p / IP(src=ip_itf.remote_ip4,
133 dst=ip_itf.local_ip4) /
134 ICMP())
135
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000136 info.data = p.copy()
137 pkts.append(p)
138 return pkts
139
Neale Rannsad422ed2016-11-02 14:20:04 +0000140 def create_stream_ip4(self, src_if, dst_ip):
Klement Sekeradab231a2016-12-21 08:50:14 +0100141 self.reset_packet_infos()
Neale Rannsad422ed2016-11-02 14:20:04 +0000142 pkts = []
143 for i in range(0, 257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100144 info = self.create_packet_info(src_if, src_if)
Neale Rannsad422ed2016-11-02 14:20:04 +0000145 payload = self.info_to_payload(info)
146 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
147 IP(src=src_if.remote_ip4, dst=dst_ip) /
148 UDP(sport=1234, dport=1234) /
149 Raw(payload))
150 info.data = p.copy()
151 pkts.append(p)
152 return pkts
153
Neale Ranns31426c62017-05-24 10:32:58 -0700154 def create_stream_labelled_ip6(self, src_if, mpls_label, mpls_ttl,
155 dst_ip=None):
156 if dst_ip is None:
157 dst_ip = src_if.remote_ip6
Klement Sekeradab231a2016-12-21 08:50:14 +0100158 self.reset_packet_infos()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000159 pkts = []
160 for i in range(0, 257):
Klement Sekeradab231a2016-12-21 08:50:14 +0100161 info = self.create_packet_info(src_if, src_if)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000162 payload = self.info_to_payload(info)
163 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
164 MPLS(label=mpls_label, ttl=mpls_ttl) /
Neale Ranns31426c62017-05-24 10:32:58 -0700165 IPv6(src=src_if.remote_ip6, dst=dst_ip) /
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000166 UDP(sport=1234, dport=1234) /
167 Raw(payload))
168 info.data = p.copy()
169 pkts.append(p)
170 return pkts
171
Neale Rannscb630ff2016-12-14 13:31:29 +0100172 def verify_capture_ip4(self, src_if, capture, sent, ping_resp=0):
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000173 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700174 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000175
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000176 self.assertEqual(len(capture), len(sent))
177
178 for i in range(len(capture)):
179 tx = sent[i]
180 rx = capture[i]
181
182 # the rx'd packet has the MPLS label popped
Neale Rannsad422ed2016-11-02 14:20:04 +0000183 eth = rx[Ether]
184 self.assertEqual(eth.type, 0x800)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000185
186 tx_ip = tx[IP]
187 rx_ip = rx[IP]
188
Neale Rannscb630ff2016-12-14 13:31:29 +0100189 if not ping_resp:
190 self.assertEqual(rx_ip.src, tx_ip.src)
191 self.assertEqual(rx_ip.dst, tx_ip.dst)
192 # IP processing post pop has decremented the TTL
193 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
194 else:
195 self.assertEqual(rx_ip.src, tx_ip.dst)
196 self.assertEqual(rx_ip.dst, tx_ip.src)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000197
198 except:
Neale Rannsad422ed2016-11-02 14:20:04 +0000199 raise
200
Neale Rannsad422ed2016-11-02 14:20:04 +0000201 def verify_capture_labelled_ip4(self, src_if, capture, sent,
202 mpls_labels):
203 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700204 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000205
206 self.assertEqual(len(capture), len(sent))
207
208 for i in range(len(capture)):
209 tx = sent[i]
210 rx = capture[i]
211 tx_ip = tx[IP]
212 rx_ip = rx[IP]
213
214 # the MPLS TTL is copied from the IP
Neale Rannsda78f952017-05-24 09:15:43 -0700215 verify_mpls_stack(self, rx, mpls_labels, rx_ip.ttl,
216 len(mpls_labels) - 1)
Neale Rannsad422ed2016-11-02 14:20:04 +0000217
218 self.assertEqual(rx_ip.src, tx_ip.src)
219 self.assertEqual(rx_ip.dst, tx_ip.dst)
220 # IP processing post pop has decremented the TTL
221 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
222
223 except:
224 raise
225
Neale Ranns8c4611b2017-05-23 03:43:47 -0700226 def verify_capture_tunneled_ip4(self, src_if, capture, sent, mpls_labels,
227 ttl=255, top=None):
228 if top is None:
229 top = len(mpls_labels) - 1
Neale Rannsad422ed2016-11-02 14:20:04 +0000230 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700231 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000232
233 self.assertEqual(len(capture), len(sent))
234
235 for i in range(len(capture)):
236 tx = sent[i]
237 rx = capture[i]
238 tx_ip = tx[IP]
239 rx_ip = rx[IP]
240
241 # the MPLS TTL is 255 since it enters a new tunnel
Neale Rannsda78f952017-05-24 09:15:43 -0700242 verify_mpls_stack(self, rx, mpls_labels, ttl, top)
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)
246 # IP processing post pop has decremented the TTL
247 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
248
249 except:
250 raise
251
252 def verify_capture_labelled(self, src_if, capture, sent,
253 mpls_labels, ttl=254, num=0):
254 try:
Neale Rannsda78f952017-05-24 09:15:43 -0700255 capture = verify_filter(capture, sent)
Neale Rannsad422ed2016-11-02 14:20:04 +0000256
257 self.assertEqual(len(capture), len(sent))
258
259 for i in range(len(capture)):
260 rx = capture[i]
Neale Rannsda78f952017-05-24 09:15:43 -0700261 verify_mpls_stack(self, rx, mpls_labels, ttl, num)
Neale Rannsad422ed2016-11-02 14:20:04 +0000262 except:
263 raise
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000264
265 def verify_capture_ip6(self, src_if, capture, sent):
266 try:
267 self.assertEqual(len(capture), len(sent))
268
269 for i in range(len(capture)):
270 tx = sent[i]
271 rx = capture[i]
272
273 # the rx'd packet has the MPLS label popped
Neale Rannsad422ed2016-11-02 14:20:04 +0000274 eth = rx[Ether]
275 self.assertEqual(eth.type, 0x86DD)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000276
277 tx_ip = tx[IPv6]
278 rx_ip = rx[IPv6]
279
280 self.assertEqual(rx_ip.src, tx_ip.src)
281 self.assertEqual(rx_ip.dst, tx_ip.dst)
282 # IP processing post pop has decremented the TTL
283 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
284
285 except:
Neale Rannsad422ed2016-11-02 14:20:04 +0000286 raise
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000287
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800288 def send_and_assert_no_replies(self, intf, pkts, remark):
289 intf.add_stream(pkts)
290 self.pg_enable_capture(self.pg_interfaces)
291 self.pg_start()
292 for i in self.pg_interfaces:
293 i.assert_nothing_captured(remark=remark)
294
Neale Rannsad422ed2016-11-02 14:20:04 +0000295 def test_swap(self):
296 """ MPLS label swap tests """
297
298 #
299 # A simple MPLS xconnect - eos label in label out
300 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800301 route_32_eos = VppMplsRoute(self, 32, 1,
302 [VppRoutePath(self.pg0.remote_ip4,
303 self.pg0.sw_if_index,
304 labels=[33])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000305 route_32_eos.add_vpp_config()
306
307 #
308 # a stream that matches the route for 10.0.0.1
309 # PG0 is in the default table
310 #
311 self.vapi.cli("clear trace")
312 tx = self.create_stream_labelled_ip4(self.pg0, [32])
313 self.pg0.add_stream(tx)
314
315 self.pg_enable_capture(self.pg_interfaces)
316 self.pg_start()
317
318 rx = self.pg0.get_capture()
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800319 self.verify_capture_labelled(self.pg0, rx, tx, [33])
Neale Rannsad422ed2016-11-02 14:20:04 +0000320
321 #
322 # A simple MPLS xconnect - non-eos label in label out
323 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800324 route_32_neos = VppMplsRoute(self, 32, 0,
325 [VppRoutePath(self.pg0.remote_ip4,
326 self.pg0.sw_if_index,
327 labels=[33])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000328 route_32_neos.add_vpp_config()
329
330 #
331 # a stream that matches the route for 10.0.0.1
332 # PG0 is in the default table
333 #
334 self.vapi.cli("clear trace")
335 tx = self.create_stream_labelled_ip4(self.pg0, [32, 99])
336 self.pg0.add_stream(tx)
337
338 self.pg_enable_capture(self.pg_interfaces)
339 self.pg_start()
340
341 rx = self.pg0.get_capture()
342 self.verify_capture_labelled(self.pg0, rx, tx, [33, 99])
343
344 #
345 # An MPLS xconnect - EOS label in IP out
346 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800347 route_33_eos = VppMplsRoute(self, 33, 1,
348 [VppRoutePath(self.pg0.remote_ip4,
349 self.pg0.sw_if_index,
350 labels=[])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000351 route_33_eos.add_vpp_config()
352
353 self.vapi.cli("clear trace")
354 tx = self.create_stream_labelled_ip4(self.pg0, [33])
355 self.pg0.add_stream(tx)
356
357 self.pg_enable_capture(self.pg_interfaces)
358 self.pg_start()
359
360 rx = self.pg0.get_capture()
361 self.verify_capture_ip4(self.pg0, rx, tx)
362
363 #
364 # An MPLS xconnect - non-EOS label in IP out - an invalid configuration
365 # so this traffic should be dropped.
366 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800367 route_33_neos = VppMplsRoute(self, 33, 0,
368 [VppRoutePath(self.pg0.remote_ip4,
369 self.pg0.sw_if_index,
370 labels=[])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000371 route_33_neos.add_vpp_config()
372
373 self.vapi.cli("clear trace")
374 tx = self.create_stream_labelled_ip4(self.pg0, [33, 99])
375 self.pg0.add_stream(tx)
376
377 self.pg_enable_capture(self.pg_interfaces)
378 self.pg_start()
Klement Sekera9225dee2016-12-12 08:36:58 +0100379 self.pg0.assert_nothing_captured(
380 remark="MPLS non-EOS packets popped and forwarded")
Neale Rannsad422ed2016-11-02 14:20:04 +0000381
382 #
383 # A recursive EOS x-connect, which resolves through another x-connect
384 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800385 route_34_eos = VppMplsRoute(self, 34, 1,
386 [VppRoutePath("0.0.0.0",
387 0xffffffff,
388 nh_via_label=32,
389 labels=[44, 45])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000390 route_34_eos.add_vpp_config()
391
Neale Rannsad422ed2016-11-02 14:20:04 +0000392 tx = self.create_stream_labelled_ip4(self.pg0, [34])
393 self.pg0.add_stream(tx)
394
395 self.pg_enable_capture(self.pg_interfaces)
396 self.pg_start()
397
398 rx = self.pg0.get_capture()
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800399 self.verify_capture_labelled(self.pg0, rx, tx, [33, 44, 45], num=2)
Neale Rannsad422ed2016-11-02 14:20:04 +0000400
401 #
Matej Klottondeb69842016-12-09 15:05:46 +0100402 # A recursive non-EOS x-connect, which resolves through another
403 # x-connect
Neale Rannsad422ed2016-11-02 14:20:04 +0000404 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800405 route_34_neos = VppMplsRoute(self, 34, 0,
406 [VppRoutePath("0.0.0.0",
407 0xffffffff,
408 nh_via_label=32,
409 labels=[44, 46])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000410 route_34_neos.add_vpp_config()
411
412 self.vapi.cli("clear trace")
413 tx = self.create_stream_labelled_ip4(self.pg0, [34, 99])
414 self.pg0.add_stream(tx)
415
416 self.pg_enable_capture(self.pg_interfaces)
417 self.pg_start()
418
419 rx = self.pg0.get_capture()
Matej Klottondeb69842016-12-09 15:05:46 +0100420 # it's the 2nd (counting from 0) label in the stack that is swapped
Neale Rannsad422ed2016-11-02 14:20:04 +0000421 self.verify_capture_labelled(self.pg0, rx, tx, [33, 44, 46, 99], num=2)
422
423 #
Matej Klottondeb69842016-12-09 15:05:46 +0100424 # an recursive IP route that resolves through the recursive non-eos
425 # x-connect
Neale Rannsad422ed2016-11-02 14:20:04 +0000426 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800427 ip_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
428 [VppRoutePath("0.0.0.0",
429 0xffffffff,
430 nh_via_label=34,
431 labels=[55])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000432 ip_10_0_0_1.add_vpp_config()
433
434 self.vapi.cli("clear trace")
435 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
436 self.pg0.add_stream(tx)
437
438 self.pg_enable_capture(self.pg_interfaces)
439 self.pg_start()
440
441 rx = self.pg0.get_capture()
442 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [33, 44, 46, 55])
443
444 ip_10_0_0_1.remove_vpp_config()
445 route_34_neos.remove_vpp_config()
446 route_34_eos.remove_vpp_config()
447 route_33_neos.remove_vpp_config()
448 route_33_eos.remove_vpp_config()
449 route_32_neos.remove_vpp_config()
450 route_32_eos.remove_vpp_config()
451
452 def test_bind(self):
453 """ MPLS Local Label Binding test """
454
455 #
456 # Add a non-recursive route with a single out label
457 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800458 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
459 [VppRoutePath(self.pg0.remote_ip4,
460 self.pg0.sw_if_index,
461 labels=[45])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000462 route_10_0_0_1.add_vpp_config()
463
464 # bind a local label to the route
Neale Ranns5a8123b2017-01-26 01:18:23 -0800465 binding = VppMplsIpBind(self, 44, "10.0.0.1", 32)
Neale Rannsad422ed2016-11-02 14:20:04 +0000466 binding.add_vpp_config()
467
468 # non-EOS stream
469 self.vapi.cli("clear trace")
470 tx = self.create_stream_labelled_ip4(self.pg0, [44, 99])
471 self.pg0.add_stream(tx)
472
473 self.pg_enable_capture(self.pg_interfaces)
474 self.pg_start()
475
476 rx = self.pg0.get_capture()
477 self.verify_capture_labelled(self.pg0, rx, tx, [45, 99])
478
479 # EOS stream
480 self.vapi.cli("clear trace")
481 tx = self.create_stream_labelled_ip4(self.pg0, [44])
482 self.pg0.add_stream(tx)
483
484 self.pg_enable_capture(self.pg_interfaces)
485 self.pg_start()
486
487 rx = self.pg0.get_capture()
488 self.verify_capture_labelled(self.pg0, rx, tx, [45])
489
490 # IP stream
491 self.vapi.cli("clear trace")
492 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
493 self.pg0.add_stream(tx)
494
495 self.pg_enable_capture(self.pg_interfaces)
496 self.pg_start()
497
498 rx = self.pg0.get_capture()
499 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [45])
500
501 #
502 # cleanup
503 #
504 binding.remove_vpp_config()
505 route_10_0_0_1.remove_vpp_config()
506
507 def test_imposition(self):
508 """ MPLS label imposition test """
509
510 #
511 # Add a non-recursive route with a single out label
512 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800513 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
514 [VppRoutePath(self.pg0.remote_ip4,
515 self.pg0.sw_if_index,
516 labels=[32])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000517 route_10_0_0_1.add_vpp_config()
518
519 #
520 # a stream that matches the route for 10.0.0.1
521 # PG0 is in the default table
522 #
523 self.vapi.cli("clear trace")
524 tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
525 self.pg0.add_stream(tx)
526
527 self.pg_enable_capture(self.pg_interfaces)
528 self.pg_start()
529
530 rx = self.pg0.get_capture()
531 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [32])
532
533 #
534 # Add a non-recursive route with a 3 out labels
535 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800536 route_10_0_0_2 = VppIpRoute(self, "10.0.0.2", 32,
537 [VppRoutePath(self.pg0.remote_ip4,
538 self.pg0.sw_if_index,
539 labels=[32, 33, 34])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000540 route_10_0_0_2.add_vpp_config()
541
542 #
543 # a stream that matches the route for 10.0.0.1
544 # PG0 is in the default table
545 #
546 self.vapi.cli("clear trace")
547 tx = self.create_stream_ip4(self.pg0, "10.0.0.2")
548 self.pg0.add_stream(tx)
549
550 self.pg_enable_capture(self.pg_interfaces)
551 self.pg_start()
552
553 rx = self.pg0.get_capture()
554 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [32, 33, 34])
555
556 #
Matej Klottondeb69842016-12-09 15:05:46 +0100557 # add a recursive path, with output label, via the 1 label route
Neale Rannsad422ed2016-11-02 14:20:04 +0000558 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800559 route_11_0_0_1 = VppIpRoute(self, "11.0.0.1", 32,
560 [VppRoutePath("10.0.0.1",
561 0xffffffff,
562 labels=[44])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000563 route_11_0_0_1.add_vpp_config()
564
565 #
566 # a stream that matches the route for 11.0.0.1, should pick up
567 # the label stack for 11.0.0.1 and 10.0.0.1
568 #
569 self.vapi.cli("clear trace")
570 tx = self.create_stream_ip4(self.pg0, "11.0.0.1")
571 self.pg0.add_stream(tx)
572
573 self.pg_enable_capture(self.pg_interfaces)
574 self.pg_start()
575
576 rx = self.pg0.get_capture()
577 self.verify_capture_labelled_ip4(self.pg0, rx, tx, [32, 44])
578
579 #
580 # add a recursive path, with 2 labels, via the 3 label route
581 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800582 route_11_0_0_2 = VppIpRoute(self, "11.0.0.2", 32,
583 [VppRoutePath("10.0.0.2",
584 0xffffffff,
585 labels=[44, 45])])
Neale Rannsad422ed2016-11-02 14:20:04 +0000586 route_11_0_0_2.add_vpp_config()
587
588 #
589 # a stream that matches the route for 11.0.0.1, should pick up
590 # the label stack for 11.0.0.1 and 10.0.0.1
591 #
592 self.vapi.cli("clear trace")
593 tx = self.create_stream_ip4(self.pg0, "11.0.0.2")
594 self.pg0.add_stream(tx)
595
596 self.pg_enable_capture(self.pg_interfaces)
597 self.pg_start()
598
599 rx = self.pg0.get_capture()
600 self.verify_capture_labelled_ip4(
601 self.pg0, rx, tx, [32, 33, 34, 44, 45])
602
603 #
604 # cleanup
605 #
606 route_11_0_0_2.remove_vpp_config()
607 route_11_0_0_1.remove_vpp_config()
608 route_10_0_0_2.remove_vpp_config()
609 route_10_0_0_1.remove_vpp_config()
610
611 def test_tunnel(self):
612 """ MPLS Tunnel Tests """
613
614 #
615 # Create a tunnel with a single out label
616 #
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800617 mpls_tun = VppMPLSTunnelInterface(self,
618 [VppRoutePath(self.pg0.remote_ip4,
619 self.pg0.sw_if_index,
620 labels=[44, 46])])
621 mpls_tun.add_vpp_config()
622 mpls_tun.admin_up()
Neale Rannsad422ed2016-11-02 14:20:04 +0000623
624 #
625 # add an unlabelled route through the new tunnel
626 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800627 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
628 [VppRoutePath("0.0.0.0",
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800629 mpls_tun._sw_if_index)])
Neale Ranns5a8123b2017-01-26 01:18:23 -0800630 route_10_0_0_3.add_vpp_config()
Neale Rannsad422ed2016-11-02 14:20:04 +0000631
632 self.vapi.cli("clear trace")
633 tx = self.create_stream_ip4(self.pg0, "10.0.0.3")
634 self.pg0.add_stream(tx)
635
636 self.pg_enable_capture(self.pg_interfaces)
637 self.pg_start()
638
639 rx = self.pg0.get_capture()
640 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [44, 46])
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000641
Neale Ranns8c4611b2017-05-23 03:43:47 -0700642 #
643 # add a labelled route through the new tunnel
644 #
645 route_10_0_0_4 = VppIpRoute(self, "10.0.0.4", 32,
646 [VppRoutePath("0.0.0.0",
647 mpls_tun._sw_if_index,
648 labels=[33])])
649 route_10_0_0_4.add_vpp_config()
650
651 self.vapi.cli("clear trace")
652 tx = self.create_stream_ip4(self.pg0, "10.0.0.4")
653 self.pg0.add_stream(tx)
654
655 self.pg_enable_capture(self.pg_interfaces)
656 self.pg_start()
657
658 rx = self.pg0.get_capture()
659 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [44, 46, 33],
660 ttl=63, top=2)
661
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000662 def test_v4_exp_null(self):
663 """ MPLS V4 Explicit NULL test """
664
665 #
666 # The first test case has an MPLS TTL of 0
667 # all packet should be dropped
668 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000669 tx = self.create_stream_labelled_ip4(self.pg0, [0], 0)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000670 self.pg0.add_stream(tx)
671
672 self.pg_enable_capture(self.pg_interfaces)
673 self.pg_start()
674
Klement Sekera9225dee2016-12-12 08:36:58 +0100675 self.pg0.assert_nothing_captured(remark="MPLS TTL=0 packets forwarded")
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000676
677 #
678 # a stream with a non-zero MPLS TTL
679 # PG0 is in the default table
680 #
Neale Rannsad422ed2016-11-02 14:20:04 +0000681 tx = self.create_stream_labelled_ip4(self.pg0, [0])
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000682 self.pg0.add_stream(tx)
683
684 self.pg_enable_capture(self.pg_interfaces)
685 self.pg_start()
686
687 rx = self.pg0.get_capture()
688 self.verify_capture_ip4(self.pg0, rx, tx)
689
690 #
691 # a stream with a non-zero MPLS TTL
692 # PG1 is in table 1
693 # we are ensuring the post-pop lookup occurs in the VRF table
694 #
695 self.vapi.cli("clear trace")
Neale Rannsad422ed2016-11-02 14:20:04 +0000696 tx = self.create_stream_labelled_ip4(self.pg1, [0])
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000697 self.pg1.add_stream(tx)
698
699 self.pg_enable_capture(self.pg_interfaces)
700 self.pg_start()
701
702 rx = self.pg1.get_capture()
703 self.verify_capture_ip4(self.pg0, rx, tx)
704
705 def test_v6_exp_null(self):
706 """ MPLS V6 Explicit NULL test """
707
708 #
709 # a stream with a non-zero MPLS TTL
710 # PG0 is in the default table
711 #
712 self.vapi.cli("clear trace")
Neale Rannsad422ed2016-11-02 14:20:04 +0000713 tx = self.create_stream_labelled_ip6(self.pg0, 2, 2)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000714 self.pg0.add_stream(tx)
715
716 self.pg_enable_capture(self.pg_interfaces)
717 self.pg_start()
718
719 rx = self.pg0.get_capture()
720 self.verify_capture_ip6(self.pg0, rx, tx)
721
722 #
723 # a stream with a non-zero MPLS TTL
724 # PG1 is in table 1
725 # we are ensuring the post-pop lookup occurs in the VRF table
726 #
727 self.vapi.cli("clear trace")
Neale Rannsad422ed2016-11-02 14:20:04 +0000728 tx = self.create_stream_labelled_ip6(self.pg1, 2, 2)
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000729 self.pg1.add_stream(tx)
730
731 self.pg_enable_capture(self.pg_interfaces)
732 self.pg_start()
733
734 rx = self.pg1.get_capture()
735 self.verify_capture_ip6(self.pg0, rx, tx)
736
Neale Rannscb630ff2016-12-14 13:31:29 +0100737 def test_deag(self):
738 """ MPLS Deagg """
739
740 #
741 # A de-agg route - next-hop lookup in default table
742 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800743 route_34_eos = VppMplsRoute(self, 34, 1,
744 [VppRoutePath("0.0.0.0",
745 0xffffffff,
746 nh_table_id=0)])
Neale Rannscb630ff2016-12-14 13:31:29 +0100747 route_34_eos.add_vpp_config()
748
749 #
750 # ping an interface in the default table
751 # PG0 is in the default table
752 #
753 self.vapi.cli("clear trace")
754 tx = self.create_stream_labelled_ip4(self.pg0, [34], ping=1,
755 ip_itf=self.pg0)
756 self.pg0.add_stream(tx)
757
758 self.pg_enable_capture(self.pg_interfaces)
759 self.pg_start()
760
761 rx = self.pg0.get_capture()
762 self.verify_capture_ip4(self.pg0, rx, tx, ping_resp=1)
763
764 #
765 # A de-agg route - next-hop lookup in non-default table
766 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800767 route_35_eos = VppMplsRoute(self, 35, 1,
768 [VppRoutePath("0.0.0.0",
769 0xffffffff,
770 nh_table_id=1)])
Neale Rannscb630ff2016-12-14 13:31:29 +0100771 route_35_eos.add_vpp_config()
772
773 #
774 # ping an interface in the non-default table
775 # PG0 is in the default table. packet arrive labelled in the
776 # default table and egress unlabelled in the non-default
777 #
778 self.vapi.cli("clear trace")
Klement Sekeradab231a2016-12-21 08:50:14 +0100779 tx = self.create_stream_labelled_ip4(
780 self.pg0, [35], ping=1, ip_itf=self.pg1)
Neale Rannscb630ff2016-12-14 13:31:29 +0100781 self.pg0.add_stream(tx)
782
783 self.pg_enable_capture(self.pg_interfaces)
784 self.pg_start()
785
Klement Sekeradab231a2016-12-21 08:50:14 +0100786 packet_count = self.get_packet_count_for_if_idx(self.pg0.sw_if_index)
787 rx = self.pg1.get_capture(packet_count)
Neale Rannscb630ff2016-12-14 13:31:29 +0100788 self.verify_capture_ip4(self.pg1, rx, tx, ping_resp=1)
789
Neale Ranns6af1c042017-05-26 03:48:53 -0700790 #
791 # Double pop
792 #
793 route_36_neos = VppMplsRoute(self, 36, 0,
794 [VppRoutePath("0.0.0.0",
795 0xffffffff)])
796 route_36_neos.add_vpp_config()
797
798 self.vapi.cli("clear trace")
799 tx = self.create_stream_labelled_ip4(self.pg0, [36, 35],
800 ping=1, ip_itf=self.pg1)
801 self.pg0.add_stream(tx)
802
803 self.pg_enable_capture(self.pg_interfaces)
804 self.pg_start()
805
806 rx = self.pg1.get_capture(len(tx))
807 self.verify_capture_ip4(self.pg1, rx, tx, ping_resp=1)
808
809 route_36_neos.remove_vpp_config()
Neale Rannscb630ff2016-12-14 13:31:29 +0100810 route_35_eos.remove_vpp_config()
811 route_34_eos.remove_vpp_config()
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000812
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800813 def test_interface_rx(self):
814 """ MPLS Interface Receive """
815
816 #
817 # Add a non-recursive route that will forward the traffic
818 # post-interface-rx
819 #
820 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
821 table_id=1,
822 paths=[VppRoutePath(self.pg1.remote_ip4,
823 self.pg1.sw_if_index)])
824 route_10_0_0_1.add_vpp_config()
825
826 #
827 # An interface receive label that maps traffic to RX on interface
828 # pg1
829 # by injecting the packet in on pg0, which is in table 0
830 # doing an interface-rx on pg1 and matching a route in table 1
831 # if the packet egresses, then we must have swapped to pg1
832 # so as to have matched the route in table 1
833 #
834 route_34_eos = VppMplsRoute(self, 34, 1,
835 [VppRoutePath("0.0.0.0",
836 self.pg1.sw_if_index,
837 is_interface_rx=1)])
838 route_34_eos.add_vpp_config()
839
840 #
841 # ping an interface in the default table
842 # PG0 is in the default table
843 #
844 self.vapi.cli("clear trace")
845 tx = self.create_stream_labelled_ip4(self.pg0, [34], n=257,
846 dst_ip="10.0.0.1")
847 self.pg0.add_stream(tx)
848
849 self.pg_enable_capture(self.pg_interfaces)
850 self.pg_start()
851
852 rx = self.pg1.get_capture(257)
853 self.verify_capture_ip4(self.pg1, rx, tx)
854
855 def test_mcast_mid_point(self):
856 """ MPLS Multicast Mid Point """
857
858 #
859 # Add a non-recursive route that will forward the traffic
860 # post-interface-rx
861 #
862 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
863 table_id=1,
864 paths=[VppRoutePath(self.pg1.remote_ip4,
865 self.pg1.sw_if_index)])
866 route_10_0_0_1.add_vpp_config()
867
868 #
869 # Add a mcast entry that replicate to pg2 and pg3
870 # and replicate to a interface-rx (like a bud node would)
871 #
872 route_3400_eos = VppMplsRoute(self, 3400, 1,
873 [VppRoutePath(self.pg2.remote_ip4,
874 self.pg2.sw_if_index,
875 labels=[3401]),
876 VppRoutePath(self.pg3.remote_ip4,
877 self.pg3.sw_if_index,
878 labels=[3402]),
879 VppRoutePath("0.0.0.0",
880 self.pg1.sw_if_index,
881 is_interface_rx=1)],
882 is_multicast=1)
883 route_3400_eos.add_vpp_config()
884
885 #
886 # ping an interface in the default table
887 # PG0 is in the default table
888 #
889 self.vapi.cli("clear trace")
890 tx = self.create_stream_labelled_ip4(self.pg0, [3400], n=257,
891 dst_ip="10.0.0.1")
892 self.pg0.add_stream(tx)
893
894 self.pg_enable_capture(self.pg_interfaces)
895 self.pg_start()
896
897 rx = self.pg1.get_capture(257)
898 self.verify_capture_ip4(self.pg1, rx, tx)
899
900 rx = self.pg2.get_capture(257)
901 self.verify_capture_labelled(self.pg2, rx, tx, [3401])
902 rx = self.pg3.get_capture(257)
903 self.verify_capture_labelled(self.pg3, rx, tx, [3402])
904
905 def test_mcast_head(self):
906 """ MPLS Multicast Head-end """
907
908 #
909 # Create a multicast tunnel with two replications
910 #
911 mpls_tun = VppMPLSTunnelInterface(self,
912 [VppRoutePath(self.pg2.remote_ip4,
913 self.pg2.sw_if_index,
914 labels=[42]),
915 VppRoutePath(self.pg3.remote_ip4,
916 self.pg3.sw_if_index,
917 labels=[43])],
918 is_multicast=1)
919 mpls_tun.add_vpp_config()
920 mpls_tun.admin_up()
921
922 #
923 # add an unlabelled route through the new tunnel
924 #
925 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
926 [VppRoutePath("0.0.0.0",
927 mpls_tun._sw_if_index)])
928 route_10_0_0_3.add_vpp_config()
929
930 self.vapi.cli("clear trace")
931 tx = self.create_stream_ip4(self.pg0, "10.0.0.3")
932 self.pg0.add_stream(tx)
933
934 self.pg_enable_capture(self.pg_interfaces)
935 self.pg_start()
936
937 rx = self.pg2.get_capture(257)
938 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [42])
939 rx = self.pg3.get_capture(257)
940 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [43])
941
942 #
943 # An an IP multicast route via the tunnel
944 # A (*,G).
945 # one accepting interface, pg0, 1 forwarding interface via the tunnel
946 #
947 route_232_1_1_1 = VppIpMRoute(
948 self,
949 "0.0.0.0",
950 "232.1.1.1", 32,
951 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
952 [VppMRoutePath(self.pg0.sw_if_index,
953 MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
954 VppMRoutePath(mpls_tun._sw_if_index,
955 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
956 route_232_1_1_1.add_vpp_config()
957
958 self.vapi.cli("clear trace")
959 tx = self.create_stream_ip4(self.pg0, "232.1.1.1")
960 self.pg0.add_stream(tx)
961
962 self.pg_enable_capture(self.pg_interfaces)
963 self.pg_start()
964
965 rx = self.pg2.get_capture(257)
966 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [42])
967 rx = self.pg3.get_capture(257)
968 self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [43])
969
Neale Ranns31426c62017-05-24 10:32:58 -0700970 def test_mcast_ip4_tail(self):
971 """ MPLS IPv4 Multicast Tail """
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800972
973 #
974 # Add a multicast route that will forward the traffic
975 # post-disposition
976 #
977 route_232_1_1_1 = VppIpMRoute(
978 self,
979 "0.0.0.0",
980 "232.1.1.1", 32,
981 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
982 table_id=1,
983 paths=[VppMRoutePath(self.pg1.sw_if_index,
984 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
985 route_232_1_1_1.add_vpp_config()
986
987 #
988 # An interface receive label that maps traffic to RX on interface
989 # pg1
990 # by injecting the packet in on pg0, which is in table 0
991 # doing an rpf-id and matching a route in table 1
992 # if the packet egresses, then we must have matched the route in
993 # table 1
994 #
995 route_34_eos = VppMplsRoute(self, 34, 1,
996 [VppRoutePath("0.0.0.0",
997 self.pg1.sw_if_index,
998 nh_table_id=1,
999 rpf_id=55)],
1000 is_multicast=1)
1001
1002 route_34_eos.add_vpp_config()
1003
1004 #
1005 # Drop due to interface lookup miss
1006 #
1007 self.vapi.cli("clear trace")
1008 tx = self.create_stream_labelled_ip4(self.pg0, [34],
1009 dst_ip="232.1.1.1", n=1)
1010 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop none")
1011
1012 #
1013 # set the RPF-ID of the enrtry to match the input packet's
1014 #
1015 route_232_1_1_1.update_rpf_id(55)
1016
1017 self.vapi.cli("clear trace")
1018 tx = self.create_stream_labelled_ip4(self.pg0, [34],
1019 dst_ip="232.1.1.1", n=257)
1020 self.pg0.add_stream(tx)
1021
1022 self.pg_enable_capture(self.pg_interfaces)
1023 self.pg_start()
1024
1025 rx = self.pg1.get_capture(257)
1026 self.verify_capture_ip4(self.pg1, rx, tx)
1027
1028 #
1029 # set the RPF-ID of the enrtry to not match the input packet's
1030 #
1031 route_232_1_1_1.update_rpf_id(56)
1032 tx = self.create_stream_labelled_ip4(self.pg0, [34],
1033 dst_ip="232.1.1.1")
1034 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop 56")
1035
Neale Ranns31426c62017-05-24 10:32:58 -07001036 def test_mcast_ip6_tail(self):
1037 """ MPLS IPv6 Multicast Tail """
1038
1039 #
1040 # Add a multicast route that will forward the traffic
1041 # post-disposition
1042 #
1043 route_ff = VppIpMRoute(
1044 self,
1045 "::",
1046 "ff01::1", 32,
1047 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
1048 table_id=1,
1049 paths=[VppMRoutePath(self.pg1.sw_if_index,
1050 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)],
1051 is_ip6=1)
1052 route_ff.add_vpp_config()
1053
1054 #
1055 # An interface receive label that maps traffic to RX on interface
1056 # pg1
1057 # by injecting the packet in on pg0, which is in table 0
1058 # doing an rpf-id and matching a route in table 1
1059 # if the packet egresses, then we must have matched the route in
1060 # table 1
1061 #
1062 route_34_eos = VppMplsRoute(
1063 self, 34, 1,
1064 [VppRoutePath("::",
1065 self.pg1.sw_if_index,
1066 nh_table_id=1,
1067 rpf_id=55,
Neale Rannsda78f952017-05-24 09:15:43 -07001068 proto=DpoProto.DPO_PROTO_IP6)],
Neale Ranns31426c62017-05-24 10:32:58 -07001069 is_multicast=1)
1070
1071 route_34_eos.add_vpp_config()
1072
1073 #
1074 # Drop due to interface lookup miss
1075 #
1076 tx = self.create_stream_labelled_ip6(self.pg0, [34], 255,
1077 dst_ip="ff01::1")
1078
1079 #
1080 # set the RPF-ID of the enrtry to match the input packet's
1081 #
1082 route_ff.update_rpf_id(55)
1083
1084 tx = self.create_stream_labelled_ip6(self.pg0, [34], 255,
1085 dst_ip="ff01::1")
1086 self.pg0.add_stream(tx)
1087
1088 self.pg_enable_capture(self.pg_interfaces)
1089 self.pg_start()
1090
1091 rx = self.pg1.get_capture(257)
1092 self.verify_capture_ip6(self.pg1, rx, tx)
1093
1094 #
1095 # set the RPF-ID of the enrtry to not match the input packet's
1096 #
1097 route_ff.update_rpf_id(56)
1098 tx = self.create_stream_labelled_ip6(self.pg0, [34], 225,
1099 dst_ip="ff01::1")
1100 self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop 56")
1101
Neale Ranns180279b2017-03-16 15:49:09 -04001102
1103class TestMPLSDisabled(VppTestCase):
1104 """ MPLS disabled """
1105
1106 def setUp(self):
1107 super(TestMPLSDisabled, self).setUp()
1108
1109 # create 2 pg interfaces
1110 self.create_pg_interfaces(range(2))
1111
Neale Ranns15002542017-09-10 04:39:11 -07001112 self.tbl = VppMplsTable(self, 0)
1113 self.tbl.add_vpp_config()
1114
Neale Ranns180279b2017-03-16 15:49:09 -04001115 # PG0 is MPLS enalbed
1116 self.pg0.admin_up()
1117 self.pg0.config_ip4()
1118 self.pg0.resolve_arp()
1119 self.pg0.enable_mpls()
1120
1121 # PG 1 is not MPLS enabled
1122 self.pg1.admin_up()
1123
1124 def tearDown(self):
Neale Ranns180279b2017-03-16 15:49:09 -04001125 for i in self.pg_interfaces:
1126 i.unconfig_ip4()
1127 i.admin_down()
1128
Neale Ranns15002542017-09-10 04:39:11 -07001129 self.pg0.disable_mpls()
1130 super(TestMPLSDisabled, self).tearDown()
1131
Neale Ranns180279b2017-03-16 15:49:09 -04001132 def send_and_assert_no_replies(self, intf, pkts, remark):
1133 intf.add_stream(pkts)
1134 self.pg_enable_capture(self.pg_interfaces)
1135 self.pg_start()
1136 for i in self.pg_interfaces:
1137 i.get_capture(0)
1138 i.assert_nothing_captured(remark=remark)
1139
1140 def test_mpls_disabled(self):
1141 """ MPLS Disabled """
1142
1143 tx = (Ether(src=self.pg1.remote_mac,
1144 dst=self.pg1.local_mac) /
1145 MPLS(label=32, ttl=64) /
1146 IPv6(src="2001::1", dst=self.pg0.remote_ip6) /
1147 UDP(sport=1234, dport=1234) /
1148 Raw('\xa5' * 100))
1149
1150 #
1151 # A simple MPLS xconnect - eos label in label out
1152 #
1153 route_32_eos = VppMplsRoute(self, 32, 1,
1154 [VppRoutePath(self.pg0.remote_ip4,
1155 self.pg0.sw_if_index,
1156 labels=[33])])
1157 route_32_eos.add_vpp_config()
1158
1159 #
1160 # PG1 does not forward IP traffic
1161 #
1162 self.send_and_assert_no_replies(self.pg1, tx, "MPLS disabled")
1163
1164 #
1165 # MPLS enable PG1
1166 #
1167 self.pg1.enable_mpls()
1168
1169 #
1170 # Now we get packets through
1171 #
1172 self.pg1.add_stream(tx)
1173 self.pg_enable_capture(self.pg_interfaces)
1174 self.pg_start()
1175
1176 rx = self.pg0.get_capture(1)
1177
1178 #
1179 # Disable PG1
1180 #
1181 self.pg1.disable_mpls()
1182
1183 #
1184 # PG1 does not forward IP traffic
1185 #
1186 self.send_and_assert_no_replies(self.pg1, tx, "IPv6 disabled")
1187 self.send_and_assert_no_replies(self.pg1, tx, "IPv6 disabled")
1188
1189
Neale Rannsf12a83f2017-04-18 09:09:40 -07001190class TestMPLSPIC(VppTestCase):
1191 """ MPLS PIC edge convergence """
1192
1193 def setUp(self):
1194 super(TestMPLSPIC, self).setUp()
1195
1196 # create 2 pg interfaces
1197 self.create_pg_interfaces(range(4))
1198
Neale Ranns15002542017-09-10 04:39:11 -07001199 mpls_tbl = VppMplsTable(self, 0)
1200 mpls_tbl.add_vpp_config()
1201 tbl4 = VppIpTable(self, 1)
1202 tbl4.add_vpp_config()
1203 tbl6 = VppIpTable(self, 1, is_ip6=1)
1204 tbl6.add_vpp_config()
1205
Neale Rannsf12a83f2017-04-18 09:09:40 -07001206 # core links
1207 self.pg0.admin_up()
1208 self.pg0.config_ip4()
1209 self.pg0.resolve_arp()
1210 self.pg0.enable_mpls()
1211 self.pg1.admin_up()
1212 self.pg1.config_ip4()
1213 self.pg1.resolve_arp()
1214 self.pg1.enable_mpls()
1215
1216 # VRF (customer facing) link
1217 self.pg2.admin_up()
1218 self.pg2.set_table_ip4(1)
1219 self.pg2.config_ip4()
1220 self.pg2.resolve_arp()
1221 self.pg2.set_table_ip6(1)
1222 self.pg2.config_ip6()
1223 self.pg2.resolve_ndp()
1224 self.pg3.admin_up()
1225 self.pg3.set_table_ip4(1)
1226 self.pg3.config_ip4()
1227 self.pg3.resolve_arp()
1228 self.pg3.set_table_ip6(1)
1229 self.pg3.config_ip6()
1230 self.pg3.resolve_ndp()
1231
1232 def tearDown(self):
Neale Rannsf12a83f2017-04-18 09:09:40 -07001233 self.pg0.disable_mpls()
Neale Ranns15002542017-09-10 04:39:11 -07001234 self.pg1.disable_mpls()
Neale Rannsf12a83f2017-04-18 09:09:40 -07001235 for i in self.pg_interfaces:
1236 i.unconfig_ip4()
1237 i.unconfig_ip6()
1238 i.set_table_ip4(0)
1239 i.set_table_ip6(0)
1240 i.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -07001241 super(TestMPLSPIC, self).tearDown()
Neale Rannsf12a83f2017-04-18 09:09:40 -07001242
1243 def test_mpls_ibgp_pic(self):
1244 """ MPLS iBGP PIC edge convergence
1245
1246 1) setup many iBGP VPN routes via a pair of iBGP peers.
1247 2) Check EMCP forwarding to these peers
1248 3) withdraw the IGP route to one of these peers.
1249 4) check forwarding continues to the remaining peer
1250 """
1251
1252 #
1253 # IGP+LDP core routes
1254 #
1255 core_10_0_0_45 = VppIpRoute(self, "10.0.0.45", 32,
1256 [VppRoutePath(self.pg0.remote_ip4,
1257 self.pg0.sw_if_index,
1258 labels=[45])])
1259 core_10_0_0_45.add_vpp_config()
1260
1261 core_10_0_0_46 = VppIpRoute(self, "10.0.0.46", 32,
1262 [VppRoutePath(self.pg1.remote_ip4,
1263 self.pg1.sw_if_index,
1264 labels=[46])])
1265 core_10_0_0_46.add_vpp_config()
1266
1267 #
1268 # Lot's of VPN routes. We need more the 64 so VPP will build
1269 # the fast convergence indirection
1270 #
1271 vpn_routes = []
1272 pkts = []
1273 for ii in range(64):
1274 dst = "192.168.1.%d" % ii
1275 vpn_routes.append(VppIpRoute(self, dst, 32,
1276 [VppRoutePath("10.0.0.45",
1277 0xffffffff,
1278 labels=[145],
1279 is_resolve_host=1),
1280 VppRoutePath("10.0.0.46",
1281 0xffffffff,
1282 labels=[146],
1283 is_resolve_host=1)],
1284 table_id=1))
1285 vpn_routes[ii].add_vpp_config()
1286
1287 pkts.append(Ether(dst=self.pg2.local_mac,
1288 src=self.pg2.remote_mac) /
1289 IP(src=self.pg2.remote_ip4, dst=dst) /
1290 UDP(sport=1234, dport=1234) /
1291 Raw('\xa5' * 100))
1292
1293 #
1294 # Send the packet stream (one pkt to each VPN route)
1295 # - expect a 50-50 split of the traffic
1296 #
1297 self.pg2.add_stream(pkts)
1298 self.pg_enable_capture(self.pg_interfaces)
1299 self.pg_start()
1300
1301 rx0 = self.pg0._get_capture(1)
1302 rx1 = self.pg1._get_capture(1)
1303
1304 # not testig the LB hashing algorithm so we're not concerned
1305 # with the split ratio, just as long as neither is 0
1306 self.assertNotEqual(0, len(rx0))
1307 self.assertNotEqual(0, len(rx1))
1308
1309 #
1310 # use a test CLI command to stop the FIB walk process, this
1311 # will prevent the FIB converging the VPN routes and thus allow
1312 # us to probe the interim (psot-fail, pre-converge) state
1313 #
1314 self.vapi.ppcli("test fib-walk-process disable")
1315
1316 #
1317 # Withdraw one of the IGP routes
1318 #
1319 core_10_0_0_46.remove_vpp_config()
1320
1321 #
1322 # now all packets should be forwarded through the remaining peer
1323 #
1324 self.vapi.ppcli("clear trace")
1325 self.pg2.add_stream(pkts)
1326 self.pg_enable_capture(self.pg_interfaces)
1327 self.pg_start()
1328
1329 rx0 = self.pg0.get_capture(len(pkts))
1330
1331 #
1332 # enable the FIB walk process to converge the FIB
1333 #
1334 self.vapi.ppcli("test fib-walk-process enable")
1335
1336 #
1337 # packets should still be forwarded through the remaining peer
1338 #
1339 self.pg2.add_stream(pkts)
1340 self.pg_enable_capture(self.pg_interfaces)
1341 self.pg_start()
1342
1343 rx0 = self.pg0.get_capture(64)
1344
1345 #
1346 # Add the IGP route back and we return to load-balancing
1347 #
1348 core_10_0_0_46.add_vpp_config()
1349
1350 self.pg2.add_stream(pkts)
1351 self.pg_enable_capture(self.pg_interfaces)
1352 self.pg_start()
1353
1354 rx0 = self.pg0._get_capture(1)
1355 rx1 = self.pg1._get_capture(1)
1356 self.assertNotEqual(0, len(rx0))
1357 self.assertNotEqual(0, len(rx1))
1358
1359 def test_mpls_ebgp_pic(self):
1360 """ MPLS eBGP PIC edge convergence
1361
1362 1) setup many eBGP VPN routes via a pair of eBGP peers
1363 2) Check EMCP forwarding to these peers
1364 3) withdraw one eBGP path - expect LB across remaining eBGP
1365 """
1366
1367 #
1368 # Lot's of VPN routes. We need more the 64 so VPP will build
1369 # the fast convergence indirection
1370 #
1371 vpn_routes = []
1372 vpn_bindings = []
1373 pkts = []
1374 for ii in range(64):
1375 dst = "192.168.1.%d" % ii
1376 local_label = 1600 + ii
1377 vpn_routes.append(VppIpRoute(self, dst, 32,
1378 [VppRoutePath(self.pg2.remote_ip4,
1379 0xffffffff,
1380 nh_table_id=1,
1381 is_resolve_attached=1),
1382 VppRoutePath(self.pg3.remote_ip4,
1383 0xffffffff,
1384 nh_table_id=1,
1385 is_resolve_attached=1)],
1386 table_id=1))
1387 vpn_routes[ii].add_vpp_config()
1388
1389 vpn_bindings.append(VppMplsIpBind(self, local_label, dst, 32,
1390 ip_table_id=1))
1391 vpn_bindings[ii].add_vpp_config()
1392
1393 pkts.append(Ether(dst=self.pg0.local_mac,
1394 src=self.pg0.remote_mac) /
1395 MPLS(label=local_label, ttl=64) /
1396 IP(src=self.pg0.remote_ip4, dst=dst) /
1397 UDP(sport=1234, dport=1234) /
1398 Raw('\xa5' * 100))
1399
1400 self.pg0.add_stream(pkts)
1401 self.pg_enable_capture(self.pg_interfaces)
1402 self.pg_start()
1403
1404 rx0 = self.pg2._get_capture(1)
1405 rx1 = self.pg3._get_capture(1)
1406 self.assertNotEqual(0, len(rx0))
1407 self.assertNotEqual(0, len(rx1))
1408
1409 #
1410 # use a test CLI command to stop the FIB walk process, this
1411 # will prevent the FIB converging the VPN routes and thus allow
1412 # us to probe the interim (psot-fail, pre-converge) state
1413 #
1414 self.vapi.ppcli("test fib-walk-process disable")
1415
1416 #
1417 # withdraw the connected prefix on the interface.
1418 #
1419 self.pg2.unconfig_ip4()
1420
1421 #
1422 # now all packets should be forwarded through the remaining peer
1423 #
1424 self.pg0.add_stream(pkts)
1425 self.pg_enable_capture(self.pg_interfaces)
1426 self.pg_start()
1427
1428 rx0 = self.pg3.get_capture(len(pkts))
1429
1430 #
1431 # enable the FIB walk process to converge the FIB
1432 #
1433 self.vapi.ppcli("test fib-walk-process enable")
1434 self.pg0.add_stream(pkts)
1435 self.pg_enable_capture(self.pg_interfaces)
1436 self.pg_start()
1437
1438 rx0 = self.pg3.get_capture(len(pkts))
1439
1440 #
1441 # put the connecteds back
1442 #
1443 self.pg2.config_ip4()
1444
1445 self.pg0.add_stream(pkts)
1446 self.pg_enable_capture(self.pg_interfaces)
1447 self.pg_start()
1448
1449 rx0 = self.pg2._get_capture(1)
1450 rx1 = self.pg3._get_capture(1)
1451 self.assertNotEqual(0, len(rx0))
1452 self.assertNotEqual(0, len(rx1))
1453
1454 def test_mpls_v6_ebgp_pic(self):
1455 """ MPLSv6 eBGP PIC edge convergence
1456
1457 1) setup many eBGP VPNv6 routes via a pair of eBGP peers
1458 2) Check EMCP forwarding to these peers
1459 3) withdraw one eBGP path - expect LB across remaining eBGP
1460 """
1461
1462 #
1463 # Lot's of VPN routes. We need more the 64 so VPP will build
1464 # the fast convergence indirection
1465 #
1466 vpn_routes = []
1467 vpn_bindings = []
1468 pkts = []
1469 for ii in range(64):
1470 dst = "3000::%d" % ii
1471 local_label = 1600 + ii
Neale Rannsda78f952017-05-24 09:15:43 -07001472 vpn_routes.append(VppIpRoute(
1473 self, dst, 128,
1474 [VppRoutePath(self.pg2.remote_ip6,
1475 0xffffffff,
1476 nh_table_id=1,
1477 is_resolve_attached=1,
1478 proto=DpoProto.DPO_PROTO_IP6),
1479 VppRoutePath(self.pg3.remote_ip6,
1480 0xffffffff,
1481 nh_table_id=1,
1482 proto=DpoProto.DPO_PROTO_IP6,
1483 is_resolve_attached=1)],
1484 table_id=1,
1485 is_ip6=1))
Neale Rannsf12a83f2017-04-18 09:09:40 -07001486 vpn_routes[ii].add_vpp_config()
1487
1488 vpn_bindings.append(VppMplsIpBind(self, local_label, dst, 128,
1489 ip_table_id=1,
1490 is_ip6=1))
1491 vpn_bindings[ii].add_vpp_config()
1492
1493 pkts.append(Ether(dst=self.pg0.local_mac,
1494 src=self.pg0.remote_mac) /
1495 MPLS(label=local_label, ttl=64) /
1496 IPv6(src=self.pg0.remote_ip6, dst=dst) /
1497 UDP(sport=1234, dport=1234) /
1498 Raw('\xa5' * 100))
1499
1500 self.pg0.add_stream(pkts)
1501 self.pg_enable_capture(self.pg_interfaces)
1502 self.pg_start()
1503
1504 rx0 = self.pg2._get_capture(1)
1505 rx1 = self.pg3._get_capture(1)
1506 self.assertNotEqual(0, len(rx0))
1507 self.assertNotEqual(0, len(rx1))
1508
1509 #
1510 # use a test CLI command to stop the FIB walk process, this
1511 # will prevent the FIB converging the VPN routes and thus allow
1512 # us to probe the interim (psot-fail, pre-converge) state
1513 #
1514 self.vapi.ppcli("test fib-walk-process disable")
1515
1516 #
1517 # withdraw the connected prefix on the interface.
1518 # and shutdown the interface so the ND cache is flushed.
1519 #
1520 self.pg2.unconfig_ip6()
1521 self.pg2.admin_down()
1522
1523 #
1524 # now all packets should be forwarded through the remaining peer
1525 #
1526 self.pg0.add_stream(pkts)
1527 self.pg_enable_capture(self.pg_interfaces)
1528 self.pg_start()
1529
1530 rx0 = self.pg3.get_capture(len(pkts))
1531
1532 #
1533 # enable the FIB walk process to converge the FIB
1534 #
1535 self.vapi.ppcli("test fib-walk-process enable")
1536 self.pg0.add_stream(pkts)
1537 self.pg_enable_capture(self.pg_interfaces)
1538 self.pg_start()
1539
1540 rx0 = self.pg3.get_capture(len(pkts))
1541
1542 #
1543 # put the connecteds back
1544 #
1545 self.pg2.admin_up()
1546 self.pg2.config_ip6()
1547
1548 self.pg0.add_stream(pkts)
1549 self.pg_enable_capture(self.pg_interfaces)
1550 self.pg_start()
1551
1552 rx0 = self.pg2._get_capture(1)
1553 rx1 = self.pg3._get_capture(1)
1554 self.assertNotEqual(0, len(rx0))
1555 self.assertNotEqual(0, len(rx1))
1556
1557
Neale Rannsda78f952017-05-24 09:15:43 -07001558class TestMPLSL2(VppTestCase):
1559 """ MPLS-L2 """
1560
1561 def setUp(self):
1562 super(TestMPLSL2, self).setUp()
1563
1564 # create 2 pg interfaces
1565 self.create_pg_interfaces(range(2))
1566
Neale Ranns15002542017-09-10 04:39:11 -07001567 # create the default MPLS table
1568 self.tables = []
1569 tbl = VppMplsTable(self, 0)
1570 tbl.add_vpp_config()
1571 self.tables.append(tbl)
1572
Neale Rannsda78f952017-05-24 09:15:43 -07001573 # use pg0 as the core facing interface
1574 self.pg0.admin_up()
1575 self.pg0.config_ip4()
1576 self.pg0.resolve_arp()
1577 self.pg0.enable_mpls()
1578
Neale Ranns15002542017-09-10 04:39:11 -07001579 # use the other 2 for customer facing L2 links
Neale Rannsda78f952017-05-24 09:15:43 -07001580 for i in self.pg_interfaces[1:]:
1581 i.admin_up()
1582
1583 def tearDown(self):
Neale Rannsda78f952017-05-24 09:15:43 -07001584 for i in self.pg_interfaces[1:]:
1585 i.admin_down()
1586
1587 self.pg0.disable_mpls()
1588 self.pg0.unconfig_ip4()
1589 self.pg0.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -07001590 super(TestMPLSL2, self).tearDown()
Neale Rannsda78f952017-05-24 09:15:43 -07001591
1592 def verify_capture_tunneled_ethernet(self, capture, sent, mpls_labels,
1593 ttl=255, top=None):
1594 if top is None:
1595 top = len(mpls_labels) - 1
1596
1597 capture = verify_filter(capture, sent)
1598
1599 self.assertEqual(len(capture), len(sent))
1600
1601 for i in range(len(capture)):
1602 tx = sent[i]
1603 rx = capture[i]
1604
1605 # the MPLS TTL is 255 since it enters a new tunnel
1606 verify_mpls_stack(self, rx, mpls_labels, ttl, top)
1607
1608 tx_eth = tx[Ether]
1609 rx_eth = Ether(str(rx[MPLS].payload))
1610
1611 self.assertEqual(rx_eth.src, tx_eth.src)
1612 self.assertEqual(rx_eth.dst, tx_eth.dst)
1613
1614 def test_vpws(self):
1615 """ Virtual Private Wire Service """
1616
1617 #
1618 # Create an MPLS tunnel that pushes 1 label
1619 #
1620 mpls_tun_1 = VppMPLSTunnelInterface(self,
1621 [VppRoutePath(self.pg0.remote_ip4,
1622 self.pg0.sw_if_index,
1623 labels=[42])],
1624 is_l2=1)
1625 mpls_tun_1.add_vpp_config()
1626 mpls_tun_1.admin_up()
1627
1628 #
1629 # Create a label entry to for 55 that does L2 input to the tunnel
1630 #
1631 route_55_eos = VppMplsRoute(
1632 self, 55, 1,
1633 [VppRoutePath("0.0.0.0",
1634 mpls_tun_1.sw_if_index,
1635 is_interface_rx=1,
1636 proto=DpoProto.DPO_PROTO_ETHERNET)])
1637 route_55_eos.add_vpp_config()
1638
1639 #
1640 # Cross-connect the tunnel with one of the customers L2 interfaces
1641 #
1642 self.vapi.sw_interface_set_l2_xconnect(self.pg1.sw_if_index,
1643 mpls_tun_1.sw_if_index,
1644 enable=1)
1645 self.vapi.sw_interface_set_l2_xconnect(mpls_tun_1.sw_if_index,
1646 self.pg1.sw_if_index,
1647 enable=1)
1648
1649 #
1650 # inject a packet from the core
1651 #
1652 pcore = (Ether(dst=self.pg0.local_mac,
1653 src=self.pg0.remote_mac) /
1654 MPLS(label=55, ttl=64) /
1655 Ether(dst="00:00:de:ad:ba:be",
1656 src="00:00:de:ad:be:ef") /
1657 IP(src="10.10.10.10", dst="11.11.11.11") /
1658 UDP(sport=1234, dport=1234) /
1659 Raw('\xa5' * 100))
1660
1661 self.pg0.add_stream(pcore * 65)
1662 self.pg_enable_capture(self.pg_interfaces)
1663 self.pg_start()
1664
1665 rx0 = self.pg1.get_capture(65)
1666 tx = pcore[MPLS].payload
1667
1668 self.assertEqual(rx0[0][Ether].dst, tx[Ether].dst)
1669 self.assertEqual(rx0[0][Ether].src, tx[Ether].src)
1670
1671 #
1672 # Inject a packet from the custoer/L2 side
1673 #
1674 self.pg1.add_stream(tx * 65)
1675 self.pg_enable_capture(self.pg_interfaces)
1676 self.pg_start()
1677
1678 rx0 = self.pg0.get_capture(65)
1679
1680 self.verify_capture_tunneled_ethernet(rx0, tx*65, [42])
1681
1682 def test_vpls(self):
1683 """ Virtual Private LAN Service """
1684 #
1685 # Create an L2 MPLS tunnel
1686 #
1687 mpls_tun = VppMPLSTunnelInterface(self,
1688 [VppRoutePath(self.pg0.remote_ip4,
1689 self.pg0.sw_if_index,
1690 labels=[42])],
1691 is_l2=1)
1692 mpls_tun.add_vpp_config()
1693 mpls_tun.admin_up()
1694
1695 #
1696 # Create a label entry to for 55 that does L2 input to the tunnel
1697 #
1698 route_55_eos = VppMplsRoute(
1699 self, 55, 1,
1700 [VppRoutePath("0.0.0.0",
1701 mpls_tun.sw_if_index,
1702 is_interface_rx=1,
1703 proto=DpoProto.DPO_PROTO_ETHERNET)])
1704 route_55_eos.add_vpp_config()
1705
1706 #
1707 # add to tunnel to the customers bridge-domain
1708 #
1709 self.vapi.sw_interface_set_l2_bridge(mpls_tun.sw_if_index,
1710 bd_id=1)
1711 self.vapi.sw_interface_set_l2_bridge(self.pg1.sw_if_index,
1712 bd_id=1)
1713
1714 #
1715 # Packet from the customer interface and from the core
1716 #
1717 p_cust = (Ether(dst="00:00:de:ad:ba:be",
1718 src="00:00:de:ad:be:ef") /
1719 IP(src="10.10.10.10", dst="11.11.11.11") /
1720 UDP(sport=1234, dport=1234) /
1721 Raw('\xa5' * 100))
1722 p_core = (Ether(src="00:00:de:ad:ba:be",
1723 dst="00:00:de:ad:be:ef") /
1724 IP(dst="10.10.10.10", src="11.11.11.11") /
1725 UDP(sport=1234, dport=1234) /
1726 Raw('\xa5' * 100))
1727
1728 #
1729 # The BD is learning, so send in one of each packet to learn
1730 #
1731 p_core_encap = (Ether(dst=self.pg0.local_mac,
1732 src=self.pg0.remote_mac) /
1733 MPLS(label=55, ttl=64) /
1734 p_core)
1735
1736 self.pg1.add_stream(p_cust)
1737 self.pg_enable_capture(self.pg_interfaces)
1738 self.pg_start()
1739 self.pg0.add_stream(p_core_encap)
1740 self.pg_enable_capture(self.pg_interfaces)
1741 self.pg_start()
1742
1743 # we've learnt this so expect it be be forwarded
1744 rx0 = self.pg1.get_capture(1)
1745
1746 self.assertEqual(rx0[0][Ether].dst, p_core[Ether].dst)
1747 self.assertEqual(rx0[0][Ether].src, p_core[Ether].src)
1748
1749 #
1750 # now a stream in each direction
1751 #
1752 self.pg1.add_stream(p_cust * 65)
1753 self.pg_enable_capture(self.pg_interfaces)
1754 self.pg_start()
1755
1756 rx0 = self.pg0.get_capture(65)
1757
1758 self.verify_capture_tunneled_ethernet(rx0, p_cust*65, [42])
1759
1760 #
1761 # remove interfaces from customers bridge-domain
1762 #
1763 self.vapi.sw_interface_set_l2_bridge(mpls_tun.sw_if_index,
1764 bd_id=1,
1765 enable=0)
1766 self.vapi.sw_interface_set_l2_bridge(self.pg1.sw_if_index,
1767 bd_id=1,
1768 enable=0)
1769
Neale Ranns8fe8cc22016-11-01 10:05:08 +00001770if __name__ == '__main__':
1771 unittest.main(testRunner=VppTestRunner)