From mboxrd@z Thu Jan 1 00:00:00 1970 From: Andre Naujoks Subject: Re: [RFC/PATCH] Add a socketoption IPV6_MULTICAST_ALL analogue to the IPV4 version Date: Tue, 8 May 2018 08:03:35 +0200 Message-ID: <45accb95-f712-1758-774d-c729727b89db@gmail.com> References: Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit To: "David S. Miller" , netdev@vger.kernel.org Return-path: Received: from mail-wm0-f65.google.com ([74.125.82.65]:35490 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752854AbeEHGDi (ORCPT ); Tue, 8 May 2018 02:03:38 -0400 Received: by mail-wm0-f65.google.com with SMTP id o78-v6so19255476wmg.0 for ; Mon, 07 May 2018 23:03:37 -0700 (PDT) In-Reply-To: Content-Language: en-US Sender: netdev-owner@vger.kernel.org List-ID: On 11.04.2018 13:02, Andre Naujoks wrote: > Hi. Hi again. Since it has been a month now, I'd like to send a little "ping" on this subject. Is anything wrong with this? Or was it just bad timing? Regards Andre > > I was running into a problem, when trying to join multiple multicast groups > on a single socket and thus binding to the any-address on said socket. I > received traffic from multicast groups, I did not join on that socket and > was at first surprised by that. After reading some old e-mails/threads, > which came to the conclusion "It is, as it is." > (e.g https://marc.info/?l=linux-kernel&m=115815686626791&w=2), I discovered > the IPv4 socketoption IP_MULTICAST_ALL, which, when disabled, does exactly > what I would expect from a socket by default. > > I propose a socket option for IPv6, which does the same and has the same > default as the IPv4 version. My first thought was, to just apply > IP_MULTICAST_ALL to a ipv6 socket, but that would change the behavior of > current applications and would probably be a big no-no. > > Regards > Andre > > > From 473653086c05a3de839c3504885053f6254c7bc5 Mon Sep 17 00:00:00 2001 > From: Andre Naujoks > Date: Wed, 11 Apr 2018 12:38:28 +0200 > Subject: [PATCH] Add a socketoption IPV6_MULTICAST_ALL analogue to the IPV4 > version > > The socket option will be enabled by default to ensure current behaviour > is not changed. This is the same for the IPv4 version. > > A socket bound to in6addr_any and a specific port will receive all traffic > on that port. Analogue to IP_MULTICAST_ALL, disable this behaviour, if > one or more multicast groups were joined (using said socket) and only > pass on multicast traffic from groups, which were explicitly joined via > this socket. > > Without this option disabled a socket (system even) joined to multiple > multicast groups is very hard to get right. Filtering by destination > address has to take place in user space to avoid receiving multicast > traffic from other multicast groups, which might have traffic on the same > port. > > The extension of the IP_MULTICAST_ALL socketoption to just apply to ipv6, > too, is not done to avoid changing the behaviour of current applications. > > Signed-off-by: Andre Naujoks > --- > include/linux/ipv6.h | 3 ++- > include/uapi/linux/in6.h | 1 + > net/ipv6/af_inet6.c | 1 + > net/ipv6/ipv6_sockglue.c | 11 +++++++++++ > net/ipv6/mcast.c | 2 +- > 5 files changed, 16 insertions(+), 2 deletions(-) > > diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h > index 8415bf1a9776..495e834c1367 100644 > --- a/include/linux/ipv6.h > +++ b/include/linux/ipv6.h > @@ -274,7 +274,8 @@ struct ipv6_pinfo { > */ > dontfrag:1, > autoflowlabel:1, > - autoflowlabel_set:1; > + autoflowlabel_set:1, > + mc_all:1; > __u8 min_hopcount; > __u8 tclass; > __be32 rcv_flowinfo; > diff --git a/include/uapi/linux/in6.h b/include/uapi/linux/in6.h > index ed291e55f024..71d82fe15b03 100644 > --- a/include/uapi/linux/in6.h > +++ b/include/uapi/linux/in6.h > @@ -177,6 +177,7 @@ struct in6_flowlabel_req { > #define IPV6_V6ONLY 26 > #define IPV6_JOIN_ANYCAST 27 > #define IPV6_LEAVE_ANYCAST 28 > +#define IPV6_MULTICAST_ALL 29 > > /* IPV6_MTU_DISCOVER values */ > #define IPV6_PMTUDISC_DONT 0 > diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c > index 8da0b513f188..7844cd9d2f10 100644 > --- a/net/ipv6/af_inet6.c > +++ b/net/ipv6/af_inet6.c > @@ -209,6 +209,7 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol, > np->hop_limit = -1; > np->mcast_hops = IPV6_DEFAULT_MCASTHOPS; > np->mc_loop = 1; > + np->mc_all = 1; > np->pmtudisc = IPV6_PMTUDISC_WANT; > np->repflow = net->ipv6.sysctl.flowlabel_reflect; > sk->sk_ipv6only = net->ipv6.sysctl.bindv6only; > diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c > index 4d780c7f0130..b2bc1942a2ee 100644 > --- a/net/ipv6/ipv6_sockglue.c > +++ b/net/ipv6/ipv6_sockglue.c > @@ -664,6 +664,13 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, > retv = ipv6_sock_ac_drop(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_acaddr); > break; > } > + case IPV6_MULTICAST_ALL: > + if (optlen < sizeof(int)) > + goto e_inval; > + np->mc_all = valbool; > + retv = 0; > + break; > + > case MCAST_JOIN_GROUP: > case MCAST_LEAVE_GROUP: > { > @@ -1255,6 +1262,10 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, > val = np->mcast_oif; > break; > > + case IPV6_MULTICAST_ALL: > + val = np->mc_all; > + break; > + > case IPV6_UNICAST_IF: > val = (__force int)htonl((__u32) np->ucast_oif); > break; > diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c > index 793159d77d8a..623ad00eb3c2 100644 > --- a/net/ipv6/mcast.c > +++ b/net/ipv6/mcast.c > @@ -622,7 +622,7 @@ bool inet6_mc_check(struct sock *sk, const struct in6_addr *mc_addr, > } > if (!mc) { > rcu_read_unlock(); > - return true; > + return np->mc_all; > } > read_lock(&mc->sflock); > psl = mc->sflist; >