[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <45accb95-f712-1758-774d-c729727b89db@gmail.com>
Date: Tue, 8 May 2018 08:03:35 +0200
From: Andre Naujoks <nautsch2@...il.com>
To: "David S. Miller" <davem@...emloft.net>, netdev@...r.kernel.org
Subject: Re: [RFC/PATCH] Add a socketoption IPV6_MULTICAST_ALL analogue to the
IPV4 version
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 <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