kernel: fix unaligned access issue in the bridge multicast-to-unicast patch
[openwrt/openwrt.git] / target / linux / generic / patches-4.4 / 645-bridge_multicast_to_unicast.patch
index 830883526d48cc179afddb5fbad16b39125fb511..5d2103fe5c7844a1966e8df825cf67fa698d5355 100644 (file)
@@ -11,8 +11,8 @@ Implement optinal multicast->unicast conversion for igmp snooping
  #define BR_ISOLATE_MODE       BIT(11)
 +#define BR_MULTICAST_TO_UCAST BIT(12)
  
- /* values as per ieee8021QBridgeFdbAgingTime */
- #define BR_MIN_AGEING_TIME    (10 * HZ)
+ #define BR_DEFAULT_AGEING_TIME        (300 * HZ)
 --- a/net/bridge/br_multicast.c
 +++ b/net/bridge/br_multicast.c
 @@ -42,12 +42,13 @@ static void br_multicast_add_router(stru
@@ -135,7 +135,11 @@ Implement optinal multicast->unicast conversion for igmp snooping
        struct igmpv3_report *ih;
        struct igmpv3_grec *grec;
        int i;
-@@ -1038,9 +1062,10 @@ static int br_ip4_multicast_igmp3_report
+@@ -1035,12 +1059,13 @@ static int br_ip4_multicast_igmp3_report
+                       continue;
+               }
++              src = eth_hdr(skb)->h_source;
                if ((type == IGMPV3_CHANGE_TO_INCLUDE ||
                     type == IGMPV3_MODE_IS_INCLUDE) &&
                    ntohs(grec->grec_nsrcs) == 0) {
@@ -143,7 +147,6 @@ Implement optinal multicast->unicast conversion for igmp snooping
 +                      br_ip4_multicast_leave_group(br, port, group, vid, src);
                } else {
 -                      err = br_ip4_multicast_add_group(br, port, group, vid);
-+                      src = eth_hdr(skb)->h_source;
 +                      err = br_ip4_multicast_add_group(br, port, group, vid, src);
                        if (err)
                                break;
@@ -297,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
+@@ -554,7 +556,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,
@@ -379,8 +382,6 @@ 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;
@@ -388,7 +389,8 @@ 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);