[dpdk-dev] [RFC 4/5] ether: Add flow timeout support
Qi Zhang
qi.z.zhang at intel.com
Wed Dec 20 22:34:48 CET 2017
Add new APIs to support flow timeout, application is able to
1. Setup the time duration of a flow, the flow is expected to be deleted
automatically when timeout.
2. Ping a flow to check if it is active or not.
3. Register a callback function when a flow is deleted due to timeout.
Signed-off-by: Qi Zhang <qi.z.zhang at intel.com>
---
doc/guides/prog_guide/rte_flow.rst | 37 ++++++++++++++++++++++++++++
lib/librte_ether/rte_flow.c | 38 +++++++++++++++++++++++++++++
lib/librte_ether/rte_flow.h | 49 ++++++++++++++++++++++++++++++++++++++
lib/librte_ether/rte_flow_driver.h | 12 ++++++++++
4 files changed, 136 insertions(+)
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 *);
};
/**
--
2.7.4
More information about the dev
mailing list