X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fip-neighbor%2Fip_neighbor.c;h=5b18473e46280ea8d4e33505d4d3d263db327b60;hb=refs%2Fchanges%2F25%2F26325%2F5;hp=960da1252a860a76f054f806b61fe04a3ee31194;hpb=c17ff6ec3b69ef228047bf346e0b524c48d2c96e;p=vpp.git diff --git a/src/vnet/ip-neighbor/ip_neighbor.c b/src/vnet/ip-neighbor/ip_neighbor.c index 960da1252a8..5b18473e462 100644 --- a/src/vnet/ip-neighbor/ip_neighbor.c +++ b/src/vnet/ip-neighbor/ip_neighbor.c @@ -99,6 +99,12 @@ ip_neighbor_get_index (const ip_neighbor_t * ipn) return (ipn - ip_neighbor_pool); } +static void +ip_neighbor_touch (ip_neighbor_t * ipn) +{ + ipn->ipn_flags &= ~IP_NEIGHBOR_FLAG_STALE; +} + static bool ip_neighbor_is_dynamic (const ip_neighbor_t * ipn) { @@ -145,6 +151,7 @@ ip_neighbor_refresh (ip_neighbor_t * ipn) * list is time sorted, newest first */ ip_neighbor_elt_t *elt, *head; + ip_neighbor_touch (ipn); ipn->ipn_time_last_updated = vlib_time_now (vlib_get_main ()); ipn->ipn_n_probes = 0; @@ -473,6 +480,8 @@ ip_neighbor_add (const ip46_address_t * ip, format_ip_neighbor_flags, flags, format_mac_address_t, mac); + ip_neighbor_touch (ipn); + /* Refuse to over-write static neighbor entry. */ if (!(flags & IP_NEIGHBOR_FLAG_STATIC) && (ipn->ipn_flags & IP_NEIGHBOR_FLAG_STATIC)) @@ -1177,6 +1186,60 @@ ip_neighbor_flush (ip46_type_t type, u32 sw_if_index) vec_free (ipnis); } +static walk_rc_t +ip_neighbor_mark_one (index_t ipni, void *ctx) +{ + ip_neighbor_t *ipn; + + ipn = ip_neighbor_get (ipni); + + ipn->ipn_flags |= IP_NEIGHBOR_FLAG_STALE; + + return (WALK_CONTINUE); +} + +void +ip_neighbor_mark (ip46_type_t type) +{ + ip_neighbor_walk (type, ~0, ip_neighbor_mark_one, NULL); +} + +typedef struct ip_neighbor_sweep_ctx_t_ +{ + index_t *ipnsc_stale; +} ip_neighbor_sweep_ctx_t; + +static walk_rc_t +ip_neighbor_sweep_one (index_t ipni, void *arg) +{ + ip_neighbor_sweep_ctx_t *ctx = arg; + ip_neighbor_t *ipn; + + ipn = ip_neighbor_get (ipni); + + if (ipn->ipn_flags & IP_NEIGHBOR_FLAG_STALE) + { + vec_add1 (ctx->ipnsc_stale, ipni); + } + + return (WALK_CONTINUE); +} + +void +ip_neighbor_sweep (ip46_type_t type) +{ + ip_neighbor_sweep_ctx_t ctx = { }; + index_t *ipni; + + ip_neighbor_walk (type, ~0, ip_neighbor_sweep_one, &ctx); + + vec_foreach (ipni, ctx.ipnsc_stale) + { + ip_neighbor_free (ip_neighbor_get (*ipni)); + } + vec_free (ctx.ipnsc_stale); +} + /* * Remove any arp entries associated with the specified interface */