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>
This commit is contained in:
parent
722d36e6e2
commit
0d4fd02e71
@ -722,6 +722,10 @@ mlx5e_rep_indr_setup_tc_block(struct net_device *netdev,
|
|||||||
if (indr_priv)
|
if (indr_priv)
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
|
|
||||||
|
if (flow_block_cb_is_busy(mlx5e_rep_indr_setup_block_cb,
|
||||||
|
indr_priv, &mlx5e_block_cb_list))
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
indr_priv = kmalloc(sizeof(*indr_priv), GFP_KERNEL);
|
indr_priv = kmalloc(sizeof(*indr_priv), GFP_KERNEL);
|
||||||
if (!indr_priv)
|
if (!indr_priv)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -1698,6 +1698,10 @@ static int mlxsw_sp_setup_tc_block(struct mlxsw_sp_port *mlxsw_sp_port,
|
|||||||
|
|
||||||
switch (f->command) {
|
switch (f->command) {
|
||||||
case FLOW_BLOCK_BIND:
|
case FLOW_BLOCK_BIND:
|
||||||
|
if (flow_block_cb_is_busy(cb, mlxsw_sp_port,
|
||||||
|
&mlxsw_sp_block_cb_list))
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
block_cb = flow_block_cb_alloc(f->net, cb, mlxsw_sp_port,
|
block_cb = flow_block_cb_alloc(f->net, cb, mlxsw_sp_port,
|
||||||
mlxsw_sp_port, NULL);
|
mlxsw_sp_port, NULL);
|
||||||
if (IS_ERR(block_cb))
|
if (IS_ERR(block_cb))
|
||||||
|
@ -153,6 +153,9 @@ static int ocelot_setup_tc_block(struct ocelot_port *port,
|
|||||||
|
|
||||||
switch (f->command) {
|
switch (f->command) {
|
||||||
case FLOW_BLOCK_BIND:
|
case FLOW_BLOCK_BIND:
|
||||||
|
if (flow_block_cb_is_busy(cb, port, &ocelot_block_cb_list))
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
block_cb = flow_block_cb_alloc(f->net, cb, port, port, NULL);
|
block_cb = flow_block_cb_alloc(f->net, cb, port, port, NULL);
|
||||||
if (IS_ERR(block_cb))
|
if (IS_ERR(block_cb))
|
||||||
return PTR_ERR(block_cb);
|
return PTR_ERR(block_cb);
|
||||||
|
@ -1320,6 +1320,10 @@ static int nfp_flower_setup_tc_block(struct net_device *netdev,
|
|||||||
|
|
||||||
switch (f->command) {
|
switch (f->command) {
|
||||||
case FLOW_BLOCK_BIND:
|
case FLOW_BLOCK_BIND:
|
||||||
|
if (flow_block_cb_is_busy(nfp_flower_setup_tc_block_cb, repr,
|
||||||
|
&nfp_block_cb_list))
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
block_cb = flow_block_cb_alloc(f->net,
|
block_cb = flow_block_cb_alloc(f->net,
|
||||||
nfp_flower_setup_tc_block_cb,
|
nfp_flower_setup_tc_block_cb,
|
||||||
repr, repr, NULL);
|
repr, repr, NULL);
|
||||||
|
@ -296,6 +296,9 @@ static inline void flow_block_cb_remove(struct flow_block_cb *block_cb,
|
|||||||
list_move(&block_cb->list, &offload->cb_list);
|
list_move(&block_cb->list, &offload->cb_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool flow_block_cb_is_busy(tc_setup_cb_t *cb, void *cb_ident,
|
||||||
|
struct list_head *driver_block_list);
|
||||||
|
|
||||||
int flow_block_cb_setup_simple(struct flow_block_offload *f,
|
int flow_block_cb_setup_simple(struct flow_block_offload *f,
|
||||||
struct list_head *driver_list, tc_setup_cb_t *cb,
|
struct list_head *driver_list, tc_setup_cb_t *cb,
|
||||||
void *cb_ident, void *cb_priv, bool ingress_only);
|
void *cb_ident, void *cb_priv, bool ingress_only);
|
||||||
|
@ -228,6 +228,21 @@ unsigned int flow_block_cb_decref(struct flow_block_cb *block_cb)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(flow_block_cb_decref);
|
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,
|
int flow_block_cb_setup_simple(struct flow_block_offload *f,
|
||||||
struct list_head *driver_block_list,
|
struct list_head *driver_block_list,
|
||||||
tc_setup_cb_t *cb, void *cb_ident, void *cb_priv,
|
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) {
|
switch (f->command) {
|
||||||
case FLOW_BLOCK_BIND:
|
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,
|
block_cb = flow_block_cb_alloc(f->net, cb, cb_ident,
|
||||||
cb_priv, NULL);
|
cb_priv, NULL);
|
||||||
if (IS_ERR(block_cb))
|
if (IS_ERR(block_cb))
|
||||||
|
@ -961,6 +961,9 @@ static int dsa_slave_setup_tc_block(struct net_device *dev,
|
|||||||
|
|
||||||
switch (f->command) {
|
switch (f->command) {
|
||||||
case FLOW_BLOCK_BIND:
|
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);
|
block_cb = flow_block_cb_alloc(f->net, cb, dev, dev, NULL);
|
||||||
if (IS_ERR(block_cb))
|
if (IS_ERR(block_cb))
|
||||||
return PTR_ERR(block_cb);
|
return PTR_ERR(block_cb);
|
||||||
|
Loading…
Reference in New Issue
Block a user