diff options
author | David S. Miller <davem@davemloft.net> | 2019-07-09 14:38:51 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-07-09 14:38:51 -0700 |
commit | c099a408949c443cc7c83679af314ebfc805cd1f (patch) | |
tree | 1bebc0df6ae6c70cd2b4cb04c435a881cd3d8441 /drivers | |
parent | 2bb295f3a5e612b36ccf5986b529a8d4b426cf4f (diff) | |
parent | c9626a2cbdb20e26587b3fad99960520a023432b (diff) |
Merge branch 'nf-hw-offload'
Pablo Neira Ayuso says:
====================
netfilter: add hardware offload infrastructure
This patchset adds support for Netfilter hardware offloads.
This patchset reuses the existing block infrastructure, the
netdev_ops->ndo_setup_tc() interface, TC_SETUP_CLSFLOWER classifier and
the flow rule API.
Patch #1 adds flow_block_cb_setup_simple(), most drivers do the same thing
to set up flow blocks, to reduce the number of changes, consolidate
codebase. Use _simple() postfix as requested by Jakub Kicinski.
This new function resides in net/core/flow_offload.c
Patch #2 renames TC_BLOCK_{UN}BIND to FLOW_BLOCK_{UN}BIND.
Patch #3 renames TCF_BLOCK_BINDER_TYPE_* to FLOW_BLOCK_BINDER_TYPE_*.
Patch #4 adds flow_block_cb_alloc() and flow_block_cb_free() helper
functions, this is the first patch of the flow block API.
Patch #5 adds the helper to deal with list operations in the flow block API.
This includes flow_block_cb_lookup(), flow_block_cb_add() and
flow_block_cb_remove().
Patch #6 adds flow_block_cb_priv(), flow_block_cb_incref() and
flow_block_cb_decref() which completes the flow block API.
Patch #7 updates the cls_api to use the flow block API from the new
tcf_block_setup(). This infrastructure transports these objects
via list (through the tc_block_offload object) back to the core
for registration.
CLS_API DRIVER
TC_SETUP_BLOCK ----------> setup flow_block_cb object &
it adds object to flow_block_offload->cb_list
|
CLS_API <-----------------------'
registers list with flow blocks
flow_block_cb & travels back to
calls ->reoffload the core for registration
drivers allocate and sets up (configure the blocks), then
registration happens from the core (cls_api and netfilter).
Patch #8 updates drivers to use the flow block API.
Patch #9 removes the tcf block callback API, which is replaced by the
flow block API.
Patch #10 adds the flow_block_cb_is_busy() helper to check if the block
is already used by a subsystem. This helper is invoked from
drivers. Once drivers are updated to support for multiple
subsystems, they can remove this check.
Patch #11 rename tc structure and definitions for the block bind/unbind
path.
Patch #12 introduces basic netfilter hardware offload infrastructure
for the ingress chain. This includes 5-tuple exact matching
and accept / drop rule actions. Only basechains are supported
at this stage, no .reoffload callback is implemented either.
Default policy to "accept" is only supported for now.
table netdev filter {
chain ingress {
type filter hook ingress device eth0 priority 0; flags offload;
ip daddr 192.168.0.10 tcp dport 22 drop
}
}
This patchset reuses the existing tcf block callback API and it places it
in the flow block callback API in net/core/flow_offload.c.
This series aims to address Jakub and Jiri's feedback, please see specific
patches in this batch for changelog in this v4.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
39 files changed, 526 insertions, 618 deletions
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 2b5b0ab8961a..3f632028eff0 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -9907,32 +9907,19 @@ static int bnxt_setup_tc_block_cb(enum tc_setup_type type, void *type_data, } } -static int bnxt_setup_tc_block(struct net_device *dev, - struct tc_block_offload *f) -{ - struct bnxt *bp = netdev_priv(dev); - - if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS) - return -EOPNOTSUPP; - - switch (f->command) { - case TC_BLOCK_BIND: - return tcf_block_cb_register(f->block, bnxt_setup_tc_block_cb, - bp, bp, f->extack); - case TC_BLOCK_UNBIND: - tcf_block_cb_unregister(f->block, bnxt_setup_tc_block_cb, bp); - return 0; - default: - return -EOPNOTSUPP; - } -} +static LIST_HEAD(bnxt_block_cb_list); static int bnxt_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data) { + struct bnxt *bp = netdev_priv(dev); + switch (type) { case TC_SETUP_BLOCK: - return bnxt_setup_tc_block(dev, type_data); + return flow_block_cb_setup_simple(type_data, + &bnxt_block_cb_list, + bnxt_setup_tc_block_cb, + bp, bp, true); case TC_SETUP_QDISC_MQPRIO: { struct tc_mqprio_qopt *mqprio = type_data; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c index 44d6c5743fb9..6fe4a7174271 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c @@ -170,10 +170,10 @@ static int bnxt_tc_parse_actions(struct bnxt *bp, } static int bnxt_tc_parse_flow(struct bnxt *bp, - struct tc_cls_flower_offload *tc_flow_cmd, + struct flow_cls_offload *tc_flow_cmd, struct bnxt_tc_flow *flow) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(tc_flow_cmd); + struct flow_rule *rule = flow_cls_offload_flow_rule(tc_flow_cmd); struct flow_dissector *dissector = rule->match.dissector; /* KEY_CONTROL and KEY_BASIC are needed for forming a meaningful key */ @@ -1262,7 +1262,7 @@ static void bnxt_tc_set_src_fid(struct bnxt *bp, struct bnxt_tc_flow *flow, * The hash-tables are already protected by the rhashtable API. */ static int bnxt_tc_add_flow(struct bnxt *bp, u16 src_fid, - struct tc_cls_flower_offload *tc_flow_cmd) + struct flow_cls_offload *tc_flow_cmd) { struct bnxt_tc_flow_node *new_node, *old_node; struct bnxt_tc_info *tc_info = bp->tc_info; @@ -1348,7 +1348,7 @@ done: } static int bnxt_tc_del_flow(struct bnxt *bp, - struct tc_cls_flower_offload *tc_flow_cmd) + struct flow_cls_offload *tc_flow_cmd) { struct bnxt_tc_info *tc_info = bp->tc_info; struct bnxt_tc_flow_node *flow_node; @@ -1363,7 +1363,7 @@ static int bnxt_tc_del_flow(struct bnxt *bp, } static int bnxt_tc_get_flow_stats(struct bnxt *bp, - struct tc_cls_flower_offload *tc_flow_cmd) + struct flow_cls_offload *tc_flow_cmd) { struct bnxt_tc_flow_stats stats, *curr_stats, *prev_stats; struct bnxt_tc_info *tc_info = bp->tc_info; @@ -1585,14 +1585,14 @@ void bnxt_tc_flow_stats_work(struct bnxt *bp) } int bnxt_tc_setup_flower(struct bnxt *bp, u16 src_fid, - struct tc_cls_flower_offload *cls_flower) + struct flow_cls_offload *cls_flower) { switch (cls_flower->command) { - case TC_CLSFLOWER_REPLACE: + case FLOW_CLS_REPLACE: return bnxt_tc_add_flow(bp, src_fid, cls_flower); - case TC_CLSFLOWER_DESTROY: + case FLOW_CLS_DESTROY: return bnxt_tc_del_flow(bp, cls_flower); - case TC_CLSFLOWER_STATS: + case FLOW_CLS_STATS: return bnxt_tc_get_flow_stats(bp, cls_flower); default: return -EOPNOTSUPP; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.h index 8a0968967bc5..ffec57d1a5ec 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.h @@ -196,7 +196,7 @@ struct bnxt_tc_flow_node { }; int bnxt_tc_setup_flower(struct bnxt *bp, u16 src_fid, - struct tc_cls_flower_offload *cls_flower); + struct flow_cls_offload *cls_flower); int bnxt_init_tc(struct bnxt *bp); void bnxt_shutdown_tc(struct bnxt *bp); void bnxt_tc_flow_stats_work(struct bnxt *bp); @@ -209,7 +209,7 @@ static inline bool bnxt_tc_flower_enabled(struct bnxt *bp) #else /* CONFIG_BNXT_FLOWER_OFFLOAD */ static inline int bnxt_tc_setup_flower(struct bnxt *bp, u16 src_fid, - struct tc_cls_flower_offload *cls_flower) + struct flow_cls_offload *cls_flower) { return -EOPNOTSUPP; } diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c index f760921389a3..f9bf7d7250ab 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c @@ -161,34 +161,19 @@ static int bnxt_vf_rep_setup_tc_block_cb(enum tc_setup_type type, } } -static int bnxt_vf_rep_setup_tc_block(struct net_device *dev, - struct tc_block_offload *f) -{ - struct bnxt_vf_rep *vf_rep = netdev_priv(dev); - - if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS) - return -EOPNOTSUPP; - - switch (f->command) { - case TC_BLOCK_BIND: - return tcf_block_cb_register(f->block, - bnxt_vf_rep_setup_tc_block_cb, - vf_rep, vf_rep, f->extack); - case TC_BLOCK_UNBIND: - tcf_block_cb_unregister(f->block, - bnxt_vf_rep_setup_tc_block_cb, vf_rep); - return 0; - default: - return -EOPNOTSUPP; - } -} +static LIST_HEAD(bnxt_vf_block_cb_list); static int bnxt_vf_rep_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data) { + struct bnxt_vf_rep *vf_rep = netdev_priv(dev); + switch (type) { case TC_SETUP_BLOCK: - return bnxt_vf_rep_setup_tc_block(dev, type_data); + return flow_block_cb_setup_simple(type_data, + &bnxt_vf_block_cb_list, + bnxt_vf_rep_setup_tc_block_cb, + vf_rep, vf_rep, true); default: return -EOPNOTSUPP; } diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index b08efc48d42f..67202b6f352e 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -3135,14 +3135,14 @@ static int cxgb_set_tx_maxrate(struct net_device *dev, int index, u32 rate) } static int cxgb_setup_tc_flower(struct net_device *dev, - struct tc_cls_flower_offload *cls_flower) + struct flow_cls_offload *cls_flower) { switch (cls_flower->command) { - case TC_CLSFLOWER_REPLACE: + case FLOW_CLS_REPLACE: return cxgb4_tc_flower_replace(dev, cls_flower); - case TC_CLSFLOWER_DESTROY: + case FLOW_CLS_DESTROY: return cxgb4_tc_flower_destroy(dev, cls_flower); - case TC_CLSFLOWER_STATS: + case FLOW_CLS_STATS: return cxgb4_tc_flower_stats(dev, cls_flower); default: return -EOPNOTSUPP; @@ -3190,32 +3190,19 @@ static int cxgb_setup_tc_block_cb(enum tc_setup_type type, void *type_data, } } -static int cxgb_setup_tc_block(struct net_device *dev, - struct tc_block_offload *f) -{ - struct port_info *pi = netdev2pinfo(dev); - - if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS) - return -EOPNOTSUPP; - - switch (f->command) { - case TC_BLOCK_BIND: - return tcf_block_cb_register(f->block, cxgb_setup_tc_block_cb, - pi, dev, f->extack); - case TC_BLOCK_UNBIND: - tcf_block_cb_unregister(f->block, cxgb_setup_tc_block_cb, pi); - return 0; - default: - return -EOPNOTSUPP; - } -} +static LIST_HEAD(cxgb_block_cb_list); static int cxgb_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data) { + struct port_info *pi = netdev2pinfo(dev); + switch (type) { case TC_SETUP_BLOCK: - return cxgb_setup_tc_block(dev, type_data); + return flow_block_cb_setup_simple(type_data, + &cxgb_block_cb_list, + cxgb_setup_tc_block_cb, + pi, dev, true); default: return -EOPNOTSUPP; } diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c index cfaf8f618d1f..312599c6b35a 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c @@ -80,10 +80,10 @@ static struct ch_tc_flower_entry *ch_flower_lookup(struct adapter *adap, } static void cxgb4_process_flow_match(struct net_device *dev, - struct tc_cls_flower_offload *cls, + struct flow_cls_offload *cls, struct ch_filter_specification *fs) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(cls); + struct flow_rule *rule = flow_cls_offload_flow_rule(cls); u16 addr_type = 0; if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CONTROL)) { @@ -223,9 +223,9 @@ static void cxgb4_process_flow_match(struct net_device *dev, } static int cxgb4_validate_flow_match(struct net_device *dev, - struct tc_cls_flower_offload *cls) + struct flow_cls_offload *cls) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(cls); + struct flow_rule *rule = flow_cls_offload_flow_rule(cls); struct flow_dissector *dissector = rule->match.dissector; u16 ethtype_mask = 0; u16 ethtype_key = 0; @@ -378,10 +378,10 @@ static void process_pedit_field(struct ch_filter_specification *fs, u32 val, } static void cxgb4_process_flow_actions(struct net_device *in, - struct tc_cls_flower_offload *cls, + struct flow_cls_offload *cls, struct ch_filter_specification *fs) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(cls); + struct flow_rule *rule = flow_cls_offload_flow_rule(cls); struct flow_action_entry *act; int i; @@ -544,9 +544,9 @@ static bool valid_pedit_action(struct net_device *dev, } static int cxgb4_validate_flow_actions(struct net_device *dev, - struct tc_cls_flower_offload *cls) + struct flow_cls_offload *cls) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(cls); + struct flow_rule *rule = flow_cls_offload_flow_rule(cls); struct flow_action_entry *act; bool act_redir = false; bool act_pedit = false; @@ -633,7 +633,7 @@ static int cxgb4_validate_flow_actions(struct net_device *dev, } int cxgb4_tc_flower_replace(struct net_device *dev, - struct tc_cls_flower_offload *cls) + struct flow_cls_offload *cls) { struct adapter *adap = netdev2adap(dev); struct ch_tc_flower_entry *ch_flower; @@ -709,7 +709,7 @@ free_entry: } int cxgb4_tc_flower_destroy(struct net_device *dev, - struct tc_cls_flower_offload *cls) + struct flow_cls_offload *cls) { struct adapter *adap = netdev2adap(dev); struct ch_tc_flower_entry *ch_flower; @@ -783,7 +783,7 @@ static void ch_flower_stats_cb(struct timer_list *t) } int cxgb4_tc_flower_stats(struct net_device *dev, - struct tc_cls_flower_offload *cls) + struct flow_cls_offload *cls) { struct adapter *adap = netdev2adap(dev); struct ch_tc_flower_stats *ofld_stats; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h index 050c8a50ae41..eb4c95248baf 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h @@ -109,11 +109,11 @@ struct ch_tc_pedit_fields { #define PEDIT_UDP_SPORT_DPORT 0x0 int cxgb4_tc_flower_replace(struct net_device *dev, - struct tc_cls_flower_offload *cls); + struct flow_cls_offload *cls); int cxgb4_tc_flower_destroy(struct net_device *dev, - struct tc_cls_flower_offload *cls); + struct flow_cls_offload *cls); int cxgb4_tc_flower_stats(struct net_device *dev, - struct tc_cls_flower_offload *cls); + struct flow_cls_offload *cls); int cxgb4_init_tc_flower(struct adapter *adap); void cxgb4_cleanup_tc_flower(struct adapter *adap); diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 5361c08328f7..9ebbe3da61bb 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -7759,15 +7759,15 @@ int i40e_add_del_cloud_filter_big_buf(struct i40e_vsi *vsi, /** * i40e_parse_cls_flower - Parse tc flower filters provided by kernel * @vsi: Pointer to VSI - * @cls_flower: Pointer to struct tc_cls_flower_offload + * @cls_flower: Pointer to struct flow_cls_offload * @filter: Pointer to cloud filter structure * **/ static int i40e_parse_cls_flower(struct i40e_vsi *vsi, - struct tc_cls_flower_offload *f, + struct flow_cls_offload *f, struct i40e_cloud_filter *filter) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(f); + struct flow_rule *rule = flow_cls_offload_flow_rule(f); struct flow_dissector *dissector = rule->match.dissector; u16 n_proto_mask = 0, n_proto_key = 0, addr_type = 0; struct i40e_pf *pf = vsi->back; @@ -8001,11 +8001,11 @@ static int i40e_handle_tclass(struct i40e_vsi *vsi, u32 tc, /** * i40e_configure_clsflower - Configure tc flower filters * @vsi: Pointer to VSI - * @cls_flower: Pointer to struct tc_cls_flower_offload + * @cls_flower: Pointer to struct flow_cls_offload * **/ static int i40e_configure_clsflower(struct i40e_vsi *vsi, - struct tc_cls_flower_offload *cls_flower) + struct flow_cls_offload *cls_flower) { int tc = tc_classid_to_hwtc(vsi->netdev, cls_flower->classid); struct i40e_cloud_filter *filter = NULL; @@ -8097,11 +8097,11 @@ static struct i40e_cloud_filter *i40e_find_cloud_filter(struct i40e_vsi *vsi, /** * i40e_delete_clsflower - Remove tc flower filters * @vsi: Pointer to VSI - * @cls_flower: Pointer to struct tc_cls_flower_offload + * @cls_flower: Pointer to struct flow_cls_offload * **/ static int i40e_delete_clsflower(struct i40e_vsi *vsi, - struct tc_cls_flower_offload *cls_flower) + struct flow_cls_offload *cls_flower) { struct i40e_cloud_filter *filter = NULL; struct i40e_pf *pf = vsi->back; @@ -8144,16 +8144,16 @@ static int i40e_delete_clsflower(struct i40e_vsi *vsi, * @type_data: offload data **/ static int i40e_setup_tc_cls_flower(struct i40e_netdev_priv *np, - struct tc_cls_flower_offload *cls_flower) + struct flow_cls_offload *cls_flower) { struct i40e_vsi *vsi = np->vsi; switch (cls_flower->command) { - case TC_CLSFLOWER_REPLACE: + case FLOW_CLS_REPLACE: return i40e_configure_clsflower(vsi, cls_flower); - case TC_CLSFLOWER_DESTROY: + case FLOW_CLS_DESTROY: return i40e_delete_clsflower(vsi, cls_flower); - case TC_CLSFLOWER_STATS: + case FLOW_CLS_STATS: return -EOPNOTSUPP; default: return -EOPNOTSUPP; @@ -8177,34 +8177,21 @@ static int i40e_setup_tc_block_cb(enum tc_setup_type type, void *type_data, } } -static int i40e_setup_tc_block(struct net_device *dev, - struct tc_block_offload *f) -{ - struct i40e_netdev_priv *np = netdev_priv(dev); - - if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS) - return -EOPNOTSUPP; - - switch (f->command) { - case TC_BLOCK_BIND: - return tcf_block_cb_register(f->block, i40e_setup_tc_block_cb, - np, np, f->extack); - case TC_BLOCK_UNBIND: - tcf_block_cb_unregister(f->block, i40e_setup_tc_block_cb, np); - return 0; - default: - return -EOPNOTSUPP; - } -} +static LIST_HEAD(i40e_block_cb_list); static int __i40e_setup_tc(struct net_device *netdev, enum tc_setup_type type, void *type_data) { + struct i40e_netdev_priv *np = netdev_priv(netdev); + switch (type) { case TC_SETUP_QDISC_MQPRIO: return i40e_setup_tc(netdev, type_data); case TC_SETUP_BLOCK: - return i40e_setup_tc_block(netdev, type_data); + return flow_block_cb_setup_simple(type_data, + &i40e_block_cb_list, + i40e_setup_tc_block_cb, + np, np, true); default: return -EOPNOTSUPP; } diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index 881561b36083..9d2b50964a08 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -2699,14 +2699,14 @@ exit: /** * iavf_parse_cls_flower - Parse tc flower filters provided by kernel * @adapter: board private structure - * @cls_flower: pointer to struct tc_cls_flower_offload + * @cls_flower: pointer to struct flow_cls_offload * @filter: pointer to cloud filter structure */ static int iavf_parse_cls_flower(struct iavf_adapter *adapter, - struct tc_cls_flower_offload *f, + struct flow_cls_offload *f, struct iavf_cloud_filter *filter) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(f); + struct flow_rule *rule = flow_cls_offload_flow_rule(f); struct flow_dissector *dissector = rule->match.dissector; u16 n_proto_mask = 0; u16 n_proto_key = 0; @@ -2971,10 +2971,10 @@ static int iavf_handle_tclass(struct iavf_adapter *adapter, u32 tc, /** * iavf_configure_clsflower - Add tc flower filters * @adapter: board private structure - * @cls_flower: Pointer to struct tc_cls_flower_offload + * @cls_flower: Pointer to struct flow_cls_offload */ static int iavf_configure_clsflower(struct iavf_adapter *adapter, - struct tc_cls_flower_offload *cls_flower) + struct flow_cls_offload *cls_flower) { int tc = tc_classid_to_hwtc(adapter->netdev, cls_flower->classid); struct iavf_cloud_filter *filter = NULL; @@ -3050,10 +3050,10 @@ static struct iavf_cloud_filter *iavf_find_cf(struct iavf_adapter *adapter, /** * iavf_delete_clsflower - Remove tc flower filters * @adapter: board private structure - * @cls_flower: Pointer to struct tc_cls_flower_offload + * @cls_flower: Pointer to struct flow_cls_offload */ static int iavf_delete_clsflower(struct iavf_adapter *adapter, - struct tc_cls_flower_offload *cls_flower) + struct flow_cls_offload *cls_flower) { struct iavf_cloud_filter *filter = NULL; int err = 0; @@ -3077,17 +3077,17 @@ static int iavf_delete_clsflower(struct iavf_adapter *adapter, * @type_data: offload data */ static int iavf_setup_tc_cls_flower(struct iavf_adapter *adapter, - struct tc_cls_flower_offload *cls_flower) + struct flow_cls_offload *cls_flower) { if (cls_flower->common.chain_index) return -EOPNOTSUPP; switch (cls_flower->command) { - case TC_CLSFLOWER_REPLACE: + case FLOW_CLS_REPLACE: return iavf_configure_clsflower(adapter, cls_flower); - case TC_CLSFLOWER_DESTROY: + case FLOW_CLS_DESTROY: return iavf_delete_clsflower(adapter, cls_flower); - case TC_CLSFLOWER_STATS: + case FLOW_CLS_STATS: return -EOPNOTSUPP; default: return -EOPNOTSUPP; @@ -3113,34 +3113,7 @@ static int iavf_setup_tc_block_cb(enum tc_setup_type type, void *type_data, } } -/** - * iavf_setup_tc_block - register callbacks for tc - * @netdev: network interface device structure - * @f: tc offload data - * - * This function registers block callbacks for tc - * offloads - **/ -static int iavf_setup_tc_block(struct net_device *dev, - struct tc_block_offload *f) -{ - struct iavf_adapter *adapter = netdev_priv(dev); - - if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS) - return -EOPNOTSUPP; - - switch (f->command) { - case TC_BLOCK_BIND: - return tcf_block_cb_register(f->block, iavf_setup_tc_block_cb, - adapter, adapter, f->extack); - case TC_BLOCK_UNBIND: - tcf_block_cb_unregister(f->block, iavf_setup_tc_block_cb, - adapter); - return 0; - default: - return -EOPNOTSUPP; - } -} +static LIST_HEAD(iavf_block_cb_list); /** * iavf_setup_tc - configure multiple traffic classes @@ -3156,11 +3129,16 @@ static int iavf_setup_tc_block(struct net_device *dev, static int iavf_setup_tc(struct net_device *netdev, enum tc_setup_type type, void *type_data) { + struct iavf_adapter *adapter = netdev_priv(netdev); + switch (type) { case TC_SETUP_QDISC_MQPRIO: return __iavf_setup_tc(netdev, type_data); case TC_SETUP_BLOCK: - return iavf_setup_tc_block(netdev, type_data); + return flow_block_cb_setup_simple(type_data, + &iavf_block_cb_list, + iavf_setup_tc_block_cb, + adapter, adapter, true); default: return -EOPNOTSUPP; } diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index f66dae72fe37..b4df3e319467 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -2578,11 +2578,11 @@ static int igb_offload_cbs(struct igb_adapter *adapter, #define VLAN_PRIO_FULL_MASK (0x07) static int igb_parse_cls_flower(struct igb_adapter *adapter, - struct tc_cls_flower_offload *f, + struct flow_cls_offload *f, int traffic_class, struct igb_nfc_filter *input) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(f); + struct flow_rule *rule = flow_cls_offload_flow_rule(f); struct flow_dissector *dissector = rule->match.dissector; struct netlink_ext_ack *extack = f->common.extack; @@ -2660,7 +2660,7 @@ static int igb_parse_cls_flower(struct igb_adapter *adapter, } static int igb_configure_clsflower(struct igb_adapter *adapter, - struct tc_cls_flower_offload *cls_flower) + struct flow_cls_offload *cls_flower) { struct netlink_ext_ack *extack = cls_flower->common.extack; struct igb_nfc_filter *filter, *f; @@ -2722,7 +2722,7 @@ err_parse: } static int igb_delete_clsflower(struct igb_adapter *adapter, - struct tc_cls_flower_offload *cls_flower) + struct flow_cls_offload *cls_flower) { struct igb_nfc_filter *filter; int err; @@ -2752,14 +2752,14 @@ out: } static int igb_setup_tc_cls_flower(struct igb_adapter *adapter, - struct tc_cls_flower_offload *cls_flower) + struct flow_cls_offload *cls_flower) { switch (cls_flower->command) { - case TC_CLSFLOWER_REPLACE: + case FLOW_CLS_REPLACE: return igb_configure_clsflower(adapter, cls_flower); - case TC_CLSFLOWER_DESTROY: + case FLOW_CLS_DESTROY: return igb_delete_clsflower(adapter, cls_flower); - case TC_CLSFLOWER_STATS: + case FLOW_CLS_STATS: return -EOPNOTSUPP; default: return -EOPNOTSUPP; @@ -2783,25 +2783,6 @@ static int igb_setup_tc_block_cb(enum tc_setup_type type, void *type_data, } } -static int igb_setup_tc_block(struct igb_adapter *adapter, - struct tc_block_offload *f) -{ - if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS) - return -EOPNOTSUPP; - - switch (f->command) { - case TC_BLOCK_BIND: - return tcf_block_cb_register(f->block, igb_setup_tc_block_cb, - adapter, adapter, f->extack); - case TC_BLOCK_UNBIND: - tcf_block_cb_unregister(f->block, igb_setup_tc_block_cb, - adapter); - return 0; - default: - return -EOPNOTSUPP; - } -} - static int igb_offload_txtime(struct igb_adapter *adapter, struct tc_etf_qopt_offload *qopt) { @@ -2825,6 +2806,8 @@ static int igb_offload_txtime(struct igb_adapter *adapter, return 0; } +static LIST_HEAD(igb_block_cb_list); + static int igb_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data) { @@ -2834,7 +2817,11 @@ static int igb_setup_tc(struct net_device *dev, enum tc_setup_type type, case TC_SETUP_QDISC_CBS: return igb_offload_cbs(adapter, type_data); case TC_SETUP_BLOCK: - return igb_setup_tc_block(adapter, type_data); + return flow_block_cb_setup_simple(type_data, + &igb_block_cb_list, + igb_setup_tc_block_cb, + adapter, adapter, true); + case TC_SETUP_QDISC_ETF: return igb_offload_txtime(adapter, type_data); diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index b613e72c8ee4..cbaf712d6529 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -9607,27 +9607,6 @@ static int ixgbe_setup_tc_block_cb(enum tc_setup_type type, void *type_data, } } -static int ixgbe_setup_tc_block(struct net_device *dev, - struct tc_block_offload *f) -{ - struct ixgbe_adapter *adapter = netdev_priv(dev); - - if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS) - return -EOPNOTSUPP; - - switch (f->command) { - case TC_BLOCK_BIND: - return tcf_block_cb_register(f->block, ixgbe_setup_tc_block_cb, - adapter, adapter, f->extack); - case TC_BLOCK_UNBIND: - tcf_block_cb_unregister(f->block, ixgbe_setup_tc_block_cb, - adapter); - return 0; - default: - return -EOPNOTSUPP; - } -} - static int ixgbe_setup_tc_mqprio(struct net_device *dev, struct tc_mqprio_qopt *mqprio) { @@ -9635,12 +9614,19 @@ static int ixgbe_setup_tc_mqprio(struct net_device *dev, return ixgbe_setup_tc(dev, mqprio->num_tc); } +static LIST_HEAD(ixgbe_block_cb_list); + static int __ixgbe_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data) { + struct ixgbe_adapter *adapter = netdev_priv(dev); + switch (type) { case TC_SETUP_BLOCK: - return ixgbe_setup_tc_block(dev, type_data); + return flow_block_cb_setup_simple(type_data, + &ixgbe_block_cb_list, + ixgbe_setup_tc_block_cb, + adapter, adapter, true); case TC_SETUP_QDISC_MQPRIO: return ixgbe_setup_tc_mqprio(dev, type_data); default: diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c index 3739646b653f..a6a52806be45 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c @@ -452,7 +452,7 @@ int mlx5e_tc_tun_init_encap_attr(struct net_device *tunnel_dev, int mlx5e_tc_tun_parse(struct net_device *filter_dev, struct mlx5e_priv *priv, struct mlx5_flow_spec *spec, - struct tc_cls_flower_offload *f, + struct flow_cls_offload *f, void *headers_c, void *headers_v, u8 *match_level) { @@ -489,11 +489,11 @@ out: int mlx5e_tc_tun_parse_udp_ports(struct mlx5e_priv *priv, struct mlx5_flow_spec *spec, - struct tc_cls_flower_offload *f, + struct flow_cls_offload *f, void *headers_c, void *headers_v) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(f); + struct flow_rule *rule = flow_cls_offload_flow_rule(f); struct netlink_ext_ack *extack = f->common.extack; struct flow_match_ports enc_ports; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.h b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.h index 3c48f7e62505..c362b9225dc2 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.h @@ -33,12 +33,12 @@ struct mlx5e_tc_tunnel { struct mlx5e_encap_entry *e); int (*parse_udp_ports)(struct mlx5e_priv *priv, struct mlx5_flow_spec *spec, - struct tc_cls_flower_offload *f, + struct flow_cls_offload *f, void *headers_c, void *headers_v); int (*parse_tunnel)(struct mlx5e_priv *priv, struct mlx5_flow_spec *spec, - struct tc_cls_flower_offload *f, + struct flow_cls_offload *f, void *headers_c, void *headers_v); }; @@ -68,13 +68,13 @@ bool mlx5e_tc_tun_device_to_offload(struct mlx5e_priv *priv, int mlx5e_tc_tun_parse(struct net_device *filter_dev, struct mlx5e_priv *priv, struct mlx5_flow_spec *spec, - struct tc_cls_flower_offload *f, + struct flow_cls_offload *f, void *headers_c, void *headers_v, u8 *match_level); int mlx5e_tc_tun_parse_udp_ports(struct mlx5e_priv *priv, struct mlx5_flow_spec *spec, - struct tc_cls_flower_offload *f, + struct flow_cls_offload *f, void *headers_c, void *headers_v); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_geneve.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_geneve.c index 238ae85d07cc..951ea26d96bc 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_geneve.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_geneve.c @@ -20,9 +20,9 @@ static int mlx5e_tc_tun_calc_hlen_geneve(struct mlx5e_encap_entry *e) } static int mlx5e_tc_tun_check_udp_dport_geneve(struct mlx5e_priv *priv, - struct tc_cls_flower_offload *f) + struct flow_cls_offload *f) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(f); + struct flow_rule *rule = flow_cls_offload_flow_rule(f); struct netlink_ext_ack *extack = f->common.extack; struct flow_match_ports enc_ports; @@ -48,7 +48,7 @@ static int mlx5e_tc_tun_check_udp_dport_geneve(struct mlx5e_priv *priv, static int mlx5e_tc_tun_parse_udp_ports_geneve(struct mlx5e_priv *priv, struct mlx5_flow_spec *spec, - struct tc_cls_flower_offload *f, + struct flow_cls_offload *f, void *headers_c, void *headers_v) { @@ -122,9 +122,9 @@ static int mlx5e_gen_ip_tunnel_header_geneve(char buf[], static int mlx5e_tc_tun_parse_geneve_vni(struct mlx5e_priv *priv, struct mlx5_flow_spec *spec, - struct tc_cls_flower_offload *f) + struct flow_cls_offload *f) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(f); + struct flow_rule *rule = flow_cls_offload_flow_rule(f); struct netlink_ext_ack *extack = f->common.extack; struct flow_match_enc_keyid enc_keyid; void *misc_c, *misc_v; @@ -154,11 +154,11 @@ static int mlx5e_tc_tun_parse_geneve_vni(struct mlx5e_priv *priv, static int mlx5e_tc_tun_parse_geneve_options(struct mlx5e_priv *priv, struct mlx5_flow_spec *spec, - struct tc_cls_flower_offload *f) + struct flow_cls_offload *f) { u8 max_tlv_option_data_len = MLX5_CAP_GEN(priv->mdev, max_geneve_tlv_option_data_len); u8 max_tlv_options = MLX5_CAP_GEN(priv->mdev, max_geneve_tlv_options); - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(f); + struct flow_rule *rule = flow_cls_offload_flow_rule(f); struct netlink_ext_ack *extack = f->common.extack; void *misc_c, *misc_v, *misc_3_c, *misc_3_v; struct geneve_opt *option_key, *option_mask; @@ -277,7 +277,7 @@ static int mlx5e_tc_tun_parse_geneve_options(struct mlx5e_priv *priv, static int mlx5e_tc_tun_parse_geneve_params(struct mlx5e_priv *priv, struct mlx5_flow_spec *spec, - struct tc_cls_flower_offload *f) + struct flow_cls_offload *f) { void *misc_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria, misc_parameters); void *misc_v = MLX5_ADDR_OF(fte_match_param, spec->match_value, misc_parameters); @@ -306,7 +306,7 @@ static int mlx5e_tc_tun_parse_geneve_params(struct mlx5e_priv *priv, static int mlx5e_tc_tun_parse_geneve(struct mlx5e_priv *priv, struct mlx5_flow_spec *spec, - struct tc_cls_flower_offload *f, + struct flow_cls_offload *f, void *headers_c, void *headers_v) { diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_gre.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_gre.c index 06908441d932..58b13192df23 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_gre.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_gre.c @@ -54,13 +54,13 @@ static int mlx5e_gen_ip_tunnel_header_gretap(char buf[], static int mlx5e_tc_tun_parse_gretap(struct mlx5e_priv *priv, struct mlx5_flow_spec *spec, - struct tc_cls_flower_offload *f, + struct flow_cls_offload *f, void *headers_c, void *headers_v) { void *misc_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria, misc_parameters); void *misc_v = MLX5_ADDR_OF(fte_match_param, spec->match_value, misc_parameters); - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(f); + struct flow_rule *rule = flow_cls_offload_flow_rule(f); MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, headers_c, ip_protocol); MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_protocol, IPPROTO_GRE); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c index 2857b38527d6..37b176801bcc 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c @@ -16,9 +16,9 @@ static int mlx5e_tc_tun_calc_hlen_vxlan(struct mlx5e_encap_entry *e) } static int mlx5e_tc_tun_check_udp_dport_vxlan(struct mlx5e_priv *priv, - struct tc_cls_flower_offload *f) + struct flow_cls_offload *f) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(f); + struct flow_rule *rule = flow_cls_offload_flow_rule(f); struct netlink_ext_ack *extack = f->common.extack; struct flow_match_ports enc_ports; @@ -44,7 +44,7 @@ static int mlx5e_tc_tun_check_udp_dport_vxlan(struct mlx5e_priv *priv, static int mlx5e_tc_tun_parse_udp_ports_vxlan(struct mlx5e_priv *priv, struct mlx5_flow_spec *spec, - struct tc_cls_flower_offload *f, + struct flow_cls_offload *f, void *headers_c, void *headers_v) { @@ -100,11 +100,11 @@ static int mlx5e_gen_ip_tunnel_header_vxlan(char buf[], static int mlx5e_tc_tun_parse_vxlan(struct mlx5e_priv *priv, struct mlx5_flow_spec *spec, - struct tc_cls_flower_offload *f, + struct flow_cls_offload *f, void *headers_c, void *headers_v) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(f); + struct flow_rule *rule = flow_cls_offload_flow_rule(f); struct netlink_ext_ack *extack = f->common.extack; struct flow_match_enc_keyid enc_keyid; void *misc_c, *misc_v; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 10efd69de7ef..6d0ae87c8ded 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -3426,17 +3426,17 @@ out: #ifdef CONFIG_MLX5_ESWITCH static int mlx5e_setup_tc_cls_flower(struct mlx5e_priv *priv, - struct tc_cls_flower_offload *cls_flower, + struct flow_cls_offload *cls_flower, int flags) { switch (cls_flower->command) { - case TC_CLSFLOWER_REPLACE: + case FLOW_CLS_REPLACE: return mlx5e_configure_flower(priv->netdev, priv, cls_flower, flags); - case TC_CLSFLOWER_DESTROY: + case FLOW_CLS_DESTROY: return mlx5e_delete_flower(priv->netdev, priv, cls_flower, flags); - case TC_CLSFLOWER_STATS: + case FLOW_CLS_STATS: return mlx5e_stats_flower(priv->netdev, priv, cls_flower, flags); default: @@ -3457,36 +3457,22 @@ static int mlx5e_setup_tc_block_cb(enum tc_setup_type type, void *type_data, return -EOPNOTSUPP; } } - -static int mlx5e_setup_tc_block(struct net_device *dev, - struct tc_block_offload *f) -{ - struct mlx5e_priv *priv = netdev_priv(dev); - - if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS) - return -EOPNOTSUPP; - - switch (f->command) { - case TC_BLOCK_BIND: - return tcf_block_cb_register(f->block, mlx5e_setup_tc_block_cb, - priv, priv, f->extack); - case TC_BLOCK_UNBIND: - tcf_block_cb_unregister(f->block, mlx5e_setup_tc_block_cb, - priv); - return 0; - default: - return -EOPNOTSUPP; - } -} #endif +static LIST_HEAD(mlx5e_block_cb_list); + static int mlx5e_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data) { + struct mlx5e_priv *priv = netdev_priv(dev); + switch (type) { #ifdef CONFIG_MLX5_ESWITCH case TC_SETUP_BLOCK: - return mlx5e_setup_tc_block(dev, type_data); + return flow_block_cb_setup_simple(type_data, + &mlx5e_block_cb_list, + mlx5e_setup_tc_block_cb, + priv, priv, true); #endif case TC_SETUP_QDISC_MQPRIO: return mlx5e_setup_tc_mqprio(dev, type_data); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c index 6810b9fa0705..10ef90a7bddd 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c @@ -656,7 +656,7 @@ static void mlx5e_rep_indr_clean_block_privs(struct mlx5e_rep_priv *rpriv) static int mlx5e_rep_indr_offload(struct net_device *netdev, - struct tc_cls_flower_offload *flower, + struct flow_cls_offload *flower, struct mlx5e_rep_indr_block_priv *indr_priv) { struct mlx5e_priv *priv = netdev_priv(indr_priv->rpriv->netdev); @@ -664,13 +664,13 @@ mlx5e_rep_indr_offload(struct net_device *netdev, int err = 0; switch (flower->command) { - case TC_CLSFLOWER_REPLACE: + case FLOW_CLS_REPLACE: err = mlx5e_configure_flower(netdev, priv, flower, flags); break; - case TC_CLSFLOWER_DESTROY: + case FLOW_CLS_DESTROY: err = mlx5e_delete_flower(netdev, priv, flower, flags); break; - case TC_CLSFLOWER_STATS: + case FLOW_CLS_STATS: err = mlx5e_stats_flower(netdev, priv, flower, flags); break; default: @@ -693,23 +693,39 @@ static int mlx5e_rep_indr_setup_block_cb(enum tc_setup_type type, } } +static void mlx5e_rep_indr_tc_block_unbind(void *cb_priv) +{ + struct mlx5e_rep_indr_block_priv *indr_priv = cb_priv; + + list_del(&indr_priv->list); + kfree(indr_priv); +} + +static LIST_HEAD(mlx5e_block_cb_list); + static int mlx5e_rep_indr_setup_tc_block(struct net_device *netdev, struct mlx5e_rep_priv *rpriv, - struct tc_block_offload *f) + struct flow_block_offload *f) { struct mlx5e_rep_indr_block_priv *indr_priv; - int err = 0; + struct flow_block_cb *block_cb; - if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS) + if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) return -EOPNOTSUPP; + f->driver_block_list = &mlx5e_block_cb_list; + switch (f->command) { - case TC_BLOCK_BIND: + case FLOW_BLOCK_BIND: indr_priv = mlx5e_rep_indr_block_priv_lookup(rpriv, 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; @@ -719,26 +735,32 @@ mlx5e_rep_indr_setup_tc_block(struct net_device *netdev, list_add(&indr_priv->list, &rpriv->uplink_priv.tc_indr_block_priv_list); - err = tcf_block_cb_register(f->block, - mlx5e_rep_indr_setup_block_cb, - indr_priv, indr_priv, f->extack); - if (err) { + block_cb = flow_block_cb_alloc(f->net, + mlx5e_rep_indr_setup_block_cb, + indr_priv, indr_priv, + mlx5e_rep_indr_tc_block_unbind); + if (IS_ERR(block_cb)) { list_del(&indr_priv->list); kfree(indr_priv); + return PTR_ERR(block_cb); } + flow_block_cb_add(block_cb, f); + list_add_tail(&block_cb->driver_list, &mlx5e_block_cb_list); - return err; - case TC_BLOCK_UNBIND: + return 0; + case FLOW_BLOCK_UNBIND: indr_priv = mlx5e_rep_indr_block_priv_lookup(rpriv, netdev); if (!indr_priv) return -ENOENT; - tcf_block_cb_unregister(f->block, - mlx5e_rep_indr_setup_block_cb, - indr_priv); - list_del(&indr_priv->list); - kfree(indr_priv); + block_cb = flow_block_cb_lookup(f, + mlx5e_rep_indr_setup_block_cb, + indr_priv); + if (!block_cb) + return -ENOENT; + flow_block_cb_remove(block_cb, f); + list_del(&block_cb->driver_list); return 0; default: return -EOPNOTSUPP; @@ -1122,16 +1144,16 @@ static int mlx5e_rep_close(struct net_device *dev) static int mlx5e_rep_setup_tc_cls_flower(struct mlx5e_priv *priv, - struct tc_cls_flower_offload *cls_flower, int flags) + struct flow_cls_offload *cls_flower, int flags) { switch (cls_flower->command) { - case TC_CLSFLOWER_REPLACE: + case FLOW_CLS_REPLACE: return mlx5e_configure_flower(priv->netdev, priv, cls_flower, flags); - case TC_CLSFLOWER_DESTROY: + case FLOW_CLS_DESTROY: return mlx5e_delete_flower(priv->netdev, priv, cls_flower, flags); - case TC_CLSFLOWER_STATS: + case FLOW_CLS_STATS: return mlx5e_stats_flower(priv->netdev, priv, cls_flower, flags); default: @@ -1153,32 +1175,16 @@ static int mlx5e_rep_setup_tc_cb(enum tc_setup_type type, void *type_data, } } -static int mlx5e_rep_setup_tc_block(struct net_device *dev, - struct tc_block_offload *f) -{ - struct mlx5e_priv *priv = netdev_priv(dev); - - if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS) - return -EOPNOTSUPP; - - switch (f->command) { - case TC_BLOCK_BIND: - return tcf_block_cb_register(f->block, mlx5e_rep_setup_tc_cb, - priv, priv, f->extack); - case TC_BLOCK_UNBIND: - tcf_block_cb_unregister(f->block, mlx5e_rep_setup_tc_cb, priv); - return 0; - default: - return -EOPNOTSUPP; - } -} - static int mlx5e_rep_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data) { + struct mlx5e_priv *priv = netdev_priv(dev); + switch (type) { case TC_SETUP_BLOCK: - return mlx5e_rep_setup_tc_block(dev, type_data); + return flow_block_cb_setup_simple(type_data, NULL, + mlx5e_rep_setup_tc_cb, + priv, priv, true); default: return -EOPNOTSUPP; } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index 3ac9b1e423ee..2d6436257f9d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -1350,7 +1350,7 @@ static void mlx5e_tc_del_flow(struct mlx5e_priv *priv, static int parse_tunnel_attr(struct mlx5e_priv *priv, struct mlx5_flow_spec *spec, - struct tc_cls_flower_offload *f, + struct flow_cls_offload *f, struct net_device *filter_dev, u8 *match_level) { struct netlink_ext_ack *extack = f->common.extack; @@ -1358,7 +1358,7 @@ static int parse_tunnel_attr(struct mlx5e_priv *priv, outer_headers); void *headers_v = MLX5_ADDR_OF(fte_match_param, spec->match_value, outer_headers); - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(f); + struct flow_rule *rule = flow_cls_offload_flow_rule(f); int err; err = mlx5e_tc_tun_parse(filter_dev, priv, spec, f, @@ -1478,7 +1478,7 @@ static void *get_match_headers_value(u32 flags, static int __parse_cls_flower(struct mlx5e_priv *priv, struct mlx5_flow_spec *spec, - struct tc_cls_flower_offload *f, + struct flow_cls_offload *f, struct net_device *filter_dev, u8 *match_level, u8 *tunnel_match_level) { @@ -1491,7 +1491,7 @@ static int __parse_cls_flower(struct mlx5e_priv *priv, misc_parameters); void *misc_v = MLX5_ADDR_OF(fte_match_param, spec->match_value, misc_parameters); - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(f); + struct flow_rule *rule = flow_cls_offload_flow_rule(f); struct flow_dissector *dissector = rule->match.dissector; u16 addr_type = 0; u8 ip_proto = 0; @@ -1831,7 +1831,7 @@ static int __parse_cls_flower(struct mlx5e_priv *priv, static int parse_cls_flower(struct mlx5e_priv *priv, struct mlx5e_tc_flow *flow, struct mlx5_flow_spec *spec, - struct tc_cls_flower_offload *f, + struct flow_cls_offload *f, struct net_device *filter_dev) { struct netlink_ext_ack *extack = f->common.extack; @@ -3115,7 +3115,7 @@ static bool is_peer_flow_needed(struct mlx5e_tc_flow *flow) static int mlx5e_alloc_flow(struct mlx5e_priv *priv, int attr_size, - struct tc_cls_flower_offload *f, u16 flow_flags, + struct flow_cls_offload *f, u16 flow_flags, struct mlx5e_tc_flow_parse_attr **__parse_attr, struct mlx5e_tc_flow **__flow) { @@ -3149,7 +3149,7 @@ static void mlx5e_flow_esw_attr_init(struct mlx5_esw_flow_attr *esw_attr, struct mlx5e_priv *priv, struct mlx5e_tc_flow_parse_attr *parse_attr, - struct tc_cls_flower_offload *f, + struct flow_cls_offload *f, struct mlx5_eswitch_rep *in_rep, struct mlx5_core_dev *in_mdev) { @@ -3171,13 +3171,13 @@ mlx5e_flow_esw_attr_init(struct mlx5_esw_flow_attr *esw_attr, static struct mlx5e_tc_flow * __mlx5e_add_fdb_flow(struct mlx5e_priv *priv, - struct tc_cls_flower_offload *f, + struct flow_cls_offload *f, u16 flow_flags, struct net_device *filter_dev, struct mlx5_eswitch_rep *in_rep, struct mlx5_core_dev *in_mdev) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(f); + struct flow_rule *rule = flow_cls_offload_flow_rule(f); struct netlink_ext_ack *extack = f->common.extack; struct mlx5e_tc_flow_parse_attr *parse_attr; struct mlx5e_tc_flow *flow; @@ -3221,7 +3221,7 @@ out: return ERR_PTR(err); } -static int mlx5e_tc_add_fdb_peer_flow(struct tc_cls_flower_offload *f, +static int mlx5e_tc_add_fdb_peer_flow(struct flow_cls_offload *f, struct mlx5e_tc_flow *flow, u16 flow_flags) { @@ -3273,7 +3273,7 @@ out: static int mlx5e_add_fdb_flow(struct mlx5e_priv *priv, - struct tc_cls_flower_offload *f, + struct flow_cls_offload *f, u16 flow_flags, struct net_device *filter_dev, struct mlx5e_tc_flow **__flow) @@ -3307,12 +3307,12 @@ out: static int mlx5e_add_nic_flow(struct mlx5e_priv *priv, - struct tc_cls_flower_offload *f, + struct flow_cls_offload *f, u16 flow_flags, struct net_device *filter_dev, struct mlx5e_tc_flow **__flow) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(f); + struct flow_rule *rule = flow_cls_offload_flow_rule(f); struct netlink_ext_ack *extack = f->common.extack; struct mlx5e_tc_flow_parse_attr *parse_attr; struct mlx5e_tc_flow *flow; @@ -3358,7 +3358,7 @@ out: static int mlx5e_tc_add_flow(struct mlx5e_priv *priv, - struct tc_cls_flower_offload *f, + struct flow_cls_offload *f, int flags, struct net_device *filter_dev, struct mlx5e_tc_flow **flow) @@ -3383,7 +3383,7 @@ mlx5e_tc_add_flow(struct mlx5e_priv *priv, } int mlx5e_configure_flower(struct net_device *dev, struct mlx5e_priv *priv, - struct tc_cls_flower_offload *f, int flags) + struct flow_cls_offload *f, int flags) { struct netlink_ext_ack *extack = f->common.extack; struct rhashtable *tc_ht = get_tc_ht(priv, flags); @@ -3430,7 +3430,7 @@ static bool same_flow_direction(struct mlx5e_tc_flow *flow, int flags) } int mlx5e_delete_flower(struct net_device *dev, struct mlx5e_priv *priv, - struct tc_cls_flower_offload *f, int flags) + struct flow_cls_offload *f, int flags) { struct rhashtable *tc_ht = get_tc_ht(priv, flags); struct mlx5e_tc_flow *flow; @@ -3449,7 +3449,7 @@ int mlx5e_delete_flower(struct net_device *dev, struct mlx5e_priv *priv, } int mlx5e_stats_flower(struct net_device *dev, struct mlx5e_priv *priv, - struct tc_cls_flower_offload *f, int flags) + struct flow_cls_offload *f, int flags) { struct mlx5_devcom *devcom = priv->mdev->priv.devcom; struct rhashtable *tc_ht = get_tc_ht(priv, flags); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h index 8f288cc53cee..3ab39275ca7d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h @@ -54,12 +54,12 @@ int mlx5e_tc_esw_init(struct rhashtable *tc_ht); void mlx5e_tc_esw_cleanup(struct rhashtable *tc_ht); int mlx5e_configure_flower(struct net_device *dev, struct mlx5e_priv *priv, - struct tc_cls_flower_offload *f, int flags); + struct flow_cls_offload *f, int flags); int mlx5e_delete_flower(struct net_device *dev, struct mlx5e_priv *priv, - struct tc_cls_flower_offload *f, int flags); + struct flow_cls_offload *f, int flags); int mlx5e_stats_flower(struct net_device *dev, struct mlx5e_priv *priv, - struct tc_cls_flower_offload *f, int flags); + struct flow_cls_offload *f, int flags); struct mlx5e_encap_entry; void mlx5e_tc_encap_flows_add(struct mlx5e_priv *priv, diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c index ce285fbeebd3..4d34d42b3b0e 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c @@ -1508,21 +1508,21 @@ static int mlxsw_sp_setup_tc_cls_matchall(struct mlxsw_sp_port *mlxsw_sp_port, static int mlxsw_sp_setup_tc_cls_flower(struct mlxsw_sp_acl_block *acl_block, - struct tc_cls_flower_offload *f) + struct flow_cls_offload *f) { struct mlxsw_sp *mlxsw_sp = mlxsw_sp_acl_block_mlxsw_sp(acl_block); switch (f->command) { - case TC_CLSFLOWER_REPLACE: + case FLOW_CLS_REPLACE: return mlxsw_sp_flower_replace(mlxsw_sp, acl_block, f); - case TC_CLSFLOWER_DESTROY: + case FLOW_CLS_DESTROY: mlxsw_sp_flower_destroy(mlxsw_sp, acl_block, f); return 0; - case TC_CLSFLOWER_STATS: + case FLOW_CLS_STATS: return mlxsw_sp_flower_stats(mlxsw_sp, acl_block, f); - case TC_CLSFLOWER_TMPLT_CREATE: + case FLOW_CLS_TMPLT_CREATE: return mlxsw_sp_flower_tmplt_create(mlxsw_sp, acl_block, f); - case TC_CLSFLOWER_TMPLT_DESTROY: + case FLOW_CLS_TMPLT_DESTROY: mlxsw_sp_flower_tmplt_destroy(mlxsw_sp, acl_block, f); return 0; default: @@ -1585,33 +1585,45 @@ static int mlxsw_sp_setup_tc_block_cb_flower(enum tc_setup_type type, } } +static void mlxsw_sp_tc_block_flower_release(void *cb_priv) +{ + struct mlxsw_sp_acl_block *acl_block = cb_priv; + + mlxsw_sp_acl_block_destroy(acl_block); +} + +static LIST_HEAD(mlxsw_sp_block_cb_list); + 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); + } + return 0; err_block_bind: - if (!tcf_block_cb_decref(block_cb)) { - __tcf_block_cb_unregister(block, block_cb); + if (!flow_block_cb_decref(block_cb)) + flow_block_cb_free(block_cb); err_cb_register: - mlxsw_sp_acl_block_destroy(acl_block); - } return err; } static void mlxsw_sp_setup_tc_block_flower_unbind(struct mlxsw_sp_port *mlxsw_sp_port, - struct tcf_block *block, bool ingress) + 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; 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) return; @@ -1652,50 +1667,63 @@ mlxsw_sp_setup_tc_block_flower_unbind(struct mlxsw_sp_port *mlxsw_sp_port, else mlxsw_sp_port->eg_acl_block = NULL; - acl_block = tcf_block_cb_priv(block_cb); + acl_block = flow_block_cb_priv(block_cb); err = mlxsw_sp_acl_block_unbind(mlxsw_sp, acl_block, mlxsw_sp_port, ingress); - if (!err && !tcf_block_cb_decref(block_cb)) { - __tcf_block_cb_unregister(block, block_cb); - mlxsw_sp_acl_block_destroy(acl_block); + if (!err && !flow_block_cb_decref(block_cb)) { + flow_block_cb_remove(block_cb, f); + list_del(&block_cb->driver_list); } } static int mlxsw_sp_setup_tc_block(struct mlxsw_sp_port *mlxsw_sp_port, - struct tc_block_offload *f) + struct flow_block_offload *f) { + struct flow_block_cb *block_cb; tc_setup_cb_t *cb; bool ingress; int err; - if (f->binder_type == TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS) { + if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) { cb = mlxsw_sp_setup_tc_block_cb_matchall_ig; ingress = true; - } else if (f->binder_type == TCF_BLOCK_BINDER_TYPE_CLSACT_EGRESS) { + } else if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS) { cb = mlxsw_sp_setup_tc_block_cb_matchall_eg; ingress = false; } else { return -EOPNOTSUPP; } + f->driver_block_list = &mlxsw_sp_block_cb_list; + switch (f->command) { - case TC_BLOCK_BIND: - err = tcf_block_cb_register(f->block, cb, mlxsw_sp_port, - mlxsw_sp_port, f->extack); - if (err) - return err; - err = mlxsw_sp_setup_tc_block_flower_bind(mlxsw_sp_port, - f->block, ingress, - f->extack); + 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)) + return PTR_ERR(block_cb); + err = mlxsw_sp_setup_tc_block_flower_bind(mlxsw_sp_port, f, + ingress); if (err) { - tcf_block_cb_unregister(f->block, cb, mlxsw_sp_port); + flow_block_cb_free(block_cb); return err; } + flow_block_cb_add(block_cb, f); + list_add_tail(&block_cb->driver_list, &mlxsw_sp_block_cb_list); return 0; - case TC_BLOCK_UNBIND: + case FLOW_BLOCK_UNBIND: mlxsw_sp_setup_tc_block_flower_unbind(mlxsw_sp_port, - f->block, ingress); - tcf_block_cb_unregister(f->block, cb, mlxsw_sp_port); + f, ingress); + block_cb = flow_block_cb_lookup(f, cb, mlxsw_sp_port); + if (!block_cb) + return -ENOENT; + + flow_block_cb_remove(block_cb, f); + list_del(&block_cb->driver_list); return 0; default: return -EOPNOTSUPP; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h index abbb563db440..a252b080dda9 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h @@ -807,19 +807,19 @@ extern const struct mlxsw_afk_ops mlxsw_sp2_afk_ops; /* spectrum_flower.c */ int mlxsw_sp_flower_replace(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_block *block, - struct tc_cls_flower_offload *f); + struct flow_cls_offload *f); void mlxsw_sp_flower_destroy(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_block *block, - struct tc_cls_flower_offload *f); + struct flow_cls_offload *f); int mlxsw_sp_flower_stats(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_block *block, - struct tc_cls_flower_offload *f); + struct flow_cls_offload *f); int mlxsw_sp_flower_tmplt_create(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_block *block, - struct tc_cls_flower_offload *f); + struct flow_cls_offload *f); void mlxsw_sp_flower_tmplt_destroy(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_block *block, - struct tc_cls_flower_offload *f); + struct flow_cls_offload *f); /* spectrum_qdisc.c */ int mlxsw_sp_tc_qdisc_init(struct mlxsw_sp_port *mlxsw_sp_port); diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c index a83e1a986ef1..202e9a246019 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c @@ -121,10 +121,10 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp, } static int mlxsw_sp_flower_parse_meta(struct mlxsw_sp_acl_rule_info *rulei, - struct tc_cls_flower_offload *f, + struct flow_cls_offload *f, struct mlxsw_sp_acl_block *block) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(f); + struct flow_rule *rule = flow_cls_offload_flow_rule(f); struct mlxsw_sp_port *mlxsw_sp_port; struct net_device *ingress_dev; struct flow_match_meta match; @@ -164,7 +164,7 @@ static int mlxsw_sp_flower_parse_meta(struct mlxsw_sp_acl_rule_info *rulei, } static void mlxsw_sp_flower_parse_ipv4(struct mlxsw_sp_acl_rule_info *rulei, - struct tc_cls_flower_offload *f) + struct flow_cls_offload *f) { struct flow_match_ipv4_addrs match; @@ -179,7 +179,7 @@ static void mlxsw_sp_flower_parse_ipv4(struct mlxsw_sp_acl_rule_info *rulei, } static void mlxsw_sp_flower_parse_ipv6(struct mlxsw_sp_acl_rule_info *rulei, - struct tc_cls_flower_offload *f) + struct flow_cls_offload *f) { struct flow_match_ipv6_addrs match; @@ -213,10 +213,10 @@ static void mlxsw_sp_flower_parse_ipv6(struct mlxsw_sp_acl_rule_info *rulei, static int mlxsw_sp_flower_parse_ports(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_rule_info *rulei, - struct tc_cls_flower_offload *f, + struct flow_cls_offload *f, u8 ip_proto) { - const struct flow_rule *rule = tc_cls_flower_offload_flow_rule(f); + const struct flow_rule *rule = flow_cls_offload_flow_rule(f); struct flow_match_ports match; if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PORTS)) @@ -240,10 +240,10 @@ static int mlxsw_sp_flower_parse_ports(struct mlxsw_sp *mlxsw_sp, static int mlxsw_sp_flower_parse_tcp(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_rule_info *rulei, - struct tc_cls_flower_offload *f, + struct flow_cls_offload *f, u8 ip_proto) { - const struct flow_rule *rule = tc_cls_flower_offload_flow_rule(f); + const struct flow_rule *rule = flow_cls_offload_flow_rule(f); struct flow_match_tcp match; if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_TCP)) @@ -265,10 +265,10 @@ static int mlxsw_sp_flower_parse_tcp(struct mlxsw_sp *mlxsw_sp, static int mlxsw_sp_flower_parse_ip(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_rule_info *rulei, - struct tc_cls_flower_offload *f, + struct flow_cls_offload *f, u16 n_proto) { - const struct flow_rule *rule = tc_cls_flower_offload_flow_rule(f); + const struct flow_rule *rule = flow_cls_offload_flow_rule(f); struct flow_match_ip match; if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IP)) @@ -299,9 +299,9 @@ static int mlxsw_sp_flower_parse_ip(struct mlxsw_sp *mlxsw_sp, static int mlxsw_sp_flower_parse(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_block *block, struct mlxsw_sp_acl_rule_info *rulei, - struct tc_cls_flower_offload *f) + struct flow_cls_offload *f) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(f); + struct flow_rule *rule = flow_cls_offload_flow_rule(f); struct flow_dissector *dissector = rule->match.dissector; u16 n_proto_mask = 0; u16 n_proto_key = 0; @@ -426,7 +426,7 @@ static int mlxsw_sp_flower_parse(struct mlxsw_sp *mlxsw_sp, int mlxsw_sp_flower_replace(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_block *block, - struct tc_cls_flower_offload *f) + struct flow_cls_offload *f) { struct mlxsw_sp_acl_rule_info *rulei; struct mlxsw_sp_acl_ruleset *ruleset; @@ -473,7 +473,7 @@ err_rule_create: void mlxsw_sp_flower_destroy(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_block *block, - struct tc_cls_flower_offload *f) + struct flow_cls_offload *f) { struct mlxsw_sp_acl_ruleset *ruleset; struct mlxsw_sp_acl_rule *rule; @@ -495,7 +495,7 @@ void mlxsw_sp_flower_destroy(struct mlxsw_sp *mlxsw_sp, int mlxsw_sp_flower_stats(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_block *block, - struct tc_cls_flower_offload *f) + struct flow_cls_offload *f) { struct mlxsw_sp_acl_ruleset *ruleset; struct mlxsw_sp_acl_rule *rule; @@ -531,7 +531,7 @@ err_rule_get_stats: int mlxsw_sp_flower_tmplt_create(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_block *block, - struct tc_cls_flower_offload *f) + struct flow_cls_offload *f) { struct mlxsw_sp_acl_ruleset *ruleset; struct mlxsw_sp_acl_rule_info rulei; @@ -552,7 +552,7 @@ int mlxsw_sp_flower_tmplt_create(struct mlxsw_sp *mlxsw_sp, void mlxsw_sp_flower_tmplt_destroy(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_block *block, - struct tc_cls_flower_offload *f) + struct flow_cls_offload *f) { struct mlxsw_sp_acl_ruleset *ruleset; diff --git a/drivers/net/ethernet/mscc/ocelot_ace.h b/drivers/net/ethernet/mscc/ocelot_ace.h index d621683643e1..e98944c87259 100644 --- a/drivers/net/ethernet/mscc/ocelot_ace.h +++ b/drivers/net/ethernet/mscc/ocelot_ace.h @@ -225,8 +225,8 @@ int ocelot_ace_init(struct ocelot *ocelot); void ocelot_ace_deinit(void); int ocelot_setup_tc_block_flower_bind(struct ocelot_port *port, - struct tc_block_offload *f); + struct flow_block_offload *f); void ocelot_setup_tc_block_flower_unbind(struct ocelot_port *port, - struct tc_block_offload *f); + struct flow_block_offload *f); #endif /* _MSCC_OCELOT_ACE_H_ */ diff --git a/drivers/net/ethernet/mscc/ocelot_flower.c b/drivers/net/ethernet/mscc/ocelot_flower.c index 8778dee5a471..7aaddc09c185 100644 --- a/drivers/net/ethernet/mscc/ocelot_flower.c +++ b/drivers/net/ethernet/mscc/ocelot_flower.c @@ -19,7 +19,7 @@ static u16 get_prio(u32 prio) return prio >> 16; } -static int ocelot_flower_parse_action(struct tc_cls_flower_offload *f, +static int ocelot_flower_parse_action(struct flow_cls_offload *f, struct ocelot_ace_rule *rule) { const struct flow_action_entry *a; @@ -44,10 +44,10 @@ static int ocelot_flower_parse_action(struct tc_cls_flower_offload *f, return 0; } -static int ocelot_flower_parse(struct tc_cls_flower_offload *f, +static int ocelot_flower_parse(struct flow_cls_offload *f, struct ocelot_ace_rule *ocelot_rule) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(f); + struct flow_rule *rule = flow_cls_offload_flow_rule(f); struct flow_dissector *dissector = rule->match.dissector; if (dissector->used_keys & @@ -174,7 +174,7 @@ finished_key_parsing: } static -struct ocelot_ace_rule *ocelot_ace_rule_create(struct tc_cls_flower_offload *f, +struct ocelot_ace_rule *ocelot_ace_rule_create(struct flow_cls_offload *f, struct ocelot_port_block *block) { struct ocelot_ace_rule *rule; @@ -188,7 +188,7 @@ struct ocelot_ace_rule *ocelot_ace_rule_create(struct tc_cls_flower_offload *f, return rule; } -static int ocelot_flower_replace(struct tc_cls_flower_offload *f, +static int ocelot_flower_replace(struct flow_cls_offload *f, struct ocelot_port_block *port_block) { struct ocelot_ace_rule *rule; @@ -212,7 +212,7 @@ static int ocelot_flower_replace(struct tc_cls_flower_offload *f, return 0; } -static int ocelot_flower_destroy(struct tc_cls_flower_offload *f, +static int ocelot_flower_destroy(struct flow_cls_offload *f, struct ocelot_port_block *port_block) { struct ocelot_ace_rule rule; @@ -230,7 +230,7 @@ static int ocelot_flower_destroy(struct tc_cls_flower_offload *f, return 0; } -static int ocelot_flower_stats_update(struct tc_cls_flower_offload *f, +static int ocelot_flower_stats_update(struct flow_cls_offload *f, struct ocelot_port_block *port_block) { struct ocelot_ace_rule rule; @@ -247,15 +247,15 @@ static int ocelot_flower_stats_update(struct tc_cls_flower_offload *f, return 0; } -static int ocelot_setup_tc_cls_flower(struct tc_cls_flower_offload *f, +static int ocelot_setup_tc_cls_flower(struct flow_cls_offload *f, struct ocelot_port_block *port_block) { switch (f->command) { - case TC_CLSFLOWER_REPLACE: + case FLOW_CLS_REPLACE: return ocelot_flower_replace(f, port_block); - case TC_CLSFLOWER_DESTROY: + case FLOW_CLS_DESTROY: return ocelot_flower_destroy(f, port_block); - case TC_CLSFLOWER_STATS: + case FLOW_CLS_STATS: return ocelot_flower_stats_update(f, port_block); default: return -EOPNOTSUPP; @@ -299,36 +299,45 @@ static void ocelot_port_block_destroy(struct ocelot_port_block *block) kfree(block); } +static void ocelot_tc_block_unbind(void *cb_priv) +{ + struct ocelot_port_block *port_block = cb_priv; + + ocelot_port_block_destroy(port_block); +} + int ocelot_setup_tc_block_flower_bind(struct ocelot_port *port, - struct tc_block_offload *f) + struct flow_block_offload *f) { struct ocelot_port_block *port_block; - struct tcf_block_cb *block_cb; + struct flow_block_cb *block_cb; int ret; - if (f->binder_type == TCF_BLOCK_BINDER_TYPE_CLSACT_EGRESS) + if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS) return -EOPNOTSUPP; - block_cb = tcf_block_cb_lookup(f->block, - ocelot_setup_tc_block_cb_flower, port); + block_cb = flow_block_cb_lookup(f, ocelot_setup_tc_block_cb_flower, + port); if (!block_cb) { port_block = ocelot_port_block_create(port); if (!port_block) return -ENOMEM; - block_cb = - __tcf_block_cb_register(f->block, - ocelot_setup_tc_block_cb_flower, - port, port_block, f->extack); + block_cb = flow_block_cb_alloc(f->net, + ocelot_setup_tc_block_cb_flower, + port, port_block, + ocelot_tc_block_unbind); if (IS_ERR(block_cb)) { ret = PTR_ERR(block_cb); goto err_cb_register; } + flow_block_cb_add(block_cb, f); + list_add_tail(&block_cb->driver_list, f->driver_block_list); } else { - port_block = tcf_block_cb_priv(block_cb); + port_block = flow_block_cb_priv(block_cb); } - tcf_block_cb_incref(block_cb); + flow_block_cb_incref(block_cb); return 0; err_cb_register: @@ -338,20 +347,17 @@ err_cb_register: } void ocelot_setup_tc_block_flower_unbind(struct ocelot_port *port, - struct tc_block_offload *f) + struct flow_block_offload *f) { - struct ocelot_port_block *port_block; - struct tcf_block_cb *block_cb; + struct flow_block_cb *block_cb; - block_cb = tcf_block_cb_lookup(f->block, - ocelot_setup_tc_block_cb_flower, port); + block_cb = flow_block_cb_lookup(f, ocelot_setup_tc_block_cb_flower, + port); if (!block_cb) return; - port_block = tcf_block_cb_priv(block_cb); - if (!tcf_block_cb_decref(block_cb)) { - tcf_block_cb_unregister(f->block, - ocelot_setup_tc_block_cb_flower, port); - ocelot_port_block_destroy(port_block); + if (!flow_block_cb_decref(block_cb)) { + flow_block_cb_remove(block_cb, f); + list_del(&block_cb->driver_list); } } diff --git a/drivers/net/ethernet/mscc/ocelot_tc.c b/drivers/net/ethernet/mscc/ocelot_tc.c index 72084306240d..9e6464ffae5d 100644 --- a/drivers/net/ethernet/mscc/ocelot_tc.c +++ b/drivers/net/ethernet/mscc/ocelot_tc.c @@ -128,35 +128,54 @@ static int ocelot_setup_tc_block_cb_eg(enum tc_setup_type type, cb_priv, false); } +static LIST_HEAD(ocelot_block_cb_list); + static int ocelot_setup_tc_block(struct ocelot_port *port, - struct tc_block_offload *f) + struct flow_block_offload *f) { + struct flow_block_cb *block_cb; tc_setup_cb_t *cb; - int ret; + int err; netdev_dbg(port->dev, "tc_block command %d, binder_type %d\n", f->command, f->binder_type); - if (f->binder_type == TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS) { + if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) { cb = ocelot_setup_tc_block_cb_ig; - port->tc.block_shared = tcf_block_shared(f->block); - } else if (f->binder_type == TCF_BLOCK_BINDER_TYPE_CLSACT_EGRESS) { + port->tc.block_shared = f->block_shared; + } else if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS) { cb = ocelot_setup_tc_block_cb_eg; } else { return -EOPNOTSUPP; } + f->driver_block_list = &ocelot_block_cb_list; + switch (f->command) { - case TC_BLOCK_BIND: - ret = tcf_block_cb_register(f->block, cb, port, - port, f->extack); - if (ret) - return ret; - - return ocelot_setup_tc_block_flower_bind(port, f); - case TC_BLOCK_UNBIND: + 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); + + err = ocelot_setup_tc_block_flower_bind(port, f); + if (err < 0) { + flow_block_cb_free(block_cb); + return err; + } + flow_block_cb_add(block_cb, f); + list_add_tail(&block_cb->driver_list, f->driver_block_list); + return 0; + case FLOW_BLOCK_UNBIND: + block_cb = flow_block_cb_lookup(f, cb, port); + if (!block_cb) + return -ENOENT; + ocelot_setup_tc_block_flower_unbind(port, f); - tcf_block_cb_unregister(f->block, cb, port); + flow_block_cb_remove(block_cb, f); + list_del(&block_cb->driver_list); return 0; default: return -EOPNOTSUPP; diff --git a/drivers/net/ethernet/netronome/nfp/abm/cls.c b/drivers/net/ethernet/netronome/nfp/abm/cls.c index ff3913085665..23ebddfb9532 100644 --- a/drivers/net/ethernet/netronome/nfp/abm/cls.c +++ b/drivers/net/ethernet/netronome/nfp/abm/cls.c @@ -262,22 +262,12 @@ static int nfp_abm_setup_tc_block_cb(enum tc_setup_type type, } } +static LIST_HEAD(nfp_abm_block_cb_list); + int nfp_abm_setup_cls_block(struct net_device *netdev, struct nfp_repr *repr, - struct tc_block_offload *f) + struct flow_block_offload *f) { - if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_EGRESS) - return -EOPNOTSUPP; - - switch (f->command) { - case TC_BLOCK_BIND: - return tcf_block_cb_register(f->block, - nfp_abm_setup_tc_block_cb, - repr, repr, f->extack); - case TC_BLOCK_UNBIND: - tcf_block_cb_unregister(f->block, nfp_abm_setup_tc_block_cb, - repr); - return 0; - default: - return -EOPNOTSUPP; - } + return flow_block_cb_setup_simple(f, &nfp_abm_block_cb_list, + nfp_abm_setup_tc_block_cb, + repr, repr, true); } diff --git a/drivers/net/ethernet/netronome/nfp/abm/main.h b/drivers/net/ethernet/netronome/nfp/abm/main.h index 49749c60885e..48746c9c6224 100644 --- a/drivers/net/ethernet/netronome/nfp/abm/main.h +++ b/drivers/net/ethernet/netronome/nfp/abm/main.h @@ -247,7 +247,7 @@ int nfp_abm_setup_tc_mq(struct net_device *netdev, struct nfp_abm_link *alink, int nfp_abm_setup_tc_gred(struct net_device *netdev, struct nfp_abm_link *alink, struct tc_gred_qopt_offload *opt); int nfp_abm_setup_cls_block(struct net_device *netdev, struct nfp_repr *repr, - struct tc_block_offload *opt); + struct flow_block_offload *opt); int nfp_abm_ctrl_read_params(struct nfp_abm_link *alink); int nfp_abm_ctrl_find_addrs(struct nfp_abm *abm); diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.c b/drivers/net/ethernet/netronome/nfp/bpf/main.c index 9c136da25221..1c9fb11470df 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/main.c +++ b/drivers/net/ethernet/netronome/nfp/bpf/main.c @@ -160,35 +160,19 @@ static int nfp_bpf_setup_tc_block_cb(enum tc_setup_type type, return 0; } -static int nfp_bpf_setup_tc_block(struct net_device *netdev, - struct tc_block_offload *f) -{ - struct nfp_net *nn = netdev_priv(netdev); - - if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS) - return -EOPNOTSUPP; - - switch (f->command) { - case TC_BLOCK_BIND: - return tcf_block_cb_register(f->block, - nfp_bpf_setup_tc_block_cb, - nn, nn, f->extack); - case TC_BLOCK_UNBIND: - tcf_block_cb_unregister(f->block, - nfp_bpf_setup_tc_block_cb, - nn); - return 0; - default: - return -EOPNOTSUPP; - } -} +static LIST_HEAD(nfp_bpf_block_cb_list); static int nfp_bpf_setup_tc(struct nfp_app *app, struct net_device *netdev, enum tc_setup_type type, void *type_data) { + struct nfp_net *nn = netdev_priv(netdev); + switch (type) { case TC_SETUP_BLOCK: - return nfp_bpf_setup_tc_block(netdev, type_data); + return flow_block_cb_setup_simple(type_data, + &nfp_bpf_block_cb_list, + nfp_bpf_setup_tc_block_cb, + nn, nn, true); default: return -EOPNOTSUPP; } diff --git a/drivers/net/ethernet/netronome/nfp/flower/action.c b/drivers/net/ethernet/netronome/nfp/flower/action.c index b6bd31fe44b2..5a54fe848de4 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/action.c +++ b/drivers/net/ethernet/netronome/nfp/flower/action.c @@ -171,7 +171,7 @@ nfp_fl_output(struct nfp_app *app, struct nfp_fl_output *output, } static bool -nfp_flower_tun_is_gre(struct tc_cls_flower_offload *flow, int start_idx) +nfp_flower_tun_is_gre(struct flow_cls_offload *flow, int start_idx) { struct flow_action_entry *act = flow->rule->action.entries; int num_act = flow->rule->action.num_entries; @@ -188,7 +188,7 @@ nfp_flower_tun_is_gre(struct tc_cls_flower_offload *flow, int start_idx) static enum nfp_flower_tun_type nfp_fl_get_tun_from_act(struct nfp_app *app, - struct tc_cls_flower_offload *flow, + struct flow_cls_offload *flow, const struct flow_action_entry *act, int act_idx) { const struct ip_tunnel_info *tun = act->tunnel; @@ -669,11 +669,11 @@ struct nfp_flower_pedit_acts { }; static int -nfp_fl_commit_mangle(struct tc_cls_flower_offload *flow, char *nfp_action, +nfp_fl_commit_mangle(struct flow_cls_offload *flow, char *nfp_action, int *a_len, struct nfp_flower_pedit_acts *set_act, u32 *csum_updated) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(flow); + struct flow_rule *rule = flow_cls_offload_flow_rule(flow); size_t act_size = 0; u8 ip_proto = 0; @@ -771,7 +771,7 @@ nfp_fl_commit_mangle(struct tc_cls_flower_offload *flow, char *nfp_action, static int nfp_fl_pedit(const struct flow_action_entry *act, - struct tc_cls_flower_offload *flow, char *nfp_action, int *a_len, + struct flow_cls_offload *flow, char *nfp_action, int *a_len, u32 *csum_updated, struct nfp_flower_pedit_acts *set_act, struct netlink_ext_ack *extack) { @@ -858,7 +858,7 @@ nfp_flower_output_action(struct nfp_app *app, static int nfp_flower_loop_action(struct nfp_app *app, const struct flow_action_entry *act, - struct tc_cls_flower_offload *flow, + struct flow_cls_offload *flow, struct nfp_fl_payload *nfp_fl, int *a_len, struct net_device *netdev, enum nfp_flower_tun_type *tun_type, int *tun_out_cnt, @@ -1021,7 +1021,7 @@ static bool nfp_fl_check_mangle_end(struct flow_action *flow_act, } int nfp_flower_compile_action(struct nfp_app *app, - struct tc_cls_flower_offload *flow, + struct flow_cls_offload *flow, struct net_device *netdev, struct nfp_fl_payload *nfp_flow, struct netlink_ext_ack *extack) diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h b/drivers/net/ethernet/netronome/nfp/flower/main.h index 1f165d89582d..af9441d5787f 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/main.h +++ b/drivers/net/ethernet/netronome/nfp/flower/main.h @@ -343,19 +343,19 @@ int nfp_flower_merge_offloaded_flows(struct nfp_app *app, struct nfp_fl_payload *sub_flow1, struct nfp_fl_payload *sub_flow2); int nfp_flower_compile_flow_match(struct nfp_app *app, - struct tc_cls_flower_offload *flow, + struct flow_cls_offload *flow, struct nfp_fl_key_ls *key_ls, struct net_device *netdev, struct nfp_fl_payload *nfp_flow, enum nfp_flower_tun_type tun_type, struct netlink_ext_ack *extack); int nfp_flower_compile_action(struct nfp_app *app, - struct tc_cls_flower_offload *flow, + struct flow_cls_offload *flow, struct net_device *netdev, struct nfp_fl_payload *nfp_flow, struct netlink_ext_ack *extack); int nfp_compile_flow_metadata(struct nfp_app *app, - struct tc_cls_flower_offload *flow, + struct flow_cls_offload *flow, struct nfp_fl_payload *nfp_flow, struct net_device *netdev, struct netlink_ext_ack *extack); diff --git a/drivers/net/ethernet/netronome/nfp/flower/match.c b/drivers/net/ethernet/netronome/nfp/flower/match.c index c1690de19172..9cc3ba17ff69 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/match.c +++ b/drivers/net/ethernet/netronome/nfp/flower/match.c @@ -10,9 +10,9 @@ static void nfp_flower_compile_meta_tci(struct nfp_flower_meta_tci *ext, struct nfp_flower_meta_tci *msk, - struct tc_cls_flower_offload *flow, u8 key_type) + struct flow_cls_offload *flow, u8 key_type) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(flow); + struct flow_rule *rule = flow_cls_offload_flow_rule(flow); u16 tmp_tci; memset(ext, 0, sizeof(struct nfp_flower_meta_tci)); @@ -78,9 +78,9 @@ nfp_flower_compile_port(struct nfp_flower_in_port *frame, u32 cmsg_port, static void nfp_flower_compile_mac(struct nfp_flower_mac_mpls *ext, struct nfp_flower_mac_mpls *msk, - struct tc_cls_flower_offload *flow) + struct flow_cls_offload *flow) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(flow); + struct flow_rule *rule = flow_cls_offload_flow_rule(flow); memset(ext, 0, sizeof(struct nfp_flower_mac_mpls)); memset(msk, 0, sizeof(struct nfp_flower_mac_mpls)); @@ -130,9 +130,9 @@ nfp_flower_compile_mac(struct nfp_flower_mac_mpls *ext, static void nfp_flower_compile_tport(struct nfp_flower_tp_ports *ext, struct nfp_flower_tp_ports *msk, - struct tc_cls_flower_offload *flow) + struct flow_cls_offload *flow) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(flow); + struct flow_rule *rule = flow_cls_offload_flow_rule(flow); memset(ext, 0, sizeof(struct nfp_flower_tp_ports)); memset(msk, 0, sizeof(struct nfp_flower_tp_ports)); @@ -151,9 +151,9 @@ nfp_flower_compile_tport(struct nfp_flower_tp_ports *ext, static void nfp_flower_compile_ip_ext(struct nfp_flower_ip_ext *ext, struct nfp_flower_ip_ext *msk, - struct tc_cls_flower_offload *flow) + struct flow_cls_offload *flow) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(flow); + struct flow_rule *rule = flow_cls_offload_flow_rule(flow); if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) { struct flow_match_basic match; @@ -225,9 +225,9 @@ nfp_flower_compile_ip_ext(struct nfp_flower_ip_ext *ext, static void nfp_flower_compile_ipv4(struct nfp_flower_ipv4 *ext, struct nfp_flower_ipv4 *msk, - struct tc_cls_flower_offload *flow) + struct flow_cls_offload *flow) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(flow); + struct flow_rule *rule = flow_cls_offload_flow_rule(flow); struct flow_match_ipv4_addrs match; memset(ext, 0, sizeof(struct nfp_flower_ipv4)); @@ -247,9 +247,9 @@ nfp_flower_compile_ipv4(struct nfp_flower_ipv4 *ext, static void nfp_flower_compile_ipv6(struct nfp_flower_ipv6 *ext, struct nfp_flower_ipv6 *msk, - struct tc_cls_flower_offload *flow) + struct flow_cls_offload *flow) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(flow); + struct flow_rule *rule = flow_cls_offload_flow_rule(flow); memset(ext, 0, sizeof(struct nfp_flower_ipv6)); memset(msk, 0, sizeof(struct nfp_flower_ipv6)); @@ -269,7 +269,7 @@ nfp_flower_compile_ipv6(struct nfp_flower_ipv6 *ext, static int nfp_flower_compile_geneve_opt(void *ext, void *msk, - struct tc_cls_flower_offload *flow) + struct flow_cls_offload *flow) { struct flow_match_enc_opts match; @@ -283,9 +283,9 @@ nfp_flower_compile_geneve_opt(void *ext, void *msk, static void nfp_flower_compile_tun_ipv4_addrs(struct nfp_flower_tun_ipv4 *ext, struct nfp_flower_tun_ipv4 *msk, - struct tc_cls_flower_offload *flow) + struct flow_cls_offload *flow) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(flow); + struct flow_rule *rule = flow_cls_offload_flow_rule(flow); if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS)) { struct flow_match_ipv4_addrs match; @@ -301,9 +301,9 @@ nfp_flower_compile_tun_ipv4_addrs(struct nfp_flower_tun_ipv4 *ext, static void nfp_flower_compile_tun_ip_ext(struct nfp_flower_tun_ip_ext *ext, struct nfp_flower_tun_ip_ext *msk, - struct tc_cls_flower_offload *flow) + struct flow_cls_offload *flow) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(flow); + struct flow_rule *rule = flow_cls_offload_flow_rule(flow); if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_IP)) { struct flow_match_ip match; @@ -319,9 +319,9 @@ nfp_flower_compile_tun_ip_ext(struct nfp_flower_tun_ip_ext *ext, static void nfp_flower_compile_ipv4_gre_tun(struct nfp_flower_ipv4_gre_tun *ext, struct nfp_flower_ipv4_gre_tun *msk, - struct tc_cls_flower_offload *flow) + struct flow_cls_offload *flow) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(flow); + struct flow_rule *rule = flow_cls_offload_flow_rule(flow); memset(ext, 0, sizeof(struct nfp_flower_ipv4_gre_tun)); memset(msk, 0, sizeof(struct nfp_flower_ipv4_gre_tun)); @@ -348,9 +348,9 @@ nfp_flower_compile_ipv4_gre_tun(struct nfp_flower_ipv4_gre_tun *ext, static void nfp_flower_compile_ipv4_udp_tun(struct nfp_flower_ipv4_udp_tun *ext, struct nfp_flower_ipv4_udp_tun *msk, - struct tc_cls_flower_offload *flow) + struct flow_cls_offload *flow) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(flow); + struct flow_rule *rule = flow_cls_offload_flow_rule(flow); memset(ext, 0, sizeof(struct nfp_flower_ipv4_udp_tun)); memset(msk, 0, sizeof(struct nfp_flower_ipv4_udp_tun)); @@ -371,7 +371,7 @@ nfp_flower_compile_ipv4_udp_tun(struct nfp_flower_ipv4_udp_tun *ext, } int nfp_flower_compile_flow_match(struct nfp_app *app, - struct tc_cls_flower_offload *flow, + struct flow_cls_offload *flow, struct nfp_fl_key_ls *key_ls, struct net_device *netdev, struct nfp_fl_payload *nfp_flow, diff --git a/drivers/net/ethernet/netronome/nfp/flower/metadata.c b/drivers/net/ethernet/netronome/nfp/flower/metadata.c index dae60961c1eb..7c4a15e967df 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/metadata.c +++ b/drivers/net/ethernet/netronome/nfp/flower/metadata.c @@ -290,7 +290,7 @@ nfp_check_mask_remove(struct nfp_app *app, char *mask_data, u32 mask_len, } int nfp_compile_flow_metadata(struct nfp_app *app, - struct tc_cls_flower_offload *flow, + struct flow_cls_offload *flow, struct nfp_fl_payload *nfp_flow, struct net_device *netdev, struct netlink_ext_ack *extack) diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c index 6dbe947269c3..7e725fa60347 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/offload.c +++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c @@ -121,9 +121,9 @@ nfp_flower_xmit_flow(struct nfp_app *app, struct nfp_fl_payload *nfp_flow, return 0; } -static bool nfp_flower_check_higher_than_mac(struct tc_cls_flower_offload *f) +static bool nfp_flower_check_higher_than_mac(struct flow_cls_offload *f) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(f); + struct flow_rule *rule = flow_cls_offload_flow_rule(f); return flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV4_ADDRS) || flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV6_ADDRS) || @@ -131,9 +131,9 @@ static bool nfp_flower_check_higher_than_mac(struct tc_cls_flower_offload *f) flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ICMP); } -static bool nfp_flower_check_higher_than_l3(struct tc_cls_flower_offload *f) +static bool nfp_flower_check_higher_than_l3(struct flow_cls_offload *f) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(f); + struct flow_rule *rule = flow_cls_offload_flow_rule(f); return flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PORTS) || flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ICMP); @@ -212,11 +212,11 @@ static int nfp_flower_calculate_key_layers(struct nfp_app *app, struct net_device *netdev, struct nfp_fl_key_ls *ret_key_ls, - struct tc_cls_flower_offload *flow, + struct flow_cls_offload *flow, enum nfp_flower_tun_type *tun_type, struct netlink_ext_ack *extack) { - struct flow_rule *rule = tc_cls_flower_offload_flow_rule(flow); + struct flow_rule *rule = flow_cls_offload_flow_rule(flow); struct flow_dissector *dissector = rule->match.dissector; struct flow_match_basic basic = { NULL, NULL}; struct nfp_flower_priv *priv = app->priv; @@ -866,7 +866,7 @@ int nfp_flower_merge_offloaded_flows(struct nfp_app *app, struct nfp_fl_payload *sub_flow1, struct nfp_fl_payload *sub_flow2) { - struct tc_cls_flower_offload merge_tc_off; + struct flow_cls_offload merge_tc_off; struct nfp_flower_priv *priv = app->priv; struct netlink_ext_ack *extack = NULL; struct nfp_fl_payload *merge_flow; @@ -962,7 +962,7 @@ err_destroy_merge_flow: */ static int nfp_flower_add_offload(struct nfp_app *app, struct net_device *netdev, - struct tc_cls_flower_offload *flow) + struct flow_cls_offload *flow) { enum nfp_flower_tun_type tun_type = NFP_FL_TUNNEL_NONE; struct nfp_flower_priv *priv = app->priv; @@ -1125,7 +1125,7 @@ nfp_flower_del_linked_merge_flows(struct nfp_app *app, */ static int nfp_flower_del_offload(struct nfp_app *app, struct net_device *netdev, - struct tc_cls_flower_offload *flow) + struct flow_cls_offload *flow) { struct nfp_flower_priv *priv = app->priv; struct netlink_ext_ack *extack = NULL; @@ -1232,7 +1232,7 @@ nfp_flower_update_merge_stats(struct nfp_app *app, */ static int nfp_flower_get_stats(struct nfp_app *app, struct net_device *netdev, - struct tc_cls_flower_offload *flow) + struct flow_cls_offload *flow) { struct nfp_flower_priv *priv = app->priv; struct netlink_ext_ack *extack = NULL; @@ -1265,17 +1265,17 @@ nfp_flower_get_stats(struct nfp_app *app, struct net_device *netdev, static int nfp_flower_repr_offload(struct nfp_app *app, struct net_device *netdev, - struct tc_cls_flower_offload *flower) + struct flow_cls_offload *flower) { if (!eth_proto_is_802_3(flower->common.protocol)) return -EOPNOTSUPP; switch (flower->command) { - case TC_CLSFLOWER_REPLACE: + case FLOW_CLS_REPLACE: return nfp_flower_add_offload(app, netdev, flower); - case TC_CLSFLOWER_DESTROY: + case FLOW_CLS_DESTROY: return nfp_flower_del_offload(app, netdev, flower); - case TC_CLSFLOWER_STATS: + case FLOW_CLS_STATS: return nfp_flower_get_stats(app, netdev, flower); default: return -EOPNOTSUPP; @@ -1302,27 +1302,45 @@ static int nfp_flower_setup_tc_block_cb(enum tc_setup_type type, } } +static LIST_HEAD(nfp_block_cb_list); + static int nfp_flower_setup_tc_block(struct net_device *netdev, - struct tc_block_offload *f) + struct flow_block_offload *f) { struct nfp_repr *repr = netdev_priv(netdev); struct nfp_flower_repr_priv *repr_priv; + struct flow_block_cb *block_cb; - if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS) + if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) return -EOPNOTSUPP; repr_priv = repr->app_priv; - repr_priv->block_shared = tcf_block_shared(f->block); + repr_priv->block_shared = f->block_shared; + f->driver_block_list = &nfp_block_cb_list; switch (f->command) { - case TC_BLOCK_BIND: - return tcf_block_cb_register(f->block, - nfp_flower_setup_tc_block_cb, - repr, repr, f->extack); - case TC_BLOCK_UNBIND: - tcf_block_cb_unregister(f->block, - nfp_flower_setup_tc_block_cb, - repr); + 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); + if (IS_ERR(block_cb)) + return PTR_ERR(block_cb); + + flow_block_cb_add(block_cb, f); + list_add_tail(&block_cb->driver_list, &nfp_block_cb_list); + return 0; + case FLOW_BLOCK_UNBIND: + block_cb = flow_block_cb_lookup(f, nfp_flower_setup_tc_block_cb, + repr); + if (!block_cb) + return -ENOENT; + + flow_block_cb_remove(block_cb, f); + list_del(&block_cb->driver_list); return 0; default: return -EOPNOTSUPP; @@ -1367,7 +1385,7 @@ static int nfp_flower_setup_indr_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv) { struct nfp_flower_indr_block_cb_priv *priv = cb_priv; - struct tc_cls_flower_offload *flower = type_data; + struct flow_cls_offload *flower = type_data; if (flower->common.chain_index) return -EOPNOTSUPP; @@ -1381,21 +1399,29 @@ static int nfp_flower_setup_indr_block_cb(enum tc_setup_type type, } } +static void nfp_flower_setup_indr_tc_release(void *cb_priv) +{ + struct nfp_flower_indr_block_cb_priv *priv = cb_priv; + + list_del(&priv->list); + kfree(priv); +} + static int nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct nfp_app *app, - struct tc_block_offload *f) + struct flow_block_offload *f) { struct nfp_flower_indr_block_cb_priv *cb_priv; struct nfp_flower_priv *priv = app->priv; - int err; + struct flow_block_cb *block_cb; - if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS && - !(f->binder_type == TCF_BLOCK_BINDER_TYPE_CLSACT_EGRESS && + if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS && + !(f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS && nfp_flower_internal_port_can_offload(app, netdev))) return -EOPNOTSUPP; switch (f->command) { - case TC_BLOCK_BIND: + case FLOW_BLOCK_BIND: cb_priv = kmalloc(sizeof(*cb_priv), GFP_KERNEL); if (!cb_priv) return -ENOMEM; @@ -1404,26 +1430,32 @@ nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct nfp_app *app, cb_priv->app = app; list_add(&cb_priv->list, &priv->indr_block_cb_priv); - err = tcf_block_cb_register(f->block, - nfp_flower_setup_indr_block_cb, - cb_priv, cb_priv, f->extack); - if (err) { + block_cb = flow_block_cb_alloc(f->net, + nfp_flower_setup_indr_block_cb, + cb_priv, cb_priv, + nfp_flower_setup_indr_tc_release); + if (IS_ERR(block_cb)) { list_del(&cb_priv->list); kfree(cb_priv); + return PTR_ERR(block_cb); } - return err; - case TC_BLOCK_UNBIND: + flow_block_cb_add(block_cb, f); + list_add_tail(&block_cb->driver_list, &nfp_block_cb_list); + return 0; + case FLOW_BLOCK_UNBIND: cb_priv = nfp_flower_indr_block_cb_priv_lookup(app, netdev); if (!cb_priv) return -ENOENT; - tcf_block_cb_unregister(f->block, - nfp_flower_setup_indr_block_cb, - cb_priv); - list_del(&cb_priv->list); - kfree(cb_priv); + block_cb = flow_block_cb_lookup(f, + nfp_flower_setup_indr_block_cb, + cb_priv); + if (!block_cb) + return -ENOENT; + flow_block_cb_remove(block_cb, f); + list_del(&block_cb->driver_list); return 0; default: return -EOPNOTSUPP; diff --git a/drivers/net/ethernet/qlogic/qede/qede.h b/drivers/net/ethernet/qlogic/qede/qede.h index b972ab07c18b..0e931c04fecf 100644 --- a/drivers/net/ethernet/qlogic/qede/qede.h +++ b/drivers/net/ethernet/qlogic/qede/qede.h @@ -551,7 +551,7 @@ int qede_txq_has_work(struct qede_tx_queue *txq); void qede_recycle_rx_bd_ring(struct qede_rx_queue *rxq, u8 count); void qede_update_rx_prod(struct qede_dev *edev, struct qede_rx_queue *rxq); int qede_add_tc_flower_fltr(struct qede_dev *edev, __be16 proto, - struct tc_cls_flower_offload *f); + struct flow_cls_offload *f); #define RX_RING_SIZE_POW 13 #define RX_RING_SIZE ((u16)BIT(RX_RING_SIZE_POW)) diff --git a/drivers/net/ethernet/qlogic/qede/qede_filter.c b/drivers/net/ethernet/qlogic/qede/qede_filter.c index add922b93d2c..9a6a9a008714 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_filter.c +++ b/drivers/net/ethernet/qlogic/qede/qede_filter.c @@ -1943,7 +1943,7 @@ qede_parse_flow_attr(struct qede_dev *edev, __be16 proto, } int qede_add_tc_flower_fltr(struct qede_dev *edev, __be16 proto, - struct tc_cls_flower_offload *f) + struct flow_cls_offload *f) { struct qede_arfs_fltr_node *n; int min_hlen, rc = -EINVAL; diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c index d4a29660751d..8d1c208f778f 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_main.c +++ b/drivers/net/ethernet/qlogic/qede/qede_main.c @@ -548,13 +548,13 @@ static int qede_setup_tc(struct net_device *ndev, u8 num_tc) } static int -qede_set_flower(struct qede_dev *edev, struct tc_cls_flower_offload *f, +qede_set_flower(struct qede_dev *edev, struct flow_cls_offload *f, __be16 proto) { switch (f->command) { - case TC_CLSFLOWER_REPLACE: + case FLOW_CLS_REPLACE: return qede_add_tc_flower_fltr(edev, proto, f); - case TC_CLSFLOWER_DESTROY: + case FLOW_CLS_DESTROY: return qede_delete_flow_filter(edev, f->cookie); default: return -EOPNOTSUPP; @@ -564,7 +564,7 @@ qede_set_flower(struct qede_dev *edev, struct tc_cls_flower_offload *f, static int qede_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv) { - struct tc_cls_flower_offload *f; + struct flow_cls_offload *f; struct qede_dev *edev = cb_priv; if (!tc_cls_can_offload_and_chain0(edev->ndev, type_data)) @@ -579,24 +579,7 @@ static int qede_setup_tc_block_cb(enum tc_setup_type type, void *type_data, } } -static int qede_setup_tc_block(struct qede_dev *edev, - struct tc_block_offload *f) -{ - if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS) - return -EOPNOTSUPP; - - switch (f->command) { - case TC_BLOCK_BIND: - return tcf_block_cb_register(f->block, - qede_setup_tc_block_cb, - edev, edev, f->extack); - case TC_BLOCK_UNBIND: - tcf_block_cb_unregister(f->block, qede_setup_tc_block_cb, edev); - return 0; - default: - return -EOPNOTSUPP; - } -} +static LIST_HEAD(qede_block_cb_list); static int qede_setup_tc_offload(struct net_device *dev, enum tc_setup_type type, @@ -607,7 +590,10 @@ qede_setup_tc_offload(struct net_device *dev, enum tc_setup_type type, switch (type) { case TC_SETUP_BLOCK: - return qede_setup_tc_block(edev, type_data); + return flow_block_cb_setup_simple(type_data, + &qede_block_cb_list, + qede_setup_tc_block_cb, + edev, edev, true); case TC_SETUP_QDISC_MQPRIO: mqprio = type_data; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index e4b06dc484b7..c7c9e5f162e6 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -3769,23 +3769,7 @@ static int stmmac_setup_tc_block_cb(enum tc_setup_type type, void *type_data, return ret; } -static int stmmac_setup_tc_block(struct stmmac_priv *priv, - struct tc_block_offload *f) -{ - if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS) - return -EOPNOTSUPP; - - switch (f->command) { - case TC_BLOCK_BIND: - return tcf_block_cb_register(f->block, stmmac_setup_tc_block_cb, - priv, priv, f->extack); - case TC_BLOCK_UNBIND: - tcf_block_cb_unregister(f->block, stmmac_setup_tc_block_cb, priv); - return 0; - default: - return -EOPNOTSUPP; - } -} +static LIST_HEAD(stmmac_block_cb_list); static int stmmac_setup_tc(struct net_device *ndev, enum tc_setup_type type, void *type_data) @@ -3794,7 +3778,10 @@ static int stmmac_setup_tc(struct net_device *ndev, enum tc_setup_type type, switch (type) { case TC_SETUP_BLOCK: - return stmmac_setup_tc_block(priv, type_data); + return flow_block_cb_setup_simple(type_data, + &stmmac_block_cb_list, + stmmac_setup_tc_block_cb, + priv, priv, true); case TC_SETUP_QDISC_CBS: return stmmac_tc_setup_cbs(priv, priv, type_data); default: diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c index e5c8aa08e1cd..0740940f41b1 100644 --- a/drivers/net/netdevsim/netdev.c +++ b/drivers/net/netdevsim/netdev.c @@ -78,26 +78,6 @@ nsim_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv) return nsim_bpf_setup_tc_block_cb(type, type_data, cb_priv); } -static int -nsim_setup_tc_block(struct net_device *dev, struct tc_block_offload *f) -{ - struct netdevsim *ns = netdev_priv(dev); - - if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS) - return -EOPNOTSUPP; - - switch (f->command) { - case TC_BLOCK_BIND: - return tcf_block_cb_register(f->block, nsim_setup_tc_block_cb, - ns, ns, f->extack); - case TC_BLOCK_UNBIND: - tcf_block_cb_unregister(f->block, nsim_setup_tc_block_cb, ns); - return 0; - default: - return -EOPNOTSUPP; - } -} - static int nsim_set_vf_mac(struct net_device *dev, int vf, u8 *mac) { struct netdevsim *ns = netdev_priv(dev); @@ -223,12 +203,19 @@ static int nsim_set_vf_link_state(struct net_device *dev, int vf, int state) return 0; } +static LIST_HEAD(nsim_block_cb_list); + static int nsim_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data) { + struct netdevsim *ns = netdev_priv(dev); + switch (type) { case TC_SETUP_BLOCK: - return nsim_setup_tc_block(dev, type_data); + return flow_block_cb_setup_simple(type_data, + &nsim_block_cb_list, + nsim_setup_tc_block_cb, + ns, ns, true); default: return -EOPNOTSUPP; } |