diff options
author | David S. Miller <davem@davemloft.net> | 2014-09-13 17:22:02 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-09-13 17:22:02 -0400 |
commit | 9e07a422383c6775bd995613f66f1816266a8063 (patch) | |
tree | b143668258d60aa96d7c232d77dbfd979c8a758c /net | |
parent | 9a72c2da690d78e93cff24b9f616412508678dd5 (diff) | |
parent | 635126b7ca13a01d6322fbf7bdc5d1c738d26807 (diff) |
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>
Diffstat (limited to 'net')
-rw-r--r-- | net/bridge/br_private.h | 3 | ||||
-rw-r--r-- | net/bridge/br_vlan.c | 18 |
2 files changed, 17 insertions, 4 deletions
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 62a7fa2e3569..b6c04cbcfdc5 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
@@ -309,6 +309,9 @@ struct br_input_skb_cb { | |||
309 | int igmp; | 309 | int igmp; |
310 | int mrouters_only; | 310 | int mrouters_only; |
311 | #endif | 311 | #endif |
312 | #ifdef CONFIG_BRIDGE_VLAN_FILTERING | ||
313 | bool vlan_filtered; | ||
314 | #endif | ||
312 | }; | 315 | }; |
313 | 316 | ||
314 | #define BR_INPUT_SKB_CB(__skb) ((struct br_input_skb_cb *)(__skb)->cb) | 317 | #define BR_INPUT_SKB_CB(__skb) ((struct br_input_skb_cb *)(__skb)->cb) |
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c index e1bcd653899b..4b86738eca9a 100644 --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c | |||
@@ -27,9 +27,13 @@ static void __vlan_add_flags(struct net_port_vlans *v, u16 vid, u16 flags) | |||
27 | { | 27 | { |
28 | if (flags & BRIDGE_VLAN_INFO_PVID) | 28 | if (flags & BRIDGE_VLAN_INFO_PVID) |
29 | __vlan_add_pvid(v, vid); | 29 | __vlan_add_pvid(v, vid); |
30 | else | ||
31 | __vlan_delete_pvid(v, vid); | ||
30 | 32 | ||
31 | if (flags & BRIDGE_VLAN_INFO_UNTAGGED) | 33 | if (flags & BRIDGE_VLAN_INFO_UNTAGGED) |
32 | set_bit(vid, v->untagged_bitmap); | 34 | set_bit(vid, v->untagged_bitmap); |
35 | else | ||
36 | clear_bit(vid, v->untagged_bitmap); | ||
33 | } | 37 | } |
34 | 38 | ||
35 | static int __vlan_add(struct net_port_vlans *v, u16 vid, u16 flags) | 39 | 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, | |||
125 | { | 129 | { |
126 | u16 vid; | 130 | u16 vid; |
127 | 131 | ||
128 | if (!br->vlan_enabled) | 132 | /* If this packet was not filtered at input, let it pass */ |
133 | if (!BR_INPUT_SKB_CB(skb)->vlan_filtered) | ||
129 | goto out; | 134 | goto out; |
130 | 135 | ||
131 | /* Vlan filter table must be configured at this point. The | 136 | /* 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, | |||
164 | /* If VLAN filtering is disabled on the bridge, all packets are | 169 | /* If VLAN filtering is disabled on the bridge, all packets are |
165 | * permitted. | 170 | * permitted. |
166 | */ | 171 | */ |
167 | if (!br->vlan_enabled) | 172 | if (!br->vlan_enabled) { |
173 | BR_INPUT_SKB_CB(skb)->vlan_filtered = false; | ||
168 | return true; | 174 | return true; |
175 | } | ||
169 | 176 | ||
170 | /* If there are no vlan in the permitted list, all packets are | 177 | /* If there are no vlan in the permitted list, all packets are |
171 | * rejected. | 178 | * rejected. |
@@ -173,6 +180,7 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, | |||
173 | if (!v) | 180 | if (!v) |
174 | goto drop; | 181 | goto drop; |
175 | 182 | ||
183 | BR_INPUT_SKB_CB(skb)->vlan_filtered = true; | ||
176 | proto = br->vlan_proto; | 184 | proto = br->vlan_proto; |
177 | 185 | ||
178 | /* If vlan tx offload is disabled on bridge device and frame was | 186 | /* If vlan tx offload is disabled on bridge device and frame was |
@@ -251,7 +259,8 @@ bool br_allowed_egress(struct net_bridge *br, | |||
251 | { | 259 | { |
252 | u16 vid; | 260 | u16 vid; |
253 | 261 | ||
254 | if (!br->vlan_enabled) | 262 | /* If this packet was not filtered at input, let it pass */ |
263 | if (!BR_INPUT_SKB_CB(skb)->vlan_filtered) | ||
255 | return true; | 264 | return true; |
256 | 265 | ||
257 | if (!v) | 266 | if (!v) |
@@ -270,7 +279,8 @@ bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid) | |||
270 | struct net_bridge *br = p->br; | 279 | struct net_bridge *br = p->br; |
271 | struct net_port_vlans *v; | 280 | struct net_port_vlans *v; |
272 | 281 | ||
273 | if (!br->vlan_enabled) | 282 | /* If filtering was disabled at input, let it pass. */ |
283 | if (!BR_INPUT_SKB_CB(skb)->vlan_filtered) | ||
274 | return true; | 284 | return true; |
275 | 285 | ||
276 | v = rcu_dereference(p->vlan_info); | 286 | v = rcu_dereference(p->vlan_info); |