From patchwork Wed Dec 20 21:34:48 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qi Zhang X-Patchwork-Id: 32543 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id EAE821B22E; Thu, 21 Dec 2017 05:44:36 +0100 (CET) Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by dpdk.org (Postfix) with ESMTP id 565DD1B21B for ; Thu, 21 Dec 2017 05:44:31 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Dec 2017 20:44:30 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.45,434,1508828400"; d="scan'208";a="17790361" Received: from dpdk27.sh.intel.com ([10.67.111.90]) by orsmga001.jf.intel.com with ESMTP; 20 Dec 2017 20:44:29 -0800 From: Qi Zhang To: adrien.mazarguil@6wind.com Cc: dev@dpdk.org, declan.doherty@intel.com, Qi Zhang Date: Wed, 20 Dec 2017 16:34:48 -0500 Message-Id: <1513805689-28202-5-git-send-email-qi.z.zhang@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1513805689-28202-1-git-send-email-qi.z.zhang@intel.com> References: <1513805689-28202-1-git-send-email-qi.z.zhang@intel.com> Subject: [dpdk-dev] [RFC 4/5] ether: Add flow timeout support X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 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 --- 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 *); }; /**