diff options
| author | Kuniyuki Iwashima <kuniyu@google.com> | 2026-06-02 19:03:44 +0000 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-06-03 18:07:41 -0700 |
| commit | 2e5feb257ec50874772962bca578207d9a9b5f5a (patch) | |
| tree | 436f20c7d413736f44e457b65b27390b6dc1343a | |
| parent | 0429413cc7811ae29ff07e4173544c5112d2ac81 (diff) | |
geneve: Add dualstack flag to struct geneve_config.
When collect metadata mode (IFLA_GENEVE_COLLECT_METADATA) is
enabled, the GENEVE device creates both IPv4 and IPv6 sockets
and bind()s them to wildcard addresses.
The next patch allows creating only one socket bound to a
specific address even when the collect metadata mode is
enabled.
Then, we need a flag to distinguish dualstack GENEVE devices
to detect local address conflict.
Let's add the dualstack flag to struct geneve_config.
IFLA_GENEVE_COLLECT_METADATA processing is moved up in
geneve_nl2info() for the next patch to overwrite dualstack
to false while keeping collect_md true.
Note that IFLA_GENEVE_REMOTE and IFLA_GENEVE_REMOTE6 does not
set cfg->dualstack to false since is_tnl_info_zero() ignores
the wildcard remote address:
# ip link add geneve0 type geneve external remote 0.0.0.1
Error: Device is externally controlled, so attributes (VNI, Port, and so on) must not be specified.
# ip link add geneve0 type geneve external remote 0.0.0.0
# ss -ua | grep geneve
UNCONN 0 0 0.0.0.0:geneve 0.0.0.0:*
UNCONN 0 0 *:geneve *:*
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20260602190436.139591-5-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
| -rw-r--r-- | drivers/net/geneve.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index 4f841eced028..3a62d132a8c4 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -73,6 +73,7 @@ struct geneve_dev_node { struct geneve_config { bool collect_md; + bool dualstack; bool use_udp6_rx_checksums; bool ttl_inherit; bool gro_hint; @@ -1108,12 +1109,12 @@ out: static int geneve_open(struct net_device *dev) { struct geneve_dev *geneve = netdev_priv(dev); - bool metadata = geneve->cfg.collect_md; + bool dualstack = geneve->cfg.dualstack; bool ipv4, ipv6; int ret = 0; - ipv6 = geneve->cfg.info.mode & IP_TUNNEL_INFO_IPV6 || metadata; - ipv4 = !ipv6 || metadata; + ipv6 = geneve->cfg.info.mode & IP_TUNNEL_INFO_IPV6 || dualstack; + ipv4 = !ipv6 || dualstack; #if IS_ENABLED(CONFIG_IPV6) if (ipv6) { ret = geneve_sock_add(geneve, true); @@ -1906,6 +1907,16 @@ static int geneve_nl2info(struct nlattr *tb[], struct nlattr *data[], struct ip_tunnel_info *info = &cfg->info; int attrtype; + if (data[IFLA_GENEVE_COLLECT_METADATA]) { + if (changelink) { + attrtype = IFLA_GENEVE_COLLECT_METADATA; + goto change_notsup; + } + + cfg->collect_md = true; + cfg->dualstack = true; + } + if (data[IFLA_GENEVE_REMOTE] && data[IFLA_GENEVE_REMOTE6]) { NL_SET_ERR_MSG(extack, "Cannot specify both IPv4 and IPv6 Remote addresses"); @@ -2025,14 +2036,6 @@ static int geneve_nl2info(struct nlattr *tb[], struct nlattr *data[], cfg->port_max = ntohs(p->high); } - if (data[IFLA_GENEVE_COLLECT_METADATA]) { - if (changelink) { - attrtype = IFLA_GENEVE_COLLECT_METADATA; - goto change_notsup; - } - cfg->collect_md = true; - } - if (data[IFLA_GENEVE_UDP_CSUM]) { if (changelink) { attrtype = IFLA_GENEVE_UDP_CSUM; @@ -2153,6 +2156,7 @@ static int geneve_newlink(struct net_device *dev, .use_udp6_rx_checksums = false, .ttl_inherit = false, .collect_md = false, + .dualstack = false, .port_min = 1, .port_max = USHRT_MAX, }; @@ -2382,6 +2386,7 @@ struct net_device *geneve_dev_create_fb(struct net *net, const char *name, .use_udp6_rx_checksums = true, .ttl_inherit = false, .collect_md = true, + .dualstack = true, .port_min = 1, .port_max = USHRT_MAX, }; |
