X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fsfc%2Fsfc_flow.c;h=0bfd284c9ee08ba23be070e9c96103a0c63c7baa;hb=c5d06df44f7ee22ab6892f8d47d7373dee5a4973;hp=f4d53bf770ef18b2c4cc753535f4a5e817a81806;hpb=662286ae61d29fc6fa26ce131f378ac8905eaff9;p=dpdk.git diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c index f4d53bf770..0bfd284c9e 100644 --- a/drivers/net/sfc/sfc_flow.c +++ b/drivers/net/sfc/sfc_flow.c @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: BSD-3-Clause * - * Copyright(c) 2019-2020 Xilinx, Inc. + * Copyright(c) 2019-2021 Xilinx, Inc. * Copyright(c) 2017-2019 Solarflare Communications Inc. * * This software was jointly developed between OKTET Labs (under contract @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include @@ -50,8 +50,8 @@ static const struct sfc_flow_ops_by_spec sfc_flow_ops_mae = { .parse = sfc_flow_parse_rte_to_mae, .verify = sfc_mae_flow_verify, .cleanup = sfc_mae_flow_cleanup, - .insert = NULL, - .remove = NULL, + .insert = sfc_mae_flow_insert, + .remove = sfc_mae_flow_remove, }; static const struct sfc_flow_ops_by_spec * @@ -96,6 +96,7 @@ static sfc_flow_item_parse sfc_flow_parse_udp; static sfc_flow_item_parse sfc_flow_parse_vxlan; static sfc_flow_item_parse sfc_flow_parse_geneve; static sfc_flow_item_parse sfc_flow_parse_nvgre; +static sfc_flow_item_parse sfc_flow_parse_pppoex; typedef int (sfc_flow_spec_set_vals)(struct sfc_flow_spec *spec, unsigned int filters_count_for_one_val, @@ -1063,6 +1064,63 @@ sfc_flow_parse_nvgre(const struct rte_flow_item *item, return rc; } +/** + * Convert PPPoEx item to EFX filter specification. + * + * @param item[in] + * Item specification. + * Matching on PPPoEx fields is not supported. + * This item can only be used to set or validate the EtherType filter. + * Only zero masks are allowed. + * Ranging is not supported. + * @param efx_spec[in, out] + * EFX filter specification to update. + * @param[out] error + * Perform verbose error reporting if not NULL. + */ +static int +sfc_flow_parse_pppoex(const struct rte_flow_item *item, + struct sfc_flow_parse_ctx *parse_ctx, + struct rte_flow_error *error) +{ + efx_filter_spec_t *efx_spec = parse_ctx->filter; + const struct rte_flow_item_pppoe *spec = NULL; + const struct rte_flow_item_pppoe *mask = NULL; + const struct rte_flow_item_pppoe supp_mask = {}; + const struct rte_flow_item_pppoe def_mask = {}; + uint16_t ether_type; + int rc; + + rc = sfc_flow_parse_init(item, + (const void **)&spec, + (const void **)&mask, + &supp_mask, + &def_mask, + sizeof(struct rte_flow_item_pppoe), + error); + if (rc != 0) + return rc; + + if (item->type == RTE_FLOW_ITEM_TYPE_PPPOED) + ether_type = RTE_ETHER_TYPE_PPPOE_DISCOVERY; + else + ether_type = RTE_ETHER_TYPE_PPPOE_SESSION; + + if ((efx_spec->efs_match_flags & EFX_FILTER_MATCH_ETHER_TYPE) != 0) { + if (efx_spec->efs_ether_type != ether_type) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "Invalid EtherType for a PPPoE flow item"); + return -rte_errno; + } + } else { + efx_spec->efs_match_flags |= EFX_FILTER_MATCH_ETHER_TYPE; + efx_spec->efs_ether_type = ether_type; + } + + return 0; +} + static const struct sfc_flow_item sfc_flow_items[] = { { .type = RTE_FLOW_ITEM_TYPE_VOID, @@ -1085,6 +1143,20 @@ static const struct sfc_flow_item sfc_flow_items[] = { .ctx_type = SFC_FLOW_PARSE_CTX_FILTER, .parse = sfc_flow_parse_vlan, }, + { + .type = RTE_FLOW_ITEM_TYPE_PPPOED, + .prev_layer = SFC_FLOW_ITEM_L2, + .layer = SFC_FLOW_ITEM_L2, + .ctx_type = SFC_FLOW_PARSE_CTX_FILTER, + .parse = sfc_flow_parse_pppoex, + }, + { + .type = RTE_FLOW_ITEM_TYPE_PPPOES, + .prev_layer = SFC_FLOW_ITEM_L2, + .layer = SFC_FLOW_ITEM_L2, + .ctx_type = SFC_FLOW_PARSE_CTX_FILTER, + .parse = sfc_flow_parse_pppoex, + }, { .type = RTE_FLOW_ITEM_TYPE_IPV4, .prev_layer = SFC_FLOW_ITEM_L2, @@ -1202,6 +1274,7 @@ sfc_flow_parse_attr(struct sfc_adapter *sa, spec_mae->priority = attr->priority; spec_mae->match_spec = NULL; spec_mae->action_set = NULL; + spec_mae->rule_id.id = EFX_MAE_RSRC_ID_INVALID; } return 0; @@ -1287,7 +1360,8 @@ sfc_flow_parse_pattern(const struct sfc_flow_item *flow_items, break; default: - if (is_ifrm) { + if (parse_ctx->type == SFC_FLOW_PARSE_CTX_FILTER && + is_ifrm) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, pattern, @@ -1678,9 +1752,6 @@ sfc_flow_parse_actions(struct sfc_adapter *sa, return -rte_errno; } -#define SFC_BUILD_SET_OVERFLOW(_action, _set) \ - RTE_BUILD_BUG_ON(_action >= sizeof(_set) * CHAR_BIT) - for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) { switch (actions->type) { case RTE_FLOW_ACTION_TYPE_VOID: @@ -1776,7 +1847,6 @@ sfc_flow_parse_actions(struct sfc_adapter *sa, actions_set |= (1UL << actions->type); } -#undef SFC_BUILD_SET_OVERFLOW /* When fate is unknown, drop traffic. */ if ((actions_set & fate_actions_mask) == 0) { @@ -2442,8 +2512,7 @@ sfc_flow_parse_rte_to_mae(struct rte_eth_dev *dev, if (rc != 0) return rc; - rc = sfc_mae_rule_parse_actions(sa, actions, &spec_mae->action_set, - error); + rc = sfc_mae_rule_parse_actions(sa, actions, spec_mae, error); if (rc != 0) return rc; @@ -2568,13 +2637,8 @@ sfc_flow_verify(struct sfc_adapter *sa, struct rte_flow *flow, } if (ops->verify != NULL) { - /* - * Use locking since verify method may need to - * access the list of already created rules. - */ - sfc_adapter_lock(sa); + SFC_ASSERT(sfc_adapter_is_locked(sa)); rc = ops->verify(sa, flow); - sfc_adapter_unlock(sa); } if (rc != 0) { @@ -2602,12 +2666,16 @@ sfc_flow_validate(struct rte_eth_dev *dev, if (flow == NULL) return -rte_errno; + sfc_adapter_lock(sa); + rc = sfc_flow_parse(dev, attr, pattern, actions, flow, error); if (rc == 0) rc = sfc_flow_verify(sa, flow, error); sfc_flow_free(sa, flow); + sfc_adapter_unlock(sa); + return rc; } @@ -2626,12 +2694,12 @@ sfc_flow_create(struct rte_eth_dev *dev, if (flow == NULL) goto fail_no_mem; + sfc_adapter_lock(sa); + rc = sfc_flow_parse(dev, attr, pattern, actions, flow, error); if (rc != 0) goto fail_bad_value; - sfc_adapter_lock(sa); - TAILQ_INSERT_TAIL(&sa->flow_list, flow, entries); if (sa->state == SFC_ADAPTER_STARTED) {