1
2
3
4
5
6
7
8
9
10
11
12
13#ifndef _LINUX_IF_VLAN_H_
14#define _LINUX_IF_VLAN_H_
15
16#ifdef __KERNEL__
17
18
19struct hlist_node;
20
21#include <linux/netdevice.h>
22#include <linux/etherdevice.h>
23
24#define VLAN_HLEN 4
25
26
27#define VLAN_ETH_ALEN 6
28#define VLAN_ETH_HLEN 18
29#define VLAN_ETH_ZLEN 64
30
31
32
33
34#define VLAN_ETH_DATA_LEN 1500
35#define VLAN_ETH_FRAME_LEN 1518
36
37
38
39
40
41
42struct vlan_hdr {
43 __be16 h_vlan_TCI;
44 __be16 h_vlan_encapsulated_proto;
45};
46
47
48
49
50
51
52
53
54
55struct vlan_ethhdr {
56 unsigned char h_dest[ETH_ALEN];
57 unsigned char h_source[ETH_ALEN];
58 __be16 h_vlan_proto;
59 __be16 h_vlan_TCI;
60 __be16 h_vlan_encapsulated_proto;
61};
62
63#include <linux/skbuff.h>
64
65static inline struct vlan_ethhdr *vlan_eth_hdr(const struct sk_buff *skb)
66{
67 return (struct vlan_ethhdr *)skb_mac_header(skb);
68}
69
70#define VLAN_VID_MASK 0xfff
71
72
73extern void vlan_ioctl_set(int (*hook)(struct net *, void __user *));
74
75
76
77
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
83struct vlan_group {
84 struct net_device *real_dev;
85
86
87 unsigned int nr_vlans;
88 struct hlist_node hlist;
89 struct net_device **vlan_devices_arrays[VLAN_GROUP_ARRAY_SPLIT_PARTS];
90 struct rcu_head rcu;
91};
92
93static inline struct net_device *vlan_group_get_device(struct vlan_group *vg,
94 unsigned int vlan_id)
95{
96 struct net_device **array;
97 array = vg->vlan_devices_arrays[vlan_id / VLAN_GROUP_ARRAY_PART_LEN];
98 return array ? array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] : NULL;
99}
100
101static inline void vlan_group_set_device(struct vlan_group *vg,
102 unsigned int vlan_id,
103 struct net_device *dev)
104{
105 struct net_device **array;
106 if (!vg)
107 return;
108 array = vg->vlan_devices_arrays[vlan_id / VLAN_GROUP_ARRAY_PART_LEN];
109 array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] = dev;
110}
111
112struct vlan_priority_tci_mapping {
113 u32 priority;
114 unsigned short vlan_qos;
115
116
117
118 struct vlan_priority_tci_mapping *next;
119};
120
121
122struct vlan_dev_info {
123
124
125
126 unsigned int nr_ingress_mappings;
127 u32 ingress_priority_map[8];
128
129 unsigned int nr_egress_mappings;
130 struct vlan_priority_tci_mapping *egress_priority_map[16];
131
132 unsigned short vlan_id;
133 unsigned short flags;
134
135
136
137
138
139
140
141 struct net_device *real_dev;
142 unsigned char real_dev_addr[ETH_ALEN];
143 struct proc_dir_entry *dent;
144 unsigned long cnt_inc_headroom_on_tx;
145 unsigned long cnt_encap_on_xmit;
146};
147
148static inline struct vlan_dev_info *vlan_dev_info(const struct net_device *dev)
149{
150 return netdev_priv(dev);
151}
152
153
154static inline __u32 vlan_get_ingress_priority(struct net_device *dev,
155 unsigned short vlan_tag)
156{
157 struct vlan_dev_info *vip = vlan_dev_info(dev);
158
159 return vip->ingress_priority_map[(vlan_tag >> 13) & 0x7];
160}
161
162
163struct vlan_skb_tx_cookie {
164 u32 magic;
165 u32 vlan_tag;
166};
167
168#define VLAN_TX_COOKIE_MAGIC 0x564c414e
169#define VLAN_TX_SKB_CB(__skb) ((struct vlan_skb_tx_cookie *)&((__skb)->cb[0]))
170#define vlan_tx_tag_present(__skb) \
171 (VLAN_TX_SKB_CB(__skb)->magic == VLAN_TX_COOKIE_MAGIC)
172#define vlan_tx_tag_get(__skb) (VLAN_TX_SKB_CB(__skb)->vlan_tag)
173
174
175static inline int __vlan_hwaccel_rx(struct sk_buff *skb,
176 struct vlan_group *grp,
177 unsigned short vlan_tag, int polling)
178{
179 struct net_device_stats *stats;
180
181 if (skb_bond_should_drop(skb)) {
182 dev_kfree_skb_any(skb);
183 return NET_RX_DROP;
184 }
185
186 skb->dev = vlan_group_get_device(grp, vlan_tag & VLAN_VID_MASK);
187 if (skb->dev == NULL) {
188 dev_kfree_skb_any(skb);
189
190
191
192
193 return 0;
194 }
195
196 skb->dev->last_rx = jiffies;
197
198 stats = &skb->dev->stats;
199 stats->rx_packets++;
200 stats->rx_bytes += skb->len;
201
202 skb->priority = vlan_get_ingress_priority(skb->dev, vlan_tag);
203 switch (skb->pkt_type) {
204 case PACKET_BROADCAST:
205 break;
206
207 case PACKET_MULTICAST:
208 stats->multicast++;
209 break;
210
211 case PACKET_OTHERHOST:
212
213
214
215
216 if (!compare_ether_addr(eth_hdr(skb)->h_dest,
217 skb->dev->dev_addr))
218 skb->pkt_type = PACKET_HOST;
219 break;
220 };
221
222 return (polling ? netif_receive_skb(skb) : netif_rx(skb));
223}
224
225static inline int vlan_hwaccel_rx(struct sk_buff *skb,
226 struct vlan_group *grp,
227 unsigned short vlan_tag)
228{
229 return __vlan_hwaccel_rx(skb, grp, vlan_tag, 0);
230}
231
232static inline int vlan_hwaccel_receive_skb(struct sk_buff *skb,
233 struct vlan_group *grp,
234 unsigned short vlan_tag)
235{
236 return __vlan_hwaccel_rx(skb, grp, vlan_tag, 1);
237}
238
239
240
241
242
243
244
245
246
247
248
249
250static inline struct sk_buff *__vlan_put_tag(struct sk_buff *skb, unsigned short tag)
251{
252 struct vlan_ethhdr *veth;
253
254 if (skb_headroom(skb) < VLAN_HLEN) {
255 struct sk_buff *sk_tmp = skb;
256 skb = skb_realloc_headroom(sk_tmp, VLAN_HLEN);
257 kfree_skb(sk_tmp);
258 if (!skb) {
259 printk(KERN_ERR "vlan: failed to realloc headroom\n");
260 return NULL;
261 }
262 } else {
263 skb = skb_unshare(skb, GFP_ATOMIC);
264 if (!skb) {
265 printk(KERN_ERR "vlan: failed to unshare skbuff\n");
266 return NULL;
267 }
268 }
269
270 veth = (struct vlan_ethhdr *)skb_push(skb, VLAN_HLEN);
271
272
273 memmove(skb->data, skb->data + VLAN_HLEN, 2 * VLAN_ETH_ALEN);
274
275
276 veth->h_vlan_proto = htons(ETH_P_8021Q);
277
278
279 veth->h_vlan_TCI = htons(tag);
280
281 skb->protocol = htons(ETH_P_8021Q);
282 skb->mac_header -= VLAN_HLEN;
283 skb->network_header -= VLAN_HLEN;
284
285 return skb;
286}
287
288
289
290
291
292
293
294
295static inline struct sk_buff *__vlan_hwaccel_put_tag(struct sk_buff *skb, unsigned short tag)
296{
297 struct vlan_skb_tx_cookie *cookie;
298
299 cookie = VLAN_TX_SKB_CB(skb);
300 cookie->magic = VLAN_TX_COOKIE_MAGIC;
301 cookie->vlan_tag = tag;
302
303 return skb;
304}
305
306#define HAVE_VLAN_PUT_TAG
307
308
309
310
311
312
313
314
315
316static inline struct sk_buff *vlan_put_tag(struct sk_buff *skb, unsigned short tag)
317{
318 if (skb->dev->features & NETIF_F_HW_VLAN_TX) {
319 return __vlan_hwaccel_put_tag(skb, tag);
320 } else {
321 return __vlan_put_tag(skb, tag);
322 }
323}
324
325
326
327
328
329
330
331
332static inline int __vlan_get_tag(const struct sk_buff *skb, unsigned short *tag)
333{
334 struct vlan_ethhdr *veth = (struct vlan_ethhdr *)skb->data;
335
336 if (veth->h_vlan_proto != htons(ETH_P_8021Q)) {
337 return -EINVAL;
338 }
339
340 *tag = ntohs(veth->h_vlan_TCI);
341
342 return 0;
343}
344
345
346
347
348
349
350
351
352static inline int __vlan_hwaccel_get_tag(const struct sk_buff *skb,
353 unsigned short *tag)
354{
355 struct vlan_skb_tx_cookie *cookie;
356
357 cookie = VLAN_TX_SKB_CB(skb);
358 if (cookie->magic == VLAN_TX_COOKIE_MAGIC) {
359 *tag = cookie->vlan_tag;
360 return 0;
361 } else {
362 *tag = 0;
363 return -EINVAL;
364 }
365}
366
367#define HAVE_VLAN_GET_TAG
368
369
370
371
372
373
374
375
376static inline int vlan_get_tag(const struct sk_buff *skb, unsigned short *tag)
377{
378 if (skb->dev->features & NETIF_F_HW_VLAN_TX) {
379 return __vlan_hwaccel_get_tag(skb, tag);
380 } else {
381 return __vlan_get_tag(skb, tag);
382 }
383}
384
385#endif
386
387
388
389
390enum vlan_ioctl_cmds {
391 ADD_VLAN_CMD,
392 DEL_VLAN_CMD,
393 SET_VLAN_INGRESS_PRIORITY_CMD,
394 SET_VLAN_EGRESS_PRIORITY_CMD,
395 GET_VLAN_INGRESS_PRIORITY_CMD,
396 GET_VLAN_EGRESS_PRIORITY_CMD,
397 SET_VLAN_NAME_TYPE_CMD,
398 SET_VLAN_FLAG_CMD,
399 GET_VLAN_REALDEV_NAME_CMD,
400 GET_VLAN_VID_CMD
401};
402
403enum vlan_flags {
404 VLAN_FLAG_REORDER_HDR = 0x1,
405};
406
407enum vlan_name_types {
408 VLAN_NAME_TYPE_PLUS_VID,
409 VLAN_NAME_TYPE_RAW_PLUS_VID,
410 VLAN_NAME_TYPE_PLUS_VID_NO_PAD,
411 VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD,
412 VLAN_NAME_TYPE_HIGHEST
413};
414
415struct vlan_ioctl_args {
416 int cmd;
417 char device1[24];
418
419 union {
420 char device2[24];
421 int VID;
422 unsigned int skb_priority;
423 unsigned int name_type;
424 unsigned int bind_type;
425 unsigned int flag;
426 } u;
427
428 short vlan_qos;
429};
430
431#endif
432