Tests to target holes in adjacency and DPO test coverage
[vpp.git] / test / test_ip_mcast.py
1 #!/usr/bin/env python
2
3 import unittest
4
5 from framework import VppTestCase, VppTestRunner
6 from vpp_sub_interface import VppSubInterface, VppDot1QSubint, VppDot1ADSubint
7 from vpp_ip_route import VppIpMRoute, VppMRoutePath, VppMFibSignal
8
9 from scapy.packet import Raw
10 from scapy.layers.l2 import Ether
11 from scapy.layers.inet import IP, UDP, getmacbyip
12 from scapy.layers.inet6 import IPv6, getmacbyip6
13 from util import ppp
14
15
16 class MRouteItfFlags:
17     MFIB_ITF_FLAG_NONE = 0
18     MFIB_ITF_FLAG_NEGATE_SIGNAL = 1
19     MFIB_ITF_FLAG_ACCEPT = 2
20     MFIB_ITF_FLAG_FORWARD = 4
21     MFIB_ITF_FLAG_SIGNAL_PRESENT = 8
22     MFIB_ITF_FLAG_INTERNAL_COPY = 16
23
24
25 class MRouteEntryFlags:
26     MFIB_ENTRY_FLAG_NONE = 0
27     MFIB_ENTRY_FLAG_SIGNAL = 1
28     MFIB_ENTRY_FLAG_DROP = 2
29     MFIB_ENTRY_FLAG_CONNECTED = 4
30     MFIB_ENTRY_FLAG_INHERIT_ACCEPT = 8
31
32 #
33 # The number of packets sent is set to 90 so that when we replicate more than 3
34 # times, which we do for some entries, we will generate more than 256 packets
35 # to the next node in the VLIB graph. Thus we are testing the code's
36 # correctness handling this over-flow
37 #
38 N_PKTS_IN_STREAM = 90
39
40
41 class TestMFIB(VppTestCase):
42     """ MFIB Test Case """
43
44     def setUp(self):
45         super(TestMFIB, self).setUp()
46
47     def test_mfib(self):
48         """ MFIB Unit Tests """
49         error = self.vapi.cli("test mfib")
50
51         if error:
52             self.logger.critical(error)
53         self.assertEqual(error.find("Failed"), -1)
54
55
56 class TestIPMcast(VppTestCase):
57     """ IP Multicast Test Case """
58
59     def setUp(self):
60         super(TestIPMcast, self).setUp()
61
62         # create 8 pg interfaces
63         self.create_pg_interfaces(range(8))
64
65         # setup interfaces
66         for i in self.pg_interfaces:
67             i.admin_up()
68             i.config_ip4()
69             i.config_ip6()
70             i.resolve_arp()
71             i.resolve_ndp()
72
73     def create_stream_ip4(self, src_if, src_ip, dst_ip):
74         pkts = []
75         for i in range(0, N_PKTS_IN_STREAM):
76             info = self.create_packet_info(src_if, src_if)
77             payload = self.info_to_payload(info)
78             p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
79                  IP(src=src_ip, dst=dst_ip) /
80                  UDP(sport=1234, dport=1234) /
81                  Raw(payload))
82             info.data = p.copy()
83             pkts.append(p)
84         return pkts
85
86     def create_stream_ip6(self, src_if, src_ip, dst_ip):
87         pkts = []
88         for i in range(0, N_PKTS_IN_STREAM):
89             info = self.create_packet_info(src_if, src_if)
90             payload = self.info_to_payload(info)
91             p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
92                  IPv6(src=src_ip, dst=dst_ip) /
93                  UDP(sport=1234, dport=1234) /
94                  Raw(payload))
95             info.data = p.copy()
96             pkts.append(p)
97         return pkts
98
99     def verify_filter(self, capture, sent):
100         if not len(capture) == len(sent):
101             # filter out any IPv6 RAs from the captur
102             for p in capture:
103                 if (p.haslayer(IPv6)):
104                     capture.remove(p)
105         return capture
106
107     def verify_capture_ip4(self, src_if, sent):
108         rxd = self.pg1.get_capture(N_PKTS_IN_STREAM)
109
110         try:
111             capture = self.verify_filter(rxd, sent)
112
113             self.assertEqual(len(capture), len(sent))
114
115             for i in range(len(capture)):
116                 tx = sent[i]
117                 rx = capture[i]
118
119                 # the rx'd packet has the MPLS label popped
120                 eth = rx[Ether]
121                 self.assertEqual(eth.type, 0x800)
122
123                 tx_ip = tx[IP]
124                 rx_ip = rx[IP]
125
126                 # check the MAC address on the RX'd packet is correctly formed
127                 self.assertEqual(eth.dst, getmacbyip(rx_ip.dst))
128
129                 self.assertEqual(rx_ip.src, tx_ip.src)
130                 self.assertEqual(rx_ip.dst, tx_ip.dst)
131                 # IP processing post pop has decremented the TTL
132                 self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
133
134         except:
135             raise
136
137     def verify_capture_ip6(self, src_if, sent):
138         capture = self.pg1.get_capture(N_PKTS_IN_STREAM)
139
140         self.assertEqual(len(capture), len(sent))
141
142         for i in range(len(capture)):
143             tx = sent[i]
144             rx = capture[i]
145
146             # the rx'd packet has the MPLS label popped
147             eth = rx[Ether]
148             self.assertEqual(eth.type, 0x86DD)
149
150             tx_ip = tx[IPv6]
151             rx_ip = rx[IPv6]
152
153             # check the MAC address on the RX'd packet is correctly formed
154             self.assertEqual(eth.dst, getmacbyip6(rx_ip.dst))
155
156             self.assertEqual(rx_ip.src, tx_ip.src)
157             self.assertEqual(rx_ip.dst, tx_ip.dst)
158             # IP processing post pop has decremented the TTL
159             self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
160
161     def test_ip_mcast(self):
162         """ IP Multicast Replication """
163
164         #
165         # a stream that matches the default route. gets dropped.
166         #
167         self.vapi.cli("clear trace")
168         tx = self.create_stream_ip4(self.pg0, "1.1.1.1", "232.1.1.1")
169         self.pg0.add_stream(tx)
170
171         self.pg_enable_capture(self.pg_interfaces)
172         self.pg_start()
173
174         self.pg0.assert_nothing_captured(
175             remark="IP multicast packets forwarded on default route")
176
177         #
178         # A (*,G).
179         # one accepting interface, pg0, 7 forwarding interfaces
180         #  many forwarding interfaces test the case where the replicare DPO
181         #  needs to use extra cache lines for the buckets.
182         #
183         route_232_1_1_1 = VppIpMRoute(
184             self,
185             "0.0.0.0",
186             "232.1.1.1", 32,
187             MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
188             [VppMRoutePath(self.pg0.sw_if_index,
189                            MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
190              VppMRoutePath(self.pg1.sw_if_index,
191                            MRouteItfFlags.MFIB_ITF_FLAG_FORWARD),
192              VppMRoutePath(self.pg2.sw_if_index,
193                            MRouteItfFlags.MFIB_ITF_FLAG_FORWARD),
194              VppMRoutePath(self.pg3.sw_if_index,
195                            MRouteItfFlags.MFIB_ITF_FLAG_FORWARD),
196              VppMRoutePath(self.pg4.sw_if_index,
197                            MRouteItfFlags.MFIB_ITF_FLAG_FORWARD),
198              VppMRoutePath(self.pg5.sw_if_index,
199                            MRouteItfFlags.MFIB_ITF_FLAG_FORWARD),
200              VppMRoutePath(self.pg6.sw_if_index,
201                            MRouteItfFlags.MFIB_ITF_FLAG_FORWARD),
202              VppMRoutePath(self.pg7.sw_if_index,
203                            MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
204         route_232_1_1_1.add_vpp_config()
205
206         #
207         # An (S,G).
208         # one accepting interface, pg0, 2 forwarding interfaces
209         #
210         route_1_1_1_1_232_1_1_1 = VppIpMRoute(
211             self,
212             "1.1.1.1",
213             "232.1.1.1", 64,
214             MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
215             [VppMRoutePath(self.pg0.sw_if_index,
216                            MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
217              VppMRoutePath(self.pg1.sw_if_index,
218                            MRouteItfFlags.MFIB_ITF_FLAG_FORWARD),
219              VppMRoutePath(self.pg2.sw_if_index,
220                            MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
221         route_1_1_1_1_232_1_1_1.add_vpp_config()
222
223         #
224         # An (*,G/m).
225         # one accepting interface, pg0, 1 forwarding interfaces
226         #
227         route_232 = VppIpMRoute(
228             self,
229             "0.0.0.0",
230             "232.0.0.0", 8,
231             MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
232             [VppMRoutePath(self.pg0.sw_if_index,
233                            MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
234              VppMRoutePath(self.pg1.sw_if_index,
235                            MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
236         route_232.add_vpp_config()
237
238         #
239         # a stream that matches the route for (1.1.1.1,232.1.1.1)
240         #
241         self.vapi.cli("clear trace")
242         tx = self.create_stream_ip4(self.pg0, "1.1.1.1", "232.1.1.1")
243         self.pg0.add_stream(tx)
244
245         self.pg_enable_capture(self.pg_interfaces)
246         self.pg_start()
247
248         # We expect replications on Pg1->7
249         self.verify_capture_ip4(self.pg1, tx)
250         self.verify_capture_ip4(self.pg2, tx)
251         self.verify_capture_ip4(self.pg3, tx)
252         self.verify_capture_ip4(self.pg4, tx)
253         self.verify_capture_ip4(self.pg5, tx)
254         self.verify_capture_ip4(self.pg6, tx)
255         self.verify_capture_ip4(self.pg7, tx)
256
257         # no replications on Pg0
258         self.pg0.assert_nothing_captured(
259             remark="IP multicast packets forwarded on PG0")
260         self.pg3.assert_nothing_captured(
261             remark="IP multicast packets forwarded on PG3")
262
263         #
264         # a stream that matches the route for (*,232.0.0.0/8)
265         # Send packets with the 9th bit set so we test the correct clearing
266         # of that bit in the mac rewrite
267         #
268         self.vapi.cli("clear trace")
269         tx = self.create_stream_ip4(self.pg0, "1.1.1.1", "232.255.255.255")
270         self.pg0.add_stream(tx)
271
272         self.pg_enable_capture(self.pg_interfaces)
273         self.pg_start()
274
275         # We expect replications on Pg1 only
276         self.verify_capture_ip4(self.pg1, tx)
277
278         # no replications on Pg0, Pg2 not Pg3
279         self.pg0.assert_nothing_captured(
280             remark="IP multicast packets forwarded on PG0")
281         self.pg2.assert_nothing_captured(
282             remark="IP multicast packets forwarded on PG2")
283         self.pg3.assert_nothing_captured(
284             remark="IP multicast packets forwarded on PG3")
285
286         #
287         # a stream that matches the route for (*,232.1.1.1)
288         #
289         self.vapi.cli("clear trace")
290         tx = self.create_stream_ip4(self.pg0, "1.1.1.2", "232.1.1.1")
291         self.pg0.add_stream(tx)
292
293         self.pg_enable_capture(self.pg_interfaces)
294         self.pg_start()
295
296         # We expect replications on Pg1, 2, 3.
297         self.verify_capture_ip4(self.pg1, tx)
298         self.verify_capture_ip4(self.pg2, tx)
299         self.verify_capture_ip4(self.pg3, tx)
300
301         # no replications on Pg0
302         self.pg0.assert_nothing_captured(
303             remark="IP multicast packets forwarded on PG0")
304
305         route_232_1_1_1.remove_vpp_config()
306         route_1_1_1_1_232_1_1_1.remove_vpp_config()
307         route_232.remove_vpp_config()
308
309     def test_ip6_mcast(self):
310         """ IPv6 Multicast Replication """
311
312         #
313         # a stream that matches the default route. gets dropped.
314         #
315         self.vapi.cli("clear trace")
316         tx = self.create_stream_ip6(self.pg0, "2001::1", "ff01::1")
317         self.pg0.add_stream(tx)
318
319         self.pg_enable_capture(self.pg_interfaces)
320         self.pg_start()
321
322         self.pg0.assert_nothing_captured(
323             remark="IPv6 multicast packets forwarded on default route")
324
325         #
326         # A (*,G).
327         # one accepting interface, pg0, 3 forwarding interfaces
328         #
329         route_ff01_1 = VppIpMRoute(
330             self,
331             "::",
332             "ff01::1", 128,
333             MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
334             [VppMRoutePath(self.pg0.sw_if_index,
335                            MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
336              VppMRoutePath(self.pg1.sw_if_index,
337                            MRouteItfFlags.MFIB_ITF_FLAG_FORWARD),
338              VppMRoutePath(self.pg2.sw_if_index,
339                            MRouteItfFlags.MFIB_ITF_FLAG_FORWARD),
340              VppMRoutePath(self.pg3.sw_if_index,
341                            MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)],
342             is_ip6=1)
343         route_ff01_1.add_vpp_config()
344
345         #
346         # An (S,G).
347         # one accepting interface, pg0, 2 forwarding interfaces
348         #
349         route_2001_ff01_1 = VppIpMRoute(
350             self,
351             "2001::1",
352             "ff01::1", 256,
353             MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
354             [VppMRoutePath(self.pg0.sw_if_index,
355                            MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
356              VppMRoutePath(self.pg1.sw_if_index,
357                            MRouteItfFlags.MFIB_ITF_FLAG_FORWARD),
358              VppMRoutePath(self.pg2.sw_if_index,
359                            MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)],
360             is_ip6=1)
361         route_2001_ff01_1.add_vpp_config()
362
363         #
364         # An (*,G/m).
365         # one accepting interface, pg0, 1 forwarding interface
366         #
367         route_ff01 = VppIpMRoute(
368             self,
369             "::",
370             "ff01::", 16,
371             MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
372             [VppMRoutePath(self.pg0.sw_if_index,
373                            MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
374              VppMRoutePath(self.pg1.sw_if_index,
375                            MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)],
376             is_ip6=1)
377         route_ff01.add_vpp_config()
378
379         #
380         # a stream that matches the route for (*, ff01::/16)
381         #
382         self.vapi.cli("clear trace")
383         tx = self.create_stream_ip6(self.pg0, "2002::1", "ff01:2::255")
384         self.pg0.add_stream(tx)
385
386         self.pg_enable_capture(self.pg_interfaces)
387         self.pg_start()
388
389         # We expect replications on Pg1
390         self.verify_capture_ip6(self.pg1, tx)
391
392         # no replications on Pg0, Pg3
393         self.pg0.assert_nothing_captured(
394             remark="IP multicast packets forwarded on PG0")
395         self.pg2.assert_nothing_captured(
396             remark="IP multicast packets forwarded on PG2")
397         self.pg3.assert_nothing_captured(
398             remark="IP multicast packets forwarded on PG3")
399
400         #
401         # a stream that matches the route for (*,ff01::1)
402         #
403         self.vapi.cli("clear trace")
404         tx = self.create_stream_ip6(self.pg0, "2002::2", "ff01::1")
405         self.pg0.add_stream(tx)
406
407         self.pg_enable_capture(self.pg_interfaces)
408         self.pg_start()
409
410         # We expect replications on Pg1, 2, 3.
411         self.verify_capture_ip6(self.pg1, tx)
412         self.verify_capture_ip6(self.pg2, tx)
413         self.verify_capture_ip6(self.pg3, tx)
414
415         # no replications on Pg0
416         self.pg0.assert_nothing_captured(
417             remark="IPv6 multicast packets forwarded on PG0")
418
419         #
420         # a stream that matches the route for (2001::1, ff00::1)
421         #
422         self.vapi.cli("clear trace")
423         tx = self.create_stream_ip6(self.pg0, "2001::1", "ff01::1")
424         self.pg0.add_stream(tx)
425
426         self.pg_enable_capture(self.pg_interfaces)
427         self.pg_start()
428
429         # We expect replications on Pg1, 2,
430         self.verify_capture_ip6(self.pg1, tx)
431         self.verify_capture_ip6(self.pg2, tx)
432
433         # no replications on Pg0, Pg3
434         self.pg0.assert_nothing_captured(
435             remark="IP multicast packets forwarded on PG0")
436         self.pg3.assert_nothing_captured(
437             remark="IP multicast packets forwarded on PG3")
438
439         route_ff01.remove_vpp_config()
440         route_ff01_1.remove_vpp_config()
441         route_2001_ff01_1.remove_vpp_config()
442
443     def _mcast_connected_send_stream(self, dst_ip):
444         self.vapi.cli("clear trace")
445         tx = self.create_stream_ip4(self.pg0,
446                                     self.pg0.remote_ip4,
447                                     dst_ip)
448         self.pg0.add_stream(tx)
449
450         self.pg_enable_capture(self.pg_interfaces)
451         self.pg_start()
452
453         # We expect replications on Pg1.
454         self.verify_capture_ip4(self.pg1, tx)
455
456         return tx
457
458     def test_ip_mcast_connected(self):
459         """ IP Multicast Connected Source check """
460
461         #
462         # A (*,G).
463         # one accepting interface, pg0, 1 forwarding interfaces
464         #
465         route_232_1_1_1 = VppIpMRoute(
466             self,
467             "0.0.0.0",
468             "232.1.1.1", 32,
469             MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
470             [VppMRoutePath(self.pg0.sw_if_index,
471                            MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
472              VppMRoutePath(self.pg1.sw_if_index,
473                            MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
474
475         route_232_1_1_1.add_vpp_config()
476         route_232_1_1_1.update_entry_flags(
477             MRouteEntryFlags.MFIB_ENTRY_FLAG_CONNECTED)
478
479         #
480         # Now the (*,G) is present, send from connected source
481         #
482         tx = self._mcast_connected_send_stream("232.1.1.1")
483
484         #
485         # Constrct a representation of the signal we expect on pg0
486         #
487         signal_232_1_1_1_itf_0 = VppMFibSignal(self,
488                                                route_232_1_1_1,
489                                                self.pg0.sw_if_index,
490                                                tx[0])
491
492         #
493         # read the only expected signal
494         #
495         signals = self.vapi.mfib_signal_dump()
496
497         self.assertEqual(1, len(signals))
498
499         signal_232_1_1_1_itf_0.compare(signals[0])
500
501         #
502         # reading the signal allows for the generation of another
503         # so send more packets and expect the next signal
504         #
505         tx = self._mcast_connected_send_stream("232.1.1.1")
506
507         signals = self.vapi.mfib_signal_dump()
508         self.assertEqual(1, len(signals))
509         signal_232_1_1_1_itf_0.compare(signals[0])
510
511         #
512         # A Second entry with connected check
513         # one accepting interface, pg0, 1 forwarding interfaces
514         #
515         route_232_1_1_2 = VppIpMRoute(
516             self,
517             "0.0.0.0",
518             "232.1.1.2", 32,
519             MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
520             [VppMRoutePath(self.pg0.sw_if_index,
521                            MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
522              VppMRoutePath(self.pg1.sw_if_index,
523                            MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
524
525         route_232_1_1_2.add_vpp_config()
526         route_232_1_1_2.update_entry_flags(
527             MRouteEntryFlags.MFIB_ENTRY_FLAG_CONNECTED)
528
529         #
530         # Send traffic to both entries. One read should net us two signals
531         #
532         signal_232_1_1_2_itf_0 = VppMFibSignal(self,
533                                                route_232_1_1_2,
534                                                self.pg0.sw_if_index,
535                                                tx[0])
536         tx = self._mcast_connected_send_stream("232.1.1.1")
537         tx2 = self._mcast_connected_send_stream("232.1.1.2")
538
539         #
540         # read the only expected signal
541         #
542         signals = self.vapi.mfib_signal_dump()
543
544         self.assertEqual(2, len(signals))
545
546         signal_232_1_1_1_itf_0.compare(signals[1])
547         signal_232_1_1_2_itf_0.compare(signals[0])
548
549         route_232_1_1_1.remove_vpp_config()
550         route_232_1_1_2.remove_vpp_config()
551
552     def test_ip_mcast_signal(self):
553         """ IP Multicast Signal """
554
555         #
556         # A (*,G).
557         # one accepting interface, pg0, 1 forwarding interfaces
558         #
559         route_232_1_1_1 = VppIpMRoute(
560             self,
561             "0.0.0.0",
562             "232.1.1.1", 32,
563             MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
564             [VppMRoutePath(self.pg0.sw_if_index,
565                            MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
566              VppMRoutePath(self.pg1.sw_if_index,
567                            MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
568
569         route_232_1_1_1.add_vpp_config()
570         route_232_1_1_1.update_entry_flags(
571             MRouteEntryFlags.MFIB_ENTRY_FLAG_SIGNAL)
572
573         #
574         # Now the (*,G) is present, send from connected source
575         #
576         tx = self._mcast_connected_send_stream("232.1.1.1")
577
578         #
579         # Constrct a representation of the signal we expect on pg0
580         #
581         signal_232_1_1_1_itf_0 = VppMFibSignal(self,
582                                                route_232_1_1_1,
583                                                self.pg0.sw_if_index,
584                                                tx[0])
585
586         #
587         # read the only expected signal
588         #
589         signals = self.vapi.mfib_signal_dump()
590
591         self.assertEqual(1, len(signals))
592
593         signal_232_1_1_1_itf_0.compare(signals[0])
594
595         #
596         # reading the signal allows for the generation of another
597         # so send more packets and expect the next signal
598         #
599         tx = self._mcast_connected_send_stream("232.1.1.1")
600
601         signals = self.vapi.mfib_signal_dump()
602         self.assertEqual(1, len(signals))
603         signal_232_1_1_1_itf_0.compare(signals[0])
604
605         #
606         # Set the negate-signal on the accepting interval - the signals
607         # should stop
608         #
609         route_232_1_1_1.update_path_flags(
610             self.pg0.sw_if_index,
611             (MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT |
612              MRouteItfFlags.MFIB_ITF_FLAG_NEGATE_SIGNAL))
613
614         tx = self._mcast_connected_send_stream("232.1.1.1")
615
616         signals = self.vapi.mfib_signal_dump()
617         self.assertEqual(0, len(signals))
618
619         #
620         # Clear the SIGNAL flag on the entry and the signals should
621         # come back since the interface is still NEGATE-SIGNAL
622         #
623         route_232_1_1_1.update_entry_flags(
624             MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE)
625
626         tx = self._mcast_connected_send_stream("232.1.1.1")
627
628         signals = self.vapi.mfib_signal_dump()
629         self.assertEqual(1, len(signals))
630         signal_232_1_1_1_itf_0.compare(signals[0])
631
632         #
633         # Lastly remove the NEGATE-SIGNAL from the interface and the
634         # signals should stop
635         #
636         route_232_1_1_1.update_path_flags(self.pg0.sw_if_index,
637                                           MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT)
638
639         tx = self._mcast_connected_send_stream("232.1.1.1")
640         signals = self.vapi.mfib_signal_dump()
641         self.assertEqual(0, len(signals))
642
643         #
644         # Cleanup
645         #
646         route_232_1_1_1.remove_vpp_config()
647
648
649 if __name__ == '__main__':
650     unittest.main(testRunner=VppTestRunner)