Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: vlan: introduce skb_vlan_eth_hdr()

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>

authored by

Vladimir Oltean and committed by
David S. Miller
1f5020ac f90615ad

+24 -20
+1 -2
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
··· 1935 1935 1936 1936 /* Skip VLAN tag if present */ 1937 1937 if (ether_type == ETH_P_8021Q) { 1938 - struct vlan_ethhdr *vhdr = 1939 - (struct vlan_ethhdr *)skb->data; 1938 + struct vlan_ethhdr *vhdr = skb_vlan_eth_hdr(skb); 1940 1939 1941 1940 ether_type = ntohs(vhdr->h_vlan_encapsulated_proto); 1942 1941 }
+1 -1
drivers/net/ethernet/emulex/benet/be_main.c
··· 1124 1124 struct be_wrb_params 1125 1125 *wrb_params) 1126 1126 { 1127 - struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; 1127 + struct vlan_ethhdr *veh = skb_vlan_eth_hdr(skb); 1128 1128 unsigned int eth_hdr_len; 1129 1129 struct iphdr *ip; 1130 1130
+1 -1
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
··· 1532 1532 if (unlikely(rc < 0)) 1533 1533 return rc; 1534 1534 1535 - vhdr = (struct vlan_ethhdr *)skb->data; 1535 + vhdr = skb_vlan_eth_hdr(skb); 1536 1536 vhdr->h_vlan_TCI |= cpu_to_be16((skb->priority << VLAN_PRIO_SHIFT) 1537 1537 & VLAN_PRIO_MASK); 1538 1538
+1 -1
drivers/net/ethernet/intel/i40e/i40e_txrx.c
··· 3063 3063 rc = skb_cow_head(skb, 0); 3064 3064 if (rc < 0) 3065 3065 return rc; 3066 - vhdr = (struct vlan_ethhdr *)skb->data; 3066 + vhdr = skb_vlan_eth_hdr(skb); 3067 3067 vhdr->h_vlan_TCI = htons(tx_flags >> 3068 3068 I40E_TX_FLAGS_VLAN_SHIFT); 3069 3069 } else {
+1 -1
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
··· 8798 8798 8799 8799 if (skb_cow_head(skb, 0)) 8800 8800 goto out_drop; 8801 - vhdr = (struct vlan_ethhdr *)skb->data; 8801 + vhdr = skb_vlan_eth_hdr(skb); 8802 8802 vhdr->h_vlan_TCI = htons(tx_flags >> 8803 8803 IXGBE_TX_FLAGS_VLAN_SHIFT); 8804 8804 } else {
+1 -1
drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
··· 1854 1854 1855 1855 if (protocol == cpu_to_be16(ETH_P_8021Q)) { 1856 1856 1857 - vh = (struct vlan_ethhdr *)skb->data; 1857 + vh = skb_vlan_eth_hdr(skb); 1858 1858 protocol = vh->h_vlan_encapsulated_proto; 1859 1859 flags = FLAGS_VLAN_TAGGED; 1860 1860
+2 -2
drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
··· 318 318 319 319 if (adapter->flags & QLCNIC_VLAN_FILTERING) { 320 320 if (protocol == ETH_P_8021Q) { 321 - vh = (struct vlan_ethhdr *)skb->data; 321 + vh = skb_vlan_eth_hdr(skb); 322 322 vlan_id = ntohs(vh->h_vlan_TCI); 323 323 } else if (skb_vlan_tag_present(skb)) { 324 324 vlan_id = skb_vlan_tag_get(skb); ··· 468 468 u32 producer = tx_ring->producer; 469 469 470 470 if (protocol == ETH_P_8021Q) { 471 - vh = (struct vlan_ethhdr *)skb->data; 471 + vh = skb_vlan_eth_hdr(skb); 472 472 flags = QLCNIC_FLAGS_VLAN_TAGGED; 473 473 vlan_tci = ntohs(vh->h_vlan_TCI); 474 474 protocol = ntohs(vh->h_vlan_encapsulated_proto);
+1 -1
drivers/net/ethernet/sfc/tx_tso.c
··· 147 147 EFX_WARN_ON_ONCE_PARANOID(((struct ethhdr *)skb->data)->h_proto != 148 148 protocol); 149 149 if (protocol == htons(ETH_P_8021Q)) { 150 - struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; 150 + struct vlan_ethhdr *veh = skb_vlan_eth_hdr(skb); 151 151 152 152 protocol = veh->h_vlan_encapsulated_proto; 153 153 }
+2 -5
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
··· 4569 4569 4570 4570 static void stmmac_rx_vlan(struct net_device *dev, struct sk_buff *skb) 4571 4571 { 4572 - struct vlan_ethhdr *veth; 4573 - __be16 vlan_proto; 4572 + struct vlan_ethhdr *veth = skb_vlan_eth_hdr(skb); 4573 + __be16 vlan_proto = veth->h_vlan_proto; 4574 4574 u16 vlanid; 4575 - 4576 - veth = (struct vlan_ethhdr *)skb->data; 4577 - vlan_proto = veth->h_vlan_proto; 4578 4575 4579 4576 if ((vlan_proto == htons(ETH_P_8021Q) && 4580 4577 dev->features & NETIF_F_HW_VLAN_CTAG_RX) ||
+2 -2
drivers/staging/gdm724x/gdm_lte.c
··· 349 349 /* Get ethernet protocol */ 350 350 eth = (struct ethhdr *)skb->data; 351 351 if (ntohs(eth->h_proto) == ETH_P_8021Q) { 352 - vlan_eth = (struct vlan_ethhdr *)skb->data; 352 + vlan_eth = skb_vlan_eth_hdr(skb); 353 353 mac_proto = ntohs(vlan_eth->h_vlan_encapsulated_proto); 354 354 network_data = skb->data + VLAN_ETH_HLEN; 355 355 nic_type |= NIC_TYPE_F_VLAN; ··· 435 435 * driver based on the NIC mac 436 436 */ 437 437 if (nic_type & NIC_TYPE_F_VLAN) { 438 - struct vlan_ethhdr *vlan_eth = (struct vlan_ethhdr *)skb->data; 438 + struct vlan_ethhdr *vlan_eth = skb_vlan_eth_hdr(skb); 439 439 440 440 nic->vlan_id = ntohs(vlan_eth->h_vlan_TCI) & VLAN_VID_MASK; 441 441 data_buf = skb->data + (VLAN_ETH_HLEN - ETH_HLEN);
+10 -2
include/linux/if_vlan.h
··· 62 62 return (struct vlan_ethhdr *)skb_mac_header(skb); 63 63 } 64 64 65 + /* Prefer this version in TX path, instead of 66 + * skb_reset_mac_header() + vlan_eth_hdr() 67 + */ 68 + static inline struct vlan_ethhdr *skb_vlan_eth_hdr(const struct sk_buff *skb) 69 + { 70 + return (struct vlan_ethhdr *)skb->data; 71 + } 72 + 65 73 #define VLAN_PRIO_MASK 0xe000 /* Priority Code Point */ 66 74 #define VLAN_PRIO_SHIFT 13 67 75 #define VLAN_CFI_MASK 0x1000 /* Canonical Format Indicator / Drop Eligible Indicator */ ··· 537 529 */ 538 530 static inline int __vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci) 539 531 { 540 - struct vlan_ethhdr *veth = (struct vlan_ethhdr *)skb->data; 532 + struct vlan_ethhdr *veth = skb_vlan_eth_hdr(skb); 541 533 542 534 if (!eth_type_vlan(veth->h_vlan_proto)) 543 535 return -EINVAL; ··· 721 713 if (unlikely(!pskb_may_pull(skb, VLAN_ETH_HLEN))) 722 714 return false; 723 715 724 - veh = (struct vlan_ethhdr *)skb->data; 716 + veh = skb_vlan_eth_hdr(skb); 725 717 protocol = veh->h_vlan_encapsulated_proto; 726 718 } 727 719
+1 -1
net/batman-adv/soft-interface.c
··· 439 439 if (!pskb_may_pull(skb, VLAN_ETH_HLEN)) 440 440 goto dropped; 441 441 442 - vhdr = (struct vlan_ethhdr *)skb->data; 442 + vhdr = skb_vlan_eth_hdr(skb); 443 443 444 444 /* drop batman-in-batman packets to prevent loops */ 445 445 if (vhdr->h_vlan_encapsulated_proto != htons(ETH_P_BATMAN))