naccyde / rpms / iproute

Forked from rpms/iproute 5 months ago
Clone
Blob Blame History Raw
From f08a8608335d46bea1b2cb122823a4c538ce6e46 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 18 Oct 2018 10:53:57 +0200
Subject: [PATCH] iplink_vxlan: take into account preferred_family creating
 vxlan device

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1626321
Upstream Status: iproute2.git commit c1360e3b483e5

commit c1360e3b483e54a61a36bd2fdb3bfb91a4d2b32a
Author: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
Date:   Fri Sep 21 15:34:25 2018 +0200

    iplink_vxlan: take into account preferred_family creating vxlan device

    Take into account the configured preferred_family if neither saddr or
    daddr are provided since otherwise vxlan kernel module will use IPv4 as
    default remote inet family neglecting the one provided by userspace.
    This behaviour was originally in commit 97d564b90ccb ("vxlan: use
    preferred address family when neither group or remote is specified").
    The issue can be triggered with the following reproducer:

    $ip -6 link add vxlan1 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

    Fixes: 1e9b8072de2c ("iplink_vxlan: Get rid of inet_get_addr()")
    Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 ip/iplink_vxlan.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/ip/iplink_vxlan.c b/ip/iplink_vxlan.c
index 2bc253f..831f39a 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))
-- 
1.8.3.1