diff options
author | Paolo Abeni <pabeni@redhat.com> | 2020-11-19 22:45:55 +0300 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2020-11-21 02:33:24 +0300 |
commit | 26aa231439fef49f11284ea9d9245e074d69197a (patch) | |
tree | 978dfbd94a562c04b1fb1ccf7e7179bf2f887a22 /net/mptcp/protocol.c | |
parent | b2771d2419fa6e978dec9ba6ccb93c5c76106374 (diff) | |
download | linux-26aa231439fef49f11284ea9d9245e074d69197a.tar.xz |
mptcp: fix state tracking for fallback socket
We need to cope with some more state transition for
fallback sockets, or could still end-up moving to TCP_CLOSE
too early and avoid spooling some pending data
Fixes: e16163b6e2b7 ("mptcp: refactor shutdown and close")
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/mptcp/protocol.c')
-rw-r--r-- | net/mptcp/protocol.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 1aaf58c59f41..2d450865937d 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -777,7 +777,9 @@ static void mptcp_check_for_eof(struct mptcp_sock *msk) inet_sk_state_store(sk, TCP_CLOSE_WAIT); break; case TCP_FIN_WAIT1: - /* fallback sockets skip TCP_CLOSING - TCP will take care */ + inet_sk_state_store(sk, TCP_CLOSING); + break; + case TCP_FIN_WAIT2: inet_sk_state_store(sk, TCP_CLOSE); break; default: @@ -2086,10 +2088,16 @@ static void __mptcp_check_send_data_fin(struct sock *sk) WRITE_ONCE(msk->snd_nxt, msk->write_seq); - /* fallback socket will not get data_fin/ack, can move to close now */ - if (__mptcp_check_fallback(msk) && sk->sk_state == TCP_LAST_ACK) { - inet_sk_state_store(sk, TCP_CLOSE); - mptcp_close_wake_up(sk); + /* fallback socket will not get data_fin/ack, can move to the next + * state now + */ + if (__mptcp_check_fallback(msk)) { + if ((1 << sk->sk_state) & (TCPF_CLOSING | TCPF_LAST_ACK)) { + inet_sk_state_store(sk, TCP_CLOSE); + mptcp_close_wake_up(sk); + } else if (sk->sk_state == TCP_FIN_WAIT1) { + inet_sk_state_store(sk, TCP_FIN_WAIT2); + } } __mptcp_flush_join_list(msk); |