mirror of
https://github.com/lkl/linux.git
synced 2025-12-19 08:03:01 +09:00
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>
This commit is contained in:
committed by
David S. Miller
parent
833ef3b91d
commit
4a992bbd36
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user