diff options
author | Vladimir Isaev <visaev@netgate.com> | 2020-02-18 15:26:12 +0300 |
---|---|---|
committer | Neale Ranns <nranns@cisco.com> | 2020-02-20 09:12:52 +0000 |
commit | 1284f8c71da8ec35cba04351cf62cba7bdd7f847 (patch) | |
tree | 54cd46d45e4503c030737871431a35c60e1164e8 | |
parent | f145c15631ba62e798395499f83a2f8a91ae83c7 (diff) |
ip-neighbor: Fix aging timeout
Before this patch VPP checked age for ARP/NDP records every 1e5 seconds
for any configured aging time. This is 27 hours and it looks like
misprint because 1e5 is the number of 10us ticks in a second.
Also time to wait is now difference between aging time and time alive
for nodes in alive state.
Type: fix
Signed-off-by: Vladimir Isaev <visaev@netgate.com>
Change-Id: Ib5baa85032a44402d5f48c1145245260a42c7bae
-rw-r--r-- | src/vnet/ip-neighbor/ip_neighbor.c | 31 | ||||
-rw-r--r-- | test/test_neighbor.py | 23 |
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 # |