src/dpdk/lib/librte_net/rte_net.c
static uint32_t
ptype_tunnel(uint16_t *proto, const struct rte_mbuf *m,
	uint32_t *off)
{
	switch (*proto) {
	case IPPROTO_GRE: {
		static const uint8_t opt_len[16] = {
			[0x0] = 4,
			[0x1] = 8,
			[0x2] = 8,
			[0x8] = 8,
			[0x3] = 12,
			[0x9] = 12,
			[0xa] = 12,
			[0xb] = 16,
		};
		const struct rte_gre_hdr *gh;
		struct rte_gre_hdr gh_copy;
		uint16_t flags;

		gh = rte_pktmbuf_read(m, *off, sizeof(*gh), &gh_copy);
		if (unlikely(gh == NULL))
			return 0;

		flags = rte_be_to_cpu_16(*(const uint16_t *)gh);
		flags >>= 12;
		if (opt_len[flags] == 0)
			return 0;

		*off += opt_len[flags];
		*proto = gh->proto;
		if (*proto == rte_cpu_to_be_16(RTE_ETHER_TYPE_TEB))
			return RTE_PTYPE_TUNNEL_NVGRE;
		else
			return RTE_PTYPE_TUNNEL_GRE;
	}
	case IPPROTO_IPIP:
		*proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
		return RTE_PTYPE_TUNNEL_IP;
	case IPPROTO_IPV6:
		*proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
		return RTE_PTYPE_TUNNEL_IP; /* IP is also valid for IPv6 */
	default:
		return 0;
	}
}
/* get the tunnel packet type if any, update proto and off. */
get the tunnel packet type if any, update proto and off.
get the tunnel packet type if any update proto and off .
static uint32_t
ptype_tunnel(uint16_t *proto, const struct rte_mbuf *m,
	uint32_t *off)
{
	switch (*proto) {
	case IPPROTO_GRE: {
		static const uint8_t opt_len[16] = {
			[0x0] = 4,
			[0x1] = 8,
			[0x2] = 8,
			[0x8] = 8,
			[0x3] = 12,
			[0x9] = 12,
			[0xa] = 12,
			[0xb] = 16,
		};
		const struct rte_gre_hdr *gh;
		struct rte_gre_hdr gh_copy;
		uint16_t flags;
		gh = rte_pktmbuf_read(m, *off, sizeof(*gh), &gh_copy);
		if (unlikely(gh == NULL))
			return 0;
		flags = rte_be_to_cpu_16(*(const uint16_t *)gh);
		flags >>= 12;
		if (opt_len[flags] == 0)
			return 0;
		*off += opt_len[flags];
		*proto = gh->proto;
		if (*proto == rte_cpu_to_be_16(RTE_ETHER_TYPE_TEB))
			return RTE_PTYPE_TUNNEL_NVGRE;
		else
			return RTE_PTYPE_TUNNEL_GRE;
	}
	case IPPROTO_IPIP:
		*proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
		return RTE_PTYPE_TUNNEL_IP;
	case IPPROTO_IPV6:
		*proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
		return RTE_PTYPE_TUNNEL_IP; 
	default:
		return 0;
	}
}
static uint32_t ptype_tunnel ( uint16_t * proto , const struct rte_mbuf * m , uint32_t * off ) { switch ( * proto ) { case IPPROTO_GRE : { static const uint8_t opt_len [ 16 ] = { [ 0x0 ] = 4 , [ 0x1 ] = 8 , [ 0x2 ] = 8 , [ 0x8 ] = 8 , [ 0x3 ] = 12 , [ 0x9 ] = 12 , [ 0xa ] = 12 , [ 0xb ] = 16 , } ; const struct rte_gre_hdr * gh ; struct rte_gre_hdr gh_copy ; uint16_t flags ; gh = rte_pktmbuf_read ( m , * off , sizeof ( * gh ) , & gh_copy ) ; if ( unlikely ( gh == NULL ) ) return 0 ; flags = rte_be_to_cpu_16 ( * ( const uint16_t * ) gh ) ; flags >>= 12 ; if ( opt_len [ flags ] == 0 ) return 0 ; * off += opt_len [ flags ] ; * proto = gh -> proto ; if ( * proto == rte_cpu_to_be_16 ( RTE_ETHER_TYPE_TEB ) ) return RTE_PTYPE_TUNNEL_NVGRE ; else return RTE_PTYPE_TUNNEL_GRE ; } case IPPROTO_IPIP : * proto = rte_cpu_to_be_16 ( RTE_ETHER_TYPE_IPV4 ) ; return RTE_PTYPE_TUNNEL_IP ; case IPPROTO_IPV6 : * proto = rte_cpu_to_be_16 ( RTE_ETHER_TYPE_IPV6 ) ; return RTE_PTYPE_TUNNEL_IP ; default : return 0 ; } }
get the tunnel packet type if any, update proto and off.
get the tunnel packet type if any update proto and off .
/* IP is also valid for IPv6 */