From f478f758b9fc13089a4ff47fa1e66d7d1db9f003 Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Thu, 17 Feb 2022 15:41:32 +0000 Subject: ping: correct the fib-index used for the reply Type: fix if original packet was to the link local, then the fib index in the buffer 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. Add a test for IPv6 ping in an MPLS-VPN where int inout interface is not the the same VRF as the response should be sent. Signed-off-by: Neale Ranns Change-Id: I18a232d90ddd3ef051a52476c5d861c87060e76f --- src/plugins/ping/ping.c | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) (limited to 'src/plugins') 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, -- cgit 1.2.3-korg