lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250717115412.11424-3-richardbgobert@gmail.com>
Date: Thu, 17 Jul 2025 13:54:10 +0200
From: Richard Gobert <richardbgobert@...il.com>
To: davem@...emloft.net,
	edumazet@...gle.com,
	kuba@...nel.org,
	pabeni@...hat.com,
	horms@...nel.org,
	dsahern@...nel.org,
	razor@...ckwall.org,
	idosch@...dia.com,
	petrm@...dia.com,
	menglong8.dong@...il.com,
	richardbgobert@...il.com,
	daniel@...earbox.net,
	martin.lau@...nel.org,
	netdev@...r.kernel.org,
	linux-kernel@...r.kernel.org
Subject: [PATCH net-next v4 2/4] net: vxlan: add netlink option to bind vxlan sockets to local addresses

Currently, VXLAN sockets always bind to 0.0.0.0, even when a local
address is defined. This commit changes this behavior.

If two VXLAN endpoints are connected through two separate subnets,
they are each able to receive traffic through both subnets, regardless
of the local address. This commit breaks this behavior.

Add a netlink option to configure the new behavior. Since the scenario
described above is unrealistic, default to binding the socket to the
local address.

It is highly unlikely this change will break any networks.

Signed-off-by: Richard Gobert <richardbgobert@...il.com>
---
 drivers/net/vxlan/vxlan_core.c     | 23 ++++++++++++++++++++++-
 include/net/vxlan.h                |  1 +
 include/uapi/linux/if_link.h       |  1 +
 tools/include/uapi/linux/if_link.h |  1 +
 4 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
index bcde95cb2a2e..667ff17c4569 100644
--- a/drivers/net/vxlan/vxlan_core.c
+++ b/drivers/net/vxlan/vxlan_core.c
@@ -3406,6 +3406,7 @@ static const struct nla_policy vxlan_policy[IFLA_VXLAN_MAX + 1] = {
 	[IFLA_VXLAN_LABEL_POLICY]       = NLA_POLICY_MAX(NLA_U32, VXLAN_LABEL_MAX),
 	[IFLA_VXLAN_RESERVED_BITS] = NLA_POLICY_EXACT_LEN(sizeof(struct vxlanhdr)),
 	[IFLA_VXLAN_MC_ROUTE]		= NLA_POLICY_MAX(NLA_U8, 1),
+	[IFLA_VXLAN_LOCALBIND]	= { .type = NLA_U8 },
 };
 
 static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[],
@@ -4071,6 +4072,9 @@ static int vxlan_nl2conf(struct nlattr *tb[], struct nlattr *data[],
 		if (changelink && (conf->saddr.sa.sa_family != AF_INET)) {
 			NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_LOCAL], "New local address family does not match old");
 			return -EOPNOTSUPP;
+		} else if (changelink && (conf->flags & VXLAN_F_LOCALBIND)) {
+			NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_LOCAL], "Cannot change local address when bound locally");
+			return -EOPNOTSUPP;
 		}
 
 		conf->saddr.sin.sin_addr.s_addr = nla_get_in_addr(data[IFLA_VXLAN_LOCAL]);
@@ -4084,6 +4088,9 @@ static int vxlan_nl2conf(struct nlattr *tb[], struct nlattr *data[],
 		if (changelink && (conf->saddr.sa.sa_family != AF_INET6)) {
 			NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_LOCAL6], "New local address family does not match old");
 			return -EOPNOTSUPP;
+		} else if (changelink && (conf->flags & VXLAN_F_LOCALBIND)) {
+			NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_LOCAL6], "Cannot change local address when bound locally");
+			return -EOPNOTSUPP;
 		}
 
 		/* TODO: respect scope id */
@@ -4354,6 +4361,17 @@ static int vxlan_nl2conf(struct nlattr *tb[], struct nlattr *data[],
 		}
 	}
 
+	if (data[IFLA_VXLAN_LOCALBIND]) {
+		err = vxlan_nl2flag(conf, data, IFLA_VXLAN_LOCALBIND,
+				    VXLAN_F_LOCALBIND, changelink,
+				    false, extack);
+		if (err)
+			return err;
+	} else {
+		/* default to bind to the local address on a new device */
+		conf->flags |= VXLAN_F_LOCALBIND;
+	}
+
 	return 0;
 }
 
@@ -4517,6 +4535,7 @@ static size_t vxlan_get_size(const struct net_device *dev)
 		nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_VNIFILTER */
 		/* IFLA_VXLAN_RESERVED_BITS */
 		nla_total_size(sizeof(struct vxlanhdr)) +
+		nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_LOCALBIND */
 		0;
 }
 
@@ -4596,7 +4615,9 @@ static int vxlan_fill_info(struct sk_buff *skb, const struct net_device *dev)
 	    nla_put_u8(skb, IFLA_VXLAN_REMCSUM_RX,
 		       !!(vxlan->cfg.flags & VXLAN_F_REMCSUM_RX)) ||
 	    nla_put_u8(skb, IFLA_VXLAN_LOCALBYPASS,
-		       !!(vxlan->cfg.flags & VXLAN_F_LOCALBYPASS)))
+		       !!(vxlan->cfg.flags & VXLAN_F_LOCALBYPASS)) ||
+		nla_put_u8(skb, IFLA_VXLAN_LOCALBIND,
+			   !!(vxlan->cfg.flags & VXLAN_F_LOCALBIND)))
 		goto nla_put_failure;
 
 	if (nla_put(skb, IFLA_VXLAN_PORT_RANGE, sizeof(ports), &ports))
diff --git a/include/net/vxlan.h b/include/net/vxlan.h
index 0ee50785f4f1..e356b5294535 100644
--- a/include/net/vxlan.h
+++ b/include/net/vxlan.h
@@ -333,6 +333,7 @@ struct vxlan_dev {
 #define VXLAN_F_MDB			0x40000
 #define VXLAN_F_LOCALBYPASS		0x80000
 #define VXLAN_F_MC_ROUTE		0x100000
+#define VXLAN_F_LOCALBIND		0x200000
 
 /* Flags that are used in the receive path. These flags must match in
  * order for a socket to be shareable
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 784ace3a519c..7350129b1444 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -1399,6 +1399,7 @@ enum {
 	IFLA_VXLAN_LABEL_POLICY, /* IPv6 flow label policy; ifla_vxlan_label_policy */
 	IFLA_VXLAN_RESERVED_BITS,
 	IFLA_VXLAN_MC_ROUTE,
+	IFLA_VXLAN_LOCALBIND,
 	__IFLA_VXLAN_MAX
 };
 #define IFLA_VXLAN_MAX	(__IFLA_VXLAN_MAX - 1)
diff --git a/tools/include/uapi/linux/if_link.h b/tools/include/uapi/linux/if_link.h
index 7e46ca4cd31b..eee934cc2cf4 100644
--- a/tools/include/uapi/linux/if_link.h
+++ b/tools/include/uapi/linux/if_link.h
@@ -1396,6 +1396,7 @@ enum {
 	IFLA_VXLAN_VNIFILTER, /* only applicable with COLLECT_METADATA mode */
 	IFLA_VXLAN_LOCALBYPASS,
 	IFLA_VXLAN_LABEL_POLICY, /* IPv6 flow label policy; ifla_vxlan_label_policy */
+	IFLA_VXLAN_LOCALBIND,
 	__IFLA_VXLAN_MAX
 };
 #define IFLA_VXLAN_MAX	(__IFLA_VXLAN_MAX - 1)
-- 
2.36.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ