summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorJeremy Kerr <jk@codeconstruct.com.au>2021-07-29 05:20:50 +0300
committerDavid S. Miller <davem@davemloft.net>2021-07-29 17:06:50 +0300
commit4a992bbd365094730a31bae1e12a6ca695336d57 (patch)
tree2e0fadd843a2f91e068b0340618eaa1f4147f5ca /include
parent833ef3b91de692ef33b800bca6b1569c39dece74 (diff)
downloadlinux-4a992bbd365094730a31bae1e12a6ca695336d57.tar.xz
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 <jk@codeconstruct.com.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r--include/net/mctp.h25
1 files changed, 22 insertions, 3 deletions
diff --git a/include/net/mctp.h b/include/net/mctp.h
index f2d98f6993c0..0a460ba185b8 100644
--- a/include/net/mctp.h
+++ b/include/net/mctp.h
@@ -84,9 +84,21 @@ struct mctp_sock {
* updates to either list are performed under the netns_mctp->keys
* lock.
*
- * - there is a single destruction path for a mctp_sk_key - through socket
- * unhash (see mctp_sk_unhash). This performs the list removal under
- * keys_lock.
+ * - a key may have a sk_buff attached as part of an in-progress message
+ * reassembly (->reasm_head). The reassembly context is protected by
+ * reasm_lock, which may be acquired with the keys lock (above) held, if
+ * necessary. Consequently, keys lock *cannot* be acquired with the
+ * reasm_lock held.
+ *
+ * - there are two destruction paths for a mctp_sk_key:
+ *
+ * - through socket unhash (see mctp_sk_unhash). This performs the list
+ * removal under keys_lock.
+ *
+ * - where a key is established to receive a reply message: after receiving
+ * the (complete) reply, or during reassembly errors. Here, we clean up
+ * the reassembly context (marking reasm_dead, to prevent another from
+ * starting), and remove the socket from the netns & socket lists.
*/
struct mctp_sk_key {
mctp_eid_t peer_addr;
@@ -102,6 +114,13 @@ struct mctp_sk_key {
/* per-socket list */
struct hlist_node sklist;
+ /* incoming fragment reassembly context */
+ spinlock_t reasm_lock;
+ struct sk_buff *reasm_head;
+ struct sk_buff **reasm_tailp;
+ bool reasm_dead;
+ u8 last_seq;
+
struct rcu_head rcu;
};