Tue, Jul 09, 2019 at 10:55:46PM CEST, pablo@xxxxxxxxxxxxx wrote: [...] > static int > mlxsw_sp_setup_tc_block_flower_bind(struct mlxsw_sp_port *mlxsw_sp_port, >- struct tcf_block *block, bool ingress, >- struct netlink_ext_ack *extack) >+ struct flow_block_offload *f, bool ingress) > { > struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; > struct mlxsw_sp_acl_block *acl_block; >- struct tcf_block_cb *block_cb; >+ struct flow_block_cb *block_cb; >+ bool register_block = false; > int err; > >- block_cb = tcf_block_cb_lookup(block, mlxsw_sp_setup_tc_block_cb_flower, >- mlxsw_sp); >+ block_cb = flow_block_cb_lookup(f, mlxsw_sp_setup_tc_block_cb_flower, >+ mlxsw_sp); > if (!block_cb) { >- acl_block = mlxsw_sp_acl_block_create(mlxsw_sp, block->net); >+ acl_block = mlxsw_sp_acl_block_create(mlxsw_sp, f->net); > if (!acl_block) > return -ENOMEM; >- block_cb = __tcf_block_cb_register(block, >- mlxsw_sp_setup_tc_block_cb_flower, >- mlxsw_sp, acl_block, extack); >+ block_cb = flow_block_cb_alloc(f->net, >+ mlxsw_sp_setup_tc_block_cb_flower, >+ mlxsw_sp, acl_block, >+ mlxsw_sp_tc_block_flower_release); > if (IS_ERR(block_cb)) { >+ mlxsw_sp_acl_block_destroy(acl_block); > err = PTR_ERR(block_cb); > goto err_cb_register; > } >+ register_block = true; > } else { >- acl_block = tcf_block_cb_priv(block_cb); >+ acl_block = flow_block_cb_priv(block_cb); > } >- tcf_block_cb_incref(block_cb); >+ flow_block_cb_incref(block_cb); > err = mlxsw_sp_acl_block_bind(mlxsw_sp, acl_block, > mlxsw_sp_port, ingress); > if (err) >@@ -1622,28 +1634,31 @@ mlxsw_sp_setup_tc_block_flower_bind(struct mlxsw_sp_port *mlxsw_sp_port, > else > mlxsw_sp_port->eg_acl_block = acl_block; > >+ if (register_block) { >+ flow_block_cb_add(block_cb, f); >+ list_add_tail(&block_cb->driver_list, &mlxsw_sp_block_cb_list); >+ } What prevents you from doing these 2 above right after flow_block_cb_alloc? More than that, what prevents you do maintain the same flow as was there originally? You just need struct flow_block as a replacement of struct tcf_block and have it contained in both struct nft_base_chain and struct tcf_block. And you would push pointer to struct flow_block down to drivers in struct flow_block_offload. [...]