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;
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);
+
+ /* use a user provided LL address if given */
+ if (NULL != link_local_addr)
+ ip6_address_copy (&il->il_ll_addr, link_local_addr);
- sw = vnet_get_sup_sw_interface (vnm, sw_if_index);
+ /* 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);
- if (sw->type == VNET_SW_INTERFACE_TYPE_SUB ||
- sw->type == VNET_SW_INTERFACE_TYPE_PIPE ||
- sw->type == VNET_SW_INTERFACE_TYPE_P2P)
+ /* 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);
/* 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 = {
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;
rv = VNET_API_ERROR_VALUE_EXIST;
}
-out:
+ il->il_locks++;
+
return (rv);
}
{
ip6_link_delegate_t *ild;
- /* *INDET-OFF* */
- FOREACH_IP6_LINK_DELEGATE (ild, il, (
- {
- il_delegate_vfts[ild->
- ild_type].ildv_disable
- (ild->ild_index);
- }));
- /* *INDET-ON* */
+ FOREACH_IP6_LINK_DELEGATE (ild, il,
+ ({
+ il_delegate_vfts[ild->ild_type].ildv_disable(ild->ild_index);
+ }));
vec_free (il->il_delegates);
il->il_delegates = NULL;
{
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);
}
{
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;
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,
ip6_address_copy (&ilp.ilp_addr, address);
ip6_ll_table_entry_update (&ilp, FIB_ROUTE_PATH_LOCAL);
- /* *INDENT-OFF* */
FOREACH_IP6_LINK_DELEGATE (ild, il,
({
if (NULL != il_delegate_vfts[ild->ild_type].ildv_ll_change)
il_delegate_vfts[ild->ild_type].ildv_ll_change(ild->ild_index,
&il->il_ll_addr);
}));
- /* *INDENT-ON* */
return (0);
}
if (NULL == il)
return;
- /* *INDENT-OFF* */
FOREACH_IP6_LINK_DELEGATE (ild, il,
({
if (is_delete)
address, address_length);
}
}));
- /* *INDENT-ON* */
}
static clib_error_t *
* Original MAC address: 16:d9:e0:91:79:86
* @cliexend
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (test_link_command, static) =
{
.path = "test ip6 link",
.function = test_ip6_link_command_fn,
.short_help = "test ip6 link <mac-address>",
};
-/* *INDENT-ON* */
static u8 *
ip6_print_addrs (u8 * s, u32 * addrs)
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;
s = format (s, "%U%U\n",
format_white_space, 4, format_ip6_address, &il->il_ll_addr);
- /* *INDENT-OFF* */
FOREACH_IP6_LINK_DELEGATE(ild, il,
({
s = format (s, "%U", il_delegate_vfts[ild->ild_type].ildv_format,
ild->ild_index, 2);
}));
- /* *INDENT-ON* */
return (s);
}
* show ip6 interface: IPv6 not enabled on interface
* @cliexend
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (ip6_link_show_command, static) =
{
.path = "show ip6 interface",
.function = ip6_link_show,
.short_help = "show ip6 interface <interface>",
};
-/* *INDENT-ON* */
static clib_error_t *
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
* Example of how enable IPv6 on a given interface:
* @cliexcmd{enable ip6 interface GigabitEthernet2/0/0}
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (enable_ip6_interface_command, static) =
{
.path = "enable ip6 interface",
.function = enable_ip6_interface_cmd,
.short_help = "enable ip6 interface <interface>",
};
-/* *INDENT-ON* */
static clib_error_t *
disable_ip6_interface_cmd (vlib_main_t * vm,
* Example of how disable IPv6 on a given interface:
* @cliexcmd{disable ip6 interface GigabitEthernet2/0/0}
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (disable_ip6_interface_command, static) =
{
.path = "disable ip6 interface",
.function = disable_ip6_interface_cmd,
.short_help = "disable ip6 interface <interface>",
};
-/* *INDENT-ON* */
/*
* fd.io coding-style-patch-verification: ON