From patchwork Tue Mar 6 15:24:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 35686 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id E6C785592; Tue, 6 Mar 2018 16:27:17 +0100 (CET) Received: from dispatch1-us1.ppe-hosted.com (dispatch1-us1.ppe-hosted.com [148.163.129.52]) by dpdk.org (Postfix) with ESMTP id 3604A4C8E for ; Tue, 6 Mar 2018 16:27:15 +0100 (CET) X-Virus-Scanned: Proofpoint Essentials engine Received: from webmail.solarflare.com (webmail.solarflare.com [12.187.104.26]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1-us4.ppe-hosted.com (Proofpoint Essentials ESMTP Server) with ESMTPS id ED0744C0060; Tue, 6 Mar 2018 15:27:13 +0000 (UTC) Received: from ocex03.SolarFlarecom.com (10.20.40.36) by ocex03.SolarFlarecom.com (10.20.40.36) with Microsoft SMTP Server (TLS) id 15.0.1044.25; Tue, 6 Mar 2018 07:27:11 -0800 Received: from opal.uk.solarflarecom.com (10.17.10.1) by ocex03.SolarFlarecom.com (10.20.40.36) with Microsoft SMTP Server (TLS) id 15.0.1044.25 via Frontend Transport; Tue, 6 Mar 2018 07:27:11 -0800 Received: from uklogin.uk.solarflarecom.com (uklogin.uk.solarflarecom.com [10.17.10.10]) by opal.uk.solarflarecom.com (8.13.8/8.13.8) with ESMTP id w26FRAMA021720; Tue, 6 Mar 2018 15:27:10 GMT Received: from uklogin.uk.solarflarecom.com (localhost.localdomain [127.0.0.1]) by uklogin.uk.solarflarecom.com (8.13.8/8.13.8) with ESMTP id w26FR9BP000659; Tue, 6 Mar 2018 15:27:10 GMT From: Andrew Rybchenko To: CC: Roman Zhukov Date: Tue, 6 Mar 2018 15:24:58 +0000 Message-ID: <1520349899-31810-14-git-send-email-arybchenko@solarflare.com> X-Mailer: git-send-email 1.8.2.3 In-Reply-To: <1520349899-31810-1-git-send-email-arybchenko@solarflare.com> References: <1519735526-2259-1-git-send-email-arybchenko@solarflare.com> <1520349899-31810-1-git-send-email-arybchenko@solarflare.com> MIME-Version: 1.0 X-MDID: 1520350034-2GjGVFJhdccb Subject: [dpdk-dev] [PATCH v2 13/14] net/sfc: avoid creation of ineffective flow rules X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Roman Zhukov Despite being versatile, the hardware support for filtering has a number of special properties which must be taken into account. Namely, there is a known set of valid filters which don't take any effect despite being accepted by the hardware. The combinations of match flags and field values which can describe the exceptional filters are as follows: - ETHER_TYPE or ETHER_TYPE | LOC_MAC with IPv4 or IPv6 EtherType - ETHER_TYPE | IP_PROTO or ETHER_TYPE | IP_PROTO | LOC_MAC with UDP or TCP IP protocol value - The same combinations with OUTER_VID and/or INNER_VID These exceptional filters can be expressed in terms of RTE flow rules. If the user creates such a flow rule, no traffic will hit the underlying filter, and no errors will be reported. This patch adds a means to prevent such ineffective flow rules from being created. Signed-off-by: Roman Zhukov Signed-off-by: Andrew Rybchenko Reviewed-by: Ivan Malov --- doc/guides/nics/sfc_efx.rst | 17 ++++++++++ drivers/net/sfc/sfc_flow.c | 78 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst index 539ce90..f41ccdb 100644 --- a/doc/guides/nics/sfc_efx.rst +++ b/doc/guides/nics/sfc_efx.rst @@ -193,6 +193,23 @@ in the mask of destination address. If destinaton address in the spec is multicast, it matches all multicast (and broadcast) packets, oherwise it matches unicast packets that are not filtered by other flow rules. +Exceptions to flow rules +~~~~~~~~~~~~~~~~~~~~~~~~ + +There is a list of exceptional flow rule patterns which will not be +accepted by the PMD. A pattern will be rejected if at least one of the +conditions is met: + +- Filtering by IPv4 or IPv6 EtherType without pattern items of internet + layer and above. + +- The last item is IPV4 or IPV6, and it's empty. + +- Filtering by TCP or UDP IP transport protocol without pattern items of + transport layer and above. + +- The last item is TCP or UDP, and it's empty. + Supported NICs -------------- diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c index 7b26653..2b8bef8 100644 --- a/drivers/net/sfc/sfc_flow.c +++ b/drivers/net/sfc/sfc_flow.c @@ -1919,6 +1919,77 @@ sfc_flow_spec_filters_complete(struct sfc_adapter *sa, return 0; } +/** + * Check that set of match flags is referred to by a filter. Filter is + * described by match flags with the ability to add OUTER_VID and INNER_VID + * flags. + * + * @param match_flags[in] + * Set of match flags. + * @param flags_pattern[in] + * Pattern of filter match flags. + */ +static boolean_t +sfc_flow_is_match_with_vids(efx_filter_match_flags_t match_flags, + efx_filter_match_flags_t flags_pattern) +{ + if ((match_flags & flags_pattern) != flags_pattern) + return B_FALSE; + + switch (match_flags & ~flags_pattern) { + case 0: + case EFX_FILTER_MATCH_OUTER_VID: + case EFX_FILTER_MATCH_OUTER_VID | EFX_FILTER_MATCH_INNER_VID: + return B_TRUE; + default: + return B_FALSE; + } +} + +/** + * Check whether the spec maps to a hardware filter which is known to be + * ineffective despite being valid. + * + * @param spec[in] + * SFC flow specification. + */ +static boolean_t +sfc_flow_is_match_flags_exception(struct sfc_flow_spec *spec) +{ + unsigned int i; + uint16_t ether_type; + uint8_t ip_proto; + efx_filter_match_flags_t match_flags; + + for (i = 0; i < spec->count; i++) { + match_flags = spec->filters[i].efs_match_flags; + + if (sfc_flow_is_match_with_vids(match_flags, + EFX_FILTER_MATCH_ETHER_TYPE) || + sfc_flow_is_match_with_vids(match_flags, + EFX_FILTER_MATCH_ETHER_TYPE | + EFX_FILTER_MATCH_LOC_MAC)) { + ether_type = spec->filters[i].efs_ether_type; + if (ether_type == EFX_ETHER_TYPE_IPV4 || + ether_type == EFX_ETHER_TYPE_IPV6) + return B_TRUE; + } else if (sfc_flow_is_match_with_vids(match_flags, + EFX_FILTER_MATCH_ETHER_TYPE | + EFX_FILTER_MATCH_IP_PROTO) || + sfc_flow_is_match_with_vids(match_flags, + EFX_FILTER_MATCH_ETHER_TYPE | + EFX_FILTER_MATCH_IP_PROTO | + EFX_FILTER_MATCH_LOC_MAC)) { + ip_proto = spec->filters[i].efs_ip_proto; + if (ip_proto == EFX_IPPROTO_TCP || + ip_proto == EFX_IPPROTO_UDP) + return B_TRUE; + } + } + + return B_FALSE; +} + static int sfc_flow_validate_match_flags(struct sfc_adapter *sa, struct rte_flow *flow, @@ -1938,6 +2009,13 @@ sfc_flow_validate_match_flags(struct sfc_adapter *sa, return rc; } + if (sfc_flow_is_match_flags_exception(&flow->spec)) { + rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, + "The flow rule pattern is unsupported"); + return -rte_errno; + } + return 0; }