net: dsa: create a helper that strips EtherType DSA headers on RX

All header taggers open-code a memmove that is fairly not all that
obvious, and we can hide the details behind a helper function, since the
only thing specific to the driver is the length of the header tag.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Vladimir Oltean 2021-08-10 16:13:53 +03:00 committed by David S. Miller
parent 1a8e628c8a
commit f1dacd7aea
8 changed files with 37 additions and 28 deletions

View File

@ -452,6 +452,32 @@ static inline void dsa_default_offload_fwd_mark(struct sk_buff *skb)
skb->offload_fwd_mark = !!(dp->bridge_dev); skb->offload_fwd_mark = !!(dp->bridge_dev);
} }
/* Helper for removing DSA header tags from packets in the RX path.
* Must not be called before skb_pull(len).
* skb->data
* |
* v
* | | | | | | | | | | | | | | | | | | |
* +-----------------------+-----------------------+---------------+-------+
* | Destination MAC | Source MAC | DSA header | EType |
* +-----------------------+-----------------------+---------------+-------+
* | |
* <----- len -----> <----- len ----->
* |
* >>>>>>> v
* >>>>>>> | | | | | | | | | | | | | | |
* >>>>>>> +-----------------------+-----------------------+-------+
* >>>>>>> | Destination MAC | Source MAC | EType |
* +-----------------------+-----------------------+-------+
* ^
* |
* skb->data
*/
static inline void dsa_strip_etype_header(struct sk_buff *skb, int len)
{
memmove(skb->data - ETH_HLEN, skb->data - ETH_HLEN - len, 2 * ETH_ALEN);
}
/* switch.c */ /* switch.c */
int dsa_switch_register_notifier(struct dsa_switch *ds); int dsa_switch_register_notifier(struct dsa_switch *ds);
void dsa_switch_unregister_notifier(struct dsa_switch *ds); void dsa_switch_unregister_notifier(struct dsa_switch *ds);

View File

@ -190,10 +190,7 @@ static struct sk_buff *brcm_tag_rcv(struct sk_buff *skb, struct net_device *dev)
if (!nskb) if (!nskb)
return nskb; return nskb;
/* Move the Ethernet DA and SA */ dsa_strip_etype_header(skb, BRCM_TAG_LEN);
memmove(nskb->data - ETH_HLEN,
nskb->data - ETH_HLEN - BRCM_TAG_LEN,
2 * ETH_ALEN);
return nskb; return nskb;
} }
@ -270,10 +267,7 @@ static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb,
dsa_default_offload_fwd_mark(skb); dsa_default_offload_fwd_mark(skb);
/* Move the Ethernet DA and SA */ dsa_strip_etype_header(skb, BRCM_LEG_TAG_LEN);
memmove(skb->data - ETH_HLEN,
skb->data - ETH_HLEN - BRCM_LEG_TAG_LEN,
2 * ETH_ALEN);
return skb; return skb;
} }

View File

@ -312,14 +312,10 @@ static struct sk_buff *dsa_rcv_ll(struct sk_buff *skb, struct net_device *dev,
memcpy(dsa_header, new_header, DSA_HLEN); memcpy(dsa_header, new_header, DSA_HLEN);
if (extra) if (extra)
memmove(skb->data - ETH_HLEN, dsa_strip_etype_header(skb, extra);
skb->data - ETH_HLEN - extra,
2 * ETH_ALEN);
} else { } else {
skb_pull_rcsum(skb, DSA_HLEN); skb_pull_rcsum(skb, DSA_HLEN);
memmove(skb->data - ETH_HLEN, dsa_strip_etype_header(skb, DSA_HLEN + extra);
skb->data - ETH_HLEN - DSA_HLEN - extra,
2 * ETH_ALEN);
} }
return skb; return skb;

View File

@ -112,8 +112,9 @@ static struct sk_buff *lan9303_rcv(struct sk_buff *skb, struct net_device *dev)
* and the current ethertype field. * and the current ethertype field.
*/ */
skb_pull_rcsum(skb, 2 + 2); skb_pull_rcsum(skb, 2 + 2);
memmove(skb->data - ETH_HLEN, skb->data - (ETH_HLEN + LAN9303_TAG_LEN),
2 * ETH_ALEN); dsa_strip_etype_header(skb, LAN9303_TAG_LEN);
if (!(lan9303_tag1 & LAN9303_TAG_RX_TRAPPED_TO_CPU)) if (!(lan9303_tag1 & LAN9303_TAG_RX_TRAPPED_TO_CPU))
dsa_default_offload_fwd_mark(skb); dsa_default_offload_fwd_mark(skb);

View File

@ -80,9 +80,7 @@ static struct sk_buff *mtk_tag_rcv(struct sk_buff *skb, struct net_device *dev)
/* Remove MTK tag and recalculate checksum. */ /* Remove MTK tag and recalculate checksum. */
skb_pull_rcsum(skb, MTK_HDR_LEN); skb_pull_rcsum(skb, MTK_HDR_LEN);
memmove(skb->data - ETH_HLEN, dsa_strip_etype_header(skb, MTK_HDR_LEN);
skb->data - ETH_HLEN - MTK_HDR_LEN,
2 * ETH_ALEN);
/* Get source port information */ /* Get source port information */
port = (hdr & MTK_HDR_RECV_SOURCE_PORT_MASK); port = (hdr & MTK_HDR_RECV_SOURCE_PORT_MASK);

View File

@ -72,8 +72,7 @@ static struct sk_buff *qca_tag_rcv(struct sk_buff *skb, struct net_device *dev)
/* Remove QCA tag and recalculate checksum */ /* Remove QCA tag and recalculate checksum */
skb_pull_rcsum(skb, QCA_HDR_LEN); skb_pull_rcsum(skb, QCA_HDR_LEN);
memmove(skb->data - ETH_HLEN, skb->data - ETH_HLEN - QCA_HDR_LEN, dsa_strip_etype_header(skb, QCA_HDR_LEN);
ETH_HLEN - QCA_HDR_LEN);
/* Get source port information */ /* Get source port information */
port = (hdr & QCA_HDR_RECV_SOURCE_PORT_MASK); port = (hdr & QCA_HDR_RECV_SOURCE_PORT_MASK);

View File

@ -108,10 +108,7 @@ static struct sk_buff *rtl4a_tag_rcv(struct sk_buff *skb,
/* Remove RTL4 tag and recalculate checksum */ /* Remove RTL4 tag and recalculate checksum */
skb_pull_rcsum(skb, RTL4_A_HDR_LEN); skb_pull_rcsum(skb, RTL4_A_HDR_LEN);
/* Move ethernet DA and SA in front of the data */ dsa_strip_etype_header(skb, RTL4_A_HDR_LEN);
memmove(skb->data - ETH_HLEN,
skb->data - ETH_HLEN - RTL4_A_HDR_LEN,
2 * ETH_ALEN);
dsa_default_offload_fwd_mark(skb); dsa_default_offload_fwd_mark(skb);

View File

@ -532,9 +532,7 @@ static struct sk_buff *sja1110_rcv_inband_control_extension(struct sk_buff *skb,
/* Advance skb->data past the DSA header */ /* Advance skb->data past the DSA header */
skb_pull_rcsum(skb, SJA1110_HEADER_LEN); skb_pull_rcsum(skb, SJA1110_HEADER_LEN);
/* Remove the DSA header */ dsa_strip_etype_header(skb, SJA1110_HEADER_LEN);
memmove(skb->data - ETH_HLEN, skb->data - ETH_HLEN - SJA1110_HEADER_LEN,
2 * ETH_ALEN);
/* With skb->data in its final place, update the MAC header /* With skb->data in its final place, update the MAC header
* so that eth_hdr() continues to works properly. * so that eth_hdr() continues to works properly.