mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-27 21:03:32 +00:00
Merge branch 'dsa-skb_mac_header'
Vladimir Oltean says: ==================== Remove skb_mac_header() dependency in DSA xmit path Eric started working on removing skb_mac_header() assumptions from the networking xmit path, and I offered to help for DSA: https://lore.kernel.org/netdev/20230321164519.1286357-1-edumazet@google.com/ The majority of this patch set is a straightforward replacement of skb_mac_header() with skb->data (hidden either behind skb_eth_hdr(), or behind skb_vlan_eth_hdr()). The only patch which is more "interesting" is 9/9. Another potential caller of __skb_vlan_pop() on xmit (and therefore also of skb_mac_header()) is tcf_vlan_act(), but I haven't had the time to investigate that (enough to submit changes other than what's here). v1->v2: - 09/09: document the vlan_tci argument of vlan_remove_tag() in the kdoc v1 at: https://lore.kernel.org/netdev/20230322233823.1806736-1-vladimir.oltean@nxp.com/ Cc: Madalin Bucur <madalin.bucur@nxp.com> ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
00266b365d
19 changed files with 66 additions and 51 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -1482,13 +1482,8 @@ static int dpaa_enable_tx_csum(struct dpaa_priv *priv,
|
|||
parse_result = (struct fman_prs_result *)parse_results;
|
||||
|
||||
/* If we're dealing with VLAN, get the real Ethernet type */
|
||||
if (ethertype == ETH_P_8021Q) {
|
||||
/* We can't always assume the MAC header is set correctly
|
||||
* by the stack, so reset to beginning of skb->data
|
||||
*/
|
||||
skb_reset_mac_header(skb);
|
||||
ethertype = ntohs(vlan_eth_hdr(skb)->h_vlan_encapsulated_proto);
|
||||
}
|
||||
if (ethertype == ETH_P_8021Q)
|
||||
ethertype = ntohs(skb_vlan_eth_hdr(skb)->h_vlan_encapsulated_proto);
|
||||
|
||||
/* Fill in the relevant L3 parse result fields
|
||||
* and read the L4 protocol type
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -4569,13 +4569,10 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
|
||||
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) &&
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
@ -351,7 +359,8 @@ static inline int __vlan_insert_inner_tag(struct sk_buff *skb,
|
|||
/* Move the mac header sans proto to the beginning of the new header. */
|
||||
if (likely(mac_len > ETH_TLEN))
|
||||
memmove(skb->data, skb->data + VLAN_HLEN, mac_len - ETH_TLEN);
|
||||
skb->mac_header -= VLAN_HLEN;
|
||||
if (skb_mac_header_was_set(skb))
|
||||
skb->mac_header -= VLAN_HLEN;
|
||||
|
||||
veth = (struct vlan_ethhdr *)(skb->data + mac_len - ETH_HLEN);
|
||||
|
||||
|
@ -528,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;
|
||||
|
@ -676,6 +685,27 @@ static inline void vlan_set_encap_proto(struct sk_buff *skb,
|
|||
skb->protocol = htons(ETH_P_802_2);
|
||||
}
|
||||
|
||||
/**
|
||||
* vlan_remove_tag - remove outer VLAN tag from payload
|
||||
* @skb: skbuff to remove tag from
|
||||
* @vlan_tci: buffer to store value
|
||||
*
|
||||
* Expects the skb to contain a VLAN tag in the payload, and to have skb->data
|
||||
* pointing at the MAC header.
|
||||
*
|
||||
* Returns a new pointer to skb->data, or NULL on failure to pull.
|
||||
*/
|
||||
static inline void *vlan_remove_tag(struct sk_buff *skb, u16 *vlan_tci)
|
||||
{
|
||||
struct vlan_hdr *vhdr = (struct vlan_hdr *)(skb->data + ETH_HLEN);
|
||||
|
||||
*vlan_tci = ntohs(vhdr->h_vlan_TCI);
|
||||
|
||||
memmove(skb->data + VLAN_HLEN, skb->data, 2 * ETH_ALEN);
|
||||
vlan_set_encap_proto(skb, vhdr);
|
||||
return __skb_pull(skb, VLAN_HLEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* skb_vlan_tagged - check if skb is vlan tagged.
|
||||
* @skb: skbuff to query
|
||||
|
@ -712,7 +742,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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -5996,7 +5996,6 @@ EXPORT_SYMBOL(skb_ensure_writable);
|
|||
*/
|
||||
int __skb_vlan_pop(struct sk_buff *skb, u16 *vlan_tci)
|
||||
{
|
||||
struct vlan_hdr *vhdr;
|
||||
int offset = skb->data - skb_mac_header(skb);
|
||||
int err;
|
||||
|
||||
|
@ -6012,13 +6011,8 @@ int __skb_vlan_pop(struct sk_buff *skb, u16 *vlan_tci)
|
|||
|
||||
skb_postpull_rcsum(skb, skb->data + (2 * ETH_ALEN), VLAN_HLEN);
|
||||
|
||||
vhdr = (struct vlan_hdr *)(skb->data + ETH_HLEN);
|
||||
*vlan_tci = ntohs(vhdr->h_vlan_TCI);
|
||||
vlan_remove_tag(skb, vlan_tci);
|
||||
|
||||
memmove(skb->data + VLAN_HLEN, skb->data, 2 * ETH_ALEN);
|
||||
__skb_pull(skb, VLAN_HLEN);
|
||||
|
||||
vlan_set_encap_proto(skb, vhdr);
|
||||
skb->mac_header += VLAN_HLEN;
|
||||
|
||||
if (skb_network_offset(skb) < ETH_HLEN)
|
||||
|
|
|
@ -229,7 +229,7 @@ static inline void *dsa_etype_header_pos_rx(struct sk_buff *skb)
|
|||
return skb->data - 2;
|
||||
}
|
||||
|
||||
/* On TX, skb->data points to skb_mac_header(skb), which means that EtherType
|
||||
/* On TX, skb->data points to the MAC header, which means that EtherType
|
||||
* header taggers start exactly where the EtherType is (the EtherType is
|
||||
* treated as part of the DSA header).
|
||||
*/
|
||||
|
|
|
@ -461,8 +461,8 @@ EXPORT_SYMBOL_GPL(dsa_tag_8021q_unregister);
|
|||
struct sk_buff *dsa_8021q_xmit(struct sk_buff *skb, struct net_device *netdev,
|
||||
u16 tpid, u16 tci)
|
||||
{
|
||||
/* skb->data points at skb_mac_header, which
|
||||
* is fine for vlan_insert_tag.
|
||||
/* skb->data points at the MAC header, which is fine
|
||||
* for vlan_insert_tag().
|
||||
*/
|
||||
return vlan_insert_tag(skb, htons(tpid), tci);
|
||||
}
|
||||
|
|
|
@ -120,18 +120,18 @@ static struct sk_buff *ksz_common_rcv(struct sk_buff *skb,
|
|||
static struct sk_buff *ksz8795_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
struct dsa_port *dp = dsa_slave_to_port(dev);
|
||||
struct ethhdr *hdr;
|
||||
u8 *tag;
|
||||
u8 *addr;
|
||||
|
||||
if (skb->ip_summed == CHECKSUM_PARTIAL && skb_checksum_help(skb))
|
||||
return NULL;
|
||||
|
||||
/* Tag encoding */
|
||||
tag = skb_put(skb, KSZ_INGRESS_TAG_LEN);
|
||||
addr = skb_mac_header(skb);
|
||||
hdr = skb_eth_hdr(skb);
|
||||
|
||||
*tag = 1 << dp->index;
|
||||
if (is_link_local_ether_addr(addr))
|
||||
if (is_link_local_ether_addr(hdr->h_dest))
|
||||
*tag |= KSZ8795_TAIL_TAG_OVERRIDE;
|
||||
|
||||
return skb;
|
||||
|
@ -273,8 +273,8 @@ static struct sk_buff *ksz9477_xmit(struct sk_buff *skb,
|
|||
u16 queue_mapping = skb_get_queue_mapping(skb);
|
||||
u8 prio = netdev_txq_to_tc(dev, queue_mapping);
|
||||
struct dsa_port *dp = dsa_slave_to_port(dev);
|
||||
struct ethhdr *hdr;
|
||||
__be16 *tag;
|
||||
u8 *addr;
|
||||
u16 val;
|
||||
|
||||
if (skb->ip_summed == CHECKSUM_PARTIAL && skb_checksum_help(skb))
|
||||
|
@ -284,13 +284,13 @@ static struct sk_buff *ksz9477_xmit(struct sk_buff *skb,
|
|||
ksz_xmit_timestamp(dp, skb);
|
||||
|
||||
tag = skb_put(skb, KSZ9477_INGRESS_TAG_LEN);
|
||||
addr = skb_mac_header(skb);
|
||||
hdr = skb_eth_hdr(skb);
|
||||
|
||||
val = BIT(dp->index);
|
||||
|
||||
val |= FIELD_PREP(KSZ9477_TAIL_TAG_PRIO, prio);
|
||||
|
||||
if (is_link_local_ether_addr(addr))
|
||||
if (is_link_local_ether_addr(hdr->h_dest))
|
||||
val |= KSZ9477_TAIL_TAG_OVERRIDE;
|
||||
|
||||
*tag = cpu_to_be16(val);
|
||||
|
@ -337,7 +337,7 @@ static struct sk_buff *ksz9893_xmit(struct sk_buff *skb,
|
|||
u16 queue_mapping = skb_get_queue_mapping(skb);
|
||||
u8 prio = netdev_txq_to_tc(dev, queue_mapping);
|
||||
struct dsa_port *dp = dsa_slave_to_port(dev);
|
||||
u8 *addr;
|
||||
struct ethhdr *hdr;
|
||||
u8 *tag;
|
||||
|
||||
if (skb->ip_summed == CHECKSUM_PARTIAL && skb_checksum_help(skb))
|
||||
|
@ -347,13 +347,13 @@ static struct sk_buff *ksz9893_xmit(struct sk_buff *skb,
|
|||
ksz_xmit_timestamp(dp, skb);
|
||||
|
||||
tag = skb_put(skb, KSZ_INGRESS_TAG_LEN);
|
||||
addr = skb_mac_header(skb);
|
||||
hdr = skb_eth_hdr(skb);
|
||||
|
||||
*tag = BIT(dp->index);
|
||||
|
||||
*tag |= FIELD_PREP(KSZ9893_TAIL_TAG_PRIO, prio);
|
||||
|
||||
if (is_link_local_ether_addr(addr))
|
||||
if (is_link_local_ether_addr(hdr->h_dest))
|
||||
*tag |= KSZ9893_TAIL_TAG_OVERRIDE;
|
||||
|
||||
return ksz_defer_xmit(dp, skb);
|
||||
|
|
|
@ -26,11 +26,11 @@ static void ocelot_xmit_get_vlan_info(struct sk_buff *skb, struct dsa_port *dp,
|
|||
return;
|
||||
}
|
||||
|
||||
hdr = (struct vlan_ethhdr *)skb_mac_header(skb);
|
||||
hdr = skb_vlan_eth_hdr(skb);
|
||||
br_vlan_get_proto(br, &proto);
|
||||
|
||||
if (ntohs(hdr->h_vlan_proto) == proto) {
|
||||
__skb_vlan_pop(skb, &tci);
|
||||
vlan_remove_tag(skb, &tci);
|
||||
*vlan_tci = tci;
|
||||
} else {
|
||||
rcu_read_lock();
|
||||
|
|
|
@ -256,7 +256,7 @@ static struct sk_buff *sja1105_pvid_tag_control_pkt(struct dsa_port *dp,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
hdr = (struct vlan_ethhdr *)skb_mac_header(skb);
|
||||
hdr = skb_vlan_eth_hdr(skb);
|
||||
|
||||
/* If skb is already VLAN-tagged, leave that VLAN ID in place */
|
||||
if (hdr->h_vlan_proto == xmit_tpid)
|
||||
|
@ -516,7 +516,7 @@ static bool sja1110_skb_has_inband_control_extension(const struct sk_buff *skb)
|
|||
static void sja1105_vlan_rcv(struct sk_buff *skb, int *source_port,
|
||||
int *switch_id, int *vbid, u16 *vid)
|
||||
{
|
||||
struct vlan_ethhdr *hdr = (struct vlan_ethhdr *)skb_mac_header(skb);
|
||||
struct vlan_ethhdr *hdr = vlan_eth_hdr(skb);
|
||||
u16 vlan_tci;
|
||||
|
||||
if (skb_vlan_tag_present(skb))
|
||||
|
|
Loading…
Reference in a new issue