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 <jsloboda@cisco.com>
Signed-off-by: Matus Fabian <matfabia@cisco.com>
diff --git a/src/vnet/api_errno.h b/src/vnet/api_errno.h
index fdafb7e..1ec5ad4 100644
--- a/src/vnet/api_errno.h
+++ b/src/vnet/api_errno.h
@@ -53,7 +53,7 @@
_(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 954ec92..cf25291 100644
--- a/src/vnet/ip/ip.api
+++ b/src/vnet/ip/ip.api
@@ -356,20 +356,6 @@
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 303c4bb..be0037e 100644
--- a/src/vnet/ip/ip6_forward.c
+++ b/src/vnet/ip/ip6_forward.c
@@ -201,6 +201,7 @@
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 @@
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 177bcc1..9be5720 100755
--- a/src/vnet/ip/ip6_neighbor.c
+++ b/src/vnet/ip/ip6_neighbor.c
@@ -243,9 +243,10 @@
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 @@
/* *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 @@
{
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 @@
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 '<em>show ip6 interface</em>' 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 <interface> <ip6-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 3256ba7..e273a10 100644
--- a/src/vnet/ip/ip6_neighbor.h
+++ b/src/vnet/ip/ip6_neighbor.h
@@ -46,6 +46,11 @@
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 0d98ba5..1a31b5a 100644
--- a/src/vnet/ip/ip_api.c
+++ b/src/vnet/ip/ip_api.c
@@ -100,8 +100,6 @@
_(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 @@
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)