Skip to content

Commit

Permalink
mptcp: Use 32-bit DATA_ACK when possible
Browse files Browse the repository at this point in the history
RFC8684 allows to send 32-bit DATA_ACKs as long as the peer is not
sending 64-bit data-sequence numbers. The 64-bit DSN is only there for
extreme scenarios when a very high throughput subflow is combined with a
long-RTT subflow such that the high-throughput subflow wraps around the
32-bit sequence number space within an RTT of the high-RTT subflow.

It is thus a rare scenario and we should try to use the 32-bit DATA_ACK
instead as long as possible. It allows to reduce the TCP-option overhead
by 4 bytes, thus makes space for an additional SACK-block. It also makes
tcpdumps much easier to read when the DSN and DATA_ACK are both either
32 or 64-bit.

Signed-off-by: Christoph Paasch <cpaasch@apple.com>
Reviewed-by: Matthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
cpaasch authored and davem330 committed May 16, 2020
1 parent 9efd6a3 commit a0c1d0e
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 10 deletions.
5 changes: 4 additions & 1 deletion include/net/mptcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ struct seq_file;

/* MPTCP sk_buff extension data */
struct mptcp_ext {
u64 data_ack;
union {
u64 data_ack;
u32 data_ack32;
};
u64 data_seq;
u32 subflow_seq;
u16 data_len;
Expand Down
33 changes: 24 additions & 9 deletions net/mptcp/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -516,18 +516,23 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb,
return ret;
}

ack_size = TCPOLEN_MPTCP_DSS_ACK64;
if (subflow->use_64bit_ack) {
ack_size = TCPOLEN_MPTCP_DSS_ACK64;
opts->ext_copy.data_ack = msk->ack_seq;
opts->ext_copy.ack64 = 1;
} else {
ack_size = TCPOLEN_MPTCP_DSS_ACK32;
opts->ext_copy.data_ack32 = (uint32_t)(msk->ack_seq);
opts->ext_copy.ack64 = 0;
}
opts->ext_copy.use_ack = 1;

/* Add kind/length/subtype/flag overhead if mapping is not populated */
if (dss_size == 0)
ack_size += TCPOLEN_MPTCP_DSS_BASE;

dss_size += ack_size;

opts->ext_copy.data_ack = msk->ack_seq;
opts->ext_copy.ack64 = 1;
opts->ext_copy.use_ack = 1;

*size = ALIGN(dss_size, 4);
return true;
}
Expand Down Expand Up @@ -986,8 +991,13 @@ void mptcp_write_options(__be32 *ptr, struct mptcp_out_options *opts)
u8 flags = 0;

if (mpext->use_ack) {
len += TCPOLEN_MPTCP_DSS_ACK64;
flags = MPTCP_DSS_HAS_ACK | MPTCP_DSS_ACK64;
flags = MPTCP_DSS_HAS_ACK;
if (mpext->ack64) {
len += TCPOLEN_MPTCP_DSS_ACK64;
flags |= MPTCP_DSS_ACK64;
} else {
len += TCPOLEN_MPTCP_DSS_ACK32;
}
}

if (mpext->use_map) {
Expand All @@ -1004,8 +1014,13 @@ void mptcp_write_options(__be32 *ptr, struct mptcp_out_options *opts)
*ptr++ = mptcp_option(MPTCPOPT_DSS, len, 0, flags);

if (mpext->use_ack) {
put_unaligned_be64(mpext->data_ack, ptr);
ptr += 2;
if (mpext->ack64) {
put_unaligned_be64(mpext->data_ack, ptr);
ptr += 2;
} else {
put_unaligned_be32(mpext->data_ack32, ptr);
ptr += 1;
}
}

if (mpext->use_map) {
Expand Down
1 change: 1 addition & 0 deletions net/mptcp/protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ 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;
Expand Down
2 changes: 2 additions & 0 deletions net/mptcp/subflow.c
Original file line number Diff line number Diff line change
Expand Up @@ -667,9 +667,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;
}

if (subflow->map_valid) {
Expand Down

0 comments on commit a0c1d0e

Please sign in to comment.