aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeale Ranns <neale@graphiant.com>2022-02-17 15:41:32 +0000
committerOle Tr�an <otroan@employees.org>2022-03-04 16:25:00 +0000
commitf478f758b9fc13089a4ff47fa1e66d7d1db9f003 (patch)
treefa9941f247208fe6e085ee17e336ae49d2c5e377
parent5c6dd17a373a2c56e57f02426d66a79af7faa19c (diff)
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 <neale@graphiant.com> Change-Id: I18a232d90ddd3ef051a52476c5d861c87060e76f
-rw-r--r--src/plugins/ping/ping.c42
-rw-r--r--test/test_mpls.py49
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