Commit 2008495d authored by Jiri Pirko's avatar Jiri Pirko Committed by David S. Miller
Browse files

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: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Reviewed-by: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3b3e808c
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -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 {
+21 −0
Original line number Diff line number Diff line
@@ -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))
+30 −1
Original line number Diff line number Diff line
@@ -3382,15 +3382,41 @@ 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);

static void tcf_mirred_get_dev(struct flow_action_entry *entry,
@@ -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)) {