diff options
author | Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp> | 2013-10-16 04:07:14 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-10-18 16:02:53 -0400 |
commit | b90356ce17c2b199cd55530cb9c3cfabe18dbdc3 (patch) | |
tree | b60f74bde46c45d0c1208be5f92c2e823f4112ab /net | |
parent | 8adff41c3d259eb5e313b7b04669eee545925154 (diff) |
bridge: Apply the PVID to priority-tagged frames
IEEE 802.1Q says that when we receive priority-tagged (VID 0) frames
use the PVID for the port as its VID.
(See IEEE 802.1Q-2011 6.9.1 and Table 9-2)
Apply the PVID to not only untagged frames but also priority-tagged frames.
Signed-off-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
Reviewed-by: Vlad Yasevich <vyasevic@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/bridge/br_vlan.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c index 21b6d217872b..5a9c44a0c306 100644 --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c | |||
@@ -189,6 +189,8 @@ out: | |||
189 | bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, | 189 | bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, |
190 | struct sk_buff *skb, u16 *vid) | 190 | struct sk_buff *skb, u16 *vid) |
191 | { | 191 | { |
192 | int err; | ||
193 | |||
192 | /* If VLAN filtering is disabled on the bridge, all packets are | 194 | /* If VLAN filtering is disabled on the bridge, all packets are |
193 | * permitted. | 195 | * permitted. |
194 | */ | 196 | */ |
@@ -201,20 +203,31 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, | |||
201 | if (!v) | 203 | if (!v) |
202 | return false; | 204 | return false; |
203 | 205 | ||
204 | if (br_vlan_get_tag(skb, vid)) { | 206 | err = br_vlan_get_tag(skb, vid); |
207 | if (!*vid) { | ||
205 | u16 pvid = br_get_pvid(v); | 208 | u16 pvid = br_get_pvid(v); |
206 | 209 | ||
207 | /* Frame did not have a tag. See if pvid is set | 210 | /* Frame had a tag with VID 0 or did not have a tag. |
208 | * on this port. That tells us which vlan untagged | 211 | * See if pvid is set on this port. That tells us which |
209 | * traffic belongs to. | 212 | * vlan untagged or priority-tagged traffic belongs to. |
210 | */ | 213 | */ |
211 | if (pvid == VLAN_N_VID) | 214 | if (pvid == VLAN_N_VID) |
212 | return false; | 215 | return false; |
213 | 216 | ||
214 | /* PVID is set on this port. Any untagged ingress | 217 | /* PVID is set on this port. Any untagged or priority-tagged |
215 | * frame is considered to belong to this vlan. | 218 | * ingress frame is considered to belong to this vlan. |
216 | */ | 219 | */ |
217 | __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), pvid); | 220 | if (likely(err)) |
221 | /* Untagged Frame. */ | ||
222 | __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), pvid); | ||
223 | else | ||
224 | /* Priority-tagged Frame. | ||
225 | * At this point, We know that skb->vlan_tci had | ||
226 | * VLAN_TAG_PRESENT bit and its VID field was 0x000. | ||
227 | * We update only VID field and preserve PCP field. | ||
228 | */ | ||
229 | skb->vlan_tci |= pvid; | ||
230 | |||
218 | return true; | 231 | return true; |
219 | } | 232 | } |
220 | 233 | ||