1 From e395d7de168305f53547cc28981aa9587bda8c87 Mon Sep 17 00:00:00 2001
2 From: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
3 Date: Wed, 3 Apr 2019 23:27:24 +0300
4 Subject: net: bridge: always clear mcast matching struct on reports and leaves
6 [ Upstream commit 1515a63fc413f160d20574ab0894e7f1020c7be2 ]
8 We need to be careful and always zero the whole br_ip struct when it is
9 used for matching since the rhashtable change. This patch fixes all the
10 places which didn't properly clear it which in turn might've caused
13 Thanks for the great bug report with reproducing steps and bisection.
15 Steps to reproduce (from the bug report):
16 ip link add br0 type bridge mcast_querier 1
19 ip link add v2 type veth peer name v3
20 ip link set v2 master br0
23 ip addr add 3.0.0.2/24 dev v3
26 ip link add v1 type veth peer name v1 netns test
27 ip link set v1 master br0
29 ip -n test link set v1 up
30 ip -n test addr add 3.0.0.1/24 dev v1
33 ip netns exec test socat
34 UDP4-RECVFROM:5588,ip-add-membership=224.224.224.224:3.0.0.1,fork -
37 echo hello | nc -u -s 3.0.0.2 224.224.224.224 5588
39 Reported-by: liam.mcbirnie@boeing.com
40 Fixes: 19e3a9c90c53 ("net: bridge: convert multicast to generic rhashtable")
41 Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
42 Signed-off-by: David S. Miller <davem@davemloft.net>
43 Signed-off-by: Sasha Levin <sashal@kernel.org>
45 net/bridge/br_multicast.c | 3 +++
46 1 file changed, 3 insertions(+)
48 diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
49 index ac92b2eb32b1..e4777614a8a0 100644
50 --- a/net/bridge/br_multicast.c
51 +++ b/net/bridge/br_multicast.c
52 @@ -599,6 +599,7 @@ static int br_ip4_multicast_add_group(struct net_bridge *br,
53 if (ipv4_is_local_multicast(group))
56 + memset(&br_group, 0, sizeof(br_group));
57 br_group.u.ip4 = group;
58 br_group.proto = htons(ETH_P_IP);
60 @@ -1489,6 +1490,7 @@ static void br_ip4_multicast_leave_group(struct net_bridge *br,
62 own_query = port ? &port->ip4_own_query : &br->ip4_own_query;
64 + memset(&br_group, 0, sizeof(br_group));
65 br_group.u.ip4 = group;
66 br_group.proto = htons(ETH_P_IP);
68 @@ -1512,6 +1514,7 @@ static void br_ip6_multicast_leave_group(struct net_bridge *br,
70 own_query = port ? &port->ip6_own_query : &br->ip6_own_query;
72 + memset(&br_group, 0, sizeof(br_group));
73 br_group.u.ip6 = *group;
74 br_group.proto = htons(ETH_P_IPV6);