Hi, 2018-05-08 15:41 GMT+09:00 Andre Naujoks <nauts...@gmail.com>: > On 08.05.2018 08:31, 吉藤英明 wrote: >> Hi, >> >> 2018-05-08 15:03 GMT+09:00 Andre Naujoks <nauts...@gmail.com>: >>> 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? >> >> I'm just curious... What kind of behaviour do you expect? >> >> Unless you explicitly join the group, you cannot get traffic for the group >> because of multicast filtering at device level (multicast fitlering) or at >> the >> switch level (MLD). >> >> If an application is interested in (several) multicast groups, it should >> explicitly join the group. So I cannot find valid (or meaningful) use-case. > > I expect only to receive the multicast traffic of groups I explicitly joined > on that > socket. This is was the IPv4 version of this socket option already does. The > problem > only exists if multiple groups are joined and the socket therefore has to be > bound > to the "any"-address. Then we get traffic from all multicast groups joined by > any(!) > process on the system (plus anything else on that IP-port).
Okay I agree that we should be able NOT to get such traffic. Acked-By: YOSHIFUJI Hideaki <yoshf...@linux-ipv6.org> --yoshfuji > > Regards > Andre > >> >> --yoshfuji >> >>> >>> 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 <nauts...@gmail.com> >>>> 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 <nauts...@gmail.com> >>>> --- >>>> 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; >>>> >>> >