diff mbox

[v2,1/3] linux-gen: packet: add packet parser structure

Message ID 1465814925-27259-1-git-send-email-matias.elo@nokia.com
State Superseded
Headers show

Commit Message

Elo, Matias (Nokia - FI/Espoo) June 13, 2016, 10:48 a.m. UTC
Collect odp_packet_hdr_t members set by the packet parser
inside a common structure packet_parser_t.

Signed-off-by: Matias Elo <matias.elo@nokia.com>
---
 .../include/odp_classification_inlines.h           |  36 ++--
 .../linux-generic/include/odp_packet_internal.h    |  58 ++++---
 platform/linux-generic/odp_classification.c        |  16 +-
 platform/linux-generic/odp_packet.c                | 183 +++++++++++----------
 platform/linux-generic/odp_packet_flags.c          |  53 +++---
 platform/linux-generic/odp_packet_io.c             |   2 +-
 platform/linux-generic/pktio/dpdk.c                |   2 +-
 platform/linux-generic/pktio/ipc.c                 |   2 +-
 platform/linux-generic/pktio/loop.c                |   2 +-
 platform/linux-generic/pktio/netmap.c              |   2 +-
 platform/linux-generic/pktio/socket.c              |   2 +-
 platform/linux-generic/pktio/socket_mmap.c         |   2 +-
 12 files changed, 183 insertions(+), 177 deletions(-)

Comments

Bill Fischofer June 13, 2016, 9:50 p.m. UTC | #1
For this series:

Reviewed-and-tested-by: Bill Fischofer <bill.fischofer@linaro.org>

On Mon, Jun 13, 2016 at 5:48 AM, Matias Elo <matias.elo@nokia.com> wrote:

> Collect odp_packet_hdr_t members set by the packet parser
> inside a common structure packet_parser_t.
>
> Signed-off-by: Matias Elo <matias.elo@nokia.com>
> ---
>  .../include/odp_classification_inlines.h           |  36 ++--
>  .../linux-generic/include/odp_packet_internal.h    |  58 ++++---
>  platform/linux-generic/odp_classification.c        |  16 +-
>  platform/linux-generic/odp_packet.c                | 183
> +++++++++++----------
>  platform/linux-generic/odp_packet_flags.c          |  53 +++---
>  platform/linux-generic/odp_packet_io.c             |   2 +-
>  platform/linux-generic/pktio/dpdk.c                |   2 +-
>  platform/linux-generic/pktio/ipc.c                 |   2 +-
>  platform/linux-generic/pktio/loop.c                |   2 +-
>  platform/linux-generic/pktio/netmap.c              |   2 +-
>  platform/linux-generic/pktio/socket.c              |   2 +-
>  platform/linux-generic/pktio/socket_mmap.c         |   2 +-
>  12 files changed, 183 insertions(+), 177 deletions(-)
>
> diff --git a/platform/linux-generic/include/odp_classification_inlines.h
> b/platform/linux-generic/include/odp_classification_inlines.h
> index 08300f5..611d706 100644
> --- a/platform/linux-generic/include/odp_classification_inlines.h
> +++ b/platform/linux-generic/include/odp_classification_inlines.h
> @@ -47,9 +47,9 @@ static inline int verify_pmr_ip_proto(const uint8_t
> *pkt_addr,
>  {
>         const odph_ipv4hdr_t *ip;
>         uint8_t proto;
> -       if (!pkt_hdr->input_flags.ipv4)
> +       if (!pkt_hdr->p.input_flags.ipv4)
>                 return 0;
> -       ip = (const odph_ipv4hdr_t *)(pkt_addr + pkt_hdr->l3_offset);
> +       ip = (const odph_ipv4hdr_t *)(pkt_addr + pkt_hdr->p.l3_offset);
>         proto = ip->proto;
>         if (term_value->match.value == (proto & term_value->match.mask))
>                 return 1;
> @@ -63,9 +63,9 @@ static inline int verify_pmr_ipv4_saddr(const uint8_t
> *pkt_addr,
>  {
>         const odph_ipv4hdr_t *ip;
>         uint32_t ipaddr;
> -       if (!pkt_hdr->input_flags.ipv4)
> +       if (!pkt_hdr->p.input_flags.ipv4)
>                 return 0;
> -       ip = (const odph_ipv4hdr_t *)(pkt_addr + pkt_hdr->l3_offset);
> +       ip = (const odph_ipv4hdr_t *)(pkt_addr + pkt_hdr->p.l3_offset);
>         ipaddr = odp_be_to_cpu_32(ip->src_addr);
>         if (term_value->match.value == (ipaddr & term_value->match.mask))
>                 return 1;
> @@ -79,9 +79,9 @@ static inline int verify_pmr_ipv4_daddr(const uint8_t
> *pkt_addr,
>  {
>         const odph_ipv4hdr_t *ip;
>         uint32_t ipaddr;
> -       if (!pkt_hdr->input_flags.ipv4)
> +       if (!pkt_hdr->p.input_flags.ipv4)
>                 return 0;
> -       ip = (const odph_ipv4hdr_t *)(pkt_addr + pkt_hdr->l3_offset);
> +       ip = (const odph_ipv4hdr_t *)(pkt_addr + pkt_hdr->p.l3_offset);
>         ipaddr = odp_be_to_cpu_32(ip->dst_addr);
>         if (term_value->match.value == (ipaddr & term_value->match.mask))
>                 return 1;
> @@ -95,9 +95,9 @@ static inline int verify_pmr_tcp_sport(const uint8_t
> *pkt_addr,
>  {
>         uint16_t sport;
>         const odph_tcphdr_t *tcp;
> -       if (!pkt_hdr->input_flags.tcp)
> +       if (!pkt_hdr->p.input_flags.tcp)
>                 return 0;
> -       tcp = (const odph_tcphdr_t *)(pkt_addr + pkt_hdr->l4_offset);
> +       tcp = (const odph_tcphdr_t *)(pkt_addr + pkt_hdr->p.l4_offset);
>         sport = odp_be_to_cpu_16(tcp->src_port);
>         if (term_value->match.value == (sport & term_value->match.mask))
>                 return 1;
> @@ -111,9 +111,9 @@ static inline int verify_pmr_tcp_dport(const uint8_t
> *pkt_addr,
>  {
>         uint16_t dport;
>         const odph_tcphdr_t *tcp;
> -       if (!pkt_hdr->input_flags.tcp)
> +       if (!pkt_hdr->p.input_flags.tcp)
>                 return 0;
> -       tcp = (const odph_tcphdr_t *)(pkt_addr + pkt_hdr->l4_offset);
> +       tcp = (const odph_tcphdr_t *)(pkt_addr + pkt_hdr->p.l4_offset);
>         dport = odp_be_to_cpu_16(tcp->dst_port);
>         if (term_value->match.value == (dport & term_value->match.mask))
>                 return 1;
> @@ -127,9 +127,9 @@ static inline int verify_pmr_udp_dport(const uint8_t
> *pkt_addr,
>  {
>         uint16_t dport;
>         const odph_udphdr_t *udp;
> -       if (!pkt_hdr->input_flags.udp)
> +       if (!pkt_hdr->p.input_flags.udp)
>                 return 0;
> -       udp = (const odph_udphdr_t *)(pkt_addr + pkt_hdr->l4_offset);
> +       udp = (const odph_udphdr_t *)(pkt_addr + pkt_hdr->p.l4_offset);
>         dport = odp_be_to_cpu_16(udp->dst_port);
>         if (term_value->match.value == (dport & term_value->match.mask))
>                         return 1;
> @@ -144,9 +144,9 @@ static inline int verify_pmr_udp_sport(const uint8_t
> *pkt_addr,
>         uint16_t sport;
>         const odph_udphdr_t *udp;
>
> -       if (!pkt_hdr->input_flags.udp)
> +       if (!pkt_hdr->p.input_flags.udp)
>                 return 0;
> -       udp = (const odph_udphdr_t *)(pkt_addr + pkt_hdr->l4_offset);
> +       udp = (const odph_udphdr_t *)(pkt_addr + pkt_hdr->p.l4_offset);
>         sport = odp_be_to_cpu_16(udp->src_port);
>         if (term_value->match.value == (sport & term_value->match.mask))
>                 return 1;
> @@ -165,7 +165,7 @@ static inline int verify_pmr_dmac(const uint8_t
> *pkt_addr,
>         if (!packet_hdr_has_eth(pkt_hdr))
>                 return 0;
>
> -       eth = (const odph_ethhdr_t *)(pkt_addr + pkt_hdr->l2_offset);
> +       eth = (const odph_ethhdr_t *)(pkt_addr + pkt_hdr->p.l2_offset);
>         memcpy(&dmac_be, eth->dst.addr, ODPH_ETHADDR_LEN);
>         dmac = odp_be_to_cpu_64(dmac_be);
>         /* since we are converting a 48 bit ethernet address from BE to cpu
> @@ -217,13 +217,13 @@ static inline int verify_pmr_ipsec_spi(const uint8_t
> *pkt_addr,
>  {
>         uint32_t spi;
>
> -       pkt_addr += pkt_hdr->l4_offset;
> +       pkt_addr += pkt_hdr->p.l4_offset;
>
> -       if (pkt_hdr->input_flags.ipsec_ah) {
> +       if (pkt_hdr->p.input_flags.ipsec_ah) {
>                 const odph_ahhdr_t *ahhdr = (const odph_ahhdr_t *)pkt_addr;
>
>                 spi = odp_be_to_cpu_32(ahhdr->spi);
> -       } else if (pkt_hdr->input_flags.ipsec_esp) {
> +       } else if (pkt_hdr->p.input_flags.ipsec_esp) {
>                 const odph_esphdr_t *esphdr = (const odph_esphdr_t
> *)pkt_addr;
>
>                 spi = odp_be_to_cpu_32(esphdr->spi);
> diff --git a/platform/linux-generic/include/odp_packet_internal.h
> b/platform/linux-generic/include/odp_packet_internal.h
> index d5ace12..99de9f9 100644
> --- a/platform/linux-generic/include/odp_packet_internal.h
> +++ b/platform/linux-generic/include/odp_packet_internal.h
> @@ -128,6 +128,23 @@ ODP_STATIC_ASSERT(sizeof(output_flags_t) ==
> sizeof(uint32_t),
>                   "OUTPUT_FLAGS_SIZE_ERROR");
>
>  /**
> + * Packet parser metadata
> + */
> +typedef struct {
> +       input_flags_t  input_flags;
> +       error_flags_t  error_flags;
> +       output_flags_t output_flags;
> +
> +       uint32_t l2_offset; /**< offset to L2 hdr, e.g. Eth */
> +       uint32_t l3_offset; /**< offset to L3 hdr, e.g. IPv4, IPv6 */
> +       uint32_t l4_offset; /**< offset to L4 hdr (TCP, UDP, SCTP, also
> ICMP) */
> +
> +       uint32_t l3_len;    /**< Layer 3 length */
> +       uint32_t l4_len;    /**< Layer 4 length */
> +
> +} packet_parser_t;
> +
> +/**
>   * Internal Packet header
>   *
>   * To optimize fast path performance this struct is not initialized to
> zero in
> @@ -139,13 +156,7 @@ typedef struct {
>         odp_buffer_hdr_t buf_hdr;
>
>         /* Following members are initialized by packet_init() */
> -       input_flags_t  input_flags;
> -       error_flags_t  error_flags;
> -       output_flags_t output_flags;
> -
> -       uint32_t l2_offset; /**< offset to L2 hdr, e.g. Eth */
> -       uint32_t l3_offset; /**< offset to L3 hdr, e.g. IPv4, IPv6 */
> -       uint32_t l4_offset; /**< offset to L4 hdr (TCP, UDP, SCTP, also
> ICMP) */
> +       packet_parser_t p;
>
>         uint32_t frame_len;
>         uint32_t headroom;
> @@ -154,9 +165,6 @@ typedef struct {
>         odp_pktio_t input;
>
>         /* Members below are not initialized by packet_init() */
> -       uint32_t l3_len;         /**< Layer 3 length */
> -       uint32_t l4_len;         /**< Layer 4 length */
> -
>         odp_queue_t dst_queue;   /**< Classifier destination queue */
>
>         uint32_t flow_hash;      /**< Flow hash value */
> @@ -180,18 +188,14 @@ static inline odp_packet_hdr_t
> *odp_packet_hdr(odp_packet_t pkt)
>  static inline void copy_packet_parser_metadata(odp_packet_hdr_t *src_hdr,
>                                                odp_packet_hdr_t *dst_hdr)
>  {
> -       dst_hdr->input_flags    = src_hdr->input_flags;
> -       dst_hdr->error_flags    = src_hdr->error_flags;
> -       dst_hdr->output_flags   = src_hdr->output_flags;
> +       dst_hdr->p = src_hdr->p;
> +}
>
> -       dst_hdr->l2_offset      = src_hdr->l2_offset;
> -       dst_hdr->l3_offset      = src_hdr->l3_offset;
> -       dst_hdr->l4_offset      = src_hdr->l4_offset;
> -
> -       dst_hdr->l3_len         = src_hdr->l3_len;
> -       dst_hdr->l4_len         = src_hdr->l4_len;
> -
> -       dst_hdr->dst_queue      = src_hdr->dst_queue;
> +static inline void copy_packet_cls_metadata(odp_packet_hdr_t *src_hdr,
> +                                           odp_packet_hdr_t *dst_hdr)
> +{
> +       dst_hdr->p = src_hdr->p;
> +       dst_hdr->dst_queue = src_hdr->dst_queue;
>  }
>
>  static inline void *packet_map(odp_packet_hdr_t *pkt_hdr,
> @@ -285,12 +289,12 @@ static inline void packet_set_len(odp_packet_t pkt,
> uint32_t len)
>
>  static inline int packet_parse_l2_not_done(odp_packet_hdr_t *pkt_hdr)
>  {
> -       return !pkt_hdr->input_flags.parsed_l2;
> +       return !pkt_hdr->p.input_flags.parsed_l2;
>  }
>
>  static inline int packet_parse_not_complete(odp_packet_hdr_t *pkt_hdr)
>  {
> -       return !pkt_hdr->input_flags.parsed_all;
> +       return !pkt_hdr->p.input_flags.parsed_all;
>  }
>
>  /* Forward declarations */
> @@ -315,24 +319,24 @@ odp_packet_t _odp_packet_from_buffer(odp_buffer_t
> buf);
>
>  static inline int packet_hdr_has_l2(odp_packet_hdr_t *pkt_hdr)
>  {
> -       return pkt_hdr->input_flags.l2;
> +       return pkt_hdr->p.input_flags.l2;
>  }
>
>  static inline void packet_hdr_has_l2_set(odp_packet_hdr_t *pkt_hdr, int
> val)
>  {
> -       pkt_hdr->input_flags.l2 = val;
> +       pkt_hdr->p.input_flags.l2 = val;
>  }
>
>  static inline int packet_hdr_has_eth(odp_packet_hdr_t *pkt_hdr)
>  {
> -       return pkt_hdr->input_flags.eth;
> +       return pkt_hdr->p.input_flags.eth;
>  }
>
>  static inline void packet_set_ts(odp_packet_hdr_t *pkt_hdr, odp_time_t
> *ts)
>  {
>         if (ts != NULL) {
>                 pkt_hdr->timestamp = *ts;
> -               pkt_hdr->input_flags.timestamp = 1;
> +               pkt_hdr->p.input_flags.timestamp = 1;
>         }
>  }
>
> diff --git a/platform/linux-generic/odp_classification.c
> b/platform/linux-generic/odp_classification.c
> index 7520bdc..15fe9a8 100644
> --- a/platform/linux-generic/odp_classification.c
> +++ b/platform/linux-generic/odp_classification.c
> @@ -776,7 +776,7 @@ static inline cos_t *cls_select_cos(pktio_entry_t
> *entry,
>                 packet_parse_full(pkt_hdr);
>
>         /* Return error cos for error packet */
> -       if (pkt_hdr->error_flags.all)
> +       if (pkt_hdr->p.error_flags.all)
>                 return cls->error_cos;
>         /* Calls all the PMRs attached at the PKTIO level*/
>         for (i = 0; i < odp_atomic_load_u32(&default_cos->s.num_rule);
> i++) {
> @@ -827,7 +827,7 @@ int cls_classify_packet(pktio_entry_t *entry, const
> uint8_t *base, uint16_t len,
>                 return -EFAULT;
>
>         *pool = cos->s.pool->s.pool_hdl;
> -       pkt_hdr->input_flags.dst_queue = 1;
> +       pkt_hdr->p.input_flags.dst_queue = 1;
>         pkt_hdr->dst_queue = cos->s.queue->s.handle;
>
>         return 0;
> @@ -841,12 +841,12 @@ cos_t *match_qos_l3_cos(pmr_l3_cos_t *l3_cos, const
> uint8_t *pkt_addr,
>         const odph_ipv4hdr_t *ipv4;
>         const odph_ipv6hdr_t *ipv6;
>
> -       if (hdr->input_flags.l3 && hdr->input_flags.ipv4) {
> -               ipv4 = (const odph_ipv4hdr_t *)(pkt_addr + hdr->l3_offset);
> +       if (hdr->p.input_flags.l3 && hdr->p.input_flags.ipv4) {
> +               ipv4 = (const odph_ipv4hdr_t *)(pkt_addr +
> hdr->p.l3_offset);
>                 dscp = ODPH_IPV4HDR_DSCP(ipv4->tos);
>                 cos = l3_cos->cos[dscp];
> -       } else if (hdr->input_flags.l3 && hdr->input_flags.ipv6) {
> -               ipv6 = (const odph_ipv6hdr_t *)(pkt_addr + hdr->l3_offset);
> +       } else if (hdr->p.input_flags.l3 && hdr->p.input_flags.ipv6) {
> +               ipv6 = (const odph_ipv6hdr_t *)(pkt_addr +
> hdr->p.l3_offset);
>                 dscp = ODPH_IPV6HDR_DSCP(ipv6->ver_tc_flow);
>                 cos = l3_cos->cos[dscp];
>         }
> @@ -862,9 +862,9 @@ cos_t *match_qos_l2_cos(pmr_l2_cos_t *l2_cos, const
> uint8_t *pkt_addr,
>         const odph_vlanhdr_t *vlan;
>         uint16_t qos;
>
> -       if (packet_hdr_has_l2(hdr) && hdr->input_flags.vlan &&
> +       if (packet_hdr_has_l2(hdr) && hdr->p.input_flags.vlan &&
>             packet_hdr_has_eth(hdr)) {
> -               eth = (const odph_ethhdr_t *)(pkt_addr + hdr->l2_offset);
> +               eth = (const odph_ethhdr_t *)(pkt_addr + hdr->p.l2_offset);
>                 vlan = (const odph_vlanhdr_t *)(eth + 1);
>                 qos = odp_be_to_cpu_16(vlan->tci);
>                 qos = ((qos >> 13) & 0x07);
> diff --git a/platform/linux-generic/odp_packet.c
> b/platform/linux-generic/odp_packet.c
> index 2868736..991a648 100644
> --- a/platform/linux-generic/odp_packet.c
> +++ b/platform/linux-generic/odp_packet.c
> @@ -28,19 +28,19 @@
>
>  static inline void packet_parse_disable(odp_packet_hdr_t *pkt_hdr)
>  {
> -       pkt_hdr->input_flags.parsed_l2  = 1;
> -       pkt_hdr->input_flags.parsed_all = 1;
> +       pkt_hdr->p.input_flags.parsed_l2  = 1;
> +       pkt_hdr->p.input_flags.parsed_all = 1;
>  }
>
>  void packet_parse_reset(odp_packet_hdr_t *pkt_hdr)
>  {
>         /* Reset parser metadata before new parse */
> -       pkt_hdr->error_flags.all  = 0;
> -       pkt_hdr->input_flags.all  = 0;
> -       pkt_hdr->output_flags.all = 0;
> -       pkt_hdr->l2_offset        = 0;
> -       pkt_hdr->l3_offset        = ODP_PACKET_OFFSET_INVALID;
> -       pkt_hdr->l4_offset        = ODP_PACKET_OFFSET_INVALID;
> +       pkt_hdr->p.error_flags.all  = 0;
> +       pkt_hdr->p.input_flags.all  = 0;
> +       pkt_hdr->p.output_flags.all = 0;
> +       pkt_hdr->p.l2_offset        = 0;
> +       pkt_hdr->p.l3_offset        = ODP_PACKET_OFFSET_INVALID;
> +       pkt_hdr->p.l4_offset        = ODP_PACKET_OFFSET_INVALID;
>  }
>
>  /**
> @@ -49,13 +49,13 @@ void packet_parse_reset(odp_packet_hdr_t *pkt_hdr)
>  static void packet_init(pool_entry_t *pool, odp_packet_hdr_t *pkt_hdr,
>                         size_t size, int parse)
>  {
> -       pkt_hdr->input_flags.all  = 0;
> -       pkt_hdr->output_flags.all = 0;
> -       pkt_hdr->error_flags.all  = 0;
> +       pkt_hdr->p.input_flags.all  = 0;
> +       pkt_hdr->p.output_flags.all = 0;
> +       pkt_hdr->p.error_flags.all  = 0;
>
> -       pkt_hdr->l2_offset = 0;
> -       pkt_hdr->l3_offset = ODP_PACKET_OFFSET_INVALID;
> -       pkt_hdr->l4_offset = ODP_PACKET_OFFSET_INVALID;
> +       pkt_hdr->p.l2_offset = 0;
> +       pkt_hdr->p.l3_offset = ODP_PACKET_OFFSET_INVALID;
> +       pkt_hdr->p.l4_offset = ODP_PACKET_OFFSET_INVALID;
>
>         /* Disable lazy parsing on user allocated packets */
>         if (!parse)
> @@ -431,7 +431,7 @@ void *odp_packet_l2_ptr(odp_packet_t pkt, uint32_t
> *len)
>
>         if (!packet_hdr_has_l2(pkt_hdr))
>                 return NULL;
> -       return packet_map(pkt_hdr, pkt_hdr->l2_offset, len);
> +       return packet_map(pkt_hdr, pkt_hdr->p.l2_offset, len);
>  }
>
>  uint32_t odp_packet_l2_offset(odp_packet_t pkt)
> @@ -440,7 +440,7 @@ uint32_t odp_packet_l2_offset(odp_packet_t pkt)
>
>         if (!packet_hdr_has_l2(pkt_hdr))
>                 return ODP_PACKET_OFFSET_INVALID;
> -       return pkt_hdr->l2_offset;
> +       return pkt_hdr->p.l2_offset;
>  }
>
>  int odp_packet_l2_offset_set(odp_packet_t pkt, uint32_t offset)
> @@ -451,7 +451,7 @@ int odp_packet_l2_offset_set(odp_packet_t pkt,
> uint32_t offset)
>                 return -1;
>
>         packet_hdr_has_l2_set(pkt_hdr, 1);
> -       pkt_hdr->l2_offset = offset;
> +       pkt_hdr->p.l2_offset = offset;
>         return 0;
>  }
>
> @@ -461,7 +461,7 @@ void *odp_packet_l3_ptr(odp_packet_t pkt, uint32_t
> *len)
>
>         if (packet_parse_not_complete(pkt_hdr))
>                 packet_parse_full(pkt_hdr);
> -       return packet_map(pkt_hdr, pkt_hdr->l3_offset, len);
> +       return packet_map(pkt_hdr, pkt_hdr->p.l3_offset, len);
>  }
>
>  uint32_t odp_packet_l3_offset(odp_packet_t pkt)
> @@ -470,7 +470,7 @@ uint32_t odp_packet_l3_offset(odp_packet_t pkt)
>
>         if (packet_parse_not_complete(pkt_hdr))
>                 packet_parse_full(pkt_hdr);
> -       return pkt_hdr->l3_offset;
> +       return pkt_hdr->p.l3_offset;
>  }
>
>  int odp_packet_l3_offset_set(odp_packet_t pkt, uint32_t offset)
> @@ -482,7 +482,7 @@ int odp_packet_l3_offset_set(odp_packet_t pkt,
> uint32_t offset)
>
>         if (packet_parse_not_complete(pkt_hdr))
>                 packet_parse_full(pkt_hdr);
> -       pkt_hdr->l3_offset = offset;
> +       pkt_hdr->p.l3_offset = offset;
>         return 0;
>  }
>
> @@ -492,7 +492,7 @@ void *odp_packet_l4_ptr(odp_packet_t pkt, uint32_t
> *len)
>
>         if (packet_parse_not_complete(pkt_hdr))
>                 packet_parse_full(pkt_hdr);
> -       return packet_map(pkt_hdr, pkt_hdr->l4_offset, len);
> +       return packet_map(pkt_hdr, pkt_hdr->p.l4_offset, len);
>  }
>
>  uint32_t odp_packet_l4_offset(odp_packet_t pkt)
> @@ -501,7 +501,7 @@ uint32_t odp_packet_l4_offset(odp_packet_t pkt)
>
>         if (packet_parse_not_complete(pkt_hdr))
>                 packet_parse_full(pkt_hdr);
> -       return pkt_hdr->l4_offset;
> +       return pkt_hdr->p.l4_offset;
>  }
>
>  int odp_packet_l4_offset_set(odp_packet_t pkt, uint32_t offset)
> @@ -513,7 +513,7 @@ int odp_packet_l4_offset_set(odp_packet_t pkt,
> uint32_t offset)
>
>         if (packet_parse_not_complete(pkt_hdr))
>                 packet_parse_full(pkt_hdr);
> -       pkt_hdr->l4_offset = offset;
> +       pkt_hdr->p.l4_offset = offset;
>         return 0;
>  }
>
> @@ -529,7 +529,7 @@ void odp_packet_flow_hash_set(odp_packet_t pkt,
> uint32_t flow_hash)
>         odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
>
>         pkt_hdr->flow_hash = flow_hash;
> -       pkt_hdr->input_flags.flow_hash = 1;
> +       pkt_hdr->p.input_flags.flow_hash = 1;
>  }
>
>  odp_time_t odp_packet_ts(odp_packet_t pkt)
> @@ -544,7 +544,7 @@ void odp_packet_ts_set(odp_packet_t pkt, odp_time_t
> timestamp)
>         odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
>
>         pkt_hdr->timestamp = timestamp;
> -       pkt_hdr->input_flags.timestamp = 1;
> +       pkt_hdr->p.input_flags.timestamp = 1;
>  }
>
>  int odp_packet_is_segmented(odp_packet_t pkt)
> @@ -929,19 +929,19 @@ void odp_packet_print(odp_packet_t pkt)
>
>         len += snprintf(&str[len], n - len, "Packet ");
>         len += odp_buffer_snprint(&str[len], n - len, (odp_buffer_t)pkt);
> -       len += snprintf(&str[len], n - len,
> -                       "  input_flags  0x%" PRIx64 "\n",
> hdr->input_flags.all);
> -       len += snprintf(&str[len], n - len,
> -                       "  error_flags  0x%" PRIx32 "\n",
> hdr->error_flags.all);
> +       len += snprintf(&str[len], n - len, "  input_flags  0x%" PRIx64
> "\n",
> +                       hdr->p.input_flags.all);
> +       len += snprintf(&str[len], n - len, "  error_flags  0x%" PRIx32
> "\n",
> +                       hdr->p.error_flags.all);
>         len += snprintf(&str[len], n - len,
>                         "  output_flags 0x%" PRIx32 "\n",
> -                       hdr->output_flags.all);
> +                       hdr->p.output_flags.all);
>         len += snprintf(&str[len], n - len,
> -                       "  l2_offset    %" PRIu32 "\n", hdr->l2_offset);
> +                       "  l2_offset    %" PRIu32 "\n", hdr->p.l2_offset);
>         len += snprintf(&str[len], n - len,
> -                       "  l3_offset    %" PRIu32 "\n", hdr->l3_offset);
> +                       "  l3_offset    %" PRIu32 "\n", hdr->p.l3_offset);
>         len += snprintf(&str[len], n - len,
> -                       "  l4_offset    %" PRIu32 "\n", hdr->l4_offset);
> +                       "  l4_offset    %" PRIu32 "\n", hdr->p.l4_offset);
>         len += snprintf(&str[len], n - len,
>                         "  frame_len    %" PRIu32 "\n", hdr->frame_len);
>         len += snprintf(&str[len], n - len,
> @@ -972,6 +972,7 @@ void _odp_packet_copy_md_to_packet(odp_packet_t
> srcpkt, odp_packet_t dstpkt)
>         odp_packet_hdr_t *dsthdr = odp_packet_hdr(dstpkt);
>
>         dsthdr->input = srchdr->input;
> +       dsthdr->dst_queue = srchdr->dst_queue;
>         dsthdr->buf_hdr.buf_u64 = srchdr->buf_hdr.buf_u64;
>         if (dsthdr->buf_hdr.uarea_addr != NULL &&
>             srchdr->buf_hdr.uarea_addr != NULL)
> @@ -1000,12 +1001,12 @@ static inline uint8_t parse_ipv4(odp_packet_hdr_t
> *pkt_hdr,
>         uint16_t frag_offset;
>         uint32_t dstaddr = odp_be_to_cpu_32(ipv4->dst_addr);
>
> -       pkt_hdr->l3_len = odp_be_to_cpu_16(ipv4->tot_len);
> +       pkt_hdr->p.l3_len = odp_be_to_cpu_16(ipv4->tot_len);
>
>         if (odp_unlikely(ihl < ODPH_IPV4HDR_IHL_MIN) ||
>             odp_unlikely(ver != 4) ||
> -           (pkt_hdr->l3_len > pkt_hdr->frame_len - *offset)) {
> -               pkt_hdr->error_flags.ip_err = 1;
> +           (pkt_hdr->p.l3_len > pkt_hdr->frame_len - *offset)) {
> +               pkt_hdr->p.error_flags.ip_err = 1;
>                 return 0;
>         }
>
> @@ -1013,7 +1014,7 @@ static inline uint8_t parse_ipv4(odp_packet_hdr_t
> *pkt_hdr,
>         *parseptr += ihl * 4;
>
>         if (odp_unlikely(ihl > ODPH_IPV4HDR_IHL_MIN))
> -               pkt_hdr->input_flags.ipopt = 1;
> +               pkt_hdr->p.input_flags.ipopt = 1;
>
>         /* A packet is a fragment if:
>         *  "more fragments" flag is set (all fragments except the last)
> @@ -1022,11 +1023,11 @@ static inline uint8_t parse_ipv4(odp_packet_hdr_t
> *pkt_hdr,
>         */
>         frag_offset = odp_be_to_cpu_16(ipv4->frag_offset);
>         if (odp_unlikely(ODPH_IPV4HDR_IS_FRAGMENT(frag_offset)))
> -               pkt_hdr->input_flags.ipfrag = 1;
> +               pkt_hdr->p.input_flags.ipfrag = 1;
>
>         /* Handle IPv4 broadcast / multicast */
> -       pkt_hdr->input_flags.ip_bcast = (dstaddr == 0xffffffff);
> -       pkt_hdr->input_flags.ip_mcast = (dstaddr >> 28) == 0xd;
> +       pkt_hdr->p.input_flags.ip_bcast = (dstaddr == 0xffffffff);
> +       pkt_hdr->p.input_flags.ip_mcast = (dstaddr >> 28) == 0xd;
>
>         return ipv4->proto;
>  }
> @@ -1041,19 +1042,19 @@ static inline uint8_t parse_ipv6(odp_packet_hdr_t
> *pkt_hdr,
>         const odph_ipv6hdr_ext_t *ipv6ext;
>         uint32_t dstaddr0 = odp_be_to_cpu_32(ipv6->dst_addr[0]);
>
> -       pkt_hdr->l3_len = odp_be_to_cpu_16(ipv6->payload_len) +
> +       pkt_hdr->p.l3_len = odp_be_to_cpu_16(ipv6->payload_len) +
>                                 ODPH_IPV6HDR_LEN;
>
>         /* Basic sanity checks on IPv6 header */
>         if ((odp_be_to_cpu_32(ipv6->ver_tc_flow) >> 28) != 6 ||
> -           pkt_hdr->l3_len > pkt_hdr->frame_len - *offset) {
> -               pkt_hdr->error_flags.ip_err = 1;
> +           pkt_hdr->p.l3_len > pkt_hdr->frame_len - *offset) {
> +               pkt_hdr->p.error_flags.ip_err = 1;
>                 return 0;
>         }
>
>         /* IPv6 broadcast / multicast flags */
> -       pkt_hdr->input_flags.ip_mcast = (dstaddr0 & 0xff000000) ==
> 0xff000000;
> -       pkt_hdr->input_flags.ip_bcast = 0;
> +       pkt_hdr->p.input_flags.ip_mcast = (dstaddr0 & 0xff000000) ==
> 0xff000000;
> +       pkt_hdr->p.input_flags.ip_bcast = 0;
>
>         /* Skip past IPv6 header */
>         *offset   += sizeof(odph_ipv6hdr_t);
> @@ -1062,7 +1063,7 @@ static inline uint8_t parse_ipv6(odp_packet_hdr_t
> *pkt_hdr,
>         /* Skip past any IPv6 extension headers */
>         if (ipv6->next_hdr == ODPH_IPPROTO_HOPOPTS ||
>             ipv6->next_hdr == ODPH_IPPROTO_ROUTE) {
> -               pkt_hdr->input_flags.ipopt = 1;
> +               pkt_hdr->p.input_flags.ipopt = 1;
>
>                 do  {
>                         ipv6ext    = (const odph_ipv6hdr_ext_t *)*parseptr;
> @@ -1074,21 +1075,21 @@ static inline uint8_t parse_ipv6(odp_packet_hdr_t
> *pkt_hdr,
>                           ipv6ext->next_hdr == ODPH_IPPROTO_ROUTE) &&
>                         *offset < pkt_hdr->frame_len);
>
> -               if (*offset >= pkt_hdr->l3_offset +
> +               if (*offset >= pkt_hdr->p.l3_offset +
>                     odp_be_to_cpu_16(ipv6->payload_len)) {
> -                       pkt_hdr->error_flags.ip_err = 1;
> +                       pkt_hdr->p.error_flags.ip_err = 1;
>                         return 0;
>                 }
>
>                 if (ipv6ext->next_hdr == ODPH_IPPROTO_FRAG)
> -                       pkt_hdr->input_flags.ipfrag = 1;
> +                       pkt_hdr->p.input_flags.ipfrag = 1;
>
>                 return ipv6ext->next_hdr;
>         }
>
>         if (odp_unlikely(ipv6->next_hdr == ODPH_IPPROTO_FRAG)) {
> -               pkt_hdr->input_flags.ipopt = 1;
> -               pkt_hdr->input_flags.ipfrag = 1;
> +               pkt_hdr->p.input_flags.ipopt = 1;
> +               pkt_hdr->p.input_flags.ipfrag = 1;
>         }
>
>         return ipv6->next_hdr;
> @@ -1103,12 +1104,12 @@ static inline void parse_tcp(odp_packet_hdr_t
> *pkt_hdr,
>         const odph_tcphdr_t *tcp = (const odph_tcphdr_t *)*parseptr;
>
>         if (tcp->hl < sizeof(odph_tcphdr_t) / sizeof(uint32_t))
> -               pkt_hdr->error_flags.tcp_err = 1;
> +               pkt_hdr->p.error_flags.tcp_err = 1;
>         else if ((uint32_t)tcp->hl * 4 > sizeof(odph_tcphdr_t))
> -               pkt_hdr->input_flags.tcpopt = 1;
> +               pkt_hdr->p.input_flags.tcpopt = 1;
>
> -       pkt_hdr->l4_len = pkt_hdr->l3_len +
> -               pkt_hdr->l3_offset - pkt_hdr->l4_offset;
> +       pkt_hdr->p.l4_len = pkt_hdr->p.l3_len +
> +               pkt_hdr->p.l3_offset - pkt_hdr->p.l4_offset;
>
>         if (offset)
>                 *offset   += (uint32_t)tcp->hl * 4;
> @@ -1125,12 +1126,12 @@ static inline void parse_udp(odp_packet_hdr_t
> *pkt_hdr,
>         uint32_t udplen = odp_be_to_cpu_16(udp->length);
>
>         if (udplen < sizeof(odph_udphdr_t) ||
> -           udplen > (pkt_hdr->l3_len +
> -                     pkt_hdr->l4_offset - pkt_hdr->l3_offset)) {
> -               pkt_hdr->error_flags.udp_err = 1;
> +           udplen > (pkt_hdr->p.l3_len +
> +                     pkt_hdr->p.l4_offset - pkt_hdr->p.l3_offset)) {
> +               pkt_hdr->p.error_flags.udp_err = 1;
>         }
>
> -       pkt_hdr->l4_len = udplen;
> +       pkt_hdr->p.l4_len = udplen;
>
>         if (offset)
>                 *offset   += sizeof(odph_udphdr_t);
> @@ -1145,16 +1146,16 @@ void packet_parse_l2(odp_packet_hdr_t *pkt_hdr)
>         /* Packet alloc or reset have already init other offsets and flags
> */
>
>         /* We only support Ethernet for now */
> -       pkt_hdr->input_flags.eth = 1;
> +       pkt_hdr->p.input_flags.eth = 1;
>
>         /* Detect jumbo frames */
>         if (pkt_hdr->frame_len > ODPH_ETH_LEN_MAX)
> -               pkt_hdr->input_flags.jumbo = 1;
> +               pkt_hdr->p.input_flags.jumbo = 1;
>
>         /* Assume valid L2 header, no CRC/FCS check in SW */
> -       pkt_hdr->input_flags.l2 = 1;
> +       pkt_hdr->p.input_flags.l2 = 1;
>
> -       pkt_hdr->input_flags.parsed_l2 = 1;
> +       pkt_hdr->p.input_flags.parsed_l2 = 1;
>  }
>
>  int _odp_parse_common(odp_packet_hdr_t *pkt_hdr, const uint8_t *ptr)
> @@ -1176,7 +1177,7 @@ int _odp_parse_common(odp_packet_hdr_t *pkt_hdr,
> const uint8_t *ptr)
>
>         /* Handle Ethernet broadcast/multicast addresses */
>         macaddr0 = odp_be_to_cpu_16(*((const uint16_t *)(const void
> *)eth));
> -       pkt_hdr->input_flags.eth_mcast = (macaddr0 & 0x0100) == 0x0100;
> +       pkt_hdr->p.input_flags.eth_mcast = (macaddr0 & 0x0100) == 0x0100;
>
>         if (macaddr0 == 0xffff) {
>                 macaddr2 =
> @@ -1185,10 +1186,10 @@ int _odp_parse_common(odp_packet_hdr_t *pkt_hdr,
> const uint8_t *ptr)
>                 macaddr4 =
>                         odp_be_to_cpu_16(*((const uint16_t *)
>                                            (const void *)eth + 2));
> -               pkt_hdr->input_flags.eth_bcast =
> +               pkt_hdr->p.input_flags.eth_bcast =
>                         (macaddr2 == 0xffff) && (macaddr4 == 0xffff);
>         } else {
> -               pkt_hdr->input_flags.eth_bcast = 0;
> +               pkt_hdr->p.input_flags.eth_bcast = 0;
>         }
>
>         /* Get Ethertype */
> @@ -1197,9 +1198,9 @@ int _odp_parse_common(odp_packet_hdr_t *pkt_hdr,
> const uint8_t *ptr)
>
>         /* Check for SNAP vs. DIX */
>         if (ethtype < ODPH_ETH_LEN_MAX) {
> -               pkt_hdr->input_flags.snap = 1;
> +               pkt_hdr->p.input_flags.snap = 1;
>                 if (ethtype > pkt_hdr->frame_len - offset) {
> -                       pkt_hdr->error_flags.snap_len = 1;
> +                       pkt_hdr->p.error_flags.snap_len = 1;
>                         goto parse_exit;
>                 }
>                 ethtype = odp_be_to_cpu_16(*((const uint16_t *)
> @@ -1210,8 +1211,8 @@ int _odp_parse_common(odp_packet_hdr_t *pkt_hdr,
> const uint8_t *ptr)
>
>         /* Parse the VLAN header(s), if present */
>         if (ethtype == ODPH_ETHTYPE_VLAN_OUTER) {
> -               pkt_hdr->input_flags.vlan_qinq = 1;
> -               pkt_hdr->input_flags.vlan = 1;
> +               pkt_hdr->p.input_flags.vlan_qinq = 1;
> +               pkt_hdr->p.input_flags.vlan = 1;
>
>                 vlan = (const odph_vlanhdr_t *)parseptr;
>                 ethtype = odp_be_to_cpu_16(vlan->type);
> @@ -1220,7 +1221,7 @@ int _odp_parse_common(odp_packet_hdr_t *pkt_hdr,
> const uint8_t *ptr)
>         }
>
>         if (ethtype == ODPH_ETHTYPE_VLAN) {
> -               pkt_hdr->input_flags.vlan = 1;
> +               pkt_hdr->p.input_flags.vlan = 1;
>                 vlan = (const odph_vlanhdr_t *)parseptr;
>                 ethtype = odp_be_to_cpu_16(vlan->type);
>                 offset += sizeof(odph_vlanhdr_t);
> @@ -1228,71 +1229,71 @@ int _odp_parse_common(odp_packet_hdr_t *pkt_hdr,
> const uint8_t *ptr)
>         }
>
>         /* Set l3_offset+flag only for known ethtypes */
> -       pkt_hdr->input_flags.l3 = 1;
> -       pkt_hdr->l3_offset = offset;
> +       pkt_hdr->p.input_flags.l3 = 1;
> +       pkt_hdr->p.l3_offset = offset;
>
>         /* Parse Layer 3 headers */
>         switch (ethtype) {
>         case ODPH_ETHTYPE_IPV4:
> -               pkt_hdr->input_flags.ipv4 = 1;
> +               pkt_hdr->p.input_flags.ipv4 = 1;
>                 ip_proto = parse_ipv4(pkt_hdr, &parseptr, &offset);
>                 break;
>
>         case ODPH_ETHTYPE_IPV6:
> -               pkt_hdr->input_flags.ipv6 = 1;
> +               pkt_hdr->p.input_flags.ipv6 = 1;
>                 ip_proto = parse_ipv6(pkt_hdr, &parseptr, &offset);
>                 break;
>
>         case ODPH_ETHTYPE_ARP:
> -               pkt_hdr->input_flags.arp = 1;
> +               pkt_hdr->p.input_flags.arp = 1;
>                 ip_proto = 255;  /* Reserved invalid by IANA */
>                 break;
>
>         default:
> -               pkt_hdr->input_flags.l3 = 0;
> -               pkt_hdr->l3_offset = ODP_PACKET_OFFSET_INVALID;
> +               pkt_hdr->p.input_flags.l3 = 0;
> +               pkt_hdr->p.l3_offset = ODP_PACKET_OFFSET_INVALID;
>                 ip_proto = 255;  /* Reserved invalid by IANA */
>         }
>
>         /* Set l4_offset+flag only for known ip_proto */
> -       pkt_hdr->input_flags.l4 = 1;
> -       pkt_hdr->l4_offset = offset;
> +       pkt_hdr->p.input_flags.l4 = 1;
> +       pkt_hdr->p.l4_offset = offset;
>
>         /* Parse Layer 4 headers */
>         switch (ip_proto) {
>         case ODPH_IPPROTO_ICMP:
> -               pkt_hdr->input_flags.icmp = 1;
> +               pkt_hdr->p.input_flags.icmp = 1;
>                 break;
>
>         case ODPH_IPPROTO_TCP:
> -               pkt_hdr->input_flags.tcp = 1;
> +               pkt_hdr->p.input_flags.tcp = 1;
>                 parse_tcp(pkt_hdr, &parseptr, NULL);
>                 break;
>
>         case ODPH_IPPROTO_UDP:
> -               pkt_hdr->input_flags.udp = 1;
> +               pkt_hdr->p.input_flags.udp = 1;
>                 parse_udp(pkt_hdr, &parseptr, NULL);
>                 break;
>
>         case ODPH_IPPROTO_AH:
> -               pkt_hdr->input_flags.ipsec = 1;
> -               pkt_hdr->input_flags.ipsec_ah = 1;
> +               pkt_hdr->p.input_flags.ipsec = 1;
> +               pkt_hdr->p.input_flags.ipsec_ah = 1;
>                 break;
>
>         case ODPH_IPPROTO_ESP:
> -               pkt_hdr->input_flags.ipsec = 1;
> -               pkt_hdr->input_flags.ipsec_esp = 1;
> +               pkt_hdr->p.input_flags.ipsec = 1;
> +               pkt_hdr->p.input_flags.ipsec_esp = 1;
>                 break;
>
>         default:
> -               pkt_hdr->input_flags.l4 = 0;
> -               pkt_hdr->l4_offset = ODP_PACKET_OFFSET_INVALID;
> +               pkt_hdr->p.input_flags.l4 = 0;
> +               pkt_hdr->p.l4_offset = ODP_PACKET_OFFSET_INVALID;
>                 break;
>         }
>
>  parse_exit:
> -       pkt_hdr->input_flags.parsed_all = 1;
> -       return pkt_hdr->error_flags.all != 0;
> +       pkt_hdr->p.input_flags.parsed_all = 1;
> +       return pkt_hdr->p.error_flags.all != 0;
>  }
>
>  /**
> diff --git a/platform/linux-generic/odp_packet_flags.c
> b/platform/linux-generic/odp_packet_flags.c
> index 3acdc53..b88324c 100644
> --- a/platform/linux-generic/odp_packet_flags.c
> +++ b/platform/linux-generic/odp_packet_flags.c
> @@ -7,26 +7,27 @@
>  #include <odp/api/packet_flags.h>
>  #include <odp_packet_internal.h>
>
> -#define retflag(p, x) do {                            \
> -       odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(p); \
> -       if (packet_parse_not_complete(pkt_hdr))        \
> -               packet_parse_full(pkt_hdr);            \
> -       return pkt_hdr->x;                             \
> +#define retflag(pkt, x) do {                             \
> +       odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); \
> +       if (packet_parse_not_complete(pkt_hdr))          \
> +               packet_parse_full(pkt_hdr);              \
> +       return pkt_hdr->p.x;                             \
>         } while (0)
>
> -#define setflag(p, x, v) do {                         \
> -       odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(p); \
> -       if (packet_parse_not_complete(pkt_hdr))        \
> -               packet_parse_full(pkt_hdr);            \
> -       pkt_hdr->x = v & 1;                            \
> +#define setflag(pkt, x, v) do {                          \
> +       odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); \
> +       if (packet_parse_not_complete(pkt_hdr))          \
> +               packet_parse_full(pkt_hdr);              \
> +       pkt_hdr->p.x = v & 1;                            \
>         } while (0)
>
>  int odp_packet_has_error(odp_packet_t pkt)
>  {
>         odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
> +
>         if (packet_parse_not_complete(pkt_hdr))
>                 packet_parse_full(pkt_hdr);
> -       return odp_packet_hdr(pkt)->error_flags.all != 0;
> +       return odp_packet_hdr(pkt)->p.error_flags.all != 0;
>  }
>
>  /* Get Input Flags */
> @@ -35,7 +36,7 @@ int odp_packet_has_l2(odp_packet_t pkt)
>  {
>         odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
>
> -       return pkt_hdr->input_flags.l2;
> +       return pkt_hdr->p.input_flags.l2;
>  }
>
>  int odp_packet_has_l2_error(odp_packet_t pkt)
> @@ -43,9 +44,9 @@ int odp_packet_has_l2_error(odp_packet_t pkt)
>         odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
>         /* L2 parsing is always done by default and hence
>         no additional check is required */
> -       return pkt_hdr->error_flags.frame_len
> -               | pkt_hdr->error_flags.snap_len
> -               | pkt_hdr->error_flags.l2_chksum;
> +       return pkt_hdr->p.error_flags.frame_len
> +               | pkt_hdr->p.error_flags.snap_len
> +               | pkt_hdr->p.error_flags.l2_chksum;
>  }
>
>  int odp_packet_has_l3(odp_packet_t pkt)
> @@ -60,7 +61,7 @@ int odp_packet_has_l3_error(odp_packet_t pkt)
>         if (packet_parse_not_complete(pkt_hdr))
>                 packet_parse_full(pkt_hdr);
>
> -       return pkt_hdr->error_flags.ip_err;
> +       return pkt_hdr->p.error_flags.ip_err;
>  }
>
>  int odp_packet_has_l4(odp_packet_t pkt)
> @@ -75,14 +76,14 @@ int odp_packet_has_l4_error(odp_packet_t pkt)
>         if (packet_parse_not_complete(pkt_hdr))
>                 packet_parse_full(pkt_hdr);
>
> -       return pkt_hdr->error_flags.tcp_err | pkt_hdr->error_flags.udp_err;
> +       return pkt_hdr->p.error_flags.tcp_err |
> pkt_hdr->p.error_flags.udp_err;
>  }
>
>  int odp_packet_has_eth(odp_packet_t pkt)
>  {
>         odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
>
> -       return pkt_hdr->input_flags.eth;
> +       return pkt_hdr->p.input_flags.eth;
>  }
>
>  int odp_packet_has_eth_bcast(odp_packet_t pkt)
> @@ -99,7 +100,7 @@ int odp_packet_has_jumbo(odp_packet_t pkt)
>  {
>         odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
>
> -       return pkt_hdr->input_flags.jumbo;
> +       return pkt_hdr->p.input_flags.jumbo;
>  }
>
>  int odp_packet_has_vlan(odp_packet_t pkt)
> @@ -176,14 +177,14 @@ int odp_packet_has_flow_hash(odp_packet_t pkt)
>  {
>         odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
>
> -       return pkt_hdr->input_flags.flow_hash;
> +       return pkt_hdr->p.input_flags.flow_hash;
>  }
>
>  int odp_packet_has_ts(odp_packet_t pkt)
>  {
>         odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
>
> -       return pkt_hdr->input_flags.timestamp;
> +       return pkt_hdr->p.input_flags.timestamp;
>  }
>
>  odp_packet_color_t odp_packet_color(odp_packet_t pkt)
> @@ -198,7 +199,7 @@ void odp_packet_color_set(odp_packet_t pkt,
> odp_packet_color_t color)
>         if (packet_parse_not_complete(pkt_hdr))
>                 packet_parse_full(pkt_hdr);
>
> -       pkt_hdr->input_flags.color = color;
> +       pkt_hdr->p.input_flags.color = color;
>  }
>
>  odp_bool_t odp_packet_drop_eligible(odp_packet_t pkt)
> @@ -208,7 +209,7 @@ odp_bool_t odp_packet_drop_eligible(odp_packet_t pkt)
>         if (packet_parse_not_complete(pkt_hdr))
>                 packet_parse_full(pkt_hdr);
>
> -       return !pkt_hdr->input_flags.nodrop;
> +       return !pkt_hdr->p.input_flags.nodrop;
>  }
>
>  void odp_packet_drop_eligible_set(odp_packet_t pkt, odp_bool_t drop)
> @@ -228,7 +229,7 @@ void odp_packet_shaper_len_adjust_set(odp_packet_t
> pkt, int8_t adj)
>         if (packet_parse_not_complete(pkt_hdr))
>                 packet_parse_full(pkt_hdr);
>
> -       pkt_hdr->output_flags.shaper_len_adj = adj;
> +       pkt_hdr->p.output_flags.shaper_len_adj = adj;
>  }
>
>  /* Set Input Flags */
> @@ -342,12 +343,12 @@ void odp_packet_has_flow_hash_clr(odp_packet_t pkt)
>  {
>         odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
>
> -       pkt_hdr->input_flags.flow_hash = 0;
> +       pkt_hdr->p.input_flags.flow_hash = 0;
>  }
>
>  void odp_packet_has_ts_clr(odp_packet_t pkt)
>  {
>         odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
>
> -       pkt_hdr->input_flags.timestamp = 0;
> +       pkt_hdr->p.input_flags.timestamp = 0;
>  }
> diff --git a/platform/linux-generic/odp_packet_io.c
> b/platform/linux-generic/odp_packet_io.c
> index 416a361..67c1adf 100644
> --- a/platform/linux-generic/odp_packet_io.c
> +++ b/platform/linux-generic/odp_packet_io.c
> @@ -551,7 +551,7 @@ static inline int pktin_recv_buf(odp_pktin_queue_t
> queue,
>                 buf = _odp_packet_to_buffer(pkt);
>                 buf_hdr = odp_buf_to_hdr(buf);
>
> -               if (pkt_hdr->input_flags.dst_queue) {
> +               if (pkt_hdr->p.input_flags.dst_queue) {
>                         queue_entry_t *dst_queue;
>                         int ret;
>
> diff --git a/platform/linux-generic/pktio/dpdk.c
> b/platform/linux-generic/pktio/dpdk.c
> index 2225dfe..e2b3aec 100644
> --- a/platform/linux-generic/pktio/dpdk.c
> +++ b/platform/linux-generic/pktio/dpdk.c
> @@ -742,7 +742,7 @@ static inline int mbuf_to_pkt(pktio_entry_t
> *pktio_entry,
>                 pkt_hdr->input = pktio_entry->s.handle;
>
>                 if (pktio_cls_enabled(pktio_entry))
> -                       copy_packet_parser_metadata(&parsed_hdr, pkt_hdr);
> +                       copy_packet_cls_metadata(&parsed_hdr, pkt_hdr);
>                 else
>                         packet_parse_l2(pkt_hdr);
>
> diff --git a/platform/linux-generic/pktio/ipc.c
> b/platform/linux-generic/pktio/ipc.c
> index bd74f11..e0d4ab9 100644
> --- a/platform/linux-generic/pktio/ipc.c
> +++ b/platform/linux-generic/pktio/ipc.c
> @@ -571,7 +571,7 @@ static int ipc_pktio_recv_lockless(pktio_entry_t
> *pktio_entry,
>                 memcpy(pkt_data, remote_pkt_data, phdr.frame_len);
>
>                 /* Copy packets L2, L3 parsed offsets and size */
> -               copy_packet_parser_metadata(&phdr, odp_packet_hdr(pkt));
> +               copy_packet_cls_metadata(&phdr, odp_packet_hdr(pkt));
>
>                 odp_packet_hdr(pkt)->frame_len = phdr.frame_len;
>                 odp_packet_hdr(pkt)->headroom = phdr.headroom;
> diff --git a/platform/linux-generic/pktio/loop.c
> b/platform/linux-generic/pktio/loop.c
> index 75f6a0a..2fb88e2 100644
> --- a/platform/linux-generic/pktio/loop.c
> +++ b/platform/linux-generic/pktio/loop.c
> @@ -111,7 +111,7 @@ static int loopback_recv(pktio_entry_t *pktio_entry,
> int index ODP_UNUSED,
>                 pkt_hdr->input = pktio_entry->s.handle;
>
>                 if (pktio_cls_enabled(pktio_entry))
> -                       copy_packet_parser_metadata(&parsed_hdr, pkt_hdr);
> +                       copy_packet_cls_metadata(&parsed_hdr, pkt_hdr);
>                 else
>                         packet_parse_l2(pkt_hdr);
>
> diff --git a/platform/linux-generic/pktio/netmap.c
> b/platform/linux-generic/pktio/netmap.c
> index 4ea0d4a..d189aae 100644
> --- a/platform/linux-generic/pktio/netmap.c
> +++ b/platform/linux-generic/pktio/netmap.c
> @@ -628,7 +628,7 @@ static inline int netmap_pkt_to_odp(pktio_entry_t
> *pktio_entry,
>         pkt_hdr->input = pktio_entry->s.handle;
>
>         if (pktio_cls_enabled(pktio_entry))
> -               copy_packet_parser_metadata(&parsed_hdr, pkt_hdr);
> +               copy_packet_cls_metadata(&parsed_hdr, pkt_hdr);
>         else
>                 packet_parse_l2(pkt_hdr);
>
> diff --git a/platform/linux-generic/pktio/socket.c
> b/platform/linux-generic/pktio/socket.c
> index e07b6ad..b116145 100644
> --- a/platform/linux-generic/pktio/socket.c
> +++ b/platform/linux-generic/pktio/socket.c
> @@ -678,7 +678,7 @@ static int sock_mmsg_recv(pktio_entry_t *pktio_entry,
> int index ODP_UNUSED,
>                                 continue;
>                         }
>                         pkt_hdr->input = pktio_entry->s.handle;
> -                       copy_packet_parser_metadata(&parsed_hdr, pkt_hdr);
> +                       copy_packet_cls_metadata(&parsed_hdr, pkt_hdr);
>                         packet_set_ts(pkt_hdr, ts);
>
>                         pkt_table[nb_rx++] = pkt;
> diff --git a/platform/linux-generic/pktio/socket_mmap.c
> b/platform/linux-generic/pktio/socket_mmap.c
> index 720004c..30c44e9 100644
> --- a/platform/linux-generic/pktio/socket_mmap.c
> +++ b/platform/linux-generic/pktio/socket_mmap.c
> @@ -224,7 +224,7 @@ static inline unsigned pkt_mmap_v2_rx(pktio_entry_t
> *pktio_entry,
>                 hdr->input = pktio_entry->s.handle;
>
>                 if (pktio_cls_enabled(pktio_entry))
> -                       copy_packet_parser_metadata(&parsed_hdr, hdr);
> +                       copy_packet_cls_metadata(&parsed_hdr, hdr);
>                 else
>                         packet_parse_l2(hdr);
>
> --
> 1.9.1
>
> _______________________________________________
> lng-odp mailing list
> lng-odp@lists.linaro.org
> https://lists.linaro.org/mailman/listinfo/lng-odp
>
Maxim Uvarov June 15, 2016, 10:56 a.m. UTC | #2
Hi Matias,

can you please update patches?

Maxim.

On 06/14/16 00:50, Bill Fischofer wrote:
> For this series:
>
> Reviewed-and-tested-by: Bill Fischofer <bill.fischofer@linaro.org>
>
> On Mon, Jun 13, 2016 at 5:48 AM, Matias Elo <matias.elo@nokia.com> wrote:
>
>> Collect odp_packet_hdr_t members set by the packet parser
>> inside a common structure packet_parser_t.
>>
>> Signed-off-by: Matias Elo <matias.elo@nokia.com>
>> ---
>>   .../include/odp_classification_inlines.h           |  36 ++--
>>   .../linux-generic/include/odp_packet_internal.h    |  58 ++++---
>>   platform/linux-generic/odp_classification.c        |  16 +-
>>   platform/linux-generic/odp_packet.c                | 183
>> +++++++++++----------
>>   platform/linux-generic/odp_packet_flags.c          |  53 +++---
>>   platform/linux-generic/odp_packet_io.c             |   2 +-
>>   platform/linux-generic/pktio/dpdk.c                |   2 +-
>>   platform/linux-generic/pktio/ipc.c                 |   2 +-
>>   platform/linux-generic/pktio/loop.c                |   2 +-
>>   platform/linux-generic/pktio/netmap.c              |   2 +-
>>   platform/linux-generic/pktio/socket.c              |   2 +-
>>   platform/linux-generic/pktio/socket_mmap.c         |   2 +-
>>   12 files changed, 183 insertions(+), 177 deletions(-)
>>
>> diff --git a/platform/linux-generic/include/odp_classification_inlines.h
>> b/platform/linux-generic/include/odp_classification_inlines.h
>> index 08300f5..611d706 100644
>> --- a/platform/linux-generic/include/odp_classification_inlines.h
>> +++ b/platform/linux-generic/include/odp_classification_inlines.h
>> @@ -47,9 +47,9 @@ static inline int verify_pmr_ip_proto(const uint8_t
>> *pkt_addr,
>>   {
>>          const odph_ipv4hdr_t *ip;
>>          uint8_t proto;
>> -       if (!pkt_hdr->input_flags.ipv4)
>> +       if (!pkt_hdr->p.input_flags.ipv4)
>>                  return 0;
>> -       ip = (const odph_ipv4hdr_t *)(pkt_addr + pkt_hdr->l3_offset);
>> +       ip = (const odph_ipv4hdr_t *)(pkt_addr + pkt_hdr->p.l3_offset);
>>          proto = ip->proto;
>>          if (term_value->match.value == (proto & term_value->match.mask))
>>                  return 1;
>> @@ -63,9 +63,9 @@ static inline int verify_pmr_ipv4_saddr(const uint8_t
>> *pkt_addr,
>>   {
>>          const odph_ipv4hdr_t *ip;
>>          uint32_t ipaddr;
>> -       if (!pkt_hdr->input_flags.ipv4)
>> +       if (!pkt_hdr->p.input_flags.ipv4)
>>                  return 0;
>> -       ip = (const odph_ipv4hdr_t *)(pkt_addr + pkt_hdr->l3_offset);
>> +       ip = (const odph_ipv4hdr_t *)(pkt_addr + pkt_hdr->p.l3_offset);
>>          ipaddr = odp_be_to_cpu_32(ip->src_addr);
>>          if (term_value->match.value == (ipaddr & term_value->match.mask))
>>                  return 1;
>> @@ -79,9 +79,9 @@ static inline int verify_pmr_ipv4_daddr(const uint8_t
>> *pkt_addr,
>>   {
>>          const odph_ipv4hdr_t *ip;
>>          uint32_t ipaddr;
>> -       if (!pkt_hdr->input_flags.ipv4)
>> +       if (!pkt_hdr->p.input_flags.ipv4)
>>                  return 0;
>> -       ip = (const odph_ipv4hdr_t *)(pkt_addr + pkt_hdr->l3_offset);
>> +       ip = (const odph_ipv4hdr_t *)(pkt_addr + pkt_hdr->p.l3_offset);
>>          ipaddr = odp_be_to_cpu_32(ip->dst_addr);
>>          if (term_value->match.value == (ipaddr & term_value->match.mask))
>>                  return 1;
>> @@ -95,9 +95,9 @@ static inline int verify_pmr_tcp_sport(const uint8_t
>> *pkt_addr,
>>   {
>>          uint16_t sport;
>>          const odph_tcphdr_t *tcp;
>> -       if (!pkt_hdr->input_flags.tcp)
>> +       if (!pkt_hdr->p.input_flags.tcp)
>>                  return 0;
>> -       tcp = (const odph_tcphdr_t *)(pkt_addr + pkt_hdr->l4_offset);
>> +       tcp = (const odph_tcphdr_t *)(pkt_addr + pkt_hdr->p.l4_offset);
>>          sport = odp_be_to_cpu_16(tcp->src_port);
>>          if (term_value->match.value == (sport & term_value->match.mask))
>>                  return 1;
>> @@ -111,9 +111,9 @@ static inline int verify_pmr_tcp_dport(const uint8_t
>> *pkt_addr,
>>   {
>>          uint16_t dport;
>>          const odph_tcphdr_t *tcp;
>> -       if (!pkt_hdr->input_flags.tcp)
>> +       if (!pkt_hdr->p.input_flags.tcp)
>>                  return 0;
>> -       tcp = (const odph_tcphdr_t *)(pkt_addr + pkt_hdr->l4_offset);
>> +       tcp = (const odph_tcphdr_t *)(pkt_addr + pkt_hdr->p.l4_offset);
>>          dport = odp_be_to_cpu_16(tcp->dst_port);
>>          if (term_value->match.value == (dport & term_value->match.mask))
>>                  return 1;
>> @@ -127,9 +127,9 @@ static inline int verify_pmr_udp_dport(const uint8_t
>> *pkt_addr,
>>   {
>>          uint16_t dport;
>>          const odph_udphdr_t *udp;
>> -       if (!pkt_hdr->input_flags.udp)
>> +       if (!pkt_hdr->p.input_flags.udp)
>>                  return 0;
>> -       udp = (const odph_udphdr_t *)(pkt_addr + pkt_hdr->l4_offset);
>> +       udp = (const odph_udphdr_t *)(pkt_addr + pkt_hdr->p.l4_offset);
>>          dport = odp_be_to_cpu_16(udp->dst_port);
>>          if (term_value->match.value == (dport & term_value->match.mask))
>>                          return 1;
>> @@ -144,9 +144,9 @@ static inline int verify_pmr_udp_sport(const uint8_t
>> *pkt_addr,
>>          uint16_t sport;
>>          const odph_udphdr_t *udp;
>>
>> -       if (!pkt_hdr->input_flags.udp)
>> +       if (!pkt_hdr->p.input_flags.udp)
>>                  return 0;
>> -       udp = (const odph_udphdr_t *)(pkt_addr + pkt_hdr->l4_offset);
>> +       udp = (const odph_udphdr_t *)(pkt_addr + pkt_hdr->p.l4_offset);
>>          sport = odp_be_to_cpu_16(udp->src_port);
>>          if (term_value->match.value == (sport & term_value->match.mask))
>>                  return 1;
>> @@ -165,7 +165,7 @@ static inline int verify_pmr_dmac(const uint8_t
>> *pkt_addr,
>>          if (!packet_hdr_has_eth(pkt_hdr))
>>                  return 0;
>>
>> -       eth = (const odph_ethhdr_t *)(pkt_addr + pkt_hdr->l2_offset);
>> +       eth = (const odph_ethhdr_t *)(pkt_addr + pkt_hdr->p.l2_offset);
>>          memcpy(&dmac_be, eth->dst.addr, ODPH_ETHADDR_LEN);
>>          dmac = odp_be_to_cpu_64(dmac_be);
>>          /* since we are converting a 48 bit ethernet address from BE to cpu
>> @@ -217,13 +217,13 @@ static inline int verify_pmr_ipsec_spi(const uint8_t
>> *pkt_addr,
>>   {
>>          uint32_t spi;
>>
>> -       pkt_addr += pkt_hdr->l4_offset;
>> +       pkt_addr += pkt_hdr->p.l4_offset;
>>
>> -       if (pkt_hdr->input_flags.ipsec_ah) {
>> +       if (pkt_hdr->p.input_flags.ipsec_ah) {
>>                  const odph_ahhdr_t *ahhdr = (const odph_ahhdr_t *)pkt_addr;
>>
>>                  spi = odp_be_to_cpu_32(ahhdr->spi);
>> -       } else if (pkt_hdr->input_flags.ipsec_esp) {
>> +       } else if (pkt_hdr->p.input_flags.ipsec_esp) {
>>                  const odph_esphdr_t *esphdr = (const odph_esphdr_t
>> *)pkt_addr;
>>
>>                  spi = odp_be_to_cpu_32(esphdr->spi);
>> diff --git a/platform/linux-generic/include/odp_packet_internal.h
>> b/platform/linux-generic/include/odp_packet_internal.h
>> index d5ace12..99de9f9 100644
>> --- a/platform/linux-generic/include/odp_packet_internal.h
>> +++ b/platform/linux-generic/include/odp_packet_internal.h
>> @@ -128,6 +128,23 @@ ODP_STATIC_ASSERT(sizeof(output_flags_t) ==
>> sizeof(uint32_t),
>>                    "OUTPUT_FLAGS_SIZE_ERROR");
>>
>>   /**
>> + * Packet parser metadata
>> + */
>> +typedef struct {
>> +       input_flags_t  input_flags;
>> +       error_flags_t  error_flags;
>> +       output_flags_t output_flags;
>> +
>> +       uint32_t l2_offset; /**< offset to L2 hdr, e.g. Eth */
>> +       uint32_t l3_offset; /**< offset to L3 hdr, e.g. IPv4, IPv6 */
>> +       uint32_t l4_offset; /**< offset to L4 hdr (TCP, UDP, SCTP, also
>> ICMP) */
>> +
>> +       uint32_t l3_len;    /**< Layer 3 length */
>> +       uint32_t l4_len;    /**< Layer 4 length */
>> +
>> +} packet_parser_t;
>> +
>> +/**
>>    * Internal Packet header
>>    *
>>    * To optimize fast path performance this struct is not initialized to
>> zero in
>> @@ -139,13 +156,7 @@ typedef struct {
>>          odp_buffer_hdr_t buf_hdr;
>>
>>          /* Following members are initialized by packet_init() */
>> -       input_flags_t  input_flags;
>> -       error_flags_t  error_flags;
>> -       output_flags_t output_flags;
>> -
>> -       uint32_t l2_offset; /**< offset to L2 hdr, e.g. Eth */
>> -       uint32_t l3_offset; /**< offset to L3 hdr, e.g. IPv4, IPv6 */
>> -       uint32_t l4_offset; /**< offset to L4 hdr (TCP, UDP, SCTP, also
>> ICMP) */
>> +       packet_parser_t p;
>>
>>          uint32_t frame_len;
>>          uint32_t headroom;
>> @@ -154,9 +165,6 @@ typedef struct {
>>          odp_pktio_t input;
>>
>>          /* Members below are not initialized by packet_init() */
>> -       uint32_t l3_len;         /**< Layer 3 length */
>> -       uint32_t l4_len;         /**< Layer 4 length */
>> -
>>          odp_queue_t dst_queue;   /**< Classifier destination queue */
>>
>>          uint32_t flow_hash;      /**< Flow hash value */
>> @@ -180,18 +188,14 @@ static inline odp_packet_hdr_t
>> *odp_packet_hdr(odp_packet_t pkt)
>>   static inline void copy_packet_parser_metadata(odp_packet_hdr_t *src_hdr,
>>                                                 odp_packet_hdr_t *dst_hdr)
>>   {
>> -       dst_hdr->input_flags    = src_hdr->input_flags;
>> -       dst_hdr->error_flags    = src_hdr->error_flags;
>> -       dst_hdr->output_flags   = src_hdr->output_flags;
>> +       dst_hdr->p = src_hdr->p;
>> +}
>>
>> -       dst_hdr->l2_offset      = src_hdr->l2_offset;
>> -       dst_hdr->l3_offset      = src_hdr->l3_offset;
>> -       dst_hdr->l4_offset      = src_hdr->l4_offset;
>> -
>> -       dst_hdr->l3_len         = src_hdr->l3_len;
>> -       dst_hdr->l4_len         = src_hdr->l4_len;
>> -
>> -       dst_hdr->dst_queue      = src_hdr->dst_queue;
>> +static inline void copy_packet_cls_metadata(odp_packet_hdr_t *src_hdr,
>> +                                           odp_packet_hdr_t *dst_hdr)
>> +{
>> +       dst_hdr->p = src_hdr->p;
>> +       dst_hdr->dst_queue = src_hdr->dst_queue;
>>   }
>>
>>   static inline void *packet_map(odp_packet_hdr_t *pkt_hdr,
>> @@ -285,12 +289,12 @@ static inline void packet_set_len(odp_packet_t pkt,
>> uint32_t len)
>>
>>   static inline int packet_parse_l2_not_done(odp_packet_hdr_t *pkt_hdr)
>>   {
>> -       return !pkt_hdr->input_flags.parsed_l2;
>> +       return !pkt_hdr->p.input_flags.parsed_l2;
>>   }
>>
>>   static inline int packet_parse_not_complete(odp_packet_hdr_t *pkt_hdr)
>>   {
>> -       return !pkt_hdr->input_flags.parsed_all;
>> +       return !pkt_hdr->p.input_flags.parsed_all;
>>   }
>>
>>   /* Forward declarations */
>> @@ -315,24 +319,24 @@ odp_packet_t _odp_packet_from_buffer(odp_buffer_t
>> buf);
>>
>>   static inline int packet_hdr_has_l2(odp_packet_hdr_t *pkt_hdr)
>>   {
>> -       return pkt_hdr->input_flags.l2;
>> +       return pkt_hdr->p.input_flags.l2;
>>   }
>>
>>   static inline void packet_hdr_has_l2_set(odp_packet_hdr_t *pkt_hdr, int
>> val)
>>   {
>> -       pkt_hdr->input_flags.l2 = val;
>> +       pkt_hdr->p.input_flags.l2 = val;
>>   }
>>
>>   static inline int packet_hdr_has_eth(odp_packet_hdr_t *pkt_hdr)
>>   {
>> -       return pkt_hdr->input_flags.eth;
>> +       return pkt_hdr->p.input_flags.eth;
>>   }
>>
>>   static inline void packet_set_ts(odp_packet_hdr_t *pkt_hdr, odp_time_t
>> *ts)
>>   {
>>          if (ts != NULL) {
>>                  pkt_hdr->timestamp = *ts;
>> -               pkt_hdr->input_flags.timestamp = 1;
>> +               pkt_hdr->p.input_flags.timestamp = 1;
>>          }
>>   }
>>
>> diff --git a/platform/linux-generic/odp_classification.c
>> b/platform/linux-generic/odp_classification.c
>> index 7520bdc..15fe9a8 100644
>> --- a/platform/linux-generic/odp_classification.c
>> +++ b/platform/linux-generic/odp_classification.c
>> @@ -776,7 +776,7 @@ static inline cos_t *cls_select_cos(pktio_entry_t
>> *entry,
>>                  packet_parse_full(pkt_hdr);
>>
>>          /* Return error cos for error packet */
>> -       if (pkt_hdr->error_flags.all)
>> +       if (pkt_hdr->p.error_flags.all)
>>                  return cls->error_cos;
>>          /* Calls all the PMRs attached at the PKTIO level*/
>>          for (i = 0; i < odp_atomic_load_u32(&default_cos->s.num_rule);
>> i++) {
>> @@ -827,7 +827,7 @@ int cls_classify_packet(pktio_entry_t *entry, const
>> uint8_t *base, uint16_t len,
>>                  return -EFAULT;
>>
>>          *pool = cos->s.pool->s.pool_hdl;
>> -       pkt_hdr->input_flags.dst_queue = 1;
>> +       pkt_hdr->p.input_flags.dst_queue = 1;
>>          pkt_hdr->dst_queue = cos->s.queue->s.handle;
>>
>>          return 0;
>> @@ -841,12 +841,12 @@ cos_t *match_qos_l3_cos(pmr_l3_cos_t *l3_cos, const
>> uint8_t *pkt_addr,
>>          const odph_ipv4hdr_t *ipv4;
>>          const odph_ipv6hdr_t *ipv6;
>>
>> -       if (hdr->input_flags.l3 && hdr->input_flags.ipv4) {
>> -               ipv4 = (const odph_ipv4hdr_t *)(pkt_addr + hdr->l3_offset);
>> +       if (hdr->p.input_flags.l3 && hdr->p.input_flags.ipv4) {
>> +               ipv4 = (const odph_ipv4hdr_t *)(pkt_addr +
>> hdr->p.l3_offset);
>>                  dscp = ODPH_IPV4HDR_DSCP(ipv4->tos);
>>                  cos = l3_cos->cos[dscp];
>> -       } else if (hdr->input_flags.l3 && hdr->input_flags.ipv6) {
>> -               ipv6 = (const odph_ipv6hdr_t *)(pkt_addr + hdr->l3_offset);
>> +       } else if (hdr->p.input_flags.l3 && hdr->p.input_flags.ipv6) {
>> +               ipv6 = (const odph_ipv6hdr_t *)(pkt_addr +
>> hdr->p.l3_offset);
>>                  dscp = ODPH_IPV6HDR_DSCP(ipv6->ver_tc_flow);
>>                  cos = l3_cos->cos[dscp];
>>          }
>> @@ -862,9 +862,9 @@ cos_t *match_qos_l2_cos(pmr_l2_cos_t *l2_cos, const
>> uint8_t *pkt_addr,
>>          const odph_vlanhdr_t *vlan;
>>          uint16_t qos;
>>
>> -       if (packet_hdr_has_l2(hdr) && hdr->input_flags.vlan &&
>> +       if (packet_hdr_has_l2(hdr) && hdr->p.input_flags.vlan &&
>>              packet_hdr_has_eth(hdr)) {
>> -               eth = (const odph_ethhdr_t *)(pkt_addr + hdr->l2_offset);
>> +               eth = (const odph_ethhdr_t *)(pkt_addr + hdr->p.l2_offset);
>>                  vlan = (const odph_vlanhdr_t *)(eth + 1);
>>                  qos = odp_be_to_cpu_16(vlan->tci);
>>                  qos = ((qos >> 13) & 0x07);
>> diff --git a/platform/linux-generic/odp_packet.c
>> b/platform/linux-generic/odp_packet.c
>> index 2868736..991a648 100644
>> --- a/platform/linux-generic/odp_packet.c
>> +++ b/platform/linux-generic/odp_packet.c
>> @@ -28,19 +28,19 @@
>>
>>   static inline void packet_parse_disable(odp_packet_hdr_t *pkt_hdr)
>>   {
>> -       pkt_hdr->input_flags.parsed_l2  = 1;
>> -       pkt_hdr->input_flags.parsed_all = 1;
>> +       pkt_hdr->p.input_flags.parsed_l2  = 1;
>> +       pkt_hdr->p.input_flags.parsed_all = 1;
>>   }
>>
>>   void packet_parse_reset(odp_packet_hdr_t *pkt_hdr)
>>   {
>>          /* Reset parser metadata before new parse */
>> -       pkt_hdr->error_flags.all  = 0;
>> -       pkt_hdr->input_flags.all  = 0;
>> -       pkt_hdr->output_flags.all = 0;
>> -       pkt_hdr->l2_offset        = 0;
>> -       pkt_hdr->l3_offset        = ODP_PACKET_OFFSET_INVALID;
>> -       pkt_hdr->l4_offset        = ODP_PACKET_OFFSET_INVALID;
>> +       pkt_hdr->p.error_flags.all  = 0;
>> +       pkt_hdr->p.input_flags.all  = 0;
>> +       pkt_hdr->p.output_flags.all = 0;
>> +       pkt_hdr->p.l2_offset        = 0;
>> +       pkt_hdr->p.l3_offset        = ODP_PACKET_OFFSET_INVALID;
>> +       pkt_hdr->p.l4_offset        = ODP_PACKET_OFFSET_INVALID;
>>   }
>>
>>   /**
>> @@ -49,13 +49,13 @@ void packet_parse_reset(odp_packet_hdr_t *pkt_hdr)
>>   static void packet_init(pool_entry_t *pool, odp_packet_hdr_t *pkt_hdr,
>>                          size_t size, int parse)
>>   {
>> -       pkt_hdr->input_flags.all  = 0;
>> -       pkt_hdr->output_flags.all = 0;
>> -       pkt_hdr->error_flags.all  = 0;
>> +       pkt_hdr->p.input_flags.all  = 0;
>> +       pkt_hdr->p.output_flags.all = 0;
>> +       pkt_hdr->p.error_flags.all  = 0;
>>
>> -       pkt_hdr->l2_offset = 0;
>> -       pkt_hdr->l3_offset = ODP_PACKET_OFFSET_INVALID;
>> -       pkt_hdr->l4_offset = ODP_PACKET_OFFSET_INVALID;
>> +       pkt_hdr->p.l2_offset = 0;
>> +       pkt_hdr->p.l3_offset = ODP_PACKET_OFFSET_INVALID;
>> +       pkt_hdr->p.l4_offset = ODP_PACKET_OFFSET_INVALID;
>>
>>          /* Disable lazy parsing on user allocated packets */
>>          if (!parse)
>> @@ -431,7 +431,7 @@ void *odp_packet_l2_ptr(odp_packet_t pkt, uint32_t
>> *len)
>>
>>          if (!packet_hdr_has_l2(pkt_hdr))
>>                  return NULL;
>> -       return packet_map(pkt_hdr, pkt_hdr->l2_offset, len);
>> +       return packet_map(pkt_hdr, pkt_hdr->p.l2_offset, len);
>>   }
>>
>>   uint32_t odp_packet_l2_offset(odp_packet_t pkt)
>> @@ -440,7 +440,7 @@ uint32_t odp_packet_l2_offset(odp_packet_t pkt)
>>
>>          if (!packet_hdr_has_l2(pkt_hdr))
>>                  return ODP_PACKET_OFFSET_INVALID;
>> -       return pkt_hdr->l2_offset;
>> +       return pkt_hdr->p.l2_offset;
>>   }
>>
>>   int odp_packet_l2_offset_set(odp_packet_t pkt, uint32_t offset)
>> @@ -451,7 +451,7 @@ int odp_packet_l2_offset_set(odp_packet_t pkt,
>> uint32_t offset)
>>                  return -1;
>>
>>          packet_hdr_has_l2_set(pkt_hdr, 1);
>> -       pkt_hdr->l2_offset = offset;
>> +       pkt_hdr->p.l2_offset = offset;
>>          return 0;
>>   }
>>
>> @@ -461,7 +461,7 @@ void *odp_packet_l3_ptr(odp_packet_t pkt, uint32_t
>> *len)
>>
>>          if (packet_parse_not_complete(pkt_hdr))
>>                  packet_parse_full(pkt_hdr);
>> -       return packet_map(pkt_hdr, pkt_hdr->l3_offset, len);
>> +       return packet_map(pkt_hdr, pkt_hdr->p.l3_offset, len);
>>   }
>>
>>   uint32_t odp_packet_l3_offset(odp_packet_t pkt)
>> @@ -470,7 +470,7 @@ uint32_t odp_packet_l3_offset(odp_packet_t pkt)
>>
>>          if (packet_parse_not_complete(pkt_hdr))
>>                  packet_parse_full(pkt_hdr);
>> -       return pkt_hdr->l3_offset;
>> +       return pkt_hdr->p.l3_offset;
>>   }
>>
>>   int odp_packet_l3_offset_set(odp_packet_t pkt, uint32_t offset)
>> @@ -482,7 +482,7 @@ int odp_packet_l3_offset_set(odp_packet_t pkt,
>> uint32_t offset)
>>
>>          if (packet_parse_not_complete(pkt_hdr))
>>                  packet_parse_full(pkt_hdr);
>> -       pkt_hdr->l3_offset = offset;
>> +       pkt_hdr->p.l3_offset = offset;
>>          return 0;
>>   }
>>
>> @@ -492,7 +492,7 @@ void *odp_packet_l4_ptr(odp_packet_t pkt, uint32_t
>> *len)
>>
>>          if (packet_parse_not_complete(pkt_hdr))
>>                  packet_parse_full(pkt_hdr);
>> -       return packet_map(pkt_hdr, pkt_hdr->l4_offset, len);
>> +       return packet_map(pkt_hdr, pkt_hdr->p.l4_offset, len);
>>   }
>>
>>   uint32_t odp_packet_l4_offset(odp_packet_t pkt)
>> @@ -501,7 +501,7 @@ uint32_t odp_packet_l4_offset(odp_packet_t pkt)
>>
>>          if (packet_parse_not_complete(pkt_hdr))
>>                  packet_parse_full(pkt_hdr);
>> -       return pkt_hdr->l4_offset;
>> +       return pkt_hdr->p.l4_offset;
>>   }
>>
>>   int odp_packet_l4_offset_set(odp_packet_t pkt, uint32_t offset)
>> @@ -513,7 +513,7 @@ int odp_packet_l4_offset_set(odp_packet_t pkt,
>> uint32_t offset)
>>
>>          if (packet_parse_not_complete(pkt_hdr))
>>                  packet_parse_full(pkt_hdr);
>> -       pkt_hdr->l4_offset = offset;
>> +       pkt_hdr->p.l4_offset = offset;
>>          return 0;
>>   }
>>
>> @@ -529,7 +529,7 @@ void odp_packet_flow_hash_set(odp_packet_t pkt,
>> uint32_t flow_hash)
>>          odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
>>
>>          pkt_hdr->flow_hash = flow_hash;
>> -       pkt_hdr->input_flags.flow_hash = 1;
>> +       pkt_hdr->p.input_flags.flow_hash = 1;
>>   }
>>
>>   odp_time_t odp_packet_ts(odp_packet_t pkt)
>> @@ -544,7 +544,7 @@ void odp_packet_ts_set(odp_packet_t pkt, odp_time_t
>> timestamp)
>>          odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
>>
>>          pkt_hdr->timestamp = timestamp;
>> -       pkt_hdr->input_flags.timestamp = 1;
>> +       pkt_hdr->p.input_flags.timestamp = 1;
>>   }
>>
>>   int odp_packet_is_segmented(odp_packet_t pkt)
>> @@ -929,19 +929,19 @@ void odp_packet_print(odp_packet_t pkt)
>>
>>          len += snprintf(&str[len], n - len, "Packet ");
>>          len += odp_buffer_snprint(&str[len], n - len, (odp_buffer_t)pkt);
>> -       len += snprintf(&str[len], n - len,
>> -                       "  input_flags  0x%" PRIx64 "\n",
>> hdr->input_flags.all);
>> -       len += snprintf(&str[len], n - len,
>> -                       "  error_flags  0x%" PRIx32 "\n",
>> hdr->error_flags.all);
>> +       len += snprintf(&str[len], n - len, "  input_flags  0x%" PRIx64
>> "\n",
>> +                       hdr->p.input_flags.all);
>> +       len += snprintf(&str[len], n - len, "  error_flags  0x%" PRIx32
>> "\n",
>> +                       hdr->p.error_flags.all);
>>          len += snprintf(&str[len], n - len,
>>                          "  output_flags 0x%" PRIx32 "\n",
>> -                       hdr->output_flags.all);
>> +                       hdr->p.output_flags.all);
>>          len += snprintf(&str[len], n - len,
>> -                       "  l2_offset    %" PRIu32 "\n", hdr->l2_offset);
>> +                       "  l2_offset    %" PRIu32 "\n", hdr->p.l2_offset);
>>          len += snprintf(&str[len], n - len,
>> -                       "  l3_offset    %" PRIu32 "\n", hdr->l3_offset);
>> +                       "  l3_offset    %" PRIu32 "\n", hdr->p.l3_offset);
>>          len += snprintf(&str[len], n - len,
>> -                       "  l4_offset    %" PRIu32 "\n", hdr->l4_offset);
>> +                       "  l4_offset    %" PRIu32 "\n", hdr->p.l4_offset);
>>          len += snprintf(&str[len], n - len,
>>                          "  frame_len    %" PRIu32 "\n", hdr->frame_len);
>>          len += snprintf(&str[len], n - len,
>> @@ -972,6 +972,7 @@ void _odp_packet_copy_md_to_packet(odp_packet_t
>> srcpkt, odp_packet_t dstpkt)
>>          odp_packet_hdr_t *dsthdr = odp_packet_hdr(dstpkt);
>>
>>          dsthdr->input = srchdr->input;
>> +       dsthdr->dst_queue = srchdr->dst_queue;
>>          dsthdr->buf_hdr.buf_u64 = srchdr->buf_hdr.buf_u64;
>>          if (dsthdr->buf_hdr.uarea_addr != NULL &&
>>              srchdr->buf_hdr.uarea_addr != NULL)
>> @@ -1000,12 +1001,12 @@ static inline uint8_t parse_ipv4(odp_packet_hdr_t
>> *pkt_hdr,
>>          uint16_t frag_offset;
>>          uint32_t dstaddr = odp_be_to_cpu_32(ipv4->dst_addr);
>>
>> -       pkt_hdr->l3_len = odp_be_to_cpu_16(ipv4->tot_len);
>> +       pkt_hdr->p.l3_len = odp_be_to_cpu_16(ipv4->tot_len);
>>
>>          if (odp_unlikely(ihl < ODPH_IPV4HDR_IHL_MIN) ||
>>              odp_unlikely(ver != 4) ||
>> -           (pkt_hdr->l3_len > pkt_hdr->frame_len - *offset)) {
>> -               pkt_hdr->error_flags.ip_err = 1;
>> +           (pkt_hdr->p.l3_len > pkt_hdr->frame_len - *offset)) {
>> +               pkt_hdr->p.error_flags.ip_err = 1;
>>                  return 0;
>>          }
>>
>> @@ -1013,7 +1014,7 @@ static inline uint8_t parse_ipv4(odp_packet_hdr_t
>> *pkt_hdr,
>>          *parseptr += ihl * 4;
>>
>>          if (odp_unlikely(ihl > ODPH_IPV4HDR_IHL_MIN))
>> -               pkt_hdr->input_flags.ipopt = 1;
>> +               pkt_hdr->p.input_flags.ipopt = 1;
>>
>>          /* A packet is a fragment if:
>>          *  "more fragments" flag is set (all fragments except the last)
>> @@ -1022,11 +1023,11 @@ static inline uint8_t parse_ipv4(odp_packet_hdr_t
>> *pkt_hdr,
>>          */
>>          frag_offset = odp_be_to_cpu_16(ipv4->frag_offset);
>>          if (odp_unlikely(ODPH_IPV4HDR_IS_FRAGMENT(frag_offset)))
>> -               pkt_hdr->input_flags.ipfrag = 1;
>> +               pkt_hdr->p.input_flags.ipfrag = 1;
>>
>>          /* Handle IPv4 broadcast / multicast */
>> -       pkt_hdr->input_flags.ip_bcast = (dstaddr == 0xffffffff);
>> -       pkt_hdr->input_flags.ip_mcast = (dstaddr >> 28) == 0xd;
>> +       pkt_hdr->p.input_flags.ip_bcast = (dstaddr == 0xffffffff);
>> +       pkt_hdr->p.input_flags.ip_mcast = (dstaddr >> 28) == 0xd;
>>
>>          return ipv4->proto;
>>   }
>> @@ -1041,19 +1042,19 @@ static inline uint8_t parse_ipv6(odp_packet_hdr_t
>> *pkt_hdr,
>>          const odph_ipv6hdr_ext_t *ipv6ext;
>>          uint32_t dstaddr0 = odp_be_to_cpu_32(ipv6->dst_addr[0]);
>>
>> -       pkt_hdr->l3_len = odp_be_to_cpu_16(ipv6->payload_len) +
>> +       pkt_hdr->p.l3_len = odp_be_to_cpu_16(ipv6->payload_len) +
>>                                  ODPH_IPV6HDR_LEN;
>>
>>          /* Basic sanity checks on IPv6 header */
>>          if ((odp_be_to_cpu_32(ipv6->ver_tc_flow) >> 28) != 6 ||
>> -           pkt_hdr->l3_len > pkt_hdr->frame_len - *offset) {
>> -               pkt_hdr->error_flags.ip_err = 1;
>> +           pkt_hdr->p.l3_len > pkt_hdr->frame_len - *offset) {
>> +               pkt_hdr->p.error_flags.ip_err = 1;
>>                  return 0;
>>          }
>>
>>          /* IPv6 broadcast / multicast flags */
>> -       pkt_hdr->input_flags.ip_mcast = (dstaddr0 & 0xff000000) ==
>> 0xff000000;
>> -       pkt_hdr->input_flags.ip_bcast = 0;
>> +       pkt_hdr->p.input_flags.ip_mcast = (dstaddr0 & 0xff000000) ==
>> 0xff000000;
>> +       pkt_hdr->p.input_flags.ip_bcast = 0;
>>
>>          /* Skip past IPv6 header */
>>          *offset   += sizeof(odph_ipv6hdr_t);
>> @@ -1062,7 +1063,7 @@ static inline uint8_t parse_ipv6(odp_packet_hdr_t
>> *pkt_hdr,
>>          /* Skip past any IPv6 extension headers */
>>          if (ipv6->next_hdr == ODPH_IPPROTO_HOPOPTS ||
>>              ipv6->next_hdr == ODPH_IPPROTO_ROUTE) {
>> -               pkt_hdr->input_flags.ipopt = 1;
>> +               pkt_hdr->p.input_flags.ipopt = 1;
>>
>>                  do  {
>>                          ipv6ext    = (const odph_ipv6hdr_ext_t *)*parseptr;
>> @@ -1074,21 +1075,21 @@ static inline uint8_t parse_ipv6(odp_packet_hdr_t
>> *pkt_hdr,
>>                            ipv6ext->next_hdr == ODPH_IPPROTO_ROUTE) &&
>>                          *offset < pkt_hdr->frame_len);
>>
>> -               if (*offset >= pkt_hdr->l3_offset +
>> +               if (*offset >= pkt_hdr->p.l3_offset +
>>                      odp_be_to_cpu_16(ipv6->payload_len)) {
>> -                       pkt_hdr->error_flags.ip_err = 1;
>> +                       pkt_hdr->p.error_flags.ip_err = 1;
>>                          return 0;
>>                  }
>>
>>                  if (ipv6ext->next_hdr == ODPH_IPPROTO_FRAG)
>> -                       pkt_hdr->input_flags.ipfrag = 1;
>> +                       pkt_hdr->p.input_flags.ipfrag = 1;
>>
>>                  return ipv6ext->next_hdr;
>>          }
>>
>>          if (odp_unlikely(ipv6->next_hdr == ODPH_IPPROTO_FRAG)) {
>> -               pkt_hdr->input_flags.ipopt = 1;
>> -               pkt_hdr->input_flags.ipfrag = 1;
>> +               pkt_hdr->p.input_flags.ipopt = 1;
>> +               pkt_hdr->p.input_flags.ipfrag = 1;
>>          }
>>
>>          return ipv6->next_hdr;
>> @@ -1103,12 +1104,12 @@ static inline void parse_tcp(odp_packet_hdr_t
>> *pkt_hdr,
>>          const odph_tcphdr_t *tcp = (const odph_tcphdr_t *)*parseptr;
>>
>>          if (tcp->hl < sizeof(odph_tcphdr_t) / sizeof(uint32_t))
>> -               pkt_hdr->error_flags.tcp_err = 1;
>> +               pkt_hdr->p.error_flags.tcp_err = 1;
>>          else if ((uint32_t)tcp->hl * 4 > sizeof(odph_tcphdr_t))
>> -               pkt_hdr->input_flags.tcpopt = 1;
>> +               pkt_hdr->p.input_flags.tcpopt = 1;
>>
>> -       pkt_hdr->l4_len = pkt_hdr->l3_len +
>> -               pkt_hdr->l3_offset - pkt_hdr->l4_offset;
>> +       pkt_hdr->p.l4_len = pkt_hdr->p.l3_len +
>> +               pkt_hdr->p.l3_offset - pkt_hdr->p.l4_offset;
>>
>>          if (offset)
>>                  *offset   += (uint32_t)tcp->hl * 4;
>> @@ -1125,12 +1126,12 @@ static inline void parse_udp(odp_packet_hdr_t
>> *pkt_hdr,
>>          uint32_t udplen = odp_be_to_cpu_16(udp->length);
>>
>>          if (udplen < sizeof(odph_udphdr_t) ||
>> -           udplen > (pkt_hdr->l3_len +
>> -                     pkt_hdr->l4_offset - pkt_hdr->l3_offset)) {
>> -               pkt_hdr->error_flags.udp_err = 1;
>> +           udplen > (pkt_hdr->p.l3_len +
>> +                     pkt_hdr->p.l4_offset - pkt_hdr->p.l3_offset)) {
>> +               pkt_hdr->p.error_flags.udp_err = 1;
>>          }
>>
>> -       pkt_hdr->l4_len = udplen;
>> +       pkt_hdr->p.l4_len = udplen;
>>
>>          if (offset)
>>                  *offset   += sizeof(odph_udphdr_t);
>> @@ -1145,16 +1146,16 @@ void packet_parse_l2(odp_packet_hdr_t *pkt_hdr)
>>          /* Packet alloc or reset have already init other offsets and flags
>> */
>>
>>          /* We only support Ethernet for now */
>> -       pkt_hdr->input_flags.eth = 1;
>> +       pkt_hdr->p.input_flags.eth = 1;
>>
>>          /* Detect jumbo frames */
>>          if (pkt_hdr->frame_len > ODPH_ETH_LEN_MAX)
>> -               pkt_hdr->input_flags.jumbo = 1;
>> +               pkt_hdr->p.input_flags.jumbo = 1;
>>
>>          /* Assume valid L2 header, no CRC/FCS check in SW */
>> -       pkt_hdr->input_flags.l2 = 1;
>> +       pkt_hdr->p.input_flags.l2 = 1;
>>
>> -       pkt_hdr->input_flags.parsed_l2 = 1;
>> +       pkt_hdr->p.input_flags.parsed_l2 = 1;
>>   }
>>
>>   int _odp_parse_common(odp_packet_hdr_t *pkt_hdr, const uint8_t *ptr)
>> @@ -1176,7 +1177,7 @@ int _odp_parse_common(odp_packet_hdr_t *pkt_hdr,
>> const uint8_t *ptr)
>>
>>          /* Handle Ethernet broadcast/multicast addresses */
>>          macaddr0 = odp_be_to_cpu_16(*((const uint16_t *)(const void
>> *)eth));
>> -       pkt_hdr->input_flags.eth_mcast = (macaddr0 & 0x0100) == 0x0100;
>> +       pkt_hdr->p.input_flags.eth_mcast = (macaddr0 & 0x0100) == 0x0100;
>>
>>          if (macaddr0 == 0xffff) {
>>                  macaddr2 =
>> @@ -1185,10 +1186,10 @@ int _odp_parse_common(odp_packet_hdr_t *pkt_hdr,
>> const uint8_t *ptr)
>>                  macaddr4 =
>>                          odp_be_to_cpu_16(*((const uint16_t *)
>>                                             (const void *)eth + 2));
>> -               pkt_hdr->input_flags.eth_bcast =
>> +               pkt_hdr->p.input_flags.eth_bcast =
>>                          (macaddr2 == 0xffff) && (macaddr4 == 0xffff);
>>          } else {
>> -               pkt_hdr->input_flags.eth_bcast = 0;
>> +               pkt_hdr->p.input_flags.eth_bcast = 0;
>>          }
>>
>>          /* Get Ethertype */
>> @@ -1197,9 +1198,9 @@ int _odp_parse_common(odp_packet_hdr_t *pkt_hdr,
>> const uint8_t *ptr)
>>
>>          /* Check for SNAP vs. DIX */
>>          if (ethtype < ODPH_ETH_LEN_MAX) {
>> -               pkt_hdr->input_flags.snap = 1;
>> +               pkt_hdr->p.input_flags.snap = 1;
>>                  if (ethtype > pkt_hdr->frame_len - offset) {
>> -                       pkt_hdr->error_flags.snap_len = 1;
>> +                       pkt_hdr->p.error_flags.snap_len = 1;
>>                          goto parse_exit;
>>                  }
>>                  ethtype = odp_be_to_cpu_16(*((const uint16_t *)
>> @@ -1210,8 +1211,8 @@ int _odp_parse_common(odp_packet_hdr_t *pkt_hdr,
>> const uint8_t *ptr)
>>
>>          /* Parse the VLAN header(s), if present */
>>          if (ethtype == ODPH_ETHTYPE_VLAN_OUTER) {
>> -               pkt_hdr->input_flags.vlan_qinq = 1;
>> -               pkt_hdr->input_flags.vlan = 1;
>> +               pkt_hdr->p.input_flags.vlan_qinq = 1;
>> +               pkt_hdr->p.input_flags.vlan = 1;
>>
>>                  vlan = (const odph_vlanhdr_t *)parseptr;
>>                  ethtype = odp_be_to_cpu_16(vlan->type);
>> @@ -1220,7 +1221,7 @@ int _odp_parse_common(odp_packet_hdr_t *pkt_hdr,
>> const uint8_t *ptr)
>>          }
>>
>>          if (ethtype == ODPH_ETHTYPE_VLAN) {
>> -               pkt_hdr->input_flags.vlan = 1;
>> +               pkt_hdr->p.input_flags.vlan = 1;
>>                  vlan = (const odph_vlanhdr_t *)parseptr;
>>                  ethtype = odp_be_to_cpu_16(vlan->type);
>>                  offset += sizeof(odph_vlanhdr_t);
>> @@ -1228,71 +1229,71 @@ int _odp_parse_common(odp_packet_hdr_t *pkt_hdr,
>> const uint8_t *ptr)
>>          }
>>
>>          /* Set l3_offset+flag only for known ethtypes */
>> -       pkt_hdr->input_flags.l3 = 1;
>> -       pkt_hdr->l3_offset = offset;
>> +       pkt_hdr->p.input_flags.l3 = 1;
>> +       pkt_hdr->p.l3_offset = offset;
>>
>>          /* Parse Layer 3 headers */
>>          switch (ethtype) {
>>          case ODPH_ETHTYPE_IPV4:
>> -               pkt_hdr->input_flags.ipv4 = 1;
>> +               pkt_hdr->p.input_flags.ipv4 = 1;
>>                  ip_proto = parse_ipv4(pkt_hdr, &parseptr, &offset);
>>                  break;
>>
>>          case ODPH_ETHTYPE_IPV6:
>> -               pkt_hdr->input_flags.ipv6 = 1;
>> +               pkt_hdr->p.input_flags.ipv6 = 1;
>>                  ip_proto = parse_ipv6(pkt_hdr, &parseptr, &offset);
>>                  break;
>>
>>          case ODPH_ETHTYPE_ARP:
>> -               pkt_hdr->input_flags.arp = 1;
>> +               pkt_hdr->p.input_flags.arp = 1;
>>                  ip_proto = 255;  /* Reserved invalid by IANA */
>>                  break;
>>
>>          default:
>> -               pkt_hdr->input_flags.l3 = 0;
>> -               pkt_hdr->l3_offset = ODP_PACKET_OFFSET_INVALID;
>> +               pkt_hdr->p.input_flags.l3 = 0;
>> +               pkt_hdr->p.l3_offset = ODP_PACKET_OFFSET_INVALID;
>>                  ip_proto = 255;  /* Reserved invalid by IANA */
>>          }
>>
>>          /* Set l4_offset+flag only for known ip_proto */
>> -       pkt_hdr->input_flags.l4 = 1;
>> -       pkt_hdr->l4_offset = offset;
>> +       pkt_hdr->p.input_flags.l4 = 1;
>> +       pkt_hdr->p.l4_offset = offset;
>>
>>          /* Parse Layer 4 headers */
>>          switch (ip_proto) {
>>          case ODPH_IPPROTO_ICMP:
>> -               pkt_hdr->input_flags.icmp = 1;
>> +               pkt_hdr->p.input_flags.icmp = 1;
>>                  break;
>>
>>          case ODPH_IPPROTO_TCP:
>> -               pkt_hdr->input_flags.tcp = 1;
>> +               pkt_hdr->p.input_flags.tcp = 1;
>>                  parse_tcp(pkt_hdr, &parseptr, NULL);
>>                  break;
>>
>>          case ODPH_IPPROTO_UDP:
>> -               pkt_hdr->input_flags.udp = 1;
>> +               pkt_hdr->p.input_flags.udp = 1;
>>                  parse_udp(pkt_hdr, &parseptr, NULL);
>>                  break;
>>
>>          case ODPH_IPPROTO_AH:
>> -               pkt_hdr->input_flags.ipsec = 1;
>> -               pkt_hdr->input_flags.ipsec_ah = 1;
>> +               pkt_hdr->p.input_flags.ipsec = 1;
>> +               pkt_hdr->p.input_flags.ipsec_ah = 1;
>>                  break;
>>
>>          case ODPH_IPPROTO_ESP:
>> -               pkt_hdr->input_flags.ipsec = 1;
>> -               pkt_hdr->input_flags.ipsec_esp = 1;
>> +               pkt_hdr->p.input_flags.ipsec = 1;
>> +               pkt_hdr->p.input_flags.ipsec_esp = 1;
>>                  break;
>>
>>          default:
>> -               pkt_hdr->input_flags.l4 = 0;
>> -               pkt_hdr->l4_offset = ODP_PACKET_OFFSET_INVALID;
>> +               pkt_hdr->p.input_flags.l4 = 0;
>> +               pkt_hdr->p.l4_offset = ODP_PACKET_OFFSET_INVALID;
>>                  break;
>>          }
>>
>>   parse_exit:
>> -       pkt_hdr->input_flags.parsed_all = 1;
>> -       return pkt_hdr->error_flags.all != 0;
>> +       pkt_hdr->p.input_flags.parsed_all = 1;
>> +       return pkt_hdr->p.error_flags.all != 0;
>>   }
>>
>>   /**
>> diff --git a/platform/linux-generic/odp_packet_flags.c
>> b/platform/linux-generic/odp_packet_flags.c
>> index 3acdc53..b88324c 100644
>> --- a/platform/linux-generic/odp_packet_flags.c
>> +++ b/platform/linux-generic/odp_packet_flags.c
>> @@ -7,26 +7,27 @@
>>   #include <odp/api/packet_flags.h>
>>   #include <odp_packet_internal.h>
>>
>> -#define retflag(p, x) do {                            \
>> -       odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(p); \
>> -       if (packet_parse_not_complete(pkt_hdr))        \
>> -               packet_parse_full(pkt_hdr);            \
>> -       return pkt_hdr->x;                             \
>> +#define retflag(pkt, x) do {                             \
>> +       odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); \
>> +       if (packet_parse_not_complete(pkt_hdr))          \
>> +               packet_parse_full(pkt_hdr);              \
>> +       return pkt_hdr->p.x;                             \
>>          } while (0)
>>
>> -#define setflag(p, x, v) do {                         \
>> -       odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(p); \
>> -       if (packet_parse_not_complete(pkt_hdr))        \
>> -               packet_parse_full(pkt_hdr);            \
>> -       pkt_hdr->x = v & 1;                            \
>> +#define setflag(pkt, x, v) do {                          \
>> +       odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); \
>> +       if (packet_parse_not_complete(pkt_hdr))          \
>> +               packet_parse_full(pkt_hdr);              \
>> +       pkt_hdr->p.x = v & 1;                            \
>>          } while (0)
>>
>>   int odp_packet_has_error(odp_packet_t pkt)
>>   {
>>          odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
>> +
>>          if (packet_parse_not_complete(pkt_hdr))
>>                  packet_parse_full(pkt_hdr);
>> -       return odp_packet_hdr(pkt)->error_flags.all != 0;
>> +       return odp_packet_hdr(pkt)->p.error_flags.all != 0;
>>   }
>>
>>   /* Get Input Flags */
>> @@ -35,7 +36,7 @@ int odp_packet_has_l2(odp_packet_t pkt)
>>   {
>>          odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
>>
>> -       return pkt_hdr->input_flags.l2;
>> +       return pkt_hdr->p.input_flags.l2;
>>   }
>>
>>   int odp_packet_has_l2_error(odp_packet_t pkt)
>> @@ -43,9 +44,9 @@ int odp_packet_has_l2_error(odp_packet_t pkt)
>>          odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
>>          /* L2 parsing is always done by default and hence
>>          no additional check is required */
>> -       return pkt_hdr->error_flags.frame_len
>> -               | pkt_hdr->error_flags.snap_len
>> -               | pkt_hdr->error_flags.l2_chksum;
>> +       return pkt_hdr->p.error_flags.frame_len
>> +               | pkt_hdr->p.error_flags.snap_len
>> +               | pkt_hdr->p.error_flags.l2_chksum;
>>   }
>>
>>   int odp_packet_has_l3(odp_packet_t pkt)
>> @@ -60,7 +61,7 @@ int odp_packet_has_l3_error(odp_packet_t pkt)
>>          if (packet_parse_not_complete(pkt_hdr))
>>                  packet_parse_full(pkt_hdr);
>>
>> -       return pkt_hdr->error_flags.ip_err;
>> +       return pkt_hdr->p.error_flags.ip_err;
>>   }
>>
>>   int odp_packet_has_l4(odp_packet_t pkt)
>> @@ -75,14 +76,14 @@ int odp_packet_has_l4_error(odp_packet_t pkt)
>>          if (packet_parse_not_complete(pkt_hdr))
>>                  packet_parse_full(pkt_hdr);
>>
>> -       return pkt_hdr->error_flags.tcp_err | pkt_hdr->error_flags.udp_err;
>> +       return pkt_hdr->p.error_flags.tcp_err |
>> pkt_hdr->p.error_flags.udp_err;
>>   }
>>
>>   int odp_packet_has_eth(odp_packet_t pkt)
>>   {
>>          odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
>>
>> -       return pkt_hdr->input_flags.eth;
>> +       return pkt_hdr->p.input_flags.eth;
>>   }
>>
>>   int odp_packet_has_eth_bcast(odp_packet_t pkt)
>> @@ -99,7 +100,7 @@ int odp_packet_has_jumbo(odp_packet_t pkt)
>>   {
>>          odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
>>
>> -       return pkt_hdr->input_flags.jumbo;
>> +       return pkt_hdr->p.input_flags.jumbo;
>>   }
>>
>>   int odp_packet_has_vlan(odp_packet_t pkt)
>> @@ -176,14 +177,14 @@ int odp_packet_has_flow_hash(odp_packet_t pkt)
>>   {
>>          odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
>>
>> -       return pkt_hdr->input_flags.flow_hash;
>> +       return pkt_hdr->p.input_flags.flow_hash;
>>   }
>>
>>   int odp_packet_has_ts(odp_packet_t pkt)
>>   {
>>          odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
>>
>> -       return pkt_hdr->input_flags.timestamp;
>> +       return pkt_hdr->p.input_flags.timestamp;
>>   }
>>
>>   odp_packet_color_t odp_packet_color(odp_packet_t pkt)
>> @@ -198,7 +199,7 @@ void odp_packet_color_set(odp_packet_t pkt,
>> odp_packet_color_t color)
>>          if (packet_parse_not_complete(pkt_hdr))
>>                  packet_parse_full(pkt_hdr);
>>
>> -       pkt_hdr->input_flags.color = color;
>> +       pkt_hdr->p.input_flags.color = color;
>>   }
>>
>>   odp_bool_t odp_packet_drop_eligible(odp_packet_t pkt)
>> @@ -208,7 +209,7 @@ odp_bool_t odp_packet_drop_eligible(odp_packet_t pkt)
>>          if (packet_parse_not_complete(pkt_hdr))
>>                  packet_parse_full(pkt_hdr);
>>
>> -       return !pkt_hdr->input_flags.nodrop;
>> +       return !pkt_hdr->p.input_flags.nodrop;
>>   }
>>
>>   void odp_packet_drop_eligible_set(odp_packet_t pkt, odp_bool_t drop)
>> @@ -228,7 +229,7 @@ void odp_packet_shaper_len_adjust_set(odp_packet_t
>> pkt, int8_t adj)
>>          if (packet_parse_not_complete(pkt_hdr))
>>                  packet_parse_full(pkt_hdr);
>>
>> -       pkt_hdr->output_flags.shaper_len_adj = adj;
>> +       pkt_hdr->p.output_flags.shaper_len_adj = adj;
>>   }
>>
>>   /* Set Input Flags */
>> @@ -342,12 +343,12 @@ void odp_packet_has_flow_hash_clr(odp_packet_t pkt)
>>   {
>>          odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
>>
>> -       pkt_hdr->input_flags.flow_hash = 0;
>> +       pkt_hdr->p.input_flags.flow_hash = 0;
>>   }
>>
>>   void odp_packet_has_ts_clr(odp_packet_t pkt)
>>   {
>>          odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
>>
>> -       pkt_hdr->input_flags.timestamp = 0;
>> +       pkt_hdr->p.input_flags.timestamp = 0;
>>   }
>> diff --git a/platform/linux-generic/odp_packet_io.c
>> b/platform/linux-generic/odp_packet_io.c
>> index 416a361..67c1adf 100644
>> --- a/platform/linux-generic/odp_packet_io.c
>> +++ b/platform/linux-generic/odp_packet_io.c
>> @@ -551,7 +551,7 @@ static inline int pktin_recv_buf(odp_pktin_queue_t
>> queue,
>>                  buf = _odp_packet_to_buffer(pkt);
>>                  buf_hdr = odp_buf_to_hdr(buf);
>>
>> -               if (pkt_hdr->input_flags.dst_queue) {
>> +               if (pkt_hdr->p.input_flags.dst_queue) {
>>                          queue_entry_t *dst_queue;
>>                          int ret;
>>
>> diff --git a/platform/linux-generic/pktio/dpdk.c
>> b/platform/linux-generic/pktio/dpdk.c
>> index 2225dfe..e2b3aec 100644
>> --- a/platform/linux-generic/pktio/dpdk.c
>> +++ b/platform/linux-generic/pktio/dpdk.c
>> @@ -742,7 +742,7 @@ static inline int mbuf_to_pkt(pktio_entry_t
>> *pktio_entry,
>>                  pkt_hdr->input = pktio_entry->s.handle;
>>
>>                  if (pktio_cls_enabled(pktio_entry))
>> -                       copy_packet_parser_metadata(&parsed_hdr, pkt_hdr);
>> +                       copy_packet_cls_metadata(&parsed_hdr, pkt_hdr);
>>                  else
>>                          packet_parse_l2(pkt_hdr);
>>
>> diff --git a/platform/linux-generic/pktio/ipc.c
>> b/platform/linux-generic/pktio/ipc.c
>> index bd74f11..e0d4ab9 100644
>> --- a/platform/linux-generic/pktio/ipc.c
>> +++ b/platform/linux-generic/pktio/ipc.c
>> @@ -571,7 +571,7 @@ static int ipc_pktio_recv_lockless(pktio_entry_t
>> *pktio_entry,
>>                  memcpy(pkt_data, remote_pkt_data, phdr.frame_len);
>>
>>                  /* Copy packets L2, L3 parsed offsets and size */
>> -               copy_packet_parser_metadata(&phdr, odp_packet_hdr(pkt));
>> +               copy_packet_cls_metadata(&phdr, odp_packet_hdr(pkt));
>>
>>                  odp_packet_hdr(pkt)->frame_len = phdr.frame_len;
>>                  odp_packet_hdr(pkt)->headroom = phdr.headroom;
>> diff --git a/platform/linux-generic/pktio/loop.c
>> b/platform/linux-generic/pktio/loop.c
>> index 75f6a0a..2fb88e2 100644
>> --- a/platform/linux-generic/pktio/loop.c
>> +++ b/platform/linux-generic/pktio/loop.c
>> @@ -111,7 +111,7 @@ static int loopback_recv(pktio_entry_t *pktio_entry,
>> int index ODP_UNUSED,
>>                  pkt_hdr->input = pktio_entry->s.handle;
>>
>>                  if (pktio_cls_enabled(pktio_entry))
>> -                       copy_packet_parser_metadata(&parsed_hdr, pkt_hdr);
>> +                       copy_packet_cls_metadata(&parsed_hdr, pkt_hdr);
>>                  else
>>                          packet_parse_l2(pkt_hdr);
>>
>> diff --git a/platform/linux-generic/pktio/netmap.c
>> b/platform/linux-generic/pktio/netmap.c
>> index 4ea0d4a..d189aae 100644
>> --- a/platform/linux-generic/pktio/netmap.c
>> +++ b/platform/linux-generic/pktio/netmap.c
>> @@ -628,7 +628,7 @@ static inline int netmap_pkt_to_odp(pktio_entry_t
>> *pktio_entry,
>>          pkt_hdr->input = pktio_entry->s.handle;
>>
>>          if (pktio_cls_enabled(pktio_entry))
>> -               copy_packet_parser_metadata(&parsed_hdr, pkt_hdr);
>> +               copy_packet_cls_metadata(&parsed_hdr, pkt_hdr);
>>          else
>>                  packet_parse_l2(pkt_hdr);
>>
>> diff --git a/platform/linux-generic/pktio/socket.c
>> b/platform/linux-generic/pktio/socket.c
>> index e07b6ad..b116145 100644
>> --- a/platform/linux-generic/pktio/socket.c
>> +++ b/platform/linux-generic/pktio/socket.c
>> @@ -678,7 +678,7 @@ static int sock_mmsg_recv(pktio_entry_t *pktio_entry,
>> int index ODP_UNUSED,
>>                                  continue;
>>                          }
>>                          pkt_hdr->input = pktio_entry->s.handle;
>> -                       copy_packet_parser_metadata(&parsed_hdr, pkt_hdr);
>> +                       copy_packet_cls_metadata(&parsed_hdr, pkt_hdr);
>>                          packet_set_ts(pkt_hdr, ts);
>>
>>                          pkt_table[nb_rx++] = pkt;
>> diff --git a/platform/linux-generic/pktio/socket_mmap.c
>> b/platform/linux-generic/pktio/socket_mmap.c
>> index 720004c..30c44e9 100644
>> --- a/platform/linux-generic/pktio/socket_mmap.c
>> +++ b/platform/linux-generic/pktio/socket_mmap.c
>> @@ -224,7 +224,7 @@ static inline unsigned pkt_mmap_v2_rx(pktio_entry_t
>> *pktio_entry,
>>                  hdr->input = pktio_entry->s.handle;
>>
>>                  if (pktio_cls_enabled(pktio_entry))
>> -                       copy_packet_parser_metadata(&parsed_hdr, hdr);
>> +                       copy_packet_cls_metadata(&parsed_hdr, hdr);
>>                  else
>>                          packet_parse_l2(hdr);
>>
>> --
>> 1.9.1
>>
>> _______________________________________________
>> lng-odp mailing list
>> lng-odp@lists.linaro.org
>> https://lists.linaro.org/mailman/listinfo/lng-odp
>>
> _______________________________________________
> lng-odp mailing list
> lng-odp@lists.linaro.org
> https://lists.linaro.org/mailman/listinfo/lng-odp
diff mbox

Patch

diff --git a/platform/linux-generic/include/odp_classification_inlines.h b/platform/linux-generic/include/odp_classification_inlines.h
index 08300f5..611d706 100644
--- a/platform/linux-generic/include/odp_classification_inlines.h
+++ b/platform/linux-generic/include/odp_classification_inlines.h
@@ -47,9 +47,9 @@  static inline int verify_pmr_ip_proto(const uint8_t *pkt_addr,
 {
 	const odph_ipv4hdr_t *ip;
 	uint8_t proto;
-	if (!pkt_hdr->input_flags.ipv4)
+	if (!pkt_hdr->p.input_flags.ipv4)
 		return 0;
-	ip = (const odph_ipv4hdr_t *)(pkt_addr + pkt_hdr->l3_offset);
+	ip = (const odph_ipv4hdr_t *)(pkt_addr + pkt_hdr->p.l3_offset);
 	proto = ip->proto;
 	if (term_value->match.value == (proto & term_value->match.mask))
 		return 1;
@@ -63,9 +63,9 @@  static inline int verify_pmr_ipv4_saddr(const uint8_t *pkt_addr,
 {
 	const odph_ipv4hdr_t *ip;
 	uint32_t ipaddr;
-	if (!pkt_hdr->input_flags.ipv4)
+	if (!pkt_hdr->p.input_flags.ipv4)
 		return 0;
-	ip = (const odph_ipv4hdr_t *)(pkt_addr + pkt_hdr->l3_offset);
+	ip = (const odph_ipv4hdr_t *)(pkt_addr + pkt_hdr->p.l3_offset);
 	ipaddr = odp_be_to_cpu_32(ip->src_addr);
 	if (term_value->match.value == (ipaddr & term_value->match.mask))
 		return 1;
@@ -79,9 +79,9 @@  static inline int verify_pmr_ipv4_daddr(const uint8_t *pkt_addr,
 {
 	const odph_ipv4hdr_t *ip;
 	uint32_t ipaddr;
-	if (!pkt_hdr->input_flags.ipv4)
+	if (!pkt_hdr->p.input_flags.ipv4)
 		return 0;
-	ip = (const odph_ipv4hdr_t *)(pkt_addr + pkt_hdr->l3_offset);
+	ip = (const odph_ipv4hdr_t *)(pkt_addr + pkt_hdr->p.l3_offset);
 	ipaddr = odp_be_to_cpu_32(ip->dst_addr);
 	if (term_value->match.value == (ipaddr & term_value->match.mask))
 		return 1;
@@ -95,9 +95,9 @@  static inline int verify_pmr_tcp_sport(const uint8_t *pkt_addr,
 {
 	uint16_t sport;
 	const odph_tcphdr_t *tcp;
-	if (!pkt_hdr->input_flags.tcp)
+	if (!pkt_hdr->p.input_flags.tcp)
 		return 0;
-	tcp = (const odph_tcphdr_t *)(pkt_addr + pkt_hdr->l4_offset);
+	tcp = (const odph_tcphdr_t *)(pkt_addr + pkt_hdr->p.l4_offset);
 	sport = odp_be_to_cpu_16(tcp->src_port);
 	if (term_value->match.value == (sport & term_value->match.mask))
 		return 1;
@@ -111,9 +111,9 @@  static inline int verify_pmr_tcp_dport(const uint8_t *pkt_addr,
 {
 	uint16_t dport;
 	const odph_tcphdr_t *tcp;
-	if (!pkt_hdr->input_flags.tcp)
+	if (!pkt_hdr->p.input_flags.tcp)
 		return 0;
-	tcp = (const odph_tcphdr_t *)(pkt_addr + pkt_hdr->l4_offset);
+	tcp = (const odph_tcphdr_t *)(pkt_addr + pkt_hdr->p.l4_offset);
 	dport = odp_be_to_cpu_16(tcp->dst_port);
 	if (term_value->match.value == (dport & term_value->match.mask))
 		return 1;
@@ -127,9 +127,9 @@  static inline int verify_pmr_udp_dport(const uint8_t *pkt_addr,
 {
 	uint16_t dport;
 	const odph_udphdr_t *udp;
-	if (!pkt_hdr->input_flags.udp)
+	if (!pkt_hdr->p.input_flags.udp)
 		return 0;
-	udp = (const odph_udphdr_t *)(pkt_addr + pkt_hdr->l4_offset);
+	udp = (const odph_udphdr_t *)(pkt_addr + pkt_hdr->p.l4_offset);
 	dport = odp_be_to_cpu_16(udp->dst_port);
 	if (term_value->match.value == (dport & term_value->match.mask))
 			return 1;
@@ -144,9 +144,9 @@  static inline int verify_pmr_udp_sport(const uint8_t *pkt_addr,
 	uint16_t sport;
 	const odph_udphdr_t *udp;
 
-	if (!pkt_hdr->input_flags.udp)
+	if (!pkt_hdr->p.input_flags.udp)
 		return 0;
-	udp = (const odph_udphdr_t *)(pkt_addr + pkt_hdr->l4_offset);
+	udp = (const odph_udphdr_t *)(pkt_addr + pkt_hdr->p.l4_offset);
 	sport = odp_be_to_cpu_16(udp->src_port);
 	if (term_value->match.value == (sport & term_value->match.mask))
 		return 1;
@@ -165,7 +165,7 @@  static inline int verify_pmr_dmac(const uint8_t *pkt_addr,
 	if (!packet_hdr_has_eth(pkt_hdr))
 		return 0;
 
-	eth = (const odph_ethhdr_t *)(pkt_addr + pkt_hdr->l2_offset);
+	eth = (const odph_ethhdr_t *)(pkt_addr + pkt_hdr->p.l2_offset);
 	memcpy(&dmac_be, eth->dst.addr, ODPH_ETHADDR_LEN);
 	dmac = odp_be_to_cpu_64(dmac_be);
 	/* since we are converting a 48 bit ethernet address from BE to cpu
@@ -217,13 +217,13 @@  static inline int verify_pmr_ipsec_spi(const uint8_t *pkt_addr,
 {
 	uint32_t spi;
 
-	pkt_addr += pkt_hdr->l4_offset;
+	pkt_addr += pkt_hdr->p.l4_offset;
 
-	if (pkt_hdr->input_flags.ipsec_ah) {
+	if (pkt_hdr->p.input_flags.ipsec_ah) {
 		const odph_ahhdr_t *ahhdr = (const odph_ahhdr_t *)pkt_addr;
 
 		spi = odp_be_to_cpu_32(ahhdr->spi);
-	} else if (pkt_hdr->input_flags.ipsec_esp) {
+	} else if (pkt_hdr->p.input_flags.ipsec_esp) {
 		const odph_esphdr_t *esphdr = (const odph_esphdr_t *)pkt_addr;
 
 		spi = odp_be_to_cpu_32(esphdr->spi);
diff --git a/platform/linux-generic/include/odp_packet_internal.h b/platform/linux-generic/include/odp_packet_internal.h
index d5ace12..99de9f9 100644
--- a/platform/linux-generic/include/odp_packet_internal.h
+++ b/platform/linux-generic/include/odp_packet_internal.h
@@ -128,6 +128,23 @@  ODP_STATIC_ASSERT(sizeof(output_flags_t) == sizeof(uint32_t),
 		  "OUTPUT_FLAGS_SIZE_ERROR");
 
 /**
+ * Packet parser metadata
+ */
+typedef struct {
+	input_flags_t  input_flags;
+	error_flags_t  error_flags;
+	output_flags_t output_flags;
+
+	uint32_t l2_offset; /**< offset to L2 hdr, e.g. Eth */
+	uint32_t l3_offset; /**< offset to L3 hdr, e.g. IPv4, IPv6 */
+	uint32_t l4_offset; /**< offset to L4 hdr (TCP, UDP, SCTP, also ICMP) */
+
+	uint32_t l3_len;    /**< Layer 3 length */
+	uint32_t l4_len;    /**< Layer 4 length */
+
+} packet_parser_t;
+
+/**
  * Internal Packet header
  *
  * To optimize fast path performance this struct is not initialized to zero in
@@ -139,13 +156,7 @@  typedef struct {
 	odp_buffer_hdr_t buf_hdr;
 
 	/* Following members are initialized by packet_init() */
-	input_flags_t  input_flags;
-	error_flags_t  error_flags;
-	output_flags_t output_flags;
-
-	uint32_t l2_offset; /**< offset to L2 hdr, e.g. Eth */
-	uint32_t l3_offset; /**< offset to L3 hdr, e.g. IPv4, IPv6 */
-	uint32_t l4_offset; /**< offset to L4 hdr (TCP, UDP, SCTP, also ICMP) */
+	packet_parser_t p;
 
 	uint32_t frame_len;
 	uint32_t headroom;
@@ -154,9 +165,6 @@  typedef struct {
 	odp_pktio_t input;
 
 	/* Members below are not initialized by packet_init() */
-	uint32_t l3_len;         /**< Layer 3 length */
-	uint32_t l4_len;         /**< Layer 4 length */
-
 	odp_queue_t dst_queue;   /**< Classifier destination queue */
 
 	uint32_t flow_hash;      /**< Flow hash value */
@@ -180,18 +188,14 @@  static inline odp_packet_hdr_t *odp_packet_hdr(odp_packet_t pkt)
 static inline void copy_packet_parser_metadata(odp_packet_hdr_t *src_hdr,
 					       odp_packet_hdr_t *dst_hdr)
 {
-	dst_hdr->input_flags    = src_hdr->input_flags;
-	dst_hdr->error_flags    = src_hdr->error_flags;
-	dst_hdr->output_flags   = src_hdr->output_flags;
+	dst_hdr->p = src_hdr->p;
+}
 
-	dst_hdr->l2_offset      = src_hdr->l2_offset;
-	dst_hdr->l3_offset      = src_hdr->l3_offset;
-	dst_hdr->l4_offset      = src_hdr->l4_offset;
-
-	dst_hdr->l3_len         = src_hdr->l3_len;
-	dst_hdr->l4_len         = src_hdr->l4_len;
-
-	dst_hdr->dst_queue      = src_hdr->dst_queue;
+static inline void copy_packet_cls_metadata(odp_packet_hdr_t *src_hdr,
+					    odp_packet_hdr_t *dst_hdr)
+{
+	dst_hdr->p = src_hdr->p;
+	dst_hdr->dst_queue = src_hdr->dst_queue;
 }
 
 static inline void *packet_map(odp_packet_hdr_t *pkt_hdr,
@@ -285,12 +289,12 @@  static inline void packet_set_len(odp_packet_t pkt, uint32_t len)
 
 static inline int packet_parse_l2_not_done(odp_packet_hdr_t *pkt_hdr)
 {
-	return !pkt_hdr->input_flags.parsed_l2;
+	return !pkt_hdr->p.input_flags.parsed_l2;
 }
 
 static inline int packet_parse_not_complete(odp_packet_hdr_t *pkt_hdr)
 {
-	return !pkt_hdr->input_flags.parsed_all;
+	return !pkt_hdr->p.input_flags.parsed_all;
 }
 
 /* Forward declarations */
@@ -315,24 +319,24 @@  odp_packet_t _odp_packet_from_buffer(odp_buffer_t buf);
 
 static inline int packet_hdr_has_l2(odp_packet_hdr_t *pkt_hdr)
 {
-	return pkt_hdr->input_flags.l2;
+	return pkt_hdr->p.input_flags.l2;
 }
 
 static inline void packet_hdr_has_l2_set(odp_packet_hdr_t *pkt_hdr, int val)
 {
-	pkt_hdr->input_flags.l2 = val;
+	pkt_hdr->p.input_flags.l2 = val;
 }
 
 static inline int packet_hdr_has_eth(odp_packet_hdr_t *pkt_hdr)
 {
-	return pkt_hdr->input_flags.eth;
+	return pkt_hdr->p.input_flags.eth;
 }
 
 static inline void packet_set_ts(odp_packet_hdr_t *pkt_hdr, odp_time_t *ts)
 {
 	if (ts != NULL) {
 		pkt_hdr->timestamp = *ts;
-		pkt_hdr->input_flags.timestamp = 1;
+		pkt_hdr->p.input_flags.timestamp = 1;
 	}
 }
 
diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c
index 7520bdc..15fe9a8 100644
--- a/platform/linux-generic/odp_classification.c
+++ b/platform/linux-generic/odp_classification.c
@@ -776,7 +776,7 @@  static inline cos_t *cls_select_cos(pktio_entry_t *entry,
 		packet_parse_full(pkt_hdr);
 
 	/* Return error cos for error packet */
-	if (pkt_hdr->error_flags.all)
+	if (pkt_hdr->p.error_flags.all)
 		return cls->error_cos;
 	/* Calls all the PMRs attached at the PKTIO level*/
 	for (i = 0; i < odp_atomic_load_u32(&default_cos->s.num_rule); i++) {
@@ -827,7 +827,7 @@  int cls_classify_packet(pktio_entry_t *entry, const uint8_t *base, uint16_t len,
 		return -EFAULT;
 
 	*pool = cos->s.pool->s.pool_hdl;
-	pkt_hdr->input_flags.dst_queue = 1;
+	pkt_hdr->p.input_flags.dst_queue = 1;
 	pkt_hdr->dst_queue = cos->s.queue->s.handle;
 
 	return 0;
@@ -841,12 +841,12 @@  cos_t *match_qos_l3_cos(pmr_l3_cos_t *l3_cos, const uint8_t *pkt_addr,
 	const odph_ipv4hdr_t *ipv4;
 	const odph_ipv6hdr_t *ipv6;
 
-	if (hdr->input_flags.l3 && hdr->input_flags.ipv4) {
-		ipv4 = (const odph_ipv4hdr_t *)(pkt_addr + hdr->l3_offset);
+	if (hdr->p.input_flags.l3 && hdr->p.input_flags.ipv4) {
+		ipv4 = (const odph_ipv4hdr_t *)(pkt_addr + hdr->p.l3_offset);
 		dscp = ODPH_IPV4HDR_DSCP(ipv4->tos);
 		cos = l3_cos->cos[dscp];
-	} else if (hdr->input_flags.l3 && hdr->input_flags.ipv6) {
-		ipv6 = (const odph_ipv6hdr_t *)(pkt_addr + hdr->l3_offset);
+	} else if (hdr->p.input_flags.l3 && hdr->p.input_flags.ipv6) {
+		ipv6 = (const odph_ipv6hdr_t *)(pkt_addr + hdr->p.l3_offset);
 		dscp = ODPH_IPV6HDR_DSCP(ipv6->ver_tc_flow);
 		cos = l3_cos->cos[dscp];
 	}
@@ -862,9 +862,9 @@  cos_t *match_qos_l2_cos(pmr_l2_cos_t *l2_cos, const uint8_t *pkt_addr,
 	const odph_vlanhdr_t *vlan;
 	uint16_t qos;
 
-	if (packet_hdr_has_l2(hdr) && hdr->input_flags.vlan &&
+	if (packet_hdr_has_l2(hdr) && hdr->p.input_flags.vlan &&
 	    packet_hdr_has_eth(hdr)) {
-		eth = (const odph_ethhdr_t *)(pkt_addr + hdr->l2_offset);
+		eth = (const odph_ethhdr_t *)(pkt_addr + hdr->p.l2_offset);
 		vlan = (const odph_vlanhdr_t *)(eth + 1);
 		qos = odp_be_to_cpu_16(vlan->tci);
 		qos = ((qos >> 13) & 0x07);
diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c
index 2868736..991a648 100644
--- a/platform/linux-generic/odp_packet.c
+++ b/platform/linux-generic/odp_packet.c
@@ -28,19 +28,19 @@ 
 
 static inline void packet_parse_disable(odp_packet_hdr_t *pkt_hdr)
 {
-	pkt_hdr->input_flags.parsed_l2  = 1;
-	pkt_hdr->input_flags.parsed_all = 1;
+	pkt_hdr->p.input_flags.parsed_l2  = 1;
+	pkt_hdr->p.input_flags.parsed_all = 1;
 }
 
 void packet_parse_reset(odp_packet_hdr_t *pkt_hdr)
 {
 	/* Reset parser metadata before new parse */
-	pkt_hdr->error_flags.all  = 0;
-	pkt_hdr->input_flags.all  = 0;
-	pkt_hdr->output_flags.all = 0;
-	pkt_hdr->l2_offset        = 0;
-	pkt_hdr->l3_offset        = ODP_PACKET_OFFSET_INVALID;
-	pkt_hdr->l4_offset        = ODP_PACKET_OFFSET_INVALID;
+	pkt_hdr->p.error_flags.all  = 0;
+	pkt_hdr->p.input_flags.all  = 0;
+	pkt_hdr->p.output_flags.all = 0;
+	pkt_hdr->p.l2_offset        = 0;
+	pkt_hdr->p.l3_offset        = ODP_PACKET_OFFSET_INVALID;
+	pkt_hdr->p.l4_offset        = ODP_PACKET_OFFSET_INVALID;
 }
 
 /**
@@ -49,13 +49,13 @@  void packet_parse_reset(odp_packet_hdr_t *pkt_hdr)
 static void packet_init(pool_entry_t *pool, odp_packet_hdr_t *pkt_hdr,
 			size_t size, int parse)
 {
-	pkt_hdr->input_flags.all  = 0;
-	pkt_hdr->output_flags.all = 0;
-	pkt_hdr->error_flags.all  = 0;
+	pkt_hdr->p.input_flags.all  = 0;
+	pkt_hdr->p.output_flags.all = 0;
+	pkt_hdr->p.error_flags.all  = 0;
 
-	pkt_hdr->l2_offset = 0;
-	pkt_hdr->l3_offset = ODP_PACKET_OFFSET_INVALID;
-	pkt_hdr->l4_offset = ODP_PACKET_OFFSET_INVALID;
+	pkt_hdr->p.l2_offset = 0;
+	pkt_hdr->p.l3_offset = ODP_PACKET_OFFSET_INVALID;
+	pkt_hdr->p.l4_offset = ODP_PACKET_OFFSET_INVALID;
 
 	/* Disable lazy parsing on user allocated packets */
 	if (!parse)
@@ -431,7 +431,7 @@  void *odp_packet_l2_ptr(odp_packet_t pkt, uint32_t *len)
 
 	if (!packet_hdr_has_l2(pkt_hdr))
 		return NULL;
-	return packet_map(pkt_hdr, pkt_hdr->l2_offset, len);
+	return packet_map(pkt_hdr, pkt_hdr->p.l2_offset, len);
 }
 
 uint32_t odp_packet_l2_offset(odp_packet_t pkt)
@@ -440,7 +440,7 @@  uint32_t odp_packet_l2_offset(odp_packet_t pkt)
 
 	if (!packet_hdr_has_l2(pkt_hdr))
 		return ODP_PACKET_OFFSET_INVALID;
-	return pkt_hdr->l2_offset;
+	return pkt_hdr->p.l2_offset;
 }
 
 int odp_packet_l2_offset_set(odp_packet_t pkt, uint32_t offset)
@@ -451,7 +451,7 @@  int odp_packet_l2_offset_set(odp_packet_t pkt, uint32_t offset)
 		return -1;
 
 	packet_hdr_has_l2_set(pkt_hdr, 1);
-	pkt_hdr->l2_offset = offset;
+	pkt_hdr->p.l2_offset = offset;
 	return 0;
 }
 
@@ -461,7 +461,7 @@  void *odp_packet_l3_ptr(odp_packet_t pkt, uint32_t *len)
 
 	if (packet_parse_not_complete(pkt_hdr))
 		packet_parse_full(pkt_hdr);
-	return packet_map(pkt_hdr, pkt_hdr->l3_offset, len);
+	return packet_map(pkt_hdr, pkt_hdr->p.l3_offset, len);
 }
 
 uint32_t odp_packet_l3_offset(odp_packet_t pkt)
@@ -470,7 +470,7 @@  uint32_t odp_packet_l3_offset(odp_packet_t pkt)
 
 	if (packet_parse_not_complete(pkt_hdr))
 		packet_parse_full(pkt_hdr);
-	return pkt_hdr->l3_offset;
+	return pkt_hdr->p.l3_offset;
 }
 
 int odp_packet_l3_offset_set(odp_packet_t pkt, uint32_t offset)
@@ -482,7 +482,7 @@  int odp_packet_l3_offset_set(odp_packet_t pkt, uint32_t offset)
 
 	if (packet_parse_not_complete(pkt_hdr))
 		packet_parse_full(pkt_hdr);
-	pkt_hdr->l3_offset = offset;
+	pkt_hdr->p.l3_offset = offset;
 	return 0;
 }
 
@@ -492,7 +492,7 @@  void *odp_packet_l4_ptr(odp_packet_t pkt, uint32_t *len)
 
 	if (packet_parse_not_complete(pkt_hdr))
 		packet_parse_full(pkt_hdr);
-	return packet_map(pkt_hdr, pkt_hdr->l4_offset, len);
+	return packet_map(pkt_hdr, pkt_hdr->p.l4_offset, len);
 }
 
 uint32_t odp_packet_l4_offset(odp_packet_t pkt)
@@ -501,7 +501,7 @@  uint32_t odp_packet_l4_offset(odp_packet_t pkt)
 
 	if (packet_parse_not_complete(pkt_hdr))
 		packet_parse_full(pkt_hdr);
-	return pkt_hdr->l4_offset;
+	return pkt_hdr->p.l4_offset;
 }
 
 int odp_packet_l4_offset_set(odp_packet_t pkt, uint32_t offset)
@@ -513,7 +513,7 @@  int odp_packet_l4_offset_set(odp_packet_t pkt, uint32_t offset)
 
 	if (packet_parse_not_complete(pkt_hdr))
 		packet_parse_full(pkt_hdr);
-	pkt_hdr->l4_offset = offset;
+	pkt_hdr->p.l4_offset = offset;
 	return 0;
 }
 
@@ -529,7 +529,7 @@  void odp_packet_flow_hash_set(odp_packet_t pkt, uint32_t flow_hash)
 	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
 
 	pkt_hdr->flow_hash = flow_hash;
-	pkt_hdr->input_flags.flow_hash = 1;
+	pkt_hdr->p.input_flags.flow_hash = 1;
 }
 
 odp_time_t odp_packet_ts(odp_packet_t pkt)
@@ -544,7 +544,7 @@  void odp_packet_ts_set(odp_packet_t pkt, odp_time_t timestamp)
 	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
 
 	pkt_hdr->timestamp = timestamp;
-	pkt_hdr->input_flags.timestamp = 1;
+	pkt_hdr->p.input_flags.timestamp = 1;
 }
 
 int odp_packet_is_segmented(odp_packet_t pkt)
@@ -929,19 +929,19 @@  void odp_packet_print(odp_packet_t pkt)
 
 	len += snprintf(&str[len], n - len, "Packet ");
 	len += odp_buffer_snprint(&str[len], n - len, (odp_buffer_t)pkt);
-	len += snprintf(&str[len], n - len,
-			"  input_flags  0x%" PRIx64 "\n", hdr->input_flags.all);
-	len += snprintf(&str[len], n - len,
-			"  error_flags  0x%" PRIx32 "\n", hdr->error_flags.all);
+	len += snprintf(&str[len], n - len, "  input_flags  0x%" PRIx64 "\n",
+			hdr->p.input_flags.all);
+	len += snprintf(&str[len], n - len, "  error_flags  0x%" PRIx32 "\n",
+			hdr->p.error_flags.all);
 	len += snprintf(&str[len], n - len,
 			"  output_flags 0x%" PRIx32 "\n",
-			hdr->output_flags.all);
+			hdr->p.output_flags.all);
 	len += snprintf(&str[len], n - len,
-			"  l2_offset    %" PRIu32 "\n", hdr->l2_offset);
+			"  l2_offset    %" PRIu32 "\n", hdr->p.l2_offset);
 	len += snprintf(&str[len], n - len,
-			"  l3_offset    %" PRIu32 "\n", hdr->l3_offset);
+			"  l3_offset    %" PRIu32 "\n", hdr->p.l3_offset);
 	len += snprintf(&str[len], n - len,
-			"  l4_offset    %" PRIu32 "\n", hdr->l4_offset);
+			"  l4_offset    %" PRIu32 "\n", hdr->p.l4_offset);
 	len += snprintf(&str[len], n - len,
 			"  frame_len    %" PRIu32 "\n", hdr->frame_len);
 	len += snprintf(&str[len], n - len,
@@ -972,6 +972,7 @@  void _odp_packet_copy_md_to_packet(odp_packet_t srcpkt, odp_packet_t dstpkt)
 	odp_packet_hdr_t *dsthdr = odp_packet_hdr(dstpkt);
 
 	dsthdr->input = srchdr->input;
+	dsthdr->dst_queue = srchdr->dst_queue;
 	dsthdr->buf_hdr.buf_u64 = srchdr->buf_hdr.buf_u64;
 	if (dsthdr->buf_hdr.uarea_addr != NULL &&
 	    srchdr->buf_hdr.uarea_addr != NULL)
@@ -1000,12 +1001,12 @@  static inline uint8_t parse_ipv4(odp_packet_hdr_t *pkt_hdr,
 	uint16_t frag_offset;
 	uint32_t dstaddr = odp_be_to_cpu_32(ipv4->dst_addr);
 
-	pkt_hdr->l3_len = odp_be_to_cpu_16(ipv4->tot_len);
+	pkt_hdr->p.l3_len = odp_be_to_cpu_16(ipv4->tot_len);
 
 	if (odp_unlikely(ihl < ODPH_IPV4HDR_IHL_MIN) ||
 	    odp_unlikely(ver != 4) ||
-	    (pkt_hdr->l3_len > pkt_hdr->frame_len - *offset)) {
-		pkt_hdr->error_flags.ip_err = 1;
+	    (pkt_hdr->p.l3_len > pkt_hdr->frame_len - *offset)) {
+		pkt_hdr->p.error_flags.ip_err = 1;
 		return 0;
 	}
 
@@ -1013,7 +1014,7 @@  static inline uint8_t parse_ipv4(odp_packet_hdr_t *pkt_hdr,
 	*parseptr += ihl * 4;
 
 	if (odp_unlikely(ihl > ODPH_IPV4HDR_IHL_MIN))
-		pkt_hdr->input_flags.ipopt = 1;
+		pkt_hdr->p.input_flags.ipopt = 1;
 
 	/* A packet is a fragment if:
 	*  "more fragments" flag is set (all fragments except the last)
@@ -1022,11 +1023,11 @@  static inline uint8_t parse_ipv4(odp_packet_hdr_t *pkt_hdr,
 	*/
 	frag_offset = odp_be_to_cpu_16(ipv4->frag_offset);
 	if (odp_unlikely(ODPH_IPV4HDR_IS_FRAGMENT(frag_offset)))
-		pkt_hdr->input_flags.ipfrag = 1;
+		pkt_hdr->p.input_flags.ipfrag = 1;
 
 	/* Handle IPv4 broadcast / multicast */
-	pkt_hdr->input_flags.ip_bcast = (dstaddr == 0xffffffff);
-	pkt_hdr->input_flags.ip_mcast = (dstaddr >> 28) == 0xd;
+	pkt_hdr->p.input_flags.ip_bcast = (dstaddr == 0xffffffff);
+	pkt_hdr->p.input_flags.ip_mcast = (dstaddr >> 28) == 0xd;
 
 	return ipv4->proto;
 }
@@ -1041,19 +1042,19 @@  static inline uint8_t parse_ipv6(odp_packet_hdr_t *pkt_hdr,
 	const odph_ipv6hdr_ext_t *ipv6ext;
 	uint32_t dstaddr0 = odp_be_to_cpu_32(ipv6->dst_addr[0]);
 
-	pkt_hdr->l3_len = odp_be_to_cpu_16(ipv6->payload_len) +
+	pkt_hdr->p.l3_len = odp_be_to_cpu_16(ipv6->payload_len) +
 				ODPH_IPV6HDR_LEN;
 
 	/* Basic sanity checks on IPv6 header */
 	if ((odp_be_to_cpu_32(ipv6->ver_tc_flow) >> 28) != 6 ||
-	    pkt_hdr->l3_len > pkt_hdr->frame_len - *offset) {
-		pkt_hdr->error_flags.ip_err = 1;
+	    pkt_hdr->p.l3_len > pkt_hdr->frame_len - *offset) {
+		pkt_hdr->p.error_flags.ip_err = 1;
 		return 0;
 	}
 
 	/* IPv6 broadcast / multicast flags */
-	pkt_hdr->input_flags.ip_mcast = (dstaddr0 & 0xff000000) == 0xff000000;
-	pkt_hdr->input_flags.ip_bcast = 0;
+	pkt_hdr->p.input_flags.ip_mcast = (dstaddr0 & 0xff000000) == 0xff000000;
+	pkt_hdr->p.input_flags.ip_bcast = 0;
 
 	/* Skip past IPv6 header */
 	*offset   += sizeof(odph_ipv6hdr_t);
@@ -1062,7 +1063,7 @@  static inline uint8_t parse_ipv6(odp_packet_hdr_t *pkt_hdr,
 	/* Skip past any IPv6 extension headers */
 	if (ipv6->next_hdr == ODPH_IPPROTO_HOPOPTS ||
 	    ipv6->next_hdr == ODPH_IPPROTO_ROUTE) {
-		pkt_hdr->input_flags.ipopt = 1;
+		pkt_hdr->p.input_flags.ipopt = 1;
 
 		do  {
 			ipv6ext    = (const odph_ipv6hdr_ext_t *)*parseptr;
@@ -1074,21 +1075,21 @@  static inline uint8_t parse_ipv6(odp_packet_hdr_t *pkt_hdr,
 			  ipv6ext->next_hdr == ODPH_IPPROTO_ROUTE) &&
 			*offset < pkt_hdr->frame_len);
 
-		if (*offset >= pkt_hdr->l3_offset +
+		if (*offset >= pkt_hdr->p.l3_offset +
 		    odp_be_to_cpu_16(ipv6->payload_len)) {
-			pkt_hdr->error_flags.ip_err = 1;
+			pkt_hdr->p.error_flags.ip_err = 1;
 			return 0;
 		}
 
 		if (ipv6ext->next_hdr == ODPH_IPPROTO_FRAG)
-			pkt_hdr->input_flags.ipfrag = 1;
+			pkt_hdr->p.input_flags.ipfrag = 1;
 
 		return ipv6ext->next_hdr;
 	}
 
 	if (odp_unlikely(ipv6->next_hdr == ODPH_IPPROTO_FRAG)) {
-		pkt_hdr->input_flags.ipopt = 1;
-		pkt_hdr->input_flags.ipfrag = 1;
+		pkt_hdr->p.input_flags.ipopt = 1;
+		pkt_hdr->p.input_flags.ipfrag = 1;
 	}
 
 	return ipv6->next_hdr;
@@ -1103,12 +1104,12 @@  static inline void parse_tcp(odp_packet_hdr_t *pkt_hdr,
 	const odph_tcphdr_t *tcp = (const odph_tcphdr_t *)*parseptr;
 
 	if (tcp->hl < sizeof(odph_tcphdr_t) / sizeof(uint32_t))
-		pkt_hdr->error_flags.tcp_err = 1;
+		pkt_hdr->p.error_flags.tcp_err = 1;
 	else if ((uint32_t)tcp->hl * 4 > sizeof(odph_tcphdr_t))
-		pkt_hdr->input_flags.tcpopt = 1;
+		pkt_hdr->p.input_flags.tcpopt = 1;
 
-	pkt_hdr->l4_len = pkt_hdr->l3_len +
-		pkt_hdr->l3_offset - pkt_hdr->l4_offset;
+	pkt_hdr->p.l4_len = pkt_hdr->p.l3_len +
+		pkt_hdr->p.l3_offset - pkt_hdr->p.l4_offset;
 
 	if (offset)
 		*offset   += (uint32_t)tcp->hl * 4;
@@ -1125,12 +1126,12 @@  static inline void parse_udp(odp_packet_hdr_t *pkt_hdr,
 	uint32_t udplen = odp_be_to_cpu_16(udp->length);
 
 	if (udplen < sizeof(odph_udphdr_t) ||
-	    udplen > (pkt_hdr->l3_len +
-		      pkt_hdr->l4_offset - pkt_hdr->l3_offset)) {
-		pkt_hdr->error_flags.udp_err = 1;
+	    udplen > (pkt_hdr->p.l3_len +
+		      pkt_hdr->p.l4_offset - pkt_hdr->p.l3_offset)) {
+		pkt_hdr->p.error_flags.udp_err = 1;
 	}
 
-	pkt_hdr->l4_len = udplen;
+	pkt_hdr->p.l4_len = udplen;
 
 	if (offset)
 		*offset   += sizeof(odph_udphdr_t);
@@ -1145,16 +1146,16 @@  void packet_parse_l2(odp_packet_hdr_t *pkt_hdr)
 	/* Packet alloc or reset have already init other offsets and flags */
 
 	/* We only support Ethernet for now */
-	pkt_hdr->input_flags.eth = 1;
+	pkt_hdr->p.input_flags.eth = 1;
 
 	/* Detect jumbo frames */
 	if (pkt_hdr->frame_len > ODPH_ETH_LEN_MAX)
-		pkt_hdr->input_flags.jumbo = 1;
+		pkt_hdr->p.input_flags.jumbo = 1;
 
 	/* Assume valid L2 header, no CRC/FCS check in SW */
-	pkt_hdr->input_flags.l2 = 1;
+	pkt_hdr->p.input_flags.l2 = 1;
 
-	pkt_hdr->input_flags.parsed_l2 = 1;
+	pkt_hdr->p.input_flags.parsed_l2 = 1;
 }
 
 int _odp_parse_common(odp_packet_hdr_t *pkt_hdr, const uint8_t *ptr)
@@ -1176,7 +1177,7 @@  int _odp_parse_common(odp_packet_hdr_t *pkt_hdr, const uint8_t *ptr)
 
 	/* Handle Ethernet broadcast/multicast addresses */
 	macaddr0 = odp_be_to_cpu_16(*((const uint16_t *)(const void *)eth));
-	pkt_hdr->input_flags.eth_mcast = (macaddr0 & 0x0100) == 0x0100;
+	pkt_hdr->p.input_flags.eth_mcast = (macaddr0 & 0x0100) == 0x0100;
 
 	if (macaddr0 == 0xffff) {
 		macaddr2 =
@@ -1185,10 +1186,10 @@  int _odp_parse_common(odp_packet_hdr_t *pkt_hdr, const uint8_t *ptr)
 		macaddr4 =
 			odp_be_to_cpu_16(*((const uint16_t *)
 					   (const void *)eth + 2));
-		pkt_hdr->input_flags.eth_bcast =
+		pkt_hdr->p.input_flags.eth_bcast =
 			(macaddr2 == 0xffff) && (macaddr4 == 0xffff);
 	} else {
-		pkt_hdr->input_flags.eth_bcast = 0;
+		pkt_hdr->p.input_flags.eth_bcast = 0;
 	}
 
 	/* Get Ethertype */
@@ -1197,9 +1198,9 @@  int _odp_parse_common(odp_packet_hdr_t *pkt_hdr, const uint8_t *ptr)
 
 	/* Check for SNAP vs. DIX */
 	if (ethtype < ODPH_ETH_LEN_MAX) {
-		pkt_hdr->input_flags.snap = 1;
+		pkt_hdr->p.input_flags.snap = 1;
 		if (ethtype > pkt_hdr->frame_len - offset) {
-			pkt_hdr->error_flags.snap_len = 1;
+			pkt_hdr->p.error_flags.snap_len = 1;
 			goto parse_exit;
 		}
 		ethtype = odp_be_to_cpu_16(*((const uint16_t *)
@@ -1210,8 +1211,8 @@  int _odp_parse_common(odp_packet_hdr_t *pkt_hdr, const uint8_t *ptr)
 
 	/* Parse the VLAN header(s), if present */
 	if (ethtype == ODPH_ETHTYPE_VLAN_OUTER) {
-		pkt_hdr->input_flags.vlan_qinq = 1;
-		pkt_hdr->input_flags.vlan = 1;
+		pkt_hdr->p.input_flags.vlan_qinq = 1;
+		pkt_hdr->p.input_flags.vlan = 1;
 
 		vlan = (const odph_vlanhdr_t *)parseptr;
 		ethtype = odp_be_to_cpu_16(vlan->type);
@@ -1220,7 +1221,7 @@  int _odp_parse_common(odp_packet_hdr_t *pkt_hdr, const uint8_t *ptr)
 	}
 
 	if (ethtype == ODPH_ETHTYPE_VLAN) {
-		pkt_hdr->input_flags.vlan = 1;
+		pkt_hdr->p.input_flags.vlan = 1;
 		vlan = (const odph_vlanhdr_t *)parseptr;
 		ethtype = odp_be_to_cpu_16(vlan->type);
 		offset += sizeof(odph_vlanhdr_t);
@@ -1228,71 +1229,71 @@  int _odp_parse_common(odp_packet_hdr_t *pkt_hdr, const uint8_t *ptr)
 	}
 
 	/* Set l3_offset+flag only for known ethtypes */
-	pkt_hdr->input_flags.l3 = 1;
-	pkt_hdr->l3_offset = offset;
+	pkt_hdr->p.input_flags.l3 = 1;
+	pkt_hdr->p.l3_offset = offset;
 
 	/* Parse Layer 3 headers */
 	switch (ethtype) {
 	case ODPH_ETHTYPE_IPV4:
-		pkt_hdr->input_flags.ipv4 = 1;
+		pkt_hdr->p.input_flags.ipv4 = 1;
 		ip_proto = parse_ipv4(pkt_hdr, &parseptr, &offset);
 		break;
 
 	case ODPH_ETHTYPE_IPV6:
-		pkt_hdr->input_flags.ipv6 = 1;
+		pkt_hdr->p.input_flags.ipv6 = 1;
 		ip_proto = parse_ipv6(pkt_hdr, &parseptr, &offset);
 		break;
 
 	case ODPH_ETHTYPE_ARP:
-		pkt_hdr->input_flags.arp = 1;
+		pkt_hdr->p.input_flags.arp = 1;
 		ip_proto = 255;  /* Reserved invalid by IANA */
 		break;
 
 	default:
-		pkt_hdr->input_flags.l3 = 0;
-		pkt_hdr->l3_offset = ODP_PACKET_OFFSET_INVALID;
+		pkt_hdr->p.input_flags.l3 = 0;
+		pkt_hdr->p.l3_offset = ODP_PACKET_OFFSET_INVALID;
 		ip_proto = 255;  /* Reserved invalid by IANA */
 	}
 
 	/* Set l4_offset+flag only for known ip_proto */
-	pkt_hdr->input_flags.l4 = 1;
-	pkt_hdr->l4_offset = offset;
+	pkt_hdr->p.input_flags.l4 = 1;
+	pkt_hdr->p.l4_offset = offset;
 
 	/* Parse Layer 4 headers */
 	switch (ip_proto) {
 	case ODPH_IPPROTO_ICMP:
-		pkt_hdr->input_flags.icmp = 1;
+		pkt_hdr->p.input_flags.icmp = 1;
 		break;
 
 	case ODPH_IPPROTO_TCP:
-		pkt_hdr->input_flags.tcp = 1;
+		pkt_hdr->p.input_flags.tcp = 1;
 		parse_tcp(pkt_hdr, &parseptr, NULL);
 		break;
 
 	case ODPH_IPPROTO_UDP:
-		pkt_hdr->input_flags.udp = 1;
+		pkt_hdr->p.input_flags.udp = 1;
 		parse_udp(pkt_hdr, &parseptr, NULL);
 		break;
 
 	case ODPH_IPPROTO_AH:
-		pkt_hdr->input_flags.ipsec = 1;
-		pkt_hdr->input_flags.ipsec_ah = 1;
+		pkt_hdr->p.input_flags.ipsec = 1;
+		pkt_hdr->p.input_flags.ipsec_ah = 1;
 		break;
 
 	case ODPH_IPPROTO_ESP:
-		pkt_hdr->input_flags.ipsec = 1;
-		pkt_hdr->input_flags.ipsec_esp = 1;
+		pkt_hdr->p.input_flags.ipsec = 1;
+		pkt_hdr->p.input_flags.ipsec_esp = 1;
 		break;
 
 	default:
-		pkt_hdr->input_flags.l4 = 0;
-		pkt_hdr->l4_offset = ODP_PACKET_OFFSET_INVALID;
+		pkt_hdr->p.input_flags.l4 = 0;
+		pkt_hdr->p.l4_offset = ODP_PACKET_OFFSET_INVALID;
 		break;
 	}
 
 parse_exit:
-	pkt_hdr->input_flags.parsed_all = 1;
-	return pkt_hdr->error_flags.all != 0;
+	pkt_hdr->p.input_flags.parsed_all = 1;
+	return pkt_hdr->p.error_flags.all != 0;
 }
 
 /**
diff --git a/platform/linux-generic/odp_packet_flags.c b/platform/linux-generic/odp_packet_flags.c
index 3acdc53..b88324c 100644
--- a/platform/linux-generic/odp_packet_flags.c
+++ b/platform/linux-generic/odp_packet_flags.c
@@ -7,26 +7,27 @@ 
 #include <odp/api/packet_flags.h>
 #include <odp_packet_internal.h>
 
-#define retflag(p, x) do {			       \
-	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(p); \
-	if (packet_parse_not_complete(pkt_hdr))	       \
-		packet_parse_full(pkt_hdr);	       \
-	return pkt_hdr->x;			       \
+#define retflag(pkt, x) do {                             \
+	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); \
+	if (packet_parse_not_complete(pkt_hdr))          \
+		packet_parse_full(pkt_hdr);              \
+	return pkt_hdr->p.x;                             \
 	} while (0)
 
-#define setflag(p, x, v) do {			       \
-	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(p); \
-	if (packet_parse_not_complete(pkt_hdr))	       \
-		packet_parse_full(pkt_hdr);	       \
-	pkt_hdr->x = v & 1;			       \
+#define setflag(pkt, x, v) do {                          \
+	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); \
+	if (packet_parse_not_complete(pkt_hdr))          \
+		packet_parse_full(pkt_hdr);              \
+	pkt_hdr->p.x = v & 1;                            \
 	} while (0)
 
 int odp_packet_has_error(odp_packet_t pkt)
 {
 	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
+
 	if (packet_parse_not_complete(pkt_hdr))
 		packet_parse_full(pkt_hdr);
-	return odp_packet_hdr(pkt)->error_flags.all != 0;
+	return odp_packet_hdr(pkt)->p.error_flags.all != 0;
 }
 
 /* Get Input Flags */
@@ -35,7 +36,7 @@  int odp_packet_has_l2(odp_packet_t pkt)
 {
 	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
 
-	return pkt_hdr->input_flags.l2;
+	return pkt_hdr->p.input_flags.l2;
 }
 
 int odp_packet_has_l2_error(odp_packet_t pkt)
@@ -43,9 +44,9 @@  int odp_packet_has_l2_error(odp_packet_t pkt)
 	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
 	/* L2 parsing is always done by default and hence
 	no additional check is required */
-	return pkt_hdr->error_flags.frame_len
-		| pkt_hdr->error_flags.snap_len
-		| pkt_hdr->error_flags.l2_chksum;
+	return pkt_hdr->p.error_flags.frame_len
+		| pkt_hdr->p.error_flags.snap_len
+		| pkt_hdr->p.error_flags.l2_chksum;
 }
 
 int odp_packet_has_l3(odp_packet_t pkt)
@@ -60,7 +61,7 @@  int odp_packet_has_l3_error(odp_packet_t pkt)
 	if (packet_parse_not_complete(pkt_hdr))
 		packet_parse_full(pkt_hdr);
 
-	return pkt_hdr->error_flags.ip_err;
+	return pkt_hdr->p.error_flags.ip_err;
 }
 
 int odp_packet_has_l4(odp_packet_t pkt)
@@ -75,14 +76,14 @@  int odp_packet_has_l4_error(odp_packet_t pkt)
 	if (packet_parse_not_complete(pkt_hdr))
 		packet_parse_full(pkt_hdr);
 
-	return pkt_hdr->error_flags.tcp_err | pkt_hdr->error_flags.udp_err;
+	return pkt_hdr->p.error_flags.tcp_err | pkt_hdr->p.error_flags.udp_err;
 }
 
 int odp_packet_has_eth(odp_packet_t pkt)
 {
 	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
 
-	return pkt_hdr->input_flags.eth;
+	return pkt_hdr->p.input_flags.eth;
 }
 
 int odp_packet_has_eth_bcast(odp_packet_t pkt)
@@ -99,7 +100,7 @@  int odp_packet_has_jumbo(odp_packet_t pkt)
 {
 	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
 
-	return pkt_hdr->input_flags.jumbo;
+	return pkt_hdr->p.input_flags.jumbo;
 }
 
 int odp_packet_has_vlan(odp_packet_t pkt)
@@ -176,14 +177,14 @@  int odp_packet_has_flow_hash(odp_packet_t pkt)
 {
 	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
 
-	return pkt_hdr->input_flags.flow_hash;
+	return pkt_hdr->p.input_flags.flow_hash;
 }
 
 int odp_packet_has_ts(odp_packet_t pkt)
 {
 	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
 
-	return pkt_hdr->input_flags.timestamp;
+	return pkt_hdr->p.input_flags.timestamp;
 }
 
 odp_packet_color_t odp_packet_color(odp_packet_t pkt)
@@ -198,7 +199,7 @@  void odp_packet_color_set(odp_packet_t pkt, odp_packet_color_t color)
 	if (packet_parse_not_complete(pkt_hdr))
 		packet_parse_full(pkt_hdr);
 
-	pkt_hdr->input_flags.color = color;
+	pkt_hdr->p.input_flags.color = color;
 }
 
 odp_bool_t odp_packet_drop_eligible(odp_packet_t pkt)
@@ -208,7 +209,7 @@  odp_bool_t odp_packet_drop_eligible(odp_packet_t pkt)
 	if (packet_parse_not_complete(pkt_hdr))
 		packet_parse_full(pkt_hdr);
 
-	return !pkt_hdr->input_flags.nodrop;
+	return !pkt_hdr->p.input_flags.nodrop;
 }
 
 void odp_packet_drop_eligible_set(odp_packet_t pkt, odp_bool_t drop)
@@ -228,7 +229,7 @@  void odp_packet_shaper_len_adjust_set(odp_packet_t pkt, int8_t adj)
 	if (packet_parse_not_complete(pkt_hdr))
 		packet_parse_full(pkt_hdr);
 
-	pkt_hdr->output_flags.shaper_len_adj = adj;
+	pkt_hdr->p.output_flags.shaper_len_adj = adj;
 }
 
 /* Set Input Flags */
@@ -342,12 +343,12 @@  void odp_packet_has_flow_hash_clr(odp_packet_t pkt)
 {
 	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
 
-	pkt_hdr->input_flags.flow_hash = 0;
+	pkt_hdr->p.input_flags.flow_hash = 0;
 }
 
 void odp_packet_has_ts_clr(odp_packet_t pkt)
 {
 	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
 
-	pkt_hdr->input_flags.timestamp = 0;
+	pkt_hdr->p.input_flags.timestamp = 0;
 }
diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c
index 416a361..67c1adf 100644
--- a/platform/linux-generic/odp_packet_io.c
+++ b/platform/linux-generic/odp_packet_io.c
@@ -551,7 +551,7 @@  static inline int pktin_recv_buf(odp_pktin_queue_t queue,
 		buf = _odp_packet_to_buffer(pkt);
 		buf_hdr = odp_buf_to_hdr(buf);
 
-		if (pkt_hdr->input_flags.dst_queue) {
+		if (pkt_hdr->p.input_flags.dst_queue) {
 			queue_entry_t *dst_queue;
 			int ret;
 
diff --git a/platform/linux-generic/pktio/dpdk.c b/platform/linux-generic/pktio/dpdk.c
index 2225dfe..e2b3aec 100644
--- a/platform/linux-generic/pktio/dpdk.c
+++ b/platform/linux-generic/pktio/dpdk.c
@@ -742,7 +742,7 @@  static inline int mbuf_to_pkt(pktio_entry_t *pktio_entry,
 		pkt_hdr->input = pktio_entry->s.handle;
 
 		if (pktio_cls_enabled(pktio_entry))
-			copy_packet_parser_metadata(&parsed_hdr, pkt_hdr);
+			copy_packet_cls_metadata(&parsed_hdr, pkt_hdr);
 		else
 			packet_parse_l2(pkt_hdr);
 
diff --git a/platform/linux-generic/pktio/ipc.c b/platform/linux-generic/pktio/ipc.c
index bd74f11..e0d4ab9 100644
--- a/platform/linux-generic/pktio/ipc.c
+++ b/platform/linux-generic/pktio/ipc.c
@@ -571,7 +571,7 @@  static int ipc_pktio_recv_lockless(pktio_entry_t *pktio_entry,
 		memcpy(pkt_data, remote_pkt_data, phdr.frame_len);
 
 		/* Copy packets L2, L3 parsed offsets and size */
-		copy_packet_parser_metadata(&phdr, odp_packet_hdr(pkt));
+		copy_packet_cls_metadata(&phdr, odp_packet_hdr(pkt));
 
 		odp_packet_hdr(pkt)->frame_len = phdr.frame_len;
 		odp_packet_hdr(pkt)->headroom = phdr.headroom;
diff --git a/platform/linux-generic/pktio/loop.c b/platform/linux-generic/pktio/loop.c
index 75f6a0a..2fb88e2 100644
--- a/platform/linux-generic/pktio/loop.c
+++ b/platform/linux-generic/pktio/loop.c
@@ -111,7 +111,7 @@  static int loopback_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 		pkt_hdr->input = pktio_entry->s.handle;
 
 		if (pktio_cls_enabled(pktio_entry))
-			copy_packet_parser_metadata(&parsed_hdr, pkt_hdr);
+			copy_packet_cls_metadata(&parsed_hdr, pkt_hdr);
 		else
 			packet_parse_l2(pkt_hdr);
 
diff --git a/platform/linux-generic/pktio/netmap.c b/platform/linux-generic/pktio/netmap.c
index 4ea0d4a..d189aae 100644
--- a/platform/linux-generic/pktio/netmap.c
+++ b/platform/linux-generic/pktio/netmap.c
@@ -628,7 +628,7 @@  static inline int netmap_pkt_to_odp(pktio_entry_t *pktio_entry,
 	pkt_hdr->input = pktio_entry->s.handle;
 
 	if (pktio_cls_enabled(pktio_entry))
-		copy_packet_parser_metadata(&parsed_hdr, pkt_hdr);
+		copy_packet_cls_metadata(&parsed_hdr, pkt_hdr);
 	else
 		packet_parse_l2(pkt_hdr);
 
diff --git a/platform/linux-generic/pktio/socket.c b/platform/linux-generic/pktio/socket.c
index e07b6ad..b116145 100644
--- a/platform/linux-generic/pktio/socket.c
+++ b/platform/linux-generic/pktio/socket.c
@@ -678,7 +678,7 @@  static int sock_mmsg_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
 				continue;
 			}
 			pkt_hdr->input = pktio_entry->s.handle;
-			copy_packet_parser_metadata(&parsed_hdr, pkt_hdr);
+			copy_packet_cls_metadata(&parsed_hdr, pkt_hdr);
 			packet_set_ts(pkt_hdr, ts);
 
 			pkt_table[nb_rx++] = pkt;
diff --git a/platform/linux-generic/pktio/socket_mmap.c b/platform/linux-generic/pktio/socket_mmap.c
index 720004c..30c44e9 100644
--- a/platform/linux-generic/pktio/socket_mmap.c
+++ b/platform/linux-generic/pktio/socket_mmap.c
@@ -224,7 +224,7 @@  static inline unsigned pkt_mmap_v2_rx(pktio_entry_t *pktio_entry,
 		hdr->input = pktio_entry->s.handle;
 
 		if (pktio_cls_enabled(pktio_entry))
-			copy_packet_parser_metadata(&parsed_hdr, hdr);
+			copy_packet_cls_metadata(&parsed_hdr, hdr);
 		else
 			packet_parse_l2(hdr);