diff --git a/include/net/mptcp.h b/include/net/mptcp.h index 3cf0c0697ed4c..be64aed19ae7a 100644 --- a/include/net/mptcp.h +++ b/include/net/mptcp.h @@ -844,7 +844,7 @@ unsigned int mptcp_xmit_size_goal(const struct sock *meta_sk, u32 mss_now, int mptcp_init_tw_sock(struct sock *sk, struct tcp_timewait_sock *tw); void mptcp_twsk_destructor(struct tcp_timewait_sock *tw); void mptcp_time_wait(struct sock *sk, int state, int timeo); -void mptcp_disconnect(struct sock *sk); +void mptcp_disconnect(struct sock *meta_sk); bool mptcp_should_expand_sndbuf(const struct sock *sk); int mptcp_retransmit_skb(struct sock *meta_sk, struct sk_buff *skb); void mptcp_tsq_flags(struct sock *sk); @@ -1458,7 +1458,7 @@ static inline int mptcp_init_tw_sock(struct sock *sk, return 0; } static inline void mptcp_twsk_destructor(struct tcp_timewait_sock *tw) {} -static inline void mptcp_disconnect(struct sock *sk) {} +static inline void mptcp_disconnect(struct sock *meta_sk) {} static inline void mptcp_tsq_flags(struct sock *sk) {} static inline void mptcp_tsq_sub_deferred(struct sock *meta_sk) {} static inline void mptcp_hash_remove_bh(struct tcp_sock *meta_tp) {} diff --git a/net/mptcp/mptcp_ctrl.c b/net/mptcp/mptcp_ctrl.c index d0f380f7fb663..01be5e4720cb3 100644 --- a/net/mptcp/mptcp_ctrl.c +++ b/net/mptcp/mptcp_ctrl.c @@ -1619,13 +1619,6 @@ static void mptcp_sub_close_doit(struct sock *sk) if (sock_flag(sk, SOCK_DEAD)) return; - /* We come from tcp_disconnect. We are sure that meta_sk is set */ - if (!mptcp(tp)) { - tp->closing = 1; - tcp_close(sk, 0); - return; - } - if (meta_sk->sk_shutdown == SHUTDOWN_MASK || sk->sk_state == TCP_CLOSE) { tp->closing = 1; tcp_close(sk, 0); @@ -1933,47 +1926,34 @@ void mptcp_close(struct sock *meta_sk, long timeout) sock_put(meta_sk); /* Taken by sock_hold */ } -void mptcp_disconnect(struct sock *sk) +void mptcp_disconnect(struct sock *meta_sk) { + struct tcp_sock *meta_tp = tcp_sk(meta_sk); struct mptcp_tcp_sock *mptcp; - struct tcp_sock *tp = tcp_sk(sk); struct hlist_node *tmp; - __skb_queue_purge(&tp->mpcb->reinject_queue); + __skb_queue_purge(&meta_tp->mpcb->reinject_queue); - if (tp->inside_tk_table) - mptcp_hash_remove_bh(tp); + if (meta_tp->inside_tk_table) + mptcp_hash_remove_bh(meta_tp); local_bh_disable(); - mptcp_for_each_sub_safe(tp->mpcb, mptcp, tmp) { + mptcp_for_each_sub_safe(meta_tp->mpcb, mptcp, tmp) { struct sock *subsk = mptcp_to_sock(mptcp); - /* The socket will get removed from the subsocket-list - * and made non-mptcp by setting mpc to 0. - * - * This is necessary, because tcp_disconnect assumes - * that the connection is completly dead afterwards. - * Thus we need to do a mptcp_del_sock. Due to this call - * we have to make it non-mptcp. - * - * We have to lock the socket, because we set mpc to 0. - * An incoming packet would take the subsocket's lock - * and go on into the receive-path. - * This would be a race. - */ + meta_sk->sk_prot->disconnect(subsk, O_NONBLOCK); + + sock_orphan(subsk); + + percpu_counter_inc(meta_sk->sk_prot->orphan_count); - bh_lock_sock(subsk); - mptcp_del_sock(subsk); - tcp_sk(subsk)->mpc = 0; - tcp_sk(subsk)->ops = &tcp_specific; - mptcp_sub_force_close(subsk); - bh_unlock_sock(subsk); + inet_csk_destroy_sock(subsk); } local_bh_enable(); - tp->was_meta_sk = 1; - tp->mpc = 0; - tp->ops = &tcp_specific; + meta_tp->was_meta_sk = 1; + meta_tp->mpc = 0; + meta_tp->ops = &tcp_specific; }