net: Make skb_ext_put_mctp() idempotent

The MCTP flow extension can be released either when it is deleted from an
skb or when the last skb holding the extension block is freed. Handle the
release in __skb_ext_del(), which is currently missing, and make
skb_ext_put_mctp() safe to call from both paths.

This will let __skb_ext_put() release the MCTP key without checking whether
the extension is present first, which is needed if we want to reuse skb_ext
chunks area after skb scrubbing.

Suggested-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com>
Acked-by: Jeremy Kerr <jk@codeconstruct.com.au>
Link: https://patch.msgid.link/20260831-skb-ext-prep-work-v1-2-ecc2a8542fd9@cloudflare.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Sitnicki 2026-08-31 08:27:39 +02:00 committed by Jakub Kicinski
parent d7470cba6d
commit dbe45b209e

View File

@ -7248,8 +7248,11 @@ static void skb_ext_put_sp(struct sec_path *sp)
#ifdef CONFIG_MCTP_FLOWS
static void skb_ext_put_mctp(struct mctp_flow *flow)
{
if (flow->key)
mctp_key_unref(flow->key);
if (!flow->key)
return;
mctp_key_unref(flow->key);
flow->key = NULL;
}
#endif
@ -7261,13 +7264,20 @@ void __skb_ext_del(struct sk_buff *skb, enum skb_ext_id id)
if (skb->active_extensions == 0) {
skb->extensions = NULL;
__skb_ext_put(ext);
#ifdef CONFIG_XFRM
} else if (id == SKB_EXT_SEC_PATH &&
refcount_read(&ext->refcnt) == 1) {
return;
}
if (refcount_read(&ext->refcnt) > 1)
return;
#ifdef CONFIG_XFRM
if (id == SKB_EXT_SEC_PATH)
skb_ext_put_sp(skb_ext_get_ptr(ext, SKB_EXT_SEC_PATH));
#endif
}
#ifdef CONFIG_MCTP_FLOWS
if (id == SKB_EXT_MCTP)
skb_ext_put_mctp(skb_ext_get_ptr(ext, SKB_EXT_MCTP));
#endif
}
EXPORT_SYMBOL(__skb_ext_del);