Skip to content

Commit 95706be

Browse files
vladimirolteankuba-moo
authored andcommitted
net: mscc: ocelot: create a function that replaces an existing VCAP filter
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 <[email protected]> Acked-by: Richard Cochran <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 8a07546 commit 95706be

File tree

2 files changed

+18
-0
lines changed

2 files changed

+18
-0
lines changed

drivers/net/ethernet/mscc/ocelot_vcap.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,6 +1217,22 @@ int ocelot_vcap_filter_del(struct ocelot *ocelot,
12171217
}
12181218
EXPORT_SYMBOL(ocelot_vcap_filter_del);
12191219

1220+
int ocelot_vcap_filter_replace(struct ocelot *ocelot,
1221+
struct ocelot_vcap_filter *filter)
1222+
{
1223+
struct ocelot_vcap_block *block = &ocelot->block[filter->block_id];
1224+
int index;
1225+
1226+
index = ocelot_vcap_block_get_filter_index(block, filter);
1227+
if (index < 0)
1228+
return index;
1229+
1230+
vcap_entry_set(ocelot, index, filter);
1231+
1232+
return 0;
1233+
}
1234+
EXPORT_SYMBOL(ocelot_vcap_filter_replace);
1235+
12201236
int ocelot_vcap_filter_stats_update(struct ocelot *ocelot,
12211237
struct ocelot_vcap_filter *filter)
12221238
{

include/soc/mscc/ocelot_vcap.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,8 @@ int ocelot_vcap_filter_add(struct ocelot *ocelot,
703703
struct netlink_ext_ack *extack);
704704
int ocelot_vcap_filter_del(struct ocelot *ocelot,
705705
struct ocelot_vcap_filter *rule);
706+
int ocelot_vcap_filter_replace(struct ocelot *ocelot,
707+
struct ocelot_vcap_filter *filter);
706708
struct ocelot_vcap_filter *
707709
ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block,
708710
unsigned long cookie, bool tc_offload);

0 commit comments

Comments
 (0)