IP bi-direction multicast - same cable check on egress 19/9819/3
authorNeale Ranns <nranns@cisco.com>
Wed, 13 Dec 2017 09:44:25 +0000 (01:44 -0800)
committerFlorin Coras <florin.coras@gmail.com>
Wed, 13 Dec 2017 21:53:11 +0000 (21:53 +0000)
Change-Id: I655382f7f74181dd7c795a2b22f151f76b50e793
Signed-off-by: Neale Ranns <nranns@cisco.com>
src/vnet/ip/ip4_error.h
src/vnet/ip/ip4_forward.c
test/test_ip_mcast.py

index d277563..d9b56bc 100644 (file)
@@ -59,6 +59,7 @@
   _ (SRC_LOOKUP_MISS, "ip4 source lookup miss")                                \
   _ (DROP, "ip4 drop")                                                  \
   _ (PUNT, "ip4 punt")                                                  \
+  _ (SAME_INTERFACE, "ip4 egrees interface same as ingress")            \
                                                                        \
   /* Errors signalled by ip4-local. */                                 \
   _ (UNKNOWN_PROTOCOL, "unknown ip protocol")                          \
index c7cf362..2f3f340 100755 (executable)
@@ -2477,6 +2477,16 @@ ip4_rewrite_inline (vlib_main_t * vm,
             rewrite_header.max_l3_packet_bytes ? IP4_ERROR_MTU_EXCEEDED :
             error1);
 
+         if (is_mcast)
+           {
+             error0 = ((adj0[0].rewrite_header.sw_if_index ==
+                        vnet_buffer (p0)->sw_if_index[VLIB_RX]) ?
+                       IP4_ERROR_SAME_INTERFACE : error0);
+             error1 = ((adj1[0].rewrite_header.sw_if_index ==
+                        vnet_buffer (p1)->sw_if_index[VLIB_RX]) ?
+                       IP4_ERROR_SAME_INTERFACE : error1);
+           }
+
          /* Don't adjust the buffer for ttl issue; icmp-error node wants
           * to see the IP headerr */
          if (PREDICT_TRUE (error0 == IP4_ERROR_NONE))
@@ -2636,7 +2646,12 @@ ip4_rewrite_inline (vlib_main_t * vm,
          error0 = (vlib_buffer_length_in_chain (vm, p0)
                    > adj0[0].rewrite_header.max_l3_packet_bytes
                    ? IP4_ERROR_MTU_EXCEEDED : error0);
-
+         if (is_mcast)
+           {
+             error0 = ((adj0[0].rewrite_header.sw_if_index ==
+                        vnet_buffer (p0)->sw_if_index[VLIB_RX]) ?
+                       IP4_ERROR_SAME_INTERFACE : error0);
+           }
          p0->error = error_node->errors[error0];
 
          /* Don't adjust the buffer for ttl issue; icmp-error node wants
index 8ca92df..f3d23a6 100644 (file)
@@ -14,12 +14,13 @@ from scapy.layers.inet6 import IPv6, getmacbyip6
 from util import ppp
 
 #
-# The number of packets sent is set to 90 so that when we replicate more than 3
+# The number of packets sent is set to 91 so that when we replicate more than 3
 # times, which we do for some entries, we will generate more than 256 packets
 # to the next node in the VLIB graph. Thus we are testing the code's
-# correctness handling this over-flow
+# correctness handling this over-flow.
+# It's also an odd number so we hit any single loops.
 #
-N_PKTS_IN_STREAM = 90
+N_PKTS_IN_STREAM = 91
 
 
 class TestMFIB(VppTestCase):
@@ -757,5 +758,44 @@ class TestIPMcast(VppTestCase):
         self.verify_capture_ip6(self.pg1, tx)
         self.verify_capture_ip6(self.pg2, tx)
 
+    def test_bidir(self):
+        """ IP Multicast Bi-directional """
+
+        #
+        # A (*,G). The set of accepting interfaces matching the forwarding
+        #
+        route_232_1_1_1 = VppIpMRoute(
+            self,
+            "0.0.0.0",
+            "232.1.1.1", 32,
+            MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
+            [VppMRoutePath(self.pg0.sw_if_index,
+                           MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT |
+                           MRouteItfFlags.MFIB_ITF_FLAG_FORWARD),
+             VppMRoutePath(self.pg1.sw_if_index,
+                           MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT |
+                           MRouteItfFlags.MFIB_ITF_FLAG_FORWARD),
+             VppMRoutePath(self.pg2.sw_if_index,
+                           MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT |
+                           MRouteItfFlags.MFIB_ITF_FLAG_FORWARD),
+             VppMRoutePath(self.pg3.sw_if_index,
+                           MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT |
+                           MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
+        route_232_1_1_1.add_vpp_config()
+
+        tx = self.create_stream_ip4(self.pg0, "1.1.1.1", "232.1.1.1")
+        self.pg0.add_stream(tx)
+
+        self.pg_enable_capture(self.pg_interfaces)
+        self.pg_start()
+
+        # We expect replications on Pg1, 2, 3, but not on pg0
+        self.verify_capture_ip4(self.pg1, tx)
+        self.verify_capture_ip4(self.pg2, tx)
+        self.verify_capture_ip4(self.pg3, tx)
+        self.pg0.assert_nothing_captured(
+            remark="IP multicast packets forwarded on PG0")
+
+
 if __name__ == '__main__':
     unittest.main(testRunner=VppTestRunner)