mptcp: fix state tracking for fallback socket
authorPaolo Abeni <pabeni@redhat.com>
Thu, 19 Nov 2020 19:45:55 +0000 (11:45 -0800)
committerJakub Kicinski <kuba@kernel.org>
Fri, 20 Nov 2020 23:33:24 +0000 (15:33 -0800)
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>
net/mptcp/protocol.c

index 1aaf58c59f41f6be152fc674ad971b0614487f91..2d450865937d5336984d33eadfc5472bde0801d3 100644 (file)
@@ -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);