LCOV - code coverage report
Current view: top level - include/linux - if_vlan.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1 1 100.0 %
Date: 2017-01-25 Functions: 0 0 -

          Line data    Source code
       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             : 
      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           1 : 
      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_) */

Generated by: LCOV version 1.10