#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 */
}
/* 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 {
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;
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;
return proto;
}
}
- return 0;
+ return -1;
}
/* parse mbuf data to get packet type */
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;
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);
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),
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;
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)
}
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;
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;
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)