Home | History | Annotate | Download | only in linux
      1 /*
      2  * VLAN		An implementation of 802.1Q VLAN tagging.
      3  *
      4  * Authors:	Ben Greear <greearb (at) candelatech.com>
      5  *
      6  *		This program is free software; you can redistribute it and/or
      7  *		modify it under the terms of the GNU General Public License
      8  *		as published by the Free Software Foundation; either version
      9  *		2 of the License, or (at your option) any later version.
     10  *
     11  */
     12 
     13 #ifndef _LINUX_IF_VLAN_H_
     14 #define _LINUX_IF_VLAN_H_
     15 
     16 #ifdef __KERNEL__
     17 #include <linux/netdevice.h>
     18 #include <linux/etherdevice.h>
     19 
     20 #define VLAN_HLEN	4		/* The additional bytes (on top of the Ethernet header)
     21 					 * that VLAN requires.
     22 					 */
     23 #define VLAN_ETH_ALEN	6		/* Octets in one ethernet addr	 */
     24 #define VLAN_ETH_HLEN	18		/* Total octets in header.	 */
     25 #define VLAN_ETH_ZLEN	64		/* Min. octets in frame sans FCS */
     26 
     27 /*
     28  * According to 802.3ac, the packet can be 4 bytes longer. --Klika Jan
     29  */
     30 #define VLAN_ETH_DATA_LEN	1500	/* Max. octets in payload	 */
     31 #define VLAN_ETH_FRAME_LEN	1518	/* Max. octets in frame sans FCS */
     32 
     33 /*
     34  * 	struct vlan_hdr - vlan header
     35  * 	@h_vlan_TCI: priority and VLAN ID
     36  *	@h_vlan_encapsulated_proto: packet type ID or len
     37  */
     38 struct vlan_hdr {
     39 	__be16	h_vlan_TCI;
     40 	__be16	h_vlan_encapsulated_proto;
     41 };
     42 
     43 /**
     44  *	struct vlan_ethhdr - vlan ethernet header (ethhdr + vlan_hdr)
     45  *	@h_dest: destination ethernet address
     46  *	@h_source: source ethernet address
     47  *	@h_vlan_proto: ethernet protocol (always 0x8100)
     48  *	@h_vlan_TCI: priority and VLAN ID
     49  *	@h_vlan_encapsulated_proto: packet type ID or len
     50  */
     51 struct vlan_ethhdr {
     52 	unsigned char	h_dest[ETH_ALEN];
     53 	unsigned char	h_source[ETH_ALEN];
     54 	__be16		h_vlan_proto;
     55 	__be16		h_vlan_TCI;
     56 	__be16		h_vlan_encapsulated_proto;
     57 };
     58 
     59 #include <linux/skbuff.h>
     60 
     61 static inline struct vlan_ethhdr *vlan_eth_hdr(const struct sk_buff *skb)
     62 {
     63 	return (struct vlan_ethhdr *)skb_mac_header(skb);
     64 }
     65 
     66 #define VLAN_PRIO_MASK		0xe000 /* Priority Code Point */
     67 #define VLAN_PRIO_SHIFT		13
     68 #define VLAN_CFI_MASK		0x1000 /* Canonical Format Indicator */
     69 #define VLAN_TAG_PRESENT	VLAN_CFI_MASK
     70 #define VLAN_VID_MASK		0x0fff /* VLAN Identifier */
     71 
     72 /* found in socket.c */
     73 extern void vlan_ioctl_set(int (*hook)(struct net *, void __user *));
     74 
     75 /* if this changes, algorithm will have to be reworked because this
     76  * depends on completely exhausting the VLAN identifier space.  Thus
     77  * it gives constant time look-up, but in many cases it wastes memory.
     78  */
     79 #define VLAN_GROUP_ARRAY_LEN          4096
     80 #define VLAN_GROUP_ARRAY_SPLIT_PARTS  8
     81 #define VLAN_GROUP_ARRAY_PART_LEN     (VLAN_GROUP_ARRAY_LEN/VLAN_GROUP_ARRAY_SPLIT_PARTS)
     82 
     83 struct vlan_group {
     84 	struct net_device	*real_dev; /* The ethernet(like) device
     85 					    * the vlan is attached to.
     86 					    */
     87 	unsigned int		nr_vlans;
     88 	int			killall;
     89 	struct hlist_node	hlist;	/* linked list */
     90 	struct net_device **vlan_devices_arrays[VLAN_GROUP_ARRAY_SPLIT_PARTS];
     91 	struct rcu_head		rcu;
     92 };
     93 
     94 static inline struct net_device *vlan_group_get_device(struct vlan_group *vg,
     95 						       u16 vlan_id)
     96 {
     97 	struct net_device **array;
     98 	array = vg->vlan_devices_arrays[vlan_id / VLAN_GROUP_ARRAY_PART_LEN];
     99 	return array ? array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] : NULL;
    100 }
    101 
    102 static inline void vlan_group_set_device(struct vlan_group *vg,
    103 					 u16 vlan_id,
    104 					 struct net_device *dev)
    105 {
    106 	struct net_device **array;
    107 	if (!vg)
    108 		return;
    109 	array = vg->vlan_devices_arrays[vlan_id / VLAN_GROUP_ARRAY_PART_LEN];
    110 	array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] = dev;
    111 }
    112 
    113 #define vlan_tx_tag_present(__skb)	((__skb)->vlan_tci & VLAN_TAG_PRESENT)
    114 #define vlan_tx_tag_get(__skb)		((__skb)->vlan_tci & ~VLAN_TAG_PRESENT)
    115 
    116 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
    117 extern struct net_device *vlan_dev_real_dev(const struct net_device *dev);
    118 extern u16 vlan_dev_vlan_id(const struct net_device *dev);
    119 
    120 extern int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
    121 			     u16 vlan_tci, int polling);
    122 extern int vlan_hwaccel_do_receive(struct sk_buff *skb);
    123 extern gro_result_t
    124 vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp,
    125 		 unsigned int vlan_tci, struct sk_buff *skb);
    126 extern gro_result_t
    127 vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp,
    128 	       unsigned int vlan_tci);
    129 
    130 #else
    131 static inline struct net_device *vlan_dev_real_dev(const struct net_device *dev)
    132 {
    133 	BUG();
    134 	return NULL;
    135 }
    136 
    137 static inline u16 vlan_dev_vlan_id(const struct net_device *dev)
    138 {
    139 	BUG();
    140 	return 0;
    141 }
    142 
    143 static inline int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
    144 				    u16 vlan_tci, int polling)
    145 {
    146 	BUG();
    147 	return NET_XMIT_SUCCESS;
    148 }
    149 
    150 static inline int vlan_hwaccel_do_receive(struct sk_buff *skb)
    151 {
    152 	return 0;
    153 }
    154 
    155 static inline gro_result_t
    156 vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp,
    157 		 unsigned int vlan_tci, struct sk_buff *skb)
    158 {
    159 	return GRO_DROP;
    160 }
    161 
    162 static inline gro_result_t
    163 vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp,
    164 	       unsigned int vlan_tci)
    165 {
    166 	return GRO_DROP;
    167 }
    168 #endif
    169 
    170 /**
    171  * vlan_hwaccel_rx - netif_rx wrapper for VLAN RX acceleration
    172  * @skb: buffer
    173  * @grp: vlan group
    174  * @vlan_tci: VLAN TCI as received from the card
    175  */
    176 static inline int vlan_hwaccel_rx(struct sk_buff *skb,
    177 				  struct vlan_group *grp,
    178 				  u16 vlan_tci)
    179 {
    180 	return __vlan_hwaccel_rx(skb, grp, vlan_tci, 0);
    181 }
    182 
    183 /**
    184  * vlan_hwaccel_receive_skb - netif_receive_skb wrapper for VLAN RX acceleration
    185  * @skb: buffer
    186  * @grp: vlan group
    187  * @vlan_tci: VLAN TCI as received from the card
    188  */
    189 static inline int vlan_hwaccel_receive_skb(struct sk_buff *skb,
    190 					   struct vlan_group *grp,
    191 					   u16 vlan_tci)
    192 {
    193 	return __vlan_hwaccel_rx(skb, grp, vlan_tci, 1);
    194 }
    195 
    196 /**
    197  * __vlan_put_tag - regular VLAN tag inserting
    198  * @skb: skbuff to tag
    199  * @vlan_tci: VLAN TCI to insert
    200  *
    201  * Inserts the VLAN tag into @skb as part of the payload
    202  * Returns a VLAN tagged skb. If a new skb is created, @skb is freed.
    203  *
    204  * Following the skb_unshare() example, in case of error, the calling function
    205  * doesn't have to worry about freeing the original skb.
    206  */
    207 static inline struct sk_buff *__vlan_put_tag(struct sk_buff *skb, u16 vlan_tci)
    208 {
    209 	struct vlan_ethhdr *veth;
    210 
    211 	if (skb_cow_head(skb, VLAN_HLEN) < 0) {
    212 		kfree_skb(skb);
    213 		return NULL;
    214 	}
    215 	veth = (struct vlan_ethhdr *)skb_push(skb, VLAN_HLEN);
    216 
    217 	/* Move the mac addresses to the beginning of the new header. */
    218 	memmove(skb->data, skb->data + VLAN_HLEN, 2 * VLAN_ETH_ALEN);
    219 	skb->mac_header -= VLAN_HLEN;
    220 
    221 	/* first, the ethernet type */
    222 	veth->h_vlan_proto = htons(ETH_P_8021Q);
    223 
    224 	/* now, the TCI */
    225 	veth->h_vlan_TCI = htons(vlan_tci);
    226 
    227 	skb->protocol = htons(ETH_P_8021Q);
    228 
    229 	return skb;
    230 }
    231 
    232 /**
    233  * __vlan_hwaccel_put_tag - hardware accelerated VLAN inserting
    234  * @skb: skbuff to tag
    235  * @vlan_tci: VLAN TCI to insert
    236  *
    237  * Puts the VLAN TCI in @skb->vlan_tci and lets the device do the rest
    238  */
    239 static inline struct sk_buff *__vlan_hwaccel_put_tag(struct sk_buff *skb,
    240 						     u16 vlan_tci)
    241 {
    242 	skb->vlan_tci = VLAN_TAG_PRESENT | vlan_tci;
    243 	return skb;
    244 }
    245 
    246 #define HAVE_VLAN_PUT_TAG
    247 
    248 /**
    249  * vlan_put_tag - inserts VLAN tag according to device features
    250  * @skb: skbuff to tag
    251  * @vlan_tci: VLAN TCI to insert
    252  *
    253  * Assumes skb->dev is the target that will xmit this frame.
    254  * Returns a VLAN tagged skb.
    255  */
    256 static inline struct sk_buff *vlan_put_tag(struct sk_buff *skb, u16 vlan_tci)
    257 {
    258 	if (skb->dev->features & NETIF_F_HW_VLAN_TX) {
    259 		return __vlan_hwaccel_put_tag(skb, vlan_tci);
    260 	} else {
    261 		return __vlan_put_tag(skb, vlan_tci);
    262 	}
    263 }
    264 
    265 /**
    266  * __vlan_get_tag - get the VLAN ID that is part of the payload
    267  * @skb: skbuff to query
    268  * @vlan_tci: buffer to store vlaue
    269  *
    270  * Returns error if the skb is not of VLAN type
    271  */
    272 static inline int __vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci)
    273 {
    274 	struct vlan_ethhdr *veth = (struct vlan_ethhdr *)skb->data;
    275 
    276 	if (veth->h_vlan_proto != htons(ETH_P_8021Q)) {
    277 		return -EINVAL;
    278 	}
    279 
    280 	*vlan_tci = ntohs(veth->h_vlan_TCI);
    281 	return 0;
    282 }
    283 
    284 /**
    285  * __vlan_hwaccel_get_tag - get the VLAN ID that is in @skb->cb[]
    286  * @skb: skbuff to query
    287  * @vlan_tci: buffer to store vlaue
    288  *
    289  * Returns error if @skb->vlan_tci is not set correctly
    290  */
    291 static inline int __vlan_hwaccel_get_tag(const struct sk_buff *skb,
    292 					 u16 *vlan_tci)
    293 {
    294 	if (vlan_tx_tag_present(skb)) {
    295 		*vlan_tci = vlan_tx_tag_get(skb);
    296 		return 0;
    297 	} else {
    298 		*vlan_tci = 0;
    299 		return -EINVAL;
    300 	}
    301 }
    302 
    303 #define HAVE_VLAN_GET_TAG
    304 
    305 /**
    306  * vlan_get_tag - get the VLAN ID from the skb
    307  * @skb: skbuff to query
    308  * @vlan_tci: buffer to store vlaue
    309  *
    310  * Returns error if the skb is not VLAN tagged
    311  */
    312 static inline int vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci)
    313 {
    314 	if (skb->dev->features & NETIF_F_HW_VLAN_TX) {
    315 		return __vlan_hwaccel_get_tag(skb, vlan_tci);
    316 	} else {
    317 		return __vlan_get_tag(skb, vlan_tci);
    318 	}
    319 }
    320 
    321 #endif /* __KERNEL__ */
    322 
    323 /* VLAN IOCTLs are found in sockios.h */
    324 
    325 /* Passed in vlan_ioctl_args structure to determine behaviour. */
    326 enum vlan_ioctl_cmds {
    327 	ADD_VLAN_CMD,
    328 	DEL_VLAN_CMD,
    329 	SET_VLAN_INGRESS_PRIORITY_CMD,
    330 	SET_VLAN_EGRESS_PRIORITY_CMD,
    331 	GET_VLAN_INGRESS_PRIORITY_CMD,
    332 	GET_VLAN_EGRESS_PRIORITY_CMD,
    333 	SET_VLAN_NAME_TYPE_CMD,
    334 	SET_VLAN_FLAG_CMD,
    335 	GET_VLAN_REALDEV_NAME_CMD, /* If this works, you know it's a VLAN device, btw */
    336 	GET_VLAN_VID_CMD /* Get the VID of this VLAN (specified by name) */
    337 };
    338 
    339 enum vlan_flags {
    340 	VLAN_FLAG_REORDER_HDR	= 0x1,
    341 	VLAN_FLAG_GVRP		= 0x2,
    342 	VLAN_FLAG_LOOSE_BINDING	= 0x4,
    343 };
    344 
    345 enum vlan_name_types {
    346 	VLAN_NAME_TYPE_PLUS_VID, /* Name will look like:  vlan0005 */
    347 	VLAN_NAME_TYPE_RAW_PLUS_VID, /* name will look like:  eth1.0005 */
    348 	VLAN_NAME_TYPE_PLUS_VID_NO_PAD, /* Name will look like:  vlan5 */
    349 	VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD, /* Name will look like:  eth0.5 */
    350 	VLAN_NAME_TYPE_HIGHEST
    351 };
    352 
    353 struct vlan_ioctl_args {
    354 	int cmd; /* Should be one of the vlan_ioctl_cmds enum above. */
    355 	char device1[24];
    356 
    357         union {
    358 		char device2[24];
    359 		int VID;
    360 		unsigned int skb_priority;
    361 		unsigned int name_type;
    362 		unsigned int bind_type;
    363 		unsigned int flag; /* Matches vlan_dev_info flags */
    364         } u;
    365 
    366 	short vlan_qos;
    367 };
    368 
    369 #endif /* !(_LINUX_IF_VLAN_H_) */
    370