[PATCH net-next v2 1/6] net: lwtunnel: change encap fill order

From: Hangbin Liu

Date: Sun Sep 20 2026 - 06:07:55 EST


From: Hangbin Liu <liuhangbin@xxxxxxxxxx>

When decoding sub‑messages, YNL tries to fetch the "selector" (encap‑type)
first. However, lwtunnel fills encap‑payload data first, which causes YNL
to fail decoding the lwtunnel encap message.

Fixing this inside YNL would be complex, so change the order in the kernel
and emit encap_type first.

Signed-off-by: Hangbin Liu <liuhangbin@xxxxxxxxxx>
---
net/core/lwtunnel.c | 35 ++++++++++++++++++-----------------
1 file changed, 18 insertions(+), 17 deletions(-)

diff --git a/net/core/lwtunnel.c b/net/core/lwtunnel.c
index b01a395d9a96..8223c44f10c8 100644
--- a/net/core/lwtunnel.c
+++ b/net/core/lwtunnel.c
@@ -231,7 +231,7 @@ int lwtunnel_fill_encap(struct sk_buff *skb, struct lwtunnel_state *lwtstate,
{
const struct lwtunnel_encap_ops *ops;
struct nlattr *nest;
- int ret;
+ int ret = 0;

if (!lwtstate)
return 0;
@@ -240,30 +240,31 @@ int lwtunnel_fill_encap(struct sk_buff *skb, struct lwtunnel_state *lwtstate,
lwtstate->type > LWTUNNEL_ENCAP_MAX)
return 0;

- nest = nla_nest_start_noflag(skb, encap_attr);
- if (!nest)
- return -EMSGSIZE;
-
- ret = -EOPNOTSUPP;
rcu_read_lock();
+
ops = rcu_dereference(lwtun_encaps[lwtstate->type]);
- if (likely(ops && ops->fill_encap))
- ret = ops->fill_encap(skb, lwtstate);
- rcu_read_unlock();
+ if (unlikely(!ops || !ops->fill_encap))
+ goto unlock_out;

- if (ret)
- goto nla_put_failure;
- nla_nest_end(skb, nest);
ret = nla_put_u16(skb, encap_type_attr, lwtstate->type);
if (ret)
- goto nla_put_failure;
+ goto unlock_out;

- return 0;
+ nest = nla_nest_start_noflag(skb, encap_attr);
+ if (!nest) {
+ ret = -EMSGSIZE;
+ goto unlock_out;
+ }

-nla_put_failure:
- nla_nest_cancel(skb, nest);
+ ret = ops->fill_encap(skb, lwtstate);
+ if (ret)
+ nla_nest_cancel(skb, nest);
+ else
+ nla_nest_end(skb, nest);

- return (ret == -EOPNOTSUPP ? 0 : ret);
+unlock_out:
+ rcu_read_unlock();
+ return ret;
}
EXPORT_SYMBOL_GPL(lwtunnel_fill_encap);


--
2.55.0