kernel: backport upstream bridge multicast snooping fixes
[openwrt/svn-archive/archive.git] / target / linux / generic / patches-3.10 / 645-bridge_multicast_to_unicast.patch
index f5b781bb1757921d00366d390308f6b1636fb31b..9ee6b01df071a7c6576612b625e4074c79fa22d8 100644 (file)
@@ -1,6 +1,6 @@
 --- a/net/bridge/br_multicast.c
 +++ b/net/bridge/br_multicast.c
-@@ -630,7 +630,8 @@ struct net_bridge_port_group *br_multica
+@@ -634,7 +634,8 @@ struct net_bridge_port_group *br_multica
                        struct net_bridge_port *port,
                        struct br_ip *group,
                        struct net_bridge_port_group __rcu *next,
@@ -10,7 +10,7 @@
  {
        struct net_bridge_port_group *p;
  
-@@ -645,12 +646,33 @@ struct net_bridge_port_group *br_multica
+@@ -649,12 +650,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);
@@ -45,7 +45,7 @@
  {
        struct net_bridge_mdb_entry *mp;
        struct net_bridge_port_group *p;
-@@ -677,13 +699,13 @@ static int br_multicast_add_group(struct
+@@ -681,13 +703,13 @@ static int br_multicast_add_group(struct
        for (pp = &mp->ports;
             (p = mlock_dereference(*pp, br)) != NULL;
             pp = &p->next) {
@@ -61,7 +61,7 @@
        if (unlikely(!p))
                goto err;
        rcu_assign_pointer(*pp, p);
-@@ -702,7 +724,7 @@ err:
+@@ -706,7 +728,7 @@ err:
  static int br_ip4_multicast_add_group(struct net_bridge *br,
                                      struct net_bridge_port *port,
                                      __be32 group,
@@ -70,7 +70,7 @@
  {
        struct br_ip br_group;
  
-@@ -713,14 +735,14 @@ static int br_ip4_multicast_add_group(st
+@@ -717,14 +739,14 @@ static int br_ip4_multicast_add_group(st
        br_group.proto = htons(ETH_P_IP);
        br_group.vid = vid;
  
@@ -87,7 +87,7 @@
  {
        struct br_ip br_group;
  
-@@ -731,7 +753,7 @@ static int br_ip6_multicast_add_group(st
+@@ -735,7 +757,7 @@ static int br_ip6_multicast_add_group(st
        br_group.proto = htons(ETH_P_IPV6);
        br_group.vid = vid;
  
@@ -96,7 +96,7 @@
  }
  #endif
  
-@@ -898,6 +920,7 @@ static int br_ip4_multicast_igmp3_report
+@@ -949,6 +971,7 @@ static int br_ip4_multicast_igmp3_report
                                         struct net_bridge_port *port,
                                         struct sk_buff *skb)
  {
        struct igmpv3_report *ih;
        struct igmpv3_grec *grec;
        int i;
-@@ -943,7 +966,7 @@ static int br_ip4_multicast_igmp3_report
+@@ -994,7 +1017,7 @@ static int br_ip4_multicast_igmp3_report
                        continue;
                }
  
                if (err)
                        break;
        }
-@@ -956,6 +979,7 @@ static int br_ip6_multicast_mld2_report(
+@@ -1007,6 +1030,7 @@ static int br_ip6_multicast_mld2_report(
                                        struct net_bridge_port *port,
                                        struct sk_buff *skb)
  {
        struct icmp6hdr *icmp6h;
        struct mld2_grec *grec;
        int i;
-@@ -1006,7 +1030,7 @@ static int br_ip6_multicast_mld2_report(
+@@ -1057,7 +1081,7 @@ static int br_ip6_multicast_mld2_report(
                }
  
                err = br_ip6_multicast_add_group(br, port, &grec->grec_mca,
                if (!err)
                        break;
        }
-@@ -1235,7 +1259,8 @@ out:
- static void br_multicast_leave_group(struct net_bridge *br,
+@@ -1302,7 +1326,8 @@ static void br_multicast_leave_group(str
                                     struct net_bridge_port *port,
--                                   struct br_ip *group)
-+                                   struct br_ip *group,
+                                    struct br_ip *group,
+                                    struct bridge_mcast_querier *querier,
+-                                   struct bridge_mcast_query *query)
++                                   struct bridge_mcast_query *query,
 +                                   const unsigned char *src)
  {
        struct net_bridge_mdb_htable *mdb;
        struct net_bridge_mdb_entry *mp;
-@@ -1260,7 +1285,7 @@ static void br_multicast_leave_group(str
+@@ -1352,7 +1377,7 @@ static void br_multicast_leave_group(str
                for (pp = &mp->ports;
                     (p = mlock_dereference(*pp, br)) != NULL;
                     pp = &p->next) {
                                continue;
  
                        rcu_assign_pointer(*pp, p->next);
-@@ -1294,7 +1319,7 @@ static void br_multicast_leave_group(str
+@@ -1386,7 +1411,7 @@ static void br_multicast_leave_group(str
        for (p = mlock_dereference(mp->ports, br);
             p != NULL;
             p = mlock_dereference(p->next, br)) {
                        continue;
  
                if (!hlist_unhashed(&p->mglist) &&
-@@ -1313,8 +1338,8 @@ out:
+@@ -1404,8 +1429,8 @@ out:
  
  static void br_ip4_multicast_leave_group(struct net_bridge *br,
                                         struct net_bridge_port *port,
 +                                       const unsigned char *src)
  {
        struct br_ip br_group;
-@@ -1325,14 +1350,14 @@ static void br_ip4_multicast_leave_group
+       struct bridge_mcast_query *query = port ? &port->ip4_query :
+@@ -1418,14 +1443,15 @@ static void br_ip4_multicast_leave_group
        br_group.proto = htons(ETH_P_IP);
        br_group.vid = vid;
  
--      br_multicast_leave_group(br, port, &br_group);
-+      br_multicast_leave_group(br, port, &br_group, src);
+-      br_multicast_leave_group(br, port, &br_group, &br->ip4_querier, query);
++      br_multicast_leave_group(br, port, &br_group, &br->ip4_querier, query,
++                               src);
  }
  
  #if IS_ENABLED(CONFIG_IPV6)
 +                                       __u16 vid, const unsigned char *src)
  {
        struct br_ip br_group;
-@@ -1343,7 +1368,7 @@ static void br_ip6_multicast_leave_group
+       struct bridge_mcast_query *query = port ? &port->ip6_query :
+@@ -1439,7 +1465,8 @@ static void br_ip6_multicast_leave_group
        br_group.proto = htons(ETH_P_IPV6);
        br_group.vid = vid;
  
--      br_multicast_leave_group(br, port, &br_group);
-+      br_multicast_leave_group(br, port, &br_group, src);
+-      br_multicast_leave_group(br, port, &br_group, &br->ip6_querier, query);
++      br_multicast_leave_group(br, port, &br_group, &br->ip6_querier, query,
++                               src);
  }
  #endif
  
-@@ -1351,6 +1376,7 @@ static int br_multicast_ipv4_rcv(struct
+@@ -1447,6 +1474,7 @@ static int br_multicast_ipv4_rcv(struct 
                                 struct net_bridge_port *port,
                                 struct sk_buff *skb)
  {
        struct sk_buff *skb2 = skb;
        const struct iphdr *iph;
        struct igmphdr *ih;
-@@ -1426,7 +1452,7 @@ static int br_multicast_ipv4_rcv(struct
+@@ -1522,7 +1550,7 @@ static int br_multicast_ipv4_rcv(struct 
        case IGMP_HOST_MEMBERSHIP_REPORT:
        case IGMPV2_HOST_MEMBERSHIP_REPORT:
                BR_INPUT_SKB_CB(skb)->mrouters_only = 1;
                break;
        case IGMPV3_HOST_MEMBERSHIP_REPORT:
                err = br_ip4_multicast_igmp3_report(br, port, skb2);
-@@ -1435,7 +1461,7 @@ static int br_multicast_ipv4_rcv(struct
+@@ -1531,7 +1559,7 @@ static int br_multicast_ipv4_rcv(struct 
                err = br_ip4_multicast_query(br, port, skb2);
                break;
        case IGMP_HOST_LEAVE_MESSAGE:
                break;
        }
  
-@@ -1452,6 +1478,7 @@ static int br_multicast_ipv6_rcv(struct
+@@ -1548,6 +1576,7 @@ static int br_multicast_ipv6_rcv(struct 
                                 struct net_bridge_port *port,
                                 struct sk_buff *skb)
  {
        struct sk_buff *skb2;
        const struct ipv6hdr *ip6h;
        u8 icmp6_type;
-@@ -1557,7 +1584,8 @@ static int br_multicast_ipv6_rcv(struct
+@@ -1659,7 +1688,8 @@ static int br_multicast_ipv6_rcv(struct 
                }
                mld = (struct mld_msg *)skb_transport_header(skb2);
                BR_INPUT_SKB_CB(skb)->mrouters_only = 1;
                break;
            }
        case ICMPV6_MLD2_REPORT:
-@@ -1574,7 +1602,7 @@ static int br_multicast_ipv6_rcv(struct
+@@ -1676,7 +1706,7 @@ static int br_multicast_ipv6_rcv(struct 
                        goto out;
                }
                mld = (struct mld_msg *)skb_transport_header(skb2);
  
 --- a/net/bridge/br_private.h
 +++ b/net/bridge/br_private.h
-@@ -101,6 +101,9 @@ struct net_bridge_port_group {
+@@ -115,6 +115,9 @@ struct net_bridge_port_group {
        struct timer_list               timer;
        struct br_ip                    addr;
        unsigned char                   state;
  };
  
  struct net_bridge_mdb_entry
-@@ -158,6 +161,7 @@ struct net_bridge_port
+@@ -172,6 +175,7 @@ struct net_bridge_port
  #define BR_MULTICAST_FAST_LEAVE       0x00000008
  #define BR_ADMIN_COST         0x00000010
  #define BR_ISOLATE_MODE               0x00000020
 +#define BR_MULTICAST_TO_UCAST 0x00000040
  
  #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
-       u32                             multicast_startup_queries_sent;
-@@ -469,7 +473,8 @@ extern struct net_bridge_port_group *br_
+       struct bridge_mcast_query       ip4_query;
+@@ -489,7 +493,8 @@ extern struct net_bridge_port_group *br_
                                struct net_bridge_port *port,
                                struct br_ip *group,
                                struct net_bridge_port_group *next,
  extern void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port,
 --- a/net/bridge/br_mdb.c
 +++ b/net/bridge/br_mdb.c
-@@ -340,7 +340,7 @@ static int br_mdb_add_group(struct net_b
+@@ -341,7 +341,7 @@ static int br_mdb_add_group(struct net_b
                        break;
        }