blob: d0ca1f6f16188cf6b838cad11097f9c28e85f27c [file] [log] [blame]
Renato Botelho do Coutoead1e532019-10-31 13:31:07 -05001#!/usr/bin/env python3
Neale Ranns32e1c012016-11-22 17:07:28 +00002
3import unittest
4
5from framework import VppTestCase, VppTestRunner
Neale Rannsc0a93142018-09-05 15:42:26 -07006from vpp_ip import DpoProto
Neale Ranns180279b2017-03-16 15:49:09 -04007from vpp_ip_route import VppIpMRoute, VppMRoutePath, VppMFibSignal, \
Neale Ranns990f6942020-10-20 07:20:17 +00008 VppIpTable, FibPathProto
Neale Rannsadb17a82019-08-04 02:41:57 -07009from vpp_gre_interface import VppGreInterface
Neale Ranns990f6942020-10-20 07:20:17 +000010from vpp_papi import VppEnum
Neale Ranns32e1c012016-11-22 17:07:28 +000011
12from scapy.packet import Raw
Neale Rannsadb17a82019-08-04 02:41:57 -070013from scapy.layers.l2 import Ether, GRE
Klement Sekerab9ef2732018-06-24 22:49:33 +020014from scapy.layers.inet import IP, UDP, getmacbyip
Neale Ranns32e1c012016-11-22 17:07:28 +000015from scapy.layers.inet6 import IPv6, getmacbyip6
Neale Ranns32e1c012016-11-22 17:07:28 +000016
Neale Ranns9bea8fb2017-02-03 04:34:01 -080017#
Neale Rannscf3561b2017-12-13 01:44:25 -080018# The number of packets sent is set to 91 so that when we replicate more than 3
Neale Ranns9bea8fb2017-02-03 04:34:01 -080019# times, which we do for some entries, we will generate more than 256 packets
Neale Rannsaaa396a2017-02-05 09:12:02 -080020# to the next node in the VLIB graph. Thus we are testing the code's
Neale Rannscf3561b2017-12-13 01:44:25 -080021# correctness handling this over-flow.
22# It's also an odd number so we hit any single loops.
Neale Ranns9bea8fb2017-02-03 04:34:01 -080023#
Neale Rannscf3561b2017-12-13 01:44:25 -080024N_PKTS_IN_STREAM = 91
Neale Ranns9bea8fb2017-02-03 04:34:01 -080025
Neale Ranns32e1c012016-11-22 17:07:28 +000026
Neale Ranns5a8123b2017-01-26 01:18:23 -080027class TestMFIB(VppTestCase):
28 """ MFIB Test Case """
29
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -070030 @classmethod
31 def setUpClass(cls):
32 super(TestMFIB, cls).setUpClass()
33
34 @classmethod
35 def tearDownClass(cls):
36 super(TestMFIB, cls).tearDownClass()
37
Neale Ranns5a8123b2017-01-26 01:18:23 -080038 def setUp(self):
39 super(TestMFIB, self).setUp()
40
41 def test_mfib(self):
42 """ MFIB Unit Tests """
43 error = self.vapi.cli("test mfib")
44
45 if error:
46 self.logger.critical(error)
Paul Vinciguerra9a6dafd2019-03-06 15:11:28 -080047 self.assertNotIn("Failed", error)
Neale Ranns5a8123b2017-01-26 01:18:23 -080048
49
Neale Ranns32e1c012016-11-22 17:07:28 +000050class TestIPMcast(VppTestCase):
51 """ IP Multicast Test Case """
52
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -070053 @classmethod
54 def setUpClass(cls):
55 super(TestIPMcast, cls).setUpClass()
56
57 @classmethod
58 def tearDownClass(cls):
59 super(TestIPMcast, cls).tearDownClass()
60
Neale Ranns32e1c012016-11-22 17:07:28 +000061 def setUp(self):
62 super(TestIPMcast, self).setUp()
63
Neale Ranns37be7362017-02-21 17:30:26 -080064 # create 8 pg interfaces
Neale Ranns15002542017-09-10 04:39:11 -070065 self.create_pg_interfaces(range(9))
Neale Ranns32e1c012016-11-22 17:07:28 +000066
67 # setup interfaces
Neale Ranns15002542017-09-10 04:39:11 -070068 for i in self.pg_interfaces[:8]:
Neale Ranns32e1c012016-11-22 17:07:28 +000069 i.admin_up()
70 i.config_ip4()
71 i.config_ip6()
72 i.resolve_arp()
73 i.resolve_ndp()
74
Neale Ranns15002542017-09-10 04:39:11 -070075 # one more in a vrf
76 tbl4 = VppIpTable(self, 10)
77 tbl4.add_vpp_config()
78 self.pg8.set_table_ip4(10)
79 self.pg8.config_ip4()
80
81 tbl6 = VppIpTable(self, 10, is_ip6=1)
82 tbl6.add_vpp_config()
83 self.pg8.set_table_ip6(10)
84 self.pg8.config_ip6()
85
86 def tearDown(self):
87 for i in self.pg_interfaces:
88 i.unconfig_ip4()
89 i.unconfig_ip6()
90 i.admin_down()
91
92 self.pg8.set_table_ip4(0)
93 self.pg8.set_table_ip6(0)
94 super(TestIPMcast, self).tearDown()
95
Neale Ranns9d676af2017-03-15 01:28:31 -070096 def create_stream_ip4(self, src_if, src_ip, dst_ip, payload_size=0):
Neale Ranns32e1c012016-11-22 17:07:28 +000097 pkts = []
Neale Ranns9d676af2017-03-15 01:28:31 -070098 # default to small packet sizes
Neale Ranns21fb4f72020-10-05 12:26:47 +000099 p = (Ether(dst=getmacbyip(dst_ip), src=src_if.remote_mac) /
Neale Ranns9d676af2017-03-15 01:28:31 -0700100 IP(src=src_ip, dst=dst_ip) /
101 UDP(sport=1234, dport=1234))
102 if not payload_size:
103 payload_size = 64 - len(p)
Ole Troan770a0de2019-11-07 13:52:21 +0100104 p = p / Raw(b'\xa5' * payload_size)
Neale Ranns9d676af2017-03-15 01:28:31 -0700105
Neale Ranns9bea8fb2017-02-03 04:34:01 -0800106 for i in range(0, N_PKTS_IN_STREAM):
Neale Ranns32e1c012016-11-22 17:07:28 +0000107 pkts.append(p)
108 return pkts
109
110 def create_stream_ip6(self, src_if, src_ip, dst_ip):
111 pkts = []
Neale Ranns9bea8fb2017-02-03 04:34:01 -0800112 for i in range(0, N_PKTS_IN_STREAM):
Neale Ranns32e1c012016-11-22 17:07:28 +0000113 info = self.create_packet_info(src_if, src_if)
114 payload = self.info_to_payload(info)
Neale Ranns21fb4f72020-10-05 12:26:47 +0000115 p = (Ether(dst=getmacbyip6(dst_ip), src=src_if.remote_mac) /
Neale Ranns32e1c012016-11-22 17:07:28 +0000116 IPv6(src=src_ip, dst=dst_ip) /
117 UDP(sport=1234, dport=1234) /
118 Raw(payload))
119 info.data = p.copy()
120 pkts.append(p)
121 return pkts
122
123 def verify_filter(self, capture, sent):
124 if not len(capture) == len(sent):
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700125 # filter out any IPv6 RAs from the capture
Neale Ranns32e1c012016-11-22 17:07:28 +0000126 for p in capture:
127 if (p.haslayer(IPv6)):
128 capture.remove(p)
129 return capture
130
Neale Rannse821ab12017-06-01 07:45:05 -0700131 def verify_capture_ip4(self, rx_if, sent, dst_mac=None):
Neale Rannsc2aad532017-05-30 09:53:52 -0700132 rxd = rx_if.get_capture(len(sent))
Neale Ranns32e1c012016-11-22 17:07:28 +0000133
134 try:
135 capture = self.verify_filter(rxd, sent)
136
137 self.assertEqual(len(capture), len(sent))
138
139 for i in range(len(capture)):
140 tx = sent[i]
141 rx = capture[i]
142
Neale Ranns32e1c012016-11-22 17:07:28 +0000143 eth = rx[Ether]
144 self.assertEqual(eth.type, 0x800)
145
146 tx_ip = tx[IP]
147 rx_ip = rx[IP]
148
Neale Rannse821ab12017-06-01 07:45:05 -0700149 if dst_mac is None:
150 dst_mac = getmacbyip(rx_ip.dst)
151
Neale Ranns32e1c012016-11-22 17:07:28 +0000152 # check the MAC address on the RX'd packet is correctly formed
Neale Rannse821ab12017-06-01 07:45:05 -0700153 self.assertEqual(eth.dst, dst_mac)
Neale Ranns32e1c012016-11-22 17:07:28 +0000154
155 self.assertEqual(rx_ip.src, tx_ip.src)
156 self.assertEqual(rx_ip.dst, tx_ip.dst)
157 # IP processing post pop has decremented the TTL
158 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
159
160 except:
161 raise
162
Neale Rannsc2aad532017-05-30 09:53:52 -0700163 def verify_capture_ip6(self, rx_if, sent):
164 capture = rx_if.get_capture(len(sent))
Neale Ranns32e1c012016-11-22 17:07:28 +0000165
166 self.assertEqual(len(capture), len(sent))
167
168 for i in range(len(capture)):
169 tx = sent[i]
170 rx = capture[i]
171
Neale Ranns32e1c012016-11-22 17:07:28 +0000172 eth = rx[Ether]
173 self.assertEqual(eth.type, 0x86DD)
174
175 tx_ip = tx[IPv6]
176 rx_ip = rx[IPv6]
177
178 # check the MAC address on the RX'd packet is correctly formed
179 self.assertEqual(eth.dst, getmacbyip6(rx_ip.dst))
180
181 self.assertEqual(rx_ip.src, tx_ip.src)
182 self.assertEqual(rx_ip.dst, tx_ip.dst)
183 # IP processing post pop has decremented the TTL
184 self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
185
186 def test_ip_mcast(self):
187 """ IP Multicast Replication """
188
Neale Ranns990f6942020-10-20 07:20:17 +0000189 MRouteItfFlags = VppEnum.vl_api_mfib_itf_flags_t
190 MRouteEntryFlags = VppEnum.vl_api_mfib_entry_flags_t
191
Neale Ranns32e1c012016-11-22 17:07:28 +0000192 #
193 # a stream that matches the default route. gets dropped.
194 #
195 self.vapi.cli("clear trace")
Neale Ranns21fb4f72020-10-05 12:26:47 +0000196 self.vapi.cli("packet mac-filter pg0 on")
197 self.vapi.cli("packet mac-filter pg1 on")
198 self.vapi.cli("packet mac-filter pg2 on")
199 self.vapi.cli("packet mac-filter pg4 on")
200 self.vapi.cli("packet mac-filter pg5 on")
201 self.vapi.cli("packet mac-filter pg6 on")
202 self.vapi.cli("packet mac-filter pg7 on")
203
Neale Ranns32e1c012016-11-22 17:07:28 +0000204 tx = self.create_stream_ip4(self.pg0, "1.1.1.1", "232.1.1.1")
205 self.pg0.add_stream(tx)
206
207 self.pg_enable_capture(self.pg_interfaces)
208 self.pg_start()
209
210 self.pg0.assert_nothing_captured(
211 remark="IP multicast packets forwarded on default route")
212
213 #
214 # A (*,G).
Neale Ranns37be7362017-02-21 17:30:26 -0800215 # one accepting interface, pg0, 7 forwarding interfaces
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700216 # many forwarding interfaces test the case where the replicate DPO
Neale Ranns37be7362017-02-21 17:30:26 -0800217 # needs to use extra cache lines for the buckets.
Neale Ranns32e1c012016-11-22 17:07:28 +0000218 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800219 route_232_1_1_1 = VppIpMRoute(
Neale Ranns32e1c012016-11-22 17:07:28 +0000220 self,
221 "0.0.0.0",
222 "232.1.1.1", 32,
Neale Ranns990f6942020-10-20 07:20:17 +0000223 MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
Neale Ranns5a8123b2017-01-26 01:18:23 -0800224 [VppMRoutePath(self.pg0.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000225 MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT),
Neale Ranns5a8123b2017-01-26 01:18:23 -0800226 VppMRoutePath(self.pg1.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000227 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD),
Neale Ranns5a8123b2017-01-26 01:18:23 -0800228 VppMRoutePath(self.pg2.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000229 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD),
Neale Ranns5a8123b2017-01-26 01:18:23 -0800230 VppMRoutePath(self.pg3.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000231 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD),
Neale Ranns37be7362017-02-21 17:30:26 -0800232 VppMRoutePath(self.pg4.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000233 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD),
Neale Ranns37be7362017-02-21 17:30:26 -0800234 VppMRoutePath(self.pg5.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000235 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD),
Neale Ranns37be7362017-02-21 17:30:26 -0800236 VppMRoutePath(self.pg6.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000237 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD),
Neale Ranns37be7362017-02-21 17:30:26 -0800238 VppMRoutePath(self.pg7.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000239 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD)])
Neale Ranns32e1c012016-11-22 17:07:28 +0000240 route_232_1_1_1.add_vpp_config()
241
242 #
243 # An (S,G).
244 # one accepting interface, pg0, 2 forwarding interfaces
245 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800246 route_1_1_1_1_232_1_1_1 = VppIpMRoute(
Neale Ranns32e1c012016-11-22 17:07:28 +0000247 self,
248 "1.1.1.1",
Neale Ranns3e42ebe2018-10-04 08:36:56 -0700249 "232.1.1.1", 27, # any grp-len is ok when src is set
Neale Ranns990f6942020-10-20 07:20:17 +0000250 MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
Neale Ranns5a8123b2017-01-26 01:18:23 -0800251 [VppMRoutePath(self.pg0.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000252 MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT),
Neale Ranns5a8123b2017-01-26 01:18:23 -0800253 VppMRoutePath(self.pg1.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000254 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD),
Neale Ranns5a8123b2017-01-26 01:18:23 -0800255 VppMRoutePath(self.pg2.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000256 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD)])
Neale Ranns32e1c012016-11-22 17:07:28 +0000257 route_1_1_1_1_232_1_1_1.add_vpp_config()
258
259 #
Neale Rannse821ab12017-06-01 07:45:05 -0700260 # An (S,G).
261 # one accepting interface, pg0, 2 forwarding interfaces
262 # that use unicast next-hops
263 #
264 route_1_1_1_1_232_1_1_2 = VppIpMRoute(
265 self,
266 "1.1.1.1",
267 "232.1.1.2", 64,
Neale Ranns990f6942020-10-20 07:20:17 +0000268 MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
Neale Rannse821ab12017-06-01 07:45:05 -0700269 [VppMRoutePath(self.pg0.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000270 MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT),
Neale Rannse821ab12017-06-01 07:45:05 -0700271 VppMRoutePath(self.pg1.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000272 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD,
Neale Rannse821ab12017-06-01 07:45:05 -0700273 nh=self.pg1.remote_ip4),
274 VppMRoutePath(self.pg2.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000275 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD,
Neale Rannse821ab12017-06-01 07:45:05 -0700276 nh=self.pg2.remote_ip4)])
277 route_1_1_1_1_232_1_1_2.add_vpp_config()
278
279 #
Neale Ranns32e1c012016-11-22 17:07:28 +0000280 # An (*,G/m).
281 # one accepting interface, pg0, 1 forwarding interfaces
282 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800283 route_232 = VppIpMRoute(
Neale Ranns32e1c012016-11-22 17:07:28 +0000284 self,
285 "0.0.0.0",
286 "232.0.0.0", 8,
Neale Ranns990f6942020-10-20 07:20:17 +0000287 MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
Neale Ranns5a8123b2017-01-26 01:18:23 -0800288 [VppMRoutePath(self.pg0.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000289 MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT),
Neale Ranns5a8123b2017-01-26 01:18:23 -0800290 VppMRoutePath(self.pg1.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000291 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD)])
Neale Ranns32e1c012016-11-22 17:07:28 +0000292 route_232.add_vpp_config()
293
294 #
295 # a stream that matches the route for (1.1.1.1,232.1.1.1)
Neale Ranns9d676af2017-03-15 01:28:31 -0700296 # small packets
Neale Ranns32e1c012016-11-22 17:07:28 +0000297 #
298 self.vapi.cli("clear trace")
299 tx = self.create_stream_ip4(self.pg0, "1.1.1.1", "232.1.1.1")
300 self.pg0.add_stream(tx)
301
302 self.pg_enable_capture(self.pg_interfaces)
303 self.pg_start()
304
Neale Ranns28c142e2018-09-07 09:37:07 -0700305 self.assertEqual(route_1_1_1_1_232_1_1_1.get_stats()['packets'],
306 len(tx))
307
Neale Ranns37be7362017-02-21 17:30:26 -0800308 # We expect replications on Pg1->7
Neale Ranns32e1c012016-11-22 17:07:28 +0000309 self.verify_capture_ip4(self.pg1, tx)
310 self.verify_capture_ip4(self.pg2, tx)
311
312 # no replications on Pg0
313 self.pg0.assert_nothing_captured(
314 remark="IP multicast packets forwarded on PG0")
315 self.pg3.assert_nothing_captured(
316 remark="IP multicast packets forwarded on PG3")
317
318 #
Neale Ranns9d676af2017-03-15 01:28:31 -0700319 # a stream that matches the route for (1.1.1.1,232.1.1.1)
320 # large packets
321 #
322 self.vapi.cli("clear trace")
323 tx = self.create_stream_ip4(self.pg0, "1.1.1.1", "232.1.1.1",
324 payload_size=1024)
325 self.pg0.add_stream(tx)
326
327 self.pg_enable_capture(self.pg_interfaces)
328 self.pg_start()
329
330 # We expect replications on Pg1->7
331 self.verify_capture_ip4(self.pg1, tx)
332 self.verify_capture_ip4(self.pg2, tx)
Neale Ranns9d676af2017-03-15 01:28:31 -0700333
Neale Ranns28c142e2018-09-07 09:37:07 -0700334 self.assertEqual(route_1_1_1_1_232_1_1_1.get_stats()['packets'],
335 2*len(tx))
336
Neale Ranns9d676af2017-03-15 01:28:31 -0700337 # no replications on Pg0
338 self.pg0.assert_nothing_captured(
339 remark="IP multicast packets forwarded on PG0")
340 self.pg3.assert_nothing_captured(
341 remark="IP multicast packets forwarded on PG3")
342
343 #
Neale Rannse821ab12017-06-01 07:45:05 -0700344 # a stream to the unicast next-hops
345 #
346 self.vapi.cli("clear trace")
347 tx = self.create_stream_ip4(self.pg0, "1.1.1.1", "232.1.1.2")
348 self.pg0.add_stream(tx)
349
350 self.pg_enable_capture(self.pg_interfaces)
351 self.pg_start()
352
353 # We expect replications on Pg1->7
354 self.verify_capture_ip4(self.pg1, tx, dst_mac=self.pg1.remote_mac)
355 self.verify_capture_ip4(self.pg2, tx, dst_mac=self.pg2.remote_mac)
356
357 # no replications on Pg0 nor pg3
358 self.pg0.assert_nothing_captured(
359 remark="IP multicast packets forwarded on PG0")
360 self.pg3.assert_nothing_captured(
361 remark="IP multicast packets forwarded on PG3")
362
363 #
Neale Ranns32e1c012016-11-22 17:07:28 +0000364 # a stream that matches the route for (*,232.0.0.0/8)
365 # Send packets with the 9th bit set so we test the correct clearing
366 # of that bit in the mac rewrite
367 #
368 self.vapi.cli("clear trace")
369 tx = self.create_stream_ip4(self.pg0, "1.1.1.1", "232.255.255.255")
370 self.pg0.add_stream(tx)
371
372 self.pg_enable_capture(self.pg_interfaces)
373 self.pg_start()
374
375 # We expect replications on Pg1 only
376 self.verify_capture_ip4(self.pg1, tx)
Neale Ranns28c142e2018-09-07 09:37:07 -0700377 self.assertEqual(route_232.get_stats()['packets'], len(tx))
Neale Ranns32e1c012016-11-22 17:07:28 +0000378
379 # no replications on Pg0, Pg2 not Pg3
380 self.pg0.assert_nothing_captured(
381 remark="IP multicast packets forwarded on PG0")
382 self.pg2.assert_nothing_captured(
383 remark="IP multicast packets forwarded on PG2")
384 self.pg3.assert_nothing_captured(
385 remark="IP multicast packets forwarded on PG3")
386
387 #
388 # a stream that matches the route for (*,232.1.1.1)
389 #
390 self.vapi.cli("clear trace")
391 tx = self.create_stream_ip4(self.pg0, "1.1.1.2", "232.1.1.1")
392 self.pg0.add_stream(tx)
393
394 self.pg_enable_capture(self.pg_interfaces)
395 self.pg_start()
396
Neale Rannse821ab12017-06-01 07:45:05 -0700397 # We expect replications on Pg1->7
Neale Ranns32e1c012016-11-22 17:07:28 +0000398 self.verify_capture_ip4(self.pg1, tx)
399 self.verify_capture_ip4(self.pg2, tx)
400 self.verify_capture_ip4(self.pg3, tx)
Neale Rannsc2aad532017-05-30 09:53:52 -0700401 self.verify_capture_ip4(self.pg4, tx)
402 self.verify_capture_ip4(self.pg5, tx)
403 self.verify_capture_ip4(self.pg6, tx)
404 self.verify_capture_ip4(self.pg7, tx)
Neale Ranns32e1c012016-11-22 17:07:28 +0000405
Neale Rannse821ab12017-06-01 07:45:05 -0700406 # no replications on Pg0
407 self.pg0.assert_nothing_captured(
408 remark="IP multicast packets forwarded on PG0")
409
Neale Ranns21fb4f72020-10-05 12:26:47 +0000410 self.vapi.cli("packet mac-filter pg0 off")
411 self.vapi.cli("packet mac-filter pg1 off")
412 self.vapi.cli("packet mac-filter pg2 off")
413 self.vapi.cli("packet mac-filter pg4 off")
414 self.vapi.cli("packet mac-filter pg5 off")
415 self.vapi.cli("packet mac-filter pg6 off")
416 self.vapi.cli("packet mac-filter pg7 off")
417
Neale Ranns32e1c012016-11-22 17:07:28 +0000418 def test_ip6_mcast(self):
419 """ IPv6 Multicast Replication """
420
Neale Ranns990f6942020-10-20 07:20:17 +0000421 MRouteItfFlags = VppEnum.vl_api_mfib_itf_flags_t
422 MRouteEntryFlags = VppEnum.vl_api_mfib_entry_flags_t
423
Neale Ranns21fb4f72020-10-05 12:26:47 +0000424 self.vapi.cli("packet mac-filter pg0 on")
425 self.vapi.cli("packet mac-filter pg1 on")
426 self.vapi.cli("packet mac-filter pg2 on")
427 self.vapi.cli("packet mac-filter pg4 on")
428 self.vapi.cli("packet mac-filter pg5 on")
429 self.vapi.cli("packet mac-filter pg6 on")
430 self.vapi.cli("packet mac-filter pg7 on")
Neale Ranns32e1c012016-11-22 17:07:28 +0000431 #
432 # a stream that matches the default route. gets dropped.
433 #
434 self.vapi.cli("clear trace")
435 tx = self.create_stream_ip6(self.pg0, "2001::1", "ff01::1")
436 self.pg0.add_stream(tx)
437
438 self.pg_enable_capture(self.pg_interfaces)
439 self.pg_start()
440
441 self.pg0.assert_nothing_captured(
442 remark="IPv6 multicast packets forwarded on default route")
443
444 #
445 # A (*,G).
446 # one accepting interface, pg0, 3 forwarding interfaces
447 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800448 route_ff01_1 = VppIpMRoute(
Neale Ranns32e1c012016-11-22 17:07:28 +0000449 self,
450 "::",
451 "ff01::1", 128,
Neale Ranns990f6942020-10-20 07:20:17 +0000452 MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
Neale Ranns5a8123b2017-01-26 01:18:23 -0800453 [VppMRoutePath(self.pg0.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000454 MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT,
Neale Ranns097fa662018-05-01 05:17:55 -0700455 proto=FibPathProto.FIB_PATH_NH_PROTO_IP6),
Neale Ranns5a8123b2017-01-26 01:18:23 -0800456 VppMRoutePath(self.pg1.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000457 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD,
Neale Ranns097fa662018-05-01 05:17:55 -0700458 proto=FibPathProto.FIB_PATH_NH_PROTO_IP6),
Neale Ranns5a8123b2017-01-26 01:18:23 -0800459 VppMRoutePath(self.pg2.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000460 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD,
Neale Ranns097fa662018-05-01 05:17:55 -0700461 proto=FibPathProto.FIB_PATH_NH_PROTO_IP6),
Neale Ranns5a8123b2017-01-26 01:18:23 -0800462 VppMRoutePath(self.pg3.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000463 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD,
Neale Ranns097fa662018-05-01 05:17:55 -0700464 proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)])
Neale Ranns32e1c012016-11-22 17:07:28 +0000465 route_ff01_1.add_vpp_config()
466
467 #
468 # An (S,G).
469 # one accepting interface, pg0, 2 forwarding interfaces
470 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800471 route_2001_ff01_1 = VppIpMRoute(
Neale Ranns32e1c012016-11-22 17:07:28 +0000472 self,
473 "2001::1",
Neale Ranns3e42ebe2018-10-04 08:36:56 -0700474 "ff01::1", 0, # any grp-len is ok when src is set
Neale Ranns990f6942020-10-20 07:20:17 +0000475 MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
Neale Ranns5a8123b2017-01-26 01:18:23 -0800476 [VppMRoutePath(self.pg0.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000477 MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT,
Neale Ranns097fa662018-05-01 05:17:55 -0700478 proto=FibPathProto.FIB_PATH_NH_PROTO_IP6),
Neale Ranns5a8123b2017-01-26 01:18:23 -0800479 VppMRoutePath(self.pg1.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000480 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD,
Neale Ranns097fa662018-05-01 05:17:55 -0700481 proto=FibPathProto.FIB_PATH_NH_PROTO_IP6),
Neale Ranns5a8123b2017-01-26 01:18:23 -0800482 VppMRoutePath(self.pg2.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000483 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD,
Neale Ranns097fa662018-05-01 05:17:55 -0700484 proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)])
Neale Ranns32e1c012016-11-22 17:07:28 +0000485 route_2001_ff01_1.add_vpp_config()
486
487 #
488 # An (*,G/m).
489 # one accepting interface, pg0, 1 forwarding interface
490 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800491 route_ff01 = VppIpMRoute(
Neale Ranns32e1c012016-11-22 17:07:28 +0000492 self,
493 "::",
494 "ff01::", 16,
Neale Ranns990f6942020-10-20 07:20:17 +0000495 MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
Neale Ranns5a8123b2017-01-26 01:18:23 -0800496 [VppMRoutePath(self.pg0.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000497 MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT,
Neale Ranns097fa662018-05-01 05:17:55 -0700498 proto=FibPathProto.FIB_PATH_NH_PROTO_IP6),
Neale Ranns5a8123b2017-01-26 01:18:23 -0800499 VppMRoutePath(self.pg1.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000500 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD,
Neale Ranns097fa662018-05-01 05:17:55 -0700501 proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)])
Neale Ranns32e1c012016-11-22 17:07:28 +0000502 route_ff01.add_vpp_config()
503
504 #
505 # a stream that matches the route for (*, ff01::/16)
Neale Rannsce111d22018-01-23 08:38:50 -0800506 # sent on the non-accepting interface
507 #
508 self.vapi.cli("clear trace")
509 tx = self.create_stream_ip6(self.pg1, "2002::1", "ff01:2::255")
510 self.send_and_assert_no_replies(self.pg1, tx, "RPF miss")
511
512 #
513 # a stream that matches the route for (*, ff01::/16)
514 # sent on the accepting interface
Neale Ranns32e1c012016-11-22 17:07:28 +0000515 #
516 self.vapi.cli("clear trace")
517 tx = self.create_stream_ip6(self.pg0, "2002::1", "ff01:2::255")
518 self.pg0.add_stream(tx)
519
520 self.pg_enable_capture(self.pg_interfaces)
521 self.pg_start()
522
523 # We expect replications on Pg1
524 self.verify_capture_ip6(self.pg1, tx)
525
526 # no replications on Pg0, Pg3
527 self.pg0.assert_nothing_captured(
528 remark="IP multicast packets forwarded on PG0")
529 self.pg2.assert_nothing_captured(
530 remark="IP multicast packets forwarded on PG2")
531 self.pg3.assert_nothing_captured(
532 remark="IP multicast packets forwarded on PG3")
533
534 #
Neale Rannsc2aad532017-05-30 09:53:52 -0700535 # Bounce the interface and it should still work
536 #
537 self.pg1.admin_down()
538 self.pg0.add_stream(tx)
539 self.pg_enable_capture(self.pg_interfaces)
540 self.pg_start()
541 self.pg1.assert_nothing_captured(
542 remark="IP multicast packets forwarded on down PG1")
543
544 self.pg1.admin_up()
545 self.pg0.add_stream(tx)
546 self.pg_enable_capture(self.pg_interfaces)
547 self.pg_start()
548 self.verify_capture_ip6(self.pg1, tx)
549
550 #
Neale Ranns32e1c012016-11-22 17:07:28 +0000551 # a stream that matches the route for (*,ff01::1)
552 #
553 self.vapi.cli("clear trace")
554 tx = self.create_stream_ip6(self.pg0, "2002::2", "ff01::1")
555 self.pg0.add_stream(tx)
556
557 self.pg_enable_capture(self.pg_interfaces)
558 self.pg_start()
559
560 # We expect replications on Pg1, 2, 3.
561 self.verify_capture_ip6(self.pg1, tx)
562 self.verify_capture_ip6(self.pg2, tx)
563 self.verify_capture_ip6(self.pg3, tx)
564
565 # no replications on Pg0
566 self.pg0.assert_nothing_captured(
567 remark="IPv6 multicast packets forwarded on PG0")
568
569 #
570 # a stream that matches the route for (2001::1, ff00::1)
571 #
572 self.vapi.cli("clear trace")
573 tx = self.create_stream_ip6(self.pg0, "2001::1", "ff01::1")
574 self.pg0.add_stream(tx)
575
576 self.pg_enable_capture(self.pg_interfaces)
577 self.pg_start()
578
579 # We expect replications on Pg1, 2,
580 self.verify_capture_ip6(self.pg1, tx)
581 self.verify_capture_ip6(self.pg2, tx)
582
583 # no replications on Pg0, Pg3
584 self.pg0.assert_nothing_captured(
585 remark="IP multicast packets forwarded on PG0")
586 self.pg3.assert_nothing_captured(
587 remark="IP multicast packets forwarded on PG3")
588
Neale Ranns21fb4f72020-10-05 12:26:47 +0000589 self.vapi.cli("packet mac-filter pg0 off")
590 self.vapi.cli("packet mac-filter pg1 off")
591 self.vapi.cli("packet mac-filter pg2 off")
592 self.vapi.cli("packet mac-filter pg4 off")
593 self.vapi.cli("packet mac-filter pg5 off")
594 self.vapi.cli("packet mac-filter pg6 off")
595 self.vapi.cli("packet mac-filter pg7 off")
596
Neale Ranns32e1c012016-11-22 17:07:28 +0000597 def _mcast_connected_send_stream(self, dst_ip):
598 self.vapi.cli("clear trace")
599 tx = self.create_stream_ip4(self.pg0,
600 self.pg0.remote_ip4,
601 dst_ip)
602 self.pg0.add_stream(tx)
603
604 self.pg_enable_capture(self.pg_interfaces)
605 self.pg_start()
606
607 # We expect replications on Pg1.
608 self.verify_capture_ip4(self.pg1, tx)
609
610 return tx
611
612 def test_ip_mcast_connected(self):
613 """ IP Multicast Connected Source check """
614
Neale Ranns990f6942020-10-20 07:20:17 +0000615 MRouteItfFlags = VppEnum.vl_api_mfib_itf_flags_t
616 MRouteEntryFlags = VppEnum.vl_api_mfib_entry_flags_t
617
Neale Ranns32e1c012016-11-22 17:07:28 +0000618 #
619 # A (*,G).
620 # one accepting interface, pg0, 1 forwarding interfaces
621 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800622 route_232_1_1_1 = VppIpMRoute(
Neale Ranns32e1c012016-11-22 17:07:28 +0000623 self,
624 "0.0.0.0",
625 "232.1.1.1", 32,
Neale Ranns990f6942020-10-20 07:20:17 +0000626 MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
Neale Ranns5a8123b2017-01-26 01:18:23 -0800627 [VppMRoutePath(self.pg0.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000628 MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT),
Neale Ranns5a8123b2017-01-26 01:18:23 -0800629 VppMRoutePath(self.pg1.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000630 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD)])
Neale Ranns32e1c012016-11-22 17:07:28 +0000631
632 route_232_1_1_1.add_vpp_config()
633 route_232_1_1_1.update_entry_flags(
Neale Ranns990f6942020-10-20 07:20:17 +0000634 MRouteEntryFlags.MFIB_API_ENTRY_FLAG_CONNECTED)
Neale Ranns32e1c012016-11-22 17:07:28 +0000635
636 #
637 # Now the (*,G) is present, send from connected source
638 #
639 tx = self._mcast_connected_send_stream("232.1.1.1")
640
641 #
642 # Constrct a representation of the signal we expect on pg0
643 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800644 signal_232_1_1_1_itf_0 = VppMFibSignal(self,
645 route_232_1_1_1,
646 self.pg0.sw_if_index,
647 tx[0])
Neale Ranns32e1c012016-11-22 17:07:28 +0000648
649 #
650 # read the only expected signal
651 #
652 signals = self.vapi.mfib_signal_dump()
653
654 self.assertEqual(1, len(signals))
655
656 signal_232_1_1_1_itf_0.compare(signals[0])
657
658 #
659 # reading the signal allows for the generation of another
660 # so send more packets and expect the next signal
661 #
662 tx = self._mcast_connected_send_stream("232.1.1.1")
663
664 signals = self.vapi.mfib_signal_dump()
665 self.assertEqual(1, len(signals))
666 signal_232_1_1_1_itf_0.compare(signals[0])
667
668 #
669 # A Second entry with connected check
670 # one accepting interface, pg0, 1 forwarding interfaces
671 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800672 route_232_1_1_2 = VppIpMRoute(
Neale Ranns32e1c012016-11-22 17:07:28 +0000673 self,
674 "0.0.0.0",
675 "232.1.1.2", 32,
Neale Ranns990f6942020-10-20 07:20:17 +0000676 MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
Neale Ranns5a8123b2017-01-26 01:18:23 -0800677 [VppMRoutePath(self.pg0.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000678 MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT),
Neale Ranns5a8123b2017-01-26 01:18:23 -0800679 VppMRoutePath(self.pg1.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000680 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD)])
Neale Ranns32e1c012016-11-22 17:07:28 +0000681
682 route_232_1_1_2.add_vpp_config()
683 route_232_1_1_2.update_entry_flags(
Neale Ranns990f6942020-10-20 07:20:17 +0000684 MRouteEntryFlags.MFIB_API_ENTRY_FLAG_CONNECTED)
Neale Ranns32e1c012016-11-22 17:07:28 +0000685
686 #
687 # Send traffic to both entries. One read should net us two signals
688 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800689 signal_232_1_1_2_itf_0 = VppMFibSignal(self,
690 route_232_1_1_2,
691 self.pg0.sw_if_index,
692 tx[0])
Neale Ranns32e1c012016-11-22 17:07:28 +0000693 tx = self._mcast_connected_send_stream("232.1.1.1")
694 tx2 = self._mcast_connected_send_stream("232.1.1.2")
695
696 #
697 # read the only expected signal
698 #
699 signals = self.vapi.mfib_signal_dump()
700
701 self.assertEqual(2, len(signals))
702
703 signal_232_1_1_1_itf_0.compare(signals[1])
704 signal_232_1_1_2_itf_0.compare(signals[0])
705
Neale Rannsd792d9c2017-10-21 10:53:20 -0700706 route_232_1_1_1.update_entry_flags(
Neale Ranns990f6942020-10-20 07:20:17 +0000707 MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE)
Neale Rannsd792d9c2017-10-21 10:53:20 -0700708 route_232_1_1_2.update_entry_flags(
Neale Ranns990f6942020-10-20 07:20:17 +0000709 MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE)
Neale Ranns32e1c012016-11-22 17:07:28 +0000710
711 def test_ip_mcast_signal(self):
712 """ IP Multicast Signal """
713
Neale Ranns990f6942020-10-20 07:20:17 +0000714 MRouteItfFlags = VppEnum.vl_api_mfib_itf_flags_t
715 MRouteEntryFlags = VppEnum.vl_api_mfib_entry_flags_t
716
Neale Ranns32e1c012016-11-22 17:07:28 +0000717 #
718 # A (*,G).
719 # one accepting interface, pg0, 1 forwarding interfaces
720 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800721 route_232_1_1_1 = VppIpMRoute(
Neale Ranns32e1c012016-11-22 17:07:28 +0000722 self,
723 "0.0.0.0",
724 "232.1.1.1", 32,
Neale Ranns990f6942020-10-20 07:20:17 +0000725 MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
Neale Ranns5a8123b2017-01-26 01:18:23 -0800726 [VppMRoutePath(self.pg0.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000727 MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT),
Neale Ranns5a8123b2017-01-26 01:18:23 -0800728 VppMRoutePath(self.pg1.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000729 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD)])
Neale Ranns32e1c012016-11-22 17:07:28 +0000730
731 route_232_1_1_1.add_vpp_config()
Neale Ranns097fa662018-05-01 05:17:55 -0700732
Neale Ranns32e1c012016-11-22 17:07:28 +0000733 route_232_1_1_1.update_entry_flags(
Neale Ranns990f6942020-10-20 07:20:17 +0000734 MRouteEntryFlags.MFIB_API_ENTRY_FLAG_SIGNAL)
Neale Ranns32e1c012016-11-22 17:07:28 +0000735
736 #
737 # Now the (*,G) is present, send from connected source
738 #
739 tx = self._mcast_connected_send_stream("232.1.1.1")
740
741 #
742 # Constrct a representation of the signal we expect on pg0
743 #
Neale Ranns5a8123b2017-01-26 01:18:23 -0800744 signal_232_1_1_1_itf_0 = VppMFibSignal(self,
745 route_232_1_1_1,
746 self.pg0.sw_if_index,
747 tx[0])
Neale Ranns32e1c012016-11-22 17:07:28 +0000748
749 #
750 # read the only expected signal
751 #
752 signals = self.vapi.mfib_signal_dump()
753
754 self.assertEqual(1, len(signals))
755
756 signal_232_1_1_1_itf_0.compare(signals[0])
757
758 #
759 # reading the signal allows for the generation of another
760 # so send more packets and expect the next signal
761 #
762 tx = self._mcast_connected_send_stream("232.1.1.1")
763
764 signals = self.vapi.mfib_signal_dump()
765 self.assertEqual(1, len(signals))
766 signal_232_1_1_1_itf_0.compare(signals[0])
767
768 #
769 # Set the negate-signal on the accepting interval - the signals
770 # should stop
771 #
772 route_232_1_1_1.update_path_flags(
773 self.pg0.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000774 (MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT |
775 MRouteItfFlags.MFIB_API_ITF_FLAG_NEGATE_SIGNAL))
Neale Ranns32e1c012016-11-22 17:07:28 +0000776
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800777 self.vapi.cli("clear trace")
Neale Ranns32e1c012016-11-22 17:07:28 +0000778 tx = self._mcast_connected_send_stream("232.1.1.1")
779
780 signals = self.vapi.mfib_signal_dump()
781 self.assertEqual(0, len(signals))
782
783 #
784 # Clear the SIGNAL flag on the entry and the signals should
785 # come back since the interface is still NEGATE-SIGNAL
786 #
787 route_232_1_1_1.update_entry_flags(
Neale Ranns990f6942020-10-20 07:20:17 +0000788 MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE)
Neale Ranns32e1c012016-11-22 17:07:28 +0000789
790 tx = self._mcast_connected_send_stream("232.1.1.1")
791
792 signals = self.vapi.mfib_signal_dump()
793 self.assertEqual(1, len(signals))
794 signal_232_1_1_1_itf_0.compare(signals[0])
795
796 #
797 # Lastly remove the NEGATE-SIGNAL from the interface and the
798 # signals should stop
799 #
Neale Ranns990f6942020-10-20 07:20:17 +0000800 route_232_1_1_1.update_path_flags(
801 self.pg0.sw_if_index,
802 MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT)
Neale Ranns32e1c012016-11-22 17:07:28 +0000803
804 tx = self._mcast_connected_send_stream("232.1.1.1")
805 signals = self.vapi.mfib_signal_dump()
806 self.assertEqual(0, len(signals))
807
Neale Ranns15002542017-09-10 04:39:11 -0700808 def test_ip_mcast_vrf(self):
809 """ IP Multicast Replication in non-default table"""
810
Neale Ranns990f6942020-10-20 07:20:17 +0000811 MRouteItfFlags = VppEnum.vl_api_mfib_itf_flags_t
812 MRouteEntryFlags = VppEnum.vl_api_mfib_entry_flags_t
813
Neale Ranns15002542017-09-10 04:39:11 -0700814 #
815 # An (S,G).
816 # one accepting interface, pg0, 2 forwarding interfaces
817 #
818 route_1_1_1_1_232_1_1_1 = VppIpMRoute(
819 self,
820 "1.1.1.1",
821 "232.1.1.1", 64,
Neale Ranns990f6942020-10-20 07:20:17 +0000822 MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
Neale Ranns15002542017-09-10 04:39:11 -0700823 [VppMRoutePath(self.pg8.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000824 MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT),
Neale Ranns15002542017-09-10 04:39:11 -0700825 VppMRoutePath(self.pg1.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000826 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD),
Neale Ranns15002542017-09-10 04:39:11 -0700827 VppMRoutePath(self.pg2.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000828 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD)],
Neale Ranns15002542017-09-10 04:39:11 -0700829 table_id=10)
830 route_1_1_1_1_232_1_1_1.add_vpp_config()
831
832 #
833 # a stream that matches the route for (1.1.1.1,232.1.1.1)
834 # small packets
835 #
836 self.vapi.cli("clear trace")
837 tx = self.create_stream_ip4(self.pg8, "1.1.1.1", "232.1.1.1")
838 self.pg8.add_stream(tx)
839
840 self.pg_enable_capture(self.pg_interfaces)
841 self.pg_start()
842
843 # We expect replications on Pg1 & 2
844 self.verify_capture_ip4(self.pg1, tx)
845 self.verify_capture_ip4(self.pg2, tx)
846
Neale Rannsadb17a82019-08-04 02:41:57 -0700847 def test_ip_mcast_gre(self):
848 """ IP Multicast Replication over GRE"""
849
Neale Ranns990f6942020-10-20 07:20:17 +0000850 MRouteItfFlags = VppEnum.vl_api_mfib_itf_flags_t
851 MRouteEntryFlags = VppEnum.vl_api_mfib_entry_flags_t
852
Neale Rannsadb17a82019-08-04 02:41:57 -0700853 gre_if_1 = VppGreInterface(
854 self,
855 self.pg1.local_ip4,
856 self.pg1.remote_ip4).add_vpp_config()
857 gre_if_2 = VppGreInterface(
858 self,
859 self.pg2.local_ip4,
860 self.pg2.remote_ip4).add_vpp_config()
861 gre_if_3 = VppGreInterface(
862 self,
863 self.pg3.local_ip4,
864 self.pg3.remote_ip4).add_vpp_config()
865
866 gre_if_1.admin_up()
867 gre_if_1.config_ip4()
868 gre_if_2.admin_up()
869 gre_if_2.config_ip4()
870 gre_if_3.admin_up()
871 gre_if_3.config_ip4()
872
873 #
874 # An (S,G).
875 # one accepting interface, pg0, 2 forwarding interfaces
876 #
877 route_1_1_1_1_232_1_1_1 = VppIpMRoute(
878 self,
879 "1.1.1.1",
880 "232.2.2.2", 64,
Neale Ranns990f6942020-10-20 07:20:17 +0000881 MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
Neale Rannsadb17a82019-08-04 02:41:57 -0700882 [VppMRoutePath(gre_if_1.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000883 MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT),
Neale Rannsadb17a82019-08-04 02:41:57 -0700884 VppMRoutePath(gre_if_2.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000885 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD),
Neale Rannsadb17a82019-08-04 02:41:57 -0700886 VppMRoutePath(gre_if_3.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +0000887 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD)])
Neale Rannsadb17a82019-08-04 02:41:57 -0700888 route_1_1_1_1_232_1_1_1.add_vpp_config()
889
890 #
891 # a stream that matches the route for (1.1.1.1,232.2.2.2)
892 # small packets
893 #
894 tx = (Ether(dst=self.pg1.local_mac,
895 src=self.pg1.remote_mac) /
896 IP(src=self.pg1.remote_ip4,
897 dst=self.pg1.local_ip4) /
898 GRE() /
899 IP(src="1.1.1.1", dst="232.2.2.2") /
900 UDP(sport=1234, dport=1234) /
Ole Troan770a0de2019-11-07 13:52:21 +0100901 Raw(b'\a5' * 64)) * 63
Neale Rannsadb17a82019-08-04 02:41:57 -0700902
903 self.vapi.cli("clear trace")
904 self.pg1.add_stream(tx)
905
906 self.pg_enable_capture(self.pg_interfaces)
907 self.pg_start()
908
909 # We expect replications on Pg2 & 3
910 # check the encap headers are as expected based on the egress tunnel
911 rxs = self.pg2.get_capture(len(tx))
912 for rx in rxs:
913 self.assertEqual(rx[IP].src, gre_if_2.t_src)
914 self.assertEqual(rx[IP].dst, gre_if_2.t_dst)
915 self.assert_packet_checksums_valid(rx)
916
917 rxs = self.pg3.get_capture(len(tx))
918 for rx in rxs:
919 self.assertEqual(rx[IP].src, gre_if_3.t_src)
920 self.assertEqual(rx[IP].dst, gre_if_3.t_dst)
921 self.assert_packet_checksums_valid(rx)
922
Neale Ranns7d8a9562020-11-20 14:32:56 +0000923 def test_ip6_mcast_gre(self):
924 """ IP6 Multicast Replication over GRE"""
925
926 MRouteItfFlags = VppEnum.vl_api_mfib_itf_flags_t
927 MRouteEntryFlags = VppEnum.vl_api_mfib_entry_flags_t
928
929 gre_if_1 = VppGreInterface(
930 self,
931 self.pg1.local_ip4,
932 self.pg1.remote_ip4).add_vpp_config()
933 gre_if_2 = VppGreInterface(
934 self,
935 self.pg2.local_ip4,
936 self.pg2.remote_ip4).add_vpp_config()
937 gre_if_3 = VppGreInterface(
938 self,
939 self.pg3.local_ip4,
940 self.pg3.remote_ip4).add_vpp_config()
941
942 gre_if_1.admin_up()
943 gre_if_1.config_ip6()
944 gre_if_2.admin_up()
945 gre_if_2.config_ip6()
946 gre_if_3.admin_up()
947 gre_if_3.config_ip6()
948
949 #
950 # An (S,G).
951 # one accepting interface, pg0, 2 forwarding interfaces
952 #
953 route_1_1_FF_1 = VppIpMRoute(
954 self,
955 "1::1",
956 "FF00::1", 256,
957 MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
958 [VppMRoutePath(gre_if_1.sw_if_index,
959 MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT),
960 VppMRoutePath(gre_if_2.sw_if_index,
961 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD),
962 VppMRoutePath(gre_if_3.sw_if_index,
963 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD)])
964 route_1_1_FF_1.add_vpp_config()
965
966 #
967 # a stream that matches the route for (1::1, FF::1)
968 # small packets
969 #
970 tx = (Ether(dst=self.pg1.local_mac,
971 src=self.pg1.remote_mac) /
972 IP(src=self.pg1.remote_ip4,
973 dst=self.pg1.local_ip4) /
974 GRE() /
975 IPv6(src="1::1", dst="FF00::1") /
976 UDP(sport=1234, dport=1234) /
977 Raw(b'\a5' * 64)) * 63
978
979 self.vapi.cli("clear trace")
980 self.pg1.add_stream(tx)
981
982 self.pg_enable_capture(self.pg_interfaces)
983 self.pg_start()
984
985 # We expect replications on Pg2 & 3
986 # check the encap headers are as expected based on the egress tunnel
987 rxs = self.pg2.get_capture(len(tx))
988 for rx in rxs:
989 self.assertEqual(rx[IP].src, gre_if_2.t_src)
990 self.assertEqual(rx[IP].dst, gre_if_2.t_dst)
991 self.assert_packet_checksums_valid(rx)
992
993 rxs = self.pg3.get_capture(len(tx))
994 for rx in rxs:
995 self.assertEqual(rx[IP].src, gre_if_3.t_src)
996 self.assertEqual(rx[IP].dst, gre_if_3.t_dst)
997 self.assert_packet_checksums_valid(rx)
998
Neale Ranns15002542017-09-10 04:39:11 -0700999 def test_ip6_mcast_vrf(self):
1000 """ IPv6 Multicast Replication in non-default table"""
1001
Neale Ranns990f6942020-10-20 07:20:17 +00001002 MRouteItfFlags = VppEnum.vl_api_mfib_itf_flags_t
1003 MRouteEntryFlags = VppEnum.vl_api_mfib_entry_flags_t
1004
Neale Ranns15002542017-09-10 04:39:11 -07001005 #
1006 # An (S,G).
1007 # one accepting interface, pg0, 2 forwarding interfaces
1008 #
1009 route_2001_ff01_1 = VppIpMRoute(
1010 self,
1011 "2001::1",
1012 "ff01::1", 256,
Neale Ranns990f6942020-10-20 07:20:17 +00001013 MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
Neale Ranns15002542017-09-10 04:39:11 -07001014 [VppMRoutePath(self.pg8.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +00001015 MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT,
Neale Ranns097fa662018-05-01 05:17:55 -07001016 proto=FibPathProto.FIB_PATH_NH_PROTO_IP6),
Neale Ranns15002542017-09-10 04:39:11 -07001017 VppMRoutePath(self.pg1.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +00001018 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD,
Neale Ranns097fa662018-05-01 05:17:55 -07001019 proto=FibPathProto.FIB_PATH_NH_PROTO_IP6),
Neale Ranns15002542017-09-10 04:39:11 -07001020 VppMRoutePath(self.pg2.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +00001021 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD,
Neale Ranns097fa662018-05-01 05:17:55 -07001022 proto=FibPathProto.FIB_PATH_NH_PROTO_IP6)],
1023 table_id=10)
Neale Ranns15002542017-09-10 04:39:11 -07001024 route_2001_ff01_1.add_vpp_config()
1025
1026 #
1027 # a stream that matches the route for (2001::1, ff00::1)
1028 #
1029 self.vapi.cli("clear trace")
1030 tx = self.create_stream_ip6(self.pg8, "2001::1", "ff01::1")
1031 self.pg8.add_stream(tx)
1032
1033 self.pg_enable_capture(self.pg_interfaces)
1034 self.pg_start()
1035
1036 # We expect replications on Pg1, 2,
1037 self.verify_capture_ip6(self.pg1, tx)
1038 self.verify_capture_ip6(self.pg2, tx)
Neale Ranns32e1c012016-11-22 17:07:28 +00001039
Neale Rannscf3561b2017-12-13 01:44:25 -08001040 def test_bidir(self):
1041 """ IP Multicast Bi-directional """
1042
Neale Ranns990f6942020-10-20 07:20:17 +00001043 MRouteItfFlags = VppEnum.vl_api_mfib_itf_flags_t
1044 MRouteEntryFlags = VppEnum.vl_api_mfib_entry_flags_t
1045
Neale Rannscf3561b2017-12-13 01:44:25 -08001046 #
1047 # A (*,G). The set of accepting interfaces matching the forwarding
1048 #
1049 route_232_1_1_1 = VppIpMRoute(
1050 self,
1051 "0.0.0.0",
1052 "232.1.1.1", 32,
Neale Ranns990f6942020-10-20 07:20:17 +00001053 MRouteEntryFlags.MFIB_API_ENTRY_FLAG_NONE,
Neale Rannscf3561b2017-12-13 01:44:25 -08001054 [VppMRoutePath(self.pg0.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +00001055 MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT |
1056 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD),
Neale Rannscf3561b2017-12-13 01:44:25 -08001057 VppMRoutePath(self.pg1.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +00001058 MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT |
1059 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD),
Neale Rannscf3561b2017-12-13 01:44:25 -08001060 VppMRoutePath(self.pg2.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +00001061 MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT |
1062 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD),
Neale Rannscf3561b2017-12-13 01:44:25 -08001063 VppMRoutePath(self.pg3.sw_if_index,
Neale Ranns990f6942020-10-20 07:20:17 +00001064 MRouteItfFlags.MFIB_API_ITF_FLAG_ACCEPT |
1065 MRouteItfFlags.MFIB_API_ITF_FLAG_FORWARD)])
Neale Rannscf3561b2017-12-13 01:44:25 -08001066 route_232_1_1_1.add_vpp_config()
1067
1068 tx = self.create_stream_ip4(self.pg0, "1.1.1.1", "232.1.1.1")
1069 self.pg0.add_stream(tx)
1070
1071 self.pg_enable_capture(self.pg_interfaces)
1072 self.pg_start()
1073
1074 # We expect replications on Pg1, 2, 3, but not on pg0
1075 self.verify_capture_ip4(self.pg1, tx)
1076 self.verify_capture_ip4(self.pg2, tx)
1077 self.verify_capture_ip4(self.pg3, tx)
1078 self.pg0.assert_nothing_captured(
1079 remark="IP multicast packets forwarded on PG0")
1080
1081
Neale Ranns32e1c012016-11-22 17:07:28 +00001082if __name__ == '__main__':
1083 unittest.main(testRunner=VppTestRunner)