Commit 8afd552d authored by Serhiy Boiko's avatar Serhiy Boiko Committed by David S. Miller
Browse files

net: prestera: acl: extract matchall logic into a separate file



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: default avatarTaras Chornyi <tchornyi@marvell.com>
Signed-off-by: default avatarSerhiy Boiko <serhiy.boiko@plvision.eu>
Signed-off-by: default avatarMaksym Glubokiy <maksym.glubokiy@plvision.eu>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6661918c
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
+5 −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;
@@ -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)
+66 −0
Original line number Diff line number Diff line
// 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);
}
+15 −0
Original line number Diff line number Diff line
/* 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_ */
+3 −57
Original line number Diff line number Diff line
@@ -120,7 +120,7 @@ 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,
int prestera_span_rule_add(struct prestera_flow_block_binding *binding,
			   struct prestera_port *to_port)
{
	struct prestera_switch *sw = binding->port->sw;
@@ -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;
Loading