diff options
-rw-r--r-- | src/vnet/ip/ip4_error.h | 1 | ||||
-rwxr-xr-x | src/vnet/ip/ip4_forward.c | 17 | ||||
-rw-r--r-- | test/test_ip_mcast.py | 46 |
3 files changed, 60 insertions, 4 deletions
diff --git a/src/vnet/ip/ip4_error.h b/src/vnet/ip/ip4_error.h index d2775636539..d9b56bc2f49 100644 --- a/src/vnet/ip/ip4_error.h +++ b/src/vnet/ip/ip4_error.h @@ -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") \ diff --git a/src/vnet/ip/ip4_forward.c b/src/vnet/ip/ip4_forward.c index c7cf362a3c0..2f3f340264f 100755 --- a/src/vnet/ip/ip4_forward.c +++ b/src/vnet/ip/ip4_forward.c @@ -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 diff --git a/test/test_ip_mcast.py b/test/test_ip_mcast.py index 8ca92df26b2..f3d23a612db 100644 --- a/test/test_ip_mcast.py +++ b/test/test_ip_mcast.py @@ -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) |