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_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 New Issue
Block a user