net/sfc: add pattern parsing stub to MAE backend
authorIvan Malov <ivan.malov@oktetlabs.ru>
Tue, 20 Oct 2020 09:12:49 +0000 (10:12 +0100)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 3 Nov 2020 22:24:24 +0000 (23:24 +0100)
Add pattern parsing stub, define and implement flow cleanup method.
The latter is needed to free any dynamic structures allocated
during flow parsing.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
drivers/net/sfc/sfc_flow.c
drivers/net/sfc/sfc_flow.h
drivers/net/sfc/sfc_mae.c
drivers/net/sfc/sfc_mae.h

index 8608220..634818c 100644 (file)
 
 struct sfc_flow_ops_by_spec {
        sfc_flow_parse_cb_t     *parse;
+       sfc_flow_cleanup_cb_t   *cleanup;
        sfc_flow_insert_cb_t    *insert;
        sfc_flow_remove_cb_t    *remove;
 };
 
 static sfc_flow_parse_cb_t sfc_flow_parse_rte_to_filter;
+static sfc_flow_parse_cb_t sfc_flow_parse_rte_to_mae;
 static sfc_flow_insert_cb_t sfc_flow_filter_insert;
 static sfc_flow_remove_cb_t sfc_flow_filter_remove;
 
 static const struct sfc_flow_ops_by_spec sfc_flow_ops_filter = {
        .parse = sfc_flow_parse_rte_to_filter,
+       .cleanup = NULL,
        .insert = sfc_flow_filter_insert,
        .remove = sfc_flow_filter_remove,
 };
 
+static const struct sfc_flow_ops_by_spec sfc_flow_ops_mae = {
+       .parse = sfc_flow_parse_rte_to_mae,
+       .cleanup = sfc_mae_flow_cleanup,
+       .insert = NULL,
+       .remove = NULL,
+};
+
 static const struct sfc_flow_ops_by_spec *
 sfc_flow_get_ops_by_spec(struct rte_flow *flow)
 {
@@ -51,6 +61,9 @@ sfc_flow_get_ops_by_spec(struct rte_flow *flow)
        case SFC_FLOW_SPEC_FILTER:
                ops = &sfc_flow_ops_filter;
                break;
+       case SFC_FLOW_SPEC_MAE:
+               ops = &sfc_flow_ops_mae;
+               break;
        default:
                SFC_ASSERT(false);
                break;
@@ -1184,6 +1197,7 @@ sfc_flow_parse_attr(struct sfc_adapter *sa,
                }
                spec->type = SFC_FLOW_SPEC_MAE;
                spec_mae->priority = attr->priority;
+               spec_mae->match_spec = NULL;
        }
 
        return 0;
@@ -2408,6 +2422,25 @@ fail_bad_value:
        return rc;
 }
 
+static int
+sfc_flow_parse_rte_to_mae(struct rte_eth_dev *dev,
+                         const struct rte_flow_item pattern[],
+                         __rte_unused const struct rte_flow_action actions[],
+                         struct rte_flow *flow,
+                         struct rte_flow_error *error)
+{
+       struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
+       struct sfc_flow_spec *spec = &flow->spec;
+       struct sfc_flow_spec_mae *spec_mae = &spec->mae;
+       int rc;
+
+       rc = sfc_mae_rule_parse_pattern(sa, pattern, spec_mae, error);
+       if (rc != 0)
+               return rc;
+
+       return 0;
+}
+
 static int
 sfc_flow_parse(struct rte_eth_dev *dev,
               const struct rte_flow_attr *attr,
@@ -2451,8 +2484,14 @@ sfc_flow_zmalloc(struct rte_flow_error *error)
 }
 
 static void
-sfc_flow_free(__rte_unused struct sfc_adapter *sa, struct rte_flow *flow)
+sfc_flow_free(struct sfc_adapter *sa, struct rte_flow *flow)
 {
+       const struct sfc_flow_ops_by_spec *ops;
+
+       ops = sfc_flow_get_ops_by_spec(flow);
+       if (ops != NULL && ops->cleanup != NULL)
+               ops->cleanup(sa, flow);
+
        rte_free(flow);
 }
 
index 1fbcb87..03a68d8 100644 (file)
@@ -63,6 +63,8 @@ struct sfc_flow_spec_filter {
 struct sfc_flow_spec_mae {
        /* Desired priority level */
        unsigned int                    priority;
+       /* EFX match specification */
+       efx_mae_match_spec_t            *match_spec;
 };
 
 /* Flow specification */
@@ -100,6 +102,7 @@ enum sfc_flow_item_layers {
 /* Flow parse context types */
 enum sfc_flow_parse_ctx_type {
        SFC_FLOW_PARSE_CTX_FILTER = 0,
+       SFC_FLOW_PARSE_CTX_MAE,
 
        SFC_FLOW_PARSE_CTX_NTYPES
 };
@@ -112,6 +115,8 @@ struct sfc_flow_parse_ctx {
        union {
                /* Context pointer valid for filter-based (VNIC) flows */
                efx_filter_spec_t *filter;
+               /* Context pointer valid for MAE-based flows */
+               struct sfc_mae_parse_ctx *mae;
        };
 };
 
@@ -154,6 +159,9 @@ typedef int (sfc_flow_parse_cb_t)(struct rte_eth_dev *dev,
                                  struct rte_flow *flow,
                                  struct rte_flow_error *error);
 
+typedef void (sfc_flow_cleanup_cb_t)(struct sfc_adapter *sa,
+                                    struct rte_flow *flow);
+
 typedef int (sfc_flow_insert_cb_t)(struct sfc_adapter *sa,
                                   struct rte_flow *flow);
 
index 487bd61..53e1417 100644 (file)
@@ -75,3 +75,68 @@ sfc_mae_detach(struct sfc_adapter *sa)
 
        sfc_log_init(sa, "done");
 }
+
+void
+sfc_mae_flow_cleanup(struct sfc_adapter *sa,
+                    struct rte_flow *flow)
+{
+       struct sfc_flow_spec *spec;
+       struct sfc_flow_spec_mae *spec_mae;
+
+       if (flow == NULL)
+               return;
+
+       spec = &flow->spec;
+
+       if (spec == NULL)
+               return;
+
+       spec_mae = &spec->mae;
+
+       if (spec_mae->match_spec != NULL)
+               efx_mae_match_spec_fini(sa->nic, spec_mae->match_spec);
+}
+
+static const struct sfc_flow_item sfc_flow_items[] = {
+};
+
+int
+sfc_mae_rule_parse_pattern(struct sfc_adapter *sa,
+                          const struct rte_flow_item pattern[],
+                          struct sfc_flow_spec_mae *spec,
+                          struct rte_flow_error *error)
+{
+       struct sfc_mae_parse_ctx ctx_mae;
+       struct sfc_flow_parse_ctx ctx;
+       int rc;
+
+       memset(&ctx_mae, 0, sizeof(ctx_mae));
+
+       rc = efx_mae_match_spec_init(sa->nic, EFX_MAE_RULE_ACTION,
+                                    spec->priority,
+                                    &ctx_mae.match_spec_action);
+       if (rc != 0) {
+               rc = rte_flow_error_set(error, rc,
+                       RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+                       "Failed to initialise action rule match specification");
+               goto fail_init_match_spec_action;
+       }
+
+       ctx.type = SFC_FLOW_PARSE_CTX_MAE;
+       ctx.mae = &ctx_mae;
+
+       rc = sfc_flow_parse_pattern(sfc_flow_items, RTE_DIM(sfc_flow_items),
+                                   pattern, &ctx, error);
+       if (rc != 0)
+               goto fail_parse_pattern;
+
+       spec->match_spec = ctx_mae.match_spec_action;
+
+       return 0;
+
+fail_parse_pattern:
+       efx_mae_match_spec_fini(sa->nic, ctx_mae.match_spec_action);
+
+fail_init_match_spec_action:
+       return rc;
+}
index dd9ca07..536dadd 100644 (file)
@@ -33,9 +33,19 @@ struct sfc_mae {
 };
 
 struct sfc_adapter;
+struct sfc_flow_spec;
+
+struct sfc_mae_parse_ctx {
+       efx_mae_match_spec_t            *match_spec_action;
+};
 
 int sfc_mae_attach(struct sfc_adapter *sa);
 void sfc_mae_detach(struct sfc_adapter *sa);
+sfc_flow_cleanup_cb_t sfc_mae_flow_cleanup;
+int sfc_mae_rule_parse_pattern(struct sfc_adapter *sa,
+                              const struct rte_flow_item pattern[],
+                              struct sfc_flow_spec_mae *spec,
+                              struct rte_flow_error *error);
 
 #ifdef __cplusplus
 }