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

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
Loading
Loading
Loading
Loading
+56 −0
Original line number Diff line number Diff line
@@ -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);
}

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);
}
+16 −0
Original line number Diff line number Diff line
@@ -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,
						  void *type_data,
						  void *cb_priv)
@@ -1147,6 +1161,8 @@ static int dpaa2_switch_port_setup_tc_block_cb_ig(enum tc_setup_type type,
	switch (type) {
	case TC_SETUP_CLSFLOWER:
		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:
		return -EOPNOTSUPP;
	}
+7 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include <net/switchdev.h>
#include <linux/if_bridge.h>
#include <linux/fsl/mc.h>
#include <net/pkt_cls.h>
#include <soc/fsl/dpaa2-io.h>

#include "dpsw.h"
@@ -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,
				    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 */