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_rxtx.o prestera_devlink.o prestera_ethtool.o \
|
||||||
prestera_switchdev.o prestera_acl.o prestera_flow.o \
|
prestera_switchdev.o prestera_acl.o prestera_flow.o \
|
||||||
prestera_flower.o prestera_span.o prestera_counter.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
|
obj-$(CONFIG_PRESTERA_PCI) += prestera_pci.o
|
||||||
|
|
|
@ -7,8 +7,9 @@
|
||||||
#include "prestera.h"
|
#include "prestera.h"
|
||||||
#include "prestera_acl.h"
|
#include "prestera_acl.h"
|
||||||
#include "prestera_flow.h"
|
#include "prestera_flow.h"
|
||||||
#include "prestera_span.h"
|
|
||||||
#include "prestera_flower.h"
|
#include "prestera_flower.h"
|
||||||
|
#include "prestera_matchall.h"
|
||||||
|
#include "prestera_span.h"
|
||||||
|
|
||||||
static LIST_HEAD(prestera_block_cb_list);
|
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) {
|
switch (f->command) {
|
||||||
case TC_CLSMATCHALL_REPLACE:
|
case TC_CLSMATCHALL_REPLACE:
|
||||||
return prestera_span_replace(block, f);
|
return prestera_mall_replace(block, f);
|
||||||
case TC_CLSMATCHALL_DESTROY:
|
case TC_CLSMATCHALL_DESTROY:
|
||||||
prestera_span_destroy(block);
|
prestera_mall_destroy(block);
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
@ -263,7 +264,7 @@ static void prestera_setup_flow_block_unbind(struct prestera_port *port,
|
||||||
|
|
||||||
block = flow_block_cb_priv(block_cb);
|
block = flow_block_cb_priv(block_cb);
|
||||||
|
|
||||||
prestera_span_destroy(block);
|
prestera_mall_destroy(block);
|
||||||
|
|
||||||
err = prestera_flow_block_unbind(block, port);
|
err = prestera_flow_block_unbind(block, port);
|
||||||
if (err)
|
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;
|
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_port *to_port)
|
||||||
{
|
{
|
||||||
struct prestera_switch *sw = binding->port->sw;
|
struct prestera_switch *sw = binding->port->sw;
|
||||||
u8 span_id;
|
u8 span_id;
|
||||||
|
@ -145,7 +145,7 @@ static int prestera_span_rule_add(struct prestera_flow_block_binding *binding,
|
||||||
return 0;
|
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;
|
int err;
|
||||||
|
|
||||||
|
@ -161,60 +161,6 @@ static int prestera_span_rule_del(struct prestera_flow_block_binding *binding)
|
||||||
return 0;
|
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)
|
int prestera_span_init(struct prestera_switch *sw)
|
||||||
{
|
{
|
||||||
struct prestera_span *span;
|
struct prestera_span *span;
|
||||||
|
|
|
@ -8,13 +8,15 @@
|
||||||
|
|
||||||
#define PRESTERA_SPAN_INVALID_ID -1
|
#define PRESTERA_SPAN_INVALID_ID -1
|
||||||
|
|
||||||
|
struct prestera_port;
|
||||||
struct prestera_switch;
|
struct prestera_switch;
|
||||||
struct prestera_flow_block;
|
struct prestera_flow_block_binding;
|
||||||
|
|
||||||
int prestera_span_init(struct prestera_switch *sw);
|
int prestera_span_init(struct prestera_switch *sw);
|
||||||
void prestera_span_fini(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);
|
int prestera_span_rule_add(struct prestera_flow_block_binding *binding,
|
||||||
void prestera_span_destroy(struct prestera_flow_block *block);
|
struct prestera_port *to_port);
|
||||||
|
int prestera_span_rule_del(struct prestera_flow_block_binding *binding);
|
||||||
|
|
||||||
#endif /* _PRESTERA_SPAN_H_ */
|
#endif /* _PRESTERA_SPAN_H_ */
|
||||||
|
|
Loading…
Reference in New Issue