diff options
Diffstat (limited to 'src/vnet/ip/ip6_neighbor.c')
-rwxr-xr-x | src/vnet/ip/ip6_neighbor.c | 143 |
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 */ |