X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fip-neighbor%2Fip_neighbor.c;h=960da1252a860a76f054f806b61fe04a3ee31194;hb=282872127;hp=ceec3732c77affcd879879193568a77d10835deb;hpb=5002e7f26f4f2f94af56e0d4b26124fb876e2a3f;p=vpp.git diff --git a/src/vnet/ip-neighbor/ip_neighbor.c b/src/vnet/ip-neighbor/ip_neighbor.c index ceec3732c77..960da1252a8 100644 --- a/src/vnet/ip-neighbor/ip_neighbor.c +++ b/src/vnet/ip-neighbor/ip_neighbor.c @@ -339,7 +339,7 @@ ip_neighbor_mk_incomplete (adj_index_t ai) ethernet_build_rewrite (vnet_get_main (), adj-> rewrite_header.sw_if_index, - adj_get_link_type (ai), + VNET_LINK_ARP, VNET_REWRITE_FOR_SW_INTERFACE_ADDRESS_BROADCAST)); } @@ -615,6 +615,13 @@ ip_neighbor_update (vnet_main_t * vnm, adj_index_t ai) * wouldn't be bad either, but that's more code than i'm prepared to * write at this time for relatively little reward. */ + /* + * adj_nbr_update_rewrite may actually call fib_walk_sync. + * fib_walk_sync may allocate a new adjacency and potentially cause + * a realloc for adj_pool. When that happens, adj pointer is no + * longer valid here.x We refresh adj pointer accordingly. + */ + adj = adj_get (ai); ip_neighbor_probe (adj); } break; @@ -1395,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 @@ -1429,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); } @@ -1474,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]); @@ -1491,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) { @@ -1518,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; } }