diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2019-07-09 23:55:42 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-07-10 00:38:50 +0300 |
commit | d63db30c8537ba45208c156d71125db73d0fe522 (patch) | |
tree | 36e704c2825d9d7667d3a5e5de247c0241fd8e79 | |
parent | 32f8c4093ac353a5f1b36cfed0ce0138faf8e15f (diff) |
net: flow_offload: add flow_block_cb_alloc() and flow_block_cb_free()
Add a new helper function to allocate flow_block_cb objects.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/flow_offload.h | 14 | ||||
-rw-r--r-- | net/core/flow_offload.c | 28 |
2 files changed, 42 insertions, 0 deletions
diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h index f12b905ad95e..45d74cb542cd 100644 --- a/include/net/flow_offload.h +++ b/include/net/flow_offload.h @@ -260,6 +260,20 @@ struct flow_block_offload { struct netlink_ext_ack *extack; }; +struct flow_block_cb { + struct list_head list; + tc_setup_cb_t *cb; + void *cb_ident; + void *cb_priv; + void (*release)(void *cb_priv); + unsigned int refcnt; +}; + +struct flow_block_cb *flow_block_cb_alloc(struct net *net, tc_setup_cb_t *cb, + void *cb_ident, void *cb_priv, + void (*release)(void *cb_priv)); +void flow_block_cb_free(struct flow_block_cb *block_cb); + int flow_block_cb_setup_simple(struct flow_block_offload *f, struct list_head *driver_list, tc_setup_cb_t *cb, void *cb_ident, void *cb_priv, bool ingress_only); diff --git a/net/core/flow_offload.c b/net/core/flow_offload.c index 6d8187e8effc..d08148cb6953 100644 --- a/net/core/flow_offload.c +++ b/net/core/flow_offload.c @@ -166,6 +166,34 @@ void flow_rule_match_enc_opts(const struct flow_rule *rule, } EXPORT_SYMBOL(flow_rule_match_enc_opts); +struct flow_block_cb *flow_block_cb_alloc(struct net *net, tc_setup_cb_t *cb, + void *cb_ident, void *cb_priv, + void (*release)(void *cb_priv)) +{ + struct flow_block_cb *block_cb; + + block_cb = kzalloc(sizeof(*block_cb), GFP_KERNEL); + if (!block_cb) + return ERR_PTR(-ENOMEM); + + block_cb->cb = cb; + block_cb->cb_ident = cb_ident; + block_cb->cb_priv = cb_priv; + block_cb->release = release; + + return block_cb; +} +EXPORT_SYMBOL(flow_block_cb_alloc); + +void flow_block_cb_free(struct flow_block_cb *block_cb) +{ + if (block_cb->release) + block_cb->release(block_cb->cb_priv); + + kfree(block_cb); +} +EXPORT_SYMBOL(flow_block_cb_free); + int flow_block_cb_setup_simple(struct flow_block_offload *f, struct list_head *driver_block_list, tc_setup_cb_t *cb, void *cb_ident, void *cb_priv, |