ramips: fix cd-poll sd card remove randomly
[openwrt/openwrt.git] / target / linux / generic / patches-4.4 / 645-bridge_multicast_to_unicast.patch
index 7232b93de5f80506a253abd9a0eeb96f69d1e59b..f1c7ab1d9c9c60afe1a13e6ee59c152641374e77 100644 (file)
@@ -1,4 +1,4 @@
-From: Felix Fietkau <nbd@openwrt.org>
+From: Felix Fietkau <nbd@nbd.name>
 Subject: [PATCH] bridge: multicast to unicast
 
 Implement optinal multicast->unicast conversion for igmp snooping
@@ -31,7 +31,7 @@ Implement optinal multicast->unicast conversion for igmp snooping
  #endif
  unsigned int br_mdb_rehash_seq;
  
-@@ -649,7 +650,8 @@ struct net_bridge_port_group *br_multica
+@@ -652,7 +653,8 @@ struct net_bridge_port_group *br_multica
                        struct net_bridge_port *port,
                        struct br_ip *group,
                        struct net_bridge_port_group __rcu *next,
@@ -41,7 +41,7 @@ Implement optinal multicast->unicast conversion for igmp snooping
  {
        struct net_bridge_port_group *p;
  
-@@ -664,12 +666,33 @@ struct net_bridge_port_group *br_multica
+@@ -667,12 +669,33 @@ struct net_bridge_port_group *br_multica
        hlist_add_head(&p->mglist, &port->mglist);
        setup_timer(&p->timer, br_multicast_port_group_expired,
                    (unsigned long)p);
@@ -76,7 +76,7 @@ Implement optinal multicast->unicast conversion for igmp snooping
  {
        struct net_bridge_mdb_entry *mp;
        struct net_bridge_port_group *p;
-@@ -696,13 +719,13 @@ static int br_multicast_add_group(struct
+@@ -699,13 +722,13 @@ static int br_multicast_add_group(struct
        for (pp = &mp->ports;
             (p = mlock_dereference(*pp, br)) != NULL;
             pp = &p->next) {
@@ -92,7 +92,7 @@ Implement optinal multicast->unicast conversion for igmp snooping
        if (unlikely(!p))
                goto err;
        rcu_assign_pointer(*pp, p);
-@@ -721,7 +744,7 @@ err:
+@@ -724,7 +747,7 @@ err:
  static int br_ip4_multicast_add_group(struct net_bridge *br,
                                      struct net_bridge_port *port,
                                      __be32 group,
@@ -101,7 +101,7 @@ Implement optinal multicast->unicast conversion for igmp snooping
  {
        struct br_ip br_group;
  
-@@ -732,14 +755,14 @@ static int br_ip4_multicast_add_group(st
+@@ -735,14 +758,14 @@ static int br_ip4_multicast_add_group(st
        br_group.proto = htons(ETH_P_IP);
        br_group.vid = vid;
  
@@ -118,7 +118,7 @@ Implement optinal multicast->unicast conversion for igmp snooping
  {
        struct br_ip br_group;
  
-@@ -750,7 +773,7 @@ static int br_ip6_multicast_add_group(st
+@@ -753,7 +776,7 @@ static int br_ip6_multicast_add_group(st
        br_group.proto = htons(ETH_P_IPV6);
        br_group.vid = vid;
  
@@ -127,7 +127,7 @@ Implement optinal multicast->unicast conversion for igmp snooping
  }
  #endif
  
-@@ -995,6 +1018,7 @@ static int br_ip4_multicast_igmp3_report
+@@ -1003,6 +1026,7 @@ static int br_ip4_multicast_igmp3_report
                                         struct sk_buff *skb,
                                         u16 vid)
  {
@@ -135,7 +135,7 @@ Implement optinal multicast->unicast conversion for igmp snooping
        struct igmpv3_report *ih;
        struct igmpv3_grec *grec;
        int i;
-@@ -1035,12 +1059,13 @@ static int br_ip4_multicast_igmp3_report
+@@ -1043,12 +1067,13 @@ static int br_ip4_multicast_igmp3_report
                        continue;
                }
  
@@ -151,7 +151,7 @@ Implement optinal multicast->unicast conversion for igmp snooping
                        if (err)
                                break;
                }
-@@ -1055,6 +1080,7 @@ static int br_ip6_multicast_mld2_report(
+@@ -1063,6 +1088,7 @@ static int br_ip6_multicast_mld2_report(
                                        struct sk_buff *skb,
                                        u16 vid)
  {
@@ -159,7 +159,7 @@ Implement optinal multicast->unicast conversion for igmp snooping
        struct icmp6hdr *icmp6h;
        struct mld2_grec *grec;
        int i;
-@@ -1106,10 +1132,10 @@ static int br_ip6_multicast_mld2_report(
+@@ -1114,10 +1140,10 @@ static int br_ip6_multicast_mld2_report(
                     grec->grec_type == MLD2_MODE_IS_INCLUDE) &&
                    ntohs(*nsrcs) == 0) {
                        br_ip6_multicast_leave_group(br, port, &grec->grec_mca,
@@ -169,10 +169,10 @@ Implement optinal multicast->unicast conversion for igmp snooping
                        err = br_ip6_multicast_add_group(br, port,
 -                                                       &grec->grec_mca, vid);
 +                                                       &grec->grec_mca, vid, src);
-                       if (!err)
+                       if (err)
                                break;
                }
-@@ -1422,7 +1448,8 @@ br_multicast_leave_group(struct net_brid
+@@ -1432,7 +1458,8 @@ br_multicast_leave_group(struct net_brid
                         struct net_bridge_port *port,
                         struct br_ip *group,
                         struct bridge_mcast_other_query *other_query,
@@ -182,7 +182,7 @@ Implement optinal multicast->unicast conversion for igmp snooping
  {
        struct net_bridge_mdb_htable *mdb;
        struct net_bridge_mdb_entry *mp;
-@@ -1446,7 +1473,7 @@ br_multicast_leave_group(struct net_brid
+@@ -1456,7 +1483,7 @@ br_multicast_leave_group(struct net_brid
                for (pp = &mp->ports;
                     (p = mlock_dereference(*pp, br)) != NULL;
                     pp = &p->next) {
@@ -191,7 +191,7 @@ Implement optinal multicast->unicast conversion for igmp snooping
                                continue;
  
                        rcu_assign_pointer(*pp, p->next);
-@@ -1509,7 +1536,7 @@ br_multicast_leave_group(struct net_brid
+@@ -1519,7 +1546,7 @@ br_multicast_leave_group(struct net_brid
        for (p = mlock_dereference(mp->ports, br);
             p != NULL;
             p = mlock_dereference(p->next, br)) {
@@ -200,7 +200,7 @@ Implement optinal multicast->unicast conversion for igmp snooping
                        continue;
  
                if (!hlist_unhashed(&p->mglist) &&
-@@ -1527,8 +1554,8 @@ out:
+@@ -1537,8 +1564,8 @@ out:
  
  static void br_ip4_multicast_leave_group(struct net_bridge *br,
                                         struct net_bridge_port *port,
@@ -211,7 +211,7 @@ Implement optinal multicast->unicast conversion for igmp snooping
  {
        struct br_ip br_group;
        struct bridge_mcast_own_query *own_query;
-@@ -1543,14 +1570,14 @@ static void br_ip4_multicast_leave_group
+@@ -1553,14 +1580,14 @@ static void br_ip4_multicast_leave_group
        br_group.vid = vid;
  
        br_multicast_leave_group(br, port, &br_group, &br->ip4_other_query,
@@ -228,7 +228,7 @@ Implement optinal multicast->unicast conversion for igmp snooping
  {
        struct br_ip br_group;
        struct bridge_mcast_own_query *own_query;
-@@ -1565,7 +1592,7 @@ static void br_ip6_multicast_leave_group
+@@ -1575,7 +1602,7 @@ static void br_ip6_multicast_leave_group
        br_group.vid = vid;
  
        br_multicast_leave_group(br, port, &br_group, &br->ip6_other_query,
@@ -237,7 +237,7 @@ Implement optinal multicast->unicast conversion for igmp snooping
  }
  #endif
  
-@@ -1574,6 +1601,7 @@ static int br_multicast_ipv4_rcv(struct
+@@ -1584,6 +1611,7 @@ static int br_multicast_ipv4_rcv(struct
                                 struct sk_buff *skb,
                                 u16 vid)
  {
@@ -245,7 +245,7 @@ Implement optinal multicast->unicast conversion for igmp snooping
        struct sk_buff *skb_trimmed = NULL;
        struct igmphdr *ih;
        int err;
-@@ -1590,12 +1618,13 @@ static int br_multicast_ipv4_rcv(struct
+@@ -1600,12 +1628,13 @@ static int br_multicast_ipv4_rcv(struct
  
        BR_INPUT_SKB_CB(skb)->igmp = 1;
        ih = igmp_hdr(skb);
@@ -260,7 +260,7 @@ Implement optinal multicast->unicast conversion for igmp snooping
                break;
        case IGMPV3_HOST_MEMBERSHIP_REPORT:
                err = br_ip4_multicast_igmp3_report(br, port, skb_trimmed, vid);
-@@ -1604,7 +1633,7 @@ static int br_multicast_ipv4_rcv(struct
+@@ -1614,7 +1643,7 @@ static int br_multicast_ipv4_rcv(struct
                err = br_ip4_multicast_query(br, port, skb_trimmed, vid);
                break;
        case IGMP_HOST_LEAVE_MESSAGE:
@@ -269,7 +269,7 @@ Implement optinal multicast->unicast conversion for igmp snooping
                break;
        }
  
-@@ -1620,6 +1649,7 @@ static int br_multicast_ipv6_rcv(struct
+@@ -1630,6 +1659,7 @@ static int br_multicast_ipv6_rcv(struct
                                 struct sk_buff *skb,
                                 u16 vid)
  {
@@ -277,7 +277,7 @@ Implement optinal multicast->unicast conversion for igmp snooping
        struct sk_buff *skb_trimmed = NULL;
        struct mld_msg *mld;
        int err;
-@@ -1639,8 +1669,9 @@ static int br_multicast_ipv6_rcv(struct
+@@ -1649,8 +1679,9 @@ static int br_multicast_ipv6_rcv(struct
  
        switch (mld->mld_type) {
        case ICMPV6_MGM_REPORT:
@@ -288,7 +288,7 @@ Implement optinal multicast->unicast conversion for igmp snooping
                break;
        case ICMPV6_MLD2_REPORT:
                err = br_ip6_multicast_mld2_report(br, port, skb_trimmed, vid);
-@@ -1649,7 +1680,8 @@ static int br_multicast_ipv6_rcv(struct
+@@ -1659,7 +1690,8 @@ static int br_multicast_ipv6_rcv(struct
                err = br_ip6_multicast_query(br, port, skb_trimmed, vid);
                break;
        case ICMPV6_MGM_REDUCTION:
@@ -300,17 +300,17 @@ Implement optinal multicast->unicast conversion for igmp snooping
  
 --- a/net/bridge/br_private.h
 +++ b/net/bridge/br_private.h
-@@ -158,6 +158,9 @@ struct net_bridge_port_group {
+@@ -157,7 +157,9 @@ struct net_bridge_port_group {
+       struct rcu_head                 rcu;
        struct timer_list               timer;
        struct br_ip                    addr;
-       unsigned char                   state;
-+
 +      unsigned char                   eth_addr[ETH_ALEN];
+       unsigned char                   state;
 +      bool                            unicast;
  };
  
  struct net_bridge_mdb_entry
-@@ -554,7 +557,8 @@ void br_multicast_free_pg(struct rcu_hea
+@@ -555,7 +557,8 @@ void br_multicast_free_pg(struct rcu_hea
  struct net_bridge_port_group *
  br_multicast_new_port_group(struct net_bridge_port *port, struct br_ip *group,
                            struct net_bridge_port_group __rcu *next,
@@ -382,6 +382,8 @@ Implement optinal multicast->unicast conversion for igmp snooping
  
 -              port = (unsigned long)lport > (unsigned long)rport ?
 -                     lport : rport;
+-
+-              prev = maybe_deliver(prev, port, skb, __packet_hook);
 +              if ((unsigned long)lport > (unsigned long)rport) {
 +                      port = lport;
 +                      addr = p->unicast ? p->eth_addr : NULL;
@@ -389,8 +391,7 @@ Implement optinal multicast->unicast conversion for igmp snooping
 +                      port = rport;
 +                      addr = NULL;
 +              }
--              prev = maybe_deliver(prev, port, skb, __packet_hook);
++
 +              if (addr)
 +                      prev = maybe_deliver_addr(prev, port, skb, addr,
 +                                                __packet_hook);