mptcp: add the fallback check
authorGeliang Tang <geliang.tang@suse.com>
Fri, 22 Apr 2022 21:55:37 +0000 (14:55 -0700)
committerDavid S. Miller <davem@davemloft.net>
Sat, 23 Apr 2022 10:51:05 +0000 (11:51 +0100)
This patch adds the fallback check in subflow_check_data_avail(). Only
do the fallback when the msk hasn't fallen back yet.

Suggested-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Geliang Tang <geliang.tang@suse.com>
Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/mptcp/subflow.c

index f217926..7f26a5b 100644 (file)
@@ -1203,35 +1203,38 @@ no_data:
        return false;
 
 fallback:
-       /* RFC 8684 section 3.7. */
-       if (subflow->send_mp_fail) {
-               if (mptcp_has_another_subflow(ssk)) {
+       if (!__mptcp_check_fallback(msk)) {
+               /* RFC 8684 section 3.7. */
+               if (subflow->send_mp_fail) {
+                       if (mptcp_has_another_subflow(ssk)) {
+                               ssk->sk_err = EBADMSG;
+                               tcp_set_state(ssk, TCP_CLOSE);
+                               subflow->reset_transient = 0;
+                               subflow->reset_reason = MPTCP_RST_EMIDDLEBOX;
+                               tcp_send_active_reset(ssk, GFP_ATOMIC);
+                               while ((skb = skb_peek(&ssk->sk_receive_queue)))
+                                       sk_eat_skb(ssk, skb);
+                       }
+                       WRITE_ONCE(subflow->data_avail, MPTCP_SUBFLOW_NODATA);
+                       return true;
+               }
+
+               if (subflow->mp_join || subflow->fully_established) {
+                       /* fatal protocol error, close the socket.
+                        * subflow_error_report() will introduce the appropriate barriers
+                        */
                        ssk->sk_err = EBADMSG;
                        tcp_set_state(ssk, TCP_CLOSE);
                        subflow->reset_transient = 0;
-                       subflow->reset_reason = MPTCP_RST_EMIDDLEBOX;
+                       subflow->reset_reason = MPTCP_RST_EMPTCP;
                        tcp_send_active_reset(ssk, GFP_ATOMIC);
-                       while ((skb = skb_peek(&ssk->sk_receive_queue)))
-                               sk_eat_skb(ssk, skb);
+                       WRITE_ONCE(subflow->data_avail, MPTCP_SUBFLOW_NODATA);
+                       return false;
                }
-               WRITE_ONCE(subflow->data_avail, MPTCP_SUBFLOW_NODATA);
-               return true;
-       }
 
-       if (subflow->mp_join || subflow->fully_established) {
-               /* fatal protocol error, close the socket.
-                * subflow_error_report() will introduce the appropriate barriers
-                */
-               ssk->sk_err = EBADMSG;
-               tcp_set_state(ssk, TCP_CLOSE);
-               subflow->reset_transient = 0;
-               subflow->reset_reason = MPTCP_RST_EMPTCP;
-               tcp_send_active_reset(ssk, GFP_ATOMIC);
-               WRITE_ONCE(subflow->data_avail, MPTCP_SUBFLOW_NODATA);
-               return false;
+               __mptcp_do_fallback(msk);
        }
 
-       __mptcp_do_fallback(msk);
        skb = skb_peek(&ssk->sk_receive_queue);
        subflow->map_valid = 1;
        subflow->map_seq = READ_ONCE(msk->ack_seq);