Skip to content

Commit ae66fb2

Browse files
mjmartineaudavem330
authored andcommitted
mptcp: Do TCP fallback on early DSS checksum failure
RFC 8684 section 3.7 describes several opportunities for a MPTCP connection to "fall back" to regular TCP early in the connection process, before it has been confirmed that MPTCP options can be successfully propagated on all SYN, SYN/ACK, and data packets. If a peer acknowledges the first received data packet with a regular TCP header (no MPTCP options), fallback is allowed. If the recipient of that first data packet finds a MPTCP DSS checksum error, this provides an opportunity to fail gracefully with a TCP fallback rather than resetting the connection (as might happen if a checksum failure were detected later). This commit modifies the checksum failure code to attempt fallback on the initial subflow of a MPTCP connection, only if it's a failure in the first data mapping. In cases where the peer initiates the connection, requests checksums, is the first to send data, and the peer is sending incorrect checksums (see multipath-tcp/mptcp_net-next#275), this allows the connection to proceed as TCP rather than reset. Fixes: dd8bcd1 ("mptcp: validate the data checksum") Acked-by: Paolo Abeni <[email protected]> Signed-off-by: Mat Martineau <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent ba2c89e commit ae66fb2

File tree

2 files changed

+20
-4
lines changed

2 files changed

+20
-4
lines changed

net/mptcp/protocol.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,8 @@ struct mptcp_subflow_context {
443443
can_ack : 1, /* only after processing the remote a key */
444444
disposable : 1, /* ctx can be free at ulp release time */
445445
stale : 1, /* unable to snd/rcv data, do not use for xmit */
446-
local_id_valid : 1; /* local_id is correctly initialized */
446+
local_id_valid : 1, /* local_id is correctly initialized */
447+
valid_csum_seen : 1; /* at least one csum validated */
447448
enum mptcp_data_avail data_avail;
448449
u32 remote_nonce;
449450
u64 thmac;

net/mptcp/subflow.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -955,11 +955,14 @@ static enum mapping_status validate_data_csum(struct sock *ssk, struct sk_buff *
955955
subflow->map_data_csum);
956956
if (unlikely(csum)) {
957957
MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_DATACSUMERR);
958-
subflow->send_mp_fail = 1;
959-
MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_MPFAILTX);
958+
if (subflow->mp_join || subflow->valid_csum_seen) {
959+
subflow->send_mp_fail = 1;
960+
MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_MPFAILTX);
961+
}
960962
return subflow->mp_join ? MAPPING_INVALID : MAPPING_DUMMY;
961963
}
962964

965+
subflow->valid_csum_seen = 1;
963966
return MAPPING_OK;
964967
}
965968

@@ -1141,6 +1144,18 @@ static void subflow_sched_work_if_closed(struct mptcp_sock *msk, struct sock *ss
11411144
}
11421145
}
11431146

1147+
static bool subflow_can_fallback(struct mptcp_subflow_context *subflow)
1148+
{
1149+
struct mptcp_sock *msk = mptcp_sk(subflow->conn);
1150+
1151+
if (subflow->mp_join)
1152+
return false;
1153+
else if (READ_ONCE(msk->csum_enabled))
1154+
return !subflow->valid_csum_seen;
1155+
else
1156+
return !subflow->fully_established;
1157+
}
1158+
11441159
static bool subflow_check_data_avail(struct sock *ssk)
11451160
{
11461161
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
@@ -1218,7 +1233,7 @@ static bool subflow_check_data_avail(struct sock *ssk)
12181233
return true;
12191234
}
12201235

1221-
if (subflow->mp_join || subflow->fully_established) {
1236+
if (!subflow_can_fallback(subflow)) {
12221237
/* fatal protocol error, close the socket.
12231238
* subflow_error_report() will introduce the appropriate barriers
12241239
*/

0 commit comments

Comments
 (0)