]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
netfilter: nft_tunnel: fix geneve_opt dump
authorFernando Fernandez Mancera <fmancera@suse.de>
Wed, 21 May 2025 09:41:08 +0000 (11:41 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 27 Jun 2025 10:04:04 +0000 (11:04 +0100)
[ Upstream commit 22a9613de4c29d7d0770bfb8a5a9d73eb8df7dad ]

When dumping a nft_tunnel with more than one geneve_opt configured the
netlink attribute hierarchy should be as follow:

 NFTA_TUNNEL_KEY_OPTS
 |
 |--NFTA_TUNNEL_KEY_OPTS_GENEVE
 |  |
 |  |--NFTA_TUNNEL_KEY_GENEVE_CLASS
 |  |--NFTA_TUNNEL_KEY_GENEVE_TYPE
 |  |--NFTA_TUNNEL_KEY_GENEVE_DATA
 |
 |--NFTA_TUNNEL_KEY_OPTS_GENEVE
 |  |
 |  |--NFTA_TUNNEL_KEY_GENEVE_CLASS
 |  |--NFTA_TUNNEL_KEY_GENEVE_TYPE
 |  |--NFTA_TUNNEL_KEY_GENEVE_DATA
 |
 |--NFTA_TUNNEL_KEY_OPTS_GENEVE
 ...

Otherwise, userspace tools won't be able to fetch the geneve options
configured correctly.

Fixes: 925d844696d9 ("netfilter: nft_tunnel: add support for geneve opts")
Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
net/netfilter/nft_tunnel.c

index cfe6cf1be4217fe75d1f0970fac568d90ba411ef..95f8230322289672d5c2bdc0cf4afa4d16b01dd7 100644 (file)
@@ -588,10 +588,10 @@ static int nft_tunnel_opts_dump(struct sk_buff *skb,
                struct geneve_opt *opt;
                int offset = 0;
 
-               inner = nla_nest_start_noflag(skb, NFTA_TUNNEL_KEY_OPTS_GENEVE);
-               if (!inner)
-                       goto failure;
                while (opts->len > offset) {
+                       inner = nla_nest_start_noflag(skb, NFTA_TUNNEL_KEY_OPTS_GENEVE);
+                       if (!inner)
+                               goto failure;
                        opt = (struct geneve_opt *)(opts->u.data + offset);
                        if (nla_put_be16(skb, NFTA_TUNNEL_KEY_GENEVE_CLASS,
                                         opt->opt_class) ||
@@ -601,8 +601,8 @@ static int nft_tunnel_opts_dump(struct sk_buff *skb,
                                    opt->length * 4, opt->opt_data))
                                goto inner_failure;
                        offset += sizeof(*opt) + opt->length * 4;
+                       nla_nest_end(skb, inner);
                }
-               nla_nest_end(skb, inner);
        }
        nla_nest_end(skb, nest);
        return 0;