Эх сурвалжийг харах

Merge branch 'bridge_vlan_filtering'

Vladislav Yasevich says:

====================
bridge: Two small fixes to vlan filtering code.

This series corrects 2 small issues that I've ran across recently
while doing more work with vlan filtering changes.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
David S. Miller 11 жил өмнө
parent
commit
9e07a42238

+ 3 - 0
net/bridge/br_private.h

@@ -309,6 +309,9 @@ struct br_input_skb_cb {
 	int igmp;
 	int igmp;
 	int mrouters_only;
 	int mrouters_only;
 #endif
 #endif
+#ifdef CONFIG_BRIDGE_VLAN_FILTERING
+	bool vlan_filtered;
+#endif
 };
 };
 
 
 #define BR_INPUT_SKB_CB(__skb)	((struct br_input_skb_cb *)(__skb)->cb)
 #define BR_INPUT_SKB_CB(__skb)	((struct br_input_skb_cb *)(__skb)->cb)

+ 14 - 4
net/bridge/br_vlan.c

@@ -27,9 +27,13 @@ static void __vlan_add_flags(struct net_port_vlans *v, u16 vid, u16 flags)
 {
 {
 	if (flags & BRIDGE_VLAN_INFO_PVID)
 	if (flags & BRIDGE_VLAN_INFO_PVID)
 		__vlan_add_pvid(v, vid);
 		__vlan_add_pvid(v, vid);
+	else
+		__vlan_delete_pvid(v, vid);
 
 
 	if (flags & BRIDGE_VLAN_INFO_UNTAGGED)
 	if (flags & BRIDGE_VLAN_INFO_UNTAGGED)
 		set_bit(vid, v->untagged_bitmap);
 		set_bit(vid, v->untagged_bitmap);
+	else
+		clear_bit(vid, v->untagged_bitmap);
 }
 }
 
 
 static int __vlan_add(struct net_port_vlans *v, u16 vid, u16 flags)
 static int __vlan_add(struct net_port_vlans *v, u16 vid, u16 flags)
@@ -125,7 +129,8 @@ struct sk_buff *br_handle_vlan(struct net_bridge *br,
 {
 {
 	u16 vid;
 	u16 vid;
 
 
-	if (!br->vlan_enabled)
+	/* If this packet was not filtered at input, let it pass */
+	if (!BR_INPUT_SKB_CB(skb)->vlan_filtered)
 		goto out;
 		goto out;
 
 
 	/* Vlan filter table must be configured at this point.  The
 	/* Vlan filter table must be configured at this point.  The
@@ -164,8 +169,10 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v,
 	/* If VLAN filtering is disabled on the bridge, all packets are
 	/* If VLAN filtering is disabled on the bridge, all packets are
 	 * permitted.
 	 * permitted.
 	 */
 	 */
-	if (!br->vlan_enabled)
+	if (!br->vlan_enabled) {
+		BR_INPUT_SKB_CB(skb)->vlan_filtered = false;
 		return true;
 		return true;
+	}
 
 
 	/* If there are no vlan in the permitted list, all packets are
 	/* If there are no vlan in the permitted list, all packets are
 	 * rejected.
 	 * rejected.
@@ -173,6 +180,7 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v,
 	if (!v)
 	if (!v)
 		goto drop;
 		goto drop;
 
 
+	BR_INPUT_SKB_CB(skb)->vlan_filtered = true;
 	proto = br->vlan_proto;
 	proto = br->vlan_proto;
 
 
 	/* If vlan tx offload is disabled on bridge device and frame was
 	/* If vlan tx offload is disabled on bridge device and frame was
@@ -251,7 +259,8 @@ bool br_allowed_egress(struct net_bridge *br,
 {
 {
 	u16 vid;
 	u16 vid;
 
 
-	if (!br->vlan_enabled)
+	/* If this packet was not filtered at input, let it pass */
+	if (!BR_INPUT_SKB_CB(skb)->vlan_filtered)
 		return true;
 		return true;
 
 
 	if (!v)
 	if (!v)
@@ -270,7 +279,8 @@ bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid)
 	struct net_bridge *br = p->br;
 	struct net_bridge *br = p->br;
 	struct net_port_vlans *v;
 	struct net_port_vlans *v;
 
 
-	if (!br->vlan_enabled)
+	/* If filtering was disabled at input, let it pass. */
+	if (!BR_INPUT_SKB_CB(skb)->vlan_filtered)
 		return true;
 		return true;
 
 
 	v = rcu_dereference(p->vlan_info);
 	v = rcu_dereference(p->vlan_info);