[PATCH AUTOSEL 5.15 65/68] net: mscc: ocelot: create a function that replaces an existing VCAP filter

Subsystems: networking drivers, ocelot ethernet switch driver, the rest

STALE1711d REVIEWED: 1 (1M)

1 review trailer.

2 messages, 2 authors, 2021-12-04 · open the first message on its own page

[PATCH AUTOSEL 5.15 65/68] net: mscc: ocelot: create a function that replaces an existing VCAP filter

From: Sasha Levin <sashal@kernel.org>
Date: 2021-11-30 14:53:05

From: Vladimir Oltean <vladimir.oltean@nxp.com>

[ Upstream commit 95706be13b9f755d93b5b82bdc782af439f1ec22 ]

VCAP (Versatile Content Aware Processor) is the TCAM-based engine behind
tc flower offload on ocelot, among other things. The ingress port mask
on which VCAP rules match is present as a bit field in the actual key of
the rule. This means that it is possible for a rule to be shared among
multiple source ports. When the rule is added one by one on each desired
port, that the ingress port mask of the key must be edited and rewritten
to hardware.

But the API in ocelot_vcap.c does not allow for this. For one thing,
ocelot_vcap_filter_add() and ocelot_vcap_filter_del() are not symmetric,
because ocelot_vcap_filter_add() works with a preallocated and
prepopulated filter and programs it to hardware, and
ocelot_vcap_filter_del() does both the job of removing the specified
filter from hardware, as well as kfreeing it. That is to say, the only
option of editing a filter in place, which is to delete it, modify the
structure and add it back, does not work because it results in
use-after-free.

This patch introduces ocelot_vcap_filter_replace, which trivially
reprograms a VCAP entry to hardware, at the exact same index at which it
existed before, without modifying any list or allocating any memory.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Acked-by: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/mscc/ocelot_vcap.c | 16 ++++++++++++++++
 include/soc/mscc/ocelot_vcap.h          |  2 ++
 2 files changed, 18 insertions(+)
diff --git a/drivers/net/ethernet/mscc/ocelot_vcap.c b/drivers/net/ethernet/mscc/ocelot_vcap.c
index 99d7376a70a74..337cd08b1a543 100644
--- a/drivers/net/ethernet/mscc/ocelot_vcap.c
+++ b/drivers/net/ethernet/mscc/ocelot_vcap.c
@@ -1217,6 +1217,22 @@ int ocelot_vcap_filter_del(struct ocelot *ocelot,
 }
 EXPORT_SYMBOL(ocelot_vcap_filter_del);
 
+int ocelot_vcap_filter_replace(struct ocelot *ocelot,
+			       struct ocelot_vcap_filter *filter)
+{
+	struct ocelot_vcap_block *block = &ocelot->block[filter->block_id];
+	int index;
+
+	index = ocelot_vcap_block_get_filter_index(block, filter);
+	if (index < 0)
+		return index;
+
+	vcap_entry_set(ocelot, index, filter);
+
+	return 0;
+}
+EXPORT_SYMBOL(ocelot_vcap_filter_replace);
+
 int ocelot_vcap_filter_stats_update(struct ocelot *ocelot,
 				    struct ocelot_vcap_filter *filter)
 {
diff --git a/include/soc/mscc/ocelot_vcap.h b/include/soc/mscc/ocelot_vcap.h
index 4869ebbd438d9..56c19068d9911 100644
--- a/include/soc/mscc/ocelot_vcap.h
+++ b/include/soc/mscc/ocelot_vcap.h
@@ -693,6 +693,8 @@ int ocelot_vcap_filter_add(struct ocelot *ocelot,
 			   struct netlink_ext_ack *extack);
 int ocelot_vcap_filter_del(struct ocelot *ocelot,
 			   struct ocelot_vcap_filter *rule);
+int ocelot_vcap_filter_replace(struct ocelot *ocelot,
+			       struct ocelot_vcap_filter *filter);
 struct ocelot_vcap_filter *
 ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block,
 				    unsigned long cookie, bool tc_offload);
-- 
2.33.0

Re: [PATCH AUTOSEL 5.15 65/68] net: mscc: ocelot: create a function that replaces an existing VCAP filter

From: Vladimir Oltean <vladimir.oltean@nxp.com>
Date: 2021-12-04 14:46:52

Hi Sasha,

On Tue, Nov 30, 2021 at 09:47:01AM -0500, Sasha Levin wrote:
From: Vladimir Oltean <vladimir.oltean@nxp.com>

[ Upstream commit 95706be13b9f755d93b5b82bdc782af439f1ec22 ]

VCAP (Versatile Content Aware Processor) is the TCAM-based engine behind
tc flower offload on ocelot, among other things. The ingress port mask
on which VCAP rules match is present as a bit field in the actual key of
the rule. This means that it is possible for a rule to be shared among
multiple source ports. When the rule is added one by one on each desired
port, that the ingress port mask of the key must be edited and rewritten
to hardware.

But the API in ocelot_vcap.c does not allow for this. For one thing,
ocelot_vcap_filter_add() and ocelot_vcap_filter_del() are not symmetric,
because ocelot_vcap_filter_add() works with a preallocated and
prepopulated filter and programs it to hardware, and
ocelot_vcap_filter_del() does both the job of removing the specified
filter from hardware, as well as kfreeing it. That is to say, the only
option of editing a filter in place, which is to delete it, modify the
structure and add it back, does not work because it results in
use-after-free.

This patch introduces ocelot_vcap_filter_replace, which trivially
reprograms a VCAP entry to hardware, at the exact same index at which it
existed before, without modifying any list or allocating any memory.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Acked-by: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
It looks like something happened and the essence of this series, aka
this patch:
https://patchwork.kernel.org/project/netdevbpf/patch/20211126172845.3149260-5-vladimir.oltean@nxp.com/
did not or could not be backported.

In this case I am afraid that all the patches below are useless and can
be dropped:

[PATCH AUTOSEL 4.4 8/9] net: ptp: add a definition for the UDP port for IEEE 1588 general messages
[PATCH AUTOSEL 4.9 11/12] net: ptp: add a definition for the UDP port for IEEE 1588 general messages
[PATCH AUTOSEL 4.14 13/14] net: ptp: add a definition for the UDP port for IEEE 1588 general messages
[PATCH AUTOSEL 4.19 16/17] net: ptp: add a definition for the UDP port for IEEE 1588 general messages
[PATCH AUTOSEL 5.4 24/25] net: ptp: add a definition for the UDP port for IEEE 1588 general messages
[PATCH AUTOSEL 5.10 42/43] net: ptp: add a definition for the UDP port for IEEE 1588 general messages
[PATCH AUTOSEL 5.15 66/68] net: ptp: add a definition for the UDP port for IEEE 1588 general messages
[PATCH AUTOSEL 5.15 65/68] net: mscc: ocelot: create a function that replaces an existing VCAP filter

Thanks.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help