net: vlan: introduce skb_vlan_eth_hdr()
authorVladimir Oltean <vladimir.oltean@nxp.com>
Thu, 20 Apr 2023 22:55:54 +0000 (01:55 +0300)
committerDavid S. Miller <davem@davemloft.net>
Sun, 23 Apr 2023 13:16:44 +0000 (14:16 +0100)
Similar to skb_eth_hdr() introduced in commit 96cc4b69581d ("macvlan: do
not assume mac_header is set in macvlan_broadcast()"), let's introduce a
skb_vlan_eth_hdr() helper which can be used in TX-only code paths to get
to the VLAN header based on skb->data rather than based on the
skb_mac_header(skb).

We also consolidate the drivers that dereference skb->data to go through
this helper.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
12 files changed:
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
drivers/net/ethernet/intel/i40e/i40e_txrx.c
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
drivers/net/ethernet/sfc/tx_tso.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/staging/gdm724x/gdm_lte.c
include/linux/if_vlan.h
net/batman-adv/soft-interface.c

index 12083b9..6ea5521 100644 (file)
@@ -1935,8 +1935,7 @@ u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb,
 
                /* Skip VLAN tag if present */
                if (ether_type == ETH_P_8021Q) {
-                       struct vlan_ethhdr *vhdr =
-                               (struct vlan_ethhdr *)skb->data;
+                       struct vlan_ethhdr *vhdr = skb_vlan_eth_hdr(skb);
 
                        ether_type = ntohs(vhdr->h_vlan_encapsulated_proto);
                }
index aed1b62..7e408bc 100644 (file)
@@ -1124,7 +1124,7 @@ static struct sk_buff *be_lancer_xmit_workarounds(struct be_adapter *adapter,
                                                  struct be_wrb_params
                                                  *wrb_params)
 {
-       struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;
+       struct vlan_ethhdr *veh = skb_vlan_eth_hdr(skb);
        unsigned int eth_hdr_len;
        struct iphdr *ip;
 
index 5caea15..7356ad9 100644 (file)
@@ -1532,7 +1532,7 @@ static int hns3_handle_vtags(struct hns3_enet_ring *tx_ring,
        if (unlikely(rc < 0))
                return rc;
 
-       vhdr = (struct vlan_ethhdr *)skb->data;
+       vhdr = skb_vlan_eth_hdr(skb);
        vhdr->h_vlan_TCI |= cpu_to_be16((skb->priority << VLAN_PRIO_SHIFT)
                                         & VLAN_PRIO_MASK);
 
index c8c2cba..8b8bf48 100644 (file)
@@ -3063,7 +3063,7 @@ static inline int i40e_tx_prepare_vlan_flags(struct sk_buff *skb,
                        rc = skb_cow_head(skb, 0);
                        if (rc < 0)
                                return rc;
-                       vhdr = (struct vlan_ethhdr *)skb->data;
+                       vhdr = skb_vlan_eth_hdr(skb);
                        vhdr->h_vlan_TCI = htons(tx_flags >>
                                                 I40E_TX_FLAGS_VLAN_SHIFT);
                } else {
index f2604fc..e961ef4 100644 (file)
@@ -8798,7 +8798,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
 
                        if (skb_cow_head(skb, 0))
                                goto out_drop;
-                       vhdr = (struct vlan_ethhdr *)skb->data;
+                       vhdr = skb_vlan_eth_hdr(skb);
                        vhdr->h_vlan_TCI = htons(tx_flags >>
                                                 IXGBE_TX_FLAGS_VLAN_SHIFT);
                } else {
index 59d0dd8..1d1e183 100644 (file)
@@ -1854,7 +1854,7 @@ netxen_tso_check(struct net_device *netdev,
 
        if (protocol == cpu_to_be16(ETH_P_8021Q)) {
 
-               vh = (struct vlan_ethhdr *)skb->data;
+               vh = skb_vlan_eth_hdr(skb);
                protocol = vh->h_vlan_encapsulated_proto;
                flags = FLAGS_VLAN_TAGGED;
 
index 92930a0..41894d1 100644 (file)
@@ -318,7 +318,7 @@ static void qlcnic_send_filter(struct qlcnic_adapter *adapter,
 
        if (adapter->flags & QLCNIC_VLAN_FILTERING) {
                if (protocol == ETH_P_8021Q) {
-                       vh = (struct vlan_ethhdr *)skb->data;
+                       vh = skb_vlan_eth_hdr(skb);
                        vlan_id = ntohs(vh->h_vlan_TCI);
                } else if (skb_vlan_tag_present(skb)) {
                        vlan_id = skb_vlan_tag_get(skb);
@@ -468,7 +468,7 @@ static int qlcnic_tx_pkt(struct qlcnic_adapter *adapter,
        u32 producer = tx_ring->producer;
 
        if (protocol == ETH_P_8021Q) {
-               vh = (struct vlan_ethhdr *)skb->data;
+               vh = skb_vlan_eth_hdr(skb);
                flags = QLCNIC_FLAGS_VLAN_TAGGED;
                vlan_tci = ntohs(vh->h_vlan_TCI);
                protocol = ntohs(vh->h_vlan_encapsulated_proto);
index 898e5c6..d381d81 100644 (file)
@@ -147,7 +147,7 @@ static __be16 efx_tso_check_protocol(struct sk_buff *skb)
        EFX_WARN_ON_ONCE_PARANOID(((struct ethhdr *)skb->data)->h_proto !=
                                  protocol);
        if (protocol == htons(ETH_P_8021Q)) {
-               struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;
+               struct vlan_ethhdr *veh = skb_vlan_eth_hdr(skb);
 
                protocol = veh->h_vlan_encapsulated_proto;
        }
index f116e4a..0fca815 100644 (file)
@@ -4569,13 +4569,10 @@ dma_map_err:
 
 static void stmmac_rx_vlan(struct net_device *dev, struct sk_buff *skb)
 {
-       struct vlan_ethhdr *veth;
-       __be16 vlan_proto;
+       struct vlan_ethhdr *veth = skb_vlan_eth_hdr(skb);
+       __be16 vlan_proto = veth->h_vlan_proto;
        u16 vlanid;
 
-       veth = (struct vlan_ethhdr *)skb->data;
-       vlan_proto = veth->h_vlan_proto;
-
        if ((vlan_proto == htons(ETH_P_8021Q) &&
             dev->features & NETIF_F_HW_VLAN_CTAG_RX) ||
            (vlan_proto == htons(ETH_P_8021AD) &&
index 671ee88..5703a9d 100644 (file)
@@ -349,7 +349,7 @@ static s32 gdm_lte_tx_nic_type(struct net_device *dev, struct sk_buff *skb)
        /* Get ethernet protocol */
        eth = (struct ethhdr *)skb->data;
        if (ntohs(eth->h_proto) == ETH_P_8021Q) {
-               vlan_eth = (struct vlan_ethhdr *)skb->data;
+               vlan_eth = skb_vlan_eth_hdr(skb);
                mac_proto = ntohs(vlan_eth->h_vlan_encapsulated_proto);
                network_data = skb->data + VLAN_ETH_HLEN;
                nic_type |= NIC_TYPE_F_VLAN;
@@ -435,7 +435,7 @@ static netdev_tx_t gdm_lte_tx(struct sk_buff *skb, struct net_device *dev)
         * driver based on the NIC mac
         */
        if (nic_type & NIC_TYPE_F_VLAN) {
-               struct vlan_ethhdr *vlan_eth = (struct vlan_ethhdr *)skb->data;
+               struct vlan_ethhdr *vlan_eth = skb_vlan_eth_hdr(skb);
 
                nic->vlan_id = ntohs(vlan_eth->h_vlan_TCI) & VLAN_VID_MASK;
                data_buf = skb->data + (VLAN_ETH_HLEN - ETH_HLEN);
index 90b76d6..3698f2b 100644 (file)
@@ -62,6 +62,14 @@ static inline struct vlan_ethhdr *vlan_eth_hdr(const struct sk_buff *skb)
        return (struct vlan_ethhdr *)skb_mac_header(skb);
 }
 
+/* Prefer this version in TX path, instead of
+ * skb_reset_mac_header() + vlan_eth_hdr()
+ */
+static inline struct vlan_ethhdr *skb_vlan_eth_hdr(const struct sk_buff *skb)
+{
+       return (struct vlan_ethhdr *)skb->data;
+}
+
 #define VLAN_PRIO_MASK         0xe000 /* Priority Code Point */
 #define VLAN_PRIO_SHIFT                13
 #define VLAN_CFI_MASK          0x1000 /* Canonical Format Indicator / Drop Eligible Indicator */
@@ -529,7 +537,7 @@ static inline void __vlan_hwaccel_put_tag(struct sk_buff *skb,
  */
 static inline int __vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci)
 {
-       struct vlan_ethhdr *veth = (struct vlan_ethhdr *)skb->data;
+       struct vlan_ethhdr *veth = skb_vlan_eth_hdr(skb);
 
        if (!eth_type_vlan(veth->h_vlan_proto))
                return -EINVAL;
@@ -713,7 +721,7 @@ static inline bool skb_vlan_tagged_multi(struct sk_buff *skb)
                if (unlikely(!pskb_may_pull(skb, VLAN_ETH_HLEN)))
                        return false;
 
-               veh = (struct vlan_ethhdr *)skb->data;
+               veh = skb_vlan_eth_hdr(skb);
                protocol = veh->h_vlan_encapsulated_proto;
        }
 
index 125f462..d3fdf82 100644 (file)
@@ -439,7 +439,7 @@ void batadv_interface_rx(struct net_device *soft_iface,
                if (!pskb_may_pull(skb, VLAN_ETH_HLEN))
                        goto dropped;
 
-               vhdr = (struct vlan_ethhdr *)skb->data;
+               vhdr = skb_vlan_eth_hdr(skb);
 
                /* drop batman-in-batman packets to prevent loops */
                if (vhdr->h_vlan_encapsulated_proto != htons(ETH_P_BATMAN))