From: Ivan Malov Date: Thu, 5 Mar 2020 10:47:51 +0000 (+0000) Subject: net/sfc: generalise flow parsing X-Git-Url: http://git.droids-corp.org/?p=dpdk.git;a=commitdiff_plain;h=5b2b9236aacc5d4fcc4e950177ce5f4d32780c46 net/sfc: generalise flow parsing Generalise flow attribute parsing function in regard to transfer attribute. Add a method table and factor out VNIC-specific parsing code as a callback. Signed-off-by: Ivan Malov Signed-off-by: Andrew Rybchenko --- diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c index 2ddde6168c..ed91c3cefe 100644 --- a/drivers/net/sfc/sfc_flow.c +++ b/drivers/net/sfc/sfc_flow.c @@ -24,6 +24,34 @@ #include "sfc_log.h" #include "sfc_dp_rx.h" +struct sfc_flow_ops_by_spec { + sfc_flow_parse_cb_t *parse; +}; + +static sfc_flow_parse_cb_t sfc_flow_parse_rte_to_filter; + +static const struct sfc_flow_ops_by_spec sfc_flow_ops_filter = { + .parse = sfc_flow_parse_rte_to_filter, +}; + +static const struct sfc_flow_ops_by_spec * +sfc_flow_get_ops_by_spec(struct rte_flow *flow) +{ + struct sfc_flow_spec *spec = &flow->spec; + const struct sfc_flow_ops_by_spec *ops = NULL; + + switch (spec->type) { + case SFC_FLOW_SPEC_FILTER: + ops = &sfc_flow_ops_filter; + break; + default: + SFC_ASSERT(false); + break; + } + + return ops; +} + /* * Currently, filter-based (VNIC) flow API is implemented in such a manner * that each flow rule is converted to one or more hardware filters. @@ -1108,35 +1136,35 @@ sfc_flow_parse_attr(const struct rte_flow_attr *attr, "Groups are not supported"); return -rte_errno; } - if (attr->priority != 0) { - rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, attr, - "Priorities are not supported"); - return -rte_errno; - } if (attr->egress != 0) { rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, attr, "Egress is not supported"); return -rte_errno; } - if (attr->transfer != 0) { + if (attr->ingress == 0) { rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER, attr, - "Transfer is not supported"); + RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, attr, + "Ingress is compulsory"); return -rte_errno; } - if (attr->ingress == 0) { + if (attr->transfer == 0) { + if (attr->priority != 0) { + rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, + attr, "Priorities are unsupported"); + return -rte_errno; + } + spec->type = SFC_FLOW_SPEC_FILTER; + spec_filter->template.efs_flags |= EFX_FILTER_FLAG_RX; + spec_filter->template.efs_rss_context = EFX_RSS_CONTEXT_DEFAULT; + } else { rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, attr, - "Only ingress is supported"); + RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER, attr, + "Transfer is not supported"); return -rte_errno; } - spec->type = SFC_FLOW_SPEC_FILTER; - spec_filter->template.efs_flags |= EFX_FILTER_FLAG_RX; - spec_filter->template.efs_rss_context = EFX_RSS_CONTEXT_DEFAULT; - return 0; } @@ -2277,20 +2305,15 @@ sfc_flow_validate_match_flags(struct sfc_adapter *sa, } static int -sfc_flow_parse(struct rte_eth_dev *dev, - const struct rte_flow_attr *attr, - const struct rte_flow_item pattern[], - const struct rte_flow_action actions[], - struct rte_flow *flow, - struct rte_flow_error *error) +sfc_flow_parse_rte_to_filter(struct rte_eth_dev *dev, + const struct rte_flow_item pattern[], + 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); int rc; - rc = sfc_flow_parse_attr(attr, flow, error); - if (rc != 0) - goto fail_bad_value; - rc = sfc_flow_parse_pattern(pattern, flow, error); if (rc != 0) goto fail_bad_value; @@ -2309,6 +2332,32 @@ fail_bad_value: return rc; } +static int +sfc_flow_parse(struct rte_eth_dev *dev, + const struct rte_flow_attr *attr, + const struct rte_flow_item pattern[], + const struct rte_flow_action actions[], + struct rte_flow *flow, + struct rte_flow_error *error) +{ + const struct sfc_flow_ops_by_spec *ops; + int rc; + + rc = sfc_flow_parse_attr(attr, flow, error); + if (rc != 0) + return rc; + + ops = sfc_flow_get_ops_by_spec(flow); + if (ops == NULL || ops->parse == NULL) { + rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, + "No backend to handle this flow"); + return -rte_errno; + } + + return ops->parse(dev, pattern, actions, flow, error); +} + static struct rte_flow * sfc_flow_zmalloc(struct rte_flow_error *error) { diff --git a/drivers/net/sfc/sfc_flow.h b/drivers/net/sfc/sfc_flow.h index 70f0cdf12c..19db8fce50 100644 --- a/drivers/net/sfc/sfc_flow.h +++ b/drivers/net/sfc/sfc_flow.h @@ -85,6 +85,12 @@ void sfc_flow_fini(struct sfc_adapter *sa); int sfc_flow_start(struct sfc_adapter *sa); void sfc_flow_stop(struct sfc_adapter *sa); +typedef int (sfc_flow_parse_cb_t)(struct rte_eth_dev *dev, + const struct rte_flow_item items[], + const struct rte_flow_action actions[], + struct rte_flow *flow, + struct rte_flow_error *error); + #ifdef __cplusplus } #endif