patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / include / linux / if_vlan.h
1 /*
2  * VLAN         An implementation of 802.1Q VLAN tagging.
3  *
4  * Authors:     Ben Greear <greearb@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
18 /* externally defined structs */
19 struct vlan_group;
20 struct net_device;
21 struct sk_buff;
22 struct packet_type;
23 struct vlan_collection;
24 struct vlan_dev_info;
25
26 #include <linux/proc_fs.h> /* for proc_dir_entry */
27 #include <linux/netdevice.h>
28
29 #define VLAN_HLEN       4               /* The additional bytes (on top of the Ethernet header)
30                                          * that VLAN requires.
31                                          */
32 #define VLAN_ETH_ALEN   6               /* Octets in one ethernet addr   */
33 #define VLAN_ETH_HLEN   18              /* Total octets in header.       */
34 #define VLAN_ETH_ZLEN   64              /* Min. octets in frame sans FCS */
35
36 /*
37  * According to 802.3ac, the packet can be 4 bytes longer. --Klika Jan
38  */
39 #define VLAN_ETH_DATA_LEN       1500    /* Max. octets in payload        */
40 #define VLAN_ETH_FRAME_LEN      1518    /* Max. octets in frame sans FCS */
41
42 struct vlan_ethhdr {
43    unsigned char        h_dest[ETH_ALEN];          /* destination eth addr      */
44    unsigned char        h_source[ETH_ALEN];        /* source ether addr */
45    unsigned short       h_vlan_proto;              /* Should always be 0x8100 */
46    unsigned short       h_vlan_TCI;                /* Encapsulates priority and VLAN ID */
47    unsigned short       h_vlan_encapsulated_proto; /* packet type ID field (or len) */
48 };
49
50 struct vlan_hdr {
51    unsigned short       h_vlan_TCI;                /* Encapsulates priority and VLAN ID */
52    unsigned short       h_vlan_encapsulated_proto; /* packet type ID field (or len) */
53 };
54
55 #define VLAN_VID_MASK   0xfff
56
57 /* found in socket.c */
58 extern void vlan_ioctl_set(int (*hook)(void __user *));
59
60 #define VLAN_NAME "vlan"
61
62 /* if this changes, algorithm will have to be reworked because this
63  * depends on completely exhausting the VLAN identifier space.  Thus
64  * it gives constant time look-up, but in many cases it wastes memory.
65  */
66 #define VLAN_GROUP_ARRAY_LEN 4096
67
68 struct vlan_group {
69         int real_dev_ifindex; /* The ifindex of the ethernet(like) device the vlan is attached to. */
70         struct net_device *vlan_devices[VLAN_GROUP_ARRAY_LEN];
71
72         struct vlan_group *next; /* the next in the list */
73 };
74
75 struct vlan_priority_tci_mapping {
76         unsigned long priority;
77         unsigned short vlan_qos; /* This should be shifted when first set, so we only do it
78                                   * at provisioning time.
79                                   * ((skb->priority << 13) & 0xE000)
80                                   */
81         struct vlan_priority_tci_mapping *next;
82 };
83
84 /* Holds information that makes sense if this device is a VLAN device. */
85 struct vlan_dev_info {
86         /** This will be the mapping that correlates skb->priority to
87          * 3 bits of VLAN QOS tags...
88          */
89         unsigned long ingress_priority_map[8];
90         struct vlan_priority_tci_mapping *egress_priority_map[16]; /* hash table */
91
92         unsigned short vlan_id;        /*  The VLAN Identifier for this interface. */
93         unsigned short flags;          /* (1 << 0) re_order_header   This option will cause the
94                                         *   VLAN code to move around the ethernet header on
95                                         *   ingress to make the skb look **exactly** like it
96                                         *   came in from an ethernet port.  This destroys some of
97                                         *   the VLAN information in the skb, but it fixes programs
98                                         *   like DHCP that use packet-filtering and don't understand
99                                         *   802.1Q
100                                         */
101         struct dev_mc_list *old_mc_list;  /* old multi-cast list for the VLAN interface..
102                                            * we save this so we can tell what changes were
103                                            * made, in order to feed the right changes down
104                                            * to the real hardware...
105                                            */
106         int old_allmulti;               /* similar to above. */
107         int old_promiscuity;            /* similar to above. */
108         struct net_device *real_dev;    /* the underlying device/interface */
109         struct proc_dir_entry *dent;    /* Holds the proc data */
110         unsigned long cnt_inc_headroom_on_tx; /* How many times did we have to grow the skb on TX. */
111         unsigned long cnt_encap_on_xmit;      /* How many times did we have to encapsulate the skb on TX. */
112         struct net_device_stats dev_stats; /* Device stats (rx-bytes, tx-pkts, etc...) */
113 };
114
115 #define VLAN_DEV_INFO(x) ((struct vlan_dev_info *)(x->priv))
116
117 /* inline functions */
118
119 static inline struct net_device_stats *vlan_dev_get_stats(struct net_device *dev)
120 {
121         return &(VLAN_DEV_INFO(dev)->dev_stats);
122 }
123
124 static inline __u32 vlan_get_ingress_priority(struct net_device *dev,
125                                               unsigned short vlan_tag)
126 {
127         struct vlan_dev_info *vip = VLAN_DEV_INFO(dev);
128
129         return vip->ingress_priority_map[(vlan_tag >> 13) & 0x7];
130 }
131
132 /* VLAN tx hw acceleration helpers. */
133 struct vlan_skb_tx_cookie {
134         u32     magic;
135         u32     vlan_tag;
136 };
137
138 #define VLAN_TX_COOKIE_MAGIC    0x564c414e      /* "VLAN" in ascii. */
139 #define VLAN_TX_SKB_CB(__skb)   ((struct vlan_skb_tx_cookie *)&((__skb)->cb[0]))
140 #define vlan_tx_tag_present(__skb) \
141         (VLAN_TX_SKB_CB(__skb)->magic == VLAN_TX_COOKIE_MAGIC)
142 #define vlan_tx_tag_get(__skb)  (VLAN_TX_SKB_CB(__skb)->vlan_tag)
143
144 /* VLAN rx hw acceleration helper.  This acts like netif_{rx,receive_skb}(). */
145 static inline int __vlan_hwaccel_rx(struct sk_buff *skb,
146                                     struct vlan_group *grp,
147                                     unsigned short vlan_tag, int polling)
148 {
149         struct net_device_stats *stats;
150
151         skb->real_dev = skb->dev;
152         skb->dev = grp->vlan_devices[vlan_tag & VLAN_VID_MASK];
153         if (skb->dev == NULL) {
154                 kfree_skb(skb);
155
156                 /* Not NET_RX_DROP, this is not being dropped
157                  * due to congestion.
158                  */
159                 return 0;
160         }
161
162         skb->dev->last_rx = jiffies;
163
164         stats = vlan_dev_get_stats(skb->dev);
165         stats->rx_packets++;
166         stats->rx_bytes += skb->len;
167
168         skb->priority = vlan_get_ingress_priority(skb->dev, vlan_tag);
169         switch (skb->pkt_type) {
170         case PACKET_BROADCAST:
171                 break;
172
173         case PACKET_MULTICAST:
174                 stats->multicast++;
175                 break;
176
177         case PACKET_OTHERHOST:
178                 /* Our lower layer thinks this is not local, let's make sure.
179                  * This allows the VLAN to have a different MAC than the underlying
180                  * device, and still route correctly.
181                  */
182                 if (!memcmp(skb->mac.ethernet->h_dest, skb->dev->dev_addr, ETH_ALEN))
183                         skb->pkt_type = PACKET_HOST;
184                 break;
185         };
186
187         return (polling ? netif_receive_skb(skb) : netif_rx(skb));
188 }
189
190 static inline int vlan_hwaccel_rx(struct sk_buff *skb,
191                                   struct vlan_group *grp,
192                                   unsigned short vlan_tag)
193 {
194         return __vlan_hwaccel_rx(skb, grp, vlan_tag, 0);
195 }
196
197 static inline int vlan_hwaccel_receive_skb(struct sk_buff *skb,
198                                            struct vlan_group *grp,
199                                            unsigned short vlan_tag)
200 {
201         return __vlan_hwaccel_rx(skb, grp, vlan_tag, 1);
202 }
203
204 /**
205  * __vlan_put_tag - regular VLAN tag inserting
206  * @skb: skbuff to tag
207  * @tag: VLAN tag to insert
208  *
209  * Inserts the VLAN tag into @skb as part of the payload
210  * Returns a VLAN tagged skb. If a new skb is created, @skb is freed.
211  * 
212  * Following the skb_unshare() example, in case of error, the calling function
213  * doesn't have to worry about freeing the original skb.
214  */
215 static inline struct sk_buff *__vlan_put_tag(struct sk_buff *skb, unsigned short tag)
216 {
217         struct vlan_ethhdr *veth;
218
219         if (skb_headroom(skb) < VLAN_HLEN) {
220                 struct sk_buff *sk_tmp = skb;
221                 skb = skb_realloc_headroom(sk_tmp, VLAN_HLEN);
222                 kfree_skb(sk_tmp);
223                 if (!skb) {
224                         printk(KERN_ERR "vlan: failed to realloc headroom\n");
225                         return NULL;
226                 }
227         } else {
228                 skb = skb_unshare(skb, GFP_ATOMIC);
229                 if (!skb) {
230                         printk(KERN_ERR "vlan: failed to unshare skbuff\n");
231                         return NULL;
232                 }
233         }
234
235         veth = (struct vlan_ethhdr *)skb_push(skb, VLAN_HLEN);
236
237         /* Move the mac addresses to the beginning of the new header. */
238         memmove(skb->data, skb->data + VLAN_HLEN, 2 * VLAN_ETH_ALEN);
239
240         /* first, the ethernet type */
241         veth->h_vlan_proto = __constant_htons(ETH_P_8021Q);
242
243         /* now, the tag */
244         veth->h_vlan_TCI = htons(tag);
245
246         skb->protocol = __constant_htons(ETH_P_8021Q);
247         skb->mac.raw -= VLAN_HLEN;
248         skb->nh.raw -= VLAN_HLEN;
249
250         return skb;
251 }
252
253 /**
254  * __vlan_hwaccel_put_tag - hardware accelerated VLAN inserting
255  * @skb: skbuff to tag
256  * @tag: VLAN tag to insert
257  *
258  * Puts the VLAN tag in @skb->cb[] and lets the device do the rest
259  */
260 static inline struct sk_buff *__vlan_hwaccel_put_tag(struct sk_buff *skb, unsigned short tag)
261 {
262         struct vlan_skb_tx_cookie *cookie;
263
264         cookie = VLAN_TX_SKB_CB(skb);
265         cookie->magic = VLAN_TX_COOKIE_MAGIC;
266         cookie->vlan_tag = tag;
267
268         return skb;
269 }
270
271 #define HAVE_VLAN_PUT_TAG
272
273 /**
274  * vlan_put_tag - inserts VLAN tag according to device features
275  * @skb: skbuff to tag
276  * @tag: VLAN tag to insert
277  *
278  * Assumes skb->dev is the target that will xmit this frame.
279  * Returns a VLAN tagged skb.
280  */
281 static inline struct sk_buff *vlan_put_tag(struct sk_buff *skb, unsigned short tag)
282 {
283         if (skb->dev->features & NETIF_F_HW_VLAN_TX) {
284                 return __vlan_hwaccel_put_tag(skb, tag);
285         } else {
286                 return __vlan_put_tag(skb, tag);
287         }
288 }
289
290 /**
291  * __vlan_get_tag - get the VLAN ID that is part of the payload
292  * @skb: skbuff to query
293  * @tag: buffer to store vlaue
294  * 
295  * Returns error if the skb is not of VLAN type
296  */
297 static inline int __vlan_get_tag(struct sk_buff *skb, unsigned short *tag)
298 {
299         struct vlan_ethhdr *veth = (struct vlan_ethhdr *)skb->data;
300
301         if (veth->h_vlan_proto != __constant_htons(ETH_P_8021Q)) {
302                 return -EINVAL;
303         }
304
305         *tag = ntohs(veth->h_vlan_TCI);
306
307         return 0;
308 }
309
310 /**
311  * __vlan_hwaccel_get_tag - get the VLAN ID that is in @skb->cb[]
312  * @skb: skbuff to query
313  * @tag: buffer to store vlaue
314  * 
315  * Returns error if @skb->cb[] is not set correctly
316  */
317 static inline int __vlan_hwaccel_get_tag(struct sk_buff *skb, unsigned short *tag)
318 {
319         struct vlan_skb_tx_cookie *cookie;
320
321         cookie = VLAN_TX_SKB_CB(skb);
322         if (cookie->magic == VLAN_TX_COOKIE_MAGIC) {
323                 *tag = cookie->vlan_tag;
324                 return 0;
325         } else {
326                 *tag = 0;
327                 return -EINVAL;
328         }
329 }
330
331 #define HAVE_VLAN_GET_TAG
332
333 /**
334  * vlan_get_tag - get the VLAN ID from the skb
335  * @skb: skbuff to query
336  * @tag: buffer to store vlaue
337  * 
338  * Returns error if the skb is not VLAN tagged
339  */
340 static inline int vlan_get_tag(struct sk_buff *skb, unsigned short *tag)
341 {
342         if (skb->dev->features & NETIF_F_HW_VLAN_TX) {
343                 return __vlan_hwaccel_get_tag(skb, tag);
344         } else {
345                 return __vlan_get_tag(skb, tag);
346         }
347 }
348
349 #endif /* __KERNEL__ */
350
351 /* VLAN IOCTLs are found in sockios.h */
352
353 /* Passed in vlan_ioctl_args structure to determine behaviour. */
354 enum vlan_ioctl_cmds {
355         ADD_VLAN_CMD,
356         DEL_VLAN_CMD,
357         SET_VLAN_INGRESS_PRIORITY_CMD,
358         SET_VLAN_EGRESS_PRIORITY_CMD,
359         GET_VLAN_INGRESS_PRIORITY_CMD,
360         GET_VLAN_EGRESS_PRIORITY_CMD,
361         SET_VLAN_NAME_TYPE_CMD,
362         SET_VLAN_FLAG_CMD
363 };
364
365 enum vlan_name_types {
366         VLAN_NAME_TYPE_PLUS_VID, /* Name will look like:  vlan0005 */
367         VLAN_NAME_TYPE_RAW_PLUS_VID, /* name will look like:  eth1.0005 */
368         VLAN_NAME_TYPE_PLUS_VID_NO_PAD, /* Name will look like:  vlan5 */
369         VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD, /* Name will look like:  eth0.5 */
370         VLAN_NAME_TYPE_HIGHEST
371 };
372
373 struct vlan_ioctl_args {
374         int cmd; /* Should be one of the vlan_ioctl_cmds enum above. */
375         char device1[24];
376
377         union {
378                 char device2[24];
379                 int VID;
380                 unsigned int skb_priority;
381                 unsigned int name_type;
382                 unsigned int bind_type;
383                 unsigned int flag; /* Matches vlan_dev_info flags */
384         } u;
385
386         short vlan_qos;   
387 };
388
389 #endif /* !(_LINUX_IF_VLAN_H_) */