Commit b8cd5831 authored by Jianbo Liu's avatar Jianbo Liu Committed by David S. Miller
Browse files

net: flow_offload: add tc police action parameters



The current police offload action entry is missing exceed/notexceed
actions and parameters that can be configured by tc police action.
Add the missing parameters as a pre-step for offloading police actions
to hardware.

Signed-off-by: default avatarJianbo Liu <jianbol@nvidia.com>
Signed-off-by: default avatarRoi Dayan <roid@nvidia.com>
Reviewed-by: default avatarIdo Schimmel <idosch@nvidia.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b42a738e
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -148,6 +148,8 @@ enum flow_action_id {
	FLOW_ACTION_MPLS_MANGLE,
	FLOW_ACTION_GATE,
	FLOW_ACTION_PPPOE_PUSH,
	FLOW_ACTION_JUMP,
	FLOW_ACTION_PIPE,
	NUM_FLOW_ACTIONS,
};

@@ -235,9 +237,16 @@ struct flow_action_entry {
		struct {				/* FLOW_ACTION_POLICE */
			u32			burst;
			u64			rate_bytes_ps;
			u64			peakrate_bytes_ps;
			u32			avrate;
			u16			overhead;
			u64			burst_pkt;
			u64			rate_pkt_ps;
			u32			mtu;
			struct {
				enum flow_action_id	act_id;
				u32			extval;
			} exceed, notexceed;
		} police;
		struct {				/* FLOW_ACTION_CT */
			int action;
+30 −0
Original line number Diff line number Diff line
@@ -159,4 +159,34 @@ static inline u32 tcf_police_tcfp_mtu(const struct tc_action *act)
	return params->tcfp_mtu;
}

static inline u64 tcf_police_peakrate_bytes_ps(const struct tc_action *act)
{
	struct tcf_police *police = to_police(act);
	struct tcf_police_params *params;

	params = rcu_dereference_protected(police->params,
					   lockdep_is_held(&police->tcf_lock));
	return params->peak.rate_bytes_ps;
}

static inline u32 tcf_police_tcfp_ewma_rate(const struct tc_action *act)
{
	struct tcf_police *police = to_police(act);
	struct tcf_police_params *params;

	params = rcu_dereference_protected(police->params,
					   lockdep_is_held(&police->tcf_lock));
	return params->tcfp_ewma_rate;
}

static inline u16 tcf_police_rate_overhead(const struct tc_action *act)
{
	struct tcf_police *police = to_police(act);
	struct tcf_police_params *params;

	params = rcu_dereference_protected(police->params,
					   lockdep_is_held(&police->tcf_lock));
	return params->rate.overhead;
}

#endif /* __NET_TC_POLICE_H */
+46 −0
Original line number Diff line number Diff line
@@ -419,20 +419,66 @@ static int tcf_police_search(struct net *net, struct tc_action **a, u32 index)
	return tcf_idr_search(tn, a, index);
}

static int tcf_police_act_to_flow_act(int tc_act, u32 *extval)
{
	int act_id = -EOPNOTSUPP;

	if (!TC_ACT_EXT_OPCODE(tc_act)) {
		if (tc_act == TC_ACT_OK)
			act_id = FLOW_ACTION_ACCEPT;
		else if (tc_act ==  TC_ACT_SHOT)
			act_id = FLOW_ACTION_DROP;
		else if (tc_act == TC_ACT_PIPE)
			act_id = FLOW_ACTION_PIPE;
	} else if (TC_ACT_EXT_CMP(tc_act, TC_ACT_GOTO_CHAIN)) {
		act_id = FLOW_ACTION_GOTO;
		*extval = tc_act & TC_ACT_EXT_VAL_MASK;
	} else if (TC_ACT_EXT_CMP(tc_act, TC_ACT_JUMP)) {
		act_id = FLOW_ACTION_JUMP;
		*extval = tc_act & TC_ACT_EXT_VAL_MASK;
	}

	return act_id;
}

static int tcf_police_offload_act_setup(struct tc_action *act, void *entry_data,
					u32 *index_inc, bool bind)
{
	if (bind) {
		struct flow_action_entry *entry = entry_data;
		struct tcf_police *police = to_police(act);
		struct tcf_police_params *p;
		int act_id;

		p = rcu_dereference_protected(police->params,
					      lockdep_is_held(&police->tcf_lock));

		entry->id = FLOW_ACTION_POLICE;
		entry->police.burst = tcf_police_burst(act);
		entry->police.rate_bytes_ps =
			tcf_police_rate_bytes_ps(act);
		entry->police.peakrate_bytes_ps = tcf_police_peakrate_bytes_ps(act);
		entry->police.avrate = tcf_police_tcfp_ewma_rate(act);
		entry->police.overhead = tcf_police_rate_overhead(act);
		entry->police.burst_pkt = tcf_police_burst_pkt(act);
		entry->police.rate_pkt_ps =
			tcf_police_rate_pkt_ps(act);
		entry->police.mtu = tcf_police_tcfp_mtu(act);

		act_id = tcf_police_act_to_flow_act(police->tcf_action,
						    &entry->police.exceed.extval);
		if (act_id < 0)
			return act_id;

		entry->police.exceed.act_id = act_id;

		act_id = tcf_police_act_to_flow_act(p->tcfp_result,
						    &entry->police.notexceed.extval);
		if (act_id < 0)
			return act_id;

		entry->police.notexceed.act_id = act_id;

		*index_inc = 1;
	} else {
		struct flow_offload_action *fl_action = entry_data;