Add a new structure for indirect AGE update.

This new structure enables:
1. Update timeout value.
2. Stop AGE checking.
3. Start AGE checking.
4. restart AGE checking.

Signed-off-by: Michael Baum <michae...@nvidia.com>
Acked-by: Ori Kam <or...@nvidia.com>
---
 app/test-pmd/cmdline_flow.c        | 66 ++++++++++++++++++++++++++++++
 app/test-pmd/config.c              | 19 ++++++---
 doc/guides/prog_guide/rte_flow.rst | 25 +++++++++--
 lib/ethdev/rte_flow.h              | 28 +++++++++++++
 4 files changed, 129 insertions(+), 9 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 992aeb95b3..88108498e0 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -586,6 +586,9 @@ enum index {
        ACTION_SET_IPV6_DSCP_VALUE,
        ACTION_AGE,
        ACTION_AGE_TIMEOUT,
+       ACTION_AGE_UPDATE,
+       ACTION_AGE_UPDATE_TIMEOUT,
+       ACTION_AGE_UPDATE_TOUCH,
        ACTION_SAMPLE,
        ACTION_SAMPLE_RATIO,
        ACTION_SAMPLE_INDEX,
@@ -1874,6 +1877,7 @@ static const enum index next_action[] = {
        ACTION_SET_IPV4_DSCP,
        ACTION_SET_IPV6_DSCP,
        ACTION_AGE,
+       ACTION_AGE_UPDATE,
        ACTION_SAMPLE,
        ACTION_INDIRECT,
        ACTION_MODIFY_FIELD,
@@ -2110,6 +2114,14 @@ static const enum index action_age[] = {
        ZERO,
 };
 
+static const enum index action_age_update[] = {
+       ACTION_AGE_UPDATE,
+       ACTION_AGE_UPDATE_TIMEOUT,
+       ACTION_AGE_UPDATE_TOUCH,
+       ACTION_NEXT,
+       ZERO,
+};
+
 static const enum index action_sample[] = {
        ACTION_SAMPLE,
        ACTION_SAMPLE_RATIO,
@@ -2188,6 +2200,9 @@ static int parse_vc_spec(struct context *, const struct 
token *,
                         const char *, unsigned int, void *, unsigned int);
 static int parse_vc_conf(struct context *, const struct token *,
                         const char *, unsigned int, void *, unsigned int);
+static int parse_vc_conf_timeout(struct context *, const struct token *,
+                                const char *, unsigned int, void *,
+                                unsigned int);
 static int parse_vc_item_ecpri_type(struct context *, const struct token *,
                                    const char *, unsigned int,
                                    void *, unsigned int);
@@ -6206,6 +6221,30 @@ static const struct token token_list[] = {
                .next = NEXT(action_age, NEXT_ENTRY(COMMON_UNSIGNED)),
                .call = parse_vc_conf,
        },
+       [ACTION_AGE_UPDATE] = {
+               .name = "age_update",
+               .help = "update aging parameter",
+               .next = NEXT(action_age_update),
+               .priv = PRIV_ACTION(AGE,
+                                   sizeof(struct rte_flow_update_age)),
+               .call = parse_vc,
+       },
+       [ACTION_AGE_UPDATE_TIMEOUT] = {
+               .name = "timeout",
+               .help = "age timeout update value",
+               .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age,
+                                          timeout, 24)),
+               .next = NEXT(action_age_update, NEXT_ENTRY(COMMON_UNSIGNED)),
+               .call = parse_vc_conf_timeout,
+       },
+       [ACTION_AGE_UPDATE_TOUCH] = {
+               .name = "touch",
+               .help = "this flow is touched",
+               .next = NEXT(action_age_update, NEXT_ENTRY(COMMON_BOOLEAN)),
+               .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age,
+                                          touch, 1)),
+               .call = parse_vc_conf,
+       },
        [ACTION_SAMPLE] = {
                .name = "sample",
                .help = "set a sample action",
@@ -7045,6 +7084,33 @@ parse_vc_conf(struct context *ctx, const struct token 
*token,
        return len;
 }
 
+/** Parse action configuration field. */
+static int
+parse_vc_conf_timeout(struct context *ctx, const struct token *token,
+                     const char *str, unsigned int len,
+                     void *buf, unsigned int size)
+{
+       struct buffer *out = buf;
+       struct rte_flow_update_age *update;
+
+       (void)size;
+       if (ctx->curr != ACTION_AGE_UPDATE_TIMEOUT)
+               return -1;
+       /* Token name must match. */
+       if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+               return -1;
+       /* Nothing else to do if there is no buffer. */
+       if (!out)
+               return len;
+       /* Point to selected object. */
+       ctx->object = out->args.vc.data;
+       ctx->objmask = NULL;
+       /* Update the timeout is valid. */
+       update = (struct rte_flow_update_age *)out->args.vc.data;
+       update->timeout_valid = 1;
+       return len;
+}
+
 /** Parse eCPRI common header type field. */
 static int
 parse_vc_item_ecpri_type(struct context *ctx, const struct token *token,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 18f3543887..e8a1b77c2a 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -1886,6 +1886,7 @@ port_action_handle_update(portid_t port_id, uint32_t id,
        if (!pia)
                return -EINVAL;
        switch (pia->type) {
+       case RTE_FLOW_ACTION_TYPE_AGE:
        case RTE_FLOW_ACTION_TYPE_CONNTRACK:
                update = action->conf;
                break;
@@ -2816,17 +2817,23 @@ port_queue_action_handle_update(portid_t port_id,
                return -EINVAL;
        }
 
-       if (pia->type == RTE_FLOW_ACTION_TYPE_METER_MARK) {
+       switch (pia->type) {
+       case RTE_FLOW_ACTION_TYPE_AGE:
+               update = action->conf;
+               break;
+       case RTE_FLOW_ACTION_TYPE_METER_MARK:
                rte_memcpy(&mtr_update.meter_mark, action->conf,
                        sizeof(struct rte_flow_action_meter_mark));
                mtr_update.profile_valid = 1;
-               mtr_update.policy_valid  = 1;
-               mtr_update.color_mode_valid  = 1;
-               mtr_update.init_color_valid  = 1;
-               mtr_update.state_valid  = 1;
+               mtr_update.policy_valid = 1;
+               mtr_update.color_mode_valid = 1;
+               mtr_update.init_color_valid = 1;
+               mtr_update.state_valid = 1;
                update = &mtr_update;
-       } else {
+               break;
+       default:
                update = action;
+               break;
        }
 
        if (rte_flow_async_action_handle_update(port_id, queue_id, &attr,
diff --git a/doc/guides/prog_guide/rte_flow.rst 
b/doc/guides/prog_guide/rte_flow.rst
index 565868aeea..1ce0277e65 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -2737,7 +2737,7 @@ Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be 
returned.
 Action: ``AGE``
 ^^^^^^^^^^^^^^^
 
-Set ageing timeout configuration to a flow.
+Set aging timeout configuration to a flow.
 
 Event RTE_ETH_EVENT_FLOW_AGED will be reported if
 timeout passed without any matching on the flow.
@@ -2756,8 +2756,8 @@ timeout passed without any matching on the flow.
    | ``context``  | user input flow context         |
    +--------------+---------------------------------+
 
-Query structure to retrieve ageing status information of a
-shared AGE action, or a flow rule using the AGE action:
+Query structure to retrieve aging status information of an
+indirect AGE action, or a flow rule using the AGE action:
 
 .. _table_rte_flow_query_age:
 
@@ -2773,6 +2773,25 @@ shared AGE action, or a flow rule using the AGE action:
    | ``sec_since_last_hit``       | out | Seconds since last traffic hit       
  |
    
+------------------------------+-----+----------------------------------------+
 
+Update structure to modify the parameters of an indirect AGE action.
+The update structure is used by ``rte_flow_action_handle_update()`` function.
+
+.. _table_rte_flow_update_age:
+
+.. table:: AGE update
+
+   
+-------------------+--------------------------------------------------------------+
+   | Field             | Value                                                 
       |
+   
+===================+==============================================================+
+   | ``reserved``      | 6 bits reserved, must be zero                         
       |
+   
+-------------------+--------------------------------------------------------------+
+   | ``timeout_valid`` | 1 bit, timeout value is valid                         
       |
+   
+-------------------+--------------------------------------------------------------+
+   | ``timeout``       | 24 bits timeout value                                 
       |
+   
+-------------------+--------------------------------------------------------------+
+   | ``touch``         | 1 bit, touch the AGE action to set 
``sec_since_last_hit`` 0  |
+   
+-------------------+--------------------------------------------------------------+
+
 Action: ``SAMPLE``
 ^^^^^^^^^^^^^^^^^^
 
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 64ec8f0903..8858b56428 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -2643,6 +2643,7 @@ enum rte_flow_action_type {
         * See function rte_flow_get_aged_flows
         * see enum RTE_ETH_EVENT_FLOW_AGED
         * See struct rte_flow_query_age
+        * See struct rte_flow_update_age
         */
        RTE_FLOW_ACTION_TYPE_AGE,
 
@@ -2809,6 +2810,33 @@ struct rte_flow_query_age {
        uint32_t sec_since_last_hit:24; /**< Seconds since last traffic hit. */
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ACTION_TYPE_AGE
+ *
+ * Update indirect AGE action attributes:
+ *  - Timeout can be updated including stop/start action:
+ *     +-------------+-------------+------------------------------+
+ *     | Old Timeout | New Timeout | Updating                     |
+ *     +=============+=============+==============================+
+ *     | 0           | positive    | Start aging with new value   |
+ *     +-------------+-------------+------------------------------+
+ *     | positive    | 0           | Stop aging                          |
+ *     +-------------+-------------+------------------------------+
+ *     | positive    | positive    | Change timeout to new value  |
+ *     +-------------+-------------+------------------------------+
+ *  - sec_since_last_hit can be reset.
+ */
+struct rte_flow_update_age {
+       uint32_t reserved:6; /**< Reserved, must be zero. */
+       uint32_t timeout_valid:1; /**< The timeout is valid for update. */
+       uint32_t timeout:24; /**< Time in seconds. */
+       /** Means that aging should assume packet passed the aging. */
+       uint32_t touch:1;
+};
+
 /**
  * @warning
  * @b EXPERIMENTAL: this structure may change without prior notice
-- 
2.25.1

Reply via email to