diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
index 4acf75781d..81be991191 100644
--- a/lib/ethdev/ethdev_driver.h
+++ b/lib/ethdev/ethdev_driver.h
@@ -1707,6 +1707,14 @@ int
 rte_eth_hairpin_queue_peer_unbind(uint16_t cur_port, uint16_t cur_queue,
 				  uint32_t direction);
 
+/**
+ * @internal
+ * Register mbuf dynamic field and flag for IP reassembly incomplete case.
+ */
+__rte_internal
+int
+rte_eth_ip_reassembly_dynfield_register(int *field_offset, int *flag);
+
 
 /*
  * Legacy ethdev API used internally by drivers.
diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index 6b37cffd07..a707f395c4 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -6570,6 +6570,34 @@ rte_eth_ip_reassembly_conf_set(uint16_t port_id,
 		       (*dev->dev_ops->ip_reassembly_conf_set)(dev, conf));
 }
 
+int
+rte_eth_ip_reassembly_dynfield_register(int *field_offset, int *flag_offset)
+{
+	static const struct rte_mbuf_dynfield field_desc = {
+		.name = RTE_MBUF_DYNFIELD_IP_REASSEMBLY_NAME,
+		.size = sizeof(rte_eth_ip_reassembly_dynfield_t),
+		.align = __alignof__(rte_eth_ip_reassembly_dynfield_t),
+	};
+	static const struct rte_mbuf_dynflag ip_reassembly_dynflag = {
+		.name = RTE_MBUF_DYNFLAG_IP_REASSEMBLY_INCOMPLETE_NAME,
+	};
+	int offset;
+
+	offset = rte_mbuf_dynfield_register(&field_desc);
+	if (offset < 0)
+		return -1;
+	if (field_offset != NULL)
+		*field_offset = offset;
+
+	offset = rte_mbuf_dynflag_register(&ip_reassembly_dynflag);
+	if (offset < 0)
+		return -1;
+	if (flag_offset != NULL)
+		*flag_offset = offset;
+
+	return 0;
+}
+
 RTE_LOG_REGISTER_DEFAULT(rte_eth_dev_logtype, INFO);
 
 RTE_INIT(ethdev_init_telemetry)
diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
index dd416fda37..b2c41ceb9a 100644
--- a/lib/ethdev/rte_ethdev.h
+++ b/lib/ethdev/rte_ethdev.h
@@ -5285,6 +5285,12 @@ int rte_eth_ip_reassembly_conf_get(uint16_t port_id,
  * configuration. The use of this API is mandatory to enable this feature and
  * should be called before rte_eth_dev_start().
  *
+ * In datapath, PMD cannot guarantee that IP reassembly is always successful.
+ * Hence, PMD shall register mbuf dynamic field and dynamic flag using
+ * rte_eth_ip_reassembly_dynfield_register() to denote incomplete IP reassembly.
+ * If dynfield is not successfully registered, error will be returned and
+ * IP reassembly offload cannnot be used.
+ *
  * @param port_id
  *   The port identifier of the device.
  * @param conf
@@ -5294,13 +5300,33 @@ int rte_eth_ip_reassembly_conf_get(uint16_t port_id,
  *   - (-ENODEV) if *port_id* invalid.
  *   - (-EIO) if device is removed.
  *   - (-EINVAL) if device is not configured or if device is already started or
- *               if *conf* passed is NULL.
+ *               if *conf* passed is NULL or if mbuf dynfield is not registered
+ *               successfully by the PMD.
  *   - (0) on success.
  */
 __rte_experimental
 int rte_eth_ip_reassembly_conf_set(uint16_t port_id,
 		const struct rte_eth_ip_reassembly_params *conf);
 
+/**
+ * In case of IP reassembly offload failure, packet will be updated with
+ * dynamic flag - RTE_MBUF_DYNFLAG_IP_REASSEMBLY_INCOMPLETE_NAME and packets
+ * will be returned without alteration.
+ * The application can retrieve the attached fragments using mbuf dynamic field
+ * RTE_MBUF_DYNFIELD_IP_REASSEMBLY_NAME.
+ */
+typedef struct {
+	/**
+	 * Next fragment packet. Application should fetch dynamic field of
+	 * each fragment until a NULL is received and nb_frags is 0.
+	 */
+	struct rte_mbuf *next_frag;
+	/** Time spent(in ms) by HW in waiting for further fragments. */
+	uint16_t time_spent;
+	/** Number of more fragments attached in mbuf dynamic fields. */
+	uint16_t nb_frags;
+} rte_eth_ip_reassembly_dynfield_t;
+
 
 #include <rte_ethdev_core.h>
 
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index e22c102818..b5499cd9b5 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -284,6 +284,7 @@ INTERNAL {
 	rte_eth_hairpin_queue_peer_bind;
 	rte_eth_hairpin_queue_peer_unbind;
 	rte_eth_hairpin_queue_peer_update;
+	rte_eth_ip_reassembly_dynfield_register;
 	rte_eth_representor_id_get;
 	rte_eth_switch_domain_alloc;
 	rte_eth_switch_domain_free;
diff --git a/lib/mbuf/rte_mbuf_dyn.h b/lib/mbuf/rte_mbuf_dyn.h
index 29abe8da53..1c948e996e 100644
--- a/lib/mbuf/rte_mbuf_dyn.h
+++ b/lib/mbuf/rte_mbuf_dyn.h
@@ -320,6 +320,15 @@ int rte_mbuf_dyn_rx_timestamp_register(int *field_offset, uint64_t *rx_flag);
  */
 int rte_mbuf_dyn_tx_timestamp_register(int *field_offset, uint64_t *tx_flag);
 
+/**
+ * For the PMDs which support IP reassembly of packets, PMD will updated the
+ * packet with RTE_MBUF_DYNFLAG_IP_REASSEMBLY_INCOMPLETE_NAME to denote that
+ * IP reassembly is incomplete and application can retrieve the packets back
+ * using RTE_MBUF_DYNFIELD_IP_REASSEMBLY_NAME.
+ */
+#define RTE_MBUF_DYNFIELD_IP_REASSEMBLY_NAME "rte_dynfield_ip_reassembly"
+#define RTE_MBUF_DYNFLAG_IP_REASSEMBLY_INCOMPLETE_NAME "rte_dynflag_ip_reassembly_incomplete"
+
 #ifdef __cplusplus
 }
 #endif
