[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAJzqFtZW=kmebXZAvkpkKv9jcvEeb5YrSjQ4odCXUnkHwnO0Rw@mail.gmail.com>
Date: Sat, 9 Dec 2017 12:32:46 -0800
From: Kevin Cernekee <cernekee@...omium.org>
To: Andrew Lunn <andrew@...n.ch>
Cc: netdev@...r.kernel.org
Subject: Re: Incorrect source IP address on IGMP membership report
On Sat, Dec 9, 2017 at 8:01 AM, Andrew Lunn <andrew@...n.ch> wrote:
> The choice of IP address for IGMP in Linux is 'interesting'. Try with
> multiple IP addresses on the interfaces, addresses with different
> scopes, etc. I've seen it reply to the querier using an address from
> a different subnet to the incoming request, etc.
>
> Part of it is an implementation problem. When the application did a
> join, it passed an IP address to identify the interface to perform the
> join on. That IP address would be an idle choice for IGMP for that
> group. However, the information gets discard once the interface has
> been determined.
Right, and even if an address is specified in struct ip_mreqn for an
IP_DROP_MEMBERSHIP call, that address is ignored (at least in my
testing).
> With a single IP address on a single interface, Linux IGMP probably
> works. Outside of that, expect oddness.
>
> In your particular case, it is a global scope address. You are allowed
> to use it on any interface. So it should not really trigger suspicious
> activity. However, the RFC about multicast suggests IGMP with an
> unexpected source address should be dropped. However, it is only a
> should, not a must, if i remember correctly.
Hmm, RFC3376 says:
4.2.13. IP Source Addresses for Reports
An IGMP report is sent with a valid IP source address for the
destination subnet. The 0.0.0.0 source address may be used by a
system that has not yet acquired an IP address. Note that the
0.0.0.0 source address may simultaneously be used by multiple systems
on a LAN. Routers MUST accept a report with a source address of
0.0.0.0.
Would it make sense to add a special case that says "zero out
pip->saddr if the interface doesn't have any IPv4 addresses"? e.g.
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index d1f8f30..db02779 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -332,6 +332,10 @@ static struct sk_buff *igmpv3_newpack(struct
net_device *dev, unsigned int mtu)
int hlen = LL_RESERVED_SPACE(dev);
int tlen = dev->needed_tailroom;
unsigned int size = mtu;
+ struct in_device *in_dev = __in_dev_get_rcu(dev);
+
+ if (!in_dev)
+ return NULL;
while (1) {
skb = alloc_skb(size + hlen + tlen,
@@ -368,7 +372,7 @@ static struct sk_buff *igmpv3_newpack(struct
net_device *dev, unsigned int mtu)
pip->frag_off = htons(IP_DF);
pip->ttl = 1;
pip->daddr = fl4.daddr;
- pip->saddr = fl4.saddr;
+ pip->saddr = in_dev->ifa_list ? fl4.saddr : INADDR_ANY;
pip->protocol = IPPROTO_IGMP;
pip->tot_len = 0; /* filled in later */
ip_select_ident(net, skb, NULL);
Powered by blists - more mailing lists