diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index c1b35ca952b4..62a2da0f2b54 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -2503,6 +2503,12 @@ out: void mptcp_close_ssk(struct sock *sk, struct sock *ssk, struct mptcp_subflow_context *subflow) { + /* The first subflow can already be closed and still in the list */ + if (subflow->close_event_done) + return; + + subflow->close_event_done = true; + if (sk->sk_state == TCP_ESTABLISHED) mptcp_event(MPTCP_EVENT_SUB_CLOSED, mptcp_sk(sk), ssk, GFP_KERNEL); diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 9a367405c1e0..ee3974b10ef0 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -479,7 +479,9 @@ struct mptcp_subflow_context { can_ack : 1, /* only after processing the remote a key */ disposable : 1, /* ctx can be free at ulp release time */ stale : 1, /* unable to snd/rcv data, do not use for xmit */ - valid_csum_seen : 1; /* at least one csum validated */ + valid_csum_seen : 1, /* at least one csum validated */ + close_event_done : 1, /* has done the post-closed part */ + __unused : 9; enum mptcp_data_avail data_avail; u32 remote_nonce; u64 thmac;