diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/vnet/ip-neighbor/ip_neighbor.api | 16 | ||||
-rw-r--r-- | src/vnet/ip-neighbor/ip_neighbor.c | 34 | ||||
-rw-r--r-- | src/vnet/ip-neighbor/ip_neighbor.h | 2 | ||||
-rw-r--r-- | src/vnet/ip-neighbor/ip_neighbor_api.c | 19 |
4 files changed, 71 insertions, 0 deletions
diff --git a/src/vnet/ip-neighbor/ip_neighbor.api b/src/vnet/ip-neighbor/ip_neighbor.api index 473024a49ea..fe344af5c82 100644 --- a/src/vnet/ip-neighbor/ip_neighbor.api +++ b/src/vnet/ip-neighbor/ip_neighbor.api @@ -163,6 +163,22 @@ autoreply define ip_neighbor_replace_end u32 context; }; +/** \brief IP neighbor flush request - removes *all* neighbours. + dynamic and static from API/CLI and dynamic from data-plane. + + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param af - Flush neighbours of this address family + @param sw_if_index - Flush on this interface (~0 => all interfaces) +*/ +autoreply define ip_neighbor_flush +{ + u32 client_index; + u32 context; + vl_api_address_family_t af; + vl_api_interface_index_t sw_if_index [default=0xffffffff]; +}; + /** \brief Register for IP4 ARP resolution event on receiving ARP reply or MAC/IP info from ARP requests in L2 BDs @param client_index - opaque cookie to identify the sender diff --git a/src/vnet/ip-neighbor/ip_neighbor.c b/src/vnet/ip-neighbor/ip_neighbor.c index 5b18473e462..afb97acb39c 100644 --- a/src/vnet/ip-neighbor/ip_neighbor.c +++ b/src/vnet/ip-neighbor/ip_neighbor.c @@ -576,6 +576,40 @@ ip_neighbor_del (const ip46_address_t * ip, ip46_type_t type, u32 sw_if_index) return (0); } +typedef struct ip_neighbor_del_all_ctx_t_ +{ + index_t *ipn_del; +} ip_neighbor_del_all_ctx_t; + +static walk_rc_t +ip_neighbor_del_all_walk_cb (index_t ipni, void *arg) +{ + ip_neighbor_del_all_ctx_t *ctx = arg; + + vec_add1 (ctx->ipn_del, ipni); + + return (WALK_CONTINUE); +} + +void +ip_neighbor_del_all (ip46_type_t type, u32 sw_if_index) +{ + IP_NEIGHBOR_INFO ("delete-all: %U, %U", + format_ip46_type, type, + format_vnet_sw_if_index_name, vnet_get_main (), + sw_if_index); + + ip_neighbor_del_all_ctx_t ctx = { + .ipn_del = NULL, + }; + index_t *ipni; + + ip_neighbor_walk (type, sw_if_index, ip_neighbor_del_all_walk_cb, &ctx); + + vec_foreach (ipni, ctx.ipn_del) ip_neighbor_free (ip_neighbor_get (*ipni)); + vec_free (ctx.ipn_del); +} + void ip_neighbor_update (vnet_main_t * vnm, adj_index_t ai) { diff --git a/src/vnet/ip-neighbor/ip_neighbor.h b/src/vnet/ip-neighbor/ip_neighbor.h index 8769fd5efd7..cdceadb0859 100644 --- a/src/vnet/ip-neighbor/ip_neighbor.h +++ b/src/vnet/ip-neighbor/ip_neighbor.h @@ -41,6 +41,8 @@ extern int ip_neighbor_del (const ip46_address_t * ip, extern int ip_neighbor_config (ip46_type_t type, u32 limit, u32 age, bool recycle); +extern void ip_neighbor_del_all (ip46_type_t type, u32 sw_if_index); + typedef walk_rc_t (*ip_neighbor_walk_cb_t) (index_t ipni, void *ctx); extern void ip_neighbor_walk (ip46_type_t type, u32 sw_if_index, diff --git a/src/vnet/ip-neighbor/ip_neighbor_api.c b/src/vnet/ip-neighbor/ip_neighbor_api.c index 86587fab31b..02952c7ba24 100644 --- a/src/vnet/ip-neighbor/ip_neighbor_api.c +++ b/src/vnet/ip-neighbor/ip_neighbor_api.c @@ -301,6 +301,25 @@ vl_api_ip_neighbor_replace_end_t_handler (vl_api_ip_neighbor_replace_end_t * REPLY_MACRO (VL_API_IP_NEIGHBOR_REPLACE_END_REPLY); } +static void +vl_api_ip_neighbor_flush_t_handler (vl_api_ip_neighbor_flush_t * mp) +{ + vl_api_ip_neighbor_flush_reply_t *rmp; + ip_address_family_t af; + int rv; + + if (mp->sw_if_index != ~0) + VALIDATE_SW_IF_INDEX (mp); + + rv = ip_address_family_decode (mp->af, &af); + + if (!rv) + ip_neighbor_del_all (ip46_type_from_af (af), ntohl (mp->sw_if_index)); + + BAD_SW_IF_INDEX_LABEL; + REPLY_MACRO (VL_API_IP_NEIGHBOR_FLUSH_REPLY); +} + #define vl_msg_name_crc_list #include <vnet/ip-neighbor/ip_neighbor.api.h> #undef vl_msg_name_crc_list |