X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fip%2Fip6_link.c;h=544a7c335059fe760aa4bfa2fea84cd82f766d97;hb=refs%2Fchanges%2F37%2F40437%2F2;hp=35b718e6dcbca6ea6f4fa71df7e5d4ac0c3b0538;hpb=306c3080d9276d020cee2cb70404a1e7d9032eb0;p=vpp.git diff --git a/src/vnet/ip/ip6_link.c b/src/vnet/ip/ip6_link.c index 35b718e6dcb..544a7c33505 100644 --- a/src/vnet/ip/ip6_link.c +++ b/src/vnet/ip/ip6_link.c @@ -146,7 +146,7 @@ ip6_link_is_enabled (u32 sw_if_index) int -ip6_link_enable (u32 sw_if_index) +ip6_link_enable (u32 sw_if_index, const ip6_address_t * link_local_addr) { ip6_link_t *il; int rv; @@ -155,41 +155,38 @@ ip6_link_enable (u32 sw_if_index) if (NULL == il) { - const vnet_sw_interface_t *sw, *sw_sup; + const vnet_sw_interface_t *sw_sup; const ethernet_interface_t *eth; vnet_main_t *vnm; + eth = NULL; vnm = vnet_get_main (); IP6_LINK_INFO ("enable: %U", format_vnet_sw_if_index_name, vnm, sw_if_index); sw_sup = vnet_get_sup_sw_interface (vnm, sw_if_index); - if (sw_sup->type != VNET_SW_INTERFACE_TYPE_HARDWARE) - { - rv = VNET_API_ERROR_UNSUPPORTED; - goto out; - } - - eth = ethernet_get_interface (ðernet_main, sw_sup->hw_if_index); - - if (NULL == eth) - { - rv = VNET_API_ERROR_UNSUPPORTED; - goto out; - } - vec_validate (ip6_links, sw_if_index); il = &ip6_links[sw_if_index]; - il->il_locks = 1; + il->il_locks = 0; il->il_sw_if_index = sw_if_index; + il->il_mcast_adj = ADJ_INDEX_INVALID; + + if (sw_sup->type == VNET_SW_INTERFACE_TYPE_HARDWARE) + eth = ethernet_get_interface (ðernet_main, sw_sup->hw_if_index); - sw = vnet_get_sup_sw_interface (vnm, sw_if_index); + /* use a user provided LL address if given */ + if (NULL != link_local_addr) + ip6_address_copy (&il->il_ll_addr, link_local_addr); - if (sw->type == VNET_SW_INTERFACE_TYPE_SUB || - sw->type == VNET_SW_INTERFACE_TYPE_PIPE || - sw->type == VNET_SW_INTERFACE_TYPE_P2P) + /* generate from ethernet MAC */ + if (ip6_address_is_zero (&il->il_ll_addr) && NULL != eth) + ip6_link_local_address_from_mac (&il->il_ll_addr, + eth->address.mac.bytes); + + /* choose a random address */ + if (ip6_address_is_zero (&il->il_ll_addr)) { il->il_ll_addr.as_u64[0] = clib_host_to_net_u64 (0xFE80000000000000ULL); @@ -200,10 +197,6 @@ ip6_link_enable (u32 sw_if_index) /* clear u bit */ il->il_ll_addr.as_u8[8] &= 0xfd; } - else - { - ip6_link_local_address_from_mac (&il->il_ll_addr, eth->address); - } { ip6_ll_prefix_t ilp = { @@ -218,8 +211,11 @@ ip6_link_enable (u32 sw_if_index) ip6_mfib_interface_enable_disable (sw_if_index, 1); ip6_sw_interface_enable_disable (sw_if_index, 1); - il->il_mcast_adj = adj_mcast_add_or_lock (FIB_PROTOCOL_IP6, - VNET_LINK_IP6, sw_if_index); + /* only ehternet interfaces support MLD and RA, which use the mcast adj + */ + if (NULL != eth) + il->il_mcast_adj = + adj_mcast_add_or_lock (FIB_PROTOCOL_IP6, VNET_LINK_IP6, sw_if_index); /* inform all register clients */ ip6_link_delegate_id_t id; @@ -236,7 +232,8 @@ ip6_link_enable (u32 sw_if_index) rv = VNET_API_ERROR_VALUE_EXIST; } -out: + il->il_locks++; + return (rv); } @@ -314,9 +311,10 @@ ip6_get_link_local_address (u32 sw_if_index) { const ip6_link_t *il; - vec_validate (ip6_links, sw_if_index); + il = ip6_link_get (sw_if_index); - il = &ip6_links[sw_if_index]; + if (NULL == il) + return (NULL); return (&il->il_ll_addr); } @@ -326,48 +324,16 @@ ip6_link_get_mcast_adj (u32 sw_if_index) { const ip6_link_t *il; - il = &ip6_links[sw_if_index]; - - return (il->il_mcast_adj); -} - -int -ip6_src_address_for_packet (u32 sw_if_index, - const ip6_address_t * dst, ip6_address_t * src) -{ - ip_lookup_main_t *lm; - - lm = &ip6_main.lookup_main; - - if (ip6_address_is_link_local_unicast (dst)) - { - ip6_address_copy (src, ip6_get_link_local_address (sw_if_index)); - - return (!0); - } - else - { - u32 if_add_index = - lm->if_address_pool_index_by_sw_if_index[sw_if_index]; - if (PREDICT_TRUE (if_add_index != ~0)) - { - ip_interface_address_t *if_add = - pool_elt_at_index (lm->if_address_pool, if_add_index); - ip6_address_t *if_ip = - ip_interface_address_get_address (lm, if_add); - *src = *if_ip; - return (!0); - } - } + il = ip6_link_get (sw_if_index); - src->as_u64[0] = 0; - src->as_u64[1] = 0; + if (NULL == il) + return (INDEX_INVALID); - return (0); + return (il->il_mcast_adj); } int -ip6_set_link_local_address (u32 sw_if_index, const ip6_address_t * address) +ip6_link_set_local_address (u32 sw_if_index, const ip6_address_t * address) { ip6_link_delegate_t *ild; ip6_link_t *il; @@ -375,7 +341,7 @@ ip6_set_link_local_address (u32 sw_if_index, const ip6_address_t * address) il = ip6_link_get (sw_if_index); if (NULL == il) - return (VNET_API_ERROR_IP6_NOT_ENABLED); + return ip6_link_enable (sw_if_index, address); ip6_ll_prefix_t ilp = { .ilp_addr = il->il_ll_addr, @@ -628,11 +594,10 @@ format_ip6_link (u8 * s, va_list * arg) if (!ip6_link_is_enabled_i (il)) return (s); - s = format (s, "%U is admin %s\n", - format_vnet_sw_interface_name, vnm, - vnet_get_sw_interface (vnm, il->il_sw_if_index), - (vnet_sw_interface_is_admin_up (vnm, il->il_sw_if_index) ? - "up" : "down")); + s = format ( + s, "%U is admin %s\n", format_vnet_sw_if_index_name, vnm, + il->il_sw_if_index, + (vnet_sw_interface_is_admin_up (vnm, il->il_sw_if_index) ? "up" : "down")); u32 ai; u32 *link_scope = 0, *global_scope = 0; @@ -794,7 +759,7 @@ enable_ip6_interface_cmd (vlib_main_t * vm, if (unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index)) { - if (ip6_link_enable (sw_if_index)) + if (ip6_link_enable (sw_if_index, NULL)) error = clib_error_return (0, "Failed\n"); } else