From 0bdd319b3b5d7d4037605f9baba8889d30bd1717 Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Fri, 7 Sep 2018 11:04:52 -0700 Subject: [PATCH] IP-neighbor: add and delete internal API Change-Id: I4d1ab5ff0c8f0756e91bf63e045f88513bb7d039 Signed-off-by: Neale Ranns --- src/vnet/ip/ip6_neighbor.c | 30 +++++++++------------ src/vnet/ip/ip6_neighbor.h | 9 +++---- src/vnet/ip/ip6_packet.h | 9 ++++++- src/vnet/ip/ip_api.c | 47 +++++++++++---------------------- src/vnet/ip/ip_neighbor.c | 66 ++++++++++++++++++++++++++++++++++++++++++++-- src/vnet/ip/ip_neighbor.h | 15 +++++++++++ 6 files changed, 118 insertions(+), 58 deletions(-) diff --git a/src/vnet/ip/ip6_neighbor.c b/src/vnet/ip/ip6_neighbor.c index a54f9e91810..8466ba70313 100755 --- a/src/vnet/ip/ip6_neighbor.c +++ b/src/vnet/ip/ip6_neighbor.c @@ -414,8 +414,9 @@ static void ip6_neighbor_set_unset_rpc_callback static void set_unset_ip6_neighbor_rpc (vlib_main_t * vm, u32 sw_if_index, - ip6_address_t * a, u8 * link_layer_address, int is_add, int is_static, - int is_no_fib_entry) + const ip6_address_t * a, + const u8 * link_layer_address, + int is_add, int is_static, int is_no_fib_entry) { ip6_neighbor_set_unset_rpc_args_t args; void vl_api_rpc_call_main_thread (void *fp, u8 * data, u32 data_length); @@ -772,8 +773,8 @@ force_reuse_neighbor_entry (void) int vnet_set_ip6_ethernet_neighbor (vlib_main_t * vm, u32 sw_if_index, - ip6_address_t * a, - u8 * link_layer_address, + const ip6_address_t * a, + const u8 * link_layer_address, uword n_bytes_link_layer_address, int is_static, int is_no_fib_entry) { @@ -895,7 +896,7 @@ check_customers: pool_put (nm->pending_resolutions, pr); } - mhash_unset (&nm->pending_resolutions_by_address, a, 0); + mhash_unset (&nm->pending_resolutions_by_address, (void *) a, 0); } /* Customer(s) requesting ND event for this address? */ @@ -914,7 +915,8 @@ check_customers: /* Call the user's data callback, return 1 to suppress dup events */ if (fp) rv = - (*fp) (mc->data, link_layer_address, sw_if_index, &ip6a_zero); + (*fp) (mc->data, (u8 *) link_layer_address, sw_if_index, + &ip6a_zero); /* * Signal the resolver process, as long as the user * says they want to be notified @@ -931,10 +933,7 @@ check_customers: int vnet_unset_ip6_ethernet_neighbor (vlib_main_t * vm, - u32 sw_if_index, - ip6_address_t * a, - u8 * link_layer_address, - uword n_bytes_link_layer_address) + u32 sw_if_index, const ip6_address_t * a) { ip6_neighbor_main_t *nm = &ip6_neighbor_main; ip6_neighbor_key_t k; @@ -944,7 +943,7 @@ vnet_unset_ip6_ethernet_neighbor (vlib_main_t * vm, if (vlib_get_thread_index ()) { - set_unset_ip6_neighbor_rpc (vm, sw_if_index, a, link_layer_address, + set_unset_ip6_neighbor_rpc (vm, sw_if_index, a, NULL, 0 /* unset */ , 0, 0); return 0; } @@ -983,8 +982,7 @@ static void ip6_neighbor_set_unset_rpc_callback a->link_layer_address, 6, a->is_static, a->is_no_fib_entry); else - vnet_unset_ip6_ethernet_neighbor (vm, a->sw_if_index, &a->addr, - a->link_layer_address, 6); + vnet_unset_ip6_ethernet_neighbor (vm, a->sw_if_index, &a->addr); } static int @@ -1122,8 +1120,7 @@ set_ip6_neighbor (vlib_main_t * vm, mac_address, sizeof (mac_address), is_static, is_no_fib_entry); else - vnet_unset_ip6_ethernet_neighbor (vm, sw_if_index, &addr, - mac_address, sizeof (mac_address)); + vnet_unset_ip6_ethernet_neighbor (vm, sw_if_index, &addr); return 0; } @@ -4928,8 +4925,7 @@ ip6_neighbor_proxy_add_del (u32 sw_if_index, ip6_address_t * addr, u8 is_del) sw_if_index, ~0, 1, FIB_ROUTE_PATH_FLAG_NONE); /* flush the ND cache of this address if it's there */ - vnet_unset_ip6_ethernet_neighbor (vlib_get_main (), - sw_if_index, addr, NULL, 0); + vnet_unset_ip6_ethernet_neighbor (vlib_get_main (), sw_if_index, addr); } else { diff --git a/src/vnet/ip/ip6_neighbor.h b/src/vnet/ip/ip6_neighbor.h index b346563c83b..3256ba77da4 100644 --- a/src/vnet/ip/ip6_neighbor.h +++ b/src/vnet/ip/ip6_neighbor.h @@ -75,18 +75,15 @@ extern void vnet_register_ip6_neighbor_resolution_event (vnet_main_t * vnm, extern int vnet_set_ip6_ethernet_neighbor (vlib_main_t * vm, u32 sw_if_index, - ip6_address_t * a, - u8 * link_layer_address, + const ip6_address_t * a, + const u8 * link_layer_address, uword n_bytes_link_layer_address, int is_static, int is_no_fib_entry); extern int vnet_unset_ip6_ethernet_neighbor (vlib_main_t * vm, u32 sw_if_index, - ip6_address_t * a, - u8 * link_layer_address, - uword - n_bytes_link_layer_address); + const ip6_address_t * a); extern int ip6_neighbor_proxy_add_del (u32 sw_if_index, ip6_address_t * addr, u8 is_add); diff --git a/src/vnet/ip/ip6_packet.h b/src/vnet/ip/ip6_packet.h index 620740061c1..ea2fa155b5e 100644 --- a/src/vnet/ip/ip6_packet.h +++ b/src/vnet/ip/ip6_packet.h @@ -93,6 +93,8 @@ typedef CLIB_PACKED (union { #define ip46_address_is_zero(ip46) (((ip46)->as_u64[0] == 0) && ((ip46)->as_u64[1] == 0)) #define ip46_address_is_equal(a1, a2) (((a1)->as_u64[0] == (a2)->as_u64[0]) \ && ((a1)->as_u64[1] == (a2)->as_u64[1])) +#define ip46_address_initializer {{{ 0 }}} + static_always_inline void ip46_address_copy (ip46_address_t * dst, const ip46_address_t * src) { @@ -100,7 +102,12 @@ ip46_address_copy (ip46_address_t * dst, const ip46_address_t * src) dst->as_u64[1] = src->as_u64[1]; } -#define ip46_address_initializer {{{ 0 }}} +static_always_inline void +ip46_address_set_ip6 (ip46_address_t * dst, const ip6_address_t * src) +{ + dst->as_u64[0] = src->as_u64[0]; + dst->as_u64[1] = src->as_u64[1]; +} always_inline ip46_address_t to_ip46 (u32 is_ipv6, u8 * buf) diff --git a/src/vnet/ip/ip_api.c b/src/vnet/ip/ip_api.c index 31b7e40a880..431a777442f 100644 --- a/src/vnet/ip/ip_api.c +++ b/src/vnet/ip/ip_api.c @@ -653,48 +653,31 @@ static void vl_api_ip_neighbor_add_del_t_handler (vl_api_ip_neighbor_add_del_t * mp, vlib_main_t * vm) { + ip46_address_t ip = ip46_address_initializer; vl_api_ip_neighbor_add_del_reply_t *rmp; - vnet_main_t *vnm = vnet_get_main (); + ip_neighbor_flags_t flags; int rv = 0; VALIDATE_SW_IF_INDEX (mp); stats_dslock_with_hint (1 /* release hint */ , 7 /* tag */ ); - /* - * there's no validation here of the ND/ARP entry being added. - * The expectation is that the FIB will ensure that nothing bad - * will come of adding bogus entries. - */ + flags = IP_NEIGHBOR_FLAG_NODE; + if (mp->is_static) + flags |= IP_NEIGHBOR_FLAG_STATIC; + if (mp->is_no_adj_fib) + flags |= IP_NEIGHBOR_FLAG_NO_ADJ_FIB; + if (mp->is_ipv6) - { - if (mp->is_add) - rv = vnet_set_ip6_ethernet_neighbor - (vm, ntohl (mp->sw_if_index), - (ip6_address_t *) (mp->dst_address), - mp->mac_address, sizeof (mp->mac_address), mp->is_static, - mp->is_no_adj_fib); - else - rv = vnet_unset_ip6_ethernet_neighbor - (vm, ntohl (mp->sw_if_index), - (ip6_address_t *) (mp->dst_address), - mp->mac_address, sizeof (mp->mac_address)); - } + clib_memcpy (&ip.ip6, mp->dst_address, 16); else - { - ethernet_arp_ip4_over_ethernet_address_t a; - - clib_memcpy (&a.ethernet, mp->mac_address, 6); - clib_memcpy (&a.ip4, mp->dst_address, 4); + clib_memcpy (&ip.ip4, mp->dst_address, 4); - if (mp->is_add) - rv = vnet_arp_set_ip4_over_ethernet (vnm, ntohl (mp->sw_if_index), - &a, mp->is_static, - mp->is_no_adj_fib); - else - rv = - vnet_arp_unset_ip4_over_ethernet (vnm, ntohl (mp->sw_if_index), &a); - } + if (mp->is_add) + rv = ip_neighbor_add (&ip, mp->is_ipv6, mp->mac_address, + ntohl (mp->sw_if_index), flags); + else + rv = ip_neighbor_del (&ip, mp->is_ipv6, ntohl (mp->sw_if_index)); stats_dsunlock (); diff --git a/src/vnet/ip/ip_neighbor.c b/src/vnet/ip/ip_neighbor.c index 80437655f92..2edd737aa07 100644 --- a/src/vnet/ip/ip_neighbor.c +++ b/src/vnet/ip/ip_neighbor.c @@ -47,6 +47,69 @@ typedef struct static ip_neighbor_scan_config_t ip_neighbor_scan_conf; +int +ip_neighbor_add (const ip46_address_t * ip, + u8 is_ip6, + const u8 * mac, u32 sw_if_index, ip_neighbor_flags_t flags) +{ + int rv; + + /* + * there's no validation here of the ND/ARP entry being added. + * The expectation is that the FIB will ensure that nothing bad + * will come of adding bogus entries. + */ + if (is_ip6) + { + rv = vnet_set_ip6_ethernet_neighbor (vlib_get_main (), + sw_if_index, &ip->ip6, mac, 6, + (flags & IP_NEIGHBOR_FLAG_STATIC), + (flags & + IP_NEIGHBOR_FLAG_NO_ADJ_FIB)); + + } + else + { + ethernet_arp_ip4_over_ethernet_address_t a = { + .ip4 = ip->ip4, + }; + + clib_memcpy (&a.ethernet, mac, 6); + + rv = vnet_arp_set_ip4_over_ethernet (vnet_get_main (), + sw_if_index, + &a, + (flags & IP_NEIGHBOR_FLAG_STATIC), + (flags & + IP_NEIGHBOR_FLAG_NO_ADJ_FIB)); + } + + return (rv); +} + +int +ip_neighbor_del (const ip46_address_t * ip, u8 is_ip6, u32 sw_if_index) +{ + int rv; + + if (is_ip6) + { + rv = vnet_unset_ip6_ethernet_neighbor (vlib_get_main (), + sw_if_index, &ip->ip6); + } + else + { + ethernet_arp_ip4_over_ethernet_address_t a = { + .ip4 = ip->ip4, + }; + + rv = + vnet_arp_unset_ip4_over_ethernet (vnet_get_main (), sw_if_index, &a); + } + + return (rv); +} + void ip_neighbor_scan_enable_disable (ip_neighbor_scan_arg_t * arg) { @@ -134,8 +197,7 @@ ip_neighbor_scan (vlib_main_t * vm, f64 start_time, u32 start_idx, else { vnet_unset_ip6_ethernet_neighbor - (vm, n6->key.sw_if_index, &n6->key.ip6_address, - n6->link_layer_address, 6); + (vm, n6->key.sw_if_index, &n6->key.ip6_address); } } else if (delta >= cfg->scan_interval) diff --git a/src/vnet/ip/ip_neighbor.h b/src/vnet/ip/ip_neighbor.h index d2790bcce5e..b865862c06e 100644 --- a/src/vnet/ip/ip_neighbor.h +++ b/src/vnet/ip/ip_neighbor.h @@ -35,6 +35,21 @@ typedef struct void ip_neighbor_scan_enable_disable (ip_neighbor_scan_arg_t * arg); +typedef enum ip_neighbor_flags_t_ +{ + IP_NEIGHBOR_FLAG_NODE = 0, + IP_NEIGHBOR_FLAG_STATIC = (1 << 0), + IP_NEIGHBOR_FLAG_NO_ADJ_FIB = (1 << 1), +} ip_neighbor_flags_t; + +extern int ip_neighbor_add (const ip46_address_t * ip, + u8 is_ip6, + const u8 * mac, + u32 sw_if_index, ip_neighbor_flags_t flags); + +extern int ip_neighbor_del (const ip46_address_t * ip, + u8 is_ip6, u32 sw_if_index); + #endif /* included_ip_neighbor_h */ /* -- 2.16.6