summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/vnet/ip/ip6_link.c46
-rw-r--r--test/test_ip6.py80
2 files changed, 97 insertions, 29 deletions
diff --git a/src/vnet/ip/ip6_link.c b/src/vnet/ip/ip6_link.c
index 0527b2ffc52..afa9d8e3ea9 100644
--- a/src/vnet/ip/ip6_link.c
+++ b/src/vnet/ip/ip6_link.c
@@ -155,43 +155,38 @@ ip6_link_enable (u32 sw_if_index, const ip6_address_t * link_local_addr)
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 (&ethernet_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 = 0;
il->il_sw_if_index = sw_if_index;
+ il->il_mcast_adj = ADJ_INDEX_INVALID;
- sw = vnet_get_sup_sw_interface (vnm, sw_if_index);
+ if (sw_sup->type == VNET_SW_INTERFACE_TYPE_HARDWARE)
+ eth = ethernet_get_interface (&ethernet_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);
- else 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);
@@ -202,11 +197,6 @@ ip6_link_enable (u32 sw_if_index, const ip6_address_t * link_local_addr)
/* clear u bit */
il->il_ll_addr.as_u8[8] &= 0xfd;
}
- else
- {
- ip6_link_local_address_from_mac (&il->il_ll_addr,
- eth->address.mac.bytes);
- }
{
ip6_ll_prefix_t ilp = {
@@ -221,8 +211,11 @@ ip6_link_enable (u32 sw_if_index, const ip6_address_t * link_local_addr)
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;
@@ -241,7 +234,6 @@ ip6_link_enable (u32 sw_if_index, const ip6_address_t * link_local_addr)
il->il_locks++;
-out:
return (rv);
}
diff --git a/test/test_ip6.py b/test/test_ip6.py
index 7635a01c7ce..6eabf5af0ec 100644
--- a/test/test_ip6.py
+++ b/test/test_ip6.py
@@ -7,14 +7,14 @@ import unittest
from parameterized import parameterized
import scapy.compat
import scapy.layers.inet6 as inet6
-from scapy.layers.inet import UDP
+from scapy.layers.inet import UDP, IP
from scapy.contrib.mpls import MPLS
from scapy.layers.inet6 import IPv6, ICMPv6ND_NS, ICMPv6ND_RS, \
ICMPv6ND_RA, ICMPv6NDOptMTU, ICMPv6NDOptSrcLLAddr, ICMPv6NDOptPrefixInfo, \
ICMPv6ND_NA, ICMPv6NDOptDstLLAddr, ICMPv6DestUnreach, icmp6types, \
ICMPv6TimeExceeded, ICMPv6EchoRequest, ICMPv6EchoReply, \
IPv6ExtHdrHopByHop, ICMPv6MLReport2, ICMPv6MLDMultAddrRec
-from scapy.layers.l2 import Ether, Dot1Q
+from scapy.layers.l2 import Ether, Dot1Q, GRE
from scapy.packet import Raw
from scapy.utils6 import in6_getnsma, in6_getnsmac, in6_ptop, in6_islladdr, \
in6_mactoifaceid
@@ -35,6 +35,8 @@ from vpp_pg_interface import is_ipv6_misc
from vpp_sub_interface import VppSubInterface, VppDot1QSubint
from vpp_policer import VppPolicer, PolicerAction
from ipaddress import IPv6Network, IPv6Address
+from vpp_gre_interface import VppGreInterface
+from vpp_teib import VppTeib
AF_INET6 = socket.AF_INET6
@@ -3002,6 +3004,11 @@ class TestIP6LinkLocal(VppTestCase):
ll2 = "fe80:2::2"
ll3 = "fe80:3::3"
+ VppNeighbor(self,
+ self.pg0.sw_if_index,
+ self.pg0.remote_mac,
+ ll2).add_vpp_config()
+
VppIpInterfaceAddress(self, self.pg0, ll1, 128).add_vpp_config()
#
@@ -3049,6 +3056,75 @@ class TestIP6LinkLocal(VppTestCase):
VppIp6LinkLocalAddress(self, self.pg1, ll3).add_vpp_config()
self.send_and_expect(self.pg1, [p_echo_request_3], self.pg1)
+ def test_ip6_ll_p2p(self):
+ """ IPv6 Link Local P2P (GRE)"""
+
+ self.pg0.config_ip4()
+ self.pg0.resolve_arp()
+ gre_if = VppGreInterface(self,
+ self.pg0.local_ip4,
+ self.pg0.remote_ip4).add_vpp_config()
+ gre_if.admin_up()
+
+ ll1 = "fe80:1::1"
+ ll2 = "fe80:2::2"
+
+ VppIpInterfaceAddress(self, gre_if, ll1, 128).add_vpp_config()
+
+ self.logger.info(self.vapi.cli("sh ip6-ll gre0 fe80:2::2"))
+
+ p_echo_request_1 = (Ether(src=self.pg0.remote_mac,
+ dst=self.pg0.local_mac) /
+ IP(src=self.pg0.remote_ip4,
+ dst=self.pg0.local_ip4) /
+ GRE() /
+ IPv6(src=ll2, dst=ll1) /
+ ICMPv6EchoRequest())
+ self.send_and_expect(self.pg0, [p_echo_request_1], self.pg0)
+
+ self.pg0.unconfig_ip4()
+ gre_if.remove_vpp_config()
+
+ def test_ip6_ll_p2mp(self):
+ """ IPv6 Link Local P2MP (GRE)"""
+
+ self.pg0.config_ip4()
+ self.pg0.resolve_arp()
+
+ gre_if = VppGreInterface(
+ self,
+ self.pg0.local_ip4,
+ "0.0.0.0",
+ mode=(VppEnum.vl_api_tunnel_mode_t.
+ TUNNEL_API_MODE_MP)).add_vpp_config()
+ gre_if.admin_up()
+
+ ll1 = "fe80:1::1"
+ ll2 = "fe80:2::2"
+
+ VppIpInterfaceAddress(self, gre_if, ll1, 128).add_vpp_config()
+
+ p_echo_request_1 = (Ether(src=self.pg0.remote_mac,
+ dst=self.pg0.local_mac) /
+ IP(src=self.pg0.remote_ip4,
+ dst=self.pg0.local_ip4) /
+ GRE() /
+ IPv6(src=ll2, dst=ll1) /
+ ICMPv6EchoRequest())
+
+ # no route back at this point
+ self.send_and_assert_no_replies(self.pg0, [p_echo_request_1])
+
+ # add teib entry for the peer
+ teib = VppTeib(self, gre_if, ll2, self.pg0.remote_ip4)
+ teib.add_vpp_config()
+
+ self.logger.info(self.vapi.cli("sh ip6-ll gre0 %s" % ll2))
+ self.send_and_expect(self.pg0, [p_echo_request_1], self.pg0)
+
+ # teardown
+ self.pg0.unconfig_ip4()
+
class TestIPv6PathMTU(VppTestCase):
""" IPv6 Path MTU """