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