rpcd: iwinfo plugin fixes
[openwrt.git] / target / linux / generic / patches-4.1 / 645-bridge_multicast_to_unicast.patch
index 6915599..1361b92 100644 (file)
@@ -1,3 +1,8 @@
+From: Felix Fietkau <nbd@nbd.name>
+Subject: [PATCH] bridge: multicast to unicast
+
+Implement optinal multicast->unicast conversion for igmp snooping
+---
 --- a/include/linux/if_bridge.h
 +++ b/include/linux/if_bridge.h
 @@ -46,6 +46,7 @@ struct br_ip_list {
        rcu_assign_pointer(*pp, p);
 --- a/net/bridge/br_forward.c
 +++ b/net/bridge/br_forward.c
-@@ -169,6 +169,29 @@ out:
+@@ -170,6 +170,34 @@ out:
        return p;
  }
  
 +                            struct sk_buff *skb))
 +{
 +      struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev;
++      const unsigned char *src = eth_hdr(skb)->h_source;
 +
 +      if (!should_deliver(p, skb))
 +              return prev;
 +
++      /* Even with hairpin, no soliloquies - prevent breaking IPv6 DAD */
++      if (skb->dev == p->dev && ether_addr_equal(src, addr))
++              return prev;
++
 +      skb = skb_copy(skb, GFP_ATOMIC);
 +      if (!skb) {
 +              dev->stats.tx_dropped++;
  /* called under bridge lock */
  static void br_flood(struct net_bridge *br, struct sk_buff *skb,
                     struct sk_buff *skb0,
-@@ -241,6 +264,7 @@ static void br_multicast_flood(struct ne
+@@ -242,6 +270,7 @@ static void br_multicast_flood(struct ne
        struct net_bridge_port *prev = NULL;
        struct net_bridge_port_group *p;
        struct hlist_node *rp;
  
        rp = rcu_dereference(hlist_first_rcu(&br->router_list));
        p = mdst ? rcu_dereference(mdst->ports) : NULL;
-@@ -251,10 +275,19 @@ static void br_multicast_flood(struct ne
+@@ -252,10 +281,19 @@ static void br_multicast_flood(struct ne
                rport = rp ? hlist_entry(rp, struct net_bridge_port, rlist) :
                             NULL;