diff options
-rw-r--r-- | src/vnet/ip-neighbor/ip_neighbor.c | 24 | ||||
-rw-r--r-- | test/test_neighbor.py | 110 |
2 files changed, 123 insertions, 11 deletions
diff --git a/src/vnet/ip-neighbor/ip_neighbor.c b/src/vnet/ip-neighbor/ip_neighbor.c index 09b56058f72..4111b02d0d8 100644 --- a/src/vnet/ip-neighbor/ip_neighbor.c +++ b/src/vnet/ip-neighbor/ip_neighbor.c @@ -141,6 +141,8 @@ ip_neighbor_list_remove (ip_neighbor_t * ipn) elt = pool_elt_at_index (ip_neighbor_elt_pool, ipn->ipn_elt); clib_llist_remove (ip_neighbor_elt_pool, ipne_anchor, elt); + + ipn->ipn_elt = ~0; } } @@ -492,6 +494,17 @@ ip_neighbor_add (const ip46_address_t * ip, return -2; } + /* A dynamic entry can become static, but not vice-versa. + * i.e. since if it was programmed by the CP then it must + * be removed by the CP */ + if ((flags & IP_NEIGHBOR_FLAG_STATIC) && + !(ipn->ipn_flags & IP_NEIGHBOR_FLAG_STATIC)) + { + ip_neighbor_list_remove (ipn); + ipn->ipn_flags |= IP_NEIGHBOR_FLAG_STATIC; + ipn->ipn_flags &= ~IP_NEIGHBOR_FLAG_DYNAMIC; + } + /* * prevent a DoS attack from the data-plane that * spams us with no-op updates to the MAC address @@ -503,17 +516,6 @@ ip_neighbor_add (const ip46_address_t * ip, } mac_address_copy (&ipn->ipn_mac, mac); - - /* A dynamic entry can become static, but not vice-versa. - * i.e. since if it was programmed by the CP then it must - * be removed by the CP */ - if ((flags & IP_NEIGHBOR_FLAG_STATIC) && - !(ipn->ipn_flags & IP_NEIGHBOR_FLAG_STATIC)) - { - ip_neighbor_list_remove (ipn); - ipn->ipn_flags |= IP_NEIGHBOR_FLAG_STATIC; - ipn->ipn_flags &= ~IP_NEIGHBOR_FLAG_DYNAMIC; - } } else { diff --git a/test/test_neighbor.py b/test/test_neighbor.py index 416241e8a64..1045f4ba1e9 100644 --- a/test/test_neighbor.py +++ b/test/test_neighbor.py @@ -1247,6 +1247,116 @@ class ARPTestCase(VppTestCase): static_arp.remove_vpp_config() self.pg2.set_table_ip4(0) + def test_arp_static_replace_dynamic_same_mac(self): + """ ARP Static can replace Dynamic (same mac) """ + self.pg2.generate_remote_hosts(1) + + dyn_arp = VppNeighbor(self, + self.pg2.sw_if_index, + self.pg2.remote_hosts[0].mac, + self.pg2.remote_hosts[0].ip4) + static_arp = VppNeighbor(self, + self.pg2.sw_if_index, + self.pg2.remote_hosts[0].mac, + self.pg2.remote_hosts[0].ip4, + is_static=1) + + # + # Add a dynamic ARP entry + # + dyn_arp.add_vpp_config() + + # + # We should find the dynamic nbr + # + self.assertFalse(find_nbr(self, + self.pg2.sw_if_index, + self.pg2.remote_hosts[0].ip4, + is_static=1)) + self.assertTrue(find_nbr(self, + self.pg2.sw_if_index, + self.pg2.remote_hosts[0].ip4, + is_static=0, + mac=self.pg2.remote_hosts[0].mac)) + + # + # Add a static ARP entry with the same mac + # + static_arp.add_vpp_config() + + # + # We should now find the static nbr with the same mac + # + self.assertFalse(find_nbr(self, + self.pg2.sw_if_index, + self.pg2.remote_hosts[0].ip4, + is_static=0)) + self.assertTrue(find_nbr(self, + self.pg2.sw_if_index, + self.pg2.remote_hosts[0].ip4, + is_static=1, + mac=self.pg2.remote_hosts[0].mac)) + + # + # clean-up + # + static_arp.remove_vpp_config() + + def test_arp_static_replace_dynamic_diff_mac(self): + """ ARP Static can replace Dynamic (diff mac) """ + self.pg2.generate_remote_hosts(2) + + dyn_arp = VppNeighbor(self, + self.pg2.sw_if_index, + self.pg2.remote_hosts[0].mac, + self.pg2.remote_hosts[0].ip4) + static_arp = VppNeighbor(self, + self.pg2.sw_if_index, + self.pg2.remote_hosts[1].mac, + self.pg2.remote_hosts[0].ip4, + is_static=1) + + # + # Add a dynamic ARP entry + # + dyn_arp.add_vpp_config() + + # + # We should find the dynamic nbr + # + self.assertFalse(find_nbr(self, + self.pg2.sw_if_index, + self.pg2.remote_hosts[0].ip4, + is_static=1)) + self.assertTrue(find_nbr(self, + self.pg2.sw_if_index, + self.pg2.remote_hosts[0].ip4, + is_static=0, + mac=self.pg2.remote_hosts[0].mac)) + + # + # Add a static ARP entry with a changed mac + # + static_arp.add_vpp_config() + + # + # We should now find the static nbr with a changed mac + # + self.assertFalse(find_nbr(self, + self.pg2.sw_if_index, + self.pg2.remote_hosts[0].ip4, + is_static=0)) + self.assertTrue(find_nbr(self, + self.pg2.sw_if_index, + self.pg2.remote_hosts[0].ip4, + is_static=1, + mac=self.pg2.remote_hosts[1].mac)) + + # + # clean-up + # + static_arp.remove_vpp_config() + def test_arp_incomplete(self): """ ARP Incomplete""" self.pg1.generate_remote_hosts(3) |