aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/ip/ip6_neighbor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/ip/ip6_neighbor.c')
-rwxr-xr-xsrc/vnet/ip/ip6_neighbor.c143
1 files changed, 64 insertions, 79 deletions
diff --git a/src/vnet/ip/ip6_neighbor.c b/src/vnet/ip/ip6_neighbor.c
index b4b6888a934..ded5b868702 100755
--- a/src/vnet/ip/ip6_neighbor.c
+++ b/src/vnet/ip/ip6_neighbor.c
@@ -26,6 +26,7 @@
#include <vnet/mfib/ip6_mfib.h>
#include <vnet/ip/ip6_ll_table.h>
#include <vnet/l2/l2_input.h>
+#include <vlibmemory/api.h>
/**
* @file
@@ -173,7 +174,7 @@ typedef struct
uword type_opaque;
uword data;
/* Used for nd event notification only */
- void *data_callback;
+ ip6_nd_change_event_cb_t data_callback;
u32 pid;
} pending_resolution_t;
@@ -266,15 +267,15 @@ ip6_neighbor_get_link_local_address (u32 sw_if_index)
* @param sw_if_index The interface on which the ARP entires are acted
*/
static int
-vnet_nd_wc_publish (u32 sw_if_index, u8 * mac, ip6_address_t * ip6)
+vnet_nd_wc_publish (u32 sw_if_index,
+ const mac_address_t * mac, const ip6_address_t * ip6)
{
wc_nd_report_t r = {
.sw_if_index = sw_if_index,
.ip6 = *ip6,
+ .mac = *mac,
};
- memcpy (r.mac, mac, sizeof r.mac);
- void vl_api_rpc_call_main_thread (void *fp, u8 * data, u32 data_length);
vl_api_rpc_call_main_thread (wc_nd_signal_report, (u8 *) & r, sizeof r);
return 0;
}
@@ -347,13 +348,13 @@ format_ip6_neighbor_ip6_entry (u8 * s, va_list * va)
return format (s, "%=12s%=45s%=6s%=20s%=40s", "Time", "Address", "Flags",
"Link layer", "Interface");
- if (n->flags & IP6_NEIGHBOR_FLAG_DYNAMIC)
+ if (n->flags & IP_NEIGHBOR_FLAG_DYNAMIC)
flags = format (flags, "D");
- if (n->flags & IP6_NEIGHBOR_FLAG_STATIC)
+ if (n->flags & IP_NEIGHBOR_FLAG_STATIC)
flags = format (flags, "S");
- if (n->flags & IP6_NEIGHBOR_FLAG_NO_FIB_ENTRY)
+ if (n->flags & IP_NEIGHBOR_FLAG_NO_FIB_ENTRY)
flags = format (flags, "N");
si = vnet_get_sw_interface (vnm, n->key.sw_if_index);
@@ -361,7 +362,7 @@ format_ip6_neighbor_ip6_entry (u8 * s, va_list * va)
format_vlib_time, vm, n->time_last_updated,
format_ip6_address, &n->key.ip6_address,
flags ? (char *) flags : "",
- format_ethernet_address, n->link_layer_address,
+ format_mac_address_t, &n->mac,
format_vnet_sw_interface_name, vnm, si);
vec_free (flags);
@@ -402,9 +403,8 @@ ip6_neighbor_adj_fib_remove (ip6_neighbor_t * n, u32 fib_index)
typedef struct
{
u8 is_add;
- u8 is_static;
- u8 is_no_fib_entry;
- u8 link_layer_address[6];
+ ip_neighbor_flags_t flags;
+ mac_address_t mac;
u32 sw_if_index;
ip6_address_t addr;
} ip6_neighbor_set_unset_rpc_args_t;
@@ -416,19 +416,16 @@ static void set_unset_ip6_neighbor_rpc
(vlib_main_t * vm,
u32 sw_if_index,
const ip6_address_t * a,
- const u8 * link_layer_address,
- int is_add, int is_static, int is_no_fib_entry)
+ const mac_address_t * mac, int is_add, ip_neighbor_flags_t flags)
{
ip6_neighbor_set_unset_rpc_args_t args;
void vl_api_rpc_call_main_thread (void *fp, u8 * data, u32 data_length);
args.sw_if_index = sw_if_index;
args.is_add = is_add;
- args.is_static = is_static;
- args.is_no_fib_entry = is_no_fib_entry;
- clib_memcpy (&args.addr, a, sizeof (*a));
- if (NULL != link_layer_address)
- clib_memcpy (args.link_layer_address, link_layer_address, 6);
+ args.flags = flags;
+ ip6_address_copy (&args.addr, a);
+ mac_address_copy (&args.mac, mac);
vl_api_rpc_call_main_thread (ip6_neighbor_set_unset_rpc_callback,
(u8 *) & args, sizeof (args));
@@ -511,7 +508,7 @@ ip6_nd_mk_complete (adj_index_t ai, ip6_neighbor_t * nbr)
ethernet_build_rewrite (vnet_get_main (),
nbr->key.sw_if_index,
adj_get_link_type (ai),
- nbr->link_layer_address));
+ nbr->mac.bytes));
}
static void
@@ -604,7 +601,7 @@ ip6_neighbor_sw_interface_up_down (vnet_main_t * vnm,
n = pool_elt_at_index (nm->neighbor_pool, to_delete[i]);
adj_nbr_walk_nh6 (n->key.sw_if_index, &n->key.ip6_address,
ip6_nd_mk_incomplete_walk, NULL);
- if (n->flags & IP6_NEIGHBOR_FLAG_STATIC)
+ if (n->flags & IP_NEIGHBOR_FLAG_STATIC)
continue;
ip6_neighbor_adj_fib_remove (n,
ip6_fib_table_get_index_for_sw_if_index
@@ -759,7 +756,7 @@ force_reuse_neighbor_entry (void)
nm->neighbor_delete_rotor = index;
index = pool_next_index (nm->neighbor_pool, index);
}
- while (n->flags & IP6_NEIGHBOR_FLAG_STATIC);
+ while (n->flags & IP_NEIGHBOR_FLAG_STATIC);
/* Remove ARP entry from its interface and update fib */
adj_nbr_walk_nh6 (n->key.sw_if_index,
@@ -775,9 +772,8 @@ int
vnet_set_ip6_ethernet_neighbor (vlib_main_t * vm,
u32 sw_if_index,
const ip6_address_t * a,
- const u8 * link_layer_address,
- uword n_bytes_link_layer_address,
- int is_static, int is_no_fib_entry)
+ const mac_address_t * mac,
+ ip_neighbor_flags_t flags)
{
ip6_neighbor_main_t *nm = &ip6_neighbor_main;
ip6_neighbor_key_t k;
@@ -789,9 +785,7 @@ vnet_set_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,
- 1 /* set new neighbor */ , is_static,
- is_no_fib_entry);
+ set_unset_ip6_neighbor_rpc (vm, sw_if_index, a, mac, 1, flags);
return 0;
}
@@ -804,11 +798,11 @@ vnet_set_ip6_ethernet_neighbor (vlib_main_t * vm,
{
n = pool_elt_at_index (nm->neighbor_pool, p[0]);
/* Refuse to over-write static neighbor entry. */
- if (!is_static && (n->flags & IP6_NEIGHBOR_FLAG_STATIC))
+ if (!(flags & IP_NEIGHBOR_FLAG_STATIC) &&
+ (n->flags & IP_NEIGHBOR_FLAG_STATIC))
{
/* if MAC address match, still check to send event */
- if (0 == memcmp (n->link_layer_address,
- link_layer_address, n_bytes_link_layer_address))
+ if (0 == mac_address_cmp (&n->mac, mac))
goto check_customers;
return -2;
}
@@ -832,20 +826,19 @@ vnet_set_ip6_ethernet_neighbor (vlib_main_t * vm,
n->key = k;
n->fib_entry_index = FIB_NODE_INDEX_INVALID;
- clib_memcpy (n->link_layer_address,
- link_layer_address, n_bytes_link_layer_address);
+ mac_address_copy (&n->mac, mac);
/*
* create the adj-fib. the entry in the FIB table for and to the peer.
*/
- if (!is_no_fib_entry)
+ if (!(flags & IP_NEIGHBOR_FLAG_NO_FIB_ENTRY))
{
ip6_neighbor_adj_fib_add
(n, ip6_fib_table_get_index_for_sw_if_index (n->key.sw_if_index));
}
else
{
- n->flags |= IP6_NEIGHBOR_FLAG_NO_FIB_ENTRY;
+ n->flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
}
}
else
@@ -854,28 +847,26 @@ vnet_set_ip6_ethernet_neighbor (vlib_main_t * vm,
* prevent a DoS attack from the data-plane that
* spams us with no-op updates to the MAC address
*/
- if (0 == memcmp (n->link_layer_address,
- link_layer_address, n_bytes_link_layer_address))
+ if (0 == mac_address_cmp (&n->mac, mac))
{
n->time_last_updated = vlib_time_now (vm);
goto check_customers;
}
- clib_memcpy (n->link_layer_address,
- link_layer_address, n_bytes_link_layer_address);
+ mac_address_copy (&n->mac, mac);
}
/* Update time stamp and flags. */
n->time_last_updated = vlib_time_now (vm);
- if (is_static)
+ if (flags & IP_NEIGHBOR_FLAG_STATIC)
{
- n->flags |= IP6_NEIGHBOR_FLAG_STATIC;
- n->flags &= ~IP6_NEIGHBOR_FLAG_DYNAMIC;
+ n->flags |= IP_NEIGHBOR_FLAG_STATIC;
+ n->flags &= ~IP_NEIGHBOR_FLAG_DYNAMIC;
}
else
{
- n->flags |= IP6_NEIGHBOR_FLAG_DYNAMIC;
- n->flags &= ~IP6_NEIGHBOR_FLAG_STATIC;
+ n->flags |= IP_NEIGHBOR_FLAG_DYNAMIC;
+ n->flags &= ~IP_NEIGHBOR_FLAG_STATIC;
}
adj_nbr_walk_nh6 (sw_if_index,
@@ -908,16 +899,13 @@ check_customers:
while (next_index != (u32) ~ 0)
{
- int (*fp) (u32, u8 *, u32, ip6_address_t *);
int rv = 1;
+
mc = pool_elt_at_index (nm->mac_changes, next_index);
- fp = mc->data_callback;
/* Call the user's data callback, return 1 to suppress dup events */
- if (fp)
- rv =
- (*fp) (mc->data, (u8 *) link_layer_address, sw_if_index,
- &ip6a_zero);
+ if (mc->data_callback)
+ rv = (mc->data_callback) (mc->data, mac, sw_if_index, &ip6a_zero);
/*
* Signal the resolver process, as long as the user
* says they want to be notified
@@ -944,8 +932,8 @@ vnet_unset_ip6_ethernet_neighbor (vlib_main_t * vm,
if (vlib_get_thread_index ())
{
- set_unset_ip6_neighbor_rpc (vm, sw_if_index, a, NULL,
- 0 /* unset */ , 0, 0);
+ set_unset_ip6_neighbor_rpc (vm, sw_if_index, a, NULL, 0,
+ IP_NEIGHBOR_FLAG_NONE);
return 0;
}
@@ -980,8 +968,7 @@ static void ip6_neighbor_set_unset_rpc_callback
vlib_main_t *vm = vlib_get_main ();
if (a->is_add)
vnet_set_ip6_ethernet_neighbor (vm, a->sw_if_index, &a->addr,
- a->link_layer_address, 6, a->is_static,
- a->is_no_fib_entry);
+ &a->mac, a->flags);
else
vnet_unset_ip6_ethernet_neighbor (vm, a->sw_if_index, &a->addr);
}
@@ -1010,7 +997,7 @@ ip6_neighbor_t *
ip6_neighbors_entries (u32 sw_if_index)
{
ip6_neighbor_main_t *nm = &ip6_neighbor_main;
- ip6_neighbor_t *n, *ns = 0;
+ ip6_neighbor_t *n, *ns = NULL;
/* *INDENT-OFF* */
pool_foreach (n, nm->neighbor_pool,
@@ -1085,13 +1072,12 @@ static clib_error_t *
set_ip6_neighbor (vlib_main_t * vm,
unformat_input_t * input, vlib_cli_command_t * cmd)
{
+ ip_neighbor_flags_t flags = IP_NEIGHBOR_FLAG_NONE;
vnet_main_t *vnm = vnet_get_main ();
ip6_address_t addr;
- u8 mac_address[6];
+ mac_address_t mac;
int addr_valid = 0;
int is_del = 0;
- int is_static = 0;
- int is_no_fib_entry = 0;
u32 sw_if_index;
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
@@ -1100,15 +1086,15 @@ set_ip6_neighbor (vlib_main_t * vm,
if (unformat (input, "%U %U %U",
unformat_vnet_sw_interface, vnm, &sw_if_index,
unformat_ip6_address, &addr,
- unformat_ethernet_address, mac_address))
+ unformat_mac_address_t, &mac))
addr_valid = 1;
else if (unformat (input, "delete") || unformat (input, "del"))
is_del = 1;
else if (unformat (input, "static"))
- is_static = 1;
+ flags |= IP_NEIGHBOR_FLAG_STATIC;
else if (unformat (input, "no-fib-entry"))
- is_no_fib_entry = 1;
+ flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
else
break;
}
@@ -1117,9 +1103,7 @@ set_ip6_neighbor (vlib_main_t * vm,
return clib_error_return (0, "Missing interface, ip6 or hw address");
if (!is_del)
- vnet_set_ip6_ethernet_neighbor (vm, sw_if_index, &addr,
- mac_address, sizeof (mac_address),
- is_static, is_no_fib_entry);
+ vnet_set_ip6_ethernet_neighbor (vm, sw_if_index, &addr, &mac, flags);
else
vnet_unset_ip6_ethernet_neighbor (vm, sw_if_index, &addr);
return 0;
@@ -1258,9 +1242,9 @@ icmp6_neighbor_solicitation_or_advertisement (vlib_main_t * vm,
is_solicitation ?
&ip0->src_address :
&h0->target_address,
+ (mac_address_t *)
o0->ethernet_address,
- sizeof (o0->ethernet_address),
- 0, 0);
+ IP_NEIGHBOR_FLAG_NONE);
}
if (is_solicitation && error0 == ICMP6_ERROR_NONE)
@@ -1591,11 +1575,11 @@ icmp6_router_solicitation (vlib_main_t * vm,
if (PREDICT_TRUE (error0 == ICMP6_ERROR_NONE && o0 != 0 &&
!is_unspecified && !is_link_local))
{
- vnet_set_ip6_ethernet_neighbor (vm, sw_if_index0,
- &ip0->src_address,
- o0->ethernet_address,
- sizeof (o0->ethernet_address),
- 0, 0);
+ vnet_set_ip6_ethernet_neighbor
+ (vm, sw_if_index0,
+ &ip0->src_address,
+ (mac_address_t *) o0->ethernet_address,
+ IP_NEIGHBOR_FLAG_NONE);
}
/* default is to drop */
@@ -2013,7 +1997,7 @@ icmp6_router_advertisement (vlib_main_t * vm,
ra_report_t r;
r.sw_if_index = sw_if_index0;
- memcpy (r.router_address, &ip0->src_address, 16);
+ memcpy (&r.router_address, &ip0->src_address, 16);
r.current_hop_limit = h0->current_hop_limit;
r.flags = h0->flags;
r.router_lifetime_in_sec =
@@ -2208,9 +2192,9 @@ icmp6_router_advertisement (vlib_main_t * vm,
prefix->preferred_time = preferred;
prefix->valid_time = valid;
prefix->flags = h->flags & 0xc0;
- prefix->dst_address_length =
- h->dst_address_length;
- prefix->dst_address = h->dst_address;
+ prefix->prefix.fp_len = h->dst_address_length;
+ prefix->prefix.fp_addr.ip6 = h->dst_address;
+ prefix->prefix.fp_proto = FIB_PROTOCOL_IP6;
/* look for matching prefix - if we our advertising it, it better be consistant */
/* *INDENT-OFF* */
@@ -4686,7 +4670,7 @@ vnet_register_ip6_neighbor_resolution_event (vnet_main_t * vnm,
int
vnet_add_del_ip6_nd_change_event (vnet_main_t * vnm,
- void *data_callback,
+ ip6_nd_change_event_cb_t data_callback,
u32 pid,
void *address_arg,
uword node_index,
@@ -4740,9 +4724,8 @@ vnet_add_del_ip6_nd_change_event (vnet_main_t * vnm,
return VNET_API_ERROR_NO_SUCH_ENTRY;
/* Clients may need to clean up pool entries, too */
- void (*fp) (u32, u8 *) = data_callback;
- if (fp)
- (*fp) (mc->data, 0 /* no new mac addrs */ );
+ if (data_callback)
+ (data_callback) (mc->data, NULL /* no new mac addrs */ , 0, NULL);
/* Remove the entry from the list and delete the entry */
*p = mc->next_index;
@@ -4764,7 +4747,9 @@ vnet_ip6_nd_term (vlib_main_t * vm,
{
ip6_neighbor_main_t *nm = &ip6_neighbor_main;
icmp6_neighbor_solicitation_or_advertisement_header_t *ndh;
+ mac_address_t mac;
+ mac_address_from_bytes (&mac, eth->src_address);
ndh = ip6_next_header (ip);
if (ndh->icmp.type != ICMP6_neighbor_solicitation &&
ndh->icmp.type != ICMP6_neighbor_advertisement)
@@ -4783,7 +4768,7 @@ vnet_ip6_nd_term (vlib_main_t * vm,
(nm->wc_ip6_nd_publisher_node != (uword) ~ 0
&& !ip6_address_is_link_local_unicast (&ip->src_address)))
{
- vnet_nd_wc_publish (sw_if_index, eth->src_address, &ip->src_address);
+ vnet_nd_wc_publish (sw_if_index, &mac, &ip->src_address);
}
/* Check if MAC entry exsist for solicited target IP */