X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fip%2Fip6_neighbor.c;h=7c7a7069e8939ee38bb88b8aa6d24c8c5c59305d;hb=1855b8e4;hp=3daea6bafbe79046b8ee687886b0e428eb4f12e1;hpb=9f781d84b0943b03af2a9fd0b7c4cef721d1d4c6;p=vpp.git diff --git a/src/vnet/ip/ip6_neighbor.c b/src/vnet/ip/ip6_neighbor.c index 3daea6bafbe..7c7a7069e89 100644 --- a/src/vnet/ip/ip6_neighbor.c +++ b/src/vnet/ip/ip6_neighbor.c @@ -236,6 +236,29 @@ static ip6_address_t ip6a_zero; /* ip6 address 0 */ static void wc_nd_signal_report (wc_nd_report_t * r); static void ra_signal_report (ra_report_t * r); +ip6_address_t +ip6_neighbor_get_link_local_address (u32 sw_if_index) +{ + static ip6_address_t empty_address = { {0} }; + ip6_neighbor_main_t *nm = &ip6_neighbor_main; + ip6_radv_t *radv_info; + u32 ri; + + ri = nm->if_radv_pool_index_by_sw_if_index[sw_if_index]; + if (ri == ~0) + { + clib_warning ("IPv6 is not enabled for sw_if_index %d", sw_if_index); + return empty_address; + } + radv_info = pool_elt_at_index (nm->if_radv_pool, ri); + if (radv_info == NULL) + { + clib_warning ("Internal error"); + return empty_address; + } + return radv_info->link_local_address; +} + /** * @brief publish wildcard arp event * @param sw_if_index The interface on which the ARP entires are acted @@ -443,6 +466,8 @@ ip6_nbr_probe (ip_adjacency_t * adj) h = vlib_packet_template_get_packet (vm, &im->discover_neighbor_packet_template, &bi); + if (!h) + return; hi = vnet_get_sup_hw_interface (vnm, adj->rewrite_header.sw_if_index); @@ -637,6 +662,14 @@ ip6_ethernet_update_adjacency (vnet_main_t * vnm, u32 sw_if_index, u32 ai) ip6_nbr_probe (adj); } break; + case IP_LOOKUP_NEXT_BCAST: + adj_nbr_update_rewrite (ai, + ADJ_NBR_REWRITE_FLAG_COMPLETE, + ethernet_build_rewrite (vnm, + sw_if_index, + VNET_LINK_IP6, + VNET_REWRITE_FOR_SW_INTERFACE_ADDRESS_BROADCAST)); + break; case IP_LOOKUP_NEXT_MCAST: { /* @@ -769,7 +802,13 @@ 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)) - return -2; + { + /* if MAC address match, still check to send event */ + if (0 == memcmp (n->link_layer_address, + link_layer_address, n_bytes_link_layer_address)) + goto check_customers; + return -2; + } make_new_nd_cache_entry = 0; } @@ -2610,10 +2649,6 @@ ip6_neighbor_sw_interface_add_del (vnet_main_t * vnm, { if (is_add) { - vnet_hw_interface_t *hw_if0; - - hw_if0 = vnet_get_sup_hw_interface (vnm, sw_if_index); - pool_get (nm->if_radv_pool, a); ri = a - nm->if_radv_pool; @@ -2647,7 +2682,8 @@ ip6_neighbor_sw_interface_add_del (vnet_main_t * vnm, a->send_radv = 1; /* fill in radv_info for this interface that will be needed later */ - a->adv_link_mtu = hw_if0->max_l3_packet_bytes[VLIB_RX]; + a->adv_link_mtu = + vnet_sw_interface_get_mtu (vnm, sw_if_index, VNET_MTU_IP6); clib_memcpy (a->link_layer_address, eth_if0->address, 6); @@ -3265,6 +3301,8 @@ ip6_discover_neighbor_inline (vlib_main_t * vm, h0 = vlib_packet_template_get_packet (vm, &im->discover_neighbor_packet_template, &bi0); + if (!h0) + continue; /* * Build ethernet header. @@ -4166,6 +4204,7 @@ enable_ip6_interface (vlib_main_t * vm, u32 sw_if_index) sw_if0 = vnet_get_sw_interface (vnm, sw_if_index); if (sw_if0->type == VNET_SW_INTERFACE_TYPE_SUB || + sw_if0->type == VNET_SW_INTERFACE_TYPE_PIPE || sw_if0->type == VNET_SW_INTERFACE_TYPE_P2P) { /* make up an interface id */ @@ -4757,11 +4796,17 @@ vnet_add_del_ip6_nd_change_event (vnet_main_t * vnm, return VNET_API_ERROR_ENTRY_ALREADY_EXISTS; pool_get (nm->mac_changes, mc); + /* *INDENT-OFF* */ *mc = (pending_resolution_t) { - .next_index = ~0,.node_index = node_index,.type_opaque = - type_opaque,.data = data,.data_callback = data_callback,.pid = - pid,}; + .next_index = ~0, + .node_index = node_index, + .type_opaque = type_opaque, + .data = data, + .data_callback = data_callback, + .pid = pid, + }; + /* *INDENT-ON* */ /* Insert new resolution at the end of the list */ u32 new_idx = mc - nm->mac_changes; @@ -5011,6 +5056,9 @@ send_ip6_na_w_addr (vlib_main_t * vm, vlib_packet_template_get_packet (vm, &i6m->discover_neighbor_packet_template, &bi); + if (!h) + return; + ip6_set_reserved_multicast_address (&h->ip.dst_address, IP6_MULTICAST_SCOPE_link_local, IP6_MULTICAST_GROUP_ID_all_hosts);