diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index dcea2f6..1a242fc 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -181,6 +181,14 @@ directions. At least one direction must be specified.
 Specifying both directions at once for a given rule is not recommended but
 may be valid in a few cases (e.g. shared counters).
 
+Attribute: Timeout
+^^^^^^^^^^^^^^^^^^
+
+Two kinds of timeout can be assigned to a flow rule. For "hard timeout", flow
+rule will be deleted when specific time duration  passed since it's creation.
+For "idle timeout", flow rule will be deleted when no packet hit in the given
+time duration.
+
 Pattern item
 ~~~~~~~~~~~~
 
@@ -1695,6 +1703,35 @@ definition.
                   void *data,
                   struct rte_flow_error *error);
 
+Is Active
+~~~~~~~~~
+
+Check if a flow is still active or not.
+
+It is possible a flow is be deleted automatically due to timeout, this function
+help to check if a flow is still exist.
+
+.. code-block:: c
+
+   int
+   rte_flow_is_active(uint8_t port_id,
+                      struct rte_flow *flow,
+                      uint8_t *active,
+                      struct rte_flow_error* error);
+
+Auto Delete Callback Set
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Register a callback function when flow is automatically deleted due to timeout.
+
+.. code-block:: c
+
+   int
+   rte_flow_auto_delete_callback_set(uint8_t port_id,
+                                     struct rte_flow *flow,
+                                     void (*callback)(struct rte_flow *),
+                                     struct rte_flow_error *error);
+
 Arguments:
 
 - ``port_id``: port identifier of Ethernet device.
diff --git a/lib/librte_ether/rte_flow.c b/lib/librte_ether/rte_flow.c
index 6659063..650c5a5 100644
--- a/lib/librte_ether/rte_flow.c
+++ b/lib/librte_ether/rte_flow.c
@@ -425,3 +425,41 @@ rte_flow_copy(struct rte_flow_desc *desc, size_t len,
 	}
 	return 0;
 }
+
+/** Check if a flow is stiall active or not. */
+int
+rte_flow_is_active(uint8_t port_id,
+		   struct rte_flow* flow,
+		   uint8_t *active,
+		   struct rte_flow_error* error)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
+
+	if (unlikely(!ops))
+		return -rte_errno;
+	if (likely(!!ops->is_active))
+		return ops->is_active(dev, flow, active, error);
+	return -rte_flow_error_set(error, ENOSYS,
+				   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				   NULL, rte_strerror(ENOSYS));
+}
+
+/** Register a callback function when flow is automatically deleted. */
+int
+rte_flow_auto_delete_callback_set(uint8_t port_id,
+				  struct rte_flow* flow,
+				  void (*callback)(struct rte_flow *),
+				  struct rte_flow_error* error)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
+
+	if (unlikely(!ops))
+		return -rte_errno;
+	if (likely(!!ops->auto_delete_callback_set))
+		return ops->auto_delete_callback_set(dev, flow, callback, error);
+	return -rte_flow_error_set(error, ENOSYS,
+				   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				   NULL, rte_strerror(ENOSYS));
+}
diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
index 8e902f0..e09e07f 100644
--- a/lib/librte_ether/rte_flow.h
+++ b/lib/librte_ether/rte_flow.h
@@ -97,6 +97,10 @@ struct rte_flow_attr {
 	uint32_t ingress:1; /**< Rule applies to ingress traffic. */
 	uint32_t egress:1; /**< Rule applies to egress traffic. */
 	uint32_t reserved:30; /**< Reserved, must be zero. */
+	uint32_t hard_timeout;
+	/**< If !0, flow will be deleted after given number of seconds. */
+	uint32_t idle_timeout;
+	/**< If !0, flow will be deleted if no packet hit in given seconds. */
 };
 
 /**
@@ -1491,6 +1495,51 @@ rte_flow_copy(struct rte_flow_desc *fd, size_t len,
 	      const struct rte_flow_item *items,
 	      const struct rte_flow_action *actions);
 
+/**
+ * Check if a flow is still active or not.
+ *
+ * @param port_id
+ *   Port identifier of Ethernet device.
+ * @param flow
+ *   Flow rule to check.
+ * @param[out] active
+ *   0 for not active, 1 for active.
+ * @param[out] error
+ *   Perform verbose error reporting if not NULL. PMDs initialize this
+ *   structure in case of error only.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int
+rte_flow_is_active(uint8_t port_id,
+		   struct rte_flow *flow,
+		   uint8_t *active,
+		   struct rte_flow_error *error);
+
+/**
+ * Register a callback function when flow is automatically deleted
+ * due to timeout
+ *
+ * @param port_id
+ *   Port identifier of Ethernet device.
+ * @param flow
+ *   Flow rule to track.
+ * @param callback
+ *   The callback function.
+ * @param[out] error
+ *   Perform verbose error reporting if not NULL. PMDs initialize this
+ *   structure in case of error only.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int
+rte_flow_auto_delete_callback_set(uint8_t port_id,
+				  struct rte_flow *flow,
+				  void (*callback)(struct rte_flow *),
+				  struct rte_flow_error *error);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_ether/rte_flow_driver.h b/lib/librte_ether/rte_flow_driver.h
index 254d1cb..862d8ab 100644
--- a/lib/librte_ether/rte_flow_driver.h
+++ b/lib/librte_ether/rte_flow_driver.h
@@ -124,6 +124,18 @@ struct rte_flow_ops {
 		(struct rte_eth_dev *,
 		 int,
 		 struct rte_flow_error *);
+	/** See rte_flow_ping(). */
+	int (*is_active)
+		(struct rte_eth_dev *,
+		 struct rte_flow *,
+		 uint8_t *,
+		 struct rte_flow_error *);
+	/** See rte_flow_delete(). */
+	int (*auto_delete_callback_set)
+		(struct rte_eth_dev *,
+		 struct rte_flow *,
+		 void (*)(struct rte_flow *),
+		 struct rte_flow_error *);
 };
 
 /**
