@@ -23,6 +23,7 @@ struct mptcp_ext {
u64 data_seq;
u32 subflow_seq;
u16 data_len;
+ __sum16 csum;
u8 use_map:1,
dsn64:1,
data_fin:1,
@@ -1279,6 +1279,25 @@ static bool mptcp_alloc_tx_skb(struct sock *sk, struct sock *ssk)
return __mptcp_alloc_tx_skb(sk, ssk, sk->sk_allocation);
}
+static __sum16 mptcp_generate_data_checksum(struct sk_buff *skb)
+{
+ struct csum_pseudo_header header;
+ struct mptcp_ext *mpext;
+ __wsum csum;
+
+ mpext = mptcp_get_ext(skb);
+
+ header.data_seq = mpext->data_seq;
+ header.subflow_seq = mpext->subflow_seq;
+ header.data_len = mpext->data_len;
+ header.csum = 0;
+
+ csum = skb_checksum(skb, 0, skb->len, 0);
+ csum = csum_partial(&header, sizeof(header), csum);
+
+ return csum_fold(csum);
+}
+
static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
struct mptcp_data_frag *dfrag,
struct mptcp_sendmsg_info *info)
@@ -1377,6 +1396,8 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
tcp_push_pending_frames(ssk);
}
out:
+ if (READ_ONCE(msk->csum_enabled))
+ mpext->csum = mptcp_generate_data_checksum(tail);
mptcp_subflow_ctx(ssk)->rel_write_seq += ret;
return ret;
}
@@ -335,6 +335,13 @@ static inline struct mptcp_data_frag *mptcp_rtx_head(const struct sock *sk)
return list_first_entry_or_null(&msk->rtx_queue, struct mptcp_data_frag, list);
}
+struct csum_pseudo_header {
+ u64 data_seq;
+ u32 subflow_seq;
+ u16 data_len;
+ __sum16 csum;
+};
+
struct mptcp_subflow_request_sock {
struct tcp_request_sock sk;
u16 mp_capable : 1,