diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2019-07-09 22:55:48 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-07-09 14:38:50 -0700 |
commit | 0d4fd02e7199fbf57c0d175dd1890c82cd4a6f4f (patch) | |
tree | c06ac553a77c2ae6bc7e36db665d77fce29f2e1c /net | |
parent | 722d36e6e29e50c640c9f5ce186b8d8709cae1a6 (diff) |
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')
-rw-r--r-- | net/core/flow_offload.c | 18 | ||||
-rw-r--r-- | net/dsa/slave.c | 3 |
2 files changed, 21 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)) diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 90c32fd680db..9bcb598fc840 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -961,6 +961,9 @@ static int dsa_slave_setup_tc_block(struct net_device *dev, switch (f->command) { case FLOW_BLOCK_BIND: + if (flow_block_cb_is_busy(cb, dev, &dsa_slave_block_cb_list)) + return -EBUSY; + block_cb = flow_block_cb_alloc(f->net, cb, dev, dev, NULL); if (IS_ERR(block_cb)) return PTR_ERR(block_cb); |