All of lore.kernel.org
 help / color / mirror / Atom feed
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
>

  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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.