diff options
author | Neale Ranns <nranns@cisco.com> | 2020-04-02 17:08:28 +0000 |
---|---|---|
committer | Neale Ranns <nranns@cisco.com> | 2020-04-23 08:15:39 +0000 |
commit | c87fbb417a580bf8e93d0176dba6a90b3cd6a787 (patch) | |
tree | a412c1c9afb4f8728632164d731f1adf67bfd6d3 /src/vnet/ip-neighbor/ip_neighbor.c | |
parent | c17ff6ec3b69ef228047bf346e0b524c48d2c96e (diff) |
ip-neighbor: Replace feature for the ip-neighbor data-base
Type: feature
DB replace is implemented with a mark and sweep algorithm (just the the
FIB)
Signed-off-by: Neale Ranns <nranns@cisco.com>
Change-Id: I54ab06e11552219e2a18e1b4a87d531321cf3829
Diffstat (limited to 'src/vnet/ip-neighbor/ip_neighbor.c')
-rw-r--r-- | src/vnet/ip-neighbor/ip_neighbor.c | 63 |
1 files changed, 63 insertions, 0 deletions
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 */ |