diff mbox series

iproute2: fail to add fdb entries to ipv6 vxlan device

Message ID 20180917171325.GA2660@localhost.localdomain
State Superseded, archived
Delegated to: stephen hemminger
Headers show
Series iproute2: fail to add fdb entries to ipv6 vxlan device | expand

Commit Message

Lorenzo Bianconi Sept. 17, 2018, 5:13 p.m. UTC
Hi all,

while working on IPv6 vlxan driver I figured out that with recent version
of iproute2 it is no longer possible to configure an IPv6 vxlan device without
endpoint info (local ip, remote ip or group ip) and later add entries in
the vxlan fdb. This issue can be triggered with the following reproducer:

$ip -6 link add vxlan0 type vxlan id 42 dev enp0s2 \
    proxy nolearning l2miss l3miss
$bridge fdb add 46:47:1f:a7:1c:25 dev vxlan1 dst 2000::2
RTNETLINK answers: Address family not supported by protocol

Starting from commit 1e9b8072de2c ("iplink_vxlan: Get rid of inet_get_addr()")
the preferred_family is no longer taken into account if neither saddr or daddr
are provided and vxlan kernel module will use IPv4 as default remote inet
family neglecting the one provided by userspace.
I guess we can fix that issue in two ways:

1- add a new netlink attribute to vxlan driver in order to specify the
preferred_family to use

2- restore the behaviour introduced in commit 97d564b90ccb ("vxlan: use
preferred address family when neither group or remote is specified") with
the following patch

-- >8 --
-- 8< --

What is the best way to proceed?

Regards,
Lorenzo
diff mbox series

Patch

diff --git a/ip/iplink_vxlan.c b/ip/iplink_vxlan.c
index 2bc253fc..831f39a2 100644
--- a/ip/iplink_vxlan.c
+++ b/ip/iplink_vxlan.c
@@ -82,6 +82,7 @@  static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
 	__u64 attrs = 0;
 	bool set_op = (n->nlmsg_type == RTM_NEWLINK &&
 		       !(n->nlmsg_flags & NLM_F_CREATE));
+	bool selected_family = false;
 
 	saddr.family = daddr.family = AF_UNSPEC;
 
@@ -356,12 +357,26 @@  static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
 		int type = (saddr.family == AF_INET) ? IFLA_VXLAN_LOCAL
 						     : IFLA_VXLAN_LOCAL6;
 		addattr_l(n, 1024, type, saddr.data, saddr.bytelen);
+		selected_family = true;
 	}
 
 	if (is_addrtype_inet(&daddr)) {
 		int type = (daddr.family == AF_INET) ? IFLA_VXLAN_GROUP
 						     : IFLA_VXLAN_GROUP6;
 		addattr_l(n, 1024, type, daddr.data, daddr.bytelen);
+		selected_family = true;
+	}
+
+	if (!selected_family) {
+		if (preferred_family == AF_INET) {
+			get_addr(&daddr, "default", AF_INET);
+			addattr_l(n, 1024, IFLA_VXLAN_GROUP,
+				  daddr.data, daddr.bytelen);
+		} else if (preferred_family == AF_INET6) {
+			get_addr(&daddr, "default", AF_INET6);
+			addattr_l(n, 1024, IFLA_VXLAN_GROUP6,
+				  daddr.data, daddr.bytelen);
+		}
 	}
 
 	if (!set_op || VXLAN_ATTRSET(attrs, IFLA_VXLAN_LEARNING))