diff options
author | Jeremy Kerr <jk@codeconstruct.com.au> | 2024-02-19 12:51:54 +0300 |
---|---|---|
committer | Sasha Levin <sashal@kernel.org> | 2024-03-27 01:16:49 +0300 |
commit | 06460a1de745b22f02c8f31153a0dbd89ca14bec (patch) | |
tree | d3c4afd4b6a09f7dc199a686fd79b72a003fc452 | |
parent | 34c4db757ed34149467a3049b770fb2f4e044790 (diff) | |
download | linux-06460a1de745b22f02c8f31153a0dbd89ca14bec.tar.xz |
net: mctp: copy skb ext data when fragmenting
[ Upstream commit 1394c1dec1c619a46867ed32791a29695372bff8 ]
If we're fragmenting on local output, the original packet may contain
ext data for the MCTP flows. We'll want this in the resulting fragment
skbs too.
So, do a skb_ext_copy() in the fragmentation path, and implement the
MCTP-specific parts of an ext copy operation.
Fixes: 67737c457281 ("mctp: Pass flow data & flow release events to drivers")
Reported-by: Jian Zhang <zhangjian.3032@bytedance.com>
Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r-- | net/core/skbuff.c | 8 | ||||
-rw-r--r-- | net/mctp/route.c | 3 |
2 files changed, 11 insertions, 0 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index edbbef563d4d..71dee435d549 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -6737,6 +6737,14 @@ static struct skb_ext *skb_ext_maybe_cow(struct skb_ext *old, xfrm_state_hold(sp->xvec[i]); } #endif +#ifdef CONFIG_MCTP_FLOWS + if (old_active & (1 << SKB_EXT_MCTP)) { + struct mctp_flow *flow = skb_ext_get_ptr(old, SKB_EXT_MCTP); + + if (flow->key) + refcount_inc(&flow->key->refs); + } +#endif __skb_ext_put(old); return new; } diff --git a/net/mctp/route.c b/net/mctp/route.c index ceee44ea09d9..01c530dbc1a6 100644 --- a/net/mctp/route.c +++ b/net/mctp/route.c @@ -843,6 +843,9 @@ static int mctp_do_fragment_route(struct mctp_route *rt, struct sk_buff *skb, /* copy message payload */ skb_copy_bits(skb, pos, skb_transport_header(skb2), size); + /* we need to copy the extensions, for MCTP flow data */ + skb_ext_copy(skb2, skb); + /* do route */ rc = rt->output(rt, skb2); if (rc) |