* [PATCH net-next v5 1/5] net: udp: add freebind option to udp_sock_create
2025-08-12 12:51 [PATCH net-next v5 0/5] net: add local address bind support to vxlan and geneve Richard Gobert
@ 2025-08-12 12:51 ` Richard Gobert
2025-08-13 9:25 ` Ido Schimmel
2025-08-12 12:51 ` [PATCH net-next v5 2/5] net: vxlan: add netlink option to bind vxlan sockets to local addresses Richard Gobert
` (4 subsequent siblings)
5 siblings, 1 reply; 23+ messages in thread
From: Richard Gobert @ 2025-08-12 12:51 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, kuba, pabeni, horms, donald.hunter,
andrew+netdev, dsahern, shuah, daniel, jacob.e.keller, razor,
idosch, petrm, menglong8.dong, martin.lau, linux-kernel,
Richard Gobert
udp_sock_create creates a UDP socket and binds it according to
udp_port_cfg.
Add a freebind option to udp_port_cfg that allows a socket to be bound
as though IP_FREEBIND is set.
This change is required for binding vxlan sockets to their local address
when the outgoing interface is down.
Signed-off-by: Richard Gobert <richardbgobert@gmail.com>
---
include/net/udp_tunnel.h | 3 ++-
net/ipv4/udp_tunnel_core.c | 1 +
net/ipv6/ip6_udp_tunnel.c | 1 +
3 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/include/net/udp_tunnel.h b/include/net/udp_tunnel.h
index 9acef2fbd2fd..6c1362aa3576 100644
--- a/include/net/udp_tunnel.h
+++ b/include/net/udp_tunnel.h
@@ -34,7 +34,8 @@ struct udp_port_cfg {
unsigned int use_udp_checksums:1,
use_udp6_tx_checksums:1,
use_udp6_rx_checksums:1,
- ipv6_v6only:1;
+ ipv6_v6only:1,
+ freebind:1;
};
int udp_sock_create4(struct net *net, struct udp_port_cfg *cfg,
diff --git a/net/ipv4/udp_tunnel_core.c b/net/ipv4/udp_tunnel_core.c
index fce945f23069..147fd8ff4f49 100644
--- a/net/ipv4/udp_tunnel_core.c
+++ b/net/ipv4/udp_tunnel_core.c
@@ -28,6 +28,7 @@ int udp_sock_create4(struct net *net, struct udp_port_cfg *cfg,
udp_addr.sin_family = AF_INET;
udp_addr.sin_addr = cfg->local_ip;
udp_addr.sin_port = cfg->local_udp_port;
+ inet_assign_bit(FREEBIND, sock->sk, cfg->freebind);
err = kernel_bind(sock, (struct sockaddr *)&udp_addr,
sizeof(udp_addr));
if (err < 0)
diff --git a/net/ipv6/ip6_udp_tunnel.c b/net/ipv6/ip6_udp_tunnel.c
index 0ff547a4bff7..65ff44c274b8 100644
--- a/net/ipv6/ip6_udp_tunnel.c
+++ b/net/ipv6/ip6_udp_tunnel.c
@@ -40,6 +40,7 @@ int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
memcpy(&udp6_addr.sin6_addr, &cfg->local_ip6,
sizeof(udp6_addr.sin6_addr));
udp6_addr.sin6_port = cfg->local_udp_port;
+ inet_assign_bit(FREEBIND, sock->sk, cfg->freebind);
err = kernel_bind(sock, (struct sockaddr *)&udp6_addr,
sizeof(udp6_addr));
if (err < 0)
--
2.36.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH net-next v5 1/5] net: udp: add freebind option to udp_sock_create
2025-08-12 12:51 ` [PATCH net-next v5 1/5] net: udp: add freebind option to udp_sock_create Richard Gobert
@ 2025-08-13 9:25 ` Ido Schimmel
2025-08-13 15:10 ` Richard Gobert
0 siblings, 1 reply; 23+ messages in thread
From: Ido Schimmel @ 2025-08-13 9:25 UTC (permalink / raw)
To: Richard Gobert
Cc: netdev, davem, edumazet, kuba, pabeni, horms, donald.hunter,
andrew+netdev, dsahern, shuah, daniel, jacob.e.keller, razor,
petrm, menglong8.dong, martin.lau, linux-kernel
On Tue, Aug 12, 2025 at 02:51:51PM +0200, Richard Gobert wrote:
> udp_sock_create creates a UDP socket and binds it according to
> udp_port_cfg.
>
> Add a freebind option to udp_port_cfg that allows a socket to be bound
> as though IP_FREEBIND is set.
>
> This change is required for binding vxlan sockets to their local address
> when the outgoing interface is down.
It's not necessarily the outgoing interface, but rather the interface to
which the address is assigned.
Anyway, I'm not sure this change is actually necessary. It was only
added in v4 because back then the default behavior was changed to bind
the VXLAN socket to the local address and existing selftests do not
necessarily configure the address before putting the VXLAN device up.
Given that in this version binding the VXLAN socket to the local address
is opt-in, it seems legitimate to prevent user space from putting the
VXLAN device up if the new option is enabled and the local address is
not present. It can also be documented in the man page so that users are
not surprised.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH net-next v5 1/5] net: udp: add freebind option to udp_sock_create
2025-08-13 9:25 ` Ido Schimmel
@ 2025-08-13 15:10 ` Richard Gobert
0 siblings, 0 replies; 23+ messages in thread
From: Richard Gobert @ 2025-08-13 15:10 UTC (permalink / raw)
To: Ido Schimmel
Cc: netdev, davem, edumazet, kuba, pabeni, horms, donald.hunter,
andrew+netdev, dsahern, shuah, daniel, jacob.e.keller, razor,
petrm, menglong8.dong, martin.lau, linux-kernel
Ido Schimmel wrote:
> On Tue, Aug 12, 2025 at 02:51:51PM +0200, Richard Gobert wrote:
>> udp_sock_create creates a UDP socket and binds it according to
>> udp_port_cfg.
>>
>> Add a freebind option to udp_port_cfg that allows a socket to be bound
>> as though IP_FREEBIND is set.
>>
>> This change is required for binding vxlan sockets to their local address
>> when the outgoing interface is down.
>
> It's not necessarily the outgoing interface, but rather the interface to
> which the address is assigned.
>
> Anyway, I'm not sure this change is actually necessary. It was only
> added in v4 because back then the default behavior was changed to bind
> the VXLAN socket to the local address and existing selftests do not
> necessarily configure the address before putting the VXLAN device up.
>
> Given that in this version binding the VXLAN socket to the local address
> is opt-in, it seems legitimate to prevent user space from putting the
> VXLAN device up if the new option is enabled and the local address is
> not present. It can also be documented in the man page so that users are
> not surprised.
Sounds good, will change in v6.
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH net-next v5 2/5] net: vxlan: add netlink option to bind vxlan sockets to local addresses
2025-08-12 12:51 [PATCH net-next v5 0/5] net: add local address bind support to vxlan and geneve Richard Gobert
2025-08-12 12:51 ` [PATCH net-next v5 1/5] net: udp: add freebind option to udp_sock_create Richard Gobert
@ 2025-08-12 12:51 ` Richard Gobert
2025-08-13 6:28 ` Kuniyuki Iwashima
2025-08-13 9:26 ` Ido Schimmel
2025-08-12 12:51 ` [PATCH net-next v5 3/5] net: vxlan: bind vxlan sockets to their local address if configured Richard Gobert
` (3 subsequent siblings)
5 siblings, 2 replies; 23+ messages in thread
From: Richard Gobert @ 2025-08-12 12:51 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, kuba, pabeni, horms, donald.hunter,
andrew+netdev, dsahern, shuah, daniel, jacob.e.keller, razor,
idosch, petrm, menglong8.dong, martin.lau, linux-kernel,
Richard Gobert
Currently, VXLAN sockets always bind to 0.0.0.0, even when a local
address is defined. This commit adds a netlink option to change
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. The new option will break this behavior.
Disable the option by default.
Signed-off-by: Richard Gobert <richardbgobert@gmail.com>
---
drivers/net/vxlan/vxlan_core.c | 43 +++++++++++++++++++++++++++---
include/net/vxlan.h | 1 +
include/uapi/linux/if_link.h | 1 +
tools/include/uapi/linux/if_link.h | 1 +
4 files changed, 43 insertions(+), 3 deletions(-)
diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
index f32be2e301f2..15fe9d83c724 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] = NLA_POLICY_MAX(NLA_U8, 1),
};
static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[],
@@ -4044,15 +4045,37 @@ static int vxlan_nl2conf(struct nlattr *tb[], struct nlattr *data[],
conf->vni = vni;
}
+ if (data[IFLA_VXLAN_LOCALBIND]) {
+ if (changelink) {
+ NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_LOCALBIND], "Cannot rebind locally");
+ return -EOPNOTSUPP;
+ }
+
+ err = vxlan_nl2flag(conf, data, IFLA_VXLAN_LOCALBIND,
+ VXLAN_F_LOCALBIND, changelink,
+ false, extack);
+ if (err)
+ return err;
+ }
+
if (data[IFLA_VXLAN_GROUP]) {
+ __be32 addr = nla_get_in_addr(data[IFLA_VXLAN_GROUP]);
+
if (changelink && (conf->remote_ip.sa.sa_family != AF_INET)) {
NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_GROUP], "New group address family does not match old group");
return -EOPNOTSUPP;
}
- conf->remote_ip.sin.sin_addr.s_addr = nla_get_in_addr(data[IFLA_VXLAN_GROUP]);
+ if ((conf->flags & VXLAN_F_LOCALBIND) && ipv4_is_multicast(addr)) {
+ NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_GROUP], "Cannot add multicast group when bound locally");
+ return -EOPNOTSUPP;
+ }
+
+ conf->remote_ip.sin.sin_addr.s_addr = addr;
conf->remote_ip.sa.sa_family = AF_INET;
} else if (data[IFLA_VXLAN_GROUP6]) {
+ struct in6_addr addr = nla_get_in6_addr(data[IFLA_VXLAN_GROUP6]);
+
if (!IS_ENABLED(CONFIG_IPV6)) {
NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_GROUP6], "IPv6 support not enabled in the kernel");
return -EPFNOSUPPORT;
@@ -4063,7 +4086,12 @@ static int vxlan_nl2conf(struct nlattr *tb[], struct nlattr *data[],
return -EOPNOTSUPP;
}
- conf->remote_ip.sin6.sin6_addr = nla_get_in6_addr(data[IFLA_VXLAN_GROUP6]);
+ if ((conf->flags & VXLAN_F_LOCALBIND) && ipv6_addr_is_multicast(&addr)) {
+ NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_GROUP6], "Cannot add multicast group when bound locally");
+ return -EOPNOTSUPP;
+ }
+
+ conf->remote_ip.sin6.sin6_addr = addr;
conf->remote_ip.sa.sa_family = AF_INET6;
}
@@ -4071,6 +4099,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 +4115,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 */
@@ -4517,6 +4551,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 +4631,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
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH net-next v5 2/5] net: vxlan: add netlink option to bind vxlan sockets to local addresses
2025-08-12 12:51 ` [PATCH net-next v5 2/5] net: vxlan: add netlink option to bind vxlan sockets to local addresses Richard Gobert
@ 2025-08-13 6:28 ` Kuniyuki Iwashima
2025-08-13 15:46 ` Richard Gobert
2025-08-13 9:26 ` Ido Schimmel
1 sibling, 1 reply; 23+ messages in thread
From: Kuniyuki Iwashima @ 2025-08-13 6:28 UTC (permalink / raw)
To: richardbgobert
Cc: andrew+netdev, daniel, davem, donald.hunter, dsahern, edumazet,
horms, idosch, jacob.e.keller, kuba, linux-kernel, martin.lau,
menglong8.dong, netdev, pabeni, petrm, razor, shuah
From: Richard Gobert <richardbgobert@gmail.com>
Date: Tue, 12 Aug 2025 14:51:52 +0200
> Currently, VXLAN sockets always bind to 0.0.0.0, even when a local
> address is defined. This commit adds a netlink option to change
> 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. The new option will break this behavior.
>
> Disable the option by default.
>
> Signed-off-by: Richard Gobert <richardbgobert@gmail.com>
> ---
> drivers/net/vxlan/vxlan_core.c | 43 +++++++++++++++++++++++++++---
> include/net/vxlan.h | 1 +
> include/uapi/linux/if_link.h | 1 +
> tools/include/uapi/linux/if_link.h | 1 +
> 4 files changed, 43 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
> index f32be2e301f2..15fe9d83c724 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] = NLA_POLICY_MAX(NLA_U8, 1),
Flagging FREEBIND sounds rather NONLOCAL to me.
More specific name would be better. NON_WILDCARD_BIND ? idk..
$ cat include/net/inet_sock.h
...
static inline bool inet_can_nonlocal_bind(struct net *net,
struct inet_sock *inet)
{
return READ_ONCE(net->ipv4.sysctl_ip_nonlocal_bind) ||
test_bit(INET_FLAGS_FREEBIND, &inet->inet_flags) ||
test_bit(INET_FLAGS_TRANSPARENT, &inet->inet_flags);
}
> };
>
> static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[],
> @@ -4044,15 +4045,37 @@ static int vxlan_nl2conf(struct nlattr *tb[], struct nlattr *data[],
> conf->vni = vni;
> }
>
> + if (data[IFLA_VXLAN_LOCALBIND]) {
> + if (changelink) {
> + NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_LOCALBIND], "Cannot rebind locally");
> + return -EOPNOTSUPP;
> + }
Are these two "if" necessary ?
> +
> + err = vxlan_nl2flag(conf, data, IFLA_VXLAN_LOCALBIND,
> + VXLAN_F_LOCALBIND, changelink,
> + false, extack);
> + if (err)
> + return err;
> + }
> +
> if (data[IFLA_VXLAN_GROUP]) {
> + __be32 addr = nla_get_in_addr(data[IFLA_VXLAN_GROUP]);
> +
> if (changelink && (conf->remote_ip.sa.sa_family != AF_INET)) {
> NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_GROUP], "New group address family does not match old group");
> return -EOPNOTSUPP;
> }
>
> - conf->remote_ip.sin.sin_addr.s_addr = nla_get_in_addr(data[IFLA_VXLAN_GROUP]);
> + if ((conf->flags & VXLAN_F_LOCALBIND) && ipv4_is_multicast(addr)) {
> + NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_GROUP], "Cannot add multicast group when bound locally");
> + return -EOPNOTSUPP;
> + }
> +
> + conf->remote_ip.sin.sin_addr.s_addr = addr;
> conf->remote_ip.sa.sa_family = AF_INET;
> } else if (data[IFLA_VXLAN_GROUP6]) {
> + struct in6_addr addr = nla_get_in6_addr(data[IFLA_VXLAN_GROUP6]);
> +
> if (!IS_ENABLED(CONFIG_IPV6)) {
> NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_GROUP6], "IPv6 support not enabled in the kernel");
> return -EPFNOSUPPORT;
> @@ -4063,7 +4086,12 @@ static int vxlan_nl2conf(struct nlattr *tb[], struct nlattr *data[],
> return -EOPNOTSUPP;
> }
>
> - conf->remote_ip.sin6.sin6_addr = nla_get_in6_addr(data[IFLA_VXLAN_GROUP6]);
> + if ((conf->flags & VXLAN_F_LOCALBIND) && ipv6_addr_is_multicast(&addr)) {
> + NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_GROUP6], "Cannot add multicast group when bound locally");
> + return -EOPNOTSUPP;
> + }
> +
> + conf->remote_ip.sin6.sin6_addr = addr;
> conf->remote_ip.sa.sa_family = AF_INET6;
> }
>
> @@ -4071,6 +4099,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 +4115,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 */
> @@ -4517,6 +4551,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 +4631,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
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH net-next v5 2/5] net: vxlan: add netlink option to bind vxlan sockets to local addresses
2025-08-13 6:28 ` Kuniyuki Iwashima
@ 2025-08-13 15:46 ` Richard Gobert
2025-08-13 16:04 ` Ido Schimmel
0 siblings, 1 reply; 23+ messages in thread
From: Richard Gobert @ 2025-08-13 15:46 UTC (permalink / raw)
To: Kuniyuki Iwashima
Cc: andrew+netdev, daniel, davem, donald.hunter, dsahern, edumazet,
horms, idosch, jacob.e.keller, kuba, linux-kernel, martin.lau,
menglong8.dong, netdev, pabeni, petrm, razor, shuah
Kuniyuki Iwashima wrote:
> From: Richard Gobert <richardbgobert@gmail.com>
> Date: Tue, 12 Aug 2025 14:51:52 +0200
>> Currently, VXLAN sockets always bind to 0.0.0.0, even when a local
>> address is defined. This commit adds a netlink option to change
>> 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. The new option will break this behavior.
>>
>> Disable the option by default.
>>
>> Signed-off-by: Richard Gobert <richardbgobert@gmail.com>
>> ---
>> drivers/net/vxlan/vxlan_core.c | 43 +++++++++++++++++++++++++++---
>> include/net/vxlan.h | 1 +
>> include/uapi/linux/if_link.h | 1 +
>> tools/include/uapi/linux/if_link.h | 1 +
>> 4 files changed, 43 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
>> index f32be2e301f2..15fe9d83c724 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] = NLA_POLICY_MAX(NLA_U8, 1),
>
> Flagging FREEBIND sounds rather NONLOCAL to me.
>
> More specific name would be better. NON_WILDCARD_BIND ? idk..
>
> $ cat include/net/inet_sock.h
> ...
> static inline bool inet_can_nonlocal_bind(struct net *net,
> struct inet_sock *inet)
> {
> return READ_ONCE(net->ipv4.sysctl_ip_nonlocal_bind) ||
> test_bit(INET_FLAGS_FREEBIND, &inet->inet_flags) ||
> test_bit(INET_FLAGS_TRANSPARENT, &inet->inet_flags);
> }
>
>
>> };
>>
>> static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[],
>> @@ -4044,15 +4045,37 @@ static int vxlan_nl2conf(struct nlattr *tb[], struct nlattr *data[],
>> conf->vni = vni;
>> }
>>
>> + if (data[IFLA_VXLAN_LOCALBIND]) {
>> + if (changelink) {
>> + NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_LOCALBIND], "Cannot rebind locally");
>> + return -EOPNOTSUPP;
>> + }
>
> Are these two "if" necessary ?
Creating a vxlan interface without localbind then adding localbind won't
result in the socket being rebound. I might implement this in the future,
but for simplicity, I didn't implement this yet.
>
>
>> +
>> + err = vxlan_nl2flag(conf, data, IFLA_VXLAN_LOCALBIND,
>> + VXLAN_F_LOCALBIND, changelink,
>> + false, extack);
>> + if (err)
>> + return err;
>> + }
>> +
>> if (data[IFLA_VXLAN_GROUP]) {
>> + __be32 addr = nla_get_in_addr(data[IFLA_VXLAN_GROUP]);
>> +
>> if (changelink && (conf->remote_ip.sa.sa_family != AF_INET)) {
>> NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_GROUP], "New group address family does not match old group");
>> return -EOPNOTSUPP;
>> }
>>
>> - conf->remote_ip.sin.sin_addr.s_addr = nla_get_in_addr(data[IFLA_VXLAN_GROUP]);
>> + if ((conf->flags & VXLAN_F_LOCALBIND) && ipv4_is_multicast(addr)) {
>> + NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_GROUP], "Cannot add multicast group when bound locally");
>> + return -EOPNOTSUPP;
>> + }
>> +
>> + conf->remote_ip.sin.sin_addr.s_addr = addr;
>> conf->remote_ip.sa.sa_family = AF_INET;
>> } else if (data[IFLA_VXLAN_GROUP6]) {
>> + struct in6_addr addr = nla_get_in6_addr(data[IFLA_VXLAN_GROUP6]);
>> +
>> if (!IS_ENABLED(CONFIG_IPV6)) {
>> NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_GROUP6], "IPv6 support not enabled in the kernel");
>> return -EPFNOSUPPORT;
>> @@ -4063,7 +4086,12 @@ static int vxlan_nl2conf(struct nlattr *tb[], struct nlattr *data[],
>> return -EOPNOTSUPP;
>> }
>>
>> - conf->remote_ip.sin6.sin6_addr = nla_get_in6_addr(data[IFLA_VXLAN_GROUP6]);
>> + if ((conf->flags & VXLAN_F_LOCALBIND) && ipv6_addr_is_multicast(&addr)) {
>> + NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_GROUP6], "Cannot add multicast group when bound locally");
>> + return -EOPNOTSUPP;
>> + }
>> +
>> + conf->remote_ip.sin6.sin6_addr = addr;
>> conf->remote_ip.sa.sa_family = AF_INET6;
>> }
>>
>> @@ -4071,6 +4099,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 +4115,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 */
>> @@ -4517,6 +4551,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 +4631,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
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH net-next v5 2/5] net: vxlan: add netlink option to bind vxlan sockets to local addresses
2025-08-13 15:46 ` Richard Gobert
@ 2025-08-13 16:04 ` Ido Schimmel
2025-08-13 17:55 ` Kuniyuki Iwashima
0 siblings, 1 reply; 23+ messages in thread
From: Ido Schimmel @ 2025-08-13 16:04 UTC (permalink / raw)
To: Richard Gobert
Cc: Kuniyuki Iwashima, andrew+netdev, daniel, davem, donald.hunter,
dsahern, edumazet, horms, jacob.e.keller, kuba, linux-kernel,
martin.lau, menglong8.dong, netdev, pabeni, petrm, razor, shuah
On Wed, Aug 13, 2025 at 05:46:44PM +0200, Richard Gobert wrote:
> Kuniyuki Iwashima wrote:
> > From: Richard Gobert <richardbgobert@gmail.com>
> >> @@ -4044,15 +4045,37 @@ static int vxlan_nl2conf(struct nlattr *tb[], struct nlattr *data[],
> >> conf->vni = vni;
> >> }
> >>
> >> + if (data[IFLA_VXLAN_LOCALBIND]) {
> >> + if (changelink) {
> >> + NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_LOCALBIND], "Cannot rebind locally");
> >> + return -EOPNOTSUPP;
> >> + }
> >
> > Are these two "if" necessary ?
>
> Creating a vxlan interface without localbind then adding localbind won't
> result in the socket being rebound. I might implement this in the future,
> but for simplicity, I didn't implement this yet.
I think Kuniyuki meant that you can just call vxlan_nl2flag() without
those two "if"s because the function is a NO-OP when the attribute is
not present and it will also fail the changelink operation.
>
> >
> >
> >> +
> >> + err = vxlan_nl2flag(conf, data, IFLA_VXLAN_LOCALBIND,
> >> + VXLAN_F_LOCALBIND, changelink,
> >> + false, extack);
> >> + if (err)
> >> + return err;
> >> + }
> >> +
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH net-next v5 2/5] net: vxlan: add netlink option to bind vxlan sockets to local addresses
2025-08-13 16:04 ` Ido Schimmel
@ 2025-08-13 17:55 ` Kuniyuki Iwashima
0 siblings, 0 replies; 23+ messages in thread
From: Kuniyuki Iwashima @ 2025-08-13 17:55 UTC (permalink / raw)
To: Ido Schimmel
Cc: Richard Gobert, andrew+netdev, daniel, davem, donald.hunter,
dsahern, edumazet, horms, jacob.e.keller, kuba, linux-kernel,
martin.lau, menglong8.dong, netdev, pabeni, petrm, razor, shuah
On Wed, Aug 13, 2025 at 9:04 AM Ido Schimmel <idosch@nvidia.com> wrote:
>
> On Wed, Aug 13, 2025 at 05:46:44PM +0200, Richard Gobert wrote:
> > Kuniyuki Iwashima wrote:
> > > From: Richard Gobert <richardbgobert@gmail.com>
> > >> @@ -4044,15 +4045,37 @@ static int vxlan_nl2conf(struct nlattr *tb[], struct nlattr *data[],
> > >> conf->vni = vni;
> > >> }
> > >>
> > >> + if (data[IFLA_VXLAN_LOCALBIND]) {
> > >> + if (changelink) {
> > >> + NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_LOCALBIND], "Cannot rebind locally");
> > >> + return -EOPNOTSUPP;
> > >> + }
> > >
> > > Are these two "if" necessary ?
> >
> > Creating a vxlan interface without localbind then adding localbind won't
> > result in the socket being rebound. I might implement this in the future,
> > but for simplicity, I didn't implement this yet.
>
> I think Kuniyuki meant that you can just call vxlan_nl2flag() without
> those two "if"s because the function is a NO-OP when the attribute is
> not present and it will also fail the changelink operation.
Yes, I don't know why other places were not converted as such
when vxlan_nl2flag() was introduced in 70fb0828800b.
>
> >
> > >
> > >
> > >> +
> > >> + err = vxlan_nl2flag(conf, data, IFLA_VXLAN_LOCALBIND,
> > >> + VXLAN_F_LOCALBIND, changelink,
> > >> + false, extack);
> > >> + if (err)
> > >> + return err;
> > >> + }
> > >> +
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH net-next v5 2/5] net: vxlan: add netlink option to bind vxlan sockets to local addresses
2025-08-12 12:51 ` [PATCH net-next v5 2/5] net: vxlan: add netlink option to bind vxlan sockets to local addresses Richard Gobert
2025-08-13 6:28 ` Kuniyuki Iwashima
@ 2025-08-13 9:26 ` Ido Schimmel
1 sibling, 0 replies; 23+ messages in thread
From: Ido Schimmel @ 2025-08-13 9:26 UTC (permalink / raw)
To: Richard Gobert
Cc: netdev, davem, edumazet, kuba, pabeni, horms, donald.hunter,
andrew+netdev, dsahern, shuah, daniel, jacob.e.keller, razor,
petrm, menglong8.dong, martin.lau, linux-kernel
On Tue, Aug 12, 2025 at 02:51:52PM +0200, Richard Gobert wrote:
> Currently, VXLAN sockets always bind to 0.0.0.0, even when a local
> address is defined. This commit adds a netlink option to change
> 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. The new option will break this behavior.
>
> Disable the option by default.
>
> Signed-off-by: Richard Gobert <richardbgobert@gmail.com>
> ---
> drivers/net/vxlan/vxlan_core.c | 43 +++++++++++++++++++++++++++---
> include/net/vxlan.h | 1 +
> include/uapi/linux/if_link.h | 1 +
> tools/include/uapi/linux/if_link.h | 1 +
> 4 files changed, 43 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
> index f32be2e301f2..15fe9d83c724 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] = NLA_POLICY_MAX(NLA_U8, 1),
You should only expose the option to user space when it's fully
supported by the kernel, which is not the case here.
> };
[...]
> 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,
As you can see, the file was not updated in a while and will result in
different values for IFLA_VXLAN_LOCALBIND. I would just drop this hunk
unless you need it for some reason, in which case you can sync the file
in a separate commit.
> __IFLA_VXLAN_MAX
> };
> #define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
> --
> 2.36.1
>
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH net-next v5 3/5] net: vxlan: bind vxlan sockets to their local address if configured
2025-08-12 12:51 [PATCH net-next v5 0/5] net: add local address bind support to vxlan and geneve Richard Gobert
2025-08-12 12:51 ` [PATCH net-next v5 1/5] net: udp: add freebind option to udp_sock_create Richard Gobert
2025-08-12 12:51 ` [PATCH net-next v5 2/5] net: vxlan: add netlink option to bind vxlan sockets to local addresses Richard Gobert
@ 2025-08-12 12:51 ` Richard Gobert
2025-08-13 7:07 ` Kuniyuki Iwashima
2025-08-13 9:26 ` Ido Schimmel
2025-08-12 12:51 ` [PATCH net-next v5 4/5] net: geneve: enable binding geneve sockets to local addresses Richard Gobert
` (2 subsequent siblings)
5 siblings, 2 replies; 23+ messages in thread
From: Richard Gobert @ 2025-08-12 12:51 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, kuba, pabeni, horms, donald.hunter,
andrew+netdev, dsahern, shuah, daniel, jacob.e.keller, razor,
idosch, petrm, menglong8.dong, martin.lau, linux-kernel,
Richard Gobert
Bind VXLAN sockets to the local addresses if the IFLA_VXLAN_LOCALBIND
option is set. This is the new default.
Change vxlan_find_sock to search for the socket using the listening
address.
This is implemented by copying the VXLAN local address to the udp_port_cfg
passed to udp_sock_create. The freebind option is set because VXLAN
interfaces may be UP before their outgoing interface is.
This fixes multiple VXLAN selftests that fail because of that race.
Signed-off-by: Richard Gobert <richardbgobert@gmail.com>
---
drivers/net/vxlan/vxlan_core.c | 59 ++++++++++++++++++++++++++--------
1 file changed, 46 insertions(+), 13 deletions(-)
diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
index 15fe9d83c724..12da9595436e 100644
--- a/drivers/net/vxlan/vxlan_core.c
+++ b/drivers/net/vxlan/vxlan_core.c
@@ -78,18 +78,34 @@ static inline bool vxlan_collect_metadata(struct vxlan_sock *vs)
}
/* Find VXLAN socket based on network namespace, address family, UDP port,
- * enabled unshareable flags and socket device binding (see l3mdev with
- * non-default VRF).
+ * bound address, enabled unshareable flags and socket device binding
+ * (see l3mdev with non-default VRF).
*/
static struct vxlan_sock *vxlan_find_sock(struct net *net, sa_family_t family,
- __be16 port, u32 flags, int ifindex)
+ __be16 port, u32 flags, int ifindex,
+ union vxlan_addr *saddr)
{
struct vxlan_sock *vs;
flags &= VXLAN_F_RCV_FLAGS;
hlist_for_each_entry_rcu(vs, vs_head(net, port), hlist) {
- if (inet_sk(vs->sock->sk)->inet_sport == port &&
+ struct sock *sk = vs->sock->sk;
+ struct inet_sock *inet = inet_sk(sk);
+
+ if (flags & VXLAN_F_LOCALBIND) {
+ if (family == AF_INET &&
+ inet->inet_rcv_saddr != saddr->sin.sin_addr.s_addr)
+ continue;
+#if IS_ENABLED(CONFIG_IPV6)
+ else if (family == AF_INET6 &&
+ ipv6_addr_cmp(&sk->sk_v6_rcv_saddr,
+ &saddr->sin6.sin6_addr) != 0)
+ continue;
+#endif
+ }
+
+ if (inet->inet_sport == port &&
vxlan_get_sk_family(vs) == family &&
vs->flags == flags &&
vs->sock->sk->sk_bound_dev_if == ifindex)
@@ -141,11 +157,12 @@ static struct vxlan_dev *vxlan_vs_find_vni(struct vxlan_sock *vs,
/* Look up VNI in a per net namespace table */
static struct vxlan_dev *vxlan_find_vni(struct net *net, int ifindex,
__be32 vni, sa_family_t family,
- __be16 port, u32 flags)
+ __be16 port, u32 flags,
+ union vxlan_addr *saddr)
{
struct vxlan_sock *vs;
- vs = vxlan_find_sock(net, family, port, flags, ifindex);
+ vs = vxlan_find_sock(net, family, port, flags, ifindex, saddr);
if (!vs)
return NULL;
@@ -2309,7 +2326,7 @@ static int encap_bypass_if_local(struct sk_buff *skb, struct net_device *dev,
dst_release(dst);
dst_vxlan = vxlan_find_vni(vxlan->net, dst_ifindex, vni,
addr_family, dst_port,
- vxlan->cfg.flags);
+ vxlan->cfg.flags, &vxlan->cfg.saddr);
if (!dst_vxlan) {
DEV_STATS_INC(dev, tx_errors);
vxlan_vnifilter_count(vxlan, vni, NULL,
@@ -3508,8 +3525,9 @@ static const struct ethtool_ops vxlan_ethtool_ops = {
.get_link_ksettings = vxlan_get_link_ksettings,
};
-static struct socket *vxlan_create_sock(struct net *net, bool ipv6,
- __be16 port, u32 flags, int ifindex)
+static struct socket *vxlan_create_sock(struct net *net, bool ipv6, __be16 port,
+ u32 flags, int ifindex,
+ union vxlan_addr *addr)
{
struct socket *sock;
struct udp_port_cfg udp_conf;
@@ -3526,6 +3544,20 @@ static struct socket *vxlan_create_sock(struct net *net, bool ipv6,
udp_conf.family = AF_INET;
}
+ if (flags & VXLAN_F_LOCALBIND) {
+ if (ipv6) {
+#if IS_ENABLED(CONFIG_IPV6)
+ memcpy(&udp_conf.local_ip6.s6_addr32,
+ &addr->sin6.sin6_addr.s6_addr32,
+ sizeof(addr->sin6.sin6_addr.s6_addr32));
+#endif
+ } else {
+ udp_conf.local_ip.s_addr = addr->sin.sin_addr.s_addr;
+ }
+
+ udp_conf.freebind = 1;
+ }
+
udp_conf.local_udp_port = port;
udp_conf.bind_ifindex = ifindex;
@@ -3541,7 +3573,8 @@ static struct socket *vxlan_create_sock(struct net *net, bool ipv6,
/* Create new listen socket if needed */
static struct vxlan_sock *vxlan_socket_create(struct net *net, bool ipv6,
__be16 port, u32 flags,
- int ifindex)
+ int ifindex,
+ union vxlan_addr *addr)
{
struct vxlan_sock *vs;
struct socket *sock;
@@ -3557,7 +3590,7 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, bool ipv6,
for (h = 0; h < VNI_HASH_SIZE; ++h)
INIT_HLIST_HEAD(&vs->vni_list[h]);
- sock = vxlan_create_sock(net, ipv6, port, flags, ifindex);
+ sock = vxlan_create_sock(net, ipv6, port, flags, ifindex, addr);
if (IS_ERR(sock)) {
kfree(vs);
return ERR_CAST(sock);
@@ -3610,7 +3643,7 @@ static int __vxlan_sock_add(struct vxlan_dev *vxlan, bool ipv6)
rcu_read_lock();
vs = vxlan_find_sock(vxlan->net, ipv6 ? AF_INET6 : AF_INET,
vxlan->cfg.dst_port, vxlan->cfg.flags,
- l3mdev_index);
+ l3mdev_index, &vxlan->cfg.saddr);
if (vs && !refcount_inc_not_zero(&vs->refcnt)) {
rcu_read_unlock();
return -EBUSY;
@@ -3620,7 +3653,7 @@ static int __vxlan_sock_add(struct vxlan_dev *vxlan, bool ipv6)
if (!vs)
vs = vxlan_socket_create(vxlan->net, ipv6,
vxlan->cfg.dst_port, vxlan->cfg.flags,
- l3mdev_index);
+ l3mdev_index, &vxlan->cfg.saddr);
if (IS_ERR(vs))
return PTR_ERR(vs);
#if IS_ENABLED(CONFIG_IPV6)
--
2.36.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH net-next v5 3/5] net: vxlan: bind vxlan sockets to their local address if configured
2025-08-12 12:51 ` [PATCH net-next v5 3/5] net: vxlan: bind vxlan sockets to their local address if configured Richard Gobert
@ 2025-08-13 7:07 ` Kuniyuki Iwashima
2025-08-13 15:41 ` Richard Gobert
2025-08-13 9:26 ` Ido Schimmel
1 sibling, 1 reply; 23+ messages in thread
From: Kuniyuki Iwashima @ 2025-08-13 7:07 UTC (permalink / raw)
To: richardbgobert
Cc: andrew+netdev, daniel, davem, donald.hunter, dsahern, edumazet,
horms, idosch, jacob.e.keller, kuba, linux-kernel, martin.lau,
menglong8.dong, netdev, pabeni, petrm, razor, shuah
From: Richard Gobert <richardbgobert@gmail.com>
Date: Tue, 12 Aug 2025 14:51:53 +0200
> diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
> index 15fe9d83c724..12da9595436e 100644
> --- a/drivers/net/vxlan/vxlan_core.c
> +++ b/drivers/net/vxlan/vxlan_core.c
> @@ -78,18 +78,34 @@ static inline bool vxlan_collect_metadata(struct vxlan_sock *vs)
> }
>
> /* Find VXLAN socket based on network namespace, address family, UDP port,
> - * enabled unshareable flags and socket device binding (see l3mdev with
> - * non-default VRF).
> + * bound address, enabled unshareable flags and socket device binding
> + * (see l3mdev with non-default VRF).
> */
> static struct vxlan_sock *vxlan_find_sock(struct net *net, sa_family_t family,
> - __be16 port, u32 flags, int ifindex)
> + __be16 port, u32 flags, int ifindex,
> + union vxlan_addr *saddr)
> {
> struct vxlan_sock *vs;
>
> flags &= VXLAN_F_RCV_FLAGS;
VXLAN_F_LOCALBIND seems to be cleared ?
>
> hlist_for_each_entry_rcu(vs, vs_head(net, port), hlist) {
> - if (inet_sk(vs->sock->sk)->inet_sport == port &&
> + struct sock *sk = vs->sock->sk;
> + struct inet_sock *inet = inet_sk(sk);
> +
> + if (flags & VXLAN_F_LOCALBIND) {
Does selftest exercise this path ?
> + if (family == AF_INET &&
> + inet->inet_rcv_saddr != saddr->sin.sin_addr.s_addr)
> + continue;
> +#if IS_ENABLED(CONFIG_IPV6)
> + else if (family == AF_INET6 &&
> + ipv6_addr_cmp(&sk->sk_v6_rcv_saddr,
> + &saddr->sin6.sin6_addr) != 0)
> + continue;
> +#endif
> + }
> +
> + if (inet->inet_sport == port &&
> vxlan_get_sk_family(vs) == family &&
> vs->flags == flags &&
> vs->sock->sk->sk_bound_dev_if == ifindex)
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH net-next v5 3/5] net: vxlan: bind vxlan sockets to their local address if configured
2025-08-13 7:07 ` Kuniyuki Iwashima
@ 2025-08-13 15:41 ` Richard Gobert
0 siblings, 0 replies; 23+ messages in thread
From: Richard Gobert @ 2025-08-13 15:41 UTC (permalink / raw)
To: Kuniyuki Iwashima
Cc: andrew+netdev, daniel, davem, donald.hunter, dsahern, edumazet,
horms, idosch, jacob.e.keller, kuba, linux-kernel, martin.lau,
menglong8.dong, netdev, pabeni, petrm, razor, shuah
Kuniyuki Iwashima wrote:
> From: Richard Gobert <richardbgobert@gmail.com>
> Date: Tue, 12 Aug 2025 14:51:53 +0200
>> diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
>> index 15fe9d83c724..12da9595436e 100644
>> --- a/drivers/net/vxlan/vxlan_core.c
>> +++ b/drivers/net/vxlan/vxlan_core.c
>> @@ -78,18 +78,34 @@ static inline bool vxlan_collect_metadata(struct vxlan_sock *vs)
>> }
>>
>> /* Find VXLAN socket based on network namespace, address family, UDP port,
>> - * enabled unshareable flags and socket device binding (see l3mdev with
>> - * non-default VRF).
>> + * bound address, enabled unshareable flags and socket device binding
>> + * (see l3mdev with non-default VRF).
>> */
>> static struct vxlan_sock *vxlan_find_sock(struct net *net, sa_family_t family,
>> - __be16 port, u32 flags, int ifindex)
>> + __be16 port, u32 flags, int ifindex,
>> + union vxlan_addr *saddr)
>> {
>> struct vxlan_sock *vs;
>>
>> flags &= VXLAN_F_RCV_FLAGS;
>
> VXLAN_F_LOCALBIND seems to be cleared ?
>
>>
>> hlist_for_each_entry_rcu(vs, vs_head(net, port), hlist) {
>> - if (inet_sk(vs->sock->sk)->inet_sport == port &&
>> + struct sock *sk = vs->sock->sk;
>> + struct inet_sock *inet = inet_sk(sk);
>> +
>> + if (flags & VXLAN_F_LOCALBIND) {
>
> Does selftest exercise this path ?
>
>
>> + if (family == AF_INET &&
>> + inet->inet_rcv_saddr != saddr->sin.sin_addr.s_addr)
>> + continue;
>> +#if IS_ENABLED(CONFIG_IPV6)
>> + else if (family == AF_INET6 &&
>> + ipv6_addr_cmp(&sk->sk_v6_rcv_saddr,
>> + &saddr->sin6.sin6_addr) != 0)
>> + continue;
>> +#endif
>> + }
>> +
>> + if (inet->inet_sport == port &&
>> vxlan_get_sk_family(vs) == family &&
>> vs->flags == flags &&
>> vs->sock->sk->sk_bound_dev_if == ifindex)
Nice catch. I don't think the new selftest exercises this path, but I'm
running the other vxlan selftests with the localbind option enabled by default
and ensuring that they pass.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH net-next v5 3/5] net: vxlan: bind vxlan sockets to their local address if configured
2025-08-12 12:51 ` [PATCH net-next v5 3/5] net: vxlan: bind vxlan sockets to their local address if configured Richard Gobert
2025-08-13 7:07 ` Kuniyuki Iwashima
@ 2025-08-13 9:26 ` Ido Schimmel
2025-08-13 15:18 ` Richard Gobert
1 sibling, 1 reply; 23+ messages in thread
From: Ido Schimmel @ 2025-08-13 9:26 UTC (permalink / raw)
To: Richard Gobert
Cc: netdev, davem, edumazet, kuba, pabeni, horms, donald.hunter,
andrew+netdev, dsahern, shuah, daniel, jacob.e.keller, razor,
petrm, menglong8.dong, martin.lau, linux-kernel
On Tue, Aug 12, 2025 at 02:51:53PM +0200, Richard Gobert wrote:
> Bind VXLAN sockets to the local addresses if the IFLA_VXLAN_LOCALBIND
> option is set. This is the new default.
Drop the last sentence?
>
> Change vxlan_find_sock to search for the socket using the listening
> address.
>
> This is implemented by copying the VXLAN local address to the udp_port_cfg
> passed to udp_sock_create. The freebind option is set because VXLAN
> interfaces may be UP before their outgoing interface is.
>
> This fixes multiple VXLAN selftests that fail because of that race.
This sentence is no longer relevant as well.
>
> Signed-off-by: Richard Gobert <richardbgobert@gmail.com>
> ---
> drivers/net/vxlan/vxlan_core.c | 59 ++++++++++++++++++++++++++--------
> 1 file changed, 46 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
> index 15fe9d83c724..12da9595436e 100644
> --- a/drivers/net/vxlan/vxlan_core.c
> +++ b/drivers/net/vxlan/vxlan_core.c
> @@ -78,18 +78,34 @@ static inline bool vxlan_collect_metadata(struct vxlan_sock *vs)
> }
>
> /* Find VXLAN socket based on network namespace, address family, UDP port,
> - * enabled unshareable flags and socket device binding (see l3mdev with
> - * non-default VRF).
> + * bound address, enabled unshareable flags and socket device binding
> + * (see l3mdev with non-default VRF).
> */
> static struct vxlan_sock *vxlan_find_sock(struct net *net, sa_family_t family,
> - __be16 port, u32 flags, int ifindex)
> + __be16 port, u32 flags, int ifindex,
> + union vxlan_addr *saddr)
> {
> struct vxlan_sock *vs;
>
> flags &= VXLAN_F_RCV_FLAGS;
>
> hlist_for_each_entry_rcu(vs, vs_head(net, port), hlist) {
> - if (inet_sk(vs->sock->sk)->inet_sport == port &&
> + struct sock *sk = vs->sock->sk;
> + struct inet_sock *inet = inet_sk(sk);
https://docs.kernel.org/process/maintainer-netdev.html#local-variable-ordering-reverse-xmas-tree-rcs
> +
> + if (flags & VXLAN_F_LOCALBIND) {
> + if (family == AF_INET &&
> + inet->inet_rcv_saddr != saddr->sin.sin_addr.s_addr)
> + continue;
> +#if IS_ENABLED(CONFIG_IPV6)
> + else if (family == AF_INET6 &&
> + ipv6_addr_cmp(&sk->sk_v6_rcv_saddr,
> + &saddr->sin6.sin6_addr) != 0)
> + continue;
> +#endif
> + }
> +
> + if (inet->inet_sport == port &&
> vxlan_get_sk_family(vs) == family &&
> vs->flags == flags &&
> vs->sock->sk->sk_bound_dev_if == ifindex)
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH net-next v5 3/5] net: vxlan: bind vxlan sockets to their local address if configured
2025-08-13 9:26 ` Ido Schimmel
@ 2025-08-13 15:18 ` Richard Gobert
0 siblings, 0 replies; 23+ messages in thread
From: Richard Gobert @ 2025-08-13 15:18 UTC (permalink / raw)
To: Ido Schimmel
Cc: netdev, davem, edumazet, kuba, pabeni, horms, donald.hunter,
andrew+netdev, dsahern, shuah, daniel, jacob.e.keller, razor,
petrm, menglong8.dong, martin.lau, linux-kernel
On 8/13/25 11:26, Ido Schimmel wrote:
> On Tue, Aug 12, 2025 at 02:51:53PM +0200, Richard Gobert wrote:
>> Bind VXLAN sockets to the local addresses if the IFLA_VXLAN_LOCALBIND
>> option is set. This is the new default.
>
> Drop the last sentence?
>
>>
>> Change vxlan_find_sock to search for the socket using the listening
>> address.
>>
>> This is implemented by copying the VXLAN local address to the udp_port_cfg
>> passed to udp_sock_create. The freebind option is set because VXLAN
>> interfaces may be UP before their outgoing interface is.
>>
>> This fixes multiple VXLAN selftests that fail because of that race.
>
> This sentence is no longer relevant as well.
>
>>
>> Signed-off-by: Richard Gobert <richardbgobert@gmail.com>
>> ---
>> drivers/net/vxlan/vxlan_core.c | 59 ++++++++++++++++++++++++++--------
>> 1 file changed, 46 insertions(+), 13 deletions(-)
>>
>> diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
>> index 15fe9d83c724..12da9595436e 100644
>> --- a/drivers/net/vxlan/vxlan_core.c
>> +++ b/drivers/net/vxlan/vxlan_core.c
>> @@ -78,18 +78,34 @@ static inline bool vxlan_collect_metadata(struct vxlan_sock *vs)
>> }
>>
>> /* Find VXLAN socket based on network namespace, address family, UDP port,
>> - * enabled unshareable flags and socket device binding (see l3mdev with
>> - * non-default VRF).
>> + * bound address, enabled unshareable flags and socket device binding
>> + * (see l3mdev with non-default VRF).
>> */
>> static struct vxlan_sock *vxlan_find_sock(struct net *net, sa_family_t family,
>> - __be16 port, u32 flags, int ifindex)
>> + __be16 port, u32 flags, int ifindex,
>> + union vxlan_addr *saddr)
>> {
>> struct vxlan_sock *vs;
>>
>> flags &= VXLAN_F_RCV_FLAGS;
>>
>> hlist_for_each_entry_rcu(vs, vs_head(net, port), hlist) {
>> - if (inet_sk(vs->sock->sk)->inet_sport == port &&
>> + struct sock *sk = vs->sock->sk;
>> + struct inet_sock *inet = inet_sk(sk);
>
> https://docs.kernel.org/process/maintainer-netdev.html#local-variable-ordering-reverse-xmas-tree-rcs
>
>> +
>> + if (flags & VXLAN_F_LOCALBIND) {
>> + if (family == AF_INET &&
>> + inet->inet_rcv_saddr != saddr->sin.sin_addr.s_addr)
>> + continue;
>> +#if IS_ENABLED(CONFIG_IPV6)
>> + else if (family == AF_INET6 &&
>> + ipv6_addr_cmp(&sk->sk_v6_rcv_saddr,
>> + &saddr->sin6.sin6_addr) != 0)
>> + continue;
>> +#endif
>> + }
>> +
>> + if (inet->inet_sport == port &&
>> vxlan_get_sk_family(vs) == family &&
>> vs->flags == flags &&
>> vs->sock->sk->sk_bound_dev_if == ifindex)
My bad, will fix.
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH net-next v5 4/5] net: geneve: enable binding geneve sockets to local addresses
2025-08-12 12:51 [PATCH net-next v5 0/5] net: add local address bind support to vxlan and geneve Richard Gobert
` (2 preceding siblings ...)
2025-08-12 12:51 ` [PATCH net-next v5 3/5] net: vxlan: bind vxlan sockets to their local address if configured Richard Gobert
@ 2025-08-12 12:51 ` Richard Gobert
2025-08-12 12:51 ` [PATCH net-next v5 5/5] selftests/net: add vxlan localbind selftest Richard Gobert
2025-08-13 9:25 ` [PATCH net-next v5 0/5] net: add local address bind support to vxlan and geneve Ido Schimmel
5 siblings, 0 replies; 23+ messages in thread
From: Richard Gobert @ 2025-08-12 12:51 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, kuba, pabeni, horms, donald.hunter,
andrew+netdev, dsahern, shuah, daniel, jacob.e.keller, razor,
idosch, petrm, menglong8.dong, martin.lau, linux-kernel,
Richard Gobert
Allow binding geneve sockets to local addresses, similar to
the VXLAN "local" option. Add a netlink option to configure
the local address.
Like VXLAN, Geneve sockets can be bound to non-local addresses,
meaning they may be UP before their outgoing interfaces.
Signed-off-by: Richard Gobert <richardbgobert@gmail.com>
---
Documentation/netlink/specs/rt-link.yaml | 8 +++
drivers/net/geneve.c | 80 +++++++++++++++++++++---
include/net/geneve.h | 6 ++
include/uapi/linux/if_link.h | 2 +
tools/include/uapi/linux/if_link.h | 2 +
5 files changed, 90 insertions(+), 8 deletions(-)
diff --git a/Documentation/netlink/specs/rt-link.yaml b/Documentation/netlink/specs/rt-link.yaml
index 210394c188a3..8188ca95fad6 100644
--- a/Documentation/netlink/specs/rt-link.yaml
+++ b/Documentation/netlink/specs/rt-link.yaml
@@ -1907,6 +1907,14 @@ attribute-sets:
name: port-range
type: binary
struct: ifla-geneve-port-range
+ -
+ name: local
+ type: binary
+ display-hint: ipv4
+ -
+ name: local6
+ type: binary
+ display-hint: ipv6
-
name: linkinfo-iptun-attrs
name-prefix: ifla-iptun-
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index 54384f9b3872..2360ca891762 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -61,6 +61,7 @@ struct geneve_config {
bool inner_proto_inherit;
u16 port_min;
u16 port_max;
+ union geneve_addr saddr;
};
/* Pseudo network device */
@@ -465,7 +466,8 @@ static int geneve_udp_encap_err_lookup(struct sock *sk, struct sk_buff *skb)
}
static struct socket *geneve_create_sock(struct net *net, bool ipv6,
- __be16 port, bool ipv6_rx_csum)
+ __be16 port, bool ipv6_rx_csum,
+ union geneve_addr *local_addr)
{
struct socket *sock;
struct udp_port_cfg udp_conf;
@@ -477,11 +479,20 @@ static struct socket *geneve_create_sock(struct net *net, bool ipv6,
udp_conf.family = AF_INET6;
udp_conf.ipv6_v6only = 1;
udp_conf.use_udp6_rx_checksums = ipv6_rx_csum;
+#if IS_ENABLED(CONFIG_IPV6)
+ memcpy(&udp_conf.local_ip6,
+ &local_addr->sin6.sin6_addr,
+ sizeof(local_addr->sin6.sin6_addr));
+#endif
} else {
udp_conf.family = AF_INET;
udp_conf.local_ip.s_addr = htonl(INADDR_ANY);
+ memcpy(&udp_conf.local_ip,
+ &local_addr->sin.sin_addr,
+ sizeof(local_addr->sin.sin_addr));
}
+ udp_conf.freebind = 1;
udp_conf.local_udp_port = port;
/* Open UDP socket */
@@ -586,7 +597,8 @@ static int geneve_gro_complete(struct sock *sk, struct sk_buff *skb,
/* Create new listen socket if needed */
static struct geneve_sock *geneve_socket_create(struct net *net, __be16 port,
- bool ipv6, bool ipv6_rx_csum)
+ bool ipv6, bool ipv6_rx_csum,
+ union geneve_addr *local_addr)
{
struct geneve_net *gn = net_generic(net, geneve_net_id);
struct geneve_sock *gs;
@@ -598,7 +610,7 @@ static struct geneve_sock *geneve_socket_create(struct net *net, __be16 port,
if (!gs)
return ERR_PTR(-ENOMEM);
- sock = geneve_create_sock(net, ipv6, port, ipv6_rx_csum);
+ sock = geneve_create_sock(net, ipv6, port, ipv6_rx_csum, local_addr);
if (IS_ERR(sock)) {
kfree(gs);
return ERR_CAST(sock);
@@ -657,12 +669,24 @@ static void geneve_sock_release(struct geneve_dev *geneve)
static struct geneve_sock *geneve_find_sock(struct geneve_net *gn,
sa_family_t family,
- __be16 dst_port)
+ __be16 dst_port,
+ union geneve_addr *saddr)
{
struct geneve_sock *gs;
list_for_each_entry(gs, &gn->sock_list, list) {
- if (inet_sk(gs->sock->sk)->inet_sport == dst_port &&
+ struct sock *sk = gs->sock->sk;
+ struct inet_sock *inet = inet_sk(sk);
+
+ if (family == AF_INET &&
+ inet->inet_rcv_saddr != saddr->sin.sin_addr.s_addr)
+ continue;
+#if IS_ENABLED(CONFIG_IPV6)
+ else if (ipv6_addr_cmp(&sk->sk_v6_rcv_saddr,
+ &saddr->sin6.sin6_addr) != 0)
+ continue;
+#endif
+ if (inet->inet_sport == dst_port &&
geneve_get_sk_family(gs) == family) {
return gs;
}
@@ -679,14 +703,16 @@ static int geneve_sock_add(struct geneve_dev *geneve, bool ipv6)
__u8 vni[3];
__u32 hash;
- gs = geneve_find_sock(gn, ipv6 ? AF_INET6 : AF_INET, geneve->cfg.info.key.tp_dst);
+ gs = geneve_find_sock(gn, ipv6 ? AF_INET6 : AF_INET,
+ geneve->cfg.info.key.tp_dst, &geneve->cfg.saddr);
if (gs) {
gs->refcnt++;
goto out;
}
gs = geneve_socket_create(net, geneve->cfg.info.key.tp_dst, ipv6,
- geneve->cfg.use_udp6_rx_checksums);
+ geneve->cfg.use_udp6_rx_checksums,
+ &geneve->cfg.saddr);
if (IS_ERR(gs))
return PTR_ERR(gs);
@@ -1246,6 +1272,8 @@ static const struct nla_policy geneve_policy[IFLA_GENEVE_MAX + 1] = {
[IFLA_GENEVE_DF] = { .type = NLA_U8 },
[IFLA_GENEVE_INNER_PROTO_INHERIT] = { .type = NLA_FLAG },
[IFLA_GENEVE_PORT_RANGE] = NLA_POLICY_EXACT_LEN(sizeof(struct ifla_geneve_port_range)),
+ [IFLA_GENEVE_LOCAL] = NLA_POLICY_EXACT_LEN(sizeof_field(struct iphdr, saddr)),
+ [IFLA_GENEVE_LOCAL6] = NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)),
};
static int geneve_validate(struct nlattr *tb[], struct nlattr *data[],
@@ -1596,6 +1624,32 @@ static int geneve_nl2info(struct nlattr *tb[], struct nlattr *data[],
cfg->inner_proto_inherit = true;
}
+ if (data[IFLA_GENEVE_LOCAL]) {
+ if (changelink && (ip_tunnel_info_af(info) != AF_INET)) {
+ attrtype = IFLA_GENEVE_LOCAL;
+ goto change_notsup;
+ }
+
+ cfg->saddr.sin.sin_addr.s_addr = nla_get_in_addr(data[IFLA_GENEVE_LOCAL]);
+ cfg->saddr.sa.sa_family = AF_INET;
+ }
+
+ if (data[IFLA_GENEVE_LOCAL6]) {
+#if IS_ENABLED(CONFIG_IPV6)
+ if (changelink && (ip_tunnel_info_af(info) != AF_INET6)) {
+ attrtype = IFLA_GENEVE_LOCAL6;
+ goto change_notsup;
+ }
+
+ cfg->saddr.sin6.sin6_addr = nla_get_in6_addr(data[IFLA_GENEVE_LOCAL6]);
+ cfg->saddr.sa.sa_family = AF_INET6;
+#else
+ NL_SET_ERR_MSG_ATTR(extack, data[IFLA_GENEVE_LOCAL6],
+ "IPv6 support not enabled in the kernel");
+ return -EPFNOSUPPORT;
+#endif
+ }
+
return 0;
change_notsup:
NL_SET_ERR_MSG_ATTR(extack, data[attrtype],
@@ -1782,6 +1836,7 @@ static size_t geneve_get_size(const struct net_device *dev)
nla_total_size(sizeof(__u8)) + /* IFLA_GENEVE_TTL_INHERIT */
nla_total_size(0) + /* IFLA_GENEVE_INNER_PROTO_INHERIT */
nla_total_size(sizeof(struct ifla_geneve_port_range)) + /* IFLA_GENEVE_PORT_RANGE */
+ nla_total_size(sizeof(struct in6_addr)) + /* IFLA_GENEVE_LOCAL{6} */
0;
}
@@ -1807,16 +1862,25 @@ static int geneve_fill_info(struct sk_buff *skb, const struct net_device *dev)
if (nla_put_in_addr(skb, IFLA_GENEVE_REMOTE,
info->key.u.ipv4.dst))
goto nla_put_failure;
+
+ if (nla_put_in_addr(skb, IFLA_GENEVE_LOCAL,
+ info->key.u.ipv4.src))
+ goto nla_put_failure;
+
if (nla_put_u8(skb, IFLA_GENEVE_UDP_CSUM,
test_bit(IP_TUNNEL_CSUM_BIT,
info->key.tun_flags)))
goto nla_put_failure;
-
#if IS_ENABLED(CONFIG_IPV6)
} else if (!metadata) {
if (nla_put_in6_addr(skb, IFLA_GENEVE_REMOTE6,
&info->key.u.ipv6.dst))
goto nla_put_failure;
+
+ if (nla_put_in6_addr(skb, IFLA_GENEVE_LOCAL6,
+ &info->key.u.ipv6.src))
+ goto nla_put_failure;
+
if (nla_put_u8(skb, IFLA_GENEVE_UDP_ZERO_CSUM6_TX,
!test_bit(IP_TUNNEL_CSUM_BIT,
info->key.tun_flags)))
diff --git a/include/net/geneve.h b/include/net/geneve.h
index 5c96827a487e..7b12c70db11f 100644
--- a/include/net/geneve.h
+++ b/include/net/geneve.h
@@ -62,6 +62,12 @@ struct genevehdr {
u8 options[];
};
+union geneve_addr {
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+ struct sockaddr sa;
+};
+
static inline bool netif_is_geneve(const struct net_device *dev)
{
return dev->rtnl_link_ops &&
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 7350129b1444..ff362d76a0d4 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -1442,6 +1442,8 @@ enum {
IFLA_GENEVE_DF,
IFLA_GENEVE_INNER_PROTO_INHERIT,
IFLA_GENEVE_PORT_RANGE,
+ IFLA_GENEVE_LOCAL,
+ IFLA_GENEVE_LOCAL6,
__IFLA_GENEVE_MAX
};
#define IFLA_GENEVE_MAX (__IFLA_GENEVE_MAX - 1)
diff --git a/tools/include/uapi/linux/if_link.h b/tools/include/uapi/linux/if_link.h
index eee934cc2cf4..894a1aa91133 100644
--- a/tools/include/uapi/linux/if_link.h
+++ b/tools/include/uapi/linux/if_link.h
@@ -1438,6 +1438,8 @@ enum {
IFLA_GENEVE_TTL_INHERIT,
IFLA_GENEVE_DF,
IFLA_GENEVE_INNER_PROTO_INHERIT,
+ IFLA_GENEVE_LOCAL,
+ IFLA_GENEVE_LOCAL6,
__IFLA_GENEVE_MAX
};
#define IFLA_GENEVE_MAX (__IFLA_GENEVE_MAX - 1)
--
2.36.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH net-next v5 5/5] selftests/net: add vxlan localbind selftest
2025-08-12 12:51 [PATCH net-next v5 0/5] net: add local address bind support to vxlan and geneve Richard Gobert
` (3 preceding siblings ...)
2025-08-12 12:51 ` [PATCH net-next v5 4/5] net: geneve: enable binding geneve sockets to local addresses Richard Gobert
@ 2025-08-12 12:51 ` Richard Gobert
2025-08-13 11:44 ` Ido Schimmel
2025-08-13 14:34 ` Jakub Kicinski
2025-08-13 9:25 ` [PATCH net-next v5 0/5] net: add local address bind support to vxlan and geneve Ido Schimmel
5 siblings, 2 replies; 23+ messages in thread
From: Richard Gobert @ 2025-08-12 12:51 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, kuba, pabeni, horms, donald.hunter,
andrew+netdev, dsahern, shuah, daniel, jacob.e.keller, razor,
idosch, petrm, menglong8.dong, martin.lau, linux-kernel,
Richard Gobert
Test to make sure the localbind netlink option works
in VXLAN interfaces.
Signed-off-by: Richard Gobert <richardbgobert@gmail.com>
---
tools/testing/selftests/net/Makefile | 1 +
.../selftests/net/test_vxlan_localbind.sh | 306 ++++++++++++++++++
2 files changed, 307 insertions(+)
create mode 100755 tools/testing/selftests/net/test_vxlan_localbind.sh
diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile
index b31a71f2b372..9305601f4eba 100644
--- a/tools/testing/selftests/net/Makefile
+++ b/tools/testing/selftests/net/Makefile
@@ -117,6 +117,7 @@ TEST_GEN_FILES += tfo
TEST_PROGS += tfo_passive.sh
TEST_PROGS += broadcast_pmtu.sh
TEST_PROGS += ipv6_force_forwarding.sh
+TEST_PROGS += test_vxlan_localbind.sh
# YNL files, must be before "include ..lib.mk"
YNL_GEN_FILES := busy_poller netlink-dumps
diff --git a/tools/testing/selftests/net/test_vxlan_localbind.sh b/tools/testing/selftests/net/test_vxlan_localbind.sh
new file mode 100755
index 000000000000..60b97a578c74
--- /dev/null
+++ b/tools/testing/selftests/net/test_vxlan_localbind.sh
@@ -0,0 +1,306 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+# This test is for checking the VXLAN localbind option.
+#
+# It simulates two hypervisors running a VM each using four network namespaces:
+# two for the HVs, two for the VMs.
+# A small VXLAN tunnel is made between the two hypervisors to have the two vms
+# in the same virtual L2, connected through two separate subnets:
+#
+# +-------------------+ +-------------------+
+# | | | |
+# | vm-1 netns | | vm-2 netns |
+# | | | |
+# | +-------------+ | | +-------------+ |
+# | | veth-hv | | | | veth-hv | |
+# | | 10.0.0.1/24 | | | | 10.0.0.2/24 | |
+# | +-------------+ | | +-------------+ |
+# | . | | . |
+# +-------------------+ +-------------------+
+# . .
+# . .
+# . .
+# +-----------------------------------+ +------------------------------------+
+# | . | | . |
+# | +----------+ | | +----------+ |
+# | | veth-tap | | | | veth-tap | |
+# | +----+-----+ | | +----+-----+ |
+# | | | | | |
+# | +--+--+ | | +--+--+ |
+# | | br0 | | | | br0 | |
+# | +--+--+ | | +--+--+ |
+# | | | | | |
+# | +---+----+ +--------+--------+ | | +--------+--------+ +---+----+ |
+# | | vxlan0 |..| veth0 |.|...|.| veth0 |..| vxlan0 | |
+# | +--------+ | 172.16.1.1/24 | | | | 172.16.1.2/24 | +--------+ |
+# | | 172.16.2.1/24 | | | | 172.16.2.2/24 | |
+# | +-----------------+ | | +-----------------+ |
+# | | | |
+# | hv-1 netns | | hv-2 netns |
+# | | | |
+# +-----------------------------------+ +------------------------------------+
+#
+# This tests the connectivity between vm-1 and vm-2 using different subnet and
+# localbind configurations.
+
+source lib.sh
+ret=0
+
+TESTS="
+ same_subnet
+ same_subnet_localbind
+ different_subnets
+ different_subnets_localbind
+"
+
+VERBOSE=0
+PAUSE_ON_FAIL=no
+PAUSE=no
+
+################################################################################
+# Utilities
+
+which ping6 > /dev/null 2>&1 && ping6=$(which ping6) || ping6=$(which ping)
+
+log_test()
+{
+ local rc=$1
+ local expected=$2
+ local msg="$3"
+
+ if [ ${rc} -eq ${expected} ]; then
+ printf "TEST: %-60s [ OK ]\n" "${msg}"
+ nsuccess=$((nsuccess+1))
+ else
+ ret=1
+ nfail=$((nfail+1))
+ printf "TEST: %-60s [FAIL]\n" "${msg}"
+ if [ "$VERBOSE" = "1" ]; then
+ echo " rc=$rc, expected $expected"
+ fi
+
+ if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
+ echo
+ echo "hit enter to continue, 'q' to quit"
+ read a
+ [ "$a" = "q" ] && exit 1
+ fi
+ fi
+
+ if [ "${PAUSE}" = "yes" ]; then
+ echo
+ echo "hit enter to continue, 'q' to quit"
+ read a
+ [ "$a" = "q" ] && exit 1
+ fi
+
+ [ "$VERBOSE" = "1" ] && echo
+}
+
+run_cmd()
+{
+ local cmd="$1"
+ local out
+ local stderr="2>/dev/null"
+
+ if [ "$VERBOSE" = "1" ]; then
+ printf "COMMAND: $cmd\n"
+ stderr=
+ fi
+
+ out=$(eval $cmd $stderr)
+ rc=$?
+ if [ "$VERBOSE" = "1" -a -n "$out" ]; then
+ echo " $out"
+ fi
+
+ return $rc
+}
+
+check_hv_connectivity() {
+ slowwait 5 ip netns exec $hv_1 ping -c 1 -W 1 172.16.1.2 &>/dev/null
+ slowwait 5 ip netns exec $hv_1 ping -c 1 -W 1 172.16.2.2 &>/dev/null
+
+ return $?
+}
+
+check_vm_connectivity() {
+ if [ $2 -eq 1 ]; then
+ prefix="! "
+ else
+ prefix=""
+ fi
+
+ slowwait 5 run_cmd "${prefix}ip netns exec $vm_1 ping -c 1 -W 1 10.0.0.2"
+ log_test $? 0 "VM connectivity over $1"
+}
+
+################################################################################
+# Setup
+
+setup-hv-networking() {
+ id=$1
+ local=$2
+ remote=$3
+ flags=$4
+
+ [ $id -eq 1 ] && peer=2 || peer=1
+
+ ip link set veth-hv-$id netns ${hv[$id]}
+ ip -netns ${hv[$id]} link set veth-hv-$id name veth0
+ ip -netns ${hv[$id]} link set veth0 up
+
+ ip -netns ${hv[$id]} addr add 172.16.1.$id/24 dev veth0
+ ip -netns ${hv[$id]} addr add 172.16.2.$id/24 dev veth0
+
+ ip -netns ${hv[$id]} link add br0 type bridge
+ ip -netns ${hv[$id]} link set br0 up
+
+ ip -netns ${hv[$id]} link add vxlan0 type vxlan id 10 local 172.16.$local.$id remote 172.16.$remote.$peer $flags dev veth0 dstport 4789
+ ip -netns ${hv[$id]} link set vxlan0 master br0
+ ip -netns ${hv[$id]} link set vxlan0 up
+
+ bridge -netns ${hv[$id]} fdb append 00:00:00:00:00:00 dev vxlan0 dst 172.16.$remote.$peer self permanent
+}
+
+setup-vm() {
+ id=$1
+
+ ip link add veth-tap type veth peer name veth-hv
+
+ ip link set veth-tap netns ${hv[$id]}
+ ip -netns ${hv[$id]} link set veth-tap master br0
+ ip -netns ${hv[$id]} link set veth-tap up
+
+ ip link set veth-hv address 02:1d:8d:dd:0c:6$id
+
+ ip link set veth-hv netns ${vm[$id]}
+ ip -netns ${vm[$id]} addr add 10.0.0.$id/24 dev veth-hv
+ ip -netns ${vm[$id]} link set veth-hv up
+}
+
+setup()
+{
+ setup_ns hv_1 hv_2 vm_1 vm_2
+ hv[1]=$hv_1
+ hv[2]=$hv_2
+ vm[1]=$vm_1
+ vm[2]=$vm_2
+
+ # Setup "Hypervisors" simulated with netns
+ ip link add veth-hv-1 type veth peer name veth-hv-2
+ setup-hv-networking 1 1 2 $2
+ setup-hv-networking 2 $1 1 $2
+ setup-vm 1
+ setup-vm 2
+}
+
+cleanup() {
+ ip link del veth-hv-1 2>/dev/null || true
+ ip link del veth-tap 2>/dev/null || true
+
+ cleanup_ns $hv_1 $hv_2 $vm_1 $vm_2
+}
+
+################################################################################
+# Tests
+
+same_subnet()
+{
+ setup 2 "nolocalbind"
+ check_hv_connectivity
+ check_vm_connectivity "same subnet (nolocalbind)" 0
+}
+
+same_subnet_localbind()
+{
+ setup 2 "localbind"
+ check_hv_connectivity
+ check_vm_connectivity "same subnet (localbind)" 0
+}
+
+different_subnets()
+{
+ setup 1 "nolocalbind"
+ check_hv_connectivity
+ check_vm_connectivity "different subnets (nolocalbind)" 0
+}
+
+different_subnets_localbind()
+{
+ setup 1 "localbind"
+ check_hv_connectivity
+ check_vm_connectivity "different subnets (localbind)" 1
+}
+
+################################################################################
+# Usage
+
+usage()
+{
+ cat <<EOF
+usage: ${0##*/} OPTS
+
+ -t <test> Test(s) to run (default: all)
+ (options: $TESTS)
+ -p Pause on fail
+ -P Pause after each test before cleanup
+ -v Verbose mode (show commands and output)
+EOF
+}
+
+################################################################################
+# Main
+
+trap cleanup EXIT
+
+while getopts ":t:pPvh" opt; do
+ case $opt in
+ t) TESTS=$OPTARG ;;
+ p) PAUSE_ON_FAIL=yes;;
+ P) PAUSE=yes;;
+ v) VERBOSE=$(($VERBOSE + 1));;
+ h) usage; exit 0;;
+ *) usage; exit 1;;
+ esac
+done
+
+# Make sure we don't pause twice.
+[ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no
+
+if [ "$(id -u)" -ne 0 ];then
+ echo "SKIP: Need root privileges"
+ exit $ksft_skip;
+fi
+
+if [ ! -x "$(command -v ip)" ]; then
+ echo "SKIP: Could not run test without ip tool"
+ exit $ksft_skip
+fi
+
+if [ ! -x "$(command -v bridge)" ]; then
+ echo "SKIP: Could not run test without bridge tool"
+ exit $ksft_skip
+fi
+
+ip link help vxlan 2>&1 | grep -q "localbind"
+if [ $? -ne 0 ]; then
+ echo "SKIP: iproute2 ip too old, missing VXLAN localbind support"
+ exit $ksft_skip
+fi
+
+cleanup
+
+for t in $TESTS
+do
+ $t; cleanup;
+done
+
+if [ "$TESTS" != "none" ]; then
+ printf "\nTests passed: %3d\n" ${nsuccess}
+ printf "Tests failed: %3d\n" ${nfail}
+fi
+
+exit $ret
+
--
2.36.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH net-next v5 5/5] selftests/net: add vxlan localbind selftest
2025-08-12 12:51 ` [PATCH net-next v5 5/5] selftests/net: add vxlan localbind selftest Richard Gobert
@ 2025-08-13 11:44 ` Ido Schimmel
2025-08-13 15:49 ` Richard Gobert
2025-08-13 14:34 ` Jakub Kicinski
1 sibling, 1 reply; 23+ messages in thread
From: Ido Schimmel @ 2025-08-13 11:44 UTC (permalink / raw)
To: Richard Gobert
Cc: netdev, davem, edumazet, kuba, pabeni, horms, donald.hunter,
andrew+netdev, dsahern, shuah, daniel, jacob.e.keller, razor,
petrm, menglong8.dong, martin.lau, linux-kernel
On Tue, Aug 12, 2025 at 02:51:55PM +0200, Richard Gobert wrote:
> Test to make sure the localbind netlink option works
> in VXLAN interfaces.
Thanks for adding a test. A few clerical comments:
1. Indentation is inconsistent. Please convert to 8 characters tabs.
2. netdev CI started running shellcheck. I don't think you can eliminate
all the errors, but some can be easily fixed.
3. There's a blank line at the end of the file that should be removed.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH net-next v5 5/5] selftests/net: add vxlan localbind selftest
2025-08-13 11:44 ` Ido Schimmel
@ 2025-08-13 15:49 ` Richard Gobert
0 siblings, 0 replies; 23+ messages in thread
From: Richard Gobert @ 2025-08-13 15:49 UTC (permalink / raw)
To: Ido Schimmel
Cc: netdev, davem, edumazet, kuba, pabeni, horms, donald.hunter,
andrew+netdev, dsahern, shuah, daniel, jacob.e.keller, razor,
petrm, menglong8.dong, martin.lau, linux-kernel
Ido Schimmel wrote:
> On Tue, Aug 12, 2025 at 02:51:55PM +0200, Richard Gobert wrote:
>> Test to make sure the localbind netlink option works
>> in VXLAN interfaces.
>
> Thanks for adding a test. A few clerical comments:
>
> 1. Indentation is inconsistent. Please convert to 8 characters tabs.
>
> 2. netdev CI started running shellcheck. I don't think you can eliminate
> all the errors, but some can be easily fixed.
>
> 3. There's a blank line at the end of the file that should be removed.
I'll take a look. Thanks.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH net-next v5 5/5] selftests/net: add vxlan localbind selftest
2025-08-12 12:51 ` [PATCH net-next v5 5/5] selftests/net: add vxlan localbind selftest Richard Gobert
2025-08-13 11:44 ` Ido Schimmel
@ 2025-08-13 14:34 ` Jakub Kicinski
2025-08-13 15:52 ` Richard Gobert
1 sibling, 1 reply; 23+ messages in thread
From: Jakub Kicinski @ 2025-08-13 14:34 UTC (permalink / raw)
To: Richard Gobert
Cc: netdev, davem, edumazet, pabeni, horms, donald.hunter,
andrew+netdev, dsahern, shuah, daniel, jacob.e.keller, razor,
idosch, petrm, menglong8.dong, martin.lau, linux-kernel
On Tue, 12 Aug 2025 14:51:55 +0200 Richard Gobert wrote:
> +ip link help vxlan 2>&1 | grep -q "localbind"
> +if [ $? -ne 0 ]; then
> + echo "SKIP: iproute2 ip too old, missing VXLAN localbind support"
> + exit $ksft_skip
> +fi
Could you add a link to a public GH with the iproute2 patches,
or co-post them?
https://www.kernel.org/doc/html/next/process/maintainer-netdev.html#co-posting-changes-to-user-space-components
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH net-next v5 5/5] selftests/net: add vxlan localbind selftest
2025-08-13 14:34 ` Jakub Kicinski
@ 2025-08-13 15:52 ` Richard Gobert
0 siblings, 0 replies; 23+ messages in thread
From: Richard Gobert @ 2025-08-13 15:52 UTC (permalink / raw)
To: Jakub Kicinski
Cc: netdev, davem, edumazet, pabeni, horms, donald.hunter,
andrew+netdev, dsahern, shuah, daniel, jacob.e.keller, razor,
idosch, petrm, menglong8.dong, martin.lau, linux-kernel
Jakub Kicinski wrote:
> On Tue, 12 Aug 2025 14:51:55 +0200 Richard Gobert wrote:
>> +ip link help vxlan 2>&1 | grep -q "localbind"
>> +if [ $? -ne 0 ]; then
>> + echo "SKIP: iproute2 ip too old, missing VXLAN localbind support"
>> + exit $ksft_skip
>> +fi
>
> Could you add a link to a public GH with the iproute2 patches,
> or co-post them?
> https://www.kernel.org/doc/html/next/process/maintainer-netdev.html#co-posting-changes-to-user-space-components
Will do.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH net-next v5 0/5] net: add local address bind support to vxlan and geneve
2025-08-12 12:51 [PATCH net-next v5 0/5] net: add local address bind support to vxlan and geneve Richard Gobert
` (4 preceding siblings ...)
2025-08-12 12:51 ` [PATCH net-next v5 5/5] selftests/net: add vxlan localbind selftest Richard Gobert
@ 2025-08-13 9:25 ` Ido Schimmel
2025-08-13 15:29 ` Richard Gobert
5 siblings, 1 reply; 23+ messages in thread
From: Ido Schimmel @ 2025-08-13 9:25 UTC (permalink / raw)
To: Richard Gobert
Cc: netdev, davem, edumazet, kuba, pabeni, horms, donald.hunter,
andrew+netdev, dsahern, shuah, daniel, jacob.e.keller, razor,
petrm, menglong8.dong, martin.lau, linux-kernel
On Tue, Aug 12, 2025 at 02:51:50PM +0200, Richard Gobert wrote:
> Currently, vxlan sockets are always bound to 0.0.0.0. For security, it is
> better to bind to the specific interface on which traffic is expected.
s/interface/address/ ?
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH net-next v5 0/5] net: add local address bind support to vxlan and geneve
2025-08-13 9:25 ` [PATCH net-next v5 0/5] net: add local address bind support to vxlan and geneve Ido Schimmel
@ 2025-08-13 15:29 ` Richard Gobert
0 siblings, 0 replies; 23+ messages in thread
From: Richard Gobert @ 2025-08-13 15:29 UTC (permalink / raw)
To: Ido Schimmel
Cc: netdev, davem, edumazet, kuba, pabeni, horms, donald.hunter,
andrew+netdev, dsahern, shuah, daniel, jacob.e.keller, razor,
petrm, menglong8.dong, martin.lau, linux-kernel
Ido Schimmel wrote:
> On Tue, Aug 12, 2025 at 02:51:50PM +0200, Richard Gobert wrote:
>> Currently, vxlan sockets are always bound to 0.0.0.0. For security, it is
>> better to bind to the specific interface on which traffic is expected.
>
> s/interface/address/ ?
Sure, will change in v6.
^ permalink raw reply [flat|nested] 23+ messages in thread