mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-01 10:45:49 +00:00
flow_offload: pass action cookie through offload structures
Extend struct flow_action_entry in order to hold TC action cookie specified by user inserting the action. Signed-off-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: Ido Schimmel <idosch@mellanox.com> Reviewed-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
3b3e808cd8
commit
2008495d81
@ -156,6 +156,16 @@ enum flow_action_mangle_base {
|
||||
|
||||
typedef void (*action_destr)(void *priv);
|
||||
|
||||
struct flow_action_cookie {
|
||||
u32 cookie_len;
|
||||
u8 cookie[];
|
||||
};
|
||||
|
||||
struct flow_action_cookie *flow_action_cookie_create(void *data,
|
||||
unsigned int len,
|
||||
gfp_t gfp);
|
||||
void flow_action_cookie_destroy(struct flow_action_cookie *cookie);
|
||||
|
||||
struct flow_action_entry {
|
||||
enum flow_action_id id;
|
||||
action_destr destructor;
|
||||
@ -214,6 +224,7 @@ struct flow_action_entry {
|
||||
u8 ttl;
|
||||
} mpls_mangle;
|
||||
};
|
||||
struct flow_action_cookie *cookie; /* user defined action cookie */
|
||||
};
|
||||
|
||||
struct flow_action {
|
||||
|
@ -167,6 +167,27 @@ void flow_rule_match_enc_opts(const struct flow_rule *rule,
|
||||
}
|
||||
EXPORT_SYMBOL(flow_rule_match_enc_opts);
|
||||
|
||||
struct flow_action_cookie *flow_action_cookie_create(void *data,
|
||||
unsigned int len,
|
||||
gfp_t gfp)
|
||||
{
|
||||
struct flow_action_cookie *cookie;
|
||||
|
||||
cookie = kmalloc(sizeof(*cookie) + len, gfp);
|
||||
if (!cookie)
|
||||
return NULL;
|
||||
cookie->cookie_len = len;
|
||||
memcpy(cookie->cookie, data, len);
|
||||
return cookie;
|
||||
}
|
||||
EXPORT_SYMBOL(flow_action_cookie_create);
|
||||
|
||||
void flow_action_cookie_destroy(struct flow_action_cookie *cookie)
|
||||
{
|
||||
kfree(cookie);
|
||||
}
|
||||
EXPORT_SYMBOL(flow_action_cookie_destroy);
|
||||
|
||||
struct flow_block_cb *flow_block_cb_alloc(flow_setup_cb_t *cb,
|
||||
void *cb_ident, void *cb_priv,
|
||||
void (*release)(void *cb_priv))
|
||||
|
@ -3382,14 +3382,40 @@ int tc_setup_cb_reoffload(struct tcf_block *block, struct tcf_proto *tp,
|
||||
}
|
||||
EXPORT_SYMBOL(tc_setup_cb_reoffload);
|
||||
|
||||
static int tcf_act_get_cookie(struct flow_action_entry *entry,
|
||||
const struct tc_action *act)
|
||||
{
|
||||
struct tc_cookie *cookie;
|
||||
int err = 0;
|
||||
|
||||
rcu_read_lock();
|
||||
cookie = rcu_dereference(act->act_cookie);
|
||||
if (cookie) {
|
||||
entry->cookie = flow_action_cookie_create(cookie->data,
|
||||
cookie->len,
|
||||
GFP_ATOMIC);
|
||||
if (!entry->cookie)
|
||||
err = -ENOMEM;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
return err;
|
||||
}
|
||||
|
||||
static void tcf_act_put_cookie(struct flow_action_entry *entry)
|
||||
{
|
||||
flow_action_cookie_destroy(entry->cookie);
|
||||
}
|
||||
|
||||
void tc_cleanup_flow_action(struct flow_action *flow_action)
|
||||
{
|
||||
struct flow_action_entry *entry;
|
||||
int i;
|
||||
|
||||
flow_action_for_each(i, entry, flow_action)
|
||||
flow_action_for_each(i, entry, flow_action) {
|
||||
tcf_act_put_cookie(entry);
|
||||
if (entry->destructor)
|
||||
entry->destructor(entry->destructor_priv);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(tc_cleanup_flow_action);
|
||||
|
||||
@ -3447,6 +3473,9 @@ int tc_setup_flow_action(struct flow_action *flow_action,
|
||||
|
||||
entry = &flow_action->entries[j];
|
||||
spin_lock_bh(&act->tcfa_lock);
|
||||
err = tcf_act_get_cookie(entry, act);
|
||||
if (err)
|
||||
goto err_out_locked;
|
||||
if (is_tcf_gact_ok(act)) {
|
||||
entry->id = FLOW_ACTION_ACCEPT;
|
||||
} else if (is_tcf_gact_shot(act)) {
|
||||
|
Loading…
Reference in New Issue
Block a user