Commit d29bdd69 authored by Po Liu's avatar Po Liu Committed by David S. Miller

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: default avatarPo Liu <Po.Liu@nxp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a51c328d
...@@ -147,6 +147,7 @@ enum flow_action_id { ...@@ -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 { ...@@ -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 @@ ...@@ -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 { ...@@ -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 @@ ...@@ -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, ...@@ -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, ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment