Commit 4ba28c1a authored by Ioana Ciornei's avatar Ioana Ciornei Committed by David S. Miller

dpaa2-switch: add tc matchall filter support

Add support TC_SETUP_CLSMATCHALL by using the same ACL table entries
framework as for tc flower. Adding a matchall rule is done by installing
an entry which has a mask of all zeroes, thus matching on any packet.

This can be used as a catch-all type of rule if used correctly, ie the
priority of the matchall filter should be kept as the lowest one in the
entire filter block.
Signed-off-by: default avatarIoana Ciornei <ioana.ciornei@nxp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1110318d
...@@ -434,3 +434,59 @@ int dpaa2_switch_cls_flower_destroy(struct dpaa2_switch_acl_tbl *acl_tbl, ...@@ -434,3 +434,59 @@ int dpaa2_switch_cls_flower_destroy(struct dpaa2_switch_acl_tbl *acl_tbl,
return dpaa2_switch_acl_tbl_remove_entry(acl_tbl, entry); return dpaa2_switch_acl_tbl_remove_entry(acl_tbl, entry);
} }
int dpaa2_switch_cls_matchall_replace(struct dpaa2_switch_acl_tbl *acl_tbl,
struct tc_cls_matchall_offload *cls)
{
struct netlink_ext_ack *extack = cls->common.extack;
struct ethsw_core *ethsw = acl_tbl->ethsw;
struct dpaa2_switch_acl_entry *acl_entry;
struct flow_action_entry *act;
int err;
if (!flow_offload_has_one_action(&cls->rule->action)) {
NL_SET_ERR_MSG(extack, "Only singular actions are supported");
return -EOPNOTSUPP;
}
if (dpaa2_switch_acl_tbl_is_full(acl_tbl)) {
NL_SET_ERR_MSG(extack, "Maximum filter capacity reached");
return -ENOMEM;
}
acl_entry = kzalloc(sizeof(*acl_entry), GFP_KERNEL);
if (!acl_entry)
return -ENOMEM;
act = &cls->rule->action.entries[0];
err = dpaa2_switch_tc_parse_action(ethsw, act,
&acl_entry->cfg.result, extack);
if (err)
goto free_acl_entry;
acl_entry->prio = cls->common.prio;
acl_entry->cookie = cls->cookie;
err = dpaa2_switch_acl_tbl_add_entry(acl_tbl, acl_entry);
if (err)
goto free_acl_entry;
return 0;
free_acl_entry:
kfree(acl_entry);
return err;
}
int dpaa2_switch_cls_matchall_destroy(struct dpaa2_switch_acl_tbl *acl_tbl,
struct tc_cls_matchall_offload *cls)
{
struct dpaa2_switch_acl_entry *entry;
entry = dpaa2_switch_acl_tbl_find_entry_by_cookie(acl_tbl, cls->cookie);
if (!entry)
return 0;
return dpaa2_switch_acl_tbl_remove_entry(acl_tbl, entry);
}
...@@ -1140,6 +1140,20 @@ dpaa2_switch_setup_tc_cls_flower(struct dpaa2_switch_acl_tbl *acl_tbl, ...@@ -1140,6 +1140,20 @@ dpaa2_switch_setup_tc_cls_flower(struct dpaa2_switch_acl_tbl *acl_tbl,
} }
} }
static int
dpaa2_switch_setup_tc_cls_matchall(struct dpaa2_switch_acl_tbl *acl_tbl,
struct tc_cls_matchall_offload *f)
{
switch (f->command) {
case TC_CLSMATCHALL_REPLACE:
return dpaa2_switch_cls_matchall_replace(acl_tbl, f);
case TC_CLSMATCHALL_DESTROY:
return dpaa2_switch_cls_matchall_destroy(acl_tbl, f);
default:
return -EOPNOTSUPP;
}
}
static int dpaa2_switch_port_setup_tc_block_cb_ig(enum tc_setup_type type, static int dpaa2_switch_port_setup_tc_block_cb_ig(enum tc_setup_type type,
void *type_data, void *type_data,
void *cb_priv) void *cb_priv)
...@@ -1147,6 +1161,8 @@ static int dpaa2_switch_port_setup_tc_block_cb_ig(enum tc_setup_type type, ...@@ -1147,6 +1161,8 @@ static int dpaa2_switch_port_setup_tc_block_cb_ig(enum tc_setup_type type,
switch (type) { switch (type) {
case TC_SETUP_CLSFLOWER: case TC_SETUP_CLSFLOWER:
return dpaa2_switch_setup_tc_cls_flower(cb_priv, type_data); return dpaa2_switch_setup_tc_cls_flower(cb_priv, type_data);
case TC_SETUP_CLSMATCHALL:
return dpaa2_switch_setup_tc_cls_matchall(cb_priv, type_data);
default: default:
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <net/switchdev.h> #include <net/switchdev.h>
#include <linux/if_bridge.h> #include <linux/if_bridge.h>
#include <linux/fsl/mc.h> #include <linux/fsl/mc.h>
#include <net/pkt_cls.h>
#include <soc/fsl/dpaa2-io.h> #include <soc/fsl/dpaa2-io.h>
#include "dpsw.h" #include "dpsw.h"
...@@ -233,4 +234,10 @@ int dpaa2_switch_cls_flower_replace(struct dpaa2_switch_acl_tbl *acl_tbl, ...@@ -233,4 +234,10 @@ int dpaa2_switch_cls_flower_replace(struct dpaa2_switch_acl_tbl *acl_tbl,
int dpaa2_switch_cls_flower_destroy(struct dpaa2_switch_acl_tbl *acl_tbl, int dpaa2_switch_cls_flower_destroy(struct dpaa2_switch_acl_tbl *acl_tbl,
struct flow_cls_offload *cls); struct flow_cls_offload *cls);
int dpaa2_switch_cls_matchall_replace(struct dpaa2_switch_acl_tbl *acl_tbl,
struct tc_cls_matchall_offload *cls);
int dpaa2_switch_cls_matchall_destroy(struct dpaa2_switch_acl_tbl *acl_tbl,
struct tc_cls_matchall_offload *cls);
#endif /* __ETHSW_H */ #endif /* __ETHSW_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment