From 7a25bc98712b6a62f493fd17a62669a6068d4298 Mon Sep 17 00:00:00 2001 From: Ivan Malov Date: Tue, 20 Oct 2020 10:12:49 +0100 Subject: [PATCH] net/sfc: add pattern parsing stub to MAE backend 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 Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/net/sfc/sfc_flow.c | 41 +++++++++++++++++++++++- drivers/net/sfc/sfc_flow.h | 8 +++++ drivers/net/sfc/sfc_mae.c | 65 ++++++++++++++++++++++++++++++++++++++ drivers/net/sfc/sfc_mae.h | 10 ++++++ 4 files changed, 123 insertions(+), 1 deletion(-) diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c index 86082208d0..634818cdf2 100644 --- a/drivers/net/sfc/sfc_flow.c +++ b/drivers/net/sfc/sfc_flow.c @@ -27,20 +27,30 @@ 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); } diff --git a/drivers/net/sfc/sfc_flow.h b/drivers/net/sfc/sfc_flow.h index 1fbcb878d1..03a68d8633 100644 --- a/drivers/net/sfc/sfc_flow.h +++ b/drivers/net/sfc/sfc_flow.h @@ -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); diff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c index 487bd61f76..53e141775a 100644 --- a/drivers/net/sfc/sfc_mae.c +++ b/drivers/net/sfc/sfc_mae.c @@ -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; +} diff --git a/drivers/net/sfc/sfc_mae.h b/drivers/net/sfc/sfc_mae.h index dd9ca07d15..536dadd092 100644 --- a/drivers/net/sfc/sfc_mae.h +++ b/drivers/net/sfc/sfc_mae.h @@ -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 } -- 2.20.1