diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 6cd99bf37f..bb22294dd3 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -3315,16 +3315,16 @@ static const struct token token_list[] = {
 		.help = "QoS flow identifier",
 		.next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED),
 			     item_param),
-		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp_psc,
-					qfi)),
+		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc,
+					hdr.qfi, 6)),
 	},
 	[ITEM_GTP_PSC_PDU_T] = {
 		.name = "pdu_t",
 		.help = "PDU type",
 		.next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED),
 			     item_param),
-		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp_psc,
-					pdu_type)),
+		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc,
+					hdr.type, 4)),
 	},
 	[ITEM_PPPOES] = {
 		.name = "pppoes",
@@ -8600,20 +8600,13 @@ cmd_set_raw_parsed(const struct buffer *in)
 					*opt = item->spec;
 				struct {
 					uint8_t len;
-					uint8_t pdu_type;
-					uint8_t qfi;
+					uint8_t pdu_type:4;
+					uint8_t qfi:6;
 					uint8_t next;
 				} psc;
-
-				if (opt->pdu_type & 0x0F) {
-					/* Support the minimal option only. */
-					fprintf(stderr,
-						"Error - GTP PSC option with extra fields not supported\n");
-					goto error;
-				}
 				psc.len = sizeof(psc);
-				psc.pdu_type = opt->pdu_type;
-				psc.qfi = opt->qfi;
+				psc.pdu_type = opt->hdr.type;
+				psc.qfi = opt->hdr.qfi;
 				psc.next = 0;
 				*total_size += sizeof(psc);
 				rte_memcpy(data_tail - (*total_size),
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 4f8751be1c..bbef706374 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3788,7 +3788,7 @@ This section lists supported pattern items and their attributes, if any.
 
   - ``pdu_type {unsigned}``: PDU type.
 
-  - ``qfi {unsigned}``: PPP, RQI and QoS flow identifier.
+  - ``qfi {unsigned}``: QoS flow identifier.
 
 - ``pppoes``, ``pppoed``: match PPPoE header.
 
diff --git a/drivers/net/iavf/iavf_fdir.c b/drivers/net/iavf/iavf_fdir.c
index da3eec8b59..8f56342762 100644
--- a/drivers/net/iavf/iavf_fdir.c
+++ b/drivers/net/iavf/iavf_fdir.c
@@ -1160,15 +1160,16 @@ iavf_fdir_parse_pattern(__rte_unused struct iavf_adapter *ad,
 
 			if (!gtp_psc_spec)
 				VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, GTPU_EH);
-			else if ((gtp_psc_mask->qfi) && !(gtp_psc_mask->pdu_type))
+			else if ((gtp_psc_mask->hdr.qfi) &&
+				!(gtp_psc_mask->hdr.type))
 				VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, GTPU_EH);
-			else if (gtp_psc_spec->pdu_type == IAVF_GTPU_EH_UPLINK)
+			else if (gtp_psc_spec->hdr.type == IAVF_GTPU_EH_UPLINK)
 				VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, GTPU_EH_PDU_UP);
-			else if (gtp_psc_spec->pdu_type == IAVF_GTPU_EH_DWLINK)
+			else if (gtp_psc_spec->hdr.type == IAVF_GTPU_EH_DWLINK)
 				VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, GTPU_EH_PDU_DWN);
 
 			if (gtp_psc_spec && gtp_psc_mask) {
-				if (gtp_psc_mask->qfi == UINT8_MAX) {
+				if (gtp_psc_mask->hdr.qfi == 0x3F) {
 					input_set |= IAVF_INSET_GTPU_QFI;
 					VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, GTPU_EH, QFI);
 				}
diff --git a/drivers/net/iavf/iavf_hash.c b/drivers/net/iavf/iavf_hash.c
index 2b03dad858..144f4277d0 100644
--- a/drivers/net/iavf/iavf_hash.c
+++ b/drivers/net/iavf/iavf_hash.c
@@ -731,9 +731,9 @@ iavf_hash_parse_pattern(const struct rte_flow_item pattern[], uint64_t *phint,
 			psc = item->spec;
 			if (!psc)
 				break;
-			else if (psc->pdu_type == IAVF_GTPU_EH_UPLINK)
+			else if (psc->hdr.type == IAVF_GTPU_EH_UPLINK)
 				*phint |= IAVF_PHINT_GTPU_EH_UP;
-			else if (psc->pdu_type == IAVF_GTPU_EH_DWNLINK)
+			else if (psc->hdr.type == IAVF_GTPU_EH_DWNLINK)
 				*phint |= IAVF_PHINT_GTPU_EH_DWN;
 			break;
 		case RTE_FLOW_ITEM_TYPE_ECPRI:
diff --git a/drivers/net/ice/ice_fdir_filter.c b/drivers/net/ice/ice_fdir_filter.c
index 82adb1fc8b..3a7ef270af 100644
--- a/drivers/net/ice/ice_fdir_filter.c
+++ b/drivers/net/ice/ice_fdir_filter.c
@@ -2104,11 +2104,11 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
 			if (!(gtp_psc_spec && gtp_psc_mask))
 				break;
 
-			if (gtp_psc_mask->qfi == UINT8_MAX)
+			if (gtp_psc_mask->hdr.qfi == 0x3F)
 				input_set_o |= ICE_INSET_GTPU_QFI;
 
 			filter->input.gtpu_data.qfi =
-				gtp_psc_spec->qfi;
+				gtp_psc_spec->hdr.qfi;
 			break;
 		case RTE_FLOW_ITEM_TYPE_ESP:
 			if (l3 == RTE_FLOW_ITEM_TYPE_IPV4 &&
diff --git a/drivers/net/ice/ice_hash.c b/drivers/net/ice/ice_hash.c
index 54d14dfcdd..caf1bfa40f 100644
--- a/drivers/net/ice/ice_hash.c
+++ b/drivers/net/ice/ice_hash.c
@@ -619,9 +619,9 @@ ice_hash_parse_pattern(const struct rte_flow_item pattern[], uint64_t *phint,
 			psc = item->spec;
 			if (!psc)
 				break;
-			else if (psc->pdu_type == ICE_GTPU_EH_UPLINK)
+			else if (psc->hdr.type == ICE_GTPU_EH_UPLINK)
 				*phint |= ICE_PHINT_GTPU_EH_UP;
-			else if (psc->pdu_type == ICE_GTPU_EH_DWNLINK)
+			else if (psc->hdr.type == ICE_GTPU_EH_DWNLINK)
 				*phint |= ICE_PHINT_GTPU_EH_DWN;
 			break;
 		default:
diff --git a/drivers/net/ice/ice_switch_filter.c b/drivers/net/ice/ice_switch_filter.c
index eeed386c63..e44c50ff3d 100644
--- a/drivers/net/ice/ice_switch_filter.c
+++ b/drivers/net/ice/ice_switch_filter.c
@@ -1350,7 +1350,7 @@ ice_switch_parse_pattern(const struct rte_flow_item pattern[],
 				return false;
 			}
 			if (gtp_psc_spec && gtp_psc_mask) {
-				if (gtp_psc_mask->pdu_type) {
+				if (gtp_psc_mask->hdr.type) {
 					rte_flow_error_set(error, EINVAL,
 						RTE_FLOW_ERROR_TYPE_ITEM,
 						item,
@@ -1358,13 +1358,13 @@ ice_switch_parse_pattern(const struct rte_flow_item pattern[],
 					return false;
 				}
 				input = &outer_input_set;
-				if (gtp_psc_mask->qfi)
+				if (gtp_psc_mask->hdr.qfi)
 					*input |= ICE_INSET_GTPU_QFI;
 				list[t].type = ICE_GTP;
 				list[t].h_u.gtp_hdr.qfi =
-					gtp_psc_spec->qfi;
+					gtp_psc_spec->hdr.qfi;
 				list[t].m_u.gtp_hdr.qfi =
-					gtp_psc_mask->qfi;
+					gtp_psc_mask->hdr.qfi;
 				input_set_byte += 1;
 				t++;
 			}
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index 76ad53f2a1..5c68d4f7d7 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -397,9 +397,6 @@ enum mlx5_feature_name {
 /* GTP extension header flag. */
 #define MLX5_GTP_EXT_HEADER_FLAG 4
 
-/* GTP extension header max PDU type value. */
-#define MLX5_GTP_EXT_MAX_PDU_TYPE 15
-
 /* GTP extension header PDU type shift. */
 #define MLX5_GTP_PDU_TYPE_SHIFT(a) ((a) << 4)
 
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 31d857030f..a54defa45f 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -2412,11 +2412,10 @@ flow_dv_validate_item_gtp_psc(const struct rte_flow_item *item,
 {
 	const struct rte_flow_item_gtp *gtp_spec;
 	const struct rte_flow_item_gtp *gtp_mask;
-	const struct rte_flow_item_gtp_psc *spec;
 	const struct rte_flow_item_gtp_psc *mask;
 	const struct rte_flow_item_gtp_psc nic_mask = {
-		.pdu_type = 0xFF,
-		.qfi = 0xFF,
+		.hdr.type = 0xF,
+		.hdr.qfi = 0x3F,
 	};
 
 	if (!gtp_item || !(last_item & MLX5_FLOW_LAYER_GTP))
@@ -2440,12 +2439,7 @@ flow_dv_validate_item_gtp_psc(const struct rte_flow_item *item,
 	/* GTP spec is here and E flag is requested to match zero. */
 	if (!item->spec)
 		return 0;
-	spec = item->spec;
 	mask = item->mask ? item->mask : &rte_flow_item_gtp_psc_mask;
-	if (spec->pdu_type > MLX5_GTP_EXT_MAX_PDU_TYPE)
-		return rte_flow_error_set
-			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item,
-			 "PDU type should be smaller than 16");
 	return mlx5_flow_item_acceptable(item, (const uint8_t *)mask,
 					 (const uint8_t *)&nic_mask,
 					 sizeof(struct rte_flow_item_gtp_psc),
@@ -9951,14 +9945,14 @@ flow_dv_translate_item_gtp_psc(void *matcher, void *key,
 		if (!gtp_psc_m)
 			gtp_psc_m = &rte_flow_item_gtp_psc_mask;
 		dw_0.w32 = 0;
-		dw_0.type_flags = MLX5_GTP_PDU_TYPE_SHIFT(gtp_psc_m->pdu_type);
-		dw_0.qfi = gtp_psc_m->qfi;
+		dw_0.type_flags = MLX5_GTP_PDU_TYPE_SHIFT(gtp_psc_m->hdr.type);
+		dw_0.qfi = gtp_psc_m->hdr.qfi;
 		MLX5_SET(fte_match_set_misc3, misc3_m, gtpu_first_ext_dw_0,
 			 rte_cpu_to_be_32(dw_0.w32));
 		dw_0.w32 = 0;
-		dw_0.type_flags = MLX5_GTP_PDU_TYPE_SHIFT(gtp_psc_v->pdu_type &
-							gtp_psc_m->pdu_type);
-		dw_0.qfi = gtp_psc_v->qfi & gtp_psc_m->qfi;
+		dw_0.type_flags = MLX5_GTP_PDU_TYPE_SHIFT(gtp_psc_v->hdr.type &
+							gtp_psc_m->hdr.type);
+		dw_0.qfi = gtp_psc_v->hdr.qfi & gtp_psc_m->hdr.qfi;
 		MLX5_SET(fte_match_set_misc3, misc3_v, gtpu_first_ext_dw_0,
 			 rte_cpu_to_be_32(dw_0.w32));
 	}
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 70f455d47d..7b1ed7f110 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -34,6 +34,7 @@
 #include <rte_mbuf.h>
 #include <rte_mbuf_dyn.h>
 #include <rte_meter.h>
+#include <rte_gtp.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -1444,15 +1445,14 @@ static const struct rte_flow_item_meta rte_flow_item_meta_mask = {
  * Matches a GTP PDU extension header with type 0x85.
  */
 struct rte_flow_item_gtp_psc {
-	uint8_t pdu_type; /**< PDU type. */
-	uint8_t qfi; /**< PPP, RQI, QoS flow identifier. */
+	struct rte_gtp_psc_generic_hdr hdr; /**< gtp psc generic hdr. */
 };
 
 /** Default mask for RTE_FLOW_ITEM_TYPE_GTP_PSC. */
 #ifndef __cplusplus
 static const struct rte_flow_item_gtp_psc
 rte_flow_item_gtp_psc_mask = {
-	.qfi = 0xff,
+	.hdr.qfi = 0x3f,
 };
 #endif
 
