X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=src%2Fvnet%2Fip%2Fip6_neighbor.c;h=46d04769a9695a4464fec1d8e0c58dd08b78c5c9;hb=32e1c010b0c34fd0984f7fc45fae648a182025c5;hp=5a1c9e86b4fdf6008e6d131449466a9316eb8bb4;hpb=7cd468a3d7dee7d6c92f69a0bb7061ae208ec727;p=vpp.git diff --git a/src/vnet/ip/ip6_neighbor.c b/src/vnet/ip/ip6_neighbor.c index 5a1c9e86b4f..46d04769a96 100644 --- a/src/vnet/ip/ip6_neighbor.c +++ b/src/vnet/ip/ip6_neighbor.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -116,9 +117,7 @@ typedef struct u32 seed; u64 randomizer; int ref_count; - adj_index_t all_nodes_adj_index; - adj_index_t all_routers_adj_index; - adj_index_t all_mldv2_routers_adj_index; + adj_index_t mcast_adj_index; /* timing information */ #define DEF_MAX_RADV_INTERVAL 200 @@ -155,8 +154,6 @@ typedef struct /* Link local address to use (defaults to underlying physical for logical interfaces */ ip6_address_t link_local_address; - u8 link_local_prefix_len; - } ip6_radv_t; typedef struct @@ -476,33 +473,72 @@ ip6_ethernet_update_adjacency (vnet_main_t * vnm, u32 sw_if_index, u32 ai) nbr = ip6_nd_find (sw_if_index, &adj->sub_type.nbr.next_hop.ip6); - if (NULL != nbr) - { - adj_nbr_walk_nh6 (sw_if_index, &nbr->key.ip6_address, - ip6_nd_mk_complete_walk, nbr); - } - else + switch (adj->lookup_next_index) { + case IP_LOOKUP_NEXT_ARP: + case IP_LOOKUP_NEXT_GLEAN: + if (NULL != nbr) + { + adj_nbr_walk_nh6 (sw_if_index, &nbr->key.ip6_address, + ip6_nd_mk_complete_walk, nbr); + } + else + { + /* + * no matching ND entry. + * construct the rewrite required to for an ND packet, and stick + * that in the adj's pipe to smoke. + */ + adj_nbr_update_rewrite (ai, + ADJ_NBR_REWRITE_FLAG_INCOMPLETE, + ethernet_build_rewrite (vnm, + sw_if_index, + VNET_LINK_IP6, + VNET_REWRITE_FOR_SW_INTERFACE_ADDRESS_BROADCAST)); + + /* + * since the FIB has added this adj for a route, it makes sense it may + * want to forward traffic sometime soon. Let's send a speculative ND. + * just one. If we were to do periodically that wouldn't be bad either, + * but that's more code than i'm prepared to write at this time for + * relatively little reward. + */ + ip6_nbr_probe (adj); + } + break; + case IP_LOOKUP_NEXT_MCAST: /* - * no matching ND entry. - * construct the rewrite required to for an ND packet, and stick - * that in the adj's pipe to smoke. + * Construct a partial rewrite from the known ethernet mcast dest MAC */ - adj_nbr_update_rewrite (ai, - ADJ_NBR_REWRITE_FLAG_INCOMPLETE, - ethernet_build_rewrite (vnm, - sw_if_index, - VNET_LINK_IP6, - VNET_REWRITE_FOR_SW_INTERFACE_ADDRESS_BROADCAST)); + adj_mcast_update_rewrite + (ai, + ethernet_build_rewrite (vnm, + sw_if_index, + adj->ia_link, + ethernet_ip6_mcast_dst_addr ())); /* - * since the FIB has added this adj for a route, it makes sense it may - * want to forward traffic sometime soon. Let's send a speculative ND. - * just one. If we were to do periodically that wouldn't be bad either, - * but that's more code than i'm prepared to write at this time for - * relatively little reward. + * Complete the remaining fields of the adj's rewrite to direct the + * complete of the rewrite at switch time by copying in the IP + * dst address's bytes. + * Ofset is 12 bytes from the end of the MAC header - which is 2 + * bytes into the desintation address. And we write 4 bytes. */ - ip6_nbr_probe (adj); + adj->rewrite_header.dst_mcast_offset = 12; + adj->rewrite_header.dst_mcast_n_bytes = 4; + + break; + + case IP_LOOKUP_NEXT_DROP: + case IP_LOOKUP_NEXT_PUNT: + case IP_LOOKUP_NEXT_LOCAL: + case IP_LOOKUP_NEXT_REWRITE: + case IP_LOOKUP_NEXT_LOAD_BALANCE: + case IP_LOOKUP_NEXT_MIDCHAIN: + case IP_LOOKUP_NEXT_ICMP_ERROR: + case IP_LOOKUP_N_NEXT: + ASSERT (0); + break; } } @@ -1316,7 +1352,8 @@ icmp6_router_solicitation (vlib_main_t * vm, /* for solicited adverts - need to rate limit */ if (is_solicitation) { - if ((now - radv_info->last_radv_time) < + if (0 != radv_info->last_radv_time && + (now - radv_info->last_radv_time) < MIN_DELAY_BETWEEN_RAS) is_dropped = 1; else @@ -1518,21 +1555,11 @@ icmp6_router_solicitation (vlib_main_t * vm, } else { - adj_index0 = radv_info->all_nodes_adj_index; + adj_index0 = radv_info->mcast_adj_index; if (adj_index0 == 0) error0 = ICMP6_ERROR_DST_LOOKUP_MISS; else { - ip_adjacency_t *adj0 = - ip_get_adjacency (&im->lookup_main, - adj_index0); - error0 = - ((adj0->rewrite_header.sw_if_index != - sw_if_index0 - || adj0->lookup_next_index != - IP_LOOKUP_NEXT_REWRITE) ? - ICMP6_ERROR_ROUTER_SOLICITATION_DEST_UNKNOWN - : error0); next0 = is_dropped ? next0 : ICMP6_ROUTER_SOLICITATION_NEXT_REPLY_RW; @@ -1929,10 +1956,8 @@ ip6_neighbor_sw_interface_add_del (vnet_main_t * vnm, ip6_radv_prefix_t *p; ip6_mldp_group_t *m; - /* remove adjacencies */ - adj_unlock (a->all_nodes_adj_index); - adj_unlock (a->all_routers_adj_index); - adj_unlock (a->all_mldv2_routers_adj_index); + /* release the lock on the interface's mcast adj */ + adj_unlock (a->mcast_adj_index); /* clean up prefix_pool */ /* *INDENT-OFF* */ @@ -2022,43 +2047,15 @@ ip6_neighbor_sw_interface_add_del (vnet_main_t * vnm, /* fill in default link-local address (this may be overridden) */ ip6_link_local_address_from_ethernet_address (&a->link_local_address, eth_if0->address); - a->link_local_prefix_len = 64; mhash_init (&a->address_to_prefix_index, sizeof (uword), sizeof (ip6_address_t)); mhash_init (&a->address_to_mldp_index, sizeof (uword), sizeof (ip6_address_t)); - { - u8 link_layer_address[6] = { 0x33, 0x33, 0x00, 0x00, 0x00, - IP6_MULTICAST_GROUP_ID_all_hosts - }; - - a->all_nodes_adj_index = - adj_rewrite_add_and_lock (FIB_PROTOCOL_IP6, VNET_LINK_IP6, - sw_if_index, link_layer_address); - } - - { - u8 link_layer_address[6] = { 0x33, 0x33, 0x00, 0x00, 0x00, - IP6_MULTICAST_GROUP_ID_all_routers - }; - - a->all_routers_adj_index = - adj_rewrite_add_and_lock (FIB_PROTOCOL_IP6, VNET_LINK_IP6, - sw_if_index, link_layer_address); - } - - { - u8 link_layer_address[6] = { 0x33, 0x33, 0x00, 0x00, 0x00, - IP6_MULTICAST_GROUP_ID_mldv2_routers - }; - - a->all_mldv2_routers_adj_index = - adj_rewrite_add_and_lock (FIB_PROTOCOL_IP6, - VNET_LINK_IP6, - sw_if_index, link_layer_address); - } + a->mcast_adj_index = adj_mcast_add_or_lock (FIB_PROTOCOL_IP6, + VNET_LINK_IP6, + sw_if_index); /* add multicast groups we will always be reporting */ ip6_address_t addr; @@ -2285,11 +2282,10 @@ ip6_neighbor_send_mldpv2_report (u32 sw_if_index) vnet_buffer (b0)->sw_if_index[VLIB_RX] = vnet_main.local_interface_sw_if_index; - vnet_buffer (b0)->ip.adj_index[VLIB_TX] = - radv_info->all_mldv2_routers_adj_index; + vnet_buffer (b0)->ip.adj_index[VLIB_TX] = radv_info->mcast_adj_index; b0->flags |= VNET_BUFFER_LOCALLY_ORIGINATED; - vlib_node_t *node = vlib_get_node_by_name (vm, (u8 *) "ip6-rewrite"); + vlib_node_t *node = vlib_get_node_by_name (vm, (u8 *) "ip6-rewrite-mcast"); f = vlib_get_frame_to_node (vm, node->index); to_next = vlib_frame_vector_args (f); @@ -2313,7 +2309,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_REPLY_RW] = "ip6-rewrite", + [ICMP6_ROUTER_SOLICITATION_NEXT_REPLY_RW] = "ip6-rewrite-mcast", [ICMP6_ROUTER_SOLICITATION_NEXT_REPLY_TX] = "interface-output", }, }; @@ -3266,9 +3262,7 @@ disable_ip6_interface (vlib_main_t * vm, u32 sw_if_index) /* essentially "disables" ipv6 on this interface */ error = ip6_add_del_interface_address (vm, sw_if_index, &radv_info-> - link_local_address, - radv_info-> - link_local_prefix_len, + link_local_address, 128, 1 /* is_del */ ); ip6_neighbor_sw_interface_add_del (vnm, sw_if_index, @@ -3372,7 +3366,6 @@ enable_ip6_interface (vlib_main_t * vm, u32 sw_if_index) else { radv_info->link_local_address = link_local_address; - radv_info->link_local_prefix_len = 64; } } } @@ -3585,8 +3578,7 @@ VLIB_CLI_COMMAND (ip6_nd_command, static) = clib_error_t * set_ip6_link_local_address (vlib_main_t * vm, - u32 sw_if_index, - ip6_address_t * address, u8 address_length) + u32 sw_if_index, ip6_address_t * address) { clib_error_t *error = 0; ip6_neighbor_main_t *nm = &ip6_neighbor_main; @@ -3615,22 +3607,18 @@ set_ip6_link_local_address (vlib_main_t * vm, /* delete the old one */ error = ip6_add_del_interface_address (vm, sw_if_index, &radv_info->link_local_address, - radv_info->link_local_prefix_len - /* address width */ , - 1 /* is_del */ ); + 128, 1 /* is_del */ ); if (!error) { /* add the new one */ error = ip6_add_del_interface_address (vm, sw_if_index, - address, address_length - /* address width */ , + address, 128, 0 /* is_del */ ); if (!error) { radv_info->link_local_address = *address; - radv_info->link_local_prefix_len = address_length; } } } @@ -3652,21 +3640,19 @@ set_ip6_link_local_address_cmd (vlib_main_t * vm, clib_error_t *error = 0; u32 sw_if_index; ip6_address_t ip6_addr; - u32 addr_len = 0; if (unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index)) { /* get the rest of the command */ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { - if (unformat (input, "%U/%d", - unformat_ip6_address, &ip6_addr, &addr_len)) + if (unformat (input, "%U", unformat_ip6_address, &ip6_addr)) break; else return (unformat_parse_error (input)); } } - error = set_ip6_link_local_address (vm, sw_if_index, &ip6_addr, addr_len); + error = set_ip6_link_local_address (vm, sw_if_index, &ip6_addr); return error; } @@ -3678,13 +3664,13 @@ set_ip6_link_local_address_cmd (vlib_main_t * vm, * * @cliexpar * Example of how to assign an IPv6 Link-local address to an interface: - * @cliexcmd{set ip6 link-local address GigabitEthernet2/0/0 FE80::AB8/64} + * @cliexcmd{set ip6 link-local address GigabitEthernet2/0/0 FE80::AB8} ?*/ /* *INDENT-OFF* */ VLIB_CLI_COMMAND (set_ip6_link_local_address_command, static) = { .path = "set ip6 link-local address", - .short_help = "set ip6 link-local address /", + .short_help = "set ip6 link-local address ", .function = set_ip6_link_local_address_cmd, }; /* *INDENT-ON* */