summaryrefslogtreecommitdiffstats
path: root/net/core/flow_offload.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2019-07-09 22:55:48 +0200
committerDavid S. Miller <davem@davemloft.net>2019-07-09 14:38:50 -0700
commit0d4fd02e7199fbf57c0d175dd1890c82cd4a6f4f (patch)
treec06ac553a77c2ae6bc7e36db665d77fce29f2e1c /net/core/flow_offload.c
parent722d36e6e29e50c640c9f5ce186b8d8709cae1a6 (diff)
downloadlinux-0d4fd02e7199fbf57c0d175dd1890c82cd4a6f4f.tar.gz
linux-0d4fd02e7199fbf57c0d175dd1890c82cd4a6f4f.tar.bz2
linux-0d4fd02e7199fbf57c0d175dd1890c82cd4a6f4f.zip
net: flow_offload: add flow_block_cb_is_busy() and use it
This patch adds a function to check if flow block callback is already in use. Call this new function from flow_block_cb_setup_simple() and from drivers. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/flow_offload.c')
-rw-r--r--net/core/flow_offload.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/net/core/flow_offload.c b/net/core/flow_offload.c
index a1b36b47dd89..76f8db3841d7 100644
--- a/net/core/flow_offload.c
+++ b/net/core/flow_offload.c
@@ -228,6 +228,21 @@ unsigned int flow_block_cb_decref(struct flow_block_cb *block_cb)
}
EXPORT_SYMBOL(flow_block_cb_decref);
+bool flow_block_cb_is_busy(tc_setup_cb_t *cb, void *cb_ident,
+ struct list_head *driver_block_list)
+{
+ struct flow_block_cb *block_cb;
+
+ list_for_each_entry(block_cb, driver_block_list, driver_list) {
+ if (block_cb->cb == cb &&
+ block_cb->cb_ident == cb_ident)
+ return true;
+ }
+
+ return false;
+}
+EXPORT_SYMBOL(flow_block_cb_is_busy);
+
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,
@@ -243,6 +258,9 @@ int flow_block_cb_setup_simple(struct flow_block_offload *f,
switch (f->command) {
case FLOW_BLOCK_BIND:
+ if (flow_block_cb_is_busy(cb, cb_ident, driver_block_list))
+ return -EBUSY;
+
block_cb = flow_block_cb_alloc(f->net, cb, cb_ident,
cb_priv, NULL);
if (IS_ERR(block_cb))