X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fip%2Fip6_neighbor.c;h=61d298350625a0271eac4e6d283f4753bd25887f;hb=8b30e471df4d42214619e1d6c50cc8298426b45f;hp=56f33ac821dd2d3bf9384e8b50a2456d09e2b6c6;hpb=1500254bee11355bbd69cc1dd9705be4f002f2bd;p=vpp.git diff --git a/src/vnet/ip/ip6_neighbor.c b/src/vnet/ip/ip6_neighbor.c index 56f33ac821d..61d29835062 100644 --- a/src/vnet/ip/ip6_neighbor.c +++ b/src/vnet/ip/ip6_neighbor.c @@ -195,6 +195,9 @@ typedef struct u32 limit_neighbor_cache_size; u32 neighbor_delete_rotor; + /* Wildcard nd report publisher */ + uword wc_ip6_nd_publisher_node; + uword wc_ip6_nd_publisher_et; } ip6_neighbor_main_t; /* ipv6 neighbor discovery - timer/event types */ @@ -216,6 +219,50 @@ typedef union static ip6_neighbor_main_t ip6_neighbor_main; static ip6_address_t ip6a_zero; /* ip6 address 0 */ +static void wc_nd_signal_report (wc_nd_report_t * r); + +/** + * @brief publish wildcard arp event + * @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) +{ + wc_nd_report_t r = { + .sw_if_index = sw_if_index, + .ip6 = *ip6, + }; + 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; +} + +static void +wc_nd_signal_report (wc_nd_report_t * r) +{ + vlib_main_t *vm = vlib_get_main (); + ip6_neighbor_main_t *nm = &ip6_neighbor_main; + uword ni = nm->wc_ip6_nd_publisher_node; + uword et = nm->wc_ip6_nd_publisher_et; + + if (ni == (uword) ~ 0) + return; + wc_nd_report_t *q = + vlib_process_signal_event_data (vm, ni, et, 1, sizeof *q); + + *q = *r; +} + +void +wc_nd_set_publisher_node (uword node_index, uword event_type) +{ + ip6_neighbor_main_t *nm = &ip6_neighbor_main; + nm->wc_ip6_nd_publisher_node = node_index; + nm->wc_ip6_nd_publisher_et = event_type; +} + static u8 * format_ip6_neighbor_ip6_entry (u8 * s, va_list * va) { @@ -251,7 +298,7 @@ format_ip6_neighbor_ip6_entry (u8 * s, va_list * va) } static void -ip6_neighbor_adj_fib_remove (ip6_neighbor_t * n, uint32_t fib_index) +ip6_neighbor_adj_fib_remove (ip6_neighbor_t * n, u32 fib_index) { if (FIB_NODE_INDEX_INVALID != n->fib_entry_index) { @@ -519,8 +566,10 @@ ip6_ethernet_update_adjacency (vnet_main_t * vnm, u32 sw_if_index, u32 ai) switch (adj->lookup_next_index) { - case IP_LOOKUP_NEXT_ARP: case IP_LOOKUP_NEXT_GLEAN: + adj_glean_update_rewrite (ai); + break; + case IP_LOOKUP_NEXT_ARP: if (NULL != nbr) { adj_nbr_walk_nh6 (sw_if_index, &nbr->key.ip6_address, @@ -589,7 +638,7 @@ ip6_ethernet_update_adjacency (vnet_main_t * vnm, u32 sw_if_index, u32 ai) static void -ip6_neighbor_adj_fib_add (ip6_neighbor_t * n, uint32_t fib_index) +ip6_neighbor_adj_fib_add (ip6_neighbor_t * n, u32 fib_index) { fib_prefix_t pfx = { .fp_len = 128, @@ -676,7 +725,7 @@ vnet_set_ip6_ethernet_neighbor (vlib_main_t * vm, */ if (0 == memcmp (n->link_layer_address, link_layer_address, n_bytes_link_layer_address)) - return -1; + goto check_customers; clib_memcpy (n->link_layer_address, link_layer_address, n_bytes_link_layer_address); @@ -692,6 +741,7 @@ vnet_set_ip6_ethernet_neighbor (vlib_main_t * vm, adj_nbr_walk_nh6 (sw_if_index, &n->key.ip6_address, ip6_nd_mk_complete_walk, n); +check_customers: /* Customer(s) waiting for this address to be resolved? */ p = mhash_get (&nm->pending_resolutions_by_address, a); if (p) @@ -2387,7 +2437,7 @@ VLIB_REGISTER_NODE (ip6_icmp_router_solicitation_node,static) = .n_next_nodes = ICMP6_ROUTER_SOLICITATION_N_NEXT, .next_nodes = { - [ICMP6_ROUTER_SOLICITATION_NEXT_DROP] = "error-drop", + [ICMP6_ROUTER_SOLICITATION_NEXT_DROP] = "ip6-drop", [ICMP6_ROUTER_SOLICITATION_NEXT_REPLY_RW] = "ip6-rewrite-mcast", [ICMP6_ROUTER_SOLICITATION_NEXT_REPLY_TX] = "interface-output", }, @@ -2580,7 +2630,7 @@ VLIB_REGISTER_NODE (ip6_icmp_router_advertisement_node,static) = .n_next_nodes = 1, .next_nodes = { - [0] = "error-drop", + [0] = "ip6-drop", }, }; /* *INDENT-ON* */ @@ -2623,7 +2673,7 @@ VLIB_REGISTER_NODE (ip6_icmp_neighbor_solicitation_node,static) = .n_next_nodes = ICMP6_NEIGHBOR_SOLICITATION_N_NEXT, .next_nodes = { - [ICMP6_NEIGHBOR_SOLICITATION_NEXT_DROP] = "error-drop", + [ICMP6_NEIGHBOR_SOLICITATION_NEXT_DROP] = "ip6-drop", [ICMP6_NEIGHBOR_SOLICITATION_NEXT_REPLY] = "interface-output", }, }; @@ -2641,7 +2691,7 @@ VLIB_REGISTER_NODE (ip6_icmp_neighbor_advertisement_node,static) = .n_next_nodes = 1, .next_nodes = { - [0] = "error-drop", + [0] = "ip6-drop", }, }; /* *INDENT-ON* */ @@ -3931,6 +3981,8 @@ ip6_neighbor_init (vlib_main_t * vm) /* default, configurable */ nm->limit_neighbor_cache_size = 50000; + nm->wc_ip6_nd_publisher_node = (uword) ~ 0; + #if 0 /* $$$$ Hack fix for today */ vec_validate_init_empty @@ -4047,7 +4099,6 @@ vnet_ip6_nd_term (vlib_main_t * vm, { ip6_neighbor_main_t *nm = &ip6_neighbor_main; icmp6_neighbor_solicitation_or_advertisement_header_t *ndh; - pending_resolution_t *mc; ndh = ip6_next_header (ip); if (ndh->icmp.type != ICMP6_neighbor_solicitation && @@ -4063,26 +4114,11 @@ vnet_ip6_nd_term (vlib_main_t * vm, } /* Check if anyone want ND events for L2 BDs */ - uword *p = mhash_get (&nm->mac_changes_by_address, &ip6a_zero); - if (p && !ip6_address_is_link_local_unicast (&ip->src_address)) + if (PREDICT_FALSE + (nm->wc_ip6_nd_publisher_node != (uword) ~ 0 + && !ip6_address_is_link_local_unicast (&ip->src_address))) { - u32 next_index = p[0]; - 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 callback, return 1 to suppress dup events */ - if (fp) - rv = (*fp) (mc->data, - eth->src_address, sw_if_index, &ip->src_address); - /* Signal the resolver process */ - if (rv == 0) - vlib_process_signal_event (vm, mc->node_index, - mc->type_opaque, mc->data); - next_index = mc->next_index; - } + vnet_nd_wc_publish (sw_if_index, eth->src_address, &ip->src_address); } /* Check if MAC entry exsist for solicited target IP */ @@ -4234,6 +4270,8 @@ ethernet_ndp_change_mac (u32 sw_if_index) } })); /* *INDENT-ON* */ + + adj_glean_update_rewrite (adj_glean_get (FIB_PROTOCOL_IP6, sw_if_index)); } void