diff options
| author | Jeremy Kerr <[email protected]> | 2021-07-29 02:20:50 +0000 |
|---|---|---|
| committer | David S. Miller <[email protected]> | 2021-07-29 14:06:50 +0000 |
| commit | 4a992bbd365094730a31bae1e12a6ca695336d57 (patch) | |
| tree | 2e0fadd843a2f91e068b0340618eaa1f4147f5ca /net/mctp/af_mctp.c | |
| parent | mctp: Populate socket implementation (diff) | |
| download | kernel-4a992bbd365094730a31bae1e12a6ca695336d57.tar.gz kernel-4a992bbd365094730a31bae1e12a6ca695336d57.zip | |
mctp: Implement message fragmentation & reassembly
This change implements MCTP fragmentation (based on route & device MTU),
and corresponding reassembly.
The MCTP specification only allows for fragmentation on the originating
message endpoint, and reassembly on the destination endpoint -
intermediate nodes do not need to reassemble/refragment. Consequently,
we only fragment in the local transmit path, and reassemble
locally-bound packets. Messages are required to be in-order, so we
simply cancel reassembly on out-of-order or missing packets.
In the fragmentation path, we just break up the message into MTU-sized
fragments; the skb structure is a simple copy for now, which we can later
improve with a shared data implementation.
For reassembly, we keep track of incoming message fragments using the
existing tag infrastructure, allocating a key on the (src,dest,tag)
tuple, and reassembles matching fragments into a skb->frag_list.
Signed-off-by: Jeremy Kerr <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Diffstat (limited to 'net/mctp/af_mctp.c')
| -rw-r--r-- | net/mctp/af_mctp.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/net/mctp/af_mctp.c b/net/mctp/af_mctp.c index 52bd7f2b78db..9ca836df19d0 100644 --- a/net/mctp/af_mctp.c +++ b/net/mctp/af_mctp.c @@ -263,6 +263,14 @@ static void mctp_sk_unhash(struct sock *sk) hlist_for_each_entry_safe(key, tmp, &msk->keys, sklist) { hlist_del_rcu(&key->sklist); hlist_del_rcu(&key->hlist); + + spin_lock(&key->reasm_lock); + if (key->reasm_head) + kfree_skb(key->reasm_head); + key->reasm_head = NULL; + key->reasm_dead = true; + spin_unlock(&key->reasm_lock); + kfree_rcu(key, rcu); } spin_unlock_irqrestore(&net->mctp.keys_lock, flags); |
