diff --git a/platform/linux-generic/include/odp/api/plat/packet_inline_types.h b/platform/linux-generic/include/odp/api/plat/packet_inline_types.h
index fb54e6402..008a06bff 100644
--- a/platform/linux-generic/include/odp/api/plat/packet_inline_types.h
+++ b/platform/linux-generic/include/odp/api/plat/packet_inline_types.h
@@ -80,14 +80,7 @@ typedef union {
 
 		uint64_t ipsec:1;     /* IPSec packet. Required by the
 					   odp_packet_has_ipsec_set() func. */
-		uint64_t ipsec_ah:1;  /* IPSec authentication header */
-		uint64_t ipsec_esp:1; /* IPSec encapsulating security
-					   payload */
-		uint64_t udp:1;       /* UDP */
-		uint64_t tcp:1;       /* TCP */
 		uint64_t tcpopt:1;    /* TCP options present */
-		uint64_t sctp:1;      /* SCTP */
-		uint64_t icmp:1;      /* ICMP */
 
 		uint64_t color:2;     /* Packet color for traffic mgmt */
 		uint64_t nodrop:1;    /* Drop eligibility status */
diff --git a/platform/linux-generic/include/odp_classification_inlines.h b/platform/linux-generic/include/odp_classification_inlines.h
index f9462e976..4d6472355 100644
--- a/platform/linux-generic/include/odp_classification_inlines.h
+++ b/platform/linux-generic/include/odp_classification_inlines.h
@@ -102,7 +102,8 @@ static inline int verify_pmr_tcp_sport(const uint8_t *pkt_addr,
 {
 	uint16_t sport;
 	const _odp_tcphdr_t *tcp;
-	if (!pkt_hdr->p.input_flags.tcp)
+
+	if (!packet_hdr_has_tcp(pkt_hdr))
 		return 0;
 	tcp = (const _odp_tcphdr_t *)(pkt_addr + pkt_hdr->p.l4_offset);
 	sport = _odp_be_to_cpu_16(tcp->src_port);
@@ -118,7 +119,8 @@ static inline int verify_pmr_tcp_dport(const uint8_t *pkt_addr,
 {
 	uint16_t dport;
 	const _odp_tcphdr_t *tcp;
-	if (!pkt_hdr->p.input_flags.tcp)
+
+	if (!packet_hdr_has_tcp(pkt_hdr))
 		return 0;
 	tcp = (const _odp_tcphdr_t *)(pkt_addr + pkt_hdr->p.l4_offset);
 	dport = _odp_be_to_cpu_16(tcp->dst_port);
@@ -134,7 +136,8 @@ static inline int verify_pmr_udp_dport(const uint8_t *pkt_addr,
 {
 	uint16_t dport;
 	const _odp_udphdr_t *udp;
-	if (!pkt_hdr->p.input_flags.udp)
+
+	if (!packet_hdr_has_udp(pkt_hdr))
 		return 0;
 	udp = (const _odp_udphdr_t *)(pkt_addr + pkt_hdr->p.l4_offset);
 	dport = _odp_be_to_cpu_16(udp->dst_port);
@@ -151,7 +154,7 @@ static inline int verify_pmr_udp_sport(const uint8_t *pkt_addr,
 	uint16_t sport;
 	const _odp_udphdr_t *udp;
 
-	if (!pkt_hdr->p.input_flags.udp)
+	if (!packet_hdr_has_udp(pkt_hdr))
 		return 0;
 	udp = (const _odp_udphdr_t *)(pkt_addr + pkt_hdr->p.l4_offset);
 	sport = _odp_be_to_cpu_16(udp->src_port);
@@ -291,11 +294,11 @@ static inline int verify_pmr_ipsec_spi(const uint8_t *pkt_addr,
 
 	pkt_addr += pkt_hdr->p.l4_offset;
 
-	if (pkt_hdr->p.input_flags.ipsec_ah) {
+	if (pkt_hdr->p.input_flags.l4_type == ODP_PROTO_L4_TYPE_AH) {
 		const _odp_ahhdr_t *ahhdr = (const _odp_ahhdr_t *)pkt_addr;
 
 		spi = _odp_be_to_cpu_32(ahhdr->spi);
-	} else if (pkt_hdr->p.input_flags.ipsec_esp) {
+	} else if (pkt_hdr->p.input_flags.l4_type == ODP_PROTO_L4_TYPE_ESP) {
 		const _odp_esphdr_t *esphdr = (const _odp_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 59cb9ded9..9ef11c677 100644
--- a/platform/linux-generic/include/odp_packet_internal.h
+++ b/platform/linux-generic/include/odp_packet_internal.h
@@ -291,6 +291,16 @@ static inline int packet_hdr_has_ipv6(odp_packet_hdr_t *pkt_hdr)
 	return pkt_hdr->p.input_flags.l3_type == ODP_PROTO_L3_TYPE_IPV6;
 }
 
+static inline int packet_hdr_has_tcp(odp_packet_hdr_t *pkt_hdr)
+{
+	return pkt_hdr->p.input_flags.l4_type == ODP_PROTO_L4_TYPE_TCP;
+}
+
+static inline int packet_hdr_has_udp(odp_packet_hdr_t *pkt_hdr)
+{
+	return pkt_hdr->p.input_flags.l4_type == ODP_PROTO_L4_TYPE_UDP;
+}
+
 static inline void packet_set_ts(odp_packet_hdr_t *pkt_hdr, odp_time_t *ts)
 {
 	if (ts != NULL) {
diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c
index 5147db137..6937ac4b2 100644
--- a/platform/linux-generic/odp_classification.c
+++ b/platform/linux-generic/odp_classification.c
@@ -1036,14 +1036,14 @@ static uint32_t packet_rss_hash(odp_packet_hdr_t *pkt_hdr,
 			tuple_len += 2;
 		}
 
-		if (pkt_hdr->p.input_flags.tcp && hash_proto.tcp) {
+		if (packet_hdr_has_tcp(pkt_hdr) && hash_proto.tcp) {
 			/* add tcp */
 			tcp = (const _odp_tcphdr_t *)(base +
 			       pkt_hdr->p.l4_offset);
 			tuple.v4.sport = tcp->src_port;
 			tuple.v4.dport = tcp->dst_port;
 			tuple_len += 1;
-		} else if (pkt_hdr->p.input_flags.udp && hash_proto.udp) {
+		} else if (packet_hdr_has_udp(pkt_hdr) && hash_proto.udp) {
 			/* add udp */
 			udp = (const _odp_udphdr_t *)(base +
 			       pkt_hdr->p.l4_offset);
@@ -1059,13 +1059,13 @@ static uint32_t packet_rss_hash(odp_packet_hdr_t *pkt_hdr,
 			thash_load_ipv6_addr(ipv6, &tuple);
 			tuple_len += 8;
 		}
-		if (pkt_hdr->p.input_flags.tcp && hash_proto.tcp) {
+		if (packet_hdr_has_tcp(pkt_hdr) && hash_proto.tcp) {
 			tcp = (const _odp_tcphdr_t *)(base +
 			       pkt_hdr->p.l4_offset);
 			tuple.v6.sport = tcp->src_port;
 			tuple.v6.dport = tcp->dst_port;
 			tuple_len += 1;
-		} else if (pkt_hdr->p.input_flags.udp && hash_proto.udp) {
+		} else if (packet_hdr_has_udp(pkt_hdr) && hash_proto.udp) {
 			/* add udp */
 			udp = (const _odp_udphdr_t *)(base +
 			       pkt_hdr->p.l4_offset);
diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c
index 065c22259..87bf23564 100644
--- a/platform/linux-generic/odp_packet.c
+++ b/platform/linux-generic/odp_packet.c
@@ -2228,10 +2228,11 @@ int packet_parse_common_l3_l4(packet_parser_t *prs, const uint8_t *parseptr,
 	/* Parse Layer 4 headers */
 	switch (ip_proto) {
 	case _ODP_IPPROTO_ICMPV4:
-	/* Fall through */
+		/* Do nothing */
+		break;
 
 	case _ODP_IPPROTO_ICMPV6:
-		prs->input_flags.icmp = 1;
+		/* Do nothing */
 		break;
 
 	case _ODP_IPPROTO_IPIP:
@@ -2241,29 +2242,25 @@ int packet_parse_common_l3_l4(packet_parser_t *prs, const uint8_t *parseptr,
 	case _ODP_IPPROTO_TCP:
 		if (odp_unlikely(offset + _ODP_TCPHDR_LEN > seg_len))
 			return -1;
-		prs->input_flags.tcp = 1;
 		parse_tcp(prs, &parseptr, NULL);
 		break;
 
 	case _ODP_IPPROTO_UDP:
 		if (odp_unlikely(offset + _ODP_UDPHDR_LEN > seg_len))
 			return -1;
-		prs->input_flags.udp = 1;
 		parse_udp(prs, &parseptr, NULL);
 		break;
 
 	case _ODP_IPPROTO_AH:
 		prs->input_flags.ipsec = 1;
-		prs->input_flags.ipsec_ah = 1;
 		break;
 
 	case _ODP_IPPROTO_ESP:
 		prs->input_flags.ipsec = 1;
-		prs->input_flags.ipsec_esp = 1;
 		break;
 
 	case _ODP_IPPROTO_SCTP:
-		prs->input_flags.sctp = 1;
+		/* Do nothing */
 		break;
 
 	default:
diff --git a/platform/linux-generic/odp_packet_flags.c b/platform/linux-generic/odp_packet_flags.c
index a1d64ddce..fdde865ee 100644
--- a/platform/linux-generic/odp_packet_flags.c
+++ b/platform/linux-generic/odp_packet_flags.c
@@ -9,6 +9,7 @@
 #include <odp/api/plat/packet_flag_inlines.h>
 #include <odp/api/packet_flags.h>
 #include <odp_packet_internal.h>
+#include <odp_debug_internal.h>
 
 #define retflag(pkt, x) do {                             \
 	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); \
@@ -129,22 +130,31 @@ int odp_packet_has_ipsec(odp_packet_t pkt)
 
 int odp_packet_has_udp(odp_packet_t pkt)
 {
-	retflag(pkt, input_flags.udp);
+	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
+
+	return pkt_hdr->p.input_flags.l4_type == ODP_PROTO_L4_TYPE_UDP;
 }
 
 int odp_packet_has_tcp(odp_packet_t pkt)
 {
-	retflag(pkt, input_flags.tcp);
+	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
+
+	return pkt_hdr->p.input_flags.l4_type == ODP_PROTO_L4_TYPE_TCP;
 }
 
 int odp_packet_has_sctp(odp_packet_t pkt)
 {
-	retflag(pkt, input_flags.sctp);
+	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
+
+	return pkt_hdr->p.input_flags.l4_type == ODP_PROTO_L4_TYPE_SCTP;
 }
 
 int odp_packet_has_icmp(odp_packet_t pkt)
 {
-	retflag(pkt, input_flags.icmp);
+	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
+
+	return pkt_hdr->p.input_flags.l4_type == ODP_PROTO_L4_TYPE_ICMPV4 ||
+	       pkt_hdr->p.input_flags.l4_type == ODP_PROTO_L4_TYPE_ICMPV6;
 }
 
 odp_packet_color_t odp_packet_color(odp_packet_t pkt)
@@ -290,22 +300,56 @@ void odp_packet_has_ipsec_set(odp_packet_t pkt, int val)
 
 void odp_packet_has_udp_set(odp_packet_t pkt, int val)
 {
-	setflag(pkt, input_flags.udp, val);
+	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
+	odp_proto_l4_type_t type = ODP_PROTO_L4_TYPE_UDP;
+
+	if (val)
+		pkt_hdr->p.input_flags.l4_type = type;
+	else if (pkt_hdr->p.input_flags.l4_type == type)
+		pkt_hdr->p.input_flags.l4_type = ODP_PROTO_L4_TYPE_NONE;
 }
 
 void odp_packet_has_tcp_set(odp_packet_t pkt, int val)
 {
-	setflag(pkt, input_flags.tcp, val);
+	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
+	odp_proto_l4_type_t type = ODP_PROTO_L4_TYPE_TCP;
+
+	if (val)
+		pkt_hdr->p.input_flags.l4_type = type;
+	else if (pkt_hdr->p.input_flags.l4_type == type)
+		pkt_hdr->p.input_flags.l4_type = ODP_PROTO_L4_TYPE_NONE;
 }
 
 void odp_packet_has_sctp_set(odp_packet_t pkt, int val)
 {
-	setflag(pkt, input_flags.sctp, val);
+	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
+	odp_proto_l4_type_t type = ODP_PROTO_L4_TYPE_SCTP;
+
+	if (val)
+		pkt_hdr->p.input_flags.l4_type = type;
+	else if (pkt_hdr->p.input_flags.l4_type == type)
+		pkt_hdr->p.input_flags.l4_type = ODP_PROTO_L4_TYPE_NONE;
 }
 
 void odp_packet_has_icmp_set(odp_packet_t pkt, int val)
 {
-	setflag(pkt, input_flags.icmp, val);
+	odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
+	odp_proto_l3_type_t ip4 = ODP_PROTO_L3_TYPE_IPV4;
+	odp_proto_l3_type_t ip6 = ODP_PROTO_L3_TYPE_IPV6;
+	odp_proto_l4_type_t type4 = ODP_PROTO_L4_TYPE_ICMPV4;
+	odp_proto_l4_type_t type6 = ODP_PROTO_L4_TYPE_ICMPV6;
+
+	if (val) {
+		if (pkt_hdr->p.input_flags.l3_type == ip4)
+			pkt_hdr->p.input_flags.l4_type = type4;
+		else if (pkt_hdr->p.input_flags.l3_type == ip6)
+			pkt_hdr->p.input_flags.l4_type = type6;
+		else
+			ODP_ERR("Setting ICMP flag for non-IPv4/IPv6 packet!\n");
+	} else if (pkt_hdr->p.input_flags.l3_type == type4 ||
+		   pkt_hdr->p.input_flags.l3_type == type6) {
+		pkt_hdr->p.input_flags.l4_type = ODP_PROTO_L4_TYPE_NONE;
+	}
 }
 
 void odp_packet_has_flow_hash_clr(odp_packet_t pkt)
