linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next 0/3] net: prestera: matchall features
@ 2022-08-23 11:39 Maksym Glubokiy
  2022-08-23 11:39 ` [PATCH net-next 1/3] net: prestera: acl: extract matchall logic into a separate file Maksym Glubokiy
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Maksym Glubokiy @ 2022-08-23 11:39 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Taras Chornyi
  Cc: Maksym Glubokiy, Serhiy Boiko, linux-kernel, netdev

This patch series extracts matchall rules management out of SPAN API
implementation and adds 2 features on top of that:
  - support for egress traffic (mirred egress action)
  - proper rule priorities management between matchall and flower

Maksym Glubokiy (1):
  net: prestera: manage matchall and flower priorities

Serhiy Boiko (2):
  net: prestera: acl: extract matchall logic into a separate file
  net: prestera: add support for egress traffic mirroring

 .../net/ethernet/marvell/prestera/Makefile    |   2 +-
 .../ethernet/marvell/prestera/prestera_acl.c  |  43 ++++++
 .../ethernet/marvell/prestera/prestera_acl.h  |   2 +
 .../ethernet/marvell/prestera/prestera_flow.c |  12 +-
 .../ethernet/marvell/prestera/prestera_flow.h |   5 +
 .../marvell/prestera/prestera_flower.c        |  48 +++++++
 .../marvell/prestera/prestera_flower.h        |   2 +
 .../ethernet/marvell/prestera/prestera_hw.c   |  30 +++--
 .../ethernet/marvell/prestera/prestera_hw.h   |   5 +-
 .../marvell/prestera/prestera_matchall.c      | 125 ++++++++++++++++++
 .../marvell/prestera/prestera_matchall.h      |  17 +++
 .../ethernet/marvell/prestera/prestera_span.c |  66 +--------
 .../ethernet/marvell/prestera/prestera_span.h |  12 +-
 13 files changed, 291 insertions(+), 78 deletions(-)
 create mode 100644 drivers/net/ethernet/marvell/prestera/prestera_matchall.c
 create mode 100644 drivers/net/ethernet/marvell/prestera/prestera_matchall.h

-- 
2.25.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH net-next 1/3] net: prestera: acl: extract matchall logic into a separate file
  2022-08-23 11:39 [PATCH net-next 0/3] net: prestera: matchall features Maksym Glubokiy
@ 2022-08-23 11:39 ` Maksym Glubokiy
  2022-08-25 11:11   ` Paolo Abeni
  2022-08-23 11:39 ` [PATCH net-next 2/3] net: prestera: add support for egress traffic mirroring Maksym Glubokiy
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Maksym Glubokiy @ 2022-08-23 11:39 UTC (permalink / raw)
  To: Taras Chornyi, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni
  Cc: Serhiy Boiko, Maksym Glubokiy, linux-kernel, netdev

From: Serhiy Boiko <serhiy.boiko@plvision.eu>

This commit adds more clarity to handling of TC_CLSMATCHALL_REPLACE and
TC_CLSMATCHALL_DESTROY events by calling newly added *_mall_*() handlers
instead of directly calling SPAN API.

This also extracts matchall rules management out of SPAN API since SPAN
is a hardware module which is used to implement 'matchall egress mirred'
action only.

Signed-off-by: Taras Chornyi <tchornyi@marvell.com>
Signed-off-by: Serhiy Boiko <serhiy.boiko@plvision.eu>
Signed-off-by: Maksym Glubokiy <maksym.glubokiy@plvision.eu>
---
 .../net/ethernet/marvell/prestera/Makefile    |  2 +-
 .../ethernet/marvell/prestera/prestera_flow.c |  9 +--
 .../marvell/prestera/prestera_matchall.c      | 66 +++++++++++++++++++
 .../marvell/prestera/prestera_matchall.h      | 15 +++++
 .../ethernet/marvell/prestera/prestera_span.c | 60 +----------------
 .../ethernet/marvell/prestera/prestera_span.h | 10 +--
 6 files changed, 96 insertions(+), 66 deletions(-)
 create mode 100644 drivers/net/ethernet/marvell/prestera/prestera_matchall.c
 create mode 100644 drivers/net/ethernet/marvell/prestera/prestera_matchall.h

diff --git a/drivers/net/ethernet/marvell/prestera/Makefile b/drivers/net/ethernet/marvell/prestera/Makefile
index d395f4131648..df14cee80153 100644
--- a/drivers/net/ethernet/marvell/prestera/Makefile
+++ b/drivers/net/ethernet/marvell/prestera/Makefile
@@ -4,6 +4,6 @@ prestera-objs		:= prestera_main.o prestera_hw.o prestera_dsa.o \
 			   prestera_rxtx.o prestera_devlink.o prestera_ethtool.o \
 			   prestera_switchdev.o prestera_acl.o prestera_flow.o \
 			   prestera_flower.o prestera_span.o prestera_counter.o \
-			   prestera_router.o prestera_router_hw.o
+			   prestera_router.o prestera_router_hw.o prestera_matchall.o
 
 obj-$(CONFIG_PRESTERA_PCI)	+= prestera_pci.o
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_flow.c b/drivers/net/ethernet/marvell/prestera/prestera_flow.c
index 2262693bd5cf..3f81eef167fa 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_flow.c
+++ b/drivers/net/ethernet/marvell/prestera/prestera_flow.c
@@ -7,8 +7,9 @@
 #include "prestera.h"
 #include "prestera_acl.h"
 #include "prestera_flow.h"
-#include "prestera_span.h"
 #include "prestera_flower.h"
+#include "prestera_matchall.h"
+#include "prestera_span.h"
 
 static LIST_HEAD(prestera_block_cb_list);
 
@@ -17,9 +18,9 @@ static int prestera_flow_block_mall_cb(struct prestera_flow_block *block,
 {
 	switch (f->command) {
 	case TC_CLSMATCHALL_REPLACE:
-		return prestera_span_replace(block, f);
+		return prestera_mall_replace(block, f);
 	case TC_CLSMATCHALL_DESTROY:
-		prestera_span_destroy(block);
+		prestera_mall_destroy(block);
 		return 0;
 	default:
 		return -EOPNOTSUPP;
@@ -263,7 +264,7 @@ static void prestera_setup_flow_block_unbind(struct prestera_port *port,
 
 	block = flow_block_cb_priv(block_cb);
 
-	prestera_span_destroy(block);
+	prestera_mall_destroy(block);
 
 	err = prestera_flow_block_unbind(block, port);
 	if (err)
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_matchall.c b/drivers/net/ethernet/marvell/prestera/prestera_matchall.c
new file mode 100644
index 000000000000..54573c6a6fe2
--- /dev/null
+++ b/drivers/net/ethernet/marvell/prestera/prestera_matchall.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+/* Copyright (c) 2019-2022 Marvell International Ltd. All rights reserved */
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+
+#include "prestera.h"
+#include "prestera_hw.h"
+#include "prestera_flow.h"
+#include "prestera_flower.h"
+#include "prestera_matchall.h"
+#include "prestera_span.h"
+
+int prestera_mall_replace(struct prestera_flow_block *block,
+			  struct tc_cls_matchall_offload *f)
+{
+	struct prestera_flow_block_binding *binding;
+	__be16 protocol = f->common.protocol;
+	struct flow_action_entry *act;
+	struct prestera_port *port;
+	int err;
+
+	if (!flow_offload_has_one_action(&f->rule->action)) {
+		NL_SET_ERR_MSG(f->common.extack,
+			       "Only singular actions are supported");
+		return -EOPNOTSUPP;
+	}
+
+	act = &f->rule->action.entries[0];
+
+	if (!prestera_netdev_check(act->dev)) {
+		NL_SET_ERR_MSG(f->common.extack,
+			       "Only Marvell Prestera port is supported");
+		return -EINVAL;
+	}
+	if (!tc_cls_can_offload_and_chain0(act->dev, &f->common))
+		return -EOPNOTSUPP;
+	if (act->id != FLOW_ACTION_MIRRED)
+		return -EOPNOTSUPP;
+	if (protocol != htons(ETH_P_ALL))
+		return -EOPNOTSUPP;
+
+	port = netdev_priv(act->dev);
+
+	list_for_each_entry(binding, &block->binding_list, list) {
+		err = prestera_span_rule_add(binding, port);
+		if (err)
+			goto rollback;
+	}
+
+	return 0;
+
+rollback:
+	list_for_each_entry_continue_reverse(binding,
+					     &block->binding_list, list)
+		prestera_span_rule_del(binding);
+	return err;
+}
+
+void prestera_mall_destroy(struct prestera_flow_block *block)
+{
+	struct prestera_flow_block_binding *binding;
+
+	list_for_each_entry(binding, &block->binding_list, list)
+		prestera_span_rule_del(binding);
+}
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_matchall.h b/drivers/net/ethernet/marvell/prestera/prestera_matchall.h
new file mode 100644
index 000000000000..31ad4d02ecbb
--- /dev/null
+++ b/drivers/net/ethernet/marvell/prestera/prestera_matchall.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
+/* Copyright (c) 2022 Marvell International Ltd. All rights reserved. */
+
+#ifndef _PRESTERA_MATCHALL_H_
+#define _PRESTERA_MATCHALL_H_
+
+#include <net/pkt_cls.h>
+
+struct prestera_flow_block;
+
+int prestera_mall_replace(struct prestera_flow_block *block,
+			  struct tc_cls_matchall_offload *f);
+void prestera_mall_destroy(struct prestera_flow_block *block);
+
+#endif /* _PRESTERA_MATCHALL_H_ */
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_span.c b/drivers/net/ethernet/marvell/prestera/prestera_span.c
index 845e9d8c8cc7..766413b9ba1b 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_span.c
+++ b/drivers/net/ethernet/marvell/prestera/prestera_span.c
@@ -120,8 +120,8 @@ static int prestera_span_put(struct prestera_switch *sw, u8 span_id)
 	return 0;
 }
 
-static int prestera_span_rule_add(struct prestera_flow_block_binding *binding,
-				  struct prestera_port *to_port)
+int prestera_span_rule_add(struct prestera_flow_block_binding *binding,
+			   struct prestera_port *to_port)
 {
 	struct prestera_switch *sw = binding->port->sw;
 	u8 span_id;
@@ -145,7 +145,7 @@ static int prestera_span_rule_add(struct prestera_flow_block_binding *binding,
 	return 0;
 }
 
-static int prestera_span_rule_del(struct prestera_flow_block_binding *binding)
+int prestera_span_rule_del(struct prestera_flow_block_binding *binding)
 {
 	int err;
 
@@ -161,60 +161,6 @@ static int prestera_span_rule_del(struct prestera_flow_block_binding *binding)
 	return 0;
 }
 
-int prestera_span_replace(struct prestera_flow_block *block,
-			  struct tc_cls_matchall_offload *f)
-{
-	struct prestera_flow_block_binding *binding;
-	__be16 protocol = f->common.protocol;
-	struct flow_action_entry *act;
-	struct prestera_port *port;
-	int err;
-
-	if (!flow_offload_has_one_action(&f->rule->action)) {
-		NL_SET_ERR_MSG(f->common.extack,
-			       "Only singular actions are supported");
-		return -EOPNOTSUPP;
-	}
-
-	act = &f->rule->action.entries[0];
-
-	if (!prestera_netdev_check(act->dev)) {
-		NL_SET_ERR_MSG(f->common.extack,
-			       "Only Marvell Prestera port is supported");
-		return -EINVAL;
-	}
-	if (!tc_cls_can_offload_and_chain0(act->dev, &f->common))
-		return -EOPNOTSUPP;
-	if (act->id != FLOW_ACTION_MIRRED)
-		return -EOPNOTSUPP;
-	if (protocol != htons(ETH_P_ALL))
-		return -EOPNOTSUPP;
-
-	port = netdev_priv(act->dev);
-
-	list_for_each_entry(binding, &block->binding_list, list) {
-		err = prestera_span_rule_add(binding, port);
-		if (err)
-			goto rollback;
-	}
-
-	return 0;
-
-rollback:
-	list_for_each_entry_continue_reverse(binding,
-					     &block->binding_list, list)
-		prestera_span_rule_del(binding);
-	return err;
-}
-
-void prestera_span_destroy(struct prestera_flow_block *block)
-{
-	struct prestera_flow_block_binding *binding;
-
-	list_for_each_entry(binding, &block->binding_list, list)
-		prestera_span_rule_del(binding);
-}
-
 int prestera_span_init(struct prestera_switch *sw)
 {
 	struct prestera_span *span;
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_span.h b/drivers/net/ethernet/marvell/prestera/prestera_span.h
index f0644521f78a..4958ce820b52 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_span.h
+++ b/drivers/net/ethernet/marvell/prestera/prestera_span.h
@@ -8,13 +8,15 @@
 
 #define PRESTERA_SPAN_INVALID_ID -1
 
+struct prestera_port;
 struct prestera_switch;
-struct prestera_flow_block;
+struct prestera_flow_block_binding;
 
 int prestera_span_init(struct prestera_switch *sw);
 void prestera_span_fini(struct prestera_switch *sw);
-int prestera_span_replace(struct prestera_flow_block *block,
-			  struct tc_cls_matchall_offload *f);
-void prestera_span_destroy(struct prestera_flow_block *block);
+
+int prestera_span_rule_add(struct prestera_flow_block_binding *binding,
+			   struct prestera_port *to_port);
+int prestera_span_rule_del(struct prestera_flow_block_binding *binding);
 
 #endif /* _PRESTERA_SPAN_H_ */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH net-next 2/3] net: prestera: add support for egress traffic mirroring
  2022-08-23 11:39 [PATCH net-next 0/3] net: prestera: matchall features Maksym Glubokiy
  2022-08-23 11:39 ` [PATCH net-next 1/3] net: prestera: acl: extract matchall logic into a separate file Maksym Glubokiy
@ 2022-08-23 11:39 ` Maksym Glubokiy
  2022-08-23 11:39 ` [PATCH net-next 3/3] net: prestera: manage matchall and flower priorities Maksym Glubokiy
  2022-08-26  9:20 ` [PATCH net-next 0/3] net: prestera: matchall features patchwork-bot+netdevbpf
  3 siblings, 0 replies; 7+ messages in thread
From: Maksym Glubokiy @ 2022-08-23 11:39 UTC (permalink / raw)
  To: Taras Chornyi, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni
  Cc: Serhiy Boiko, Maksym Glubokiy, netdev, linux-kernel

From: Serhiy Boiko <serhiy.boiko@plvision.eu>

This enables adding matchall rules for egress:

  tc filter add .. egress .. matchall skip_sw \
    action mirred egress mirror dev ..

Signed-off-by: Serhiy Boiko <serhiy.boiko@plvision.eu>
Signed-off-by: Maksym Glubokiy <maksym.glubokiy@plvision.eu>
---
 .../ethernet/marvell/prestera/prestera_hw.c   | 30 ++++++++++++++-----
 .../ethernet/marvell/prestera/prestera_hw.h   |  5 ++--
 .../marvell/prestera/prestera_matchall.c      |  7 +++--
 .../ethernet/marvell/prestera/prestera_span.c | 10 ++++---
 .../ethernet/marvell/prestera/prestera_span.h |  6 ++--
 5 files changed, 39 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/marvell/prestera/prestera_hw.c b/drivers/net/ethernet/marvell/prestera/prestera_hw.c
index e0e9ae34ceea..8430db3384f9 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_hw.c
+++ b/drivers/net/ethernet/marvell/prestera/prestera_hw.c
@@ -78,9 +78,11 @@ enum prestera_cmd_type_t {
 	PRESTERA_CMD_TYPE_STP_PORT_SET = 0x1000,
 
 	PRESTERA_CMD_TYPE_SPAN_GET = 0x1100,
-	PRESTERA_CMD_TYPE_SPAN_BIND = 0x1101,
-	PRESTERA_CMD_TYPE_SPAN_UNBIND = 0x1102,
+	PRESTERA_CMD_TYPE_SPAN_INGRESS_BIND = 0x1101,
+	PRESTERA_CMD_TYPE_SPAN_INGRESS_UNBIND = 0x1102,
 	PRESTERA_CMD_TYPE_SPAN_RELEASE = 0x1103,
+	PRESTERA_CMD_TYPE_SPAN_EGRESS_BIND = 0x1104,
+	PRESTERA_CMD_TYPE_SPAN_EGRESS_UNBIND = 0x1105,
 
 	PRESTERA_CMD_TYPE_POLICER_CREATE = 0x1500,
 	PRESTERA_CMD_TYPE_POLICER_RELEASE = 0x1501,
@@ -1432,27 +1434,39 @@ int prestera_hw_span_get(const struct prestera_port *port, u8 *span_id)
 	return 0;
 }
 
-int prestera_hw_span_bind(const struct prestera_port *port, u8 span_id)
+int prestera_hw_span_bind(const struct prestera_port *port, u8 span_id,
+			  bool ingress)
 {
 	struct prestera_msg_span_req req = {
 		.port = __cpu_to_le32(port->hw_id),
 		.dev = __cpu_to_le32(port->dev_id),
 		.id = span_id,
 	};
+	enum prestera_cmd_type_t cmd_type;
+
+	if (ingress)
+		cmd_type = PRESTERA_CMD_TYPE_SPAN_INGRESS_BIND;
+	else
+		cmd_type = PRESTERA_CMD_TYPE_SPAN_EGRESS_BIND;
+
+	return prestera_cmd(port->sw, cmd_type, &req.cmd, sizeof(req));
 
-	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_SPAN_BIND,
-			    &req.cmd, sizeof(req));
 }
 
-int prestera_hw_span_unbind(const struct prestera_port *port)
+int prestera_hw_span_unbind(const struct prestera_port *port, bool ingress)
 {
 	struct prestera_msg_span_req req = {
 		.port = __cpu_to_le32(port->hw_id),
 		.dev = __cpu_to_le32(port->dev_id),
 	};
+	enum prestera_cmd_type_t cmd_type;
 
-	return prestera_cmd(port->sw, PRESTERA_CMD_TYPE_SPAN_UNBIND,
-			    &req.cmd, sizeof(req));
+	if (ingress)
+		cmd_type = PRESTERA_CMD_TYPE_SPAN_INGRESS_UNBIND;
+	else
+		cmd_type = PRESTERA_CMD_TYPE_SPAN_EGRESS_UNBIND;
+
+	return prestera_cmd(port->sw, cmd_type, &req.cmd, sizeof(req));
 }
 
 int prestera_hw_span_release(struct prestera_switch *sw, u8 span_id)
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_hw.h b/drivers/net/ethernet/marvell/prestera/prestera_hw.h
index 56e043146dd2..a589450e9f27 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_hw.h
+++ b/drivers/net/ethernet/marvell/prestera/prestera_hw.h
@@ -243,8 +243,9 @@ int prestera_hw_counter_clear(struct prestera_switch *sw, u32 block_id,
 
 /* SPAN API */
 int prestera_hw_span_get(const struct prestera_port *port, u8 *span_id);
-int prestera_hw_span_bind(const struct prestera_port *port, u8 span_id);
-int prestera_hw_span_unbind(const struct prestera_port *port);
+int prestera_hw_span_bind(const struct prestera_port *port, u8 span_id,
+			  bool ingress);
+int prestera_hw_span_unbind(const struct prestera_port *port, bool ingress);
 int prestera_hw_span_release(struct prestera_switch *sw, u8 span_id);
 
 /* Router API */
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_matchall.c b/drivers/net/ethernet/marvell/prestera/prestera_matchall.c
index 54573c6a6fe2..3fc13176e046 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_matchall.c
+++ b/drivers/net/ethernet/marvell/prestera/prestera_matchall.c
@@ -43,7 +43,7 @@ int prestera_mall_replace(struct prestera_flow_block *block,
 	port = netdev_priv(act->dev);
 
 	list_for_each_entry(binding, &block->binding_list, list) {
-		err = prestera_span_rule_add(binding, port);
+		err = prestera_span_rule_add(binding, port, block->ingress);
 		if (err)
 			goto rollback;
 	}
@@ -53,7 +53,7 @@ int prestera_mall_replace(struct prestera_flow_block *block,
 rollback:
 	list_for_each_entry_continue_reverse(binding,
 					     &block->binding_list, list)
-		prestera_span_rule_del(binding);
+		prestera_span_rule_del(binding, block->ingress);
 	return err;
 }
 
@@ -62,5 +62,6 @@ void prestera_mall_destroy(struct prestera_flow_block *block)
 	struct prestera_flow_block_binding *binding;
 
 	list_for_each_entry(binding, &block->binding_list, list)
-		prestera_span_rule_del(binding);
+		prestera_span_rule_del(binding, block->ingress);
+
 }
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_span.c b/drivers/net/ethernet/marvell/prestera/prestera_span.c
index 766413b9ba1b..f0e9d6ea88c5 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_span.c
+++ b/drivers/net/ethernet/marvell/prestera/prestera_span.c
@@ -121,7 +121,8 @@ static int prestera_span_put(struct prestera_switch *sw, u8 span_id)
 }
 
 int prestera_span_rule_add(struct prestera_flow_block_binding *binding,
-			   struct prestera_port *to_port)
+			   struct prestera_port *to_port,
+			   bool ingress)
 {
 	struct prestera_switch *sw = binding->port->sw;
 	u8 span_id;
@@ -135,7 +136,7 @@ int prestera_span_rule_add(struct prestera_flow_block_binding *binding,
 	if (err)
 		return err;
 
-	err = prestera_hw_span_bind(binding->port, span_id);
+	err = prestera_hw_span_bind(binding->port, span_id, ingress);
 	if (err) {
 		prestera_span_put(sw, span_id);
 		return err;
@@ -145,11 +146,12 @@ int prestera_span_rule_add(struct prestera_flow_block_binding *binding,
 	return 0;
 }
 
-int prestera_span_rule_del(struct prestera_flow_block_binding *binding)
+int prestera_span_rule_del(struct prestera_flow_block_binding *binding,
+			   bool ingress)
 {
 	int err;
 
-	err = prestera_hw_span_unbind(binding->port);
+	err = prestera_hw_span_unbind(binding->port, ingress);
 	if (err)
 		return err;
 
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_span.h b/drivers/net/ethernet/marvell/prestera/prestera_span.h
index 4958ce820b52..493b68524bcb 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_span.h
+++ b/drivers/net/ethernet/marvell/prestera/prestera_span.h
@@ -16,7 +16,9 @@ int prestera_span_init(struct prestera_switch *sw);
 void prestera_span_fini(struct prestera_switch *sw);
 
 int prestera_span_rule_add(struct prestera_flow_block_binding *binding,
-			   struct prestera_port *to_port);
-int prestera_span_rule_del(struct prestera_flow_block_binding *binding);
+			   struct prestera_port *to_port,
+			   bool ingress);
+int prestera_span_rule_del(struct prestera_flow_block_binding *binding,
+			   bool ingress);
 
 #endif /* _PRESTERA_SPAN_H_ */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH net-next 3/3] net: prestera: manage matchall and flower priorities
  2022-08-23 11:39 [PATCH net-next 0/3] net: prestera: matchall features Maksym Glubokiy
  2022-08-23 11:39 ` [PATCH net-next 1/3] net: prestera: acl: extract matchall logic into a separate file Maksym Glubokiy
  2022-08-23 11:39 ` [PATCH net-next 2/3] net: prestera: add support for egress traffic mirroring Maksym Glubokiy
@ 2022-08-23 11:39 ` Maksym Glubokiy
  2022-08-26  9:20 ` [PATCH net-next 0/3] net: prestera: matchall features patchwork-bot+netdevbpf
  3 siblings, 0 replies; 7+ messages in thread
From: Maksym Glubokiy @ 2022-08-23 11:39 UTC (permalink / raw)
  To: Taras Chornyi, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni
  Cc: Maksym Glubokiy, Serhiy Boiko, netdev, linux-kernel

matchall rules can be added only to chain 0 and their priorities have
limitations:
 - new matchall ingress rule's priority must be higher (lower value)
   than any existing flower rule;
 - new matchall egress rule's priority must be lower (higher value)
   than any existing flower rule.

The opposite works for flower rule adding:
 - new flower ingress rule's priority must be lower (higher value)
   than any existing matchall rule;
 - new flower egress rule's priority must be higher (lower value)
   than any existing matchall rule.

This is a hardware limitation and thus must be properly handled in
driver by reporting errors to the user when newly added rule has such a
priority that cannot be installed into the hardware.

To achieve this, the driver must maintain both min/max matchall
priorities for every flower block when user adds/deletes a matchall
rule, as well as both min/max flower priorities for chain 0 for every
adding/deletion of flower rules for chain 0.

Cc: Serhiy Boiko <serhiy.boiko@plvision.eu>
Signed-off-by: Maksym Glubokiy <maksym.glubokiy@plvision.eu>
---
 .../ethernet/marvell/prestera/prestera_acl.c  | 43 ++++++++++++++
 .../ethernet/marvell/prestera/prestera_acl.h  |  2 +
 .../ethernet/marvell/prestera/prestera_flow.c |  3 +
 .../ethernet/marvell/prestera/prestera_flow.h |  5 ++
 .../marvell/prestera/prestera_flower.c        | 48 +++++++++++++++
 .../marvell/prestera/prestera_flower.h        |  2 +
 .../marvell/prestera/prestera_matchall.c      | 58 +++++++++++++++++++
 .../marvell/prestera/prestera_matchall.h      |  2 +
 8 files changed, 163 insertions(+)

diff --git a/drivers/net/ethernet/marvell/prestera/prestera_acl.c b/drivers/net/ethernet/marvell/prestera/prestera_acl.c
index 3d4b85f2d541..0fa7541f0d7e 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_acl.c
+++ b/drivers/net/ethernet/marvell/prestera/prestera_acl.c
@@ -54,6 +54,10 @@ struct prestera_acl_ruleset {
 	struct prestera_acl_ruleset_ht_key ht_key;
 	struct rhashtable rule_ht;
 	struct prestera_acl *acl;
+	struct {
+		u32 min;
+		u32 max;
+	} prio;
 	unsigned long rule_count;
 	refcount_t refcount;
 	void *keymask;
@@ -162,6 +166,9 @@ prestera_acl_ruleset_create(struct prestera_acl *acl,
 	ruleset->pcl_id = PRESTERA_ACL_PCL_ID_MAKE((u8)uid, chain_index);
 	ruleset->index = uid;
 
+	ruleset->prio.min = UINT_MAX;
+	ruleset->prio.max = 0;
+
 	err = rhashtable_insert_fast(&acl->ruleset_ht, &ruleset->ht_node,
 				     prestera_acl_ruleset_ht_params);
 	if (err)
@@ -365,6 +372,26 @@ prestera_acl_ruleset_block_unbind(struct prestera_acl_ruleset *ruleset,
 	block->ruleset_zero = NULL;
 }
 
+static void
+prestera_acl_ruleset_prio_refresh(struct prestera_acl *acl,
+				  struct prestera_acl_ruleset *ruleset)
+{
+	struct prestera_acl_rule *rule;
+
+	ruleset->prio.min = UINT_MAX;
+	ruleset->prio.max = 0;
+
+	list_for_each_entry(rule, &acl->rules, list) {
+		if (ruleset->ingress != rule->ruleset->ingress)
+			continue;
+		if (ruleset->ht_key.chain_index != rule->chain_index)
+			continue;
+
+		ruleset->prio.min = min(ruleset->prio.min, rule->priority);
+		ruleset->prio.max = max(ruleset->prio.max, rule->priority);
+	}
+}
+
 void
 prestera_acl_rule_keymask_pcl_id_set(struct prestera_acl_rule *rule, u16 pcl_id)
 {
@@ -389,6 +416,13 @@ u32 prestera_acl_ruleset_index_get(const struct prestera_acl_ruleset *ruleset)
 	return ruleset->index;
 }
 
+void prestera_acl_ruleset_prio_get(struct prestera_acl_ruleset *ruleset,
+				   u32 *prio_min, u32 *prio_max)
+{
+	*prio_min = ruleset->prio.min;
+	*prio_max = ruleset->prio.max;
+}
+
 bool prestera_acl_ruleset_is_offload(struct prestera_acl_ruleset *ruleset)
 {
 	return ruleset->offload;
@@ -429,6 +463,13 @@ void prestera_acl_rule_destroy(struct prestera_acl_rule *rule)
 	kfree(rule);
 }
 
+static void prestera_acl_ruleset_prio_update(struct prestera_acl_ruleset *ruleset,
+					     u32 prio)
+{
+	ruleset->prio.min = min(ruleset->prio.min, prio);
+	ruleset->prio.max = max(ruleset->prio.max, prio);
+}
+
 int prestera_acl_rule_add(struct prestera_switch *sw,
 			  struct prestera_acl_rule *rule)
 {
@@ -468,6 +509,7 @@ int prestera_acl_rule_add(struct prestera_switch *sw,
 
 	list_add_tail(&rule->list, &sw->acl->rules);
 	ruleset->rule_count++;
+	prestera_acl_ruleset_prio_update(ruleset, rule->priority);
 	return 0;
 
 err_acl_block_bind:
@@ -492,6 +534,7 @@ void prestera_acl_rule_del(struct prestera_switch *sw,
 	list_del(&rule->list);
 
 	prestera_acl_rule_entry_destroy(sw->acl, rule->re);
+	prestera_acl_ruleset_prio_refresh(sw->acl, ruleset);
 
 	/* unbind block (all ports) */
 	if (!ruleset->ht_key.chain_index && !ruleset->rule_count)
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_acl.h b/drivers/net/ethernet/marvell/prestera/prestera_acl.h
index 03fc5b9dc925..d45ee88e8287 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_acl.h
+++ b/drivers/net/ethernet/marvell/prestera/prestera_acl.h
@@ -195,6 +195,8 @@ int prestera_acl_ruleset_bind(struct prestera_acl_ruleset *ruleset,
 int prestera_acl_ruleset_unbind(struct prestera_acl_ruleset *ruleset,
 				struct prestera_port *port);
 u32 prestera_acl_ruleset_index_get(const struct prestera_acl_ruleset *ruleset);
+void prestera_acl_ruleset_prio_get(struct prestera_acl_ruleset *ruleset,
+				   u32 *prio_min, u32 *prio_max);
 void
 prestera_acl_rule_keymask_pcl_id_set(struct prestera_acl_rule *rule,
 				     u16 pcl_id);
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_flow.c b/drivers/net/ethernet/marvell/prestera/prestera_flow.c
index 3f81eef167fa..9f4267f326b0 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_flow.c
+++ b/drivers/net/ethernet/marvell/prestera/prestera_flow.c
@@ -90,6 +90,9 @@ prestera_flow_block_create(struct prestera_switch *sw,
 	INIT_LIST_HEAD(&block->template_list);
 	block->net = net;
 	block->sw = sw;
+	block->mall.prio_min = UINT_MAX;
+	block->mall.prio_max = 0;
+	block->mall.bound = false;
 	block->ingress = ingress;
 
 	return block;
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_flow.h b/drivers/net/ethernet/marvell/prestera/prestera_flow.h
index 0c9e13263261..a85a3eb40279 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_flow.h
+++ b/drivers/net/ethernet/marvell/prestera/prestera_flow.h
@@ -22,6 +22,11 @@ struct prestera_flow_block {
 	struct prestera_acl_ruleset *ruleset_zero;
 	struct flow_block_cb *block_cb;
 	struct list_head template_list;
+	struct {
+		u32 prio_min;
+		u32 prio_max;
+		bool bound;
+	} mall;
 	unsigned int rule_count;
 	bool ingress;
 };
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_flower.c b/drivers/net/ethernet/marvell/prestera/prestera_flower.c
index 19d3b55c578e..f38e8b3a543e 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_flower.c
+++ b/drivers/net/ethernet/marvell/prestera/prestera_flower.c
@@ -5,6 +5,7 @@
 #include "prestera_acl.h"
 #include "prestera_flow.h"
 #include "prestera_flower.h"
+#include "prestera_matchall.h"
 
 struct prestera_flower_template {
 	struct prestera_acl_ruleset *ruleset;
@@ -360,6 +361,49 @@ static int prestera_flower_parse(struct prestera_flow_block *block,
 					     f->common.extack);
 }
 
+static int prestera_flower_prio_check(struct prestera_flow_block *block,
+				      struct flow_cls_offload *f)
+{
+	u32 mall_prio_min;
+	u32 mall_prio_max;
+	int err;
+
+	err = prestera_mall_prio_get(block, &mall_prio_min, &mall_prio_max);
+	if (err == -ENOENT)
+		/* No matchall filters installed on this chain. */
+		return 0;
+
+	if (err) {
+		NL_SET_ERR_MSG(f->common.extack, "Failed to get matchall priorities");
+		return err;
+	}
+
+	if (f->common.prio <= mall_prio_max && block->ingress) {
+		NL_SET_ERR_MSG(f->common.extack,
+			       "Failed to add in front of existing matchall rules");
+		return -EOPNOTSUPP;
+	}
+	if (f->common.prio >= mall_prio_min && !block->ingress) {
+		NL_SET_ERR_MSG(f->common.extack, "Failed to add behind of existing matchall rules");
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+int prestera_flower_prio_get(struct prestera_flow_block *block, u32 chain_index,
+			     u32 *prio_min, u32 *prio_max)
+{
+	struct prestera_acl_ruleset *ruleset;
+
+	ruleset = prestera_acl_ruleset_lookup(block->sw->acl, block, chain_index);
+	if (IS_ERR(ruleset))
+		return PTR_ERR(ruleset);
+
+	prestera_acl_ruleset_prio_get(ruleset, prio_min, prio_max);
+	return 0;
+}
+
 int prestera_flower_replace(struct prestera_flow_block *block,
 			    struct flow_cls_offload *f)
 {
@@ -368,6 +412,10 @@ int prestera_flower_replace(struct prestera_flow_block *block,
 	struct prestera_acl_rule *rule;
 	int err;
 
+	err = prestera_flower_prio_check(block, f);
+	if (err)
+		return err;
+
 	ruleset = prestera_acl_ruleset_get(acl, block, f->common.chain_index);
 	if (IS_ERR(ruleset))
 		return PTR_ERR(ruleset);
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_flower.h b/drivers/net/ethernet/marvell/prestera/prestera_flower.h
index 495f151e6fa9..1181115fe6fa 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_flower.h
+++ b/drivers/net/ethernet/marvell/prestera/prestera_flower.h
@@ -19,5 +19,7 @@ int prestera_flower_tmplt_create(struct prestera_flow_block *block,
 void prestera_flower_tmplt_destroy(struct prestera_flow_block *block,
 				   struct flow_cls_offload *f);
 void prestera_flower_template_cleanup(struct prestera_flow_block *block);
+int prestera_flower_prio_get(struct prestera_flow_block *block, u32 chain_index,
+			     u32 *prio_min, u32 *prio_max);
 
 #endif /* _PRESTERA_FLOWER_H_ */
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_matchall.c b/drivers/net/ethernet/marvell/prestera/prestera_matchall.c
index 3fc13176e046..6f2b95a5263e 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_matchall.c
+++ b/drivers/net/ethernet/marvell/prestera/prestera_matchall.c
@@ -11,6 +11,54 @@
 #include "prestera_matchall.h"
 #include "prestera_span.h"
 
+static int prestera_mall_prio_check(struct prestera_flow_block *block,
+				    struct tc_cls_matchall_offload *f)
+{
+	u32 flower_prio_min;
+	u32 flower_prio_max;
+	int err;
+
+	err = prestera_flower_prio_get(block, f->common.chain_index,
+				       &flower_prio_min, &flower_prio_max);
+	if (err == -ENOENT)
+		/* No flower filters installed on this chain. */
+		return 0;
+
+	if (err) {
+		NL_SET_ERR_MSG(f->common.extack, "Failed to get flower priorities");
+		return err;
+	}
+
+	if (f->common.prio <= flower_prio_max && !block->ingress) {
+		NL_SET_ERR_MSG(f->common.extack, "Failed to add in front of existing flower rules");
+		return -EOPNOTSUPP;
+	}
+	if (f->common.prio >= flower_prio_min && block->ingress) {
+		NL_SET_ERR_MSG(f->common.extack, "Failed to add behind of existing flower rules");
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+int prestera_mall_prio_get(struct prestera_flow_block *block,
+			   u32 *prio_min, u32 *prio_max)
+{
+	if (!block->mall.bound)
+		return -ENOENT;
+
+	*prio_min = block->mall.prio_min;
+	*prio_max = block->mall.prio_max;
+	return 0;
+}
+
+static void prestera_mall_prio_update(struct prestera_flow_block *block,
+				      struct tc_cls_matchall_offload *f)
+{
+	block->mall.prio_min = min(block->mall.prio_min, f->common.prio);
+	block->mall.prio_max = max(block->mall.prio_max, f->common.prio);
+}
+
 int prestera_mall_replace(struct prestera_flow_block *block,
 			  struct tc_cls_matchall_offload *f)
 {
@@ -40,6 +88,10 @@ int prestera_mall_replace(struct prestera_flow_block *block,
 	if (protocol != htons(ETH_P_ALL))
 		return -EOPNOTSUPP;
 
+	err = prestera_mall_prio_check(block, f);
+	if (err)
+		return err;
+
 	port = netdev_priv(act->dev);
 
 	list_for_each_entry(binding, &block->binding_list, list) {
@@ -48,6 +100,9 @@ int prestera_mall_replace(struct prestera_flow_block *block,
 			goto rollback;
 	}
 
+	prestera_mall_prio_update(block, f);
+
+	block->mall.bound = true;
 	return 0;
 
 rollback:
@@ -64,4 +119,7 @@ void prestera_mall_destroy(struct prestera_flow_block *block)
 	list_for_each_entry(binding, &block->binding_list, list)
 		prestera_span_rule_del(binding, block->ingress);
 
+	block->mall.prio_min = UINT_MAX;
+	block->mall.prio_max = 0;
+	block->mall.bound = false;
 }
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_matchall.h b/drivers/net/ethernet/marvell/prestera/prestera_matchall.h
index 31ad4d02ecbb..fed08be80257 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_matchall.h
+++ b/drivers/net/ethernet/marvell/prestera/prestera_matchall.h
@@ -11,5 +11,7 @@ struct prestera_flow_block;
 int prestera_mall_replace(struct prestera_flow_block *block,
 			  struct tc_cls_matchall_offload *f);
 void prestera_mall_destroy(struct prestera_flow_block *block);
+int prestera_mall_prio_get(struct prestera_flow_block *block,
+			   u32 *prio_min, u32 *prio_max);
 
 #endif /* _PRESTERA_MATCHALL_H_ */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH net-next 1/3] net: prestera: acl: extract matchall logic into a separate file
  2022-08-23 11:39 ` [PATCH net-next 1/3] net: prestera: acl: extract matchall logic into a separate file Maksym Glubokiy
@ 2022-08-25 11:11   ` Paolo Abeni
  2022-08-25 11:43     ` Maksym Glubokiy
  0 siblings, 1 reply; 7+ messages in thread
From: Paolo Abeni @ 2022-08-25 11:11 UTC (permalink / raw)
  To: Maksym Glubokiy, Taras Chornyi, David S. Miller, Eric Dumazet,
	Jakub Kicinski
  Cc: Serhiy Boiko, linux-kernel, netdev

Hello,

On Tue, 2022-08-23 at 14:39 +0300, Maksym Glubokiy wrote:
> From: Serhiy Boiko <serhiy.boiko@plvision.eu>
> 
> This commit adds more clarity to handling of TC_CLSMATCHALL_REPLACE and
> TC_CLSMATCHALL_DESTROY events by calling newly added *_mall_*() handlers
> instead of directly calling SPAN API.
> 
> This also extracts matchall rules management out of SPAN API since SPAN
> is a hardware module which is used to implement 'matchall egress mirred'
> action only.
> 
> Signed-off-by: Taras Chornyi <tchornyi@marvell.com>
> Signed-off-by: Serhiy Boiko <serhiy.boiko@plvision.eu>
> Signed-off-by: Maksym Glubokiy <maksym.glubokiy@plvision.eu>

This SoB chain is not clear to me. Did Taras co-developed the patch? In
that case a Co-developed-by: tag is missing, as the first tag in the
list. Otherwise why is Taras' SoB there?

Thanks!

Paolo


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH net-next 1/3] net: prestera: acl: extract matchall logic into a separate file
  2022-08-25 11:11   ` Paolo Abeni
@ 2022-08-25 11:43     ` Maksym Glubokiy
  0 siblings, 0 replies; 7+ messages in thread
From: Maksym Glubokiy @ 2022-08-25 11:43 UTC (permalink / raw)
  To: Paolo Abeni
  Cc: Taras Chornyi, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Serhiy Boiko, linux-kernel, netdev

On Thu, Aug 25, 2022 at 01:11:35PM +0200, Paolo Abeni wrote:
> Hello,
> 
> On Tue, 2022-08-23 at 14:39 +0300, Maksym Glubokiy wrote:
> > From: Serhiy Boiko <serhiy.boiko@plvision.eu>
> > 
> > This commit adds more clarity to handling of TC_CLSMATCHALL_REPLACE and
> > TC_CLSMATCHALL_DESTROY events by calling newly added *_mall_*() handlers
> > instead of directly calling SPAN API.
> > 
> > This also extracts matchall rules management out of SPAN API since SPAN
> > is a hardware module which is used to implement 'matchall egress mirred'
> > action only.
> > 
> > Signed-off-by: Taras Chornyi <tchornyi@marvell.com>
> > Signed-off-by: Serhiy Boiko <serhiy.boiko@plvision.eu>
> > Signed-off-by: Maksym Glubokiy <maksym.glubokiy@plvision.eu>
> 
> This SoB chain is not clear to me. Did Taras co-developed the patch? In
> that case a Co-developed-by: tag is missing, as the first tag in the
> list. Otherwise why is Taras' SoB there?
There are new files being added with Marvel's copyright and my understanding is
that there must be someone from Marvel on SoB list in such a case.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH net-next 0/3] net: prestera: matchall features
  2022-08-23 11:39 [PATCH net-next 0/3] net: prestera: matchall features Maksym Glubokiy
                   ` (2 preceding siblings ...)
  2022-08-23 11:39 ` [PATCH net-next 3/3] net: prestera: manage matchall and flower priorities Maksym Glubokiy
@ 2022-08-26  9:20 ` patchwork-bot+netdevbpf
  3 siblings, 0 replies; 7+ messages in thread
From: patchwork-bot+netdevbpf @ 2022-08-26  9:20 UTC (permalink / raw)
  To: Maksym Glubokiy
  Cc: davem, edumazet, kuba, pabeni, tchornyi, serhiy.boiko,
	linux-kernel, netdev

Hello:

This series was applied to netdev/net-next.git (master)
by David S. Miller <davem@davemloft.net>:

On Tue, 23 Aug 2022 14:39:55 +0300 you wrote:
> This patch series extracts matchall rules management out of SPAN API
> implementation and adds 2 features on top of that:
>   - support for egress traffic (mirred egress action)
>   - proper rule priorities management between matchall and flower
> 
> Maksym Glubokiy (1):
>   net: prestera: manage matchall and flower priorities
> 
> [...]

Here is the summary with links:
  - [net-next,1/3] net: prestera: acl: extract matchall logic into a separate file
    https://git.kernel.org/netdev/net-next/c/8afd552db463
  - [net-next,2/3] net: prestera: add support for egress traffic mirroring
    https://git.kernel.org/netdev/net-next/c/8c448c2b5fd2
  - [net-next,3/3] net: prestera: manage matchall and flower priorities
    https://git.kernel.org/netdev/net-next/c/44af95718fed

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2022-08-26  9:20 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-23 11:39 [PATCH net-next 0/3] net: prestera: matchall features Maksym Glubokiy
2022-08-23 11:39 ` [PATCH net-next 1/3] net: prestera: acl: extract matchall logic into a separate file Maksym Glubokiy
2022-08-25 11:11   ` Paolo Abeni
2022-08-25 11:43     ` Maksym Glubokiy
2022-08-23 11:39 ` [PATCH net-next 2/3] net: prestera: add support for egress traffic mirroring Maksym Glubokiy
2022-08-23 11:39 ` [PATCH net-next 3/3] net: prestera: manage matchall and flower priorities Maksym Glubokiy
2022-08-26  9:20 ` [PATCH net-next 0/3] net: prestera: matchall features patchwork-bot+netdevbpf

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).