summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorDavide Caratti <dcaratti@redhat.com>2020-10-06 19:26:17 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-10-29 12:07:00 +0300
commitb91a8c7486a38f999bf11ff867668300ace1c81c (patch)
tree32f4c3a830e6a15819b105a76fdd652ba726507f /net
parenta0f063a63afa59042cc5ed6fc03fa384baa9a313 (diff)
downloadlinux-b91a8c7486a38f999bf11ff867668300ace1c81c.tar.xz
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 <pabeni@redhat.com> Signed-off-by: Davide Caratti <dcaratti@redhat.com> Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net')
-rw-r--r--net/mptcp/options.c2
-rw-r--r--net/mptcp/protocol.h2
-rw-r--r--net/mptcp/subflow.c3
3 files changed, 3 insertions, 4 deletions
diff --git a/net/mptcp/options.c b/net/mptcp/options.c
index 8f940be42f98..77d46cc8165b 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 c6eeaf3e8dcb..4675a7bbebb1 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 3838a0b3a21f..2e145b53b81f 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 */