Merge branch 'mptcp-fixes'
Florian Westphal says: ==================== mptcp: fix 'attempt to release socket in state...' splats These two patches fix error handling corner-cases where inet_sock_destruct gets called for a mptcp_sk that is not in TCP_CLOSE state. This results in unwanted error printks from the network stack. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Коммит
56e639e6a2
|
@ -1355,12 +1355,15 @@ struct sock *mptcp_sk_clone(const struct sock *sk, struct request_sock *req)
|
|||
msk->subflow = NULL;
|
||||
|
||||
if (unlikely(mptcp_token_new_accept(subflow_req->token, nsk))) {
|
||||
nsk->sk_state = TCP_CLOSE;
|
||||
bh_unlock_sock(nsk);
|
||||
|
||||
/* we can't call into mptcp_close() here - possible BH context
|
||||
* free the sock directly
|
||||
* free the sock directly.
|
||||
* sk_clone_lock() sets nsk refcnt to two, hence call sk_free()
|
||||
* too.
|
||||
*/
|
||||
nsk->sk_prot->destroy(nsk);
|
||||
sk_common_release(nsk);
|
||||
sk_free(nsk);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1431,6 +1434,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);
|
||||
|
||||
|
|
|
@ -347,6 +347,35 @@ 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 void mptcp_force_close(struct sock *sk)
|
||||
{
|
||||
inet_sk_state_store(sk, TCP_CLOSE);
|
||||
sk_common_release(sk);
|
||||
}
|
||||
|
||||
static struct sock *subflow_syn_recv_sock(const struct sock *sk,
|
||||
struct sk_buff *skb,
|
||||
struct request_sock *req,
|
||||
|
@ -422,7 +451,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;
|
||||
|
@ -444,7 +473,7 @@ create_child:
|
|||
out:
|
||||
/* dispose of the left over mptcp master, if any */
|
||||
if (unlikely(new_msk))
|
||||
sock_put(new_msk);
|
||||
mptcp_force_close(new_msk);
|
||||
return child;
|
||||
|
||||
close_child:
|
||||
|
|
Загрузка…
Ссылка в новой задаче