net: support QinQ in software packet type parser
authorOlivier Matz <olivier.matz@6wind.com>
Mon, 3 Oct 2016 08:38:48 +0000 (10:38 +0200)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Tue, 11 Oct 2016 16:17:12 +0000 (18:17 +0200)
Add a new RTE_PTYPE_L2_ETHER_QINQ packet type, and its support in
rte_net_get_ptype().

Signed-off-by: Didier Pallard <didier.pallard@6wind.com>
Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
lib/librte_mbuf/rte_mbuf_ptype.h
lib/librte_net/rte_ether.h
lib/librte_net/rte_net.c
lib/librte_net/rte_net.h

index a955c5a..6e62492 100644 (file)
@@ -142,6 +142,13 @@ extern "C" {
  * <'ether type'=[0x8100]>
  */
 #define RTE_PTYPE_L2_ETHER_VLAN             0x00000006
+/**
+ * QinQ packet type.
+ *
+ * Packet format:
+ * <'ether type'=[0x88A8]>
+ */
+#define RTE_PTYPE_L2_ETHER_QINQ             0x00000007
 /**
  * Mask of layer 2 packet types.
  * It is used for outer packet for tunneling cases.
index 647e6c9..ff3d065 100644 (file)
@@ -329,6 +329,7 @@ struct vxlan_hdr {
 #define ETHER_TYPE_ARP  0x0806 /**< Arp Protocol. */
 #define ETHER_TYPE_RARP 0x8035 /**< Reverse Arp Protocol. */
 #define ETHER_TYPE_VLAN 0x8100 /**< IEEE 802.1Q VLAN tagging. */
+#define ETHER_TYPE_QINQ 0x88A8 /**< IEEE 802.1ad QinQ tagging. */
 #define ETHER_TYPE_1588 0x88F7 /**< IEEE 802.1AS 1588 Precise Time Protocol. */
 #define ETHER_TYPE_SLOW 0x8809 /**< Slow protocols (LACP and Marker). */
 #define ETHER_TYPE_TEB  0x6558 /**< Transparent Ethernet Bridging. */
index a75b509..dc9e376 100644 (file)
@@ -167,6 +167,9 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m,
        off = sizeof(*eh);
        hdr_lens->l2_len = off;
 
+       if (proto == rte_cpu_to_be_16(ETHER_TYPE_IPv4))
+               goto l3; /* fast path if packet is IPv4 */
+
        if (proto == rte_cpu_to_be_16(ETHER_TYPE_VLAN)) {
                const struct vlan_hdr *vh;
                struct vlan_hdr vh_copy;
@@ -178,8 +181,21 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m,
                off += sizeof(*vh);
                hdr_lens->l2_len += sizeof(*vh);
                proto = vh->eth_proto;
+       } else if (proto == rte_cpu_to_be_16(ETHER_TYPE_QINQ)) {
+               const struct vlan_hdr *vh;
+               struct vlan_hdr vh_copy;
+
+               pkt_type = RTE_PTYPE_L2_ETHER_QINQ;
+               vh = rte_pktmbuf_read(m, off + sizeof(*vh), sizeof(*vh),
+                       &vh_copy);
+               if (unlikely(vh == NULL))
+                       return pkt_type;
+               off += 2 * sizeof(*vh);
+               hdr_lens->l2_len += 2 * sizeof(*vh);
+               proto = vh->eth_proto;
        }
 
+ l3:
        if (proto == rte_cpu_to_be_16(ETHER_TYPE_IPv4)) {
                const struct ipv4_hdr *ip4h;
                struct ipv4_hdr ip4h_copy;
index 81979f1..1224b0e 100644 (file)
@@ -65,7 +65,7 @@ struct rte_net_hdr_lens {
  * (retval & RTE_PTYPE_L2_MASK) != RTE_PTYPE_UNKNOWN.
  *
  * Supported packet types are:
- *   L2: Ether
+ *   L2: Ether, Vlan, QinQ
  *   L3: IPv4, IPv6
  *   L4: TCP, UDP, SCTP
  *