diff options
Diffstat (limited to 'target/linux/generic/patches-4.4/646-bridge_fix_ipv6_mc_snooping_if_bridge_has_no_ipv6_address.patch')
-rw-r--r-- | target/linux/generic/patches-4.4/646-bridge_fix_ipv6_mc_snooping_if_bridge_has_no_ipv6_address.patch | 113 |
1 files changed, 0 insertions, 113 deletions
diff --git a/target/linux/generic/patches-4.4/646-bridge_fix_ipv6_mc_snooping_if_bridge_has_no_ipv6_address.patch b/target/linux/generic/patches-4.4/646-bridge_fix_ipv6_mc_snooping_if_bridge_has_no_ipv6_address.patch deleted file mode 100644 index 4388cda6ef..0000000000 --- a/target/linux/generic/patches-4.4/646-bridge_fix_ipv6_mc_snooping_if_bridge_has_no_ipv6_address.patch +++ /dev/null @@ -1,113 +0,0 @@ -From: daniel <daniel@dd-wrt.com> -Date: Fri, 24 Jun 2016 12:35:18 +0200 -Subject: [PATCH] Bridge: Fix ipv6 mc snooping if bridge has no ipv6 address - -The bridge is falsly dropping ipv6 mulitcast packets if there is: - 1. No ipv6 address assigned on the brigde. - 2. No external mld querier present. - 3. The internal querier enabled. - -When the bridge fails to build mld queries, because it has no -ipv6 address, it slilently returns, but keeps the local querier enabled. -This specific case causes confusing packet loss. - -Ipv6 multicast snooping can only work if: - a) An external querier is present - OR - b) The bridge has an ipv6 address an is capable of sending own queries - -Otherwise it has to forward/flood the ipv6 multicast traffic, -because snooping cannot work. - -This patch fixes the issue by adding a flag to the bridge struct that -indicates that there is currently no ipv6 address assinged to the bridge -and returns a false state for the local querier in -__br_multicast_querier_exists(). - -Special thanks to Linus Lüssing. - -Fixes: d1d81d4c3dd8 ("bridge: check return value of ipv6_dev_get_saddr()") -Signed-off-by: Daniel Danzberger <daniel@dd-wrt.com> -Acked-by: Linus Lüssing <linus.luessing@c0d3.blue> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - net/bridge/br_multicast.c | 4 ++++ - net/bridge/br_private.h | 23 +++++++++++++++++++---- - 2 files changed, 23 insertions(+), 4 deletions(-) - -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index c8c2a8a..d063a10 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -465,8 +465,11 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br, - if (ipv6_dev_get_saddr(dev_net(br->dev), br->dev, &ip6h->daddr, 0, - &ip6h->saddr)) { - kfree_skb(skb); -+ br->has_ipv6_addr = 0; - return NULL; - } -+ -+ br->has_ipv6_addr = 1; - ipv6_eth_mc_map(&ip6h->daddr, eth->h_dest); - - hopopt = (u8 *)(ip6h + 1); -@@ -1768,6 +1771,7 @@ void br_multicast_init(struct net_bridge *br) - br->ip6_other_query.delay_time = 0; - br->ip6_querier.port = NULL; - #endif -+ br->has_ipv6_addr = 1; - - spin_lock_init(&br->multicast_lock); - setup_timer(&br->multicast_router_timer, -diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -index e24abfd..3dd7e2c 100644 ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -303,6 +303,7 @@ struct net_bridge - u8 multicast_disabled:1; - u8 multicast_querier:1; - u8 multicast_query_use_ifaddr:1; -+ u8 has_ipv6_addr:1; - - u32 hash_elasticity; - u32 hash_max; -@@ -577,10 +578,22 @@ static inline bool br_multicast_is_router(struct net_bridge *br) - - static inline bool - __br_multicast_querier_exists(struct net_bridge *br, -- struct bridge_mcast_other_query *querier) -+ struct bridge_mcast_other_query *querier, -+ const bool is_ipv6) - { -+ bool own_querier_enabled; -+ -+ if (br->multicast_querier) { -+ if (is_ipv6 && !br->has_ipv6_addr) -+ own_querier_enabled = false; -+ else -+ own_querier_enabled = true; -+ } else { -+ own_querier_enabled = false; -+ } -+ - return time_is_before_jiffies(querier->delay_time) && -- (br->multicast_querier || timer_pending(&querier->timer)); -+ (own_querier_enabled || timer_pending(&querier->timer)); - } - - static inline bool br_multicast_querier_exists(struct net_bridge *br, -@@ -588,10 +601,12 @@ static inline bool br_multicast_querier_exists(struct net_bridge *br, - { - switch (eth->h_proto) { - case (htons(ETH_P_IP)): -- return __br_multicast_querier_exists(br, &br->ip4_other_query); -+ return __br_multicast_querier_exists(br, -+ &br->ip4_other_query, false); - #if IS_ENABLED(CONFIG_IPV6) - case (htons(ETH_P_IPV6)): -- return __br_multicast_querier_exists(br, &br->ip6_other_query); -+ return __br_multicast_querier_exists(br, -+ &br->ip6_other_query, true); - #endif - default: - return false; |