blob: c4f64bdbdddffd4ecd8b658cef54b225beeb0c58 [file] [log] [blame]
Neale Rannsd792d9c2017-10-21 10:53:20 -07001#!/usr/bin/env python
2
3import unittest
4import socket
5
Neale Rannsf0510722018-01-31 11:35:41 -08006from framework import VppTestCase, VppTestRunner, running_extended_tests
Neale Rannsd792d9c2017-10-21 10:53:20 -07007from vpp_ip_route import VppIpRoute, VppRoutePath, VppMplsRoute, \
8 VppMplsTable, VppIpMRoute, VppMRoutePath, VppIpTable, \
Neale Ranns31ed7442018-02-23 05:29:09 -08009 MRouteEntryFlags, MRouteItfFlags, MPLS_LABEL_INVALID, DpoProto, \
10 VppMplsLabel
Neale Rannsd792d9c2017-10-21 10:53:20 -070011from vpp_bier import *
Neale Ranns91286372017-12-05 13:24:04 -080012from vpp_udp_encap import *
Neale Rannsd792d9c2017-10-21 10:53:20 -070013
14from scapy.packet import Raw
15from scapy.layers.l2 import Ether
16from scapy.layers.inet import IP, UDP, ICMP
17from scapy.layers.inet6 import IPv6
18from scapy.contrib.mpls import MPLS
19from scapy.contrib.bier import *
20
21
22class TestBFIB(VppTestCase):
23 """ BIER FIB Test Case """
24
25 def test_bfib(self):
26 """ BFIB Unit Tests """
27 error = self.vapi.cli("test bier")
28
29 if error:
30 self.logger.critical(error)
31 self.assertEqual(error.find("Failed"), -1)
32
33
34class TestBier(VppTestCase):
35 """ BIER Test Case """
36
37 def setUp(self):
38 super(TestBier, self).setUp()
39
40 # create 2 pg interfaces
41 self.create_pg_interfaces(range(3))
42
43 # create the default MPLS table
44 self.tables = []
45 tbl = VppMplsTable(self, 0)
46 tbl.add_vpp_config()
47 self.tables.append(tbl)
48
49 tbl = VppIpTable(self, 10)
50 tbl.add_vpp_config()
51 self.tables.append(tbl)
52
53 # setup both interfaces
54 for i in self.pg_interfaces:
55 if i == self.pg2:
56 i.set_table_ip4(10)
57 i.admin_up()
58 i.config_ip4()
59 i.resolve_arp()
60 i.enable_mpls()
61
62 def tearDown(self):
63 for i in self.pg_interfaces:
64 i.disable_mpls()
65 i.unconfig_ip4()
66 i.set_table_ip4(0)
67 i.admin_down()
68 super(TestBier, self).tearDown()
69
Neale Rannsf0510722018-01-31 11:35:41 -080070 def bier_midpoint(self, hdr_len_id, n_bytes, max_bp):
Neale Rannsd792d9c2017-10-21 10:53:20 -070071 """BIER midpoint"""
72
73 #
74 # Add a BIER table for sub-domain 0, set 0, and BSL 256
75 #
Neale Rannsf0510722018-01-31 11:35:41 -080076 bti = VppBierTableID(0, 0, hdr_len_id)
Neale Rannsd792d9c2017-10-21 10:53:20 -070077 bt = VppBierTable(self, bti, 77)
78 bt.add_vpp_config()
79
80 #
81 # A packet with no bits set gets dropped
82 #
83 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
84 MPLS(label=77, ttl=255) /
Neale Rannsf0510722018-01-31 11:35:41 -080085 BIER(length=hdr_len_id) /
Neale Rannsd792d9c2017-10-21 10:53:20 -070086 IPv6(src=self.pg0.remote_ip6, dst=self.pg0.remote_ip6) /
87 UDP(sport=1234, dport=1234) /
88 Raw())
89 pkts = [p]
90
91 self.send_and_assert_no_replies(self.pg0, pkts,
92 "Empty Bit-String")
93
94 #
95 # Add a BIER route for each bit-position in the table via a different
96 # next-hop. Testing whether the BIER walk and replicate forwarding
97 # function works for all bit posisitons.
98 #
99 nh_routes = []
100 bier_routes = []
Neale Rannsf0510722018-01-31 11:35:41 -0800101 for i in range(1, max_bp+1):
Neale Rannsd792d9c2017-10-21 10:53:20 -0700102 nh = "10.0.%d.%d" % (i / 255, i % 255)
Neale Ranns31ed7442018-02-23 05:29:09 -0800103 nh_routes.append(
104 VppIpRoute(self, nh, 32,
105 [VppRoutePath(self.pg1.remote_ip4,
106 self.pg1.sw_if_index,
107 labels=[VppMplsLabel(2000+i)])]))
Neale Rannsd792d9c2017-10-21 10:53:20 -0700108 nh_routes[-1].add_vpp_config()
109
Neale Ranns31ed7442018-02-23 05:29:09 -0800110 bier_routes.append(
111 VppBierRoute(self, bti, i,
112 [VppRoutePath(nh, 0xffffffff,
113 labels=[VppMplsLabel(100+i)])]))
Neale Rannsd792d9c2017-10-21 10:53:20 -0700114 bier_routes[-1].add_vpp_config()
115
116 #
Neale Rannsf0510722018-01-31 11:35:41 -0800117 # A packet with all bits set gets replicated once for each bit
Neale Rannsd792d9c2017-10-21 10:53:20 -0700118 #
Neale Rannsf0510722018-01-31 11:35:41 -0800119 pkt_sizes = [64, 1400]
Neale Rannsd792d9c2017-10-21 10:53:20 -0700120
Neale Rannsf0510722018-01-31 11:35:41 -0800121 for pkt_size in pkt_sizes:
122 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
123 MPLS(label=77, ttl=255) /
124 BIER(length=hdr_len_id, BitString=chr(255)*n_bytes) /
125 IPv6(src=self.pg0.remote_ip6, dst=self.pg0.remote_ip6) /
126 UDP(sport=1234, dport=1234) /
127 Raw(chr(5) * pkt_size))
128 pkts = p
Neale Rannsd792d9c2017-10-21 10:53:20 -0700129
Neale Rannsf0510722018-01-31 11:35:41 -0800130 self.pg0.add_stream(pkts)
131 self.pg_enable_capture(self.pg_interfaces)
132 self.pg_start()
Neale Rannsd792d9c2017-10-21 10:53:20 -0700133
Neale Rannsf0510722018-01-31 11:35:41 -0800134 rx = self.pg1.get_capture(max_bp)
Neale Rannsd792d9c2017-10-21 10:53:20 -0700135
Neale Rannsf0510722018-01-31 11:35:41 -0800136 for rxp in rx:
137 #
138 # The packets are not required to be sent in bit-position order
139 # when we setup the routes above we used the bit-position to
140 # construct the out-label. so use that here to determine the BP
141 #
142 olabel = rxp[MPLS]
143 bp = olabel.label - 2000
Neale Rannsd792d9c2017-10-21 10:53:20 -0700144
Neale Rannsf0510722018-01-31 11:35:41 -0800145 blabel = olabel[MPLS].payload
146 self.assertEqual(blabel.label, 100+bp)
147 self.assertEqual(blabel.ttl, 254)
Neale Rannsd792d9c2017-10-21 10:53:20 -0700148
Neale Rannsf0510722018-01-31 11:35:41 -0800149 bier_hdr = blabel[MPLS].payload
Neale Rannsd792d9c2017-10-21 10:53:20 -0700150
Neale Rannsf0510722018-01-31 11:35:41 -0800151 self.assertEqual(bier_hdr.id, 5)
152 self.assertEqual(bier_hdr.version, 0)
153 self.assertEqual(bier_hdr.length, hdr_len_id)
154 self.assertEqual(bier_hdr.entropy, 0)
155 self.assertEqual(bier_hdr.OAM, 0)
156 self.assertEqual(bier_hdr.RSV, 0)
157 self.assertEqual(bier_hdr.DSCP, 0)
158 self.assertEqual(bier_hdr.Proto, 5)
Neale Rannsd792d9c2017-10-21 10:53:20 -0700159
Neale Rannsf0510722018-01-31 11:35:41 -0800160 # The bit-string should consist only of the BP given by i.
161 byte_array = ['\0'] * (n_bytes)
162 byte_val = chr(1 << (bp - 1) % 8)
163 byte_pos = n_bytes - (((bp - 1) / 8) + 1)
164 byte_array[byte_pos] = byte_val
165 bitstring = ''.join(byte_array)
Neale Rannsd792d9c2017-10-21 10:53:20 -0700166
Neale Rannsf0510722018-01-31 11:35:41 -0800167 self.assertEqual(len(bitstring), len(bier_hdr.BitString))
168 self.assertEqual(bitstring, bier_hdr.BitString)
169
170 #
171 # cleanup. not strictly necessary, but it's much quicker this way
172 # becuase the bier_fib_dump and ip_fib_dump will be empty when the
173 # auto-cleanup kicks in
174 #
175 for br in bier_routes:
176 br.remove_vpp_config()
177 for nhr in nh_routes:
178 nhr.remove_vpp_config()
179
180 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
181 def test_bier_midpoint_1024(self):
182 """BIER midpoint BSL:1024"""
183 self.bier_midpoint(BIERLength.BIER_LEN_1024, 128, 1024)
184
185 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
186 def test_bier_midpoint_512(self):
187 """BIER midpoint BSL:512"""
188 self.bier_midpoint(BIERLength.BIER_LEN_512, 64, 512)
189
190 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
191 def test_bier_midpoint_256(self):
192 """BIER midpoint BSL:256"""
193 self.bier_midpoint(BIERLength.BIER_LEN_256, 32, 256)
194
195 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
196 def test_bier_midpoint_128(self):
197 """BIER midpoint BSL:128"""
198 self.bier_midpoint(BIERLength.BIER_LEN_128, 16, 128)
199
200 def test_bier_midpoint_64(self):
Neale Rannsc819fc62018-02-16 02:44:05 -0800201 """BIER midpoint BSL:64"""
Neale Rannsf0510722018-01-31 11:35:41 -0800202 self.bier_midpoint(BIERLength.BIER_LEN_64, 8, 64)
Neale Rannsd792d9c2017-10-21 10:53:20 -0700203
204 def test_bier_head(self):
205 """BIER head"""
206
207 #
208 # Add a BIER table for sub-domain 0, set 0, and BSL 256
209 #
210 bti = VppBierTableID(0, 0, BIERLength.BIER_LEN_256)
211 bt = VppBierTable(self, bti, 77)
212 bt.add_vpp_config()
213
214 #
215 # 2 bit positions via two next hops
216 #
217 nh1 = "10.0.0.1"
218 nh2 = "10.0.0.2"
219 ip_route_1 = VppIpRoute(self, nh1, 32,
220 [VppRoutePath(self.pg1.remote_ip4,
221 self.pg1.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800222 labels=[VppMplsLabel(2001)])])
Neale Rannsd792d9c2017-10-21 10:53:20 -0700223 ip_route_2 = VppIpRoute(self, nh2, 32,
224 [VppRoutePath(self.pg1.remote_ip4,
225 self.pg1.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800226 labels=[VppMplsLabel(2002)])])
Neale Rannsd792d9c2017-10-21 10:53:20 -0700227 ip_route_1.add_vpp_config()
228 ip_route_2.add_vpp_config()
229
Neale Ranns91286372017-12-05 13:24:04 -0800230 bier_route_1 = VppBierRoute(self, bti, 1,
231 [VppRoutePath(nh1, 0xffffffff,
Neale Ranns31ed7442018-02-23 05:29:09 -0800232 labels=[VppMplsLabel(101)])])
Neale Ranns91286372017-12-05 13:24:04 -0800233 bier_route_2 = VppBierRoute(self, bti, 2,
234 [VppRoutePath(nh2, 0xffffffff,
Neale Ranns31ed7442018-02-23 05:29:09 -0800235 labels=[VppMplsLabel(102)])])
Neale Rannsd792d9c2017-10-21 10:53:20 -0700236 bier_route_1.add_vpp_config()
237 bier_route_2.add_vpp_config()
238
239 #
240 # An imposition object with both bit-positions set
241 #
242 bi = VppBierImp(self, bti, 333, chr(0x3) * 32)
243 bi.add_vpp_config()
244
245 #
246 # Add a multicast route that will forward into the BIER doamin
247 #
248 route_ing_232_1_1_1 = VppIpMRoute(
249 self,
250 "0.0.0.0",
251 "232.1.1.1", 32,
252 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
253 paths=[VppMRoutePath(self.pg0.sw_if_index,
254 MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
255 VppMRoutePath(0xffffffff,
256 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD,
257 proto=DpoProto.DPO_PROTO_BIER,
258 bier_imp=bi.bi_index)])
259 route_ing_232_1_1_1.add_vpp_config()
260
261 #
Neale Ranns91286372017-12-05 13:24:04 -0800262 # inject an IP packet. We expect it to be BIER encapped and
Neale Rannsd792d9c2017-10-21 10:53:20 -0700263 # replicated.
264 #
265 p = (Ether(dst=self.pg0.local_mac,
266 src=self.pg0.remote_mac) /
267 IP(src="1.1.1.1", dst="232.1.1.1") /
268 UDP(sport=1234, dport=1234))
269
270 self.pg0.add_stream([p])
271 self.pg_enable_capture(self.pg_interfaces)
272 self.pg_start()
273
274 rx = self.pg1.get_capture(2)
275
Neale Ranns91286372017-12-05 13:24:04 -0800276 #
277 # Encap Stack is; eth, MPLS, MPLS, BIER
278 #
279 igp_mpls = rx[0][MPLS]
280 self.assertEqual(igp_mpls.label, 2001)
281 self.assertEqual(igp_mpls.ttl, 64)
282 self.assertEqual(igp_mpls.s, 0)
283 bier_mpls = igp_mpls[MPLS].payload
284 self.assertEqual(bier_mpls.label, 101)
285 self.assertEqual(bier_mpls.ttl, 64)
286 self.assertEqual(bier_mpls.s, 1)
287 self.assertEqual(rx[0][BIER].length, 2)
288
289 igp_mpls = rx[1][MPLS]
290 self.assertEqual(igp_mpls.label, 2002)
291 self.assertEqual(igp_mpls.ttl, 64)
292 self.assertEqual(igp_mpls.s, 0)
293 bier_mpls = igp_mpls[MPLS].payload
294 self.assertEqual(bier_mpls.label, 102)
295 self.assertEqual(bier_mpls.ttl, 64)
296 self.assertEqual(bier_mpls.s, 1)
297 self.assertEqual(rx[0][BIER].length, 2)
298
Neale Rannsd792d9c2017-10-21 10:53:20 -0700299 def test_bier_tail(self):
300 """BIER Tail"""
301
302 #
303 # Add a BIER table for sub-domain 0, set 0, and BSL 256
304 #
305 bti = VppBierTableID(0, 0, BIERLength.BIER_LEN_256)
306 bt = VppBierTable(self, bti, 77)
307 bt.add_vpp_config()
308
309 #
310 # disposition table
311 #
312 bdt = VppBierDispTable(self, 8)
313 bdt.add_vpp_config()
314
315 #
316 # BIER route in table that's for-us
317 #
Neale Ranns2303cb12018-02-21 04:57:17 -0800318 bier_route_1 = VppBierRoute(
319 self, bti, 1,
320 [VppRoutePath("0.0.0.0",
321 0xffffffff,
322 proto=DpoProto.DPO_PROTO_BIER,
323 nh_table_id=8)])
Neale Rannsd792d9c2017-10-21 10:53:20 -0700324 bier_route_1.add_vpp_config()
325
326 #
327 # An entry in the disposition table
328 #
329 bier_de_1 = VppBierDispEntry(self, bdt.id, 99,
330 BIER_HDR_PAYLOAD.BIER_HDR_PROTO_IPV4,
Neale Rannsf0510722018-01-31 11:35:41 -0800331 DpoProto.DPO_PROTO_BIER,
Neale Rannsd792d9c2017-10-21 10:53:20 -0700332 "0.0.0.0", 0, rpf_id=8192)
333 bier_de_1.add_vpp_config()
334
335 #
336 # A multicast route to forward post BIER disposition
337 #
338 route_eg_232_1_1_1 = VppIpMRoute(
339 self,
340 "0.0.0.0",
341 "232.1.1.1", 32,
342 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
343 paths=[VppMRoutePath(self.pg1.sw_if_index,
344 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
345 route_eg_232_1_1_1.add_vpp_config()
346 route_eg_232_1_1_1.update_rpf_id(8192)
347
348 #
349 # A packet with all bits set gets spat out to BP:1
350 #
351 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
352 MPLS(label=77, ttl=255) /
Neale Rannsf0510722018-01-31 11:35:41 -0800353 BIER(length=BIERLength.BIER_LEN_256,
354 BitString=chr(255)*32,
355 BFRID=99) /
Neale Rannsd792d9c2017-10-21 10:53:20 -0700356 IP(src="1.1.1.1", dst="232.1.1.1") /
357 UDP(sport=1234, dport=1234) /
358 Raw())
359
360 self.send_and_expect(self.pg0, [p], self.pg1)
361
Neale Rannsceb4d052017-12-13 09:13:41 -0800362 #
363 # A packet that does not match the Disposition entry gets dropped
364 #
365 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
366 MPLS(label=77, ttl=255) /
Neale Rannsf0510722018-01-31 11:35:41 -0800367 BIER(length=BIERLength.BIER_LEN_256,
368 BitString=chr(255)*32,
369 BFRID=77) /
Neale Rannsceb4d052017-12-13 09:13:41 -0800370 IP(src="1.1.1.1", dst="232.1.1.1") /
371 UDP(sport=1234, dport=1234) /
372 Raw())
373 self.send_and_assert_no_replies(self.pg0, p*2,
374 "no matching disposition entry")
375
376 #
377 # Add the default route to the disposition table
378 #
379 bier_de_2 = VppBierDispEntry(self, bdt.id, 0,
380 BIER_HDR_PAYLOAD.BIER_HDR_PROTO_IPV4,
Neale Rannsf0510722018-01-31 11:35:41 -0800381 DpoProto.DPO_PROTO_BIER,
Neale Rannsceb4d052017-12-13 09:13:41 -0800382 "0.0.0.0", 0, rpf_id=8192)
383 bier_de_2.add_vpp_config()
384
385 #
386 # now the previous packet is forwarded
387 #
388 self.send_and_expect(self.pg0, [p], self.pg1)
389
Neale Rannsf0510722018-01-31 11:35:41 -0800390 def bier_e2e(self, hdr_len_id, n_bytes, max_bp):
391 """ BIER end-to-end"""
Neale Rannsd792d9c2017-10-21 10:53:20 -0700392
393 #
394 # Add a BIER table for sub-domain 0, set 0, and BSL 256
395 #
Neale Rannsf0510722018-01-31 11:35:41 -0800396 bti = VppBierTableID(0, 0, hdr_len_id)
Neale Rannsd792d9c2017-10-21 10:53:20 -0700397 bt = VppBierTable(self, bti, 77)
398 bt.add_vpp_config()
399
Neale Rannsf0510722018-01-31 11:35:41 -0800400 lowest = ['\0'] * (n_bytes)
401 lowest[-1] = chr(1)
402 highest = ['\0'] * (n_bytes)
403 highest[0] = chr(128)
404
Neale Rannsd792d9c2017-10-21 10:53:20 -0700405 #
Neale Rannsf0510722018-01-31 11:35:41 -0800406 # Impostion Sets bit strings
Neale Rannsd792d9c2017-10-21 10:53:20 -0700407 #
Neale Rannsf0510722018-01-31 11:35:41 -0800408 bi_low = VppBierImp(self, bti, 333, lowest)
409 bi_low.add_vpp_config()
410 bi_high = VppBierImp(self, bti, 334, highest)
411 bi_high.add_vpp_config()
Neale Rannsd792d9c2017-10-21 10:53:20 -0700412
413 #
414 # Add a multicast route that will forward into the BIER doamin
415 #
416 route_ing_232_1_1_1 = VppIpMRoute(
417 self,
418 "0.0.0.0",
419 "232.1.1.1", 32,
420 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
421 paths=[VppMRoutePath(self.pg0.sw_if_index,
422 MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
423 VppMRoutePath(0xffffffff,
424 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD,
425 proto=DpoProto.DPO_PROTO_BIER,
Neale Rannsf0510722018-01-31 11:35:41 -0800426 bier_imp=bi_low.bi_index)])
Neale Rannsd792d9c2017-10-21 10:53:20 -0700427 route_ing_232_1_1_1.add_vpp_config()
Neale Rannsf0510722018-01-31 11:35:41 -0800428 route_ing_232_1_1_2 = VppIpMRoute(
429 self,
430 "0.0.0.0",
431 "232.1.1.2", 32,
432 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
433 paths=[VppMRoutePath(self.pg0.sw_if_index,
434 MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
435 VppMRoutePath(0xffffffff,
436 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD,
437 proto=DpoProto.DPO_PROTO_BIER,
438 bier_imp=bi_high.bi_index)])
439 route_ing_232_1_1_2.add_vpp_config()
Neale Rannsd792d9c2017-10-21 10:53:20 -0700440
441 #
442 # disposition table 8
443 #
444 bdt = VppBierDispTable(self, 8)
445 bdt.add_vpp_config()
446
447 #
Neale Rannsf0510722018-01-31 11:35:41 -0800448 # BIER routes in table that are for-us, resolving through
Neale Rannsd792d9c2017-10-21 10:53:20 -0700449 # disp table 8.
450 #
Neale Ranns2303cb12018-02-21 04:57:17 -0800451 bier_route_1 = VppBierRoute(
452 self, bti, 1,
453 [VppRoutePath("0.0.0.0",
454 0xffffffff,
455 proto=DpoProto.DPO_PROTO_BIER,
456 nh_table_id=8)])
Neale Rannsd792d9c2017-10-21 10:53:20 -0700457 bier_route_1.add_vpp_config()
Neale Rannsf0510722018-01-31 11:35:41 -0800458 bier_route_max = VppBierRoute(self, bti, max_bp,
459 [VppRoutePath("0.0.0.0",
460 0xffffffff,
461 nh_table_id=8)])
462 bier_route_max.add_vpp_config()
Neale Rannsd792d9c2017-10-21 10:53:20 -0700463
464 #
465 # An entry in the disposition table for sender 333
466 # lookup in VRF 10
467 #
468 bier_de_1 = VppBierDispEntry(self, bdt.id, 333,
469 BIER_HDR_PAYLOAD.BIER_HDR_PROTO_IPV4,
Neale Rannsf0510722018-01-31 11:35:41 -0800470 DpoProto.DPO_PROTO_BIER,
Neale Rannsd792d9c2017-10-21 10:53:20 -0700471 "0.0.0.0", 10, rpf_id=8192)
472 bier_de_1.add_vpp_config()
Neale Rannsf0510722018-01-31 11:35:41 -0800473 bier_de_1 = VppBierDispEntry(self, bdt.id, 334,
474 BIER_HDR_PAYLOAD.BIER_HDR_PROTO_IPV4,
475 DpoProto.DPO_PROTO_BIER,
476 "0.0.0.0", 10, rpf_id=8193)
477 bier_de_1.add_vpp_config()
Neale Rannsd792d9c2017-10-21 10:53:20 -0700478
479 #
Neale Rannsf0510722018-01-31 11:35:41 -0800480 # Add a multicast routes that will forward the traffic
Neale Rannsd792d9c2017-10-21 10:53:20 -0700481 # post-disposition
482 #
483 route_eg_232_1_1_1 = VppIpMRoute(
484 self,
485 "0.0.0.0",
486 "232.1.1.1", 32,
487 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
488 table_id=10,
489 paths=[VppMRoutePath(self.pg1.sw_if_index,
490 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
491 route_eg_232_1_1_1.add_vpp_config()
492 route_eg_232_1_1_1.update_rpf_id(8192)
Neale Rannsf0510722018-01-31 11:35:41 -0800493 route_eg_232_1_1_2 = VppIpMRoute(
494 self,
495 "0.0.0.0",
496 "232.1.1.2", 32,
497 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
498 table_id=10,
499 paths=[VppMRoutePath(self.pg1.sw_if_index,
500 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
501 route_eg_232_1_1_2.add_vpp_config()
502 route_eg_232_1_1_2.update_rpf_id(8193)
Neale Rannsd792d9c2017-10-21 10:53:20 -0700503
504 #
505 # inject a packet in VRF-0. We expect it to be BIER encapped,
506 # replicated, then hit the disposition and be forwarded
507 # out of VRF 10, i.e. on pg1
508 #
509 p = (Ether(dst=self.pg0.local_mac,
510 src=self.pg0.remote_mac) /
511 IP(src="1.1.1.1", dst="232.1.1.1") /
Neale Rannsf0510722018-01-31 11:35:41 -0800512 UDP(sport=1234, dport=1234) /
513 Raw(chr(5) * 32))
Neale Rannsd792d9c2017-10-21 10:53:20 -0700514
Neale Ranns91286372017-12-05 13:24:04 -0800515 rx = self.send_and_expect(self.pg0, p*65, self.pg1)
516
Neale Ranns91286372017-12-05 13:24:04 -0800517 self.assertEqual(rx[0][IP].src, "1.1.1.1")
518 self.assertEqual(rx[0][IP].dst, "232.1.1.1")
519
Neale Rannsf0510722018-01-31 11:35:41 -0800520 p = (Ether(dst=self.pg0.local_mac,
521 src=self.pg0.remote_mac) /
522 IP(src="1.1.1.1", dst="232.1.1.2") /
523 UDP(sport=1234, dport=1234) /
524 Raw(chr(5) * 512))
525
526 rx = self.send_and_expect(self.pg0, p*65, self.pg1)
527 self.assertEqual(rx[0][IP].src, "1.1.1.1")
528 self.assertEqual(rx[0][IP].dst, "232.1.1.2")
529
530 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
531 def test_bier_e2e_1024(self):
532 """ BIER end-to-end BSL:1024"""
533 self.bier_e2e(BIERLength.BIER_LEN_1024, 128, 1024)
534
535 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
536 def test_bier_e2e_512(self):
537 """ BIER end-to-end BSL:512"""
538 self.bier_e2e(BIERLength.BIER_LEN_512, 64, 512)
539
540 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
541 def test_bier_e2e_256(self):
542 """ BIER end-to-end BSL:256"""
543 self.bier_e2e(BIERLength.BIER_LEN_256, 32, 256)
544
545 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
546 def test_bier_e2e_128(self):
547 """ BIER end-to-end BSL:128"""
548 self.bier_e2e(BIERLength.BIER_LEN_128, 16, 128)
549
550 def test_bier_e2e_64(self):
551 """ BIER end-to-end BSL:64"""
552 self.bier_e2e(BIERLength.BIER_LEN_64, 8, 64)
553
Neale Ranns91286372017-12-05 13:24:04 -0800554 def test_bier_head_o_udp(self):
555 """BIER head over UDP"""
556
557 #
558 # Add a BIER table for sub-domain 1, set 0, and BSL 256
559 #
560 bti = VppBierTableID(1, 0, BIERLength.BIER_LEN_256)
561 bt = VppBierTable(self, bti, 77)
562 bt.add_vpp_config()
563
564 #
565 # 1 bit positions via 1 next hops
566 #
567 nh1 = "10.0.0.1"
568 ip_route = VppIpRoute(self, nh1, 32,
569 [VppRoutePath(self.pg1.remote_ip4,
570 self.pg1.sw_if_index,
Neale Ranns31ed7442018-02-23 05:29:09 -0800571 labels=[VppMplsLabel(2001)])])
Neale Ranns91286372017-12-05 13:24:04 -0800572 ip_route.add_vpp_config()
573
574 udp_encap = VppUdpEncap(self, 4,
575 self.pg0.local_ip4,
576 nh1,
577 330, 8138)
578 udp_encap.add_vpp_config()
579
Neale Ranns2303cb12018-02-21 04:57:17 -0800580 bier_route = VppBierRoute(
581 self, bti, 1,
582 [VppRoutePath("0.0.0.0",
583 0xFFFFFFFF,
584 is_udp_encap=1,
585 next_hop_id=4)])
Neale Ranns91286372017-12-05 13:24:04 -0800586 bier_route.add_vpp_config()
587
588 #
Neale Rannseea537a2018-01-09 04:11:28 -0800589 # An 2 imposition objects with all bit-positions set
590 # only use the second, but creating 2 tests with a non-zero
591 # value index in the route add
Neale Ranns91286372017-12-05 13:24:04 -0800592 #
593 bi = VppBierImp(self, bti, 333, chr(0xff) * 32)
594 bi.add_vpp_config()
Neale Rannseea537a2018-01-09 04:11:28 -0800595 bi2 = VppBierImp(self, bti, 334, chr(0xff) * 32)
596 bi2.add_vpp_config()
Neale Ranns91286372017-12-05 13:24:04 -0800597
598 #
599 # Add a multicast route that will forward into the BIER doamin
600 #
601 route_ing_232_1_1_1 = VppIpMRoute(
602 self,
603 "0.0.0.0",
604 "232.1.1.1", 32,
605 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
606 paths=[VppMRoutePath(self.pg0.sw_if_index,
607 MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
608 VppMRoutePath(0xffffffff,
609 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD,
610 proto=DpoProto.DPO_PROTO_BIER,
Neale Rannseea537a2018-01-09 04:11:28 -0800611 bier_imp=bi2.bi_index)])
Neale Ranns91286372017-12-05 13:24:04 -0800612 route_ing_232_1_1_1.add_vpp_config()
613
614 #
615 # inject a packet an IP. We expect it to be BIER and UDP encapped,
616 #
617 p = (Ether(dst=self.pg0.local_mac,
618 src=self.pg0.remote_mac) /
619 IP(src="1.1.1.1", dst="232.1.1.1") /
620 UDP(sport=1234, dport=1234))
621
622 self.pg0.add_stream([p])
623 self.pg_enable_capture(self.pg_interfaces)
624 self.pg_start()
625
626 rx = self.pg1.get_capture(1)
627
628 #
629 # Encap Stack is, eth, IP, UDP, BIFT, BIER
630 #
631 self.assertEqual(rx[0][IP].src, self.pg0.local_ip4)
632 self.assertEqual(rx[0][IP].dst, nh1)
633 self.assertEqual(rx[0][UDP].sport, 330)
634 self.assertEqual(rx[0][UDP].dport, 8138)
635 self.assertEqual(rx[0][BIFT].bsl, 2)
636 self.assertEqual(rx[0][BIFT].sd, 1)
637 self.assertEqual(rx[0][BIFT].set, 0)
638 self.assertEqual(rx[0][BIFT].ttl, 64)
639 self.assertEqual(rx[0][BIER].length, 2)
640
641 def test_bier_tail_o_udp(self):
642 """BIER Tail over UDP"""
643
644 #
645 # Add a BIER table for sub-domain 0, set 0, and BSL 256
646 #
647 bti = VppBierTableID(1, 0, BIERLength.BIER_LEN_256)
648 bt = VppBierTable(self, bti, MPLS_LABEL_INVALID)
649 bt.add_vpp_config()
650
651 #
652 # disposition table
653 #
654 bdt = VppBierDispTable(self, 8)
655 bdt.add_vpp_config()
656
657 #
658 # BIER route in table that's for-us
659 #
Neale Ranns2303cb12018-02-21 04:57:17 -0800660 bier_route_1 = VppBierRoute(
661 self, bti, 1,
662 [VppRoutePath("0.0.0.0",
663 0xffffffff,
664 proto=DpoProto.DPO_PROTO_BIER,
665 nh_table_id=8)])
Neale Ranns91286372017-12-05 13:24:04 -0800666 bier_route_1.add_vpp_config()
667
668 #
669 # An entry in the disposition table
670 #
671 bier_de_1 = VppBierDispEntry(self, bdt.id, 99,
672 BIER_HDR_PAYLOAD.BIER_HDR_PROTO_IPV4,
Neale Rannsf0510722018-01-31 11:35:41 -0800673 DpoProto.DPO_PROTO_BIER,
Neale Ranns91286372017-12-05 13:24:04 -0800674 "0.0.0.0", 0, rpf_id=8192)
675 bier_de_1.add_vpp_config()
676
677 #
678 # A multicast route to forward post BIER disposition
679 #
680 route_eg_232_1_1_1 = VppIpMRoute(
681 self,
682 "0.0.0.0",
683 "232.1.1.1", 32,
684 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
685 paths=[VppMRoutePath(self.pg1.sw_if_index,
686 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
687 route_eg_232_1_1_1.add_vpp_config()
688 route_eg_232_1_1_1.update_rpf_id(8192)
689
690 #
691 # A packet with all bits set gets spat out to BP:1
692 #
693 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
694 IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) /
695 UDP(sport=333, dport=8138) /
696 BIFT(sd=1, set=0, bsl=2, ttl=255) /
Neale Rannsf0510722018-01-31 11:35:41 -0800697 BIER(length=BIERLength.BIER_LEN_256,
698 BitString=chr(255)*32,
699 BFRID=99) /
Neale Ranns91286372017-12-05 13:24:04 -0800700 IP(src="1.1.1.1", dst="232.1.1.1") /
701 UDP(sport=1234, dport=1234) /
702 Raw())
703
704 rx = self.send_and_expect(self.pg0, [p], self.pg1)
Neale Rannsd792d9c2017-10-21 10:53:20 -0700705
706
707if __name__ == '__main__':
708 unittest.main(testRunner=VppTestRunner)