]> Pileus Git - ~andy/linux/blobdiff - net/bridge/br_forward.c
bridge: Add a flag to control unicast packet flood.
[~andy/linux] / net / bridge / br_forward.c
index 092b20e4ee4c3fc3a054477b67d2273263adf543..4b81b147178987f6ea29ee6efba261cd738102b9 100644 (file)
@@ -174,7 +174,8 @@ out:
 static void br_flood(struct net_bridge *br, struct sk_buff *skb,
                     struct sk_buff *skb0,
                     void (*__packet_hook)(const struct net_bridge_port *p,
-                                          struct sk_buff *skb))
+                                          struct sk_buff *skb),
+                    bool unicast)
 {
        struct net_bridge_port *p;
        struct net_bridge_port *prev;
@@ -182,6 +183,9 @@ static void br_flood(struct net_bridge *br, struct sk_buff *skb,
        prev = NULL;
 
        list_for_each_entry_rcu(p, &br->port_list, list) {
+               /* Do not flood unicast traffic to ports that turn it off */
+               if (unicast && !(p->flags & BR_FLOOD))
+                       continue;
                prev = maybe_deliver(prev, p, skb, __packet_hook);
                if (IS_ERR(prev))
                        goto out;
@@ -203,16 +207,16 @@ out:
 
 
 /* called with rcu_read_lock */
-void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb)
+void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb, bool unicast)
 {
-       br_flood(br, skb, NULL, __br_deliver);
+       br_flood(br, skb, NULL, __br_deliver, unicast);
 }
 
 /* called under bridge lock */
 void br_flood_forward(struct net_bridge *br, struct sk_buff *skb,
-                     struct sk_buff *skb2)
+                     struct sk_buff *skb2, bool unicast)
 {
-       br_flood(br, skb, skb2, __br_forward);
+       br_flood(br, skb, skb2, __br_forward, unicast);
 }
 
 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING