@@ -37,11 +37,10 @@ static void mptcp_parse_option(const struct sock *sk,
case MPTCPOPT_MP_CAPABLE:
/* strict size checking */
if (!(TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN)) {
- if (skb->len > tcp_hdr(skb)->doff << 2) {
+ if (skb->len > tcp_hdr(skb)->doff << 2)
expected_opsize = TCPOLEN_MPTCP_MPC_ACK_DATA;
- } else {
+ else
expected_opsize = TCPOLEN_MPTCP_MPC_ACK;
- }
} else {
if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_ACK)
expected_opsize = TCPOLEN_MPTCP_MPC_SYNACK;
@@ -166,6 +165,7 @@ static void mptcp_parse_option(const struct sock *sk,
mp_opt->use_map = (flags & MPTCP_DSS_HAS_MAP) != 0;
mp_opt->ack64 = (flags & MPTCP_DSS_ACK64) != 0;
mp_opt->use_ack = (flags & MPTCP_DSS_HAS_ACK);
+ mp_opt->csum_reqd = READ_ONCE(msk->csum_enabled);
pr_debug("data_fin=%d dsn64=%d use_map=%d ack64=%d use_ack=%d",
mp_opt->data_fin, mp_opt->dsn64,
@@ -186,6 +186,9 @@ static void mptcp_parse_option(const struct sock *sk,
expected_opsize += TCPOLEN_MPTCP_DSS_MAP64;
else
expected_opsize += TCPOLEN_MPTCP_DSS_MAP32;
+
+ if (mp_opt->csum_reqd)
+ expected_opsize += TCPOLEN_MPTCP_DSS_CHECKSUM;
}
/* RFC 6824, Section 3.3:
@@ -193,8 +196,7 @@ static void mptcp_parse_option(const struct sock *sk,
* not been negotiated in the MP_CAPABLE handshake,
* the checksum field MUST be ignored.
*/
- if (opsize != expected_opsize &&
- opsize != expected_opsize + TCPOLEN_MPTCP_DSS_CHECKSUM)
+ if (opsize != expected_opsize)
break;
mp_opt->dss = 1;
@@ -226,9 +228,14 @@ static void mptcp_parse_option(const struct sock *sk,
mp_opt->data_len = get_unaligned_be16(ptr);
ptr += 2;
- pr_debug("data_seq=%llu subflow_seq=%u data_len=%u",
+ if (mp_opt->csum_reqd) {
+ mp_opt->csum = (__force __sum16)get_unaligned_be16(ptr);
+ ptr += 2;
+ }
+
+ pr_debug("data_seq=%llu subflow_seq=%u data_len=%u csum=%u",
mp_opt->data_seq, mp_opt->subflow_seq,
- mp_opt->data_len);
+ mp_opt->data_len, mp_opt->csum);
}
break;