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: Taras Chornyi <tchornyi@marvell.com> Signed-off-by: Serhiy Boiko <serhiy.boiko@plvision.eu> Signed-off-by: Maksym Glubokiy <maksym.glubokiy@plvision.eu> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
6661918c3b
commit
8afd552db4
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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_ */
|
|
@ -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;
|
||||
|
|
|
@ -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_ */
|
||||
|
|
Loading…
Reference in New Issue