From: Peter Krystad <peter.krys...@linux.intel.com>

Call shutdown on all subflows in use on the given socket, or on the
fallback socket.

Signed-off-by: Peter Krystad <peter.krys...@linux.intel.com>
---
 net/mptcp/protocol.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 0a9c447db159..dba4d7a4a61a 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -431,6 +431,37 @@ static __poll_t mptcp_poll(struct file *file, struct 
socket *sock,
        return ret;
 }
 
+static int mptcp_shutdown(struct socket *sock, int how)
+{
+       struct mptcp_sock *msk = mptcp_sk(sock->sk);
+       struct mptcp_subflow_context *subflow;
+       struct socket *ssock;
+       int ret = 0;
+
+       pr_debug("sk=%p, how=%d", msk, how);
+
+       lock_sock(sock->sk);
+       ssock = __mptcp_fallback_get_ref(msk);
+       if (ssock) {
+               release_sock(sock->sk);
+               pr_debug("subflow=%p", ssock->sk);
+               ret = kernel_sock_shutdown(ssock, how);
+               sock_put(ssock->sk);
+               return ret;
+       }
+
+       mptcp_for_each_subflow(msk, subflow) {
+               struct socket *tcp_socket;
+
+               tcp_socket = mptcp_subflow_tcp_socket(subflow);
+               pr_debug("conn_list->subflow=%p", subflow);
+               ret = kernel_sock_shutdown(tcp_socket, how);
+       }
+       release_sock(sock->sk);
+
+       return ret;
+}
+
 static struct proto_ops mptcp_stream_ops;
 
 static struct inet_protosw mptcp_protosw = {
@@ -451,6 +482,7 @@ void __init mptcp_init(void)
        mptcp_stream_ops.accept = mptcp_stream_accept;
        mptcp_stream_ops.getname = mptcp_getname;
        mptcp_stream_ops.listen = mptcp_listen;
+       mptcp_stream_ops.shutdown = mptcp_shutdown;
 
        mptcp_subflow_init();
 
-- 
2.23.0

Reply via email to