[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAPA1RqCtkYE8is=kbANNGktgoiqKHZy+0wtE-spUwgq4V-_XTw@mail.gmail.com>
Date: Tue, 8 May 2018 20:48:08 +0900
From: 吉藤英明 <hideaki.yoshifuji@...aclelinux.com>
To: Andre Naujoks <nautsch2@...il.com>
Cc: "David S. Miller" <davem@...emloft.net>, netdev@...r.kernel.org,
yoshfuji@...ux-ipv6.org
Subject: Re: [RFC/PATCH] Add a socketoption IPV6_MULTICAST_ALL analogue to the
IPV4 version
Hi,
2018-05-08 15:41 GMT+09:00 Andre Naujoks <nautsch2@...il.com>:
> On 08.05.2018 08:31, 吉藤英明 wrote:
>> Hi,
>>
>> 2018-05-08 15:03 GMT+09:00 Andre Naujoks <nautsch2@...il.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 <yoshfuji@...ux-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 <nautsch2@...il.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 <nautsch2@...il.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;
>>>>
>>>
>
Powered by blists - more mailing lists