From: Jiri Pirko <jiri@resnulli.us>
To: Pablo Neira Ayuso <pablo@netfilter.org>
Cc: netdev@vger.kernel.org, davem@davemloft.net,
thomas.lendacky@amd.com, f.fainelli@gmail.com,
ariel.elior@cavium.com, michael.chan@broadcom.com,
santosh@chelsio.com, madalin.bucur@nxp.com,
yisen.zhuang@huawei.com, salil.mehta@huawei.com,
jeffrey.t.kirsher@intel.com, tariqt@mellanox.com,
saeedm@mellanox.com, jiri@mellanox.com, idosch@mellanox.com,
jakub.kicinski@netronome.com, peppe.cavallaro@st.com,
grygorii.strashko@ti.com, andrew@lunn.ch,
vivien.didelot@savoirfairelinux.com, alexandre.torgue@st.com,
joabreu@synopsys.com, linux-net-drivers@solarflare.com,
ganeshgr@chelsio.com, ogerlitz@mellanox.com
Subject: Re: [PATCH net-next 12/12] qede: use ethtool_rx_flow_rule() to remove duplicated parser code
Date: Mon, 19 Nov 2018 17:00:13 +0100 [thread overview]
Message-ID: <20181119160013.GA2364@nanopsycho> (raw)
In-Reply-To: <20181119001519.12124-13-pablo@netfilter.org>
Mon, Nov 19, 2018 at 01:15:19AM CET, pablo@netfilter.org wrote:
>The qede driver supports for ethtool_rx_flow_spec and flower, both
>codebases look very similar.
>
>This patch uses the ethtool_rx_flow_rule() infrastructure to remove the
>duplicated ethtool_rx_flow_spec parser and consolidate ACL offload
>support around the flow_rule infrastructure.
>
>Furthermore, more code can be consolidated by merging
>qede_add_cls_rule() and qede_add_tc_flower_fltr(), these two functions
>also look very similar.
>
>This driver currently provides simple ACL support, such as 5-tuple
>matching, drop policy and queue to CPU.
>
>Drivers that support more features can benefit from this infrastructure
>to save even more redundant codebase.
>
>Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
>---
>Note that, after this patch, qede_add_cls_rule() and
>qede_add_tc_flower_fltr() can be also consolidated since their code is
>redundant.
>
> drivers/net/ethernet/qlogic/qede/qede_filter.c | 246 ++++++-------------------
> 1 file changed, 53 insertions(+), 193 deletions(-)
>
>diff --git a/drivers/net/ethernet/qlogic/qede/qede_filter.c b/drivers/net/ethernet/qlogic/qede/qede_filter.c
>index aca302c3261b..f82b26ba8f80 100644
>--- a/drivers/net/ethernet/qlogic/qede/qede_filter.c
>+++ b/drivers/net/ethernet/qlogic/qede/qede_filter.c
>@@ -1578,30 +1578,6 @@ static void qede_flow_build_ipv6_hdr(struct qede_arfs_tuple *t,
> ports[1] = t->dst_port;
> }
>
>-/* Validate fields which are set and not accepted by the driver */
>-static int qede_flow_spec_validate_unused(struct qede_dev *edev,
>- struct ethtool_rx_flow_spec *fs)
>-{
>- if (fs->flow_type & FLOW_MAC_EXT) {
>- DP_INFO(edev, "Don't support MAC extensions\n");
>- return -EOPNOTSUPP;
>- }
>-
>- if ((fs->flow_type & FLOW_EXT) &&
>- (fs->h_ext.vlan_etype || fs->h_ext.vlan_tci)) {
>- DP_INFO(edev, "Don't support vlan-based classification\n");
>- return -EOPNOTSUPP;
>- }
>-
>- if ((fs->flow_type & FLOW_EXT) &&
>- (fs->h_ext.data[0] || fs->h_ext.data[1])) {
>- DP_INFO(edev, "Don't support user defined data\n");
>- return -EOPNOTSUPP;
>- }
>-
>- return 0;
>-}
>-
> static int qede_set_v4_tuple_to_profile(struct qede_dev *edev,
> struct qede_arfs_tuple *t)
> {
>@@ -1665,132 +1641,6 @@ static int qede_set_v6_tuple_to_profile(struct qede_dev *edev,
> return 0;
> }
>
>-static int qede_flow_spec_to_tuple_ipv4_common(struct qede_dev *edev,
>- struct qede_arfs_tuple *t,
>- struct ethtool_rx_flow_spec *fs)
>-{
>- if ((fs->h_u.tcp_ip4_spec.ip4src &
>- fs->m_u.tcp_ip4_spec.ip4src) != fs->h_u.tcp_ip4_spec.ip4src) {
>- DP_INFO(edev, "Don't support IP-masks\n");
>- return -EOPNOTSUPP;
>- }
>-
>- if ((fs->h_u.tcp_ip4_spec.ip4dst &
>- fs->m_u.tcp_ip4_spec.ip4dst) != fs->h_u.tcp_ip4_spec.ip4dst) {
>- DP_INFO(edev, "Don't support IP-masks\n");
>- return -EOPNOTSUPP;
>- }
>-
>- if ((fs->h_u.tcp_ip4_spec.psrc &
>- fs->m_u.tcp_ip4_spec.psrc) != fs->h_u.tcp_ip4_spec.psrc) {
>- DP_INFO(edev, "Don't support port-masks\n");
>- return -EOPNOTSUPP;
>- }
>-
>- if ((fs->h_u.tcp_ip4_spec.pdst &
>- fs->m_u.tcp_ip4_spec.pdst) != fs->h_u.tcp_ip4_spec.pdst) {
>- DP_INFO(edev, "Don't support port-masks\n");
>- return -EOPNOTSUPP;
>- }
>-
>- if (fs->h_u.tcp_ip4_spec.tos) {
>- DP_INFO(edev, "Don't support tos\n");
>- return -EOPNOTSUPP;
>- }
>-
>- t->eth_proto = htons(ETH_P_IP);
>- t->src_ipv4 = fs->h_u.tcp_ip4_spec.ip4src;
>- t->dst_ipv4 = fs->h_u.tcp_ip4_spec.ip4dst;
>- t->src_port = fs->h_u.tcp_ip4_spec.psrc;
>- t->dst_port = fs->h_u.tcp_ip4_spec.pdst;
>-
>- return qede_set_v4_tuple_to_profile(edev, t);
>-}
>-
>-static int qede_flow_spec_to_tuple_tcpv4(struct qede_dev *edev,
>- struct qede_arfs_tuple *t,
>- struct ethtool_rx_flow_spec *fs)
>-{
>- t->ip_proto = IPPROTO_TCP;
>-
>- if (qede_flow_spec_to_tuple_ipv4_common(edev, t, fs))
>- return -EINVAL;
>-
>- return 0;
>-}
>-
>-static int qede_flow_spec_to_tuple_udpv4(struct qede_dev *edev,
>- struct qede_arfs_tuple *t,
>- struct ethtool_rx_flow_spec *fs)
>-{
>- t->ip_proto = IPPROTO_UDP;
>-
>- if (qede_flow_spec_to_tuple_ipv4_common(edev, t, fs))
>- return -EINVAL;
>-
>- return 0;
>-}
>-
>-static int qede_flow_spec_to_tuple_ipv6_common(struct qede_dev *edev,
>- struct qede_arfs_tuple *t,
>- struct ethtool_rx_flow_spec *fs)
>-{
>- struct in6_addr zero_addr;
>-
>- memset(&zero_addr, 0, sizeof(zero_addr));
>-
>- if ((fs->h_u.tcp_ip6_spec.psrc &
>- fs->m_u.tcp_ip6_spec.psrc) != fs->h_u.tcp_ip6_spec.psrc) {
>- DP_INFO(edev, "Don't support port-masks\n");
>- return -EOPNOTSUPP;
>- }
>-
>- if ((fs->h_u.tcp_ip6_spec.pdst &
>- fs->m_u.tcp_ip6_spec.pdst) != fs->h_u.tcp_ip6_spec.pdst) {
>- DP_INFO(edev, "Don't support port-masks\n");
>- return -EOPNOTSUPP;
>- }
>-
>- if (fs->h_u.tcp_ip6_spec.tclass) {
>- DP_INFO(edev, "Don't support tclass\n");
>- return -EOPNOTSUPP;
>- }
>-
>- t->eth_proto = htons(ETH_P_IPV6);
>- memcpy(&t->src_ipv6, &fs->h_u.tcp_ip6_spec.ip6src,
>- sizeof(struct in6_addr));
>- memcpy(&t->dst_ipv6, &fs->h_u.tcp_ip6_spec.ip6dst,
>- sizeof(struct in6_addr));
>- t->src_port = fs->h_u.tcp_ip6_spec.psrc;
>- t->dst_port = fs->h_u.tcp_ip6_spec.pdst;
>-
>- return qede_set_v6_tuple_to_profile(edev, t, &zero_addr);
>-}
>-
>-static int qede_flow_spec_to_tuple_tcpv6(struct qede_dev *edev,
>- struct qede_arfs_tuple *t,
>- struct ethtool_rx_flow_spec *fs)
>-{
>- t->ip_proto = IPPROTO_TCP;
>-
>- if (qede_flow_spec_to_tuple_ipv6_common(edev, t, fs))
>- return -EINVAL;
>-
>- return 0;
>-}
>-
>-static int qede_flow_spec_to_tuple_udpv6(struct qede_dev *edev,
>- struct qede_arfs_tuple *t,
>- struct ethtool_rx_flow_spec *fs)
>-{
>- t->ip_proto = IPPROTO_UDP;
>-
>- if (qede_flow_spec_to_tuple_ipv6_common(edev, t, fs))
>- return -EINVAL;
>-
>- return 0;
>-}
>-
> /* Must be called while qede lock is held */
> static struct qede_arfs_fltr_node *
> qede_flow_find_fltr(struct qede_dev *edev, struct qede_arfs_tuple *t)
>@@ -1875,25 +1725,32 @@ static int qede_parse_actions(struct qede_dev *edev,
> struct flow_action *flow_action)
> {
> const struct flow_action_key *act;
>- int rc = -EINVAL, num_act = 0, i;
>- bool is_drop = false;
>+ int i;
>
> if (!flow_action_has_keys(flow_action)) {
>- DP_NOTICE(edev, "No tc actions received\n");
>- return rc;
>+ DP_NOTICE(edev, "No actions received\n");
>+ return -EINVAL;
> }
>
> flow_action_for_each(i, act, flow_action) {
>- num_act++;
>+ switch (act->id) {
>+ case FLOW_ACTION_KEY_DROP:
>+ break;
>+ case FLOW_ACTION_KEY_QUEUE:
>+ if (ethtool_get_flow_spec_ring_vf(act->queue_index))
>+ break;
>
>- if (act->id == FLOW_ACTION_KEY_DROP)
>- is_drop = true;
>+ if (act->queue_index >= QEDE_RSS_COUNT(edev)) {
>+ DP_INFO(edev, "Queue out-of-bounds\n");
>+ return -EINVAL;
>+ }
>+ break;
>+ default:
>+ return -EINVAL;
>+ }
> }
>
>- if (num_act == 1 && is_drop)
>- return 0;
>-
>- return rc;
>+ return 0;
> }
>
> static int
>@@ -2147,16 +2004,17 @@ int qede_add_tc_flower_fltr(struct qede_dev *edev, __be16 proto,
> }
>
> static int qede_flow_spec_validate(struct qede_dev *edev,
>- struct ethtool_rx_flow_spec *fs,
>- struct qede_arfs_tuple *t)
>+ struct flow_action *flow_action,
>+ struct qede_arfs_tuple *t,
>+ __u32 location)
> {
>- if (fs->location >= QEDE_RFS_MAX_FLTR) {
>+ if (location >= QEDE_RFS_MAX_FLTR) {
> DP_INFO(edev, "Location out-of-bounds\n");
> return -EINVAL;
> }
>
> /* Check location isn't already in use */
>- if (test_bit(fs->location, edev->arfs->arfs_fltr_bmap)) {
>+ if (test_bit(location, edev->arfs->arfs_fltr_bmap)) {
> DP_INFO(edev, "Location already in use\n");
> return -EINVAL;
> }
>@@ -2170,46 +2028,53 @@ static int qede_flow_spec_validate(struct qede_dev *edev,
> return -EINVAL;
> }
>
>- /* If drop requested then no need to validate other data */
>- if (fs->ring_cookie == RX_CLS_FLOW_DISC)
>- return 0;
>-
>- if (ethtool_get_flow_spec_ring_vf(fs->ring_cookie))
>- return 0;
>-
>- if (fs->ring_cookie >= QEDE_RSS_COUNT(edev)) {
>- DP_INFO(edev, "Queue out-of-bounds\n");
>+ if (qede_parse_actions(edev, flow_action))
> return -EINVAL;
>- }
>
> return 0;
> }
>
>-static int qede_flow_spec_to_tuple(struct qede_dev *edev,
>- struct qede_arfs_tuple *t,
>- struct ethtool_rx_flow_spec *fs)
>+static int qede_flow_spec_to_rule(struct qede_dev *edev,
>+ struct qede_arfs_tuple *t,
>+ struct ethtool_rx_flow_spec *fs)
> {
>- memset(t, 0, sizeof(*t));
>-
>- if (qede_flow_spec_validate_unused(edev, fs))
>- return -EOPNOTSUPP;
>+ struct tc_cls_flower_offload f = {};
>+ struct flow_rule *flow_rule;
>+ __be16 proto;
>+ int err = 0;
>
> switch ((fs->flow_type & ~FLOW_EXT)) {
> case TCP_V4_FLOW:
>- return qede_flow_spec_to_tuple_tcpv4(edev, t, fs);
> case UDP_V4_FLOW:
>- return qede_flow_spec_to_tuple_udpv4(edev, t, fs);
>+ proto = htons(ETH_P_IP);
>+ break;
> case TCP_V6_FLOW:
>- return qede_flow_spec_to_tuple_tcpv6(edev, t, fs);
> case UDP_V6_FLOW:
>- return qede_flow_spec_to_tuple_udpv6(edev, t, fs);
>+ proto = htons(ETH_P_IPV6);
>+ break;
> default:
> DP_VERBOSE(edev, NETIF_MSG_IFUP,
> "Can't support flow of type %08x\n", fs->flow_type);
> return -EOPNOTSUPP;
> }
>
>- return 0;
>+ flow_rule = ethtool_rx_flow_rule(fs);
>+ if (!flow_rule)
>+ return -ENOMEM;
>+
>+ f.rule = *flow_rule;
This does not look right. I undersntand that you want to use the same
driver code to parse same struct coming either from tc-flower or
ethtool. That is why you introduced flow_rule as a intermediate layer.
However, here, you use struct that is very tc-flower specific. Common
parser should work on struct flow_rule.
qede_parse_flower_attr() should accept struct flow_rule * and should be
renamed to something like qede_parse_flow_rule()
>+
>+ if (qede_parse_flower_attr(edev, proto, &f, t)) {
>+ err = -EINVAL;
>+ goto err_out;
>+ }
>+
>+ /* Make sure location is valid and filter isn't already set */
>+ err = qede_flow_spec_validate(edev, &f.rule.action, t, fs->location);
>+err_out:
>+ ethtool_rx_flow_rule_free(flow_rule);
>+ return err;
>+
> }
>
> int qede_add_cls_rule(struct qede_dev *edev, struct ethtool_rxnfc *info)
>@@ -2227,12 +2092,7 @@ int qede_add_cls_rule(struct qede_dev *edev, struct ethtool_rxnfc *info)
> }
>
> /* Translate the flow specification into something fittign our DB */
>- rc = qede_flow_spec_to_tuple(edev, &t, fsp);
>- if (rc)
>- goto unlock;
>-
>- /* Make sure location is valid and filter isn't already set */
>- rc = qede_flow_spec_validate(edev, fsp, &t);
>+ rc = qede_flow_spec_to_rule(edev, &t, fsp);
> if (rc)
> goto unlock;
>
>--
>2.11.0
>
next prev parent reply other threads:[~2018-11-20 2:30 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-11-19 0:15 [PATCH 00/12 net-next,v2] add flow_rule infrastructure Pablo Neira Ayuso
2018-11-19 0:15 ` [PATCH net-next,v2 01/12] flow_dissector: add flow_rule and flow_match structures and use them Pablo Neira Ayuso
2018-11-19 0:15 ` [PATCH net-next,v2 02/12] net/mlx5e: support for two independent packet edit actions Pablo Neira Ayuso
2018-11-19 0:15 ` [PATCH net-next,v2 03/12] flow_dissector: add flow action infrastructure Pablo Neira Ayuso
2018-11-19 11:56 ` Jiri Pirko
2018-11-19 12:35 ` Pablo Neira Ayuso
2018-11-19 13:05 ` Jiri Pirko
2018-11-19 14:03 ` Jiri Pirko
2018-11-19 14:42 ` Pablo Neira Ayuso
2018-11-19 16:26 ` Pablo Neira Ayuso
2018-11-19 16:29 ` Jiri Pirko
2018-11-19 0:15 ` [PATCH net-next,v2 04/12] cls_api: add translator to flow_action representation Pablo Neira Ayuso
2018-11-19 12:12 ` Jiri Pirko
2018-11-19 13:21 ` Pablo Neira Ayuso
2018-11-19 13:22 ` Jiri Pirko
2018-11-19 12:16 ` Jiri Pirko
2018-11-19 12:37 ` Pablo Neira Ayuso
2018-11-19 0:15 ` [PATCH net-next,v2 05/12] cls_flower: add statistics retrieval infrastructure and use it Pablo Neira Ayuso
2018-11-19 13:57 ` Jiri Pirko
2018-11-19 14:48 ` Pablo Neira Ayuso
2018-11-19 15:04 ` Jiri Pirko
2018-11-19 16:15 ` Pablo Neira Ayuso
2018-11-19 0:15 ` [PATCH net-next,v2 06/12] drivers: net: use flow action infrastructure Pablo Neira Ayuso
2018-11-19 0:15 ` [PATCH net-next,v2 07/12] cls_flower: don't expose TC actions to drivers anymore Pablo Neira Ayuso
2018-11-19 0:15 ` [PATCH net-next,v2 08/12] flow_dissector: add wake-up-on-lan and queue to flow_action Pablo Neira Ayuso
2018-11-19 13:59 ` Jiri Pirko
2018-11-19 0:15 ` [PATCH net-next,v2 09/12] flow_dissector: add basic ethtool_rx_flow_spec to flow_rule structure translator Pablo Neira Ayuso
2018-11-19 14:17 ` Jiri Pirko
2018-11-19 14:43 ` Pablo Neira Ayuso
2018-11-19 14:49 ` Jiri Pirko
2018-11-19 16:16 ` Pablo Neira Ayuso
2018-11-19 0:15 ` [PATCH net-next,v2 10/12] dsa: bcm_sf2: use flow_rule infrastructure Pablo Neira Ayuso
2018-11-19 0:15 ` [PATCH net-next 11/12] qede: place ethtool_rx_flow_spec after code after TC flower codebase Pablo Neira Ayuso
2018-11-19 0:15 ` [PATCH net-next 12/12] qede: use ethtool_rx_flow_rule() to remove duplicated parser code Pablo Neira Ayuso
2018-11-19 16:00 ` Jiri Pirko [this message]
2018-11-19 16:12 ` Pablo Neira Ayuso
2018-11-19 21:44 ` Chopra, Manish
2018-11-19 9:20 ` [PATCH 00/12 net-next,v2] add flow_rule infrastructure Jose Abreu
2018-11-19 10:19 ` Pablo Neira Ayuso
2018-11-19 20:12 ` David Miller
2018-11-19 21:19 ` Or Gerlitz
2018-11-20 7:39 ` Jiri Pirko
2018-11-20 17:16 ` David Miller
2018-11-21 7:46 ` Jiri Pirko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20181119160013.GA2364@nanopsycho \
--to=jiri@resnulli.us \
--cc=alexandre.torgue@st.com \
--cc=andrew@lunn.ch \
--cc=ariel.elior@cavium.com \
--cc=davem@davemloft.net \
--cc=f.fainelli@gmail.com \
--cc=ganeshgr@chelsio.com \
--cc=grygorii.strashko@ti.com \
--cc=idosch@mellanox.com \
--cc=jakub.kicinski@netronome.com \
--cc=jeffrey.t.kirsher@intel.com \
--cc=jiri@mellanox.com \
--cc=joabreu@synopsys.com \
--cc=linux-net-drivers@solarflare.com \
--cc=madalin.bucur@nxp.com \
--cc=michael.chan@broadcom.com \
--cc=netdev@vger.kernel.org \
--cc=ogerlitz@mellanox.com \
--cc=pablo@netfilter.org \
--cc=peppe.cavallaro@st.com \
--cc=saeedm@mellanox.com \
--cc=salil.mehta@huawei.com \
--cc=santosh@chelsio.com \
--cc=tariqt@mellanox.com \
--cc=thomas.lendacky@amd.com \
--cc=vivien.didelot@savoirfairelinux.com \
--cc=yisen.zhuang@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).