diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2019-07-09 22:55:43 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-07-09 23:38:50 +0200 |
commit | da3eeb904ff432ec22cf7b4db17a47647428873a (patch) | |
tree | baaf713b85b1eff561b7a155686012807edcc733 | |
parent | net: flow_offload: add flow_block_cb_alloc() and flow_block_cb_free() (diff) | |
download | linux-da3eeb904ff432ec22cf7b4db17a47647428873a.tar.xz linux-da3eeb904ff432ec22cf7b4db17a47647428873a.zip |
net: flow_offload: add list handling functions
This patch adds the list handling functions for the flow block API:
* flow_block_cb_lookup() allows drivers to look up for existing flow blocks.
* flow_block_cb_add() adds a flow block to the per driver list to be registered
by the core.
* flow_block_cb_remove() to remove a flow block from the list of existing
flow blocks per driver and to request the core to unregister this.
The flow block API also annotates the netns this flow block belongs to.
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 | 19 | ||||
-rw-r--r-- | net/core/flow_offload.c | 17 | ||||
-rw-r--r-- | net/sched/cls_api.c | 3 |
3 files changed, 39 insertions, 0 deletions
diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h index 45d74cb542cd..563d7dc7afc1 100644 --- a/include/net/flow_offload.h +++ b/include/net/flow_offload.h @@ -256,12 +256,16 @@ struct flow_block_offload { enum flow_block_command command; enum flow_block_binder_type binder_type; struct tcf_block *block; + struct net *net; + struct list_head cb_list; struct list_head *driver_block_list; struct netlink_ext_ack *extack; }; struct flow_block_cb { + struct list_head driver_list; struct list_head list; + struct net *net; tc_setup_cb_t *cb; void *cb_ident; void *cb_priv; @@ -274,6 +278,21 @@ struct flow_block_cb *flow_block_cb_alloc(struct net *net, tc_setup_cb_t *cb, void (*release)(void *cb_priv)); void flow_block_cb_free(struct flow_block_cb *block_cb); +struct flow_block_cb *flow_block_cb_lookup(struct flow_block_offload *offload, + tc_setup_cb_t *cb, void *cb_ident); + +static inline void flow_block_cb_add(struct flow_block_cb *block_cb, + struct flow_block_offload *offload) +{ + list_add_tail(&block_cb->list, &offload->cb_list); +} + +static inline void flow_block_cb_remove(struct flow_block_cb *block_cb, + struct flow_block_offload *offload) +{ + list_move(&block_cb->list, &offload->cb_list); +} + 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 d08148cb6953..c81a7e0c5e04 100644 --- a/net/core/flow_offload.c +++ b/net/core/flow_offload.c @@ -176,6 +176,7 @@ struct flow_block_cb *flow_block_cb_alloc(struct net *net, tc_setup_cb_t *cb, if (!block_cb) return ERR_PTR(-ENOMEM); + block_cb->net = net; block_cb->cb = cb; block_cb->cb_ident = cb_ident; block_cb->cb_priv = cb_priv; @@ -194,6 +195,22 @@ void flow_block_cb_free(struct flow_block_cb *block_cb) } EXPORT_SYMBOL(flow_block_cb_free); +struct flow_block_cb *flow_block_cb_lookup(struct flow_block_offload *f, + tc_setup_cb_t *cb, void *cb_ident) +{ + struct flow_block_cb *block_cb; + + list_for_each_entry(block_cb, f->driver_block_list, driver_list) { + if (block_cb->net == f->net && + block_cb->cb == cb && + block_cb->cb_ident == cb_ident) + return block_cb; + } + + return NULL; +} +EXPORT_SYMBOL(flow_block_cb_lookup); + 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, diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 49b89c89a8b9..ccbd51bed88c 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -680,6 +680,7 @@ static void tc_indr_block_ing_cmd(struct tc_indr_block_dev *indr_dev, struct tc_block_offload bo = { .command = command, .binder_type = FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS, + .net = dev_net(indr_dev->dev), .block = indr_dev->block, }; @@ -768,6 +769,7 @@ static void tc_indr_block_call(struct tcf_block *block, struct net_device *dev, struct tc_block_offload bo = { .command = command, .binder_type = ei->binder_type, + .net = dev_net(dev), .block = block, .extack = extack, }; @@ -796,6 +798,7 @@ static int tcf_block_offload_cmd(struct tcf_block *block, { struct tc_block_offload bo = {}; + bo.net = dev_net(dev); bo.command = command; bo.binder_type = ei->binder_type; bo.block = block; |