aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPaolo Abeni <pabeni@redhat.com>2020-11-19 11:45:55 -0800
committerJakub Kicinski <kuba@kernel.org>2020-11-20 15:33:24 -0800
commit26aa231439fef49f11284ea9d9245e074d69197a (patch)
tree978dfbd94a562c04b1fb1ccf7e7179bf2f887a22 /net
parentmptcp: drop WORKER_RUNNING status bit (diff)
downloadlinux-dev-26aa231439fef49f11284ea9d9245e074d69197a.tar.xz
linux-dev-26aa231439fef49f11284ea9d9245e074d69197a.zip
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')
-rw-r--r--net/mptcp/protocol.c18
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);