From 5bb1ecae8786fdf0fffde9e956a5cee477b5df20 Mon Sep 17 00:00:00 2001 From: Juraj Sloboda Date: Mon, 22 Oct 2018 09:57:13 +0200 Subject: [PATCH] IPv6: Make link-local configurable per-interface (VPP-1446) Remove old nonfunctional code for setting link-local addresses. Use common API for setting all IPv6 addresses. Change-Id: I562329df86341f81ef2441510a9eefbbf710f6e0 Signed-off-by: Juraj Sloboda Signed-off-by: Matus Fabian --- src/vat/api_format.c | 54 ----------------------------- src/vnet/api_errno.h | 2 +- src/vnet/ip/ip.api | 14 -------- src/vnet/ip/ip6_forward.c | 31 +++++++++++++++++ src/vnet/ip/ip6_neighbor.c | 84 +++++++++------------------------------------- src/vnet/ip/ip6_neighbor.h | 5 +++ src/vnet/ip/ip_api.c | 34 ------------------- src/vpp/api/custom_dump.c | 16 --------- 8 files changed, 52 insertions(+), 188 deletions(-) diff --git a/src/vat/api_format.c b/src/vat/api_format.c index 8b56f7693eb..599b29b2576 100644 --- a/src/vat/api_format.c +++ b/src/vat/api_format.c @@ -5469,7 +5469,6 @@ _(dhcp_proxy_set_vss_reply) \ _(dhcp_client_config_reply) \ _(set_ip_flow_hash_reply) \ _(sw_interface_ip6_enable_disable_reply) \ -_(sw_interface_ip6_set_link_local_address_reply) \ _(ip6nd_proxy_add_del_reply) \ _(sw_interface_ip6nd_ra_prefix_reply) \ _(sw_interface_ip6nd_ra_config_reply) \ @@ -5695,8 +5694,6 @@ _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply) \ _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply) \ _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY, \ sw_interface_ip6_enable_disable_reply) \ -_(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY, \ - sw_interface_ip6_set_link_local_address_reply) \ _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply) \ _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details) \ _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY, \ @@ -10685,55 +10682,6 @@ api_sw_interface_ip6_enable_disable (vat_main_t * vam) return ret; } -static int -api_sw_interface_ip6_set_link_local_address (vat_main_t * vam) -{ - unformat_input_t *i = vam->input; - vl_api_sw_interface_ip6_set_link_local_address_t *mp; - u32 sw_if_index; - u8 sw_if_index_set = 0; - u8 v6_address_set = 0; - ip6_address_t v6address; - int ret; - - /* Parse args required to build the message */ - while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) - { - if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index)) - sw_if_index_set = 1; - else if (unformat (i, "sw_if_index %d", &sw_if_index)) - sw_if_index_set = 1; - else if (unformat (i, "%U", unformat_ip6_address, &v6address)) - v6_address_set = 1; - else - break; - } - - if (sw_if_index_set == 0) - { - errmsg ("missing interface name or sw_if_index"); - return -99; - } - if (!v6_address_set) - { - errmsg ("no address set"); - return -99; - } - - /* Construct the API message */ - M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp); - - mp->sw_if_index = ntohl (sw_if_index); - clib_memcpy (mp->address, &v6address, sizeof (v6address)); - - /* send it... */ - S (mp); - - /* Wait for a reply, return good/bad news */ - W (ret); - return ret; -} - static int api_ip6nd_proxy_add_del (vat_main_t * vam) { @@ -23767,8 +23715,6 @@ _(set_ip_flow_hash, \ "vrf [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]") \ _(sw_interface_ip6_enable_disable, \ " | sw_if_index enable | disable") \ -_(sw_interface_ip6_set_link_local_address, \ - " | sw_if_index /") \ _(ip6nd_proxy_add_del, \ " | sw_if_index ") \ _(ip6nd_proxy_dump, "") \ diff --git a/src/vnet/api_errno.h b/src/vnet/api_errno.h index fdafb7e6b54..1ec5ad4a683 100644 --- a/src/vnet/api_errno.h +++ b/src/vnet/api_errno.h @@ -53,7 +53,7 @@ _(INVALID_SRC_ADDRESS, -57, "Invalid src address") \ _(INVALID_DST_ADDRESS, -58, "Invalid dst address") \ _(ADDRESS_LENGTH_MISMATCH, -59, "Address length mismatch") \ _(ADDRESS_NOT_FOUND_FOR_INTERFACE, -60, "Address not found for interface") \ -_(ADDRESS_NOT_LINK_LOCAL, -61, "Address not link-local") \ +_(ADDRESS_NOT_DELETABLE, -61, "Address not deletable") \ _(IP6_NOT_ENABLED, -62, "ip6 not enabled") \ _(IN_PROGRESS, 10, "Operation in progress") \ _(NO_SUCH_NODE, -63, "No such graph node") \ diff --git a/src/vnet/ip/ip.api b/src/vnet/ip/ip.api index 954ec92967f..cf25291b9bf 100644 --- a/src/vnet/ip/ip.api +++ b/src/vnet/ip/ip.api @@ -356,20 +356,6 @@ autoreply define sw_interface_ip6_enable_disable u8 enable; /* set to true if enable */ }; -/** \brief IPv6 set link local address on interface request - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param sw_if_index - interface to set link local on - @param address[] - the new link local address -*/ -autoreply define sw_interface_ip6_set_link_local_address -{ - u32 client_index; - u32 context; - u32 sw_if_index; - u8 address[16]; -}; - /** \brief Add / del route request @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request diff --git a/src/vnet/ip/ip6_forward.c b/src/vnet/ip/ip6_forward.c index 303c4bbd8e4..be0037e5edd 100644 --- a/src/vnet/ip/ip6_forward.c +++ b/src/vnet/ip/ip6_forward.c @@ -201,6 +201,7 @@ ip6_add_del_interface_address (vlib_main_t * vm, clib_error_t *error; u32 if_address_index; ip6_address_fib_t ip6_af, *addr_fib = 0; + ip6_address_t ll_addr; /* local0 interface doesn't support IP addressing */ if (sw_if_index == 0) @@ -209,6 +210,36 @@ ip6_add_del_interface_address (vlib_main_t * vm, clib_error_create ("local0 interface doesn't support IP addressing"); } + if (ip6_address_is_link_local_unicast (address)) + { + if (address_length != 128) + { + vnm->api_errno = VNET_API_ERROR_ADDRESS_LENGTH_MISMATCH; + return + clib_error_create + ("prefix length of link-local address must be 128"); + } + if (!is_del) + { + return ip6_neighbor_set_link_local_address (vm, sw_if_index, + address); + } + else + { + ll_addr = ip6_neighbor_get_link_local_address (sw_if_index); + if (ip6_address_is_equal (&ll_addr, address)) + { + vnm->api_errno = VNET_API_ERROR_ADDRESS_NOT_DELETABLE; + return clib_error_create ("address not deletable"); + } + else + { + vnm->api_errno = VNET_API_ERROR_ADDRESS_NOT_FOUND_FOR_INTERFACE; + return clib_error_create ("address not found"); + } + } + } + vec_validate (im->fib_index_by_sw_if_index, sw_if_index); vec_validate (im->mfib_index_by_sw_if_index, sw_if_index); diff --git a/src/vnet/ip/ip6_neighbor.c b/src/vnet/ip/ip6_neighbor.c index 177bcc14a7d..9be57207572 100755 --- a/src/vnet/ip/ip6_neighbor.c +++ b/src/vnet/ip/ip6_neighbor.c @@ -243,9 +243,10 @@ 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; + u32 ri = ~0; - ri = nm->if_radv_pool_index_by_sw_if_index[sw_if_index]; + if (vec_len (nm->if_radv_pool_index_by_sw_if_index) > sw_if_index) + 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); @@ -4424,21 +4425,19 @@ VLIB_CLI_COMMAND (ip6_nd_command, static) = /* *INDENT-ON* */ clib_error_t * -set_ip6_link_local_address (vlib_main_t * vm, - u32 sw_if_index, ip6_address_t * address) +ip6_neighbor_set_link_local_address (vlib_main_t * vm, u32 sw_if_index, + ip6_address_t * address) { clib_error_t *error = 0; ip6_neighbor_main_t *nm = &ip6_neighbor_main; u32 ri; ip6_radv_t *radv_info; vnet_main_t *vnm = vnet_get_main (); + ip6_ll_prefix_t pfx = { 0, }; if (!ip6_address_is_link_local_unicast (address)) - { - vnm->api_errno = VNET_API_ERROR_ADDRESS_NOT_LINK_LOCAL; - return (error = clib_error_return (0, "address not link-local", - format_unformat_error)); - } + return (error = clib_error_return (0, "address not link-local", + format_unformat_error)); /* call enable ipv6 */ enable_ip6_interface (vm, sw_if_index); @@ -4449,25 +4448,16 @@ set_ip6_link_local_address (vlib_main_t * vm, { radv_info = pool_elt_at_index (nm->if_radv_pool, ri); - /* save if link local address (overwrite default) */ + pfx.ilp_sw_if_index = sw_if_index; - /* delete the old one */ - error = ip6_add_del_interface_address (vm, sw_if_index, - &radv_info->link_local_address, - 128, 1 /* is_del */ ); + pfx.ilp_addr = radv_info->link_local_address; + ip6_ll_table_entry_delete (&pfx); - if (!error) - { - /* add the new one */ - error = ip6_add_del_interface_address (vm, sw_if_index, - address, 128, - 0 /* is_del */ ); + pfx.ilp_addr = *address; + ip6_ll_table_entry_update (&pfx, FIB_ROUTE_PATH_LOCAL); - if (!error) - { - radv_info->link_local_address = *address; - } - } + radv_info = pool_elt_at_index (nm->if_radv_pool, ri); + radv_info->link_local_address = *address; } else { @@ -4478,50 +4468,6 @@ set_ip6_link_local_address (vlib_main_t * vm, return error; } -clib_error_t * -set_ip6_link_local_address_cmd (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) -{ - vnet_main_t *vnm = vnet_get_main (); - clib_error_t *error = 0; - u32 sw_if_index; - ip6_address_t ip6_addr; - - 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", unformat_ip6_address, &ip6_addr)) - break; - else - return (unformat_parse_error (input)); - } - } - error = set_ip6_link_local_address (vm, sw_if_index, &ip6_addr); - return error; -} - -/*? - * This command is used to assign an IPv6 Link-local address to an - * interface. This command will enable IPv6 on an interface if it - * is not already enabled. Use the 'show ip6 interface' command - * to display the assigned Link-local address. - * - * @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} -?*/ -/* *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 ", - .function = set_ip6_link_local_address_cmd, -}; -/* *INDENT-ON* */ - /** * @brief callback when an interface address is added or deleted */ diff --git a/src/vnet/ip/ip6_neighbor.h b/src/vnet/ip/ip6_neighbor.h index 3256ba77da4..e273a10799f 100644 --- a/src/vnet/ip/ip6_neighbor.h +++ b/src/vnet/ip/ip6_neighbor.h @@ -46,6 +46,11 @@ typedef struct extern ip6_address_t ip6_neighbor_get_link_local_address (u32 sw_if_index); +extern clib_error_t *ip6_neighbor_set_link_local_address (vlib_main_t * vm, + u32 sw_if_index, + ip6_address_t * + address); + extern ip6_neighbor_t *ip6_neighbors_pool (void); extern ip6_neighbor_t *ip6_neighbors_entries (u32 sw_if_index); diff --git a/src/vnet/ip/ip_api.c b/src/vnet/ip/ip_api.c index 0d98ba5d597..1a31b5abf73 100644 --- a/src/vnet/ip/ip_api.c +++ b/src/vnet/ip/ip_api.c @@ -100,8 +100,6 @@ _(IP6ND_PROXY_ADD_DEL, ip6nd_proxy_add_del) \ _(IP6ND_PROXY_DUMP, ip6nd_proxy_dump) \ _(IP6ND_SEND_ROUTER_SOLICITATION, ip6nd_send_router_solicitation) \ _(SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable ) \ -_(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, \ - sw_interface_ip6_set_link_local_address) \ _(IP_CONTAINER_PROXY_ADD_DEL, ip_container_proxy_add_del) \ _(IP_CONTAINER_PROXY_DUMP, ip_container_proxy_dump) \ _(IOAM_ENABLE, ioam_enable) \ @@ -1825,38 +1823,6 @@ static void REPLY_MACRO (VL_API_SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY); } -static void - vl_api_sw_interface_ip6_set_link_local_address_t_handler - (vl_api_sw_interface_ip6_set_link_local_address_t * mp) -{ - vlib_main_t *vm = vlib_get_main (); - vl_api_sw_interface_ip6_set_link_local_address_reply_t *rmp; - int rv = 0; - clib_error_t *error; - vnet_main_t *vnm = vnet_get_main (); - - vnm->api_errno = 0; - - VALIDATE_SW_IF_INDEX (mp); - - error = set_ip6_link_local_address (vm, - ntohl (mp->sw_if_index), - (ip6_address_t *) mp->address); - if (error) - { - clib_error_report (error); - rv = VNET_API_ERROR_UNSPECIFIED; - } - else - { - rv = vnm->api_errno; - } - - BAD_SW_IF_INDEX_LABEL; - - REPLY_MACRO (VL_API_SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY); -} - void vl_mfib_signal_send_one (vl_api_registration_t * reg, u32 context, const mfib_signal_t * mfs) diff --git a/src/vpp/api/custom_dump.c b/src/vpp/api/custom_dump.c index e837b4deee4..833972108a8 100644 --- a/src/vpp/api/custom_dump.c +++ b/src/vpp/api/custom_dump.c @@ -1269,20 +1269,6 @@ static void *vl_api_set_ip_flow_hash_t_print FINISH; } -static void *vl_api_sw_interface_ip6_set_link_local_address_t_print - (vl_api_sw_interface_ip6_set_link_local_address_t * mp, void *handle) -{ - u8 *s; - - s = format (0, "SCRIPT: sw_interface_ip6_set_link_local_address "); - - s = format (s, "sw_if_index %d ", ntohl (mp->sw_if_index)); - - s = format (s, "%U ", format_ip6_address, mp->address); - - FINISH; -} - static void *vl_api_sw_interface_ip6nd_ra_prefix_t_print (vl_api_sw_interface_ip6nd_ra_prefix_t * mp, void *handle) { @@ -3774,8 +3760,6 @@ _(RESET_FIB, reset_fib) \ _(DHCP_PROXY_CONFIG, dhcp_proxy_config) \ _(DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss) \ _(SET_IP_FLOW_HASH, set_ip_flow_hash) \ -_(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, \ - sw_interface_ip6_set_link_local_address) \ _(SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix) \ _(SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config) \ _(SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit) \ -- 2.16.6