Commit c54e1d92 authored by Baowen Zheng's avatar Baowen Zheng Committed by David S. Miller
Browse files

flow_offload: add ops to tc_action_ops for flow action setup



Add a new ops to tc_action_ops for flow action setup.

Refactor function tc_setup_flow_action to use this new ops.

We make this change to facilitate to add standalone action module.

We will also use this ops to offload action independent of filter
in following patch.

Signed-off-by: default avatarBaowen Zheng <baowen.zheng@corigine.com>
Signed-off-by: default avatarSimon Horman <simon.horman@corigine.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9c1c0e12
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -88,6 +88,16 @@ static inline void tcf_tm_dump(struct tcf_t *dtm, const struct tcf_t *stm)
	dtm->expires = jiffies_to_clock_t(stm->expires);
}

static inline enum flow_action_hw_stats tc_act_hw_stats(u8 hw_stats)
{
	if (WARN_ON_ONCE(hw_stats > TCA_ACT_HW_STATS_ANY))
		return FLOW_ACTION_HW_STATS_DONT_CARE;
	else if (!hw_stats)
		return FLOW_ACTION_HW_STATS_DISABLED;

	return hw_stats;
}

#ifdef CONFIG_NET_CLS_ACT

#define ACT_P_CREATED 1
@@ -121,6 +131,8 @@ struct tc_action_ops {
	struct psample_group *
	(*get_psample_group)(const struct tc_action *a,
			     tc_action_priv_destructor *destructor);
	int     (*offload_act_setup)(struct tc_action *act, void *entry_data,
				     u32 *index_inc, bool bind);
};

struct tc_action_net {
+17 −0
Original line number Diff line number Diff line
@@ -695,6 +695,22 @@ static size_t tcf_csum_get_fill_size(const struct tc_action *act)
	return nla_total_size(sizeof(struct tc_csum));
}

static int tcf_csum_offload_act_setup(struct tc_action *act, void *entry_data,
				      u32 *index_inc, bool bind)
{
	if (bind) {
		struct flow_action_entry *entry = entry_data;

		entry->id = FLOW_ACTION_CSUM;
		entry->csum_flags = tcf_csum_update_flags(act);
		*index_inc = 1;
	} else {
		return -EOPNOTSUPP;
	}

	return 0;
}

static struct tc_action_ops act_csum_ops = {
	.kind		= "csum",
	.id		= TCA_ID_CSUM,
@@ -706,6 +722,7 @@ static struct tc_action_ops act_csum_ops = {
	.walk		= tcf_csum_walker,
	.lookup		= tcf_csum_search,
	.get_fill_size  = tcf_csum_get_fill_size,
	.offload_act_setup = tcf_csum_offload_act_setup,
	.size		= sizeof(struct tcf_csum),
};

+19 −0
Original line number Diff line number Diff line
@@ -1493,6 +1493,24 @@ static void tcf_stats_update(struct tc_action *a, u64 bytes, u64 packets,
	c->tcf_tm.lastuse = max_t(u64, c->tcf_tm.lastuse, lastuse);
}

static int tcf_ct_offload_act_setup(struct tc_action *act, void *entry_data,
				    u32 *index_inc, bool bind)
{
	if (bind) {
		struct flow_action_entry *entry = entry_data;

		entry->id = FLOW_ACTION_CT;
		entry->ct.action = tcf_ct_action(act);
		entry->ct.zone = tcf_ct_zone(act);
		entry->ct.flow_table = tcf_ct_ft(act);
		*index_inc = 1;
	} else {
		return -EOPNOTSUPP;
	}

	return 0;
}

static struct tc_action_ops act_ct_ops = {
	.kind		=	"ct",
	.id		=	TCA_ID_CT,
@@ -1504,6 +1522,7 @@ static struct tc_action_ops act_ct_ops = {
	.walk		=	tcf_ct_walker,
	.lookup		=	tcf_ct_search,
	.stats_update	=	tcf_stats_update,
	.offload_act_setup =	tcf_ct_offload_act_setup,
	.size		=	sizeof(struct tcf_ct),
};

+27 −0
Original line number Diff line number Diff line
@@ -252,6 +252,32 @@ static size_t tcf_gact_get_fill_size(const struct tc_action *act)
	return sz;
}

static int tcf_gact_offload_act_setup(struct tc_action *act, void *entry_data,
				      u32 *index_inc, bool bind)
{
	if (bind) {
		struct flow_action_entry *entry = entry_data;

		if (is_tcf_gact_ok(act)) {
			entry->id = FLOW_ACTION_ACCEPT;
		} else if (is_tcf_gact_shot(act)) {
			entry->id = FLOW_ACTION_DROP;
		} else if (is_tcf_gact_trap(act)) {
			entry->id = FLOW_ACTION_TRAP;
		} else if (is_tcf_gact_goto_chain(act)) {
			entry->id = FLOW_ACTION_GOTO;
			entry->chain_index = tcf_gact_goto_chain_index(act);
		} else {
			return -EOPNOTSUPP;
		}
		*index_inc = 1;
	} else {
		return -EOPNOTSUPP;
	}

	return 0;
}

static struct tc_action_ops act_gact_ops = {
	.kind		=	"gact",
	.id		=	TCA_ID_GACT,
@@ -263,6 +289,7 @@ static struct tc_action_ops act_gact_ops = {
	.walk		=	tcf_gact_walker,
	.lookup		=	tcf_gact_search,
	.get_fill_size	=	tcf_gact_get_fill_size,
	.offload_act_setup =	tcf_gact_offload_act_setup,
	.size		=	sizeof(struct tcf_gact),
};

+47 −0
Original line number Diff line number Diff line
@@ -597,6 +597,52 @@ static size_t tcf_gate_get_fill_size(const struct tc_action *act)
	return nla_total_size(sizeof(struct tc_gate));
}

static void tcf_gate_entry_destructor(void *priv)
{
	struct action_gate_entry *oe = priv;

	kfree(oe);
}

static int tcf_gate_get_entries(struct flow_action_entry *entry,
				const struct tc_action *act)
{
	entry->gate.entries = tcf_gate_get_list(act);

	if (!entry->gate.entries)
		return -EINVAL;

	entry->destructor = tcf_gate_entry_destructor;
	entry->destructor_priv = entry->gate.entries;

	return 0;
}

static int tcf_gate_offload_act_setup(struct tc_action *act, void *entry_data,
				      u32 *index_inc, bool bind)
{
	int err;

	if (bind) {
		struct flow_action_entry *entry = entry_data;

		entry->id = FLOW_ACTION_GATE;
		entry->gate.prio = tcf_gate_prio(act);
		entry->gate.basetime = tcf_gate_basetime(act);
		entry->gate.cycletime = tcf_gate_cycletime(act);
		entry->gate.cycletimeext = tcf_gate_cycletimeext(act);
		entry->gate.num_entries = tcf_gate_num_entries(act);
		err = tcf_gate_get_entries(entry, act);
		if (err)
			return err;
		*index_inc = 1;
	} else {
		return -EOPNOTSUPP;
	}

	return 0;
}

static struct tc_action_ops act_gate_ops = {
	.kind		=	"gate",
	.id		=	TCA_ID_GATE,
@@ -609,6 +655,7 @@ static struct tc_action_ops act_gate_ops = {
	.stats_update	=	tcf_gate_stats_update,
	.get_fill_size	=	tcf_gate_get_fill_size,
	.lookup		=	tcf_gate_search,
	.offload_act_setup =	tcf_gate_offload_act_setup,
	.size		=	sizeof(struct tcf_gate),
};

Loading