From: Davide Caratti Date: Tue, 6 Oct 2020 16:26:17 +0000 (+0200) Subject: net: mptcp: make DACK4/DACK8 usage consistent among all subflows X-Git-Tag: v5.8.17~622 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b91a8c7486a38f999bf11ff867668300ace1c81c;p=thirdparty%2Fkernel%2Fstable.git net: mptcp: make DACK4/DACK8 usage consistent among all subflows [ Upstream commit 37198e93ced70733f0b993dff28b7c33857e254f ] using packetdrill it's possible to observe the same MPTCP DSN being acked by different subflows with DACK4 and DACK8. This is in contrast with what specified in RFC8684 ยง3.3.2: if an MPTCP endpoint transmits a 64-bit wide DSN, it MUST be acknowledged with a 64-bit wide DACK. Fix 'use_64bit_ack' variable to make it a property of MPTCP sockets, not TCP subflows. Fixes: a0c1d0eafd1e ("mptcp: Use 32-bit DATA_ACK when possible") Acked-by: Paolo Abeni Signed-off-by: Davide Caratti Reviewed-by: Mat Martineau Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- diff --git a/net/mptcp/options.c b/net/mptcp/options.c index 8f940be42f98a..77d46cc8165bc 100644 --- a/net/mptcp/options.c +++ b/net/mptcp/options.c @@ -517,7 +517,7 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb, return ret; } - if (subflow->use_64bit_ack) { + if (READ_ONCE(msk->use_64bit_ack)) { ack_size = TCPOLEN_MPTCP_DSS_ACK64; opts->ext_copy.data_ack = msk->ack_seq; opts->ext_copy.ack64 = 1; diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index c6eeaf3e8dcb7..4675a7bbebb15 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -199,6 +199,7 @@ struct mptcp_sock { u32 token; unsigned long flags; bool can_ack; + bool use_64bit_ack; /* Set when we received a 64-bit DSN */ spinlock_t join_list_lock; struct work_struct work; struct list_head conn_list; @@ -285,7 +286,6 @@ struct mptcp_subflow_context { data_avail : 1, rx_eof : 1, data_fin_tx_enable : 1, - use_64bit_ack : 1, /* Set when we received a 64-bit DSN */ can_ack : 1; /* only after processing the remote a key */ u64 data_fin_tx_seq; u32 remote_nonce; diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index 3838a0b3a21ff..2e145b53b81f4 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -682,12 +682,11 @@ static enum mapping_status get_mapping_status(struct sock *ssk) if (!mpext->dsn64) { map_seq = expand_seq(subflow->map_seq, subflow->map_data_len, mpext->data_seq); - subflow->use_64bit_ack = 0; pr_debug("expanded seq=%llu", subflow->map_seq); } else { map_seq = mpext->data_seq; - subflow->use_64bit_ack = 1; } + WRITE_ONCE(mptcp_sk(subflow->conn)->use_64bit_ack, !!mpext->dsn64); if (subflow->map_valid) { /* Allow replacing only with an identical map */