mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
Merge branch 'net-prepare-skb-extensions-for-reuse-across-scrubs'
Jakub Sitnicki says: ==================== net: Prepare skb extensions for reuse across scrubs Following Florian's suggestion from the discussion in [1]. The skb extension allocator retains the extension's offset after the extension is deleted. This, in theory, allows skb_ext_add() to reuse the existing storage instead of appending another copy when an extension is added again. However, it also means that we can't rely on the offset as an indicator that the extension is present. Make the extension cleanup safe, even when the offset is already allocated and set, by making the individual extension put helpers idempotent, so that they can be called multiple times. This is preparatory work to support skb extension chunk area reuse after skb scrubbing, which would be needed to persist BPF metadata skb extension across scrubs [2]. [1] https://lore.kernel.org/ao9UV9S7rUkyQ8jv@strlen.de [2] https://lore.kernel.org/64365932-c765-472e-bf6c-b07c9ee25eaf@kernel.org ==================== Link: https://patch.msgid.link/20260831-skb-ext-prep-work-v1-0-ecc2a8542fd9@cloudflare.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
0a1071aa32
|
|
@ -7236,16 +7236,23 @@ static void skb_ext_put_sp(struct sec_path *sp)
|
|||
{
|
||||
unsigned int i;
|
||||
|
||||
if (!sp->len)
|
||||
return;
|
||||
|
||||
for (i = 0; i < sp->len; i++)
|
||||
xfrm_state_put(sp->xvec[i]);
|
||||
sp->len = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
||||
|
|
@ -7257,15 +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) {
|
||||
struct sec_path *sp = skb_ext_get_ptr(ext, SKB_EXT_SEC_PATH);
|
||||
|
||||
skb_ext_put_sp(sp);
|
||||
sp->len = 0;
|
||||
#endif
|
||||
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);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user