@@ -343,6 +343,8 @@ enum index {
ACTION_SET_IPV4_DSCP_VALUE,
ACTION_SET_IPV6_DSCP,
ACTION_SET_IPV6_DSCP_VALUE,
+ ACTION_AGE,
+ ACTION_AGE_TIMEOUT,
};
/** Maximum size for pattern in struct rte_flow_item_raw. */
@@ -1145,6 +1147,7 @@ static const enum index next_action[] = {
ACTION_SET_META,
ACTION_SET_IPV4_DSCP,
ACTION_SET_IPV6_DSCP,
+ ACTION_AGE,
ZERO,
};
@@ -1370,6 +1373,13 @@ static const enum index action_set_ipv6_dscp[] = {
ZERO,
};
+static const enum index action_age[] = {
+ ACTION_AGE,
+ ACTION_AGE_TIMEOUT,
+ ACTION_NEXT,
+ ZERO,
+};
+
static int parse_set_raw_encap_decap(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
@@ -3694,6 +3704,22 @@ static const struct token token_list[] = {
(struct rte_flow_action_set_dscp, dscp)),
.call = parse_vc_conf,
},
+ [ACTION_AGE] = {
+ .name = "age",
+ .help = "set a specific metadata header",
+ .next = NEXT(action_age),
+ .priv = PRIV_ACTION(AGE,
+ sizeof(struct rte_flow_action_age)),
+ .call = parse_vc,
+ },
+ [ACTION_AGE_TIMEOUT] = {
+ .name = "timeout",
+ .help = "flow age timeout value",
+ .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_age,
+ timeout, 24)),
+ .next = NEXT(action_age, NEXT_ENTRY(UNSIGNED)),
+ .call = parse_vc_conf,
+ },
};
/** Remove and return last entry from argument stack. */
@@ -11,3 +11,7 @@
type_kind = enum
name = rte_crypto_asym_xform_type
changed_enumerators = RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
+[suppress_type]
+ type_kind = enum
+ name = rte_eth_event_type
+ changed_enumerators = RTE_ETH_EVENT_MAX
@@ -2616,6 +2616,28 @@ Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
| ``dscp`` | DSCP in low 6 bits, rest ignore |
+-----------+---------------------------------+
+Action: ``AGE``
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Set ageing timeout configuration to a flow.
+
+Event RTE_ETH_EVENT_FLOW_AGED will be reported if
+timeout passed without any matching on the flow.
+
+.. _table_rte_flow_action_age:
+
+.. table:: AGE
+
+ +--------------+---------------------------------+
+ | Field | Value |
+ +==============+=================================+
+ | ``timeout`` | 24 bits timeout value |
+ +--------------+---------------------------------+
+ | ``reserved`` | 8 bits reserved, must be zero |
+ +--------------+---------------------------------+
+ | ``context`` | user input flow context |
+ +--------------+---------------------------------+
+
Negative types
~~~~~~~~~~~~~~
@@ -135,6 +135,17 @@ New Features
by making use of the event device capabilities. The event mode currently supports
only inline IPsec protocol offload.
+* **Added flow Aging Support.**
+
+ Added flow Aging support to detect and report aged-out flows, including:
+
+ * Added new action: RTE_FLOW_ACTION_TYPE_AGE to set the timeout and the
+ application flow context for each flow.
+ * Added new event: RTE_ETH_EVENT_FLOW_AGED for the driver to report that
+ there are new aged-out flows.
+ * Added new API: rte_flow_get_aged_flows to get the aged-out flows contexts
+ from the port.
+
Removed Items
-------------
@@ -3018,6 +3018,7 @@ enum rte_eth_event_type {
RTE_ETH_EVENT_NEW, /**< port is probed */
RTE_ETH_EVENT_DESTROY, /**< port is released */
RTE_ETH_EVENT_IPSEC, /**< IPsec offload related event */
+ RTE_ETH_EVENT_FLOW_AGED,/**< New aged-out flows is detected */
RTE_ETH_EVENT_MAX /**< max value of this enum */
};
@@ -230,4 +230,7 @@ EXPERIMENTAL {
# added in 20.02
rte_flow_dev_dump;
+
+ # added in 20.05
+ rte_flow_get_aged_flows;
};
@@ -172,6 +172,7 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = {
MK_FLOW_ACTION(SET_META, sizeof(struct rte_flow_action_set_meta)),
MK_FLOW_ACTION(SET_IPV4_DSCP, sizeof(struct rte_flow_action_set_dscp)),
MK_FLOW_ACTION(SET_IPV6_DSCP, sizeof(struct rte_flow_action_set_dscp)),
+ MK_FLOW_ACTION(AGE, sizeof(struct rte_flow_action_age)),
};
int
@@ -1232,3 +1233,20 @@ rte_flow_dev_dump(uint16_t port_id, FILE *file, struct rte_flow_error *error)
RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
NULL, rte_strerror(ENOSYS));
}
+
+int
+rte_flow_get_aged_flows(uint16_t port_id, void **contexts,
+ uint32_t nb_contexts, 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->get_aged_flows))
+ return flow_err(port_id, ops->get_aged_flows(dev, contexts,
+ nb_contexts, error), error);
+ return rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+ NULL, rte_strerror(ENOTSUP));
+}
@@ -2081,6 +2081,16 @@ enum rte_flow_action_type {
* See struct rte_flow_action_set_dscp.
*/
RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP,
+
+ /**
+ * Report as aged flow if timeout passed without any matching on the
+ * flow.
+ *
+ * See struct rte_flow_action_age.
+ * See function rte_flow_get_aged_flows
+ * see enum RTE_ETH_EVENT_FLOW_AGED
+ */
+ RTE_FLOW_ACTION_TYPE_AGE,
};
/**
@@ -2122,6 +2132,25 @@ struct rte_flow_action_queue {
uint16_t index; /**< Queue index to use. */
};
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ACTION_TYPE_AGE
+ *
+ * Report flow as aged-out if timeout passed without any matching
+ * on the flow. RTE_ETH_EVENT_FLOW_AGED event is triggered when a
+ * port detects new aged-out flows.
+ *
+ * The flow context and the flow handle will be reported by the
+ * rte_flow_get_aged_flows API.
+ */
+struct rte_flow_action_age {
+ uint32_t timeout:24; /**< Time in seconds. */
+ uint32_t reserved:8; /**< Reserved, must be zero. */
+ void *context;
+ /**< The user flow context, NULL means the rte_flow pointer. */
+};
/**
* @warning
@@ -3254,6 +3283,39 @@ rte_flow_conv(enum rte_flow_conv_op op,
const void *src,
struct rte_flow_error *error);
+/**
+ * Get aged-out flows of a given port.
+ *
+ * RTE_ETH_EVENT_FLOW_AGED event will be triggered when at least one new aged
+ * out flow was detected after the last call to rte_flow_get_aged_flows.
+ * This function can be called to get the aged flows usynchronously from the
+ * event callback or synchronously regardless the event.
+ * This is not safe to call rte_flow_get_aged_flows function with other flow
+ * functions from multiple threads simultaneously.
+ *
+ * @param port_id
+ * Port identifier of Ethernet device.
+ * @param[in, out] contexts
+ * The address of an array of pointers to the aged-out flows contexts.
+ * @param[in] nb_contexts
+ * The length of context array pointers.
+ * @param[out] error
+ * Perform verbose error reporting if not NULL. Initialized in case of
+ * error only.
+ *
+ * @return
+ * if nb_contexts is 0, return the amount of all aged contexts.
+ * if nb_contexts is not 0 , return the amount of aged flows reported
+ * in the context array, otherwise negative errno value.
+ *
+ * @see rte_flow_action_age
+ * @see RTE_ETH_EVENT_FLOW_AGED
+ */
+__rte_experimental
+int
+rte_flow_get_aged_flows(uint16_t port_id, void **contexts,
+ uint32_t nb_contexts, struct rte_flow_error *error);
+
#ifdef __cplusplus
}
#endif
@@ -101,6 +101,12 @@ struct rte_flow_ops {
(struct rte_eth_dev *dev,
FILE *file,
struct rte_flow_error *error);
+ /** See rte_flow_get_aged_flows() */
+ int (*get_aged_flows)
+ (struct rte_eth_dev *dev,
+ void **context,
+ uint32_t nb_contexts,
+ struct rte_flow_error *err);
};
/**