Commit 5b3b51a1 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'prestera-matchall'



Maksym Glubokiy says:

====================
net: prestera: matchall features

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
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 6661918c 44af9571
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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
+43 −0
Original line number Diff line number Diff line
@@ -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)
+2 −0
Original line number Diff line number Diff line
@@ -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);
+8 −4
Original line number Diff line number Diff line
@@ -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;
@@ -89,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;
@@ -263,7 +267,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)
+5 −0
Original line number Diff line number Diff line
@@ -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;
};
Loading