diff options
Diffstat (limited to 'platform/linux-dpdk/odp_packet.c')
-rw-r--r-- | platform/linux-dpdk/odp_packet.c | 575 |
1 files changed, 27 insertions, 548 deletions
diff --git a/platform/linux-dpdk/odp_packet.c b/platform/linux-dpdk/odp_packet.c index 0963bd570..1af9bf0c5 100644 --- a/platform/linux-dpdk/odp_packet.c +++ b/platform/linux-dpdk/odp_packet.c @@ -28,6 +28,9 @@ #include <odp_macros_internal.h> #include <odp_packet_internal.h> #include <odp_packet_io_internal.h> +#include <odp_parse_internal.h> + +#include <rte_version.h> #include <protocols/eth.h> #include <protocols/ip.h> @@ -40,6 +43,10 @@ #include <stddef.h> #include <inttypes.h> +#if RTE_VERSION < RTE_VERSION_NUM(21, 11, 0, 0) + #define RTE_MBUF_F_RX_RSS_HASH PKT_RX_RSS_HASH +#endif + #include <odp/visibility_begin.h> /* Fill in packet header field offsets for inline functions */ @@ -64,7 +71,7 @@ const _odp_packet_inline_offset_t _odp_packet_inline ODP_ALIGNED_CACHE = { .user_area = offsetof(odp_packet_hdr_t, uarea_addr), .rss = offsetof(odp_packet_hdr_t, event_hdr.mb.hash.rss), .ol_flags = offsetof(odp_packet_hdr_t, event_hdr.mb.ol_flags), - .rss_flag = PKT_RX_RSS_HASH + .rss_flag = RTE_MBUF_F_RX_RSS_HASH }; #include <odp/visibility_end.h> @@ -1291,500 +1298,6 @@ static uint32_t packet_sum_crc32c(odp_packet_hdr_t *pkt_hdr, return sum; } -/* - * In the worst case we look at the Ethernet header, 8 bytes of LLC/SNAP - * header and two VLAN tags in the same packet. - */ -#define PARSE_ETH_BYTES (sizeof(_odp_ethhdr_t) + 8 + 2 * sizeof(_odp_vlanhdr_t)) -/** Parser helper function for Ethernet packets - * - * Requires up to PARSE_ETH_BYTES bytes of contiguous packet data. - */ -static inline uint16_t parse_eth(packet_parser_t *prs, const uint8_t **parseptr, - uint32_t *offset, uint32_t frame_len) -{ - uint16_t ethtype; - const _odp_ethhdr_t *eth; - uint16_t macaddr0, macaddr2, macaddr4; - const _odp_vlanhdr_t *vlan; - _odp_packet_input_flags_t input_flags; - - input_flags.all = 0; - input_flags.l2 = 1; - input_flags.eth = 1; - - eth = (const _odp_ethhdr_t *)*parseptr; - - /* Detect jumbo frames */ - if (odp_unlikely(frame_len - *offset > _ODP_ETH_LEN_MAX)) - input_flags.jumbo = 1; - - /* Handle Ethernet broadcast/multicast addresses */ - macaddr0 = odp_be_to_cpu_16(*((const uint16_t *)(const void *)eth)); - if (odp_unlikely((macaddr0 & 0x0100) == 0x0100)) - input_flags.eth_mcast = 1; - - if (odp_unlikely(macaddr0 == 0xffff)) { - macaddr2 = - odp_be_to_cpu_16(*((const uint16_t *) - (const void *)eth + 1)); - macaddr4 = - odp_be_to_cpu_16(*((const uint16_t *) - (const void *)eth + 2)); - - if ((macaddr2 == 0xffff) && (macaddr4 == 0xffff)) - input_flags.eth_bcast = 1; - } - - /* Get Ethertype */ - ethtype = odp_be_to_cpu_16(eth->type); - *offset += sizeof(*eth); - *parseptr += sizeof(*eth); - - /* Check for SNAP vs. DIX */ - if (odp_unlikely(ethtype < _ODP_ETH_LEN_MAX)) { - input_flags.snap = 1; - if (ethtype > frame_len - *offset) { - prs->flags.snap_len_err = 1; - ethtype = 0; - goto error; - } - ethtype = odp_be_to_cpu_16(*((const uint16_t *)(uintptr_t) - (*parseptr + 6))); - *offset += 8; - *parseptr += 8; - } - - /* Parse the VLAN header(s), if present */ - if (odp_unlikely(ethtype == _ODP_ETHTYPE_VLAN_OUTER)) { - input_flags.vlan_qinq = 1; - input_flags.vlan = 1; - - vlan = (const _odp_vlanhdr_t *)*parseptr; - ethtype = odp_be_to_cpu_16(vlan->type); - *offset += sizeof(_odp_vlanhdr_t); - *parseptr += sizeof(_odp_vlanhdr_t); - } - - if (ethtype == _ODP_ETHTYPE_VLAN) { - input_flags.vlan = 1; - vlan = (const _odp_vlanhdr_t *)*parseptr; - ethtype = odp_be_to_cpu_16(vlan->type); - *offset += sizeof(_odp_vlanhdr_t); - *parseptr += sizeof(_odp_vlanhdr_t); - } - - /* - * The packet was too short for what we parsed. We just give up - * entirely without trying to parse what fits in the packet. - */ - if (odp_unlikely(*offset > frame_len)) { - input_flags.all = 0; - input_flags.l2 = 1; - ethtype = 0; - } - -error: - prs->input_flags.all |= input_flags.all; - - return ethtype; -} - -#define PARSE_IPV4_BYTES (0xfU * 4) /* max IPv4 header length with options */ -/** - * Parser helper function for IPv4 - * - * Requires up to PARSE_IPV4_BYTES bytes of contiguous packet data. - */ -static inline uint8_t parse_ipv4(packet_parser_t *prs, const uint8_t **parseptr, - uint32_t *offset, uint32_t frame_len, - odp_proto_chksums_t chksums, - uint64_t *l4_part_sum) -{ - const _odp_ipv4hdr_t *ipv4 = (const _odp_ipv4hdr_t *)*parseptr; - uint32_t dstaddr = odp_be_to_cpu_32(ipv4->dst_addr); - uint32_t l3_len = odp_be_to_cpu_16(ipv4->tot_len); - uint16_t frag_offset = odp_be_to_cpu_16(ipv4->frag_offset); - uint8_t ver = _ODP_IPV4HDR_VER(ipv4->ver_ihl); - uint8_t ihl = _ODP_IPV4HDR_IHL(ipv4->ver_ihl); - - if (odp_unlikely(ihl < _ODP_IPV4HDR_IHL_MIN || - ver != 4 || - sizeof(*ipv4) > frame_len - *offset || - (l3_len > frame_len - *offset))) { - prs->flags.ip_err = 1; - return 0; - } - - if (chksums.chksum.ipv4) { - prs->input_flags.l3_chksum_done = 1; - if (chksum_finalize(chksum_partial(ipv4, ihl * 4, 0)) != 0xffff) { - prs->flags.ip_err = 1; - prs->flags.l3_chksum_err = 1; - return 0; - } - } - - *offset += ihl * 4; - *parseptr += ihl * 4; - - if (chksums.chksum.udp || chksums.chksum.tcp) - *l4_part_sum = chksum_partial((const uint8_t *)&ipv4->src_addr, - 2 * _ODP_IPV4ADDR_LEN, 0); - - if (odp_unlikely(ihl > _ODP_IPV4HDR_IHL_MIN)) - prs->input_flags.ipopt = 1; - - /* A packet is a fragment if: - * "more fragments" flag is set (all fragments except the last) - * OR - * "fragment offset" field is nonzero (all fragments except the first) - */ - if (odp_unlikely(_ODP_IPV4HDR_IS_FRAGMENT(frag_offset))) - prs->input_flags.ipfrag = 1; - - /* Handle IPv4 broadcast / multicast */ - if (odp_unlikely(dstaddr == 0xffffffff)) - prs->input_flags.ip_bcast = 1; - - if (odp_unlikely((dstaddr >> 28) == 0xe)) - prs->input_flags.ip_mcast = 1; - - return ipv4->proto; -} - -/* - * Peeks 2 bytes beyond IPv6 base header without length check if there - * are extension headers. - */ -#define PARSE_IPV6_BYTES (sizeof(_odp_ipv6hdr_t) + 2) -/** - * Parser helper function for IPv6 - * - * Requires at least PARSE_IPV6_BYTES bytes of contiguous packet data. - */ -static inline uint8_t parse_ipv6(packet_parser_t *prs, const uint8_t **parseptr, - uint32_t *offset, uint32_t frame_len, - uint32_t seg_len, - odp_proto_chksums_t chksums, - uint64_t *l4_part_sum) -{ - const _odp_ipv6hdr_t *ipv6 = (const _odp_ipv6hdr_t *)*parseptr; - const _odp_ipv6hdr_ext_t *ipv6ext; - uint32_t dstaddr0 = odp_be_to_cpu_32(ipv6->dst_addr.u8[0]); - uint32_t l3_len = odp_be_to_cpu_16(ipv6->payload_len) + - _ODP_IPV6HDR_LEN; - - /* Basic sanity checks on IPv6 header */ - if (odp_unlikely((odp_be_to_cpu_32(ipv6->ver_tc_flow) >> 28) != 6 || - sizeof(*ipv6) > frame_len - *offset || - l3_len > frame_len - *offset)) { - prs->flags.ip_err = 1; - return 0; - } - - /* IPv6 broadcast / multicast flags */ - prs->input_flags.ip_mcast = (dstaddr0 & 0xff000000) == 0xff000000; - prs->input_flags.ip_bcast = 0; - - /* Skip past IPv6 header */ - *offset += sizeof(_odp_ipv6hdr_t); - *parseptr += sizeof(_odp_ipv6hdr_t); - - if (chksums.chksum.udp || chksums.chksum.tcp) - *l4_part_sum = chksum_partial((const uint8_t *)&ipv6->src_addr, - 2 * _ODP_IPV6ADDR_LEN, 0); - - /* Skip past any IPv6 extension headers */ - if (ipv6->next_hdr == _ODP_IPPROTO_HOPOPTS || - ipv6->next_hdr == _ODP_IPPROTO_ROUTE) { - prs->input_flags.ipopt = 1; - - do { - ipv6ext = (const _odp_ipv6hdr_ext_t *)*parseptr; - uint16_t extlen = 8 + ipv6ext->ext_len * 8; - - *offset += extlen; - *parseptr += extlen; - } while ((ipv6ext->next_hdr == _ODP_IPPROTO_HOPOPTS || - ipv6ext->next_hdr == _ODP_IPPROTO_ROUTE) && - *offset < seg_len); - - if (*offset >= prs->l3_offset + - odp_be_to_cpu_16(ipv6->payload_len)) { - prs->flags.ip_err = 1; - return 0; - } - - if (ipv6ext->next_hdr == _ODP_IPPROTO_FRAG) - prs->input_flags.ipfrag = 1; - - return ipv6ext->next_hdr; - } - - if (odp_unlikely(ipv6->next_hdr == _ODP_IPPROTO_FRAG)) { - prs->input_flags.ipopt = 1; - prs->input_flags.ipfrag = 1; - } - - return ipv6->next_hdr; -} - -#define PARSE_TCP_BYTES (sizeof(_odp_tcphdr_t)) -/** - * Parser helper function for TCP - * - * Requires PARSE_TCP_BYTES bytes of contiguous packet data. - */ -static inline void parse_tcp(packet_parser_t *prs, const uint8_t **parseptr, - uint16_t tcp_len, - odp_proto_chksums_t chksums, - uint64_t *l4_part_sum) -{ - const _odp_tcphdr_t *tcp = (const _odp_tcphdr_t *)*parseptr; - uint32_t len = tcp->hl * 4; - - if (odp_unlikely(tcp->hl < sizeof(_odp_tcphdr_t) / sizeof(uint32_t))) - prs->flags.tcp_err = 1; - - if (chksums.chksum.tcp && - !prs->input_flags.ipfrag) { - *l4_part_sum += odp_cpu_to_be_16(tcp_len); -#if ODP_BYTE_ORDER == ODP_BIG_ENDIAN - *l4_part_sum += _ODP_IPPROTO_TCP; -#else - *l4_part_sum += _ODP_IPPROTO_TCP << 8; -#endif - } - - *parseptr += len; -} - -/* - * In the worst case we look at the UDP header and 4 bytes of the UDP - * payload (the non-ESP marker to distinguish IKE packets from ESP packets). - */ -#define PARSE_UDP_BYTES (sizeof(_odp_udphdr_t) + 4) -/** - * Parser helper function for UDP - * - * Requires PARSE_UDP_BYTES bytes of contiguous packet data. - */ -static inline void parse_udp(packet_parser_t *prs, const uint8_t **parseptr, - odp_proto_chksums_t chksums, - uint64_t *l4_part_sum) -{ - const _odp_udphdr_t *udp = (const _odp_udphdr_t *)*parseptr; - uint32_t udplen = odp_be_to_cpu_16(udp->length); - uint16_t ipsec_port = odp_cpu_to_be_16(_ODP_UDP_IPSEC_PORT); - - if (odp_unlikely(udplen < sizeof(_odp_udphdr_t))) { - prs->flags.udp_err = 1; - return; - } - - if (chksums.chksum.udp && - !prs->input_flags.ipfrag) { - if (udp->chksum == 0) { - prs->input_flags.l4_chksum_done = 1; - prs->flags.l4_chksum_err = - (prs->input_flags.ipv4 != 1); - } else { - *l4_part_sum += udp->length; -#if ODP_BYTE_ORDER == ODP_BIG_ENDIAN - *l4_part_sum += _ODP_IPPROTO_UDP; -#else - *l4_part_sum += _ODP_IPPROTO_UDP << 8; -#endif - } - prs->input_flags.udp_chksum_zero = (udp->chksum == 0); - } - - if (odp_unlikely(ipsec_port == udp->dst_port && udplen > 4)) { - uint32_t val; - - memcpy(&val, udp + 1, 4); - if (val != 0) { - prs->input_flags.ipsec = 1; - prs->input_flags.ipsec_udp = 1; - } - } - - *parseptr += sizeof(_odp_udphdr_t); -} - -#define PARSE_SCTP_BYTES (sizeof(_odp_sctphdr_t)) -/** - * Parser helper function for SCTP - * - * Requires PARSE_SCTP_BYTES bytes of contiguous packet data. - */ -static inline void parse_sctp(packet_parser_t *prs, const uint8_t **parseptr, - uint16_t sctp_len, - odp_proto_chksums_t chksums, - uint64_t *l4_part_sum) -{ - if (odp_unlikely(sctp_len < sizeof(_odp_sctphdr_t))) { - prs->flags.sctp_err = 1; - return; - } - - if (chksums.chksum.sctp && - !prs->input_flags.ipfrag) { - const _odp_sctphdr_t *sctp = - (const _odp_sctphdr_t *)*parseptr; - uint32_t crc = ~0; - uint32_t zero = 0; - - crc = odp_hash_crc32c(sctp, sizeof(*sctp) - 4, crc); - crc = odp_hash_crc32c(&zero, 4, crc); - *l4_part_sum = crc; - } - - *parseptr += sizeof(_odp_sctphdr_t); -} - -#define MAX3(a, b, c) (MAX(MAX((a), (b)), (c))) -#define PARSE_L3_L4_BYTES (MAX(PARSE_IPV4_BYTES, PARSE_IPV6_BYTES) + \ - MAX3(PARSE_TCP_BYTES, PARSE_UDP_BYTES, PARSE_SCTP_BYTES)) -/* Requires up to PARSE_L3_L4_BYTES bytes of contiguous packet data. */ -static inline -int packet_parse_common_l3_l4(packet_parser_t *prs, const uint8_t *parseptr, - uint32_t offset, - uint32_t frame_len, uint32_t seg_len, - int layer, uint16_t ethtype, - odp_proto_chksums_t chksums, - uint64_t *l4_part_sum) -{ - uint8_t ip_proto; - - prs->l3_offset = offset; - - if (odp_unlikely(layer <= ODP_PROTO_LAYER_L2)) - return prs->flags.all.error != 0; - - /* Set l3 flag only for known ethtypes */ - prs->input_flags.l3 = 1; - - /* Parse Layer 3 headers */ - switch (ethtype) { - case _ODP_ETHTYPE_IPV4: - prs->input_flags.ipv4 = 1; - ip_proto = parse_ipv4(prs, &parseptr, &offset, frame_len, - chksums, l4_part_sum); - prs->l4_offset = offset; - break; - - case _ODP_ETHTYPE_IPV6: - prs->input_flags.ipv6 = 1; - ip_proto = parse_ipv6(prs, &parseptr, &offset, frame_len, - seg_len, chksums, l4_part_sum); - prs->l4_offset = offset; - break; - - case _ODP_ETHTYPE_ARP: - prs->input_flags.arp = 1; - ip_proto = 255; /* Reserved invalid by IANA */ - break; - - default: - prs->input_flags.l3 = 0; - ip_proto = 255; /* Reserved invalid by IANA */ - } - - if (layer == ODP_PROTO_LAYER_L3) - return prs->flags.all.error != 0; - - /* Set l4 flag only for known ip_proto */ - prs->input_flags.l4 = 1; - - /* Parse Layer 4 headers */ - switch (ip_proto) { - case _ODP_IPPROTO_ICMPV4: - /* Fall through */ - - case _ODP_IPPROTO_ICMPV6: - prs->input_flags.icmp = 1; - break; - - case _ODP_IPPROTO_IPIP: - /* Do nothing */ - break; - - case _ODP_IPPROTO_TCP: - if (odp_unlikely(offset + _ODP_TCPHDR_LEN > seg_len)) - return -1; - prs->input_flags.tcp = 1; - parse_tcp(prs, &parseptr, frame_len - prs->l4_offset, chksums, - l4_part_sum); - break; - - case _ODP_IPPROTO_UDP: - if (odp_unlikely(offset + _ODP_UDPHDR_LEN > seg_len)) - return -1; - prs->input_flags.udp = 1; - parse_udp(prs, &parseptr, chksums, l4_part_sum); - break; - - case _ODP_IPPROTO_AH: - prs->input_flags.ipsec = 1; - prs->input_flags.ipsec_ah = 1; - break; - - case _ODP_IPPROTO_ESP: - prs->input_flags.ipsec = 1; - prs->input_flags.ipsec_esp = 1; - break; - - case _ODP_IPPROTO_SCTP: - prs->input_flags.sctp = 1; - parse_sctp(prs, &parseptr, frame_len - prs->l4_offset, chksums, - l4_part_sum); - break; - - case _ODP_IPPROTO_NO_NEXT: - prs->input_flags.no_next_hdr = 1; - break; - - default: - prs->input_flags.l4 = 0; - break; - } - - return prs->flags.all.error != 0; -} - -/** - * Parse common packet headers up to given layer - * - * The function expects at least PACKET_PARSE_SEG_LEN bytes of data to be - * available from the ptr. Also parse metadata must be already initialized. - */ -int _odp_packet_parse_common(packet_parser_t *prs, const uint8_t *ptr, - uint32_t frame_len, uint32_t seg_len, - int layer, odp_proto_chksums_t chksums) -{ - uint32_t offset; - uint16_t ethtype; - const uint8_t *parseptr; - uint64_t l4_part_sum; - - parseptr = ptr; - offset = 0; - - if (odp_unlikely(layer == ODP_PROTO_LAYER_NONE)) - return 0; - - /* Assume valid L2 header, no CRC/FCS check in SW */ - prs->l2_offset = offset; - - ethtype = parse_eth(prs, &parseptr, &offset, frame_len); - - return packet_parse_common_l3_l4(prs, parseptr, offset, frame_len, - seg_len, layer, ethtype, chksums, - &l4_part_sum); -} - static inline int packet_ipv4_chksum(odp_packet_t pkt, uint32_t offset, _odp_ipv4hdr_t *ip, @@ -1853,7 +1366,7 @@ static int _odp_packet_tcp_udp_chksum_insert(odp_packet_t pkt, uint16_t proto) odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt); uint32_t zero = 0; uint64_t sum; - uint16_t l3_ver; + uint16_t l3_ver = 0; /* GCC */ uint16_t chksum; uint32_t chksum_offset; uint32_t frame_len = odp_packet_len(pkt); @@ -1964,9 +1477,8 @@ int _odp_packet_sctp_chksum_insert(odp_packet_t pkt) return odp_packet_copy_from_mem(pkt, pkt_hdr->p.l4_offset + 8, 4, &sum); } -static int packet_l4_chksum(odp_packet_hdr_t *pkt_hdr, - odp_proto_chksums_t chksums, - uint64_t l4_part_sum) +int _odp_packet_l4_chksum(odp_packet_hdr_t *pkt_hdr, odp_proto_chksums_t chksums, + uint64_t l4_part_sum) { uint32_t frame_len = odp_packet_len(packet_handle(pkt_hdr)); @@ -2042,44 +1554,6 @@ static int packet_l4_chksum(odp_packet_hdr_t *pkt_hdr, return pkt_hdr->p.flags.all.error != 0; } -/** - * Simple packet parser - */ -int _odp_packet_parse_layer(odp_packet_hdr_t *pkt_hdr, - odp_proto_layer_t layer, - odp_proto_chksums_t chksums) -{ - odp_packet_t pkt = packet_handle(pkt_hdr); - uint32_t seg_len = odp_packet_seg_len(pkt); - uint32_t len = odp_packet_len(pkt); - const uint8_t *base = odp_packet_data(pkt); - uint32_t offset = 0; - uint16_t ethtype; - uint64_t l4_part_sum = 0; - int rc; - - if (odp_unlikely(layer == ODP_PROTO_LAYER_NONE)) - return 0; - - /* Assume valid L2 header, no CRC/FCS check in SW */ - pkt_hdr->p.l2_offset = offset; - - ethtype = parse_eth(&pkt_hdr->p, &base, &offset, len); - - rc = packet_parse_common_l3_l4(&pkt_hdr->p, base, offset, - len, - seg_len, layer, ethtype, chksums, - &l4_part_sum); - - if (rc != 0) - return rc; - - if (layer >= ODP_PROTO_LAYER_L4) - return packet_l4_chksum(pkt_hdr, chksums, l4_part_sum); - else - return 0; -} - int odp_packet_parse(odp_packet_t pkt, uint32_t offset, const odp_packet_parse_param_t *param) { @@ -2094,6 +1568,7 @@ int odp_packet_parse(odp_packet_t pkt, uint32_t offset, uint64_t l4_part_sum = 0; const uint32_t min_seglen = PARSE_ETH_BYTES + PARSE_L3_L4_BYTES; uint8_t buf[min_seglen]; + odp_pktin_config_opt_t opt; if (proto == ODP_PROTO_NONE || layer == ODP_PROTO_LAYER_NONE) return -1; @@ -2124,7 +1599,7 @@ int odp_packet_parse(odp_packet_t pkt, uint32_t offset, /* Assume valid L2 header, no CRC/FCS check in SW */ pkt_hdr->p.l2_offset = offset; - ethtype = parse_eth(&pkt_hdr->p, &data, &offset, packet_len); + ethtype = _odp_parse_eth(&pkt_hdr->p, &data, &offset, packet_len); } else if (proto == ODP_PROTO_IPV4) { ethtype = _ODP_ETHTYPE_IPV4; } else if (proto == ODP_PROTO_IPV6) { @@ -2133,17 +1608,18 @@ int odp_packet_parse(odp_packet_t pkt, uint32_t offset, ethtype = 0; /* Invalid */ } - ret = packet_parse_common_l3_l4(&pkt_hdr->p, data, offset, - packet_len, seg_len, - layer, ethtype, - param->chksums, - &l4_part_sum); + opt.all_bits = 0; + + ret = _odp_packet_parse_common_l3_l4(&pkt_hdr->p, data, offset, + packet_len, seg_len, layer, + ethtype, param->chksums, + &l4_part_sum, opt); if (ret) return -1; if (layer >= ODP_PROTO_LAYER_L4) { - ret = packet_l4_chksum(pkt_hdr, param->chksums, l4_part_sum); + ret = _odp_packet_l4_chksum(pkt_hdr, param->chksums, l4_part_sum); if (ret) return -1; } @@ -2390,14 +1866,17 @@ int odp_packet_payload_offset_set(odp_packet_t pkt, uint32_t offset) void odp_packet_aging_tmo_set(odp_packet_t pkt, uint64_t tmo_ns) { - (void)pkt; - (void)tmo_ns; + odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt); + + pkt_hdr->p.flags.tx_aging = tmo_ns ? 1 : 0; + pkt_hdr->tx_aging_ns = tmo_ns; } uint64_t odp_packet_aging_tmo(odp_packet_t pkt) { - (void)pkt; - return 0; + odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt); + + return pkt_hdr->p.flags.tx_aging ? pkt_hdr->tx_aging_ns : 0; } int odp_packet_tx_compl_request(odp_packet_t pkt, const odp_packet_tx_compl_opt_t *opt) |