#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
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) {
+ 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;
--- 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,
- 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;
+ port = rport;
+ addr = NULL;
+ }
-+
+
+- prev = maybe_deliver(prev, port, skb, __packet_hook);
+ if (addr)
+ prev = maybe_deliver_addr(prev, port, skb, addr,
+ __packet_hook);