forked from mirrors/linux
		
	net: schedule: add action gate offloading
Add the gate action to the flow action entry. Add the gate parameters to the tc_setup_flow_action() queueing to the entries of flow_action_entry array provide to the driver. Signed-off-by: Po Liu <Po.Liu@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									a51c328df3
								
							
						
					
					
						commit
						d29bdd69ec
					
				
					 3 changed files with 142 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -147,6 +147,7 @@ enum flow_action_id {
 | 
			
		|||
	FLOW_ACTION_MPLS_PUSH,
 | 
			
		||||
	FLOW_ACTION_MPLS_POP,
 | 
			
		||||
	FLOW_ACTION_MPLS_MANGLE,
 | 
			
		||||
	FLOW_ACTION_GATE,
 | 
			
		||||
	NUM_FLOW_ACTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -255,6 +256,15 @@ struct flow_action_entry {
 | 
			
		|||
			u8		bos;
 | 
			
		||||
			u8		ttl;
 | 
			
		||||
		} mpls_mangle;
 | 
			
		||||
		struct {
 | 
			
		||||
			u32		index;
 | 
			
		||||
			s32		prio;
 | 
			
		||||
			u64		basetime;
 | 
			
		||||
			u64		cycletime;
 | 
			
		||||
			u64		cycletimeext;
 | 
			
		||||
			u32		num_entries;
 | 
			
		||||
			struct action_gate_entry *entries;
 | 
			
		||||
		} gate;
 | 
			
		||||
	};
 | 
			
		||||
	struct flow_action_cookie *cookie; /* user defined action cookie */
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,13 @@
 | 
			
		|||
#include <net/act_api.h>
 | 
			
		||||
#include <linux/tc_act/tc_gate.h>
 | 
			
		||||
 | 
			
		||||
struct action_gate_entry {
 | 
			
		||||
	u8			gate_state;
 | 
			
		||||
	u32			interval;
 | 
			
		||||
	s32			ipv;
 | 
			
		||||
	s32			maxoctets;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct tcfg_gate_entry {
 | 
			
		||||
	int			index;
 | 
			
		||||
	u8			gate_state;
 | 
			
		||||
| 
						 | 
				
			
			@ -44,4 +51,96 @@ struct tcf_gate {
 | 
			
		|||
 | 
			
		||||
#define to_gate(a) ((struct tcf_gate *)a)
 | 
			
		||||
 | 
			
		||||
static inline bool is_tcf_gate(const struct tc_action *a)
 | 
			
		||||
{
 | 
			
		||||
#ifdef CONFIG_NET_CLS_ACT
 | 
			
		||||
	if (a->ops && a->ops->id == TCA_ID_GATE)
 | 
			
		||||
		return true;
 | 
			
		||||
#endif
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline u32 tcf_gate_index(const struct tc_action *a)
 | 
			
		||||
{
 | 
			
		||||
	return a->tcfa_index;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline s32 tcf_gate_prio(const struct tc_action *a)
 | 
			
		||||
{
 | 
			
		||||
	s32 tcfg_prio;
 | 
			
		||||
 | 
			
		||||
	tcfg_prio = to_gate(a)->param.tcfg_priority;
 | 
			
		||||
 | 
			
		||||
	return tcfg_prio;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline u64 tcf_gate_basetime(const struct tc_action *a)
 | 
			
		||||
{
 | 
			
		||||
	u64 tcfg_basetime;
 | 
			
		||||
 | 
			
		||||
	tcfg_basetime = to_gate(a)->param.tcfg_basetime;
 | 
			
		||||
 | 
			
		||||
	return tcfg_basetime;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline u64 tcf_gate_cycletime(const struct tc_action *a)
 | 
			
		||||
{
 | 
			
		||||
	u64 tcfg_cycletime;
 | 
			
		||||
 | 
			
		||||
	tcfg_cycletime = to_gate(a)->param.tcfg_cycletime;
 | 
			
		||||
 | 
			
		||||
	return tcfg_cycletime;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline u64 tcf_gate_cycletimeext(const struct tc_action *a)
 | 
			
		||||
{
 | 
			
		||||
	u64 tcfg_cycletimeext;
 | 
			
		||||
 | 
			
		||||
	tcfg_cycletimeext = to_gate(a)->param.tcfg_cycletime_ext;
 | 
			
		||||
 | 
			
		||||
	return tcfg_cycletimeext;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline u32 tcf_gate_num_entries(const struct tc_action *a)
 | 
			
		||||
{
 | 
			
		||||
	u32 num_entries;
 | 
			
		||||
 | 
			
		||||
	num_entries = to_gate(a)->param.num_entries;
 | 
			
		||||
 | 
			
		||||
	return num_entries;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline struct action_gate_entry
 | 
			
		||||
			*tcf_gate_get_list(const struct tc_action *a)
 | 
			
		||||
{
 | 
			
		||||
	struct action_gate_entry *oe;
 | 
			
		||||
	struct tcf_gate_params *p;
 | 
			
		||||
	struct tcfg_gate_entry *entry;
 | 
			
		||||
	u32 num_entries;
 | 
			
		||||
	int i = 0;
 | 
			
		||||
 | 
			
		||||
	p = &to_gate(a)->param;
 | 
			
		||||
	num_entries = p->num_entries;
 | 
			
		||||
 | 
			
		||||
	list_for_each_entry(entry, &p->entries, list)
 | 
			
		||||
		i++;
 | 
			
		||||
 | 
			
		||||
	if (i != num_entries)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	oe = kcalloc(num_entries, sizeof(*oe), GFP_ATOMIC);
 | 
			
		||||
	if (!oe)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	i = 0;
 | 
			
		||||
	list_for_each_entry(entry, &p->entries, list) {
 | 
			
		||||
		oe[i].gate_state = entry->gate_state;
 | 
			
		||||
		oe[i].interval = entry->interval;
 | 
			
		||||
		oe[i].ipv = entry->ipv;
 | 
			
		||||
		oe[i].maxoctets = entry->maxoctets;
 | 
			
		||||
		i++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return oe;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,6 +39,7 @@
 | 
			
		|||
#include <net/tc_act/tc_skbedit.h>
 | 
			
		||||
#include <net/tc_act/tc_ct.h>
 | 
			
		||||
#include <net/tc_act/tc_mpls.h>
 | 
			
		||||
#include <net/tc_act/tc_gate.h>
 | 
			
		||||
#include <net/flow_offload.h>
 | 
			
		||||
 | 
			
		||||
extern const struct nla_policy rtm_tca_policy[TCA_MAX + 1];
 | 
			
		||||
| 
						 | 
				
			
			@ -3526,6 +3527,27 @@ static void tcf_sample_get_group(struct flow_action_entry *entry,
 | 
			
		|||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int tc_setup_flow_action(struct flow_action *flow_action,
 | 
			
		||||
			 const struct tcf_exts *exts)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -3672,6 +3694,17 @@ int tc_setup_flow_action(struct flow_action *flow_action,
 | 
			
		|||
		} else if (is_tcf_skbedit_priority(act)) {
 | 
			
		||||
			entry->id = FLOW_ACTION_PRIORITY;
 | 
			
		||||
			entry->priority = tcf_skbedit_priority(act);
 | 
			
		||||
		} else if (is_tcf_gate(act)) {
 | 
			
		||||
			entry->id = FLOW_ACTION_GATE;
 | 
			
		||||
			entry->gate.index = tcf_gate_index(act);
 | 
			
		||||
			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)
 | 
			
		||||
				goto err_out;
 | 
			
		||||
		} else {
 | 
			
		||||
			err = -EOPNOTSUPP;
 | 
			
		||||
			goto err_out_locked;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue