linux/include/linux/if_vlan.h
<<
>>
Prefs
   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#include <linux/netdevice.h>
  18#include <linux/etherdevice.h>
  19#include <linux/rtnetlink.h>
  20
  21#define VLAN_HLEN       4               /* The additional bytes (on top of the Ethernet header)
  22                                         * that VLAN requires.
  23                                         */
  24#define VLAN_ETH_ALEN   6               /* Octets in one ethernet addr   */
  25#define VLAN_ETH_HLEN   18              /* Total octets in header.       */
  26#define VLAN_ETH_ZLEN   64              /* Min. octets in frame sans FCS */
  27
  28/*
  29 * According to 802.3ac, the packet can be 4 bytes longer. --Klika Jan
  30 */
  31#define VLAN_ETH_DATA_LEN       1500    /* Max. octets in payload        */
  32#define VLAN_ETH_FRAME_LEN      1518    /* Max. octets in frame sans FCS */
  33
  34/*
  35 *      struct vlan_hdr - vlan header
  36 *      @h_vlan_TCI: priority and VLAN ID
  37 *      @h_vlan_encapsulated_proto: packet type ID or len
  38 */
  39struct vlan_hdr {
  40        __be16  h_vlan_TCI;
  41        __be16  h_vlan_encapsulated_proto;
  42};
  43
  44/**
  45 *      struct vlan_ethhdr - vlan ethernet header (ethhdr + vlan_hdr)
  46 *      @h_dest: destination ethernet address
  47 *      @h_source: source ethernet address
  48 *      @h_vlan_proto: ethernet protocol (always 0x8100)
  49 *      @h_vlan_TCI: priority and VLAN ID
  50 *      @h_vlan_encapsulated_proto: packet type ID or len
  51 */
  52struct vlan_ethhdr {
  53        unsigned char   h_dest[ETH_ALEN];
  54        unsigned char   h_source[ETH_ALEN];
  55        __be16          h_vlan_proto;
  56        __be16          h_vlan_TCI;
  57        __be16          h_vlan_encapsulated_proto;
  58};
  59
  60#include <linux/skbuff.h>
  61
  62static inline struct vlan_ethhdr *vlan_eth_hdr(const struct sk_buff *skb)
  63{
  64        return (struct vlan_ethhdr *)skb_mac_header(skb);
  65}
  66
  67#define VLAN_PRIO_MASK          0xe000 /* Priority Code Point */
  68#define VLAN_PRIO_SHIFT         13
  69#define VLAN_CFI_MASK           0x1000 /* Canonical Format Indicator */
  70#define VLAN_TAG_PRESENT        VLAN_CFI_MASK
  71#define VLAN_VID_MASK           0x0fff /* VLAN Identifier */
  72#define VLAN_N_VID              4096
  73
  74/* found in socket.c */
  75extern void vlan_ioctl_set(int (*hook)(struct net *, void __user *));
  76
  77struct vlan_info;
  78
  79static inline int is_vlan_dev(struct net_device *dev)
  80{
  81        return dev->priv_flags & IFF_802_1Q_VLAN;
  82}
  83
  84#define vlan_tx_tag_present(__skb)      ((__skb)->vlan_tci & VLAN_TAG_PRESENT)
  85#define vlan_tx_tag_get(__skb)          ((__skb)->vlan_tci & ~VLAN_TAG_PRESENT)
  86
  87#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
  88
  89extern struct net_device *__vlan_find_dev_deep(struct net_device *real_dev,
  90                                               u16 vlan_id);
  91extern struct net_device *vlan_dev_real_dev(const struct net_device *dev);
  92extern u16 vlan_dev_vlan_id(const struct net_device *dev);
  93
  94extern bool vlan_do_receive(struct sk_buff **skb, bool last_handler);
  95extern struct sk_buff *vlan_untag(struct sk_buff *skb);
  96
  97extern int vlan_vid_add(struct net_device *dev, unsigned short vid);
  98extern void vlan_vid_del(struct net_device *dev, unsigned short vid);
  99
 100extern int vlan_vids_add_by_dev(struct net_device *dev,
 101                                const struct net_device *by_dev);
 102extern void vlan_vids_del_by_dev(struct net_device *dev,
 103                                 const struct net_device *by_dev);
 104#else
 105static inline struct net_device *
 106__vlan_find_dev_deep(struct net_device *real_dev, u16 vlan_id)
 107{
 108        return NULL;
 109}
 110
 111static inline struct net_device *vlan_dev_real_dev(const struct net_device *dev)
 112{
 113        BUG();
 114        return NULL;
 115}
 116
 117static inline u16 vlan_dev_vlan_id(const struct net_device *dev)
 118{
 119        BUG();
 120        return 0;
 121}
 122
 123static inline bool vlan_do_receive(struct sk_buff **skb, bool last_handler)
 124{
 125        if (((*skb)->vlan_tci & VLAN_VID_MASK) && last_handler)
 126                (*skb)->pkt_type = PACKET_OTHERHOST;
 127        return false;
 128}
 129
 130static inline struct sk_buff *vlan_untag(struct sk_buff *skb)
 131{
 132        return skb;
 133}
 134
 135static inline int vlan_vid_add(struct net_device *dev, unsigned short vid)
 136{
 137        return 0;
 138}
 139
 140static inline void vlan_vid_del(struct net_device *dev, unsigned short vid)
 141{
 142}
 143
 144static inline int vlan_vids_add_by_dev(struct net_device *dev,
 145                                       const struct net_device *by_dev)
 146{
 147        return 0;
 148}
 149
 150static inline void vlan_vids_del_by_dev(struct net_device *dev,
 151                                        const struct net_device *by_dev)
 152{
 153}
 154#endif
 155
 156/**
 157 * vlan_insert_tag - regular VLAN tag inserting
 158 * @skb: skbuff to tag
 159 * @vlan_tci: VLAN TCI to insert
 160 *
 161 * Inserts the VLAN tag into @skb as part of the payload
 162 * Returns a VLAN tagged skb. If a new skb is created, @skb is freed.
 163 *
 164 * Following the skb_unshare() example, in case of error, the calling function
 165 * doesn't have to worry about freeing the original skb.
 166 *
 167 * Does not change skb->protocol so this function can be used during receive.
 168 */
 169static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb, u16 vlan_tci)
 170{
 171        struct vlan_ethhdr *veth;
 172
 173        if (skb_cow_head(skb, VLAN_HLEN) < 0) {
 174                kfree_skb(skb);
 175                return NULL;
 176        }
 177        veth = (struct vlan_ethhdr *)skb_push(skb, VLAN_HLEN);
 178
 179        /* Move the mac addresses to the beginning of the new header. */
 180        memmove(skb->data, skb->data + VLAN_HLEN, 2 * VLAN_ETH_ALEN);
 181        skb->mac_header -= VLAN_HLEN;
 182
 183        /* first, the ethernet type */
 184        veth->h_vlan_proto = htons(ETH_P_8021Q);
 185
 186        /* now, the TCI */
 187        veth->h_vlan_TCI = htons(vlan_tci);
 188
 189        return skb;
 190}
 191
 192/**
 193 * __vlan_put_tag - regular VLAN tag inserting
 194 * @skb: skbuff to tag
 195 * @vlan_tci: VLAN TCI to insert
 196 *
 197 * Inserts the VLAN tag into @skb as part of the payload
 198 * Returns a VLAN tagged skb. If a new skb is created, @skb is freed.
 199 *
 200 * Following the skb_unshare() example, in case of error, the calling function
 201 * doesn't have to worry about freeing the original skb.
 202 */
 203static inline struct sk_buff *__vlan_put_tag(struct sk_buff *skb, u16 vlan_tci)
 204{
 205        skb = vlan_insert_tag(skb, vlan_tci);
 206        if (skb)
 207                skb->protocol = htons(ETH_P_8021Q);
 208        return skb;
 209}
 210
 211/**
 212 * __vlan_hwaccel_put_tag - hardware accelerated VLAN inserting
 213 * @skb: skbuff to tag
 214 * @vlan_tci: VLAN TCI to insert
 215 *
 216 * Puts the VLAN TCI in @skb->vlan_tci and lets the device do the rest
 217 */
 218static inline struct sk_buff *__vlan_hwaccel_put_tag(struct sk_buff *skb,
 219                                                     u16 vlan_tci)
 220{
 221        skb->vlan_tci = VLAN_TAG_PRESENT | vlan_tci;
 222        return skb;
 223}
 224
 225#define HAVE_VLAN_PUT_TAG
 226
 227/**
 228 * vlan_put_tag - inserts VLAN tag according to device features
 229 * @skb: skbuff to tag
 230 * @vlan_tci: VLAN TCI to insert
 231 *
 232 * Assumes skb->dev is the target that will xmit this frame.
 233 * Returns a VLAN tagged skb.
 234 */
 235static inline struct sk_buff *vlan_put_tag(struct sk_buff *skb, u16 vlan_tci)
 236{
 237        if (skb->dev->features & NETIF_F_HW_VLAN_TX) {
 238                return __vlan_hwaccel_put_tag(skb, vlan_tci);
 239        } else {
 240                return __vlan_put_tag(skb, vlan_tci);
 241        }
 242}
 243
 244/**
 245 * __vlan_get_tag - get the VLAN ID that is part of the payload
 246 * @skb: skbuff to query
 247 * @vlan_tci: buffer to store vlaue
 248 *
 249 * Returns error if the skb is not of VLAN type
 250 */
 251static inline int __vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci)
 252{
 253        struct vlan_ethhdr *veth = (struct vlan_ethhdr *)skb->data;
 254
 255        if (veth->h_vlan_proto != htons(ETH_P_8021Q)) {
 256                return -EINVAL;
 257        }
 258
 259        *vlan_tci = ntohs(veth->h_vlan_TCI);
 260        return 0;
 261}
 262
 263/**
 264 * __vlan_hwaccel_get_tag - get the VLAN ID that is in @skb->cb[]
 265 * @skb: skbuff to query
 266 * @vlan_tci: buffer to store vlaue
 267 *
 268 * Returns error if @skb->vlan_tci is not set correctly
 269 */
 270static inline int __vlan_hwaccel_get_tag(const struct sk_buff *skb,
 271                                         u16 *vlan_tci)
 272{
 273        if (vlan_tx_tag_present(skb)) {
 274                *vlan_tci = vlan_tx_tag_get(skb);
 275                return 0;
 276        } else {
 277                *vlan_tci = 0;
 278                return -EINVAL;
 279        }
 280}
 281
 282#define HAVE_VLAN_GET_TAG
 283
 284/**
 285 * vlan_get_tag - get the VLAN ID from the skb
 286 * @skb: skbuff to query
 287 * @vlan_tci: buffer to store vlaue
 288 *
 289 * Returns error if the skb is not VLAN tagged
 290 */
 291static inline int vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci)
 292{
 293        if (skb->dev->features & NETIF_F_HW_VLAN_TX) {
 294                return __vlan_hwaccel_get_tag(skb, vlan_tci);
 295        } else {
 296                return __vlan_get_tag(skb, vlan_tci);
 297        }
 298}
 299
 300/**
 301 * vlan_get_protocol - get protocol EtherType.
 302 * @skb: skbuff to query
 303 *
 304 * Returns the EtherType of the packet, regardless of whether it is
 305 * vlan encapsulated (normal or hardware accelerated) or not.
 306 */
 307static inline __be16 vlan_get_protocol(const struct sk_buff *skb)
 308{
 309        __be16 protocol = 0;
 310
 311        if (vlan_tx_tag_present(skb) ||
 312             skb->protocol != cpu_to_be16(ETH_P_8021Q))
 313                protocol = skb->protocol;
 314        else {
 315                __be16 proto, *protop;
 316                protop = skb_header_pointer(skb, offsetof(struct vlan_ethhdr,
 317                                                h_vlan_encapsulated_proto),
 318                                                sizeof(proto), &proto);
 319                if (likely(protop))
 320                        protocol = *protop;
 321        }
 322
 323        return protocol;
 324}
 325
 326static inline void vlan_set_encap_proto(struct sk_buff *skb,
 327                                        struct vlan_hdr *vhdr)
 328{
 329        __be16 proto;
 330        unsigned char *rawp;
 331
 332        /*
 333         * Was a VLAN packet, grab the encapsulated protocol, which the layer
 334         * three protocols care about.
 335         */
 336
 337        proto = vhdr->h_vlan_encapsulated_proto;
 338        if (ntohs(proto) >= 1536) {
 339                skb->protocol = proto;
 340                return;
 341        }
 342
 343        rawp = skb->data;
 344        if (*(unsigned short *) rawp == 0xFFFF)
 345                /*
 346                 * This is a magic hack to spot IPX packets. Older Novell
 347                 * breaks the protocol design and runs IPX over 802.3 without
 348                 * an 802.2 LLC layer. We look for FFFF which isn't a used
 349                 * 802.2 SSAP/DSAP. This won't work for fault tolerant netware
 350                 * but does for the rest.
 351                 */
 352                skb->protocol = htons(ETH_P_802_3);
 353        else
 354                /*
 355                 * Real 802.2 LLC
 356                 */
 357                skb->protocol = htons(ETH_P_802_2);
 358}
 359#endif /* __KERNEL__ */
 360
 361/* VLAN IOCTLs are found in sockios.h */
 362
 363/* Passed in vlan_ioctl_args structure to determine behaviour. */
 364enum vlan_ioctl_cmds {
 365        ADD_VLAN_CMD,
 366        DEL_VLAN_CMD,
 367        SET_VLAN_INGRESS_PRIORITY_CMD,
 368        SET_VLAN_EGRESS_PRIORITY_CMD,
 369        GET_VLAN_INGRESS_PRIORITY_CMD,
 370        GET_VLAN_EGRESS_PRIORITY_CMD,
 371        SET_VLAN_NAME_TYPE_CMD,
 372        SET_VLAN_FLAG_CMD,
 373        GET_VLAN_REALDEV_NAME_CMD, /* If this works, you know it's a VLAN device, btw */
 374        GET_VLAN_VID_CMD /* Get the VID of this VLAN (specified by name) */
 375};
 376
 377enum vlan_flags {
 378        VLAN_FLAG_REORDER_HDR   = 0x1,
 379        VLAN_FLAG_GVRP          = 0x2,
 380        VLAN_FLAG_LOOSE_BINDING = 0x4,
 381};
 382
 383enum vlan_name_types {
 384        VLAN_NAME_TYPE_PLUS_VID, /* Name will look like:  vlan0005 */
 385        VLAN_NAME_TYPE_RAW_PLUS_VID, /* name will look like:  eth1.0005 */
 386        VLAN_NAME_TYPE_PLUS_VID_NO_PAD, /* Name will look like:  vlan5 */
 387        VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD, /* Name will look like:  eth0.5 */
 388        VLAN_NAME_TYPE_HIGHEST
 389};
 390
 391struct vlan_ioctl_args {
 392        int cmd; /* Should be one of the vlan_ioctl_cmds enum above. */
 393        char device1[24];
 394
 395        union {
 396                char device2[24];
 397                int VID;
 398                unsigned int skb_priority;
 399                unsigned int name_type;
 400                unsigned int bind_type;
 401                unsigned int flag; /* Matches vlan_dev_priv flags */
 402        } u;
 403
 404        short vlan_qos;   
 405};
 406
 407#endif /* !(_LINUX_IF_VLAN_H_) */
 408