diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2009-10-26 21:40:35 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-10-27 04:02:33 -0400 |
commit | 05423b241311c9380b7280179295bac7794281b6 (patch) | |
tree | 8a84aca48cbc30b142bdf143dbf11fdbab9cad67 /net | |
parent | 9dbb58d867e90d2528752339751216c955523e62 (diff) |
vlan: allow null VLAN ID to be used
We currently use a 16 bit field (vlan_tci) to store VLAN ID/PRIO on a skb.
Null value is used as a special value, meaning vlan tagging not enabled.
This forbids use of null vlan ID.
As pointed by David, some drivers use the 3 high order bits (PRIO)
As VLAN ID is 12 bits, we can use the remaining bit (CFI) as a flag, and
allow null VLAN ID.
In case future code really wants to use VLAN_CFI_MASK, we'll have to use
a bit outside of vlan_tci.
#define VLAN_PRIO_MASK 0xe000 /* Priority Code Point */
#define VLAN_PRIO_SHIFT 13
#define VLAN_CFI_MASK 0x1000 /* Canonical Format Indicator */
#define VLAN_TAG_PRESENT VLAN_CFI_MASK
#define VLAN_VID_MASK 0x0fff /* VLAN Identifier */
Reported-by: Gertjan Hofman <gertjan_hofman@yahoo.com>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/8021q/vlan.h | 2 | ||||
-rw-r--r-- | net/8021q/vlan_dev.c | 2 | ||||
-rw-r--r-- | net/core/dev.c | 2 | ||||
-rw-r--r-- | net/packet/af_packet.c | 5 |
4 files changed, 6 insertions, 5 deletions
diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h index 82570bc2a180..4ade5edf1033 100644 --- a/net/8021q/vlan.h +++ b/net/8021q/vlan.h | |||
@@ -89,7 +89,7 @@ static inline u32 vlan_get_ingress_priority(struct net_device *dev, | |||
89 | { | 89 | { |
90 | struct vlan_dev_info *vip = vlan_dev_info(dev); | 90 | struct vlan_dev_info *vip = vlan_dev_info(dev); |
91 | 91 | ||
92 | return vip->ingress_priority_map[(vlan_tci >> 13) & 0x7]; | 92 | return vip->ingress_priority_map[(vlan_tci >> VLAN_PRIO_SHIFT) & 0x7]; |
93 | } | 93 | } |
94 | 94 | ||
95 | #ifdef CONFIG_VLAN_8021Q_GVRP | 95 | #ifdef CONFIG_VLAN_8021Q_GVRP |
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 4198ec5c8abc..e3701977f58d 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
@@ -393,7 +393,7 @@ int vlan_dev_set_egress_priority(const struct net_device *dev, | |||
393 | struct vlan_dev_info *vlan = vlan_dev_info(dev); | 393 | struct vlan_dev_info *vlan = vlan_dev_info(dev); |
394 | struct vlan_priority_tci_mapping *mp = NULL; | 394 | struct vlan_priority_tci_mapping *mp = NULL; |
395 | struct vlan_priority_tci_mapping *np; | 395 | struct vlan_priority_tci_mapping *np; |
396 | u32 vlan_qos = (vlan_prio << 13) & 0xE000; | 396 | u32 vlan_qos = (vlan_prio << VLAN_PRIO_SHIFT) & VLAN_PRIO_MASK; |
397 | 397 | ||
398 | /* See if a priority mapping exists.. */ | 398 | /* See if a priority mapping exists.. */ |
399 | mp = vlan->egress_priority_map[skb_prio & 0xF]; | 399 | mp = vlan->egress_priority_map[skb_prio & 0xF]; |
diff --git a/net/core/dev.c b/net/core/dev.c index e7bada1d5ed9..950c13fa60d2 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2300,7 +2300,7 @@ int netif_receive_skb(struct sk_buff *skb) | |||
2300 | if (!skb->tstamp.tv64) | 2300 | if (!skb->tstamp.tv64) |
2301 | net_timestamp(skb); | 2301 | net_timestamp(skb); |
2302 | 2302 | ||
2303 | if (skb->vlan_tci && vlan_hwaccel_do_receive(skb)) | 2303 | if (vlan_tx_tag_present(skb) && vlan_hwaccel_do_receive(skb)) |
2304 | return NET_RX_SUCCESS; | 2304 | return NET_RX_SUCCESS; |
2305 | 2305 | ||
2306 | /* if we've gotten here through NAPI, check netpoll */ | 2306 | /* if we've gotten here through NAPI, check netpoll */ |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index ff752c606413..33e68f20ec61 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -79,6 +79,7 @@ | |||
79 | #include <linux/module.h> | 79 | #include <linux/module.h> |
80 | #include <linux/init.h> | 80 | #include <linux/init.h> |
81 | #include <linux/mutex.h> | 81 | #include <linux/mutex.h> |
82 | #include <linux/if_vlan.h> | ||
82 | 83 | ||
83 | #ifdef CONFIG_INET | 84 | #ifdef CONFIG_INET |
84 | #include <net/inet_common.h> | 85 | #include <net/inet_common.h> |
@@ -766,7 +767,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, | |||
766 | getnstimeofday(&ts); | 767 | getnstimeofday(&ts); |
767 | h.h2->tp_sec = ts.tv_sec; | 768 | h.h2->tp_sec = ts.tv_sec; |
768 | h.h2->tp_nsec = ts.tv_nsec; | 769 | h.h2->tp_nsec = ts.tv_nsec; |
769 | h.h2->tp_vlan_tci = skb->vlan_tci; | 770 | h.h2->tp_vlan_tci = vlan_tx_tag_get(skb); |
770 | hdrlen = sizeof(*h.h2); | 771 | hdrlen = sizeof(*h.h2); |
771 | break; | 772 | break; |
772 | default: | 773 | default: |
@@ -1493,7 +1494,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1493 | aux.tp_snaplen = skb->len; | 1494 | aux.tp_snaplen = skb->len; |
1494 | aux.tp_mac = 0; | 1495 | aux.tp_mac = 0; |
1495 | aux.tp_net = skb_network_offset(skb); | 1496 | aux.tp_net = skb_network_offset(skb); |
1496 | aux.tp_vlan_tci = skb->vlan_tci; | 1497 | aux.tp_vlan_tci = vlan_tx_tag_get(skb); |
1497 | 1498 | ||
1498 | put_cmsg(msg, SOL_PACKET, PACKET_AUXDATA, sizeof(aux), &aux); | 1499 | put_cmsg(msg, SOL_PACKET, PACKET_AUXDATA, sizeof(aux), &aux); |
1499 | } | 1500 | } |