net: dsa: create a helper which allocates space for EtherType DSA headers
authorVladimir Oltean <vladimir.oltean@nxp.com>
Tue, 10 Aug 2021 13:13:54 +0000 (16:13 +0300)
committerDavid S. Miller <davem@davemloft.net>
Wed, 11 Aug 2021 13:44:58 +0000 (14:44 +0100)
Hide away the memmove used by DSA EtherType header taggers to shift the
MAC SA and DA to the left to make room for the header, after they've
called skb_push(). The call to skb_push() is still left explicit in
drivers, to be symmetric with dsa_strip_etype_header, and because not
all callers can be refactored to do it (for example, brcm_tag_xmit_ll
has common code for a pre-Ethernet DSA tag and an EtherType DSA 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>
net/dsa/dsa_priv.h
net/dsa/tag_brcm.c
net/dsa/tag_dsa.c
net/dsa/tag_lan9303.c
net/dsa/tag_mtk.c
net/dsa/tag_qca.c
net/dsa/tag_rtl4_a.c
net/dsa/tag_sja1105.c

index 8a12ec1..28e1fbe 100644 (file)
@@ -478,6 +478,35 @@ 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);
 }
 
+/* Helper for creating space for DSA header tags in TX path packets.
+ * Must not be called before skb_push(len).
+ *
+ * Before:
+ *
+ *       <<<<<<<   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+ * ^     <<<<<<<   +-----------------------+-----------------------+-------+
+ * |     <<<<<<<   |    Destination MAC    |      Source MAC       | EType |
+ * |               +-----------------------+-----------------------+-------+
+ * <----- len ----->
+ * |
+ * |
+ * skb->data
+ *
+ * After:
+ *
+ * |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+ * +-----------------------+-----------------------+---------------+-------+
+ * |    Destination MAC    |      Source MAC       |  DSA header   | EType |
+ * +-----------------------+-----------------------+---------------+-------+
+ * ^                                               |               |
+ * |                                               <----- len ----->
+ * skb->data
+ */
+static inline void dsa_alloc_etype_header(struct sk_buff *skb, int len)
+{
+       memmove(skb->data, skb->data + len, 2 * ETH_ALEN);
+}
+
 /* switch.c */
 int dsa_switch_register_notifier(struct dsa_switch *ds);
 void dsa_switch_unregister_notifier(struct dsa_switch *ds);
index 2fc546b..c62a89b 100644 (file)
@@ -99,7 +99,7 @@ static struct sk_buff *brcm_tag_xmit_ll(struct sk_buff *skb,
        skb_push(skb, BRCM_TAG_LEN);
 
        if (offset)
-               memmove(skb->data, skb->data + BRCM_TAG_LEN, offset);
+               dsa_alloc_etype_header(skb, BRCM_TAG_LEN);
 
        brcm_tag = skb->data + offset;
 
@@ -228,7 +228,7 @@ static struct sk_buff *brcm_leg_tag_xmit(struct sk_buff *skb,
 
        skb_push(skb, BRCM_LEG_TAG_LEN);
 
-       memmove(skb->data, skb->data + BRCM_LEG_TAG_LEN, 2 * ETH_ALEN);
+       dsa_alloc_etype_header(skb, BRCM_LEG_TAG_LEN);
 
        brcm_tag = skb->data + 2 * ETH_ALEN;
 
index ad9c841..ab2c638 100644 (file)
@@ -166,7 +166,7 @@ static struct sk_buff *dsa_xmit_ll(struct sk_buff *skb, struct net_device *dev,
        if (skb->protocol == htons(ETH_P_8021Q)) {
                if (extra) {
                        skb_push(skb, extra);
-                       memmove(skb->data, skb->data + extra, 2 * ETH_ALEN);
+                       dsa_alloc_etype_header(skb, extra);
                }
 
                /* Construct tagged DSA tag from 802.1Q tag. */
@@ -181,7 +181,7 @@ static struct sk_buff *dsa_xmit_ll(struct sk_buff *skb, struct net_device *dev,
                }
        } else {
                skb_push(skb, DSA_HLEN + extra);
-               memmove(skb->data, skb->data + DSA_HLEN + extra, 2 * ETH_ALEN);
+               dsa_alloc_etype_header(skb, DSA_HLEN + extra);
 
                /* Construct untagged DSA tag. */
                dsa_header = skb->data + 2 * ETH_ALEN + extra;
index af13c0a..e8ad372 100644 (file)
@@ -62,7 +62,7 @@ static struct sk_buff *lan9303_xmit(struct sk_buff *skb, struct net_device *dev)
        skb_push(skb, LAN9303_TAG_LEN);
 
        /* make room between MACs and Ether-Type */
-       memmove(skb->data, skb->data + LAN9303_TAG_LEN, 2 * ETH_ALEN);
+       dsa_alloc_etype_header(skb, LAN9303_TAG_LEN);
 
        lan9303_tag = (__be16 *)(skb->data + 2 * ETH_ALEN);
        tag = lan9303_xmit_use_arl(dp, skb->data) ?
index 6a78e9f..06d1cfc 100644 (file)
@@ -41,7 +41,7 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb,
        default:
                xmit_tpid = MTK_HDR_XMIT_UNTAGGED;
                skb_push(skb, MTK_HDR_LEN);
-               memmove(skb->data, skb->data + MTK_HDR_LEN, 2 * ETH_ALEN);
+               dsa_alloc_etype_header(skb, MTK_HDR_LEN);
        }
 
        mtk_tag = skb->data + 2 * ETH_ALEN;
index f9fc881..c68a814 100644 (file)
@@ -36,7 +36,7 @@ static struct sk_buff *qca_tag_xmit(struct sk_buff *skb, struct net_device *dev)
 
        skb_push(skb, QCA_HDR_LEN);
 
-       memmove(skb->data, skb->data + QCA_HDR_LEN, 2 * ETH_ALEN);
+       dsa_alloc_etype_header(skb, QCA_HDR_LEN);
        phdr = (__be16 *)(skb->data + 2 * ETH_ALEN);
 
        /* Set the version field, and set destination port information */
index ff8707f..06e901e 100644 (file)
@@ -47,7 +47,7 @@ static struct sk_buff *rtl4a_tag_xmit(struct sk_buff *skb,
                   dp->index);
        skb_push(skb, RTL4_A_HDR_LEN);
 
-       memmove(skb->data, skb->data + RTL4_A_HDR_LEN, 2 * ETH_ALEN);
+       dsa_alloc_etype_header(skb, RTL4_A_HDR_LEN);
        tag = skb->data + 2 * ETH_ALEN;
 
        /* Set Ethertype */
index 33fbd3d..03d5002 100644 (file)
@@ -206,8 +206,7 @@ static struct sk_buff *sja1110_xmit(struct sk_buff *skb,
 
        skb_push(skb, SJA1110_HEADER_LEN);
 
-       /* Move Ethernet header to the left, making space for DSA tag */
-       memmove(skb->data, skb->data + SJA1110_HEADER_LEN, 2 * ETH_ALEN);
+       dsa_alloc_etype_header(skb, SJA1110_HEADER_LEN);
 
        trailer_pos = skb->len;