summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladimir Isaev <visaev@netgate.com>2020-07-16 17:05:18 +0300
committerMatthew Smith <mgsmith@netgate.com>2020-07-31 16:02:49 +0000
commitb2f44bd8e7d226d851d4d05981914e642a4da571 (patch)
treed9e1c242be1860237ce5d2c10f9d53c99085df9f
parent5d27037d165ce55dd80aa472a367923d6a08f755 (diff)
ip-neighbor: Allow to replace dynamic entry
Before this patch it was not allowed to replace a dynamic ARP entry with a static one with the same mac-address. Type: fix Signed-off-by: Vladimir Isaev <visaev@netgate.com> Change-Id: I6cfc0e510ffdf141c61874288f11a60395182374
-rw-r--r--src/vnet/ip-neighbor/ip_neighbor.c24
-rw-r--r--test/test_neighbor.py110
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)