From 2e2e5bdf908ef7ce6ba7a33be5bec6f42f4a39fe Mon Sep 17 00:00:00 2001 From: Ivan Malov Date: Thu, 5 Mar 2020 10:47:53 +0000 Subject: [PATCH] net/sfc: generalise flow pattern item processing This is needed to reuse pattern processing engine for MAE. Signed-off-by: Ivan Malov Signed-off-by: Andrew Rybchenko --- drivers/net/sfc/sfc_flow.c | 101 ++++++++++++++++++++++--------------- drivers/net/sfc/sfc_flow.h | 52 +++++++++++++++++++ 2 files changed, 111 insertions(+), 42 deletions(-) diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c index b95acff31c..ec0ca3cd6b 100644 --- a/drivers/net/sfc/sfc_flow.c +++ b/drivers/net/sfc/sfc_flow.c @@ -69,25 +69,6 @@ sfc_flow_get_ops_by_spec(struct rte_flow *flow) * of such a field. */ -enum sfc_flow_item_layers { - SFC_FLOW_ITEM_ANY_LAYER, - SFC_FLOW_ITEM_START_LAYER, - SFC_FLOW_ITEM_L2, - SFC_FLOW_ITEM_L3, - SFC_FLOW_ITEM_L4, -}; - -typedef int (sfc_flow_item_parse)(const struct rte_flow_item *item, - efx_filter_spec_t *spec, - struct rte_flow_error *error); - -struct sfc_flow_item { - enum rte_flow_item_type type; /* Type of item */ - enum sfc_flow_item_layers layer; /* Layer of item */ - enum sfc_flow_item_layers prev_layer; /* Previous layer of item */ - sfc_flow_item_parse *parse; /* Parsing function */ -}; - static sfc_flow_item_parse sfc_flow_parse_void; static sfc_flow_item_parse sfc_flow_parse_eth; static sfc_flow_item_parse sfc_flow_parse_vlan; @@ -144,7 +125,7 @@ sfc_flow_is_zero(const uint8_t *buf, unsigned int size) /* * Validate item and prepare structures spec and mask for parsing */ -static int +int sfc_flow_parse_init(const struct rte_flow_item *item, const void **spec_ptr, const void **mask_ptr, @@ -243,7 +224,7 @@ exit: static int sfc_flow_parse_void(__rte_unused const struct rte_flow_item *item, - __rte_unused efx_filter_spec_t *efx_spec, + __rte_unused struct sfc_flow_parse_ctx *parse_ctx, __rte_unused struct rte_flow_error *error) { return 0; @@ -265,10 +246,11 @@ sfc_flow_parse_void(__rte_unused const struct rte_flow_item *item, */ static int sfc_flow_parse_eth(const struct rte_flow_item *item, - efx_filter_spec_t *efx_spec, + struct sfc_flow_parse_ctx *parse_ctx, struct rte_flow_error *error) { int rc; + efx_filter_spec_t *efx_spec = parse_ctx->filter; const struct rte_flow_item_eth *spec = NULL; const struct rte_flow_item_eth *mask = NULL; const struct rte_flow_item_eth supp_mask = { @@ -377,11 +359,12 @@ fail_bad_mask: */ static int sfc_flow_parse_vlan(const struct rte_flow_item *item, - efx_filter_spec_t *efx_spec, + struct sfc_flow_parse_ctx *parse_ctx, struct rte_flow_error *error) { int rc; uint16_t vid; + efx_filter_spec_t *efx_spec = parse_ctx->filter; const struct rte_flow_item_vlan *spec = NULL; const struct rte_flow_item_vlan *mask = NULL; const struct rte_flow_item_vlan supp_mask = { @@ -463,10 +446,11 @@ sfc_flow_parse_vlan(const struct rte_flow_item *item, */ static int sfc_flow_parse_ipv4(const struct rte_flow_item *item, - efx_filter_spec_t *efx_spec, + struct sfc_flow_parse_ctx *parse_ctx, struct rte_flow_error *error) { int rc; + efx_filter_spec_t *efx_spec = parse_ctx->filter; const struct rte_flow_item_ipv4 *spec = NULL; const struct rte_flow_item_ipv4 *mask = NULL; const uint16_t ether_type_ipv4 = rte_cpu_to_le_16(EFX_ETHER_TYPE_IPV4); @@ -553,10 +537,11 @@ fail_bad_mask: */ static int sfc_flow_parse_ipv6(const struct rte_flow_item *item, - efx_filter_spec_t *efx_spec, + struct sfc_flow_parse_ctx *parse_ctx, struct rte_flow_error *error) { int rc; + efx_filter_spec_t *efx_spec = parse_ctx->filter; const struct rte_flow_item_ipv6 *spec = NULL; const struct rte_flow_item_ipv6 *mask = NULL; const uint16_t ether_type_ipv6 = rte_cpu_to_le_16(EFX_ETHER_TYPE_IPV6); @@ -661,10 +646,11 @@ fail_bad_mask: */ static int sfc_flow_parse_tcp(const struct rte_flow_item *item, - efx_filter_spec_t *efx_spec, + struct sfc_flow_parse_ctx *parse_ctx, struct rte_flow_error *error) { int rc; + efx_filter_spec_t *efx_spec = parse_ctx->filter; const struct rte_flow_item_tcp *spec = NULL; const struct rte_flow_item_tcp *mask = NULL; const struct rte_flow_item_tcp supp_mask = { @@ -742,10 +728,11 @@ fail_bad_mask: */ static int sfc_flow_parse_udp(const struct rte_flow_item *item, - efx_filter_spec_t *efx_spec, + struct sfc_flow_parse_ctx *parse_ctx, struct rte_flow_error *error) { int rc; + efx_filter_spec_t *efx_spec = parse_ctx->filter; const struct rte_flow_item_udp *spec = NULL; const struct rte_flow_item_udp *mask = NULL; const struct rte_flow_item_udp supp_mask = { @@ -900,10 +887,11 @@ sfc_flow_set_efx_spec_vni_or_vsid(efx_filter_spec_t *efx_spec, */ static int sfc_flow_parse_vxlan(const struct rte_flow_item *item, - efx_filter_spec_t *efx_spec, + struct sfc_flow_parse_ctx *parse_ctx, struct rte_flow_error *error) { int rc; + efx_filter_spec_t *efx_spec = parse_ctx->filter; const struct rte_flow_item_vxlan *spec = NULL; const struct rte_flow_item_vxlan *mask = NULL; const struct rte_flow_item_vxlan supp_mask = { @@ -952,10 +940,11 @@ sfc_flow_parse_vxlan(const struct rte_flow_item *item, */ static int sfc_flow_parse_geneve(const struct rte_flow_item *item, - efx_filter_spec_t *efx_spec, + struct sfc_flow_parse_ctx *parse_ctx, struct rte_flow_error *error) { int rc; + efx_filter_spec_t *efx_spec = parse_ctx->filter; const struct rte_flow_item_geneve *spec = NULL; const struct rte_flow_item_geneve *mask = NULL; const struct rte_flow_item_geneve supp_mask = { @@ -1019,10 +1008,11 @@ sfc_flow_parse_geneve(const struct rte_flow_item *item, */ static int sfc_flow_parse_nvgre(const struct rte_flow_item *item, - efx_filter_spec_t *efx_spec, + struct sfc_flow_parse_ctx *parse_ctx, struct rte_flow_error *error) { int rc; + efx_filter_spec_t *efx_spec = parse_ctx->filter; const struct rte_flow_item_nvgre *spec = NULL; const struct rte_flow_item_nvgre *mask = NULL; const struct rte_flow_item_nvgre supp_mask = { @@ -1061,60 +1051,70 @@ static const struct sfc_flow_item sfc_flow_items[] = { .type = RTE_FLOW_ITEM_TYPE_VOID, .prev_layer = SFC_FLOW_ITEM_ANY_LAYER, .layer = SFC_FLOW_ITEM_ANY_LAYER, + .ctx_type = SFC_FLOW_PARSE_CTX_FILTER, .parse = sfc_flow_parse_void, }, { .type = RTE_FLOW_ITEM_TYPE_ETH, .prev_layer = SFC_FLOW_ITEM_START_LAYER, .layer = SFC_FLOW_ITEM_L2, + .ctx_type = SFC_FLOW_PARSE_CTX_FILTER, .parse = sfc_flow_parse_eth, }, { .type = RTE_FLOW_ITEM_TYPE_VLAN, .prev_layer = SFC_FLOW_ITEM_L2, .layer = SFC_FLOW_ITEM_L2, + .ctx_type = SFC_FLOW_PARSE_CTX_FILTER, .parse = sfc_flow_parse_vlan, }, { .type = RTE_FLOW_ITEM_TYPE_IPV4, .prev_layer = SFC_FLOW_ITEM_L2, .layer = SFC_FLOW_ITEM_L3, + .ctx_type = SFC_FLOW_PARSE_CTX_FILTER, .parse = sfc_flow_parse_ipv4, }, { .type = RTE_FLOW_ITEM_TYPE_IPV6, .prev_layer = SFC_FLOW_ITEM_L2, .layer = SFC_FLOW_ITEM_L3, + .ctx_type = SFC_FLOW_PARSE_CTX_FILTER, .parse = sfc_flow_parse_ipv6, }, { .type = RTE_FLOW_ITEM_TYPE_TCP, .prev_layer = SFC_FLOW_ITEM_L3, .layer = SFC_FLOW_ITEM_L4, + .ctx_type = SFC_FLOW_PARSE_CTX_FILTER, .parse = sfc_flow_parse_tcp, }, { .type = RTE_FLOW_ITEM_TYPE_UDP, .prev_layer = SFC_FLOW_ITEM_L3, .layer = SFC_FLOW_ITEM_L4, + .ctx_type = SFC_FLOW_PARSE_CTX_FILTER, .parse = sfc_flow_parse_udp, }, { .type = RTE_FLOW_ITEM_TYPE_VXLAN, .prev_layer = SFC_FLOW_ITEM_L4, .layer = SFC_FLOW_ITEM_START_LAYER, + .ctx_type = SFC_FLOW_PARSE_CTX_FILTER, .parse = sfc_flow_parse_vxlan, }, { .type = RTE_FLOW_ITEM_TYPE_GENEVE, .prev_layer = SFC_FLOW_ITEM_L4, .layer = SFC_FLOW_ITEM_START_LAYER, + .ctx_type = SFC_FLOW_PARSE_CTX_FILTER, .parse = sfc_flow_parse_geneve, }, { .type = RTE_FLOW_ITEM_TYPE_NVGRE, .prev_layer = SFC_FLOW_ITEM_L3, .layer = SFC_FLOW_ITEM_START_LAYER, + .ctx_type = SFC_FLOW_PARSE_CTX_FILTER, .parse = sfc_flow_parse_nvgre, }, }; @@ -1176,28 +1176,30 @@ sfc_flow_parse_attr(const struct rte_flow_attr *attr, /* Get item from array sfc_flow_items */ static const struct sfc_flow_item * -sfc_flow_get_item(enum rte_flow_item_type type) +sfc_flow_get_item(const struct sfc_flow_item *items, + unsigned int nb_items, + enum rte_flow_item_type type) { unsigned int i; - for (i = 0; i < RTE_DIM(sfc_flow_items); i++) - if (sfc_flow_items[i].type == type) - return &sfc_flow_items[i]; + for (i = 0; i < nb_items; i++) + if (items[i].type == type) + return &items[i]; return NULL; } -static int -sfc_flow_parse_pattern(const struct rte_flow_item pattern[], - struct rte_flow *flow, +int +sfc_flow_parse_pattern(const struct sfc_flow_item *flow_items, + unsigned int nb_flow_items, + const struct rte_flow_item pattern[], + struct sfc_flow_parse_ctx *parse_ctx, struct rte_flow_error *error) { int rc; unsigned int prev_layer = SFC_FLOW_ITEM_ANY_LAYER; boolean_t is_ifrm = B_FALSE; const struct sfc_flow_item *item; - struct sfc_flow_spec *spec = &flow->spec; - struct sfc_flow_spec_filter *spec_filter = &spec->filter; if (pattern == NULL) { rte_flow_error_set(error, EINVAL, @@ -1207,7 +1209,8 @@ sfc_flow_parse_pattern(const struct rte_flow_item pattern[], } for (; pattern->type != RTE_FLOW_ITEM_TYPE_END; pattern++) { - item = sfc_flow_get_item(pattern->type); + item = sfc_flow_get_item(flow_items, nb_flow_items, + pattern->type); if (item == NULL) { rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, pattern, @@ -1262,7 +1265,14 @@ sfc_flow_parse_pattern(const struct rte_flow_item pattern[], break; } - rc = item->parse(pattern, &spec_filter->template, error); + if (parse_ctx->type != item->ctx_type) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, pattern, + "Parse context type mismatch"); + return -rte_errno; + } + + rc = item->parse(pattern, parse_ctx, error); if (rc != 0) return rc; @@ -2318,9 +2328,16 @@ sfc_flow_parse_rte_to_filter(struct rte_eth_dev *dev, 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_filter *spec_filter = &spec->filter; + struct sfc_flow_parse_ctx ctx; int rc; - rc = sfc_flow_parse_pattern(pattern, flow, error); + ctx.type = SFC_FLOW_PARSE_CTX_FILTER; + ctx.filter = &spec_filter->template; + + rc = sfc_flow_parse_pattern(sfc_flow_items, RTE_DIM(sfc_flow_items), + pattern, &ctx, error); if (rc != 0) goto fail_bad_value; diff --git a/drivers/net/sfc/sfc_flow.h b/drivers/net/sfc/sfc_flow.h index 5d87212c15..0a87924b23 100644 --- a/drivers/net/sfc/sfc_flow.h +++ b/drivers/net/sfc/sfc_flow.h @@ -78,6 +78,58 @@ TAILQ_HEAD(sfc_flow_list, rte_flow); extern const struct rte_flow_ops sfc_flow_ops; +enum sfc_flow_item_layers { + SFC_FLOW_ITEM_ANY_LAYER, + SFC_FLOW_ITEM_START_LAYER, + SFC_FLOW_ITEM_L2, + SFC_FLOW_ITEM_L3, + SFC_FLOW_ITEM_L4, +}; + +/* Flow parse context types */ +enum sfc_flow_parse_ctx_type { + SFC_FLOW_PARSE_CTX_FILTER = 0, + + SFC_FLOW_PARSE_CTX_NTYPES +}; + +/* Flow parse context */ +struct sfc_flow_parse_ctx { + enum sfc_flow_parse_ctx_type type; + + RTE_STD_C11 + union { + /* Context pointer valid for filter-based (VNIC) flows */ + efx_filter_spec_t *filter; + }; +}; + +typedef int (sfc_flow_item_parse)(const struct rte_flow_item *item, + struct sfc_flow_parse_ctx *parse_ctx, + struct rte_flow_error *error); + +struct sfc_flow_item { + enum rte_flow_item_type type; /* Type of item */ + enum sfc_flow_item_layers layer; /* Layer of item */ + enum sfc_flow_item_layers prev_layer; /* Previous layer of item */ + enum sfc_flow_parse_ctx_type ctx_type; /* Parse context type */ + sfc_flow_item_parse *parse; /* Parsing function */ +}; + +int sfc_flow_parse_pattern(const struct sfc_flow_item *flow_items, + unsigned int nb_flow_items, + const struct rte_flow_item pattern[], + struct sfc_flow_parse_ctx *parse_ctx, + struct rte_flow_error *error); + +int sfc_flow_parse_init(const struct rte_flow_item *item, + const void **spec_ptr, + const void **mask_ptr, + const void *supp_mask, + const void *def_mask, + unsigned int size, + struct rte_flow_error *error); + struct sfc_adapter; void sfc_flow_init(struct sfc_adapter *sa); -- 2.20.1