summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/mptcp/protocol.c1
-rw-r--r--net/mptcp/subflow.c25
2 files changed, 25 insertions, 1 deletions
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 9936e33ac351..1c8b021b4537 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -1431,6 +1431,7 @@ static struct sock *mptcp_accept(struct sock *sk, int flags, int *err,
newsk = new_mptcp_sock;
mptcp_copy_inaddrs(newsk, ssk);
list_add(&subflow->node, &msk->conn_list);
+ inet_sk_state_store(newsk, TCP_ESTABLISHED);
bh_unlock_sock(new_mptcp_sock);
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index 50a8bea987c6..57a836fe4988 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -347,6 +347,29 @@ static bool subflow_hmac_valid(const struct request_sock *req,
return ret;
}
+static void mptcp_sock_destruct(struct sock *sk)
+{
+ /* if new mptcp socket isn't accepted, it is free'd
+ * from the tcp listener sockets request queue, linked
+ * from req->sk. The tcp socket is released.
+ * This calls the ULP release function which will
+ * also remove the mptcp socket, via
+ * sock_put(ctx->conn).
+ *
+ * Problem is that the mptcp socket will not be in
+ * SYN_RECV state and doesn't have SOCK_DEAD flag.
+ * Both result in warnings from inet_sock_destruct.
+ */
+
+ if (sk->sk_state == TCP_SYN_RECV) {
+ sk->sk_state = TCP_CLOSE;
+ WARN_ON_ONCE(sk->sk_socket);
+ sock_orphan(sk);
+ }
+
+ inet_sock_destruct(sk);
+}
+
static struct sock *subflow_syn_recv_sock(const struct sock *sk,
struct sk_buff *skb,
struct request_sock *req,
@@ -422,7 +445,7 @@ create_child:
/* new mpc subflow takes ownership of the newly
* created mptcp socket
*/
- inet_sk_state_store(new_msk, TCP_ESTABLISHED);
+ new_msk->sk_destruct = mptcp_sock_destruct;
mptcp_pm_new_connection(mptcp_sk(new_msk), 1);
ctx->conn = new_msk;
new_msk = NULL;