LCOV - code coverage report
Current view: top level - include/linux - if_vlan.h (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 116 0.0 %
Date: 2022-04-01 14:17:54 Functions: 0 9 0.0 %
Branches: 0 86 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: GPL-2.0-or-later */
       2                 :            : /*
       3                 :            :  * VLAN         An implementation of 802.1Q VLAN tagging.
       4                 :            :  *
       5                 :            :  * Authors:     Ben Greear <greearb@candelatech.com>
       6                 :            :  */
       7                 :            : #ifndef _LINUX_IF_VLAN_H_
       8                 :            : #define _LINUX_IF_VLAN_H_
       9                 :            : 
      10                 :            : #include <linux/netdevice.h>
      11                 :            : #include <linux/etherdevice.h>
      12                 :            : #include <linux/rtnetlink.h>
      13                 :            : #include <linux/bug.h>
      14                 :            : #include <uapi/linux/if_vlan.h>
      15                 :            : 
      16                 :            : #define VLAN_HLEN       4               /* The additional bytes required by VLAN
      17                 :            :                                          * (in addition to the Ethernet header)
      18                 :            :                                          */
      19                 :            : #define VLAN_ETH_HLEN   18              /* Total octets in header.       */
      20                 :            : #define VLAN_ETH_ZLEN   64              /* Min. octets in frame sans FCS */
      21                 :            : 
      22                 :            : /*
      23                 :            :  * According to 802.3ac, the packet can be 4 bytes longer. --Klika Jan
      24                 :            :  */
      25                 :            : #define VLAN_ETH_DATA_LEN       1500    /* Max. octets in payload        */
      26                 :            : #define VLAN_ETH_FRAME_LEN      1518    /* Max. octets in frame sans FCS */
      27                 :            : 
      28                 :            : /*
      29                 :            :  *      struct vlan_hdr - vlan header
      30                 :            :  *      @h_vlan_TCI: priority and VLAN ID
      31                 :            :  *      @h_vlan_encapsulated_proto: packet type ID or len
      32                 :            :  */
      33                 :            : struct vlan_hdr {
      34                 :            :         __be16  h_vlan_TCI;
      35                 :            :         __be16  h_vlan_encapsulated_proto;
      36                 :            : };
      37                 :            : 
      38                 :            : /**
      39                 :            :  *      struct vlan_ethhdr - vlan ethernet header (ethhdr + vlan_hdr)
      40                 :            :  *      @h_dest: destination ethernet address
      41                 :            :  *      @h_source: source ethernet address
      42                 :            :  *      @h_vlan_proto: ethernet protocol
      43                 :            :  *      @h_vlan_TCI: priority and VLAN ID
      44                 :            :  *      @h_vlan_encapsulated_proto: packet type ID or len
      45                 :            :  */
      46                 :            : struct vlan_ethhdr {
      47                 :            :         unsigned char   h_dest[ETH_ALEN];
      48                 :            :         unsigned char   h_source[ETH_ALEN];
      49                 :            :         __be16          h_vlan_proto;
      50                 :            :         __be16          h_vlan_TCI;
      51                 :            :         __be16          h_vlan_encapsulated_proto;
      52                 :            : };
      53                 :            : 
      54                 :            : #include <linux/skbuff.h>
      55                 :            : 
      56                 :            : static inline struct vlan_ethhdr *vlan_eth_hdr(const struct sk_buff *skb)
      57                 :            : {
      58                 :            :         return (struct vlan_ethhdr *)skb_mac_header(skb);
      59                 :            : }
      60                 :            : 
      61                 :            : #define VLAN_PRIO_MASK          0xe000 /* Priority Code Point */
      62                 :            : #define VLAN_PRIO_SHIFT         13
      63                 :            : #define VLAN_CFI_MASK           0x1000 /* Canonical Format Indicator / Drop Eligible Indicator */
      64                 :            : #define VLAN_VID_MASK           0x0fff /* VLAN Identifier */
      65                 :            : #define VLAN_N_VID              4096
      66                 :            : 
      67                 :            : /* found in socket.c */
      68                 :            : extern void vlan_ioctl_set(int (*hook)(struct net *, void __user *));
      69                 :            : 
      70                 :          0 : static inline bool is_vlan_dev(const struct net_device *dev)
      71                 :            : {
      72         [ #  # ]:          0 :         return dev->priv_flags & IFF_802_1Q_VLAN;
      73                 :            : }
      74                 :            : 
      75                 :            : #define skb_vlan_tag_present(__skb)     ((__skb)->vlan_present)
      76                 :            : #define skb_vlan_tag_get(__skb)         ((__skb)->vlan_tci)
      77                 :            : #define skb_vlan_tag_get_id(__skb)      ((__skb)->vlan_tci & VLAN_VID_MASK)
      78                 :            : #define skb_vlan_tag_get_cfi(__skb)     (!!((__skb)->vlan_tci & VLAN_CFI_MASK))
      79                 :            : #define skb_vlan_tag_get_prio(__skb)    (((__skb)->vlan_tci & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT)
      80                 :            : 
      81                 :          0 : static inline int vlan_get_rx_ctag_filter_info(struct net_device *dev)
      82                 :            : {
      83   [ #  #  #  # ]:          0 :         ASSERT_RTNL();
      84                 :          0 :         return notifier_to_errno(call_netdevice_notifiers(NETDEV_CVLAN_FILTER_PUSH_INFO, dev));
      85                 :            : }
      86                 :            : 
      87                 :          0 : static inline void vlan_drop_rx_ctag_filter_info(struct net_device *dev)
      88                 :            : {
      89   [ #  #  #  # ]:          0 :         ASSERT_RTNL();
      90                 :          0 :         call_netdevice_notifiers(NETDEV_CVLAN_FILTER_DROP_INFO, dev);
      91                 :          0 : }
      92                 :            : 
      93                 :          0 : static inline int vlan_get_rx_stag_filter_info(struct net_device *dev)
      94                 :            : {
      95   [ #  #  #  # ]:          0 :         ASSERT_RTNL();
      96                 :          0 :         return notifier_to_errno(call_netdevice_notifiers(NETDEV_SVLAN_FILTER_PUSH_INFO, dev));
      97                 :            : }
      98                 :            : 
      99                 :          0 : static inline void vlan_drop_rx_stag_filter_info(struct net_device *dev)
     100                 :            : {
     101   [ #  #  #  # ]:          0 :         ASSERT_RTNL();
     102                 :          0 :         call_netdevice_notifiers(NETDEV_SVLAN_FILTER_DROP_INFO, dev);
     103                 :          0 : }
     104                 :            : 
     105                 :            : /**
     106                 :            :  *      struct vlan_pcpu_stats - VLAN percpu rx/tx stats
     107                 :            :  *      @rx_packets: number of received packets
     108                 :            :  *      @rx_bytes: number of received bytes
     109                 :            :  *      @rx_multicast: number of received multicast packets
     110                 :            :  *      @tx_packets: number of transmitted packets
     111                 :            :  *      @tx_bytes: number of transmitted bytes
     112                 :            :  *      @syncp: synchronization point for 64bit counters
     113                 :            :  *      @rx_errors: number of rx errors
     114                 :            :  *      @tx_dropped: number of tx drops
     115                 :            :  */
     116                 :            : struct vlan_pcpu_stats {
     117                 :            :         u64                     rx_packets;
     118                 :            :         u64                     rx_bytes;
     119                 :            :         u64                     rx_multicast;
     120                 :            :         u64                     tx_packets;
     121                 :            :         u64                     tx_bytes;
     122                 :            :         struct u64_stats_sync   syncp;
     123                 :            :         u32                     rx_errors;
     124                 :            :         u32                     tx_dropped;
     125                 :            : };
     126                 :            : 
     127                 :            : #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
     128                 :            : 
     129                 :            : extern struct net_device *__vlan_find_dev_deep_rcu(struct net_device *real_dev,
     130                 :            :                                                __be16 vlan_proto, u16 vlan_id);
     131                 :            : extern int vlan_for_each(struct net_device *dev,
     132                 :            :                          int (*action)(struct net_device *dev, int vid,
     133                 :            :                                        void *arg), void *arg);
     134                 :            : extern struct net_device *vlan_dev_real_dev(const struct net_device *dev);
     135                 :            : extern u16 vlan_dev_vlan_id(const struct net_device *dev);
     136                 :            : extern __be16 vlan_dev_vlan_proto(const struct net_device *dev);
     137                 :            : 
     138                 :            : /**
     139                 :            :  *      struct vlan_priority_tci_mapping - vlan egress priority mappings
     140                 :            :  *      @priority: skb priority
     141                 :            :  *      @vlan_qos: vlan priority: (skb->priority << 13) & 0xE000
     142                 :            :  *      @next: pointer to next struct
     143                 :            :  */
     144                 :            : struct vlan_priority_tci_mapping {
     145                 :            :         u32                                     priority;
     146                 :            :         u16                                     vlan_qos;
     147                 :            :         struct vlan_priority_tci_mapping        *next;
     148                 :            : };
     149                 :            : 
     150                 :            : struct proc_dir_entry;
     151                 :            : struct netpoll;
     152                 :            : 
     153                 :            : /**
     154                 :            :  *      struct vlan_dev_priv - VLAN private device data
     155                 :            :  *      @nr_ingress_mappings: number of ingress priority mappings
     156                 :            :  *      @ingress_priority_map: ingress priority mappings
     157                 :            :  *      @nr_egress_mappings: number of egress priority mappings
     158                 :            :  *      @egress_priority_map: hash of egress priority mappings
     159                 :            :  *      @vlan_proto: VLAN encapsulation protocol
     160                 :            :  *      @vlan_id: VLAN identifier
     161                 :            :  *      @flags: device flags
     162                 :            :  *      @real_dev: underlying netdevice
     163                 :            :  *      @real_dev_addr: address of underlying netdevice
     164                 :            :  *      @dent: proc dir entry
     165                 :            :  *      @vlan_pcpu_stats: ptr to percpu rx stats
     166                 :            :  */
     167                 :            : struct vlan_dev_priv {
     168                 :            :         unsigned int                            nr_ingress_mappings;
     169                 :            :         u32                                     ingress_priority_map[8];
     170                 :            :         unsigned int                            nr_egress_mappings;
     171                 :            :         struct vlan_priority_tci_mapping        *egress_priority_map[16];
     172                 :            : 
     173                 :            :         __be16                                  vlan_proto;
     174                 :            :         u16                                     vlan_id;
     175                 :            :         u16                                     flags;
     176                 :            : 
     177                 :            :         struct net_device                       *real_dev;
     178                 :            :         unsigned char                           real_dev_addr[ETH_ALEN];
     179                 :            : 
     180                 :            :         struct proc_dir_entry                   *dent;
     181                 :            :         struct vlan_pcpu_stats __percpu         *vlan_pcpu_stats;
     182                 :            : #ifdef CONFIG_NET_POLL_CONTROLLER
     183                 :            :         struct netpoll                          *netpoll;
     184                 :            : #endif
     185                 :            : };
     186                 :            : 
     187                 :            : static inline struct vlan_dev_priv *vlan_dev_priv(const struct net_device *dev)
     188                 :            : {
     189                 :            :         return netdev_priv(dev);
     190                 :            : }
     191                 :            : 
     192                 :            : static inline u16
     193                 :            : vlan_dev_get_egress_qos_mask(struct net_device *dev, u32 skprio)
     194                 :            : {
     195                 :            :         struct vlan_priority_tci_mapping *mp;
     196                 :            : 
     197                 :            :         smp_rmb(); /* coupled with smp_wmb() in vlan_dev_set_egress_priority() */
     198                 :            : 
     199                 :            :         mp = vlan_dev_priv(dev)->egress_priority_map[(skprio & 0xF)];
     200                 :            :         while (mp) {
     201                 :            :                 if (mp->priority == skprio) {
     202                 :            :                         return mp->vlan_qos; /* This should already be shifted
     203                 :            :                                               * to mask correctly with the
     204                 :            :                                               * VLAN's TCI */
     205                 :            :                 }
     206                 :            :                 mp = mp->next;
     207                 :            :         }
     208                 :            :         return 0;
     209                 :            : }
     210                 :            : 
     211                 :            : extern bool vlan_do_receive(struct sk_buff **skb);
     212                 :            : 
     213                 :            : extern int vlan_vid_add(struct net_device *dev, __be16 proto, u16 vid);
     214                 :            : extern void vlan_vid_del(struct net_device *dev, __be16 proto, u16 vid);
     215                 :            : 
     216                 :            : extern int vlan_vids_add_by_dev(struct net_device *dev,
     217                 :            :                                 const struct net_device *by_dev);
     218                 :            : extern void vlan_vids_del_by_dev(struct net_device *dev,
     219                 :            :                                  const struct net_device *by_dev);
     220                 :            : 
     221                 :            : extern bool vlan_uses_dev(const struct net_device *dev);
     222                 :            : 
     223                 :            : #else
     224                 :            : static inline struct net_device *
     225                 :            : __vlan_find_dev_deep_rcu(struct net_device *real_dev,
     226                 :            :                      __be16 vlan_proto, u16 vlan_id)
     227                 :            : {
     228                 :            :         return NULL;
     229                 :            : }
     230                 :            : 
     231                 :            : static inline int
     232                 :            : vlan_for_each(struct net_device *dev,
     233                 :            :               int (*action)(struct net_device *dev, int vid, void *arg),
     234                 :            :               void *arg)
     235                 :            : {
     236                 :            :         return 0;
     237                 :            : }
     238                 :            : 
     239                 :            : static inline struct net_device *vlan_dev_real_dev(const struct net_device *dev)
     240                 :            : {
     241                 :            :         BUG();
     242                 :            :         return NULL;
     243                 :            : }
     244                 :            : 
     245                 :            : static inline u16 vlan_dev_vlan_id(const struct net_device *dev)
     246                 :            : {
     247                 :            :         BUG();
     248                 :            :         return 0;
     249                 :            : }
     250                 :            : 
     251                 :            : static inline __be16 vlan_dev_vlan_proto(const struct net_device *dev)
     252                 :            : {
     253                 :            :         BUG();
     254                 :            :         return 0;
     255                 :            : }
     256                 :            : 
     257                 :            : static inline u16 vlan_dev_get_egress_qos_mask(struct net_device *dev,
     258                 :            :                                                u32 skprio)
     259                 :            : {
     260                 :            :         return 0;
     261                 :            : }
     262                 :            : 
     263                 :          0 : static inline bool vlan_do_receive(struct sk_buff **skb)
     264                 :            : {
     265         [ #  # ]:          0 :         return false;
     266                 :            : }
     267                 :            : 
     268                 :            : static inline int vlan_vid_add(struct net_device *dev, __be16 proto, u16 vid)
     269                 :            : {
     270                 :            :         return 0;
     271                 :            : }
     272                 :            : 
     273                 :            : static inline void vlan_vid_del(struct net_device *dev, __be16 proto, u16 vid)
     274                 :            : {
     275                 :            : }
     276                 :            : 
     277                 :          0 : static inline int vlan_vids_add_by_dev(struct net_device *dev,
     278                 :            :                                        const struct net_device *by_dev)
     279                 :            : {
     280         [ #  # ]:          0 :         return 0;
     281                 :            : }
     282                 :            : 
     283                 :          0 : static inline void vlan_vids_del_by_dev(struct net_device *dev,
     284                 :            :                                         const struct net_device *by_dev)
     285                 :            : {
     286                 :          0 : }
     287                 :            : 
     288                 :            : static inline bool vlan_uses_dev(const struct net_device *dev)
     289                 :            : {
     290                 :            :         return false;
     291                 :            : }
     292                 :            : #endif
     293                 :            : 
     294                 :            : /**
     295                 :            :  * eth_type_vlan - check for valid vlan ether type.
     296                 :            :  * @ethertype: ether type to check
     297                 :            :  *
     298                 :            :  * Returns true if the ether type is a vlan ether type.
     299                 :            :  */
     300                 :          0 : static inline bool eth_type_vlan(__be16 ethertype)
     301                 :            : {
     302   [ #  #  #  # ]:          0 :         switch (ethertype) {
     303                 :            :         case htons(ETH_P_8021Q):
     304                 :            :         case htons(ETH_P_8021AD):
     305                 :            :                 return true;
     306                 :          0 :         default:
     307                 :          0 :                 return false;
     308                 :            :         }
     309                 :            : }
     310                 :            : 
     311                 :          0 : static inline bool vlan_hw_offload_capable(netdev_features_t features,
     312                 :            :                                            __be16 proto)
     313                 :            : {
     314   [ #  #  #  # ]:          0 :         if (proto == htons(ETH_P_8021Q) && features & NETIF_F_HW_VLAN_CTAG_TX)
     315                 :            :                 return true;
     316   [ #  #  #  # ]:          0 :         if (proto == htons(ETH_P_8021AD) && features & NETIF_F_HW_VLAN_STAG_TX)
     317                 :            :                 return true;
     318                 :            :         return false;
     319                 :            : }
     320                 :            : 
     321                 :            : /**
     322                 :            :  * __vlan_insert_inner_tag - inner VLAN tag inserting
     323                 :            :  * @skb: skbuff to tag
     324                 :            :  * @vlan_proto: VLAN encapsulation protocol
     325                 :            :  * @vlan_tci: VLAN TCI to insert
     326                 :            :  * @mac_len: MAC header length including outer vlan headers
     327                 :            :  *
     328                 :            :  * Inserts the VLAN tag into @skb as part of the payload at offset mac_len
     329                 :            :  * Returns error if skb_cow_head fails.
     330                 :            :  *
     331                 :            :  * Does not change skb->protocol so this function can be used during receive.
     332                 :            :  */
     333                 :          0 : static inline int __vlan_insert_inner_tag(struct sk_buff *skb,
     334                 :            :                                           __be16 vlan_proto, u16 vlan_tci,
     335                 :            :                                           unsigned int mac_len)
     336                 :            : {
     337                 :          0 :         struct vlan_ethhdr *veth;
     338                 :            : 
     339         [ #  # ]:          0 :         if (skb_cow_head(skb, VLAN_HLEN) < 0)
     340                 :            :                 return -ENOMEM;
     341                 :            : 
     342                 :          0 :         skb_push(skb, VLAN_HLEN);
     343                 :            : 
     344                 :            :         /* Move the mac header sans proto to the beginning of the new header. */
     345         [ #  # ]:          0 :         if (likely(mac_len > ETH_TLEN))
     346                 :          0 :                 memmove(skb->data, skb->data + VLAN_HLEN, mac_len - ETH_TLEN);
     347                 :          0 :         skb->mac_header -= VLAN_HLEN;
     348                 :            : 
     349                 :          0 :         veth = (struct vlan_ethhdr *)(skb->data + mac_len - ETH_HLEN);
     350                 :            : 
     351                 :            :         /* first, the ethernet type */
     352         [ #  # ]:          0 :         if (likely(mac_len >= ETH_TLEN)) {
     353                 :            :                 /* h_vlan_encapsulated_proto should already be populated, and
     354                 :            :                  * skb->data has space for h_vlan_proto
     355                 :            :                  */
     356                 :          0 :                 veth->h_vlan_proto = vlan_proto;
     357                 :            :         } else {
     358                 :            :                 /* h_vlan_encapsulated_proto should not be populated, and
     359                 :            :                  * skb->data has no space for h_vlan_proto
     360                 :            :                  */
     361                 :          0 :                 veth->h_vlan_encapsulated_proto = skb->protocol;
     362                 :            :         }
     363                 :            : 
     364                 :            :         /* now, the TCI */
     365                 :          0 :         veth->h_vlan_TCI = htons(vlan_tci);
     366                 :            : 
     367                 :          0 :         return 0;
     368                 :            : }
     369                 :            : 
     370                 :            : /**
     371                 :            :  * __vlan_insert_tag - regular VLAN tag inserting
     372                 :            :  * @skb: skbuff to tag
     373                 :            :  * @vlan_proto: VLAN encapsulation protocol
     374                 :            :  * @vlan_tci: VLAN TCI to insert
     375                 :            :  *
     376                 :            :  * Inserts the VLAN tag into @skb as part of the payload
     377                 :            :  * Returns error if skb_cow_head fails.
     378                 :            :  *
     379                 :            :  * Does not change skb->protocol so this function can be used during receive.
     380                 :            :  */
     381                 :          0 : static inline int __vlan_insert_tag(struct sk_buff *skb,
     382                 :            :                                     __be16 vlan_proto, u16 vlan_tci)
     383                 :            : {
     384                 :          0 :         return __vlan_insert_inner_tag(skb, vlan_proto, vlan_tci, ETH_HLEN);
     385                 :            : }
     386                 :            : 
     387                 :            : /**
     388                 :            :  * vlan_insert_inner_tag - inner VLAN tag inserting
     389                 :            :  * @skb: skbuff to tag
     390                 :            :  * @vlan_proto: VLAN encapsulation protocol
     391                 :            :  * @vlan_tci: VLAN TCI to insert
     392                 :            :  * @mac_len: MAC header length including outer vlan headers
     393                 :            :  *
     394                 :            :  * Inserts the VLAN tag into @skb as part of the payload at offset mac_len
     395                 :            :  * Returns a VLAN tagged skb. If a new skb is created, @skb is freed.
     396                 :            :  *
     397                 :            :  * Following the skb_unshare() example, in case of error, the calling function
     398                 :            :  * doesn't have to worry about freeing the original skb.
     399                 :            :  *
     400                 :            :  * Does not change skb->protocol so this function can be used during receive.
     401                 :            :  */
     402                 :          0 : static inline struct sk_buff *vlan_insert_inner_tag(struct sk_buff *skb,
     403                 :            :                                                     __be16 vlan_proto,
     404                 :            :                                                     u16 vlan_tci,
     405                 :            :                                                     unsigned int mac_len)
     406                 :            : {
     407                 :          0 :         int err;
     408                 :            : 
     409                 :          0 :         err = __vlan_insert_inner_tag(skb, vlan_proto, vlan_tci, mac_len);
     410         [ #  # ]:          0 :         if (err) {
     411                 :          0 :                 dev_kfree_skb_any(skb);
     412                 :          0 :                 return NULL;
     413                 :            :         }
     414                 :            :         return skb;
     415                 :            : }
     416                 :            : 
     417                 :            : /**
     418                 :            :  * vlan_insert_tag - regular VLAN tag inserting
     419                 :            :  * @skb: skbuff to tag
     420                 :            :  * @vlan_proto: VLAN encapsulation protocol
     421                 :            :  * @vlan_tci: VLAN TCI to insert
     422                 :            :  *
     423                 :            :  * Inserts the VLAN tag into @skb as part of the payload
     424                 :            :  * Returns a VLAN tagged skb. If a new skb is created, @skb is freed.
     425                 :            :  *
     426                 :            :  * Following the skb_unshare() example, in case of error, the calling function
     427                 :            :  * doesn't have to worry about freeing the original skb.
     428                 :            :  *
     429                 :            :  * Does not change skb->protocol so this function can be used during receive.
     430                 :            :  */
     431                 :          0 : static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb,
     432                 :            :                                               __be16 vlan_proto, u16 vlan_tci)
     433                 :            : {
     434                 :          0 :         return vlan_insert_inner_tag(skb, vlan_proto, vlan_tci, ETH_HLEN);
     435                 :            : }
     436                 :            : 
     437                 :            : /**
     438                 :            :  * vlan_insert_tag_set_proto - regular VLAN tag inserting
     439                 :            :  * @skb: skbuff to tag
     440                 :            :  * @vlan_proto: VLAN encapsulation protocol
     441                 :            :  * @vlan_tci: VLAN TCI to insert
     442                 :            :  *
     443                 :            :  * Inserts the VLAN tag into @skb as part of the payload
     444                 :            :  * Returns a VLAN tagged skb. If a new skb is created, @skb is freed.
     445                 :            :  *
     446                 :            :  * Following the skb_unshare() example, in case of error, the calling function
     447                 :            :  * doesn't have to worry about freeing the original skb.
     448                 :            :  */
     449                 :          0 : static inline struct sk_buff *vlan_insert_tag_set_proto(struct sk_buff *skb,
     450                 :            :                                                         __be16 vlan_proto,
     451                 :            :                                                         u16 vlan_tci)
     452                 :            : {
     453                 :          0 :         skb = vlan_insert_tag(skb, vlan_proto, vlan_tci);
     454         [ #  # ]:          0 :         if (skb)
     455                 :          0 :                 skb->protocol = vlan_proto;
     456                 :          0 :         return skb;
     457                 :            : }
     458                 :            : 
     459                 :            : /**
     460                 :            :  * __vlan_hwaccel_clear_tag - clear hardware accelerated VLAN info
     461                 :            :  * @skb: skbuff to clear
     462                 :            :  *
     463                 :            :  * Clears the VLAN information from @skb
     464                 :            :  */
     465                 :          0 : static inline void __vlan_hwaccel_clear_tag(struct sk_buff *skb)
     466                 :            : {
     467                 :          0 :         skb->vlan_present = 0;
     468                 :          0 : }
     469                 :            : 
     470                 :            : /**
     471                 :            :  * __vlan_hwaccel_copy_tag - copy hardware accelerated VLAN info from another skb
     472                 :            :  * @dst: skbuff to copy to
     473                 :            :  * @src: skbuff to copy from
     474                 :            :  *
     475                 :            :  * Copies VLAN information from @src to @dst (for branchless code)
     476                 :            :  */
     477                 :            : static inline void __vlan_hwaccel_copy_tag(struct sk_buff *dst, const struct sk_buff *src)
     478                 :            : {
     479                 :            :         dst->vlan_present = src->vlan_present;
     480                 :            :         dst->vlan_proto = src->vlan_proto;
     481                 :            :         dst->vlan_tci = src->vlan_tci;
     482                 :            : }
     483                 :            : 
     484                 :            : /*
     485                 :            :  * __vlan_hwaccel_push_inside - pushes vlan tag to the payload
     486                 :            :  * @skb: skbuff to tag
     487                 :            :  *
     488                 :            :  * Pushes the VLAN tag from @skb->vlan_tci inside to the payload.
     489                 :            :  *
     490                 :            :  * Following the skb_unshare() example, in case of error, the calling function
     491                 :            :  * doesn't have to worry about freeing the original skb.
     492                 :            :  */
     493                 :          0 : static inline struct sk_buff *__vlan_hwaccel_push_inside(struct sk_buff *skb)
     494                 :            : {
     495                 :          0 :         skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto,
     496                 :          0 :                                         skb_vlan_tag_get(skb));
     497         [ #  # ]:          0 :         if (likely(skb))
     498                 :          0 :                 __vlan_hwaccel_clear_tag(skb);
     499                 :          0 :         return skb;
     500                 :            : }
     501                 :            : 
     502                 :            : /**
     503                 :            :  * __vlan_hwaccel_put_tag - hardware accelerated VLAN inserting
     504                 :            :  * @skb: skbuff to tag
     505                 :            :  * @vlan_proto: VLAN encapsulation protocol
     506                 :            :  * @vlan_tci: VLAN TCI to insert
     507                 :            :  *
     508                 :            :  * Puts the VLAN TCI in @skb->vlan_tci and lets the device do the rest
     509                 :            :  */
     510                 :          0 : static inline void __vlan_hwaccel_put_tag(struct sk_buff *skb,
     511                 :            :                                           __be16 vlan_proto, u16 vlan_tci)
     512                 :            : {
     513                 :          0 :         skb->vlan_proto = vlan_proto;
     514                 :          0 :         skb->vlan_tci = vlan_tci;
     515                 :          0 :         skb->vlan_present = 1;
     516                 :          0 : }
     517                 :            : 
     518                 :            : /**
     519                 :            :  * __vlan_get_tag - get the VLAN ID that is part of the payload
     520                 :            :  * @skb: skbuff to query
     521                 :            :  * @vlan_tci: buffer to store value
     522                 :            :  *
     523                 :            :  * Returns error if the skb is not of VLAN type
     524                 :            :  */
     525                 :            : static inline int __vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci)
     526                 :            : {
     527                 :            :         struct vlan_ethhdr *veth = (struct vlan_ethhdr *)skb->data;
     528                 :            : 
     529                 :            :         if (!eth_type_vlan(veth->h_vlan_proto))
     530                 :            :                 return -EINVAL;
     531                 :            : 
     532                 :            :         *vlan_tci = ntohs(veth->h_vlan_TCI);
     533                 :            :         return 0;
     534                 :            : }
     535                 :            : 
     536                 :            : /**
     537                 :            :  * __vlan_hwaccel_get_tag - get the VLAN ID that is in @skb->cb[]
     538                 :            :  * @skb: skbuff to query
     539                 :            :  * @vlan_tci: buffer to store value
     540                 :            :  *
     541                 :            :  * Returns error if @skb->vlan_tci is not set correctly
     542                 :            :  */
     543                 :            : static inline int __vlan_hwaccel_get_tag(const struct sk_buff *skb,
     544                 :            :                                          u16 *vlan_tci)
     545                 :            : {
     546                 :            :         if (skb_vlan_tag_present(skb)) {
     547                 :            :                 *vlan_tci = skb_vlan_tag_get(skb);
     548                 :            :                 return 0;
     549                 :            :         } else {
     550                 :            :                 *vlan_tci = 0;
     551                 :            :                 return -EINVAL;
     552                 :            :         }
     553                 :            : }
     554                 :            : 
     555                 :            : /**
     556                 :            :  * vlan_get_tag - get the VLAN ID from the skb
     557                 :            :  * @skb: skbuff to query
     558                 :            :  * @vlan_tci: buffer to store value
     559                 :            :  *
     560                 :            :  * Returns error if the skb is not VLAN tagged
     561                 :            :  */
     562                 :            : static inline int vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci)
     563                 :            : {
     564                 :            :         if (skb->dev->features & NETIF_F_HW_VLAN_CTAG_TX) {
     565                 :            :                 return __vlan_hwaccel_get_tag(skb, vlan_tci);
     566                 :            :         } else {
     567                 :            :                 return __vlan_get_tag(skb, vlan_tci);
     568                 :            :         }
     569                 :            : }
     570                 :            : 
     571                 :            : /**
     572                 :            :  * vlan_get_protocol - get protocol EtherType.
     573                 :            :  * @skb: skbuff to query
     574                 :            :  * @type: first vlan protocol
     575                 :            :  * @depth: buffer to store length of eth and vlan tags in bytes
     576                 :            :  *
     577                 :            :  * Returns the EtherType of the packet, regardless of whether it is
     578                 :            :  * vlan encapsulated (normal or hardware accelerated) or not.
     579                 :            :  */
     580                 :          0 : static inline __be16 __vlan_get_protocol(struct sk_buff *skb, __be16 type,
     581                 :            :                                          int *depth)
     582                 :            : {
     583                 :          0 :         unsigned int vlan_depth = skb->mac_len;
     584                 :            : 
     585                 :            :         /* if type is 802.1Q/AD then the header should already be
     586                 :            :          * present at mac_len - VLAN_HLEN (if mac_len > 0), or at
     587                 :            :          * ETH_HLEN otherwise
     588                 :            :          */
     589         [ #  # ]:          0 :         if (eth_type_vlan(type)) {
     590         [ #  # ]:          0 :                 if (vlan_depth) {
     591   [ #  #  #  # ]:          0 :                         if (WARN_ON(vlan_depth < VLAN_HLEN))
     592                 :            :                                 return 0;
     593                 :          0 :                         vlan_depth -= VLAN_HLEN;
     594                 :            :                 } else {
     595                 :            :                         vlan_depth = ETH_HLEN;
     596                 :            :                 }
     597                 :          0 :                 do {
     598                 :          0 :                         struct vlan_hdr *vh;
     599                 :            : 
     600         [ #  # ]:          0 :                         if (unlikely(!pskb_may_pull(skb,
     601                 :            :                                                     vlan_depth + VLAN_HLEN)))
     602                 :            :                                 return 0;
     603                 :            : 
     604                 :          0 :                         vh = (struct vlan_hdr *)(skb->data + vlan_depth);
     605                 :          0 :                         type = vh->h_vlan_encapsulated_proto;
     606                 :          0 :                         vlan_depth += VLAN_HLEN;
     607         [ #  # ]:          0 :                 } while (eth_type_vlan(type));
     608                 :            :         }
     609                 :            : 
     610         [ #  # ]:          0 :         if (depth)
     611                 :          0 :                 *depth = vlan_depth;
     612                 :            : 
     613                 :            :         return type;
     614                 :            : }
     615                 :            : 
     616                 :            : /**
     617                 :            :  * vlan_get_protocol - get protocol EtherType.
     618                 :            :  * @skb: skbuff to query
     619                 :            :  *
     620                 :            :  * Returns the EtherType of the packet, regardless of whether it is
     621                 :            :  * vlan encapsulated (normal or hardware accelerated) or not.
     622                 :            :  */
     623                 :          0 : static inline __be16 vlan_get_protocol(struct sk_buff *skb)
     624                 :            : {
     625                 :          0 :         return __vlan_get_protocol(skb, skb->protocol, NULL);
     626                 :            : }
     627                 :            : 
     628                 :          0 : static inline void vlan_set_encap_proto(struct sk_buff *skb,
     629                 :            :                                         struct vlan_hdr *vhdr)
     630                 :            : {
     631                 :          0 :         __be16 proto;
     632                 :          0 :         unsigned short *rawp;
     633                 :            : 
     634                 :            :         /*
     635                 :            :          * Was a VLAN packet, grab the encapsulated protocol, which the layer
     636                 :            :          * three protocols care about.
     637                 :            :          */
     638                 :            : 
     639                 :          0 :         proto = vhdr->h_vlan_encapsulated_proto;
     640   [ #  #  #  # ]:          0 :         if (eth_proto_is_802_3(proto)) {
     641                 :          0 :                 skb->protocol = proto;
     642                 :          0 :                 return;
     643                 :            :         }
     644                 :            : 
     645                 :          0 :         rawp = (unsigned short *)(vhdr + 1);
     646   [ #  #  #  # ]:          0 :         if (*rawp == 0xFFFF)
     647                 :            :                 /*
     648                 :            :                  * This is a magic hack to spot IPX packets. Older Novell
     649                 :            :                  * breaks the protocol design and runs IPX over 802.3 without
     650                 :            :                  * an 802.2 LLC layer. We look for FFFF which isn't a used
     651                 :            :                  * 802.2 SSAP/DSAP. This won't work for fault tolerant netware
     652                 :            :                  * but does for the rest.
     653                 :            :                  */
     654                 :          0 :                 skb->protocol = htons(ETH_P_802_3);
     655                 :            :         else
     656                 :            :                 /*
     657                 :            :                  * Real 802.2 LLC
     658                 :            :                  */
     659                 :          0 :                 skb->protocol = htons(ETH_P_802_2);
     660                 :            : }
     661                 :            : 
     662                 :            : /**
     663                 :            :  * skb_vlan_tagged - check if skb is vlan tagged.
     664                 :            :  * @skb: skbuff to query
     665                 :            :  *
     666                 :            :  * Returns true if the skb is tagged, regardless of whether it is hardware
     667                 :            :  * accelerated or not.
     668                 :            :  */
     669                 :          0 : static inline bool skb_vlan_tagged(const struct sk_buff *skb)
     670                 :            : {
     671         [ #  # ]:          0 :         if (!skb_vlan_tag_present(skb) &&
     672   [ #  #  #  # ]:          0 :             likely(!eth_type_vlan(skb->protocol)))
     673                 :            :                 return false;
     674                 :            : 
     675                 :            :         return true;
     676                 :            : }
     677                 :            : 
     678                 :            : /**
     679                 :            :  * skb_vlan_tagged_multi - check if skb is vlan tagged with multiple headers.
     680                 :            :  * @skb: skbuff to query
     681                 :            :  *
     682                 :            :  * Returns true if the skb is tagged with multiple vlan headers, regardless
     683                 :            :  * of whether it is hardware accelerated or not.
     684                 :            :  */
     685                 :          0 : static inline bool skb_vlan_tagged_multi(struct sk_buff *skb)
     686                 :            : {
     687                 :          0 :         __be16 protocol = skb->protocol;
     688                 :            : 
     689         [ #  # ]:          0 :         if (!skb_vlan_tag_present(skb)) {
     690                 :          0 :                 struct vlan_ethhdr *veh;
     691                 :            : 
     692   [ #  #  #  # ]:          0 :                 if (likely(!eth_type_vlan(protocol)))
     693                 :            :                         return false;
     694                 :            : 
     695         [ #  # ]:          0 :                 if (unlikely(!pskb_may_pull(skb, VLAN_ETH_HLEN)))
     696                 :            :                         return false;
     697                 :            : 
     698                 :          0 :                 veh = (struct vlan_ethhdr *)skb->data;
     699                 :          0 :                 protocol = veh->h_vlan_encapsulated_proto;
     700                 :            :         }
     701                 :            : 
     702         [ #  # ]:          0 :         if (!eth_type_vlan(protocol))
     703                 :          0 :                 return false;
     704                 :            : 
     705                 :            :         return true;
     706                 :            : }
     707                 :            : 
     708                 :            : /**
     709                 :            :  * vlan_features_check - drop unsafe features for skb with multiple tags.
     710                 :            :  * @skb: skbuff to query
     711                 :            :  * @features: features to be checked
     712                 :            :  *
     713                 :            :  * Returns features without unsafe ones if the skb has multiple tags.
     714                 :            :  */
     715                 :          0 : static inline netdev_features_t vlan_features_check(struct sk_buff *skb,
     716                 :            :                                                     netdev_features_t features)
     717                 :            : {
     718         [ #  # ]:          0 :         if (skb_vlan_tagged_multi(skb)) {
     719                 :            :                 /* In the case of multi-tagged packets, use a direct mask
     720                 :            :                  * instead of using netdev_interesect_features(), to make
     721                 :            :                  * sure that only devices supporting NETIF_F_HW_CSUM will
     722                 :            :                  * have checksum offloading support.
     723                 :            :                  */
     724                 :          0 :                 features &= NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_HW_CSUM |
     725                 :            :                             NETIF_F_FRAGLIST | NETIF_F_HW_VLAN_CTAG_TX |
     726                 :            :                             NETIF_F_HW_VLAN_STAG_TX;
     727                 :            :         }
     728                 :            : 
     729                 :          0 :         return features;
     730                 :            : }
     731                 :            : 
     732                 :            : /**
     733                 :            :  * compare_vlan_header - Compare two vlan headers
     734                 :            :  * @h1: Pointer to vlan header
     735                 :            :  * @h2: Pointer to vlan header
     736                 :            :  *
     737                 :            :  * Compare two vlan headers, returns 0 if equal.
     738                 :            :  *
     739                 :            :  * Please note that alignment of h1 & h2 are only guaranteed to be 16 bits.
     740                 :            :  */
     741                 :            : static inline unsigned long compare_vlan_header(const struct vlan_hdr *h1,
     742                 :            :                                                 const struct vlan_hdr *h2)
     743                 :            : {
     744                 :            : #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
     745                 :            :         return *(u32 *)h1 ^ *(u32 *)h2;
     746                 :            : #else
     747                 :            :         return ((__force u32)h1->h_vlan_TCI ^ (__force u32)h2->h_vlan_TCI) |
     748                 :            :                ((__force u32)h1->h_vlan_encapsulated_proto ^
     749                 :            :                 (__force u32)h2->h_vlan_encapsulated_proto);
     750                 :            : #endif
     751                 :            : }
     752                 :            : #endif /* !(_LINUX_IF_VLAN_H_) */

Generated by: LCOV version 1.14