aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/vnet/ip-neighbor/ip_neighbor.c31
-rw-r--r--test/test_neighbor.py23
2 files changed, 41 insertions, 13 deletions
diff --git a/src/vnet/ip-neighbor/ip_neighbor.c b/src/vnet/ip-neighbor/ip_neighbor.c
index 6af76d262a4..960da1252a8 100644
--- a/src/vnet/ip-neighbor/ip_neighbor.c
+++ b/src/vnet/ip-neighbor/ip_neighbor.c
@@ -1402,22 +1402,24 @@ static ip_neighbor_age_state_t
ip_neighbour_age_out (index_t ipni, f64 now, f64 * wait)
{
ip_neighbor_t *ipn;
- f64 ttl;
+ u32 ipndb_age;
+ u32 ttl;
ipn = ip_neighbor_get (ipni);
+ ipndb_age = ip_neighbor_db[ipn->ipn_key->ipnk_type].ipndb_age;
ttl = now - ipn->ipn_time_last_updated;
- *wait = IP_NEIGHBOR_PROCESS_SLEEP_LONG;
+ *wait = ipndb_age;
- if (ttl > ip_neighbor_db[ipn->ipn_key->ipnk_type].ipndb_age)
+ if (ttl > ipndb_age)
{
IP_NEIGHBOR_DBG ("aged: %U @%f - %f > %d",
format_ip_neighbor, ipni, now,
- ipn->ipn_time_last_updated,
- ip_neighbor_db[ipn->ipn_key->ipnk_type].ipndb_age);
+ ipn->ipn_time_last_updated, ipndb_age);
if (ipn->ipn_n_probes > 2)
{
/* 3 strikes and yea-re out */
IP_NEIGHBOR_DBG ("dead: %U", format_ip_neighbor, ipni);
+ *wait = 1;
return (IP_NEIGHBOR_AGE_DEAD);
}
else
@@ -1436,7 +1438,8 @@ ip_neighbour_age_out (index_t ipni, f64 now, f64 * wait)
}
else
{
- *wait = ttl;
+ /* here we are sure that ttl <= ipndb_age */
+ *wait = ipndb_age - ttl + 1;
return (IP_NEIGHBOR_AGE_ALIVE);
}
@@ -1481,7 +1484,7 @@ ip_neighbor_age_loop (vlib_main_t * vm,
ip_neighbor_elt_t *elt, *head;
f64 wait;
- timeout = 1e5;
+ timeout = ip_neighbor_db[type].ipndb_age;
head = pool_elt_at_index (ip_neighbor_elt_pool,
ip_neighbor_list_head[type]);
@@ -1498,6 +1501,7 @@ ip_neighbor_age_loop (vlib_main_t * vm,
if (IP_NEIGHBOR_AGE_ALIVE == res) {
/* the oldest neighbor has not yet expired, go back to sleep */
+ timeout = clib_min (wait, timeout);
break;
}
else if (IP_NEIGHBOR_AGE_DEAD == res) {
@@ -1525,13 +1529,16 @@ ip_neighbor_age_loop (vlib_main_t * vm,
head = pool_elt_at_index (ip_neighbor_elt_pool,
ip_neighbor_list_head[type]);
- elt = clib_llist_prev (ip_neighbor_elt_pool, ipne_anchor, head);
+ /* no neighbors yet */
+ if (clib_llist_is_empty (ip_neighbor_elt_pool, ipne_anchor, head))
+ {
+ timeout = ip_neighbor_db[type].ipndb_age;
+ break;
+ }
/* poke the oldset neighbour for aging, which returns how long we sleep for */
- if (IP_NEIGHBOR_AGE_PROBE ==
- ip_neighbour_age_out (elt->ipne_index, now, &timeout))
- /* we probed for the oldest entry, sleep for a short time to get to the next */
- timeout = 0.01;
+ elt = clib_llist_prev (ip_neighbor_elt_pool, ipne_anchor, head);
+ ip_neighbour_age_out (elt->ipne_index, now, &timeout);
break;
}
}
diff --git a/test/test_neighbor.py b/test/test_neighbor.py
index d1fb8f83582..7157839127b 100644
--- a/test/test_neighbor.py
+++ b/test/test_neighbor.py
@@ -1731,7 +1731,7 @@ class NeighborAgeTestCase(VppTestCase):
#
# Set the neighbor configuration:
# limi = 200
- # age = 2 seconds
+ # age = 0 seconds
# recycle = false
#
self.vapi.ip_neighbor_config(af=vaf.ADDRESS_IP4,
@@ -1809,6 +1809,27 @@ class NeighborAgeTestCase(VppTestCase):
af=vaf.ADDRESS_IP4))
#
+ # load up some neighbours again with 2s aging enabled
+ # they should be removed after 10s (2s age + 4s for probes + gap)
+ #
+ for ii in range(10):
+ VppNeighbor(self,
+ self.pg0.sw_if_index,
+ self.pg0.remote_hosts[ii].mac,
+ self.pg0.remote_hosts[ii].ip4).add_vpp_config()
+ self.sleep(10)
+ self.assertFalse(self.vapi.ip_neighbor_dump(sw_if_index=0xffffffff,
+ af=vaf.ADDRESS_IP4))
+
+ #
+ # check if we can set age and recycle with empty neighbor list
+ #
+ self.vapi.ip_neighbor_config(af=vaf.ADDRESS_IP4,
+ max_number=200,
+ max_age=1000,
+ recycle=True)
+
+ #
# load up some neighbours again, then disable the aging
# they should still be there in 10 seconds time
#