diff options
author | Mat Martineau <mathew.j.martineau@linux.intel.com> | 2020-01-09 16:59:22 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2020-01-10 03:41:41 +0100 |
commit | 9cfcca2389d7e07647ee69950f46ab5e6dfe03ac (patch) | |
tree | 88600218e9477c870620645b827b44814235e3aa /net/ipv4/tcp_output.c | |
parent | tcp: Export TCP functions and ops struct (diff) | |
download | linux-9cfcca2389d7e07647ee69950f46ab5e6dfe03ac.tar.xz linux-9cfcca2389d7e07647ee69950f46ab5e6dfe03ac.zip |
tcp: Check for filled TCP option space before SACK
Update the SACK check to work with zero option space available, a case
that's possible with MPTCP but not MD5+TS. Maintained only one
conditional branch for insufficient SACK space.
v1 -> v2:
- Moves the check inside the SACK branch by taking recent SACK fix:
9424e2e7ad93 (tcp: md5: fix potential overestimation of TCP option space)
in to account, but modifies it to work in MPTCP scenarios beyond the
MD5+TS corner case.
Co-developed-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_output.c')
-rw-r--r-- | net/ipv4/tcp_output.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 3ce7fe1c4076..05109d0c675b 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -754,13 +754,17 @@ static unsigned int tcp_established_options(struct sock *sk, struct sk_buff *skb eff_sacks = tp->rx_opt.num_sacks + tp->rx_opt.dsack; if (unlikely(eff_sacks)) { const unsigned int remaining = MAX_TCP_OPTION_SPACE - size; + if (unlikely(remaining < TCPOLEN_SACK_BASE_ALIGNED + + TCPOLEN_SACK_PERBLOCK)) + return size; + opts->num_sack_blocks = min_t(unsigned int, eff_sacks, (remaining - TCPOLEN_SACK_BASE_ALIGNED) / TCPOLEN_SACK_PERBLOCK); - if (likely(opts->num_sack_blocks)) - size += TCPOLEN_SACK_BASE_ALIGNED + - opts->num_sack_blocks * TCPOLEN_SACK_PERBLOCK; + + size += TCPOLEN_SACK_BASE_ALIGNED + + opts->num_sack_blocks * TCPOLEN_SACK_PERBLOCK; } return size; |