diff options
Diffstat (limited to 'net/bridge/br_vlan.c')
-rw-r--r-- | net/bridge/br_vlan.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c index 2b2774fe0703..3ba57fcdcd13 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) |
@@ -55,10 +59,8 @@ static int __vlan_add(struct net_port_vlans *v, u16 vid, u16 flags) | |||
55 | 59 | ||
56 | if (p) { | 60 | if (p) { |
57 | /* Add VLAN to the device filter if it is supported. | 61 | /* Add VLAN to the device filter if it is supported. |
58 | * Stricly speaking, this is not necessary now, since | 62 | * This ensures tagged traffic enters the bridge when |
59 | * devices are made promiscuous by the bridge, but if | 63 | * promiscuous mode is disabled by br_manage_promisc(). |
60 | * that ever changes this code will allow tagged | ||
61 | * traffic to enter the bridge. | ||
62 | */ | 64 | */ |
63 | err = vlan_vid_add(dev, br->vlan_proto, vid); | 65 | err = vlan_vid_add(dev, br->vlan_proto, vid); |
64 | if (err) | 66 | if (err) |
@@ -127,7 +129,8 @@ struct sk_buff *br_handle_vlan(struct net_bridge *br, | |||
127 | { | 129 | { |
128 | u16 vid; | 130 | u16 vid; |
129 | 131 | ||
130 | 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) | ||
131 | goto out; | 134 | goto out; |
132 | 135 | ||
133 | /* Vlan filter table must be configured at this point. The | 136 | /* Vlan filter table must be configured at this point. The |
@@ -166,8 +169,10 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, | |||
166 | /* If VLAN filtering is disabled on the bridge, all packets are | 169 | /* If VLAN filtering is disabled on the bridge, all packets are |
167 | * permitted. | 170 | * permitted. |
168 | */ | 171 | */ |
169 | if (!br->vlan_enabled) | 172 | if (!br->vlan_enabled) { |
173 | BR_INPUT_SKB_CB(skb)->vlan_filtered = false; | ||
170 | return true; | 174 | return true; |
175 | } | ||
171 | 176 | ||
172 | /* 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 |
173 | * rejected. | 178 | * rejected. |
@@ -175,6 +180,7 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, | |||
175 | if (!v) | 180 | if (!v) |
176 | goto drop; | 181 | goto drop; |
177 | 182 | ||
183 | BR_INPUT_SKB_CB(skb)->vlan_filtered = true; | ||
178 | proto = br->vlan_proto; | 184 | proto = br->vlan_proto; |
179 | 185 | ||
180 | /* 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 |
@@ -183,7 +189,7 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, | |||
183 | */ | 189 | */ |
184 | if (unlikely(!vlan_tx_tag_present(skb) && | 190 | if (unlikely(!vlan_tx_tag_present(skb) && |
185 | skb->protocol == proto)) { | 191 | skb->protocol == proto)) { |
186 | skb = vlan_untag(skb); | 192 | skb = skb_vlan_untag(skb); |
187 | if (unlikely(!skb)) | 193 | if (unlikely(!skb)) |
188 | return false; | 194 | return false; |
189 | } | 195 | } |
@@ -253,7 +259,8 @@ bool br_allowed_egress(struct net_bridge *br, | |||
253 | { | 259 | { |
254 | u16 vid; | 260 | u16 vid; |
255 | 261 | ||
256 | 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) | ||
257 | return true; | 264 | return true; |
258 | 265 | ||
259 | if (!v) | 266 | if (!v) |
@@ -272,6 +279,7 @@ bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid) | |||
272 | struct net_bridge *br = p->br; | 279 | struct net_bridge *br = p->br; |
273 | struct net_port_vlans *v; | 280 | struct net_port_vlans *v; |
274 | 281 | ||
282 | /* If filtering was disabled at input, let it pass. */ | ||
275 | if (!br->vlan_enabled) | 283 | if (!br->vlan_enabled) |
276 | return true; | 284 | return true; |
277 | 285 | ||