diff options
-rw-r--r-- | src/vnet/arp/arp.c | 13 | ||||
-rw-r--r-- | test/test_neighbor.py | 31 | ||||
-rw-r--r-- | test/vpp_neighbor.py | 3 |
3 files changed, 41 insertions, 6 deletions
diff --git a/src/vnet/arp/arp.c b/src/vnet/arp/arp.c index 14a1ae97d1e..6a32229adda 100644 --- a/src/vnet/arp/arp.c +++ b/src/vnet/arp/arp.c @@ -543,6 +543,8 @@ arp_reply (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) dst_fei = ip4_fib_table_lookup (ip4_fib_get (fib_index0), &arp0->ip4_over_ethernet[1].ip4, 32); + conn_sw_if_index0 = fib_entry_get_resolving_interface (dst_fei); + switch (arp_dst_fib_check (dst_fei, &dst_flags)) { case ARP_DST_FIB_ADJ: @@ -554,10 +556,12 @@ arp_reply (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) * from spamming us with gratuitous ARPS that might otherwise * blow our ARP cache */ - if (arp0->ip4_over_ethernet[0].ip4.as_u32 == - arp0->ip4_over_ethernet[1].ip4.as_u32) - error0 = - arp_learn (sw_if_index0, &arp0->ip4_over_ethernet[0]); + if (conn_sw_if_index0 != sw_if_index0) + error0 = ETHERNET_ARP_ERROR_l3_dst_address_not_local; + else if (arp0->ip4_over_ethernet[0].ip4.as_u32 == + arp0->ip4_over_ethernet[1].ip4.as_u32) + error0 = arp_learn (sw_if_index0, + &arp0->ip4_over_ethernet[0]); goto drop; case ARP_DST_FIB_CONN: /* destination is connected, continue to process */ @@ -615,7 +619,6 @@ arp_reply (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) } /* Honor unnumbered interface, if any */ - conn_sw_if_index0 = fib_entry_get_resolving_interface (dst_fei); if (sw_if_index0 != conn_sw_if_index0 || sw_if_index0 != fib_entry_get_resolving_interface (src_fei)) { diff --git a/test/test_neighbor.py b/test/test_neighbor.py index 1045f4ba1e9..dfefb151091 100644 --- a/test/test_neighbor.py +++ b/test/test_neighbor.py @@ -1435,6 +1435,7 @@ class ARPTestCase(VppTestCase): # Generate some hosts on the LAN # self.pg1.generate_remote_hosts(4) + self.pg2.generate_remote_hosts(4) # # And an ARP entry @@ -1526,6 +1527,36 @@ class ARPTestCase(VppTestCase): self.pg1.sw_if_index, self.pg1.remote_hosts[2].ip4)) + # + # IP address in different subnets are not learnt + # + self.pg2.configure_ipv4_neighbors() + + for op in ["is-at", "who-has"]: + p1 = [(Ether(dst="ff:ff:ff:ff:ff:ff", + src=self.pg2.remote_hosts[1].mac) / + ARP(op=op, + hwdst=self.pg2.local_mac, + hwsrc=self.pg2.remote_hosts[1].mac, + pdst=self.pg2.remote_hosts[1].ip4, + psrc=self.pg2.remote_hosts[1].ip4)), + (Ether(dst="ff:ff:ff:ff:ff:ff", + src=self.pg2.remote_hosts[1].mac) / + ARP(op=op, + hwdst="ff:ff:ff:ff:ff:ff", + hwsrc=self.pg2.remote_hosts[1].mac, + pdst=self.pg2.remote_hosts[1].ip4, + psrc=self.pg2.remote_hosts[1].ip4))] + + self.send_and_assert_no_replies(self.pg1, p1) + self.assertFalse(find_nbr(self, + self.pg1.sw_if_index, + self.pg2.remote_hosts[1].ip4)) + + # they are all dropped because the subnet's don't match + self.assertEqual(4, self.statistics.get_err_counter( + "/err/arp-reply/IP4 destination address not local to subnet")) + def test_arp_incomplete(self): """ Incomplete Entries """ diff --git a/test/vpp_neighbor.py b/test/vpp_neighbor.py index ffe87d93b58..6f5426180fb 100644 --- a/test/vpp_neighbor.py +++ b/test/vpp_neighbor.py @@ -20,7 +20,8 @@ def find_nbr(test, sw_if_index, nbr_addr, is_static=0, mac=None): af=ip_addr.vapi_af) for n in nbrs: - if ip_addr == n.neighbor.ip_address and \ + if sw_if_index == n.neighbor.sw_if_index and \ + ip_addr == n.neighbor.ip_address and \ is_static == (n.neighbor.flags & e.IP_API_NEIGHBOR_FLAG_STATIC): if mac: if mac == str(n.neighbor.mac_address): |