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);
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)
{
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? */
/* 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
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;
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;
}
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
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;
}
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
{
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);
#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)
{
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)
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 ();
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)
{
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)
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 */
/*