aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorToshiaki Makita <makita.toshiaki@lab.ntt.co.jp>2013-10-16 04:07:14 -0400
committerDavid S. Miller <davem@davemloft.net>2013-10-18 16:02:53 -0400
commitb90356ce17c2b199cd55530cb9c3cfabe18dbdc3 (patch)
treeb60f74bde46c45d0c1208be5f92c2e823f4112ab /net
parent8adff41c3d259eb5e313b7b04669eee545925154 (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.c27
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:
189bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, 189bool 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