diff options
-rw-r--r-- | src/vnet/fib/fib_table.c | 6 | ||||
-rw-r--r-- | src/vnet/ip-neighbor/ip4_neighbor.c | 10 | ||||
-rw-r--r-- | test/test_neighbor.py | 22 |
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() |