forked from Minki/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
@ -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 New Issue
Block a user