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) | ||||
| 			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); | ||||
| 		if (!indr_priv) | ||||
| 			return -ENOMEM; | ||||
|  | ||||
| @ -1698,6 +1698,10 @@ static int mlxsw_sp_setup_tc_block(struct mlxsw_sp_port *mlxsw_sp_port, | ||||
| 
 | ||||
| 	switch (f->command) { | ||||
| 	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, | ||||
| 					       mlxsw_sp_port, NULL); | ||||
| 		if (IS_ERR(block_cb)) | ||||
|  | ||||
| @ -153,6 +153,9 @@ static int ocelot_setup_tc_block(struct ocelot_port *port, | ||||
| 
 | ||||
| 	switch (f->command) { | ||||
| 	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); | ||||
| 		if (IS_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) { | ||||
| 	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, | ||||
| 					       nfp_flower_setup_tc_block_cb, | ||||
| 					       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); | ||||
| } | ||||
| 
 | ||||
| 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, | ||||
| 			       struct list_head *driver_list, tc_setup_cb_t *cb, | ||||
| 			       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); | ||||
| 
 | ||||
| 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)) | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user