clib_warning ("Failed to delete interface address");
pool_put (rm->address_pool, address_info);
/* make sure ip6 stays enabled */
- ip6_link_enable (sw_if_index);
+ ip6_link_enable (sw_if_index, NULL);
client_state = &rm->client_state_by_sw_if_index[sw_if_index];
if (--client_state->address_count == 0)
{
dhcp6_clients_enable_disable (1);
}
- ip6_link_enable (sw_if_index);
+ ip6_link_enable (sw_if_index, NULL);
send_client_message_start_stop (sw_if_index, ~0, DHCPV6_MSG_SOLICIT,
0, 1);
}
dhcp6_clients_enable_disable (1);
}
- ip6_link_enable (sw_if_index);
+ ip6_link_enable (sw_if_index, NULL);
send_client_message_start_stop (sw_if_index, ~0, DHCPV6_MSG_SOLICIT,
0, 1);
}
{
int rv;
- rv = ip6_set_link_local_address (sw_if_index, address);
+ rv = ip6_link_set_local_address (sw_if_index, address);
if (rv)
{
return clib_error_create ("address not found");
}
}
+
+ return (NULL);
}
vec_validate (im->fib_index_by_sw_if_index, sw_if_index);
ip6_sw_interface_enable_disable (sw_if_index, !is_del);
if (!is_del)
- ip6_link_enable (sw_if_index);
+ ip6_link_enable (sw_if_index, NULL);
/* intf addr routes are added/deleted on admin up/down */
if (vnet_sw_interface_is_admin_up (vnm, 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;
sw = vnet_get_sup_sw_interface (vnm, sw_if_index);
- if (sw->type == VNET_SW_INTERFACE_TYPE_SUB ||
- sw->type == VNET_SW_INTERFACE_TYPE_PIPE ||
- sw->type == VNET_SW_INTERFACE_TYPE_P2P)
+ if (NULL != link_local_addr)
+ ip6_address_copy (&il->il_ll_addr, link_local_addr);
+ else if (sw->type == VNET_SW_INTERFACE_TYPE_SUB ||
+ sw->type == VNET_SW_INTERFACE_TYPE_PIPE ||
+ sw->type == VNET_SW_INTERFACE_TYPE_P2P)
{
il->il_ll_addr.as_u64[0] =
clib_host_to_net_u64 (0xFE80000000000000ULL);
}
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,
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
* IPv6 Configuration on an interface
*/
-extern int ip6_link_enable (u32 sw_if_index);
+extern int ip6_link_enable (u32 sw_if_index,
+ const ip6_address_t * link_local_addr);
extern bool ip6_link_is_enabled (u32 sw_if_index);
extern int ip6_link_disable (u32 sw_if_index);
extern const ip6_address_t *ip6_get_link_local_address (u32 sw_if_index);
-extern int ip6_set_link_local_address (u32 sw_if_index,
+extern int ip6_link_set_local_address (u32 sw_if_index,
const ip6_address_t * address);
extern adj_index_t ip6_link_get_mcast_adj (u32 sw_if_index);
VALIDATE_SW_IF_INDEX (mp);
rv = ((mp->enable == 1) ?
- ip6_link_enable (ntohl (mp->sw_if_index)) :
+ ip6_link_enable (ntohl (mp->sw_if_index), NULL) :
ip6_link_disable (ntohl (mp->sw_if_index)));
BAD_SW_IF_INDEX_LABEL;
ip6_address_decode (mp->ip, &ip);
- rv = ip6_set_link_local_address (ntohl (mp->sw_if_index), &ip);
+ rv = ip6_link_set_local_address (ntohl (mp->sw_if_index), &ip);
BAD_SW_IF_INDEX_LABEL;
REPLY_MACRO (VL_API_SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY);
u32 sw_if_index = slaac_address->sw_if_index;
remove_slaac_address (vm, slaac_address);
/* make sure ip6 stays enabled */
- ip6_link_enable (sw_if_index);
+ ip6_link_enable (sw_if_index, NULL);
}
}));
pool_foreach_index (index, rm->default_route_pool,
if_config = &rm->config_by_sw_if_index[sw_if_index];
if (!if_config->enabled && enable)
- ip6_link_enable (sw_if_index);
+ ip6_link_enable (sw_if_index, NULL);
if ((!if_config->enabled && enable)
|| (!if_config->install_default_routes && install_default_routes))
from vpp_ip_route import VppIpRoute, VppRoutePath, find_route, VppIpMRoute, \
VppMRoutePath, MRouteItfFlags, MRouteEntryFlags, VppMplsIpBind, \
VppMplsRoute, VppMplsTable, VppIpTable, FibPathType, FibPathProto, \
- VppIpInterfaceAddress, find_route_in_dump, find_mroute_in_dump
+ VppIpInterfaceAddress, find_route_in_dump, find_mroute_in_dump, \
+ VppIp6LinkLocalAddress
from vpp_neighbor import find_nbr, VppNeighbor
from vpp_pg_interface import is_ipv6_misc
from vpp_sub_interface import VppSubInterface, VppDot1QSubint
for i in self.pg_interfaces:
i.admin_up()
i.config_ip6()
- i.resolve_arp()
i.generate_remote_hosts(2)
self.tables.append(VppIpTable(self, table_id,
True).add_vpp_config())
super(TestIPReplace, self).tearDown()
for i in self.pg_interfaces:
i.admin_down()
- i.unconfig_ip4()
+ i.unconfig_ip6()
def test_replace(self):
""" IP Table Replace """
self.assertTrue(pfx.query_vpp_config())
+class TestIP6LinkLocal(VppTestCase):
+ """ IPv6 Link Local """
+
+ @classmethod
+ def setUpClass(cls):
+ super(TestIP6LinkLocal, cls).setUpClass()
+
+ @classmethod
+ def tearDownClass(cls):
+ super(TestIP6LinkLocal, cls).tearDownClass()
+
+ def setUp(self):
+ super(TestIP6LinkLocal, self).setUp()
+
+ self.create_pg_interfaces(range(2))
+
+ for i in self.pg_interfaces:
+ i.admin_up()
+
+ def tearDown(self):
+ super(TestIP6LinkLocal, self).tearDown()
+ for i in self.pg_interfaces:
+ i.admin_down()
+
+ def test_ip6_ll(self):
+ """ IPv6 Link Local """
+
+ #
+ # two APIs to add a link local address.
+ # 1 - just like any other prefix
+ # 2 - with the special set LL API
+ #
+
+ #
+ # First with the API to set a 'normal' prefix
+ #
+ ll1 = "fe80:1::1"
+ ll2 = "fe80:2::2"
+ ll3 = "fe80:3::3"
+
+ VppIpInterfaceAddress(self, self.pg0, ll1, 128).add_vpp_config()
+
+ #
+ # should be able to ping the ll
+ #
+ p_echo_request_1 = (Ether(src=self.pg0.remote_mac,
+ dst=self.pg0.local_mac) /
+ IPv6(src=ll2,
+ dst=ll1) /
+ ICMPv6EchoRequest())
+
+ self.send_and_expect(self.pg0, [p_echo_request_1], self.pg0)
+
+ #
+ # change the link-local on pg0
+ #
+ v_ll3 = VppIpInterfaceAddress(self, self.pg0,
+ ll3, 128).add_vpp_config()
+
+ p_echo_request_3 = (Ether(src=self.pg0.remote_mac,
+ dst=self.pg0.local_mac) /
+ IPv6(src=ll2,
+ dst=ll3) /
+ ICMPv6EchoRequest())
+
+ self.send_and_expect(self.pg0, [p_echo_request_3], self.pg0)
+
+ #
+ # set a normal v6 prefix on the link
+ #
+ self.pg0.config_ip6()
+
+ self.send_and_expect(self.pg0, [p_echo_request_3], self.pg0)
+
+ # the link-local cannot be removed
+ with self.vapi.assert_negative_api_retval():
+ v_ll3.remove_vpp_config()
+
+ #
+ # Use the specific link-local API on pg1
+ #
+ VppIp6LinkLocalAddress(self, self.pg1, ll1).add_vpp_config()
+ self.send_and_expect(self.pg1, [p_echo_request_1], self.pg1)
+
+ VppIp6LinkLocalAddress(self, self.pg1, ll3).add_vpp_config()
+ self.send_and_expect(self.pg1, [p_echo_request_3], self.pg1)
+
+
if __name__ == '__main__':
unittest.main(testRunner=VppTestRunner)
self.prefix)
+class VppIp6LinkLocalAddress(VppObject):
+
+ def __init__(self, test, intf, addr):
+ self._test = test
+ self.intf = intf
+ self.addr = addr
+
+ def add_vpp_config(self):
+ self._test.vapi.sw_interface_ip6_set_link_local_address(
+ sw_if_index=self.intf.sw_if_index, ip=self.addr)
+ self._test.registry.register(self, self._test.logger)
+ return self
+
+ def remove_vpp_config(self):
+ # link locals can't be removed, only changed
+ pass
+
+ def query_vpp_config(self):
+ # no API to query
+ return False
+
+ def object_id(self):
+ return "ip6-link-local-%s-%s" % (self.intf, self.addr)
+
+
class VppIpInterfaceBind(VppObject):
def __init__(self, test, intf, table):