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_PUSH,
 | 
				
			||||||
	FLOW_ACTION_MPLS_POP,
 | 
						FLOW_ACTION_MPLS_POP,
 | 
				
			||||||
	FLOW_ACTION_MPLS_MANGLE,
 | 
						FLOW_ACTION_MPLS_MANGLE,
 | 
				
			||||||
 | 
						FLOW_ACTION_GATE,
 | 
				
			||||||
	NUM_FLOW_ACTIONS,
 | 
						NUM_FLOW_ACTIONS,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -255,6 +256,15 @@ struct flow_action_entry {
 | 
				
			||||||
			u8		bos;
 | 
								u8		bos;
 | 
				
			||||||
			u8		ttl;
 | 
								u8		ttl;
 | 
				
			||||||
		} mpls_mangle;
 | 
							} 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 */
 | 
						struct flow_action_cookie *cookie; /* user defined action cookie */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,13 @@
 | 
				
			||||||
#include <net/act_api.h>
 | 
					#include <net/act_api.h>
 | 
				
			||||||
#include <linux/tc_act/tc_gate.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 {
 | 
					struct tcfg_gate_entry {
 | 
				
			||||||
	int			index;
 | 
						int			index;
 | 
				
			||||||
	u8			gate_state;
 | 
						u8			gate_state;
 | 
				
			||||||
| 
						 | 
					@ -44,4 +51,96 @@ struct tcf_gate {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define to_gate(a) ((struct tcf_gate *)a)
 | 
					#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
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,6 +39,7 @@
 | 
				
			||||||
#include <net/tc_act/tc_skbedit.h>
 | 
					#include <net/tc_act/tc_skbedit.h>
 | 
				
			||||||
#include <net/tc_act/tc_ct.h>
 | 
					#include <net/tc_act/tc_ct.h>
 | 
				
			||||||
#include <net/tc_act/tc_mpls.h>
 | 
					#include <net/tc_act/tc_mpls.h>
 | 
				
			||||||
 | 
					#include <net/tc_act/tc_gate.h>
 | 
				
			||||||
#include <net/flow_offload.h>
 | 
					#include <net/flow_offload.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern const struct nla_policy rtm_tca_policy[TCA_MAX + 1];
 | 
					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
 | 
					#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,
 | 
					int tc_setup_flow_action(struct flow_action *flow_action,
 | 
				
			||||||
			 const struct tcf_exts *exts)
 | 
								 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)) {
 | 
							} else if (is_tcf_skbedit_priority(act)) {
 | 
				
			||||||
			entry->id = FLOW_ACTION_PRIORITY;
 | 
								entry->id = FLOW_ACTION_PRIORITY;
 | 
				
			||||||
			entry->priority = tcf_skbedit_priority(act);
 | 
								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 {
 | 
							} else {
 | 
				
			||||||
			err = -EOPNOTSUPP;
 | 
								err = -EOPNOTSUPP;
 | 
				
			||||||
			goto err_out_locked;
 | 
								goto err_out_locked;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue