net: add rte prefix to ether structures
[dpdk.git] / lib / librte_net / rte_net.c
index 53cfef8..315c37c 100644 (file)
@@ -1,34 +1,5 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright 2016 6WIND S.A.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of 6WIND S.A. nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2016 6WIND S.A.
  */
 
 #include <stdint.h>
@@ -42,6 +13,7 @@
 #include <rte_udp.h>
 #include <rte_sctp.h>
 #include <rte_gre.h>
+#include <rte_mpls.h>
 #include <rte_net.h>
 
 /* get l3 packet type from ip6 next protocol */
@@ -207,8 +179,8 @@ ip4_hlen(const struct ipv4_hdr *hdr)
 }
 
 /* parse ipv6 extended headers, update offset and return next proto */
-static uint16_t
-skip_ip6_ext(uint16_t proto, const struct rte_mbuf *m, uint32_t *off,
+int __rte_experimental
+rte_net_skip_ip6_ext(uint16_t proto, const struct rte_mbuf *m, uint32_t *off,
        int *frag)
 {
        struct ext_hdr {
@@ -230,7 +202,7 @@ skip_ip6_ext(uint16_t proto, const struct rte_mbuf *m, uint32_t *off,
                        xh = rte_pktmbuf_read(m, *off, sizeof(*xh),
                                &xh_copy);
                        if (xh == NULL)
-                               return 0;
+                               return -1;
                        *off += (xh->len + 1) * 8;
                        proto = xh->next_hdr;
                        break;
@@ -238,7 +210,7 @@ skip_ip6_ext(uint16_t proto, const struct rte_mbuf *m, uint32_t *off,
                        xh = rte_pktmbuf_read(m, *off, sizeof(*xh),
                                &xh_copy);
                        if (xh == NULL)
-                               return 0;
+                               return -1;
                        *off += 8;
                        proto = xh->next_hdr;
                        *frag = 1;
@@ -249,19 +221,20 @@ skip_ip6_ext(uint16_t proto, const struct rte_mbuf *m, uint32_t *off,
                        return proto;
                }
        }
-       return 0;
+       return -1;
 }
 
 /* parse mbuf data to get packet type */
 uint32_t rte_net_get_ptype(const struct rte_mbuf *m,
-       struct rte_net_hdr_lens *hdr_lens)
+       struct rte_net_hdr_lens *hdr_lens, uint32_t layers)
 {
        struct rte_net_hdr_lens local_hdr_lens;
-       const struct ether_hdr *eh;
-       struct ether_hdr eh_copy;
+       const struct rte_ether_hdr *eh;
+       struct rte_ether_hdr eh_copy;
        uint32_t pkt_type = RTE_PTYPE_L2_ETHER;
        uint32_t off = 0;
        uint16_t proto;
+       int ret;
 
        if (hdr_lens == NULL)
                hdr_lens = &local_hdr_lens;
@@ -273,12 +246,15 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m,
        off = sizeof(*eh);
        hdr_lens->l2_len = off;
 
+       if ((layers & RTE_PTYPE_L2_MASK) == 0)
+               return 0;
+
        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;
+               const struct rte_vlan_hdr *vh;
+               struct rte_vlan_hdr vh_copy;
 
                pkt_type = RTE_PTYPE_L2_ETHER_VLAN;
                vh = rte_pktmbuf_read(m, off, sizeof(*vh), &vh_copy);
@@ -288,8 +264,8 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m,
                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;
+               const struct rte_vlan_hdr *vh;
+               struct rte_vlan_hdr vh_copy;
 
                pkt_type = RTE_PTYPE_L2_ETHER_QINQ;
                vh = rte_pktmbuf_read(m, off + sizeof(*vh), sizeof(*vh),
@@ -299,9 +275,30 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m,
                off += 2 * sizeof(*vh);
                hdr_lens->l2_len += 2 * sizeof(*vh);
                proto = vh->eth_proto;
+       } else if ((proto == rte_cpu_to_be_16(ETHER_TYPE_MPLS)) ||
+               (proto == rte_cpu_to_be_16(ETHER_TYPE_MPLSM))) {
+               unsigned int i;
+               const struct mpls_hdr *mh;
+               struct mpls_hdr mh_copy;
+
+#define MAX_MPLS_HDR 5
+               for (i = 0; i < MAX_MPLS_HDR; i++) {
+                       mh = rte_pktmbuf_read(m, off + (i * sizeof(*mh)),
+                               sizeof(*mh), &mh_copy);
+                       if (unlikely(mh == NULL))
+                               return pkt_type;
+               }
+               if (i == MAX_MPLS_HDR)
+                       return pkt_type;
+               pkt_type = RTE_PTYPE_L2_ETHER_MPLS;
+               hdr_lens->l2_len += (sizeof(*mh) * i);
+               return pkt_type;
        }
 
- l3:
+l3:
+       if ((layers & RTE_PTYPE_L3_MASK) == 0)
+               return pkt_type;
+
        if (proto == rte_cpu_to_be_16(ETHER_TYPE_IPv4)) {
                const struct ipv4_hdr *ip4h;
                struct ipv4_hdr ip4h_copy;
@@ -313,6 +310,10 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m,
                pkt_type |= ptype_l3_ip(ip4h->version_ihl);
                hdr_lens->l3_len = ip4_hlen(ip4h);
                off += hdr_lens->l3_len;
+
+               if ((layers & RTE_PTYPE_L4_MASK) == 0)
+                       return pkt_type;
+
                if (ip4h->fragment_offset & rte_cpu_to_be_16(
                                IPV4_HDR_OFFSET_MASK | IPV4_HDR_MF_FLAG)) {
                        pkt_type |= RTE_PTYPE_L4_FRAG;
@@ -335,11 +336,18 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m,
                off += hdr_lens->l3_len;
                pkt_type |= ptype_l3_ip6(proto);
                if ((pkt_type & RTE_PTYPE_L3_MASK) == RTE_PTYPE_L3_IPV6_EXT) {
-                       proto = skip_ip6_ext(proto, m, &off, &frag);
+                       ret = rte_net_skip_ip6_ext(proto, m, &off, &frag);
+                       if (ret < 0)
+                               return pkt_type;
+                       proto = ret;
                        hdr_lens->l3_len = off - hdr_lens->l2_len;
                }
                if (proto == 0)
                        return pkt_type;
+
+               if ((layers & RTE_PTYPE_L4_MASK) == 0)
+                       return pkt_type;
+
                if (frag) {
                        pkt_type |= RTE_PTYPE_L4_FRAG;
                        hdr_lens->l4_len = 0;
@@ -368,6 +376,10 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m,
                uint32_t prev_off = off;
 
                hdr_lens->l4_len = 0;
+
+               if ((layers & RTE_PTYPE_TUNNEL_MASK) == 0)
+                       return pkt_type;
+
                pkt_type |= ptype_tunnel(&proto, m, &off);
                hdr_lens->tunnel_len = off - prev_off;
        }
@@ -375,6 +387,10 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m,
        /* same job for inner header: we need to duplicate the code
         * because the packet types do not have the same value.
         */
+       if ((layers & RTE_PTYPE_INNER_L2_MASK) == 0)
+               return pkt_type;
+
+       hdr_lens->inner_l2_len = 0;
        if (proto == rte_cpu_to_be_16(ETHER_TYPE_TEB)) {
                eh = rte_pktmbuf_read(m, off, sizeof(*eh), &eh_copy);
                if (unlikely(eh == NULL))
@@ -386,8 +402,8 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m,
        }
 
        if (proto == rte_cpu_to_be_16(ETHER_TYPE_VLAN)) {
-               const struct vlan_hdr *vh;
-               struct vlan_hdr vh_copy;
+               const struct rte_vlan_hdr *vh;
+               struct rte_vlan_hdr vh_copy;
 
                pkt_type &= ~RTE_PTYPE_INNER_L2_MASK;
                pkt_type |= RTE_PTYPE_INNER_L2_ETHER_VLAN;
@@ -398,8 +414,8 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m,
                hdr_lens->inner_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;
+               const struct rte_vlan_hdr *vh;
+               struct rte_vlan_hdr vh_copy;
 
                pkt_type &= ~RTE_PTYPE_INNER_L2_MASK;
                pkt_type |= RTE_PTYPE_INNER_L2_ETHER_QINQ;
@@ -412,6 +428,9 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m,
                proto = vh->eth_proto;
        }
 
+       if ((layers & RTE_PTYPE_INNER_L3_MASK) == 0)
+               return pkt_type;
+
        if (proto == rte_cpu_to_be_16(ETHER_TYPE_IPv4)) {
                const struct ipv4_hdr *ip4h;
                struct ipv4_hdr ip4h_copy;
@@ -423,6 +442,9 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m,
                pkt_type |= ptype_inner_l3_ip(ip4h->version_ihl);
                hdr_lens->inner_l3_len = ip4_hlen(ip4h);
                off += hdr_lens->inner_l3_len;
+
+               if ((layers & RTE_PTYPE_INNER_L4_MASK) == 0)
+                       return pkt_type;
                if (ip4h->fragment_offset &
                                rte_cpu_to_be_16(IPV4_HDR_OFFSET_MASK |
                                        IPV4_HDR_MF_FLAG)) {
@@ -450,11 +472,18 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m,
                        uint32_t prev_off;
 
                        prev_off = off;
-                       proto = skip_ip6_ext(proto, m, &off, &frag);
+                       ret = rte_net_skip_ip6_ext(proto, m, &off, &frag);
+                       if (ret < 0)
+                               return pkt_type;
+                       proto = ret;
                        hdr_lens->inner_l3_len += off - prev_off;
                }
                if (proto == 0)
                        return pkt_type;
+
+               if ((layers & RTE_PTYPE_INNER_L4_MASK) == 0)
+                       return pkt_type;
+
                if (frag) {
                        pkt_type |= RTE_PTYPE_INNER_L4_FRAG;
                        hdr_lens->inner_l4_len = 0;