From: Ivan Malov <ivan.ma...@oktetlabs.ru> 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.ma...@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <arybche...@solarflare.com> Reviewed-by: Andy Moreton <amore...@xilinx.com> --- 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 @@ sfc_flow_parse_rte_to_filter(struct rte_eth_dev *dev, 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.17.1