On Mon, 2021-02-15 at 16:36 +0100, Florian Westphal wrote: > mptcp re-used inet(6)_release, so the subflow sockets are ignored. > Need to invoke ip(v6)_mc_drop_socket function to ensure mcast join > resources get free'd. > > Fixes: 717e79c867ca5 ("mptcp: Add setsockopt()/getsockopt() socket operations") > Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/110 > Signed-off-by: Florian Westphal > --- > net/mptcp/protocol.c | 55 ++++++++++++++++++++++++++++++++++++++++++-- > 1 file changed, 53 insertions(+), 2 deletions(-) > > diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c > index 19faa43be2f8..d811f60a867b 100644 > --- a/net/mptcp/protocol.c > +++ b/net/mptcp/protocol.c > @@ -11,6 +11,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -19,6 +20,7 @@ > #include > #if IS_ENABLED(CONFIG_MPTCP_IPV6) > #include > +#include > #endif > #include > #include > @@ -3388,10 +3390,34 @@ static __poll_t mptcp_poll(struct file *file, struct socket *sock, > return mask; > } > > +static int mptcp_release(struct socket *sock) > +{ > + struct mptcp_subflow_context *subflow; > + struct sock *sk = sock->sk; > + struct mptcp_sock *msk; > + > + if (!sk) > + return 0; > + > + lock_sock(sk); > + > + msk = mptcp_sk(sk); > + > + mptcp_for_each_subflow(msk, subflow) { > + struct sock *ssk = mptcp_subflow_tcp_sock(subflow); > + > + ip_mc_drop_socket(ssk); > + } > + > + release_sock(sk); > + > + return inet_release(sock); > +} > + > static const struct proto_ops mptcp_stream_ops = { > .family = PF_INET, > .owner = THIS_MODULE, > - .release = inet_release, > + .release = mptcp_release, > .bind = mptcp_bind, > .connect = mptcp_stream_connect, > .socketpair = sock_no_socketpair, > @@ -3489,10 +3515,35 @@ void __init mptcp_proto_init(void) > } > > #if IS_ENABLED(CONFIG_MPTCP_IPV6) > +static int mptcp6_release(struct socket *sock) > +{ > + struct mptcp_subflow_context *subflow; > + struct mptcp_sock *msk; > + struct sock *sk = sock->sk; > + > + if (!sk) > + return 0; > + > + lock_sock(sk); > + > + msk = mptcp_sk(sk); > + > + mptcp_for_each_subflow(msk, subflow) { > + struct sock *ssk = mptcp_subflow_tcp_sock(subflow); > + > + ip_mc_drop_socket(ssk); > + ipv6_sock_mc_close(ssk); > + ipv6_sock_ac_close(ssk); > + } > + > + release_sock(sk); > + return inet6_release(sock); > +} > + > static const struct proto_ops mptcp_v6_stream_ops = { > .family = PF_INET6, > .owner = THIS_MODULE, > - .release = inet6_release, > + .release = mptcp6_release, > .bind = mptcp_bind, > .connect = mptcp_stream_connect, > .socketpair = sock_no_socketpair, Nice, LGTM. Thanks Florian! /P