summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHangbin Liu <liuhangbin@kylinos.cn>2026-10-08 16:24:01 +0800
committerJakub Kicinski <kuba@kernel.org>2026-10-15 16:59:58 -0700
commit499f32f0eb56603af2930ba67b4eb82fc1437264 (patch)
tree4c0b1ce3eb56cf3705d77ce19ab3779c2456b517
parente6435b2cc5fdf008cdb67ad9a811a266e8ac9c1e (diff)
net: lwtunnel: change encap fill order
I plan to add lwtunnel encap attributes to the YNL rt-route.yaml spec. When decoding submessages, YNL expects to read the "selector" (encap-type) first. Currently lwtunnel writes the encap payload first, which makes YNL fail to parse the lwtunnel encap message. Fixing this within YNL itself would be complicated. Instead, reorder the netlink attributes in the kernel to output encap_type first. This is a preparatory change for the upcoming rt-route spec updates. Reviewed-by: Ido Schimmel <idosch@nvidia.com> Signed-off-by: Hangbin Liu <liuhangbin@kylinos.cn> Link: https://patch.msgid.link/20261008-ynl_rt_encap-v4-1-4ed2ccf7f949@kylinos.cn Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r--net/core/lwtunnel.c35
1 files 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);