diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 882f577848..d3ab57ab8d 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -982,6 +982,7 @@ bnxt_ulp_create_vfr_default_rules(struct rte_eth_dev *vfr_ethdev);
 int32_t
 bnxt_ulp_delete_vfr_default_rules(struct bnxt_representor *vfr);
 uint16_t bnxt_get_vnic_id(uint16_t port, enum bnxt_ulp_intf_type type);
+struct bnxt *bnxt_get_bp(uint16_t port);
 uint16_t bnxt_get_svif(uint16_t port_id, bool func_svif,
 		       enum bnxt_ulp_intf_type type);
 uint16_t bnxt_get_fw_func_id(uint16_t port, enum bnxt_ulp_intf_type type);
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index a0e0ba5884..ebb326b0d1 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -4787,6 +4787,32 @@ static void bnxt_config_vf_req_fwd(struct bnxt *bp)
 	BNXT_HWRM_CMD_TO_FORWARD(HWRM_OEM_CMD);
 }
 
+struct bnxt *
+bnxt_get_bp(uint16_t port)
+{
+	struct bnxt *bp;
+	struct rte_eth_dev *dev;
+
+	if (!rte_eth_dev_is_valid_port(port)) {
+		PMD_DRV_LOG(ERR, "Invalid port %d\n", port);
+		return NULL;
+	}
+
+	dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(dev)) {
+		PMD_DRV_LOG(ERR, "Device %d not supported\n", port);
+		return NULL;
+	}
+
+	bp = (struct bnxt *)dev->data->dev_private;
+	if (!BNXT_TRUFLOW_EN(bp)) {
+		PMD_DRV_LOG(ERR, "TRUFLOW not enabled\n");
+		return NULL;
+	}
+
+	return bp;
+}
+
 uint16_t
 bnxt_get_svif(uint16_t port_id, bool func_svif,
 	      enum bnxt_ulp_intf_type type)
diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
index 554123679e..5a2249f349 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
@@ -1008,6 +1008,9 @@ ulp_rte_ipv4_hdr_handler(const struct rte_flow_item *item,
 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_L3, 1);
 	}
 
+	if (proto == IPPROTO_GRE)
+		ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_T_GRE);
+
 	/* Update the field protocol hdr bitmap */
 	ulp_rte_l3_proto_type_update(params, proto, inner_flag);
 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_L3_HDR_CNT, ++cnt);
@@ -1146,6 +1149,9 @@ ulp_rte_ipv6_hdr_handler(const struct rte_flow_item *item,
 		ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_O_L3, 1);
 	}
 
+	if (proto == IPPROTO_GRE)
+		ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_T_GRE);
+
 	/* Update the field protocol hdr bitmap */
 	ulp_rte_l3_proto_type_update(params, proto, inner_flag);
 	ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_L3_HDR_CNT, ++cnt);
@@ -1420,6 +1426,57 @@ ulp_rte_vxlan_hdr_handler(const struct rte_flow_item *item,
 	return BNXT_TF_RC_SUCCESS;
 }
 
+/* Function to handle the parsing of RTE Flow item GRE Header. */
+int32_t
+ulp_rte_gre_hdr_handler(const struct rte_flow_item *item,
+			  struct ulp_rte_parser_params *params)
+{
+	const struct rte_flow_item_gre *gre_spec = item->spec;
+	const struct rte_flow_item_gre *gre_mask = item->mask;
+	struct ulp_rte_hdr_bitmap *hdr_bitmap = &params->hdr_bitmap;
+	uint32_t idx = params->field_idx;
+	uint32_t size;
+	struct ulp_rte_hdr_field *field;
+
+	if (!gre_spec && !gre_mask) {
+		BNXT_TF_DBG(ERR, "Parse Error: GRE item is invalid\n");
+		return BNXT_TF_RC_ERROR;
+	}
+
+	if (gre_spec) {
+		size = sizeof(gre_spec->c_rsvd0_ver);
+		field = ulp_rte_parser_fld_copy(&params->hdr_field[idx],
+						&gre_spec->c_rsvd0_ver,
+						size);
+		size = sizeof(gre_spec->protocol);
+		field = ulp_rte_parser_fld_copy(field,
+						&gre_spec->protocol,
+						size);
+	}
+	if (gre_mask) {
+		ulp_rte_prsr_mask_copy(params, &idx,
+				       &gre_mask->c_rsvd0_ver,
+				       sizeof(gre_mask->c_rsvd0_ver));
+		ulp_rte_prsr_mask_copy(params, &idx,
+				       &gre_mask->protocol,
+				       sizeof(gre_mask->protocol));
+	}
+	/* Add number of GRE header elements */
+	params->field_idx += BNXT_ULP_PROTO_HDR_GRE_NUM;
+
+	/* Update the hdr_bitmap with GRE */
+	ULP_BITMAP_SET(hdr_bitmap->bits, BNXT_ULP_HDR_BIT_T_GRE);
+	return BNXT_TF_RC_SUCCESS;
+}
+
+/* Function to handle the parsing of RTE Flow item ANY. */
+int32_t
+ulp_rte_item_any_handler(const struct rte_flow_item *item __rte_unused,
+			 struct ulp_rte_parser_params *params __rte_unused)
+{
+	return BNXT_TF_RC_SUCCESS;
+}
+
 /* Function to handle the parsing of RTE Flow item void Header */
 int32_t
 ulp_rte_void_hdr_handler(const struct rte_flow_item *item __rte_unused,
@@ -1879,8 +1936,9 @@ ulp_rte_vf_act_handler(const struct rte_flow_action *action_item,
 		       struct ulp_rte_parser_params *params)
 {
 	const struct rte_flow_action_vf *vf_action;
-	uint32_t ifindex;
 	enum bnxt_ulp_intf_type intf_type;
+	uint32_t ifindex;
+	struct bnxt *bp;
 
 	vf_action = action_item->conf;
 	if (!vf_action) {
@@ -1893,12 +1951,23 @@ ulp_rte_vf_act_handler(const struct rte_flow_action *action_item,
 		return BNXT_TF_RC_PARSE_ERR;
 	}
 
-	/* Check the port is VF port */
-	if (ulp_port_db_dev_func_id_to_ulp_index(params->ulp_ctx, vf_action->id,
+	bp = bnxt_get_bp(params->port_id);
+	if (bp == NULL) {
+		BNXT_TF_DBG(ERR, "Invalid bp\n");
+		return BNXT_TF_RC_ERROR;
+	}
+
+	/* vf_action->id is a logical number which in this case is an
+	 * offset from the first VF. So, to get the absolute VF id, the
+	 * offset must be added to the absolute first vf id of that port.
+	 */
+	if (ulp_port_db_dev_func_id_to_ulp_index(params->ulp_ctx,
+						 bp->first_vf_id + vf_action->id,
 						 &ifindex)) {
 		BNXT_TF_DBG(ERR, "VF is not valid interface\n");
 		return BNXT_TF_RC_ERROR;
 	}
+	/* Check the port is VF port */
 	intf_type = ulp_port_db_port_type_get(params->ulp_ctx, ifindex);
 	if (intf_type != BNXT_ULP_INTF_TYPE_VF &&
 	    intf_type != BNXT_ULP_INTF_TYPE_TRUSTED_VF) {
diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
index 7996317903..cb9ae02371 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.h
@@ -126,6 +126,15 @@ int32_t
 ulp_rte_vxlan_hdr_handler(const struct rte_flow_item *item,
 			  struct ulp_rte_parser_params *params);
 
+/* Function to handle the parsing of RTE Flow item GRE Header. */
+int32_t
+ulp_rte_gre_hdr_handler(const struct rte_flow_item *item,
+			struct ulp_rte_parser_params *params);
+
+int32_t
+ulp_rte_item_any_handler(const struct rte_flow_item *item __rte_unused,
+			 struct ulp_rte_parser_params *params __rte_unused);
+
 /* Function to handle the parsing of RTE Flow item void Header. */
 int32_t
 ulp_rte_void_hdr_handler(const struct rte_flow_item *item,
diff --git a/drivers/net/bnxt/tf_ulp/ulp_template_struct.h b/drivers/net/bnxt/tf_ulp/ulp_template_struct.h
index 2950097685..5150ed2b07 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_template_struct.h
+++ b/drivers/net/bnxt/tf_ulp/ulp_template_struct.h
@@ -27,6 +27,7 @@
 #define BNXT_ULP_PROTO_HDR_UDP_NUM	4
 #define BNXT_ULP_PROTO_HDR_TCP_NUM	9
 #define BNXT_ULP_PROTO_HDR_VXLAN_NUM	4
+#define BNXT_ULP_PROTO_HDR_GRE_NUM	6
 #define BNXT_ULP_PROTO_HDR_MAX		128
 #define BNXT_ULP_PROTO_HDR_FIELD_SVIF_IDX	1
 
@@ -76,6 +77,7 @@ struct ulp_rte_parser_params {
 	uint32_t			parent_flow;
 	uint32_t			parent_fid;
 	uint16_t			func_id;
+	uint16_t			port_id;
 	uint32_t			class_id;
 	uint32_t			act_tmpl;
 	struct bnxt_ulp_context		*ulp_ctx;
