summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeale Ranns <neale@graphiant.com>2023-03-08 04:53:37 +0000
committerFlorin Coras <florin.coras@gmail.com>2023-09-24 02:29:00 +0000
commit39528796098973fe9a5411e0f6f94268c3324e94 (patch)
treef722676f850e0d4926aaef20302eab0b3ecbfba7
parent25801d6d2abee52dcafc8583b77d33d99a4bf313 (diff)
fib: Don't use an address from an attached prefix when sending ARP requests.
Change-Id: I4c3144794dd0bd7de6150929e53f6d305c496b17 Type: fix Signed-off-by: Neale Ranns <neale@graphiant.com> Change-Id: I7b0c2c2dec5e867970599b8f2f2da17f2ff0b17c
-rw-r--r--src/vnet/fib/fib_table.c6
-rw-r--r--src/vnet/ip-neighbor/ip4_neighbor.c10
-rw-r--r--test/test_neighbor.py22
3 files changed, 34 insertions, 4 deletions
diff --git a/src/vnet/fib/fib_table.c b/src/vnet/fib/fib_table.c
index 3a46d226ebd..85b17870eec 100644
--- a/src/vnet/fib/fib_table.c
+++ b/src/vnet/fib/fib_table.c
@@ -534,7 +534,11 @@ fib_table_route_path_fixup (const fib_prefix_t *prefix,
else if (fib_route_path_is_attached(path))
{
path->frp_flags |= FIB_ROUTE_PATH_GLEAN;
- fib_prefix_normalize(prefix, &path->frp_connected);
+ /*
+ * attached prefixes are not suitable as the source of ARP requests
+ * so don't save the prefix in the glean adj
+ */
+ clib_memset(&path->frp_connected, 0, sizeof(path->frp_connected));
}
if (*eflags & FIB_ENTRY_FLAG_DROP)
{
diff --git a/src/vnet/ip-neighbor/ip4_neighbor.c b/src/vnet/ip-neighbor/ip4_neighbor.c
index 2d4b2957ecd..8be4b824712 100644
--- a/src/vnet/ip-neighbor/ip4_neighbor.c
+++ b/src/vnet/ip-neighbor/ip4_neighbor.c
@@ -187,12 +187,16 @@ ip4_arp_inline (vlib_main_t * vm,
/* resolve the packet's destination */
ip4_header_t *ip0 = vlib_buffer_get_current (p0);
resolve0 = ip0->dst_address;
- src0 = adj0->sub_type.glean.rx_pfx.fp_addr.ip4;
}
else
+ /* resolve the incomplete adj */
+ resolve0 = adj0->sub_type.nbr.next_hop.ip4;
+
+ if (is_glean && adj0->sub_type.glean.rx_pfx.fp_len)
+ /* the glean is for a connected, local prefix */
+ src0 = adj0->sub_type.glean.rx_pfx.fp_addr.ip4;
+ else
{
- /* resolve the incomplete adj */
- resolve0 = adj0->sub_type.nbr.next_hop.ip4;
/* Src IP address in ARP header. */
if (!fib_sas4_get (sw_if_index0, &resolve0, &src0) &&
!ip4_sas_by_sw_if_index (sw_if_index0, &resolve0, &src0))
diff --git a/test/test_neighbor.py b/test/test_neighbor.py
index b600a97c3c2..24737da0eca 100644
--- a/test/test_neighbor.py
+++ b/test/test_neighbor.py
@@ -2069,6 +2069,28 @@ class ARPTestCase(VppTestCase):
for rx in rxs:
self.verify_arp_req(rx, self.pg1.local_mac, "10.0.1.2", "10.0.1.128")
+ # apply an attached prefix to the interface
+ # since there's no local address in this prefix,
+ # any other address is used
+ p3 = (
+ Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
+ / IP(src=self.pg1.remote_ip4, dst="10.0.2.128")
+ / Raw(b"0x5" * 100)
+ )
+
+ VppIpRoute(
+ self,
+ "10.0.2.0",
+ 24,
+ [VppRoutePath("0.0.0.0", self.pg1.sw_if_index)],
+ ).add_vpp_config()
+
+ rxs = self.send_and_expect(self.pg0, [p3], self.pg1)
+ for rx in rxs:
+ self.verify_arp_req(
+ rx, self.pg1.local_mac, self.pg1.local_ip4, "10.0.2.128"
+ )
+
# cleanup
conn3.remove_vpp_config()
conn2.remove_vpp_config()