diff options
-rw-r--r-- | src/plugins/ping/ping.c | 42 | ||||
-rw-r--r-- | test/test_mpls.py | 49 |
2 files changed, 62 insertions, 29 deletions
diff --git a/src/plugins/ping/ping.c b/src/plugins/ping/ping.c index 2cc6b771268..050048211e6 100644 --- a/src/plugins/ping/ping.c +++ b/src/plugins/ping/ping.c @@ -662,15 +662,20 @@ ip6_icmp_echo_request (vlib_main_t *vm, vlib_node_runtime_t *node, ip0->hop_limit = im->host_config.ttl; ip1->hop_limit = im->host_config.ttl; - /* Determine the correct lookup fib indices... */ - fib_index0 = vec_elt (im->fib_index_by_sw_if_index, - vnet_buffer (p0)->sw_if_index[VLIB_RX]); - vnet_buffer (p0)->sw_if_index[VLIB_TX] = fib_index0; - /* Determine the correct lookup fib indices... */ - fib_index1 = vec_elt (im->fib_index_by_sw_if_index, - vnet_buffer (p1)->sw_if_index[VLIB_RX]); - vnet_buffer (p1)->sw_if_index[VLIB_TX] = fib_index1; - + if (ip6_address_is_link_local_unicast (&ip0->src_address) && + !ip6_address_is_link_local_unicast (&ip0->dst_address)) + { + fib_index0 = vec_elt (im->fib_index_by_sw_if_index, + vnet_buffer (p0)->sw_if_index[VLIB_RX]); + vnet_buffer (p0)->sw_if_index[VLIB_TX] = fib_index0; + } + if (ip6_address_is_link_local_unicast (&ip1->src_address) && + !ip6_address_is_link_local_unicast (&ip1->dst_address)) + { + fib_index1 = vec_elt (im->fib_index_by_sw_if_index, + vnet_buffer (p1)->sw_if_index[VLIB_RX]); + vnet_buffer (p1)->sw_if_index[VLIB_TX] = fib_index1; + } p0->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED; p1->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED; @@ -722,12 +727,19 @@ ip6_icmp_echo_request (vlib_main_t *vm, vlib_node_runtime_t *node, ip0->hop_limit = im->host_config.ttl; - /* if the packet is link local, we'll bounce through the link-local - * table with the RX interface correctly set */ - fib_index0 = vec_elt (im->fib_index_by_sw_if_index, - vnet_buffer (p0)->sw_if_index[VLIB_RX]); - vnet_buffer (p0)->sw_if_index[VLIB_TX] = fib_index0; - + if (ip6_address_is_link_local_unicast (&ip0->src_address) && + !ip6_address_is_link_local_unicast (&ip0->dst_address)) + { + /* if original packet was to the link local, then the + * fib index is that of the LL table, we can't use that + * to foward the response if the new destination + * is global, so reset to the fib index of the link. + * In other case, the fib index we need has been written + * to the buffer already. */ + fib_index0 = vec_elt (im->fib_index_by_sw_if_index, + vnet_buffer (p0)->sw_if_index[VLIB_RX]); + vnet_buffer (p0)->sw_if_index[VLIB_TX] = fib_index0; + } p0->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED; /* Verify speculative enqueue, maybe switch current next frame */ vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, diff --git a/test/test_mpls.py b/test/test_mpls.py index f7709d10cc1..4cc7a0759f2 100644 --- a/test/test_mpls.py +++ b/test/test_mpls.py @@ -18,7 +18,7 @@ import scapy.compat from scapy.packet import Raw from scapy.layers.l2 import Ether, ARP from scapy.layers.inet import IP, UDP, ICMP -from scapy.layers.inet6 import IPv6, ICMPv6TimeExceeded +from scapy.layers.inet6 import IPv6, ICMPv6TimeExceeded, ICMPv6EchoRequest from scapy.contrib.mpls import MPLS NUM_PKTS = 67 @@ -196,7 +196,8 @@ class TestMPLS(VppTestCase): return pkts def create_stream_labelled_ip6(self, src_if, mpls_labels, - hlim=64, dst_ip=None): + hlim=64, dst_ip=None, + ping=0, ip_itf=None): if dst_ip is None: dst_ip = src_if.remote_ip6 self.reset_packet_infos() @@ -208,9 +209,14 @@ class TestMPLS(VppTestCase): for l in mpls_labels: p = p / MPLS(label=l.value, ttl=l.ttl, cos=l.exp) - p = p / (IPv6(src=src_if.remote_ip6, dst=dst_ip, hlim=hlim) / - UDP(sport=1234, dport=1234) / - Raw(payload)) + if ping: + p = p / (IPv6(src=ip_itf.remote_ip6, + dst=ip_itf.local_ip6) / + ICMPv6EchoRequest()) + else: + p = p / (IPv6(src=src_if.remote_ip6, dst=dst_ip, hlim=hlim) / + UDP(sport=1234, dport=1234) / + Raw(payload)) info.data = p.copy() pkts.append(p) return pkts @@ -337,7 +343,8 @@ class TestMPLS(VppTestCase): raise def verify_capture_ip6(self, src_if, capture, sent, - ip_hlim=None, ip_dscp=0): + ip_hlim=None, ip_dscp=0, + ping_resp=0): try: self.assertEqual(len(capture), len(sent)) @@ -352,15 +359,18 @@ class TestMPLS(VppTestCase): tx_ip = tx[IPv6] rx_ip = rx[IPv6] - self.assertEqual(rx_ip.src, tx_ip.src) - self.assertEqual(rx_ip.dst, tx_ip.dst) - self.assertEqual(rx_ip.tc, ip_dscp) - # IP processing post pop has decremented the TTL - if not ip_hlim: - self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim) + if not ping_resp: + self.assertEqual(rx_ip.src, tx_ip.src) + self.assertEqual(rx_ip.dst, tx_ip.dst) + self.assertEqual(rx_ip.tc, ip_dscp) + # IP processing post pop has decremented the TTL + if not ip_hlim: + self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim) + else: + self.assertEqual(rx_ip.hlim, ip_hlim) else: - self.assertEqual(rx_ip.hlim, ip_hlim) - + self.assertEqual(rx_ip.src, tx_ip.dst) + self.assertEqual(rx_ip.dst, tx_ip.src) except: raise @@ -1170,6 +1180,13 @@ class TestMPLS(VppTestCase): 0xffffffff, nh_table_id=1)]) route_35_eos.add_vpp_config() + route_356_eos = VppMplsRoute( + self, 356, 1, + [VppRoutePath("0::0", + 0xffffffff, + nh_table_id=1)], + eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP6) + route_356_eos.add_vpp_config() # # ping an interface in the non-default table @@ -1180,6 +1197,10 @@ class TestMPLS(VppTestCase): self.pg0, [VppMplsLabel(35)], ping=1, ip_itf=self.pg1) rx = self.send_and_expect(self.pg0, tx, self.pg1) self.verify_capture_ip4(self.pg1, rx, tx, ping_resp=1) + tx = self.create_stream_labelled_ip6( + self.pg0, [VppMplsLabel(356)], ping=1, ip_itf=self.pg1) + rx = self.send_and_expect(self.pg0, tx, self.pg1) + self.verify_capture_ip6(self.pg1, rx, tx, ping_resp=1) # # Double pop |