summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2019-07-09 16:55:39 -0400
committerDavid S. Miller <davem@davemloft.net>2019-07-09 17:38:50 -0400
commit4e95bc268b915c3a19ec8b9110f61e4ea41a1ed0 (patch)
tree98ae57b058ea60b87e43192551dc3868d866877f
parent2bb295f3a5e612b36ccf5986b529a8d4b426cf4f (diff)
net: flow_offload: add flow_block_cb_setup_simple()
Most drivers do the same thing to set up the flow block callbacks, this patch adds a helper function to do this. This preparation patch reduces the number of changes to adapt the existing drivers to use the flow block callback API. This new helper function takes a flow block list per-driver, which is set to NULL until this driver list is used. This patch also introduces the flow_block_command and flow_block_binder_type enumerations, which are renamed to use FLOW_BLOCK_* in follow up patches. There are three definitions (aliases) in order to reduce the number of updates in this patch, which go away once drivers are fully adapted to use this flow block API. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt.c26
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c28
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c26
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_main.c26
-rw-r--r--drivers/net/ethernet/intel/iavf/iavf_main.c35
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c24
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c27
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_main.c27
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_rep.c26
-rw-r--r--drivers/net/ethernet/netronome/nfp/abm/cls.c17
-rw-r--r--drivers/net/ethernet/netronome/nfp/bpf/main.c29
-rw-r--r--drivers/net/ethernet/qlogic/qede/qede_main.c23
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c22
-rw-r--r--drivers/net/netdevsim/netdev.c26
-rw-r--r--include/net/flow_offload.h27
-rw-r--r--include/net/pkt_cls.h20
-rw-r--r--net/core/flow_offload.c25
17 files changed, 117 insertions, 317 deletions
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 2b5b0ab8961a..06819590f6d0 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -9907,32 +9907,16 @@ static int bnxt_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
9907 } 9907 }
9908} 9908}
9909 9909
9910static int bnxt_setup_tc_block(struct net_device *dev,
9911 struct tc_block_offload *f)
9912{
9913 struct bnxt *bp = netdev_priv(dev);
9914
9915 if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
9916 return -EOPNOTSUPP;
9917
9918 switch (f->command) {
9919 case TC_BLOCK_BIND:
9920 return tcf_block_cb_register(f->block, bnxt_setup_tc_block_cb,
9921 bp, bp, f->extack);
9922 case TC_BLOCK_UNBIND:
9923 tcf_block_cb_unregister(f->block, bnxt_setup_tc_block_cb, bp);
9924 return 0;
9925 default:
9926 return -EOPNOTSUPP;
9927 }
9928}
9929
9930static int bnxt_setup_tc(struct net_device *dev, enum tc_setup_type type, 9910static int bnxt_setup_tc(struct net_device *dev, enum tc_setup_type type,
9931 void *type_data) 9911 void *type_data)
9932{ 9912{
9913 struct bnxt *bp = netdev_priv(dev);
9914
9933 switch (type) { 9915 switch (type) {
9934 case TC_SETUP_BLOCK: 9916 case TC_SETUP_BLOCK:
9935 return bnxt_setup_tc_block(dev, type_data); 9917 return flow_block_cb_setup_simple(type_data, NULL,
9918 bnxt_setup_tc_block_cb,
9919 bp, bp, true);
9936 case TC_SETUP_QDISC_MQPRIO: { 9920 case TC_SETUP_QDISC_MQPRIO: {
9937 struct tc_mqprio_qopt *mqprio = type_data; 9921 struct tc_mqprio_qopt *mqprio = type_data;
9938 9922
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c
index f760921389a3..89398ff011d4 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c
@@ -161,34 +161,16 @@ static int bnxt_vf_rep_setup_tc_block_cb(enum tc_setup_type type,
161 } 161 }
162} 162}
163 163
164static int bnxt_vf_rep_setup_tc_block(struct net_device *dev,
165 struct tc_block_offload *f)
166{
167 struct bnxt_vf_rep *vf_rep = netdev_priv(dev);
168
169 if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
170 return -EOPNOTSUPP;
171
172 switch (f->command) {
173 case TC_BLOCK_BIND:
174 return tcf_block_cb_register(f->block,
175 bnxt_vf_rep_setup_tc_block_cb,
176 vf_rep, vf_rep, f->extack);
177 case TC_BLOCK_UNBIND:
178 tcf_block_cb_unregister(f->block,
179 bnxt_vf_rep_setup_tc_block_cb, vf_rep);
180 return 0;
181 default:
182 return -EOPNOTSUPP;
183 }
184}
185
186static int bnxt_vf_rep_setup_tc(struct net_device *dev, enum tc_setup_type type, 164static int bnxt_vf_rep_setup_tc(struct net_device *dev, enum tc_setup_type type,
187 void *type_data) 165 void *type_data)
188{ 166{
167 struct bnxt_vf_rep *vf_rep = netdev_priv(dev);
168
189 switch (type) { 169 switch (type) {
190 case TC_SETUP_BLOCK: 170 case TC_SETUP_BLOCK:
191 return bnxt_vf_rep_setup_tc_block(dev, type_data); 171 return flow_block_cb_setup_simple(type_data, NULL,
172 bnxt_vf_rep_setup_tc_block_cb,
173 vf_rep, vf_rep, true);
192 default: 174 default:
193 return -EOPNOTSUPP; 175 return -EOPNOTSUPP;
194 } 176 }
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index b08efc48d42f..9a486282a32e 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -3190,32 +3190,16 @@ static int cxgb_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
3190 } 3190 }
3191} 3191}
3192 3192
3193static int cxgb_setup_tc_block(struct net_device *dev,
3194 struct tc_block_offload *f)
3195{
3196 struct port_info *pi = netdev2pinfo(dev);
3197
3198 if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
3199 return -EOPNOTSUPP;
3200
3201 switch (f->command) {
3202 case TC_BLOCK_BIND:
3203 return tcf_block_cb_register(f->block, cxgb_setup_tc_block_cb,
3204 pi, dev, f->extack);
3205 case TC_BLOCK_UNBIND:
3206 tcf_block_cb_unregister(f->block, cxgb_setup_tc_block_cb, pi);
3207 return 0;
3208 default:
3209 return -EOPNOTSUPP;
3210 }
3211}
3212
3213static int cxgb_setup_tc(struct net_device *dev, enum tc_setup_type type, 3193static int cxgb_setup_tc(struct net_device *dev, enum tc_setup_type type,
3214 void *type_data) 3194 void *type_data)
3215{ 3195{
3196 struct port_info *pi = netdev2pinfo(dev);
3197
3216 switch (type) { 3198 switch (type) {
3217 case TC_SETUP_BLOCK: 3199 case TC_SETUP_BLOCK:
3218 return cxgb_setup_tc_block(dev, type_data); 3200 return flow_block_cb_setup_simple(type_data, NULL,
3201 cxgb_setup_tc_block_cb,
3202 pi, dev, true);
3219 default: 3203 default:
3220 return -EOPNOTSUPP; 3204 return -EOPNOTSUPP;
3221 } 3205 }
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 5361c08328f7..52f0f14d4207 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -8177,34 +8177,18 @@ static int i40e_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
8177 } 8177 }
8178} 8178}
8179 8179
8180static int i40e_setup_tc_block(struct net_device *dev,
8181 struct tc_block_offload *f)
8182{
8183 struct i40e_netdev_priv *np = netdev_priv(dev);
8184
8185 if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
8186 return -EOPNOTSUPP;
8187
8188 switch (f->command) {
8189 case TC_BLOCK_BIND:
8190 return tcf_block_cb_register(f->block, i40e_setup_tc_block_cb,
8191 np, np, f->extack);
8192 case TC_BLOCK_UNBIND:
8193 tcf_block_cb_unregister(f->block, i40e_setup_tc_block_cb, np);
8194 return 0;
8195 default:
8196 return -EOPNOTSUPP;
8197 }
8198}
8199
8200static int __i40e_setup_tc(struct net_device *netdev, enum tc_setup_type type, 8180static int __i40e_setup_tc(struct net_device *netdev, enum tc_setup_type type,
8201 void *type_data) 8181 void *type_data)
8202{ 8182{
8183 struct i40e_netdev_priv *np = netdev_priv(netdev);
8184
8203 switch (type) { 8185 switch (type) {
8204 case TC_SETUP_QDISC_MQPRIO: 8186 case TC_SETUP_QDISC_MQPRIO:
8205 return i40e_setup_tc(netdev, type_data); 8187 return i40e_setup_tc(netdev, type_data);
8206 case TC_SETUP_BLOCK: 8188 case TC_SETUP_BLOCK:
8207 return i40e_setup_tc_block(netdev, type_data); 8189 return flow_block_cb_setup_simple(type_data, NULL,
8190 i40e_setup_tc_block_cb,
8191 np, np, true);
8208 default: 8192 default:
8209 return -EOPNOTSUPP; 8193 return -EOPNOTSUPP;
8210 } 8194 }
diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
index 881561b36083..fd0e2bcc75e5 100644
--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
+++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
@@ -3114,35 +3114,6 @@ static int iavf_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
3114} 3114}
3115 3115
3116/** 3116/**
3117 * iavf_setup_tc_block - register callbacks for tc
3118 * @netdev: network interface device structure
3119 * @f: tc offload data
3120 *
3121 * This function registers block callbacks for tc
3122 * offloads
3123 **/
3124static int iavf_setup_tc_block(struct net_device *dev,
3125 struct tc_block_offload *f)
3126{
3127 struct iavf_adapter *adapter = netdev_priv(dev);
3128
3129 if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
3130 return -EOPNOTSUPP;
3131
3132 switch (f->command) {
3133 case TC_BLOCK_BIND:
3134 return tcf_block_cb_register(f->block, iavf_setup_tc_block_cb,
3135 adapter, adapter, f->extack);
3136 case TC_BLOCK_UNBIND:
3137 tcf_block_cb_unregister(f->block, iavf_setup_tc_block_cb,
3138 adapter);
3139 return 0;
3140 default:
3141 return -EOPNOTSUPP;
3142 }
3143}
3144
3145/**
3146 * iavf_setup_tc - configure multiple traffic classes 3117 * iavf_setup_tc - configure multiple traffic classes
3147 * @netdev: network interface device structure 3118 * @netdev: network interface device structure
3148 * @type: type of offload 3119 * @type: type of offload
@@ -3156,11 +3127,15 @@ static int iavf_setup_tc_block(struct net_device *dev,
3156static int iavf_setup_tc(struct net_device *netdev, enum tc_setup_type type, 3127static int iavf_setup_tc(struct net_device *netdev, enum tc_setup_type type,
3157 void *type_data) 3128 void *type_data)
3158{ 3129{
3130 struct iavf_adapter *adapter = netdev_priv(netdev);
3131
3159 switch (type) { 3132 switch (type) {
3160 case TC_SETUP_QDISC_MQPRIO: 3133 case TC_SETUP_QDISC_MQPRIO:
3161 return __iavf_setup_tc(netdev, type_data); 3134 return __iavf_setup_tc(netdev, type_data);
3162 case TC_SETUP_BLOCK: 3135 case TC_SETUP_BLOCK:
3163 return iavf_setup_tc_block(netdev, type_data); 3136 return flow_block_cb_setup_simple(type_data, NULL,
3137 iavf_setup_tc_block_cb,
3138 adapter, adapter, true);
3164 default: 3139 default:
3165 return -EOPNOTSUPP; 3140 return -EOPNOTSUPP;
3166 } 3141 }
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index f66dae72fe37..836f9e1a136c 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -2783,25 +2783,6 @@ static int igb_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
2783 } 2783 }
2784} 2784}
2785 2785
2786static int igb_setup_tc_block(struct igb_adapter *adapter,
2787 struct tc_block_offload *f)
2788{
2789 if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
2790 return -EOPNOTSUPP;
2791
2792 switch (f->command) {
2793 case TC_BLOCK_BIND:
2794 return tcf_block_cb_register(f->block, igb_setup_tc_block_cb,
2795 adapter, adapter, f->extack);
2796 case TC_BLOCK_UNBIND:
2797 tcf_block_cb_unregister(f->block, igb_setup_tc_block_cb,
2798 adapter);
2799 return 0;
2800 default:
2801 return -EOPNOTSUPP;
2802 }
2803}
2804
2805static int igb_offload_txtime(struct igb_adapter *adapter, 2786static int igb_offload_txtime(struct igb_adapter *adapter,
2806 struct tc_etf_qopt_offload *qopt) 2787 struct tc_etf_qopt_offload *qopt)
2807{ 2788{
@@ -2834,7 +2815,10 @@ static int igb_setup_tc(struct net_device *dev, enum tc_setup_type type,
2834 case TC_SETUP_QDISC_CBS: 2815 case TC_SETUP_QDISC_CBS:
2835 return igb_offload_cbs(adapter, type_data); 2816 return igb_offload_cbs(adapter, type_data);
2836 case TC_SETUP_BLOCK: 2817 case TC_SETUP_BLOCK:
2837 return igb_setup_tc_block(adapter, type_data); 2818 return flow_block_cb_setup_simple(type_data, NULL,
2819 igb_setup_tc_block_cb,
2820 adapter, adapter, true);
2821
2838 case TC_SETUP_QDISC_ETF: 2822 case TC_SETUP_QDISC_ETF:
2839 return igb_offload_txtime(adapter, type_data); 2823 return igb_offload_txtime(adapter, type_data);
2840 2824
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index b613e72c8ee4..b098f5be9c0d 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,
9607 } 9607 }
9608} 9608}
9609 9609
9610static int ixgbe_setup_tc_block(struct net_device *dev,
9611 struct tc_block_offload *f)
9612{
9613 struct ixgbe_adapter *adapter = netdev_priv(dev);
9614
9615 if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
9616 return -EOPNOTSUPP;
9617
9618 switch (f->command) {
9619 case TC_BLOCK_BIND:
9620 return tcf_block_cb_register(f->block, ixgbe_setup_tc_block_cb,
9621 adapter, adapter, f->extack);
9622 case TC_BLOCK_UNBIND:
9623 tcf_block_cb_unregister(f->block, ixgbe_setup_tc_block_cb,
9624 adapter);
9625 return 0;
9626 default:
9627 return -EOPNOTSUPP;
9628 }
9629}
9630
9631static int ixgbe_setup_tc_mqprio(struct net_device *dev, 9610static int ixgbe_setup_tc_mqprio(struct net_device *dev,
9632 struct tc_mqprio_qopt *mqprio) 9611 struct tc_mqprio_qopt *mqprio)
9633{ 9612{
@@ -9638,9 +9617,13 @@ static int ixgbe_setup_tc_mqprio(struct net_device *dev,
9638static int __ixgbe_setup_tc(struct net_device *dev, enum tc_setup_type type, 9617static int __ixgbe_setup_tc(struct net_device *dev, enum tc_setup_type type,
9639 void *type_data) 9618 void *type_data)
9640{ 9619{
9620 struct ixgbe_adapter *adapter = netdev_priv(dev);
9621
9641 switch (type) { 9622 switch (type) {
9642 case TC_SETUP_BLOCK: 9623 case TC_SETUP_BLOCK:
9643 return ixgbe_setup_tc_block(dev, type_data); 9624 return flow_block_cb_setup_simple(type_data, NULL,
9625 ixgbe_setup_tc_block_cb,
9626 adapter, adapter, true);
9644 case TC_SETUP_QDISC_MQPRIO: 9627 case TC_SETUP_QDISC_MQPRIO:
9645 return ixgbe_setup_tc_mqprio(dev, type_data); 9628 return ixgbe_setup_tc_mqprio(dev, type_data);
9646 default: 9629 default:
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 10efd69de7ef..8e5ebdb7c459 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -3457,36 +3457,19 @@ static int mlx5e_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
3457 return -EOPNOTSUPP; 3457 return -EOPNOTSUPP;
3458 } 3458 }
3459} 3459}
3460
3461static int mlx5e_setup_tc_block(struct net_device *dev,
3462 struct tc_block_offload *f)
3463{
3464 struct mlx5e_priv *priv = netdev_priv(dev);
3465
3466 if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
3467 return -EOPNOTSUPP;
3468
3469 switch (f->command) {
3470 case TC_BLOCK_BIND:
3471 return tcf_block_cb_register(f->block, mlx5e_setup_tc_block_cb,
3472 priv, priv, f->extack);
3473 case TC_BLOCK_UNBIND:
3474 tcf_block_cb_unregister(f->block, mlx5e_setup_tc_block_cb,
3475 priv);
3476 return 0;
3477 default:
3478 return -EOPNOTSUPP;
3479 }
3480}
3481#endif 3460#endif
3482 3461
3483static int mlx5e_setup_tc(struct net_device *dev, enum tc_setup_type type, 3462static int mlx5e_setup_tc(struct net_device *dev, enum tc_setup_type type,
3484 void *type_data) 3463 void *type_data)
3485{ 3464{
3465 struct mlx5e_priv *priv = netdev_priv(dev);
3466
3486 switch (type) { 3467 switch (type) {
3487#ifdef CONFIG_MLX5_ESWITCH 3468#ifdef CONFIG_MLX5_ESWITCH
3488 case TC_SETUP_BLOCK: 3469 case TC_SETUP_BLOCK:
3489 return mlx5e_setup_tc_block(dev, type_data); 3470 return flow_block_cb_setup_simple(type_data, NULL,
3471 mlx5e_setup_tc_block_cb,
3472 priv, priv, true);
3490#endif 3473#endif
3491 case TC_SETUP_QDISC_MQPRIO: 3474 case TC_SETUP_QDISC_MQPRIO:
3492 return mlx5e_setup_tc_mqprio(dev, type_data); 3475 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..a211cdb5eb8b 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
@@ -1153,32 +1153,16 @@ static int mlx5e_rep_setup_tc_cb(enum tc_setup_type type, void *type_data,
1153 } 1153 }
1154} 1154}
1155 1155
1156static int mlx5e_rep_setup_tc_block(struct net_device *dev,
1157 struct tc_block_offload *f)
1158{
1159 struct mlx5e_priv *priv = netdev_priv(dev);
1160
1161 if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
1162 return -EOPNOTSUPP;
1163
1164 switch (f->command) {
1165 case TC_BLOCK_BIND:
1166 return tcf_block_cb_register(f->block, mlx5e_rep_setup_tc_cb,
1167 priv, priv, f->extack);
1168 case TC_BLOCK_UNBIND:
1169 tcf_block_cb_unregister(f->block, mlx5e_rep_setup_tc_cb, priv);
1170 return 0;
1171 default:
1172 return -EOPNOTSUPP;
1173 }
1174}
1175
1176static int mlx5e_rep_setup_tc(struct net_device *dev, enum tc_setup_type type, 1156static int mlx5e_rep_setup_tc(struct net_device *dev, enum tc_setup_type type,
1177 void *type_data) 1157 void *type_data)
1178{ 1158{
1159 struct mlx5e_priv *priv = netdev_priv(dev);
1160
1179 switch (type) { 1161 switch (type) {
1180 case TC_SETUP_BLOCK: 1162 case TC_SETUP_BLOCK:
1181 return mlx5e_rep_setup_tc_block(dev, type_data); 1163 return flow_block_cb_setup_simple(type_data, NULL,
1164 mlx5e_rep_setup_tc_cb,
1165 priv, priv, true);
1182 default: 1166 default:
1183 return -EOPNOTSUPP; 1167 return -EOPNOTSUPP;
1184 } 1168 }
diff --git a/drivers/net/ethernet/netronome/nfp/abm/cls.c b/drivers/net/ethernet/netronome/nfp/abm/cls.c
index ff3913085665..29fb45734962 100644
--- a/drivers/net/ethernet/netronome/nfp/abm/cls.c
+++ b/drivers/net/ethernet/netronome/nfp/abm/cls.c
@@ -265,19 +265,6 @@ static int nfp_abm_setup_tc_block_cb(enum tc_setup_type type,
265int nfp_abm_setup_cls_block(struct net_device *netdev, struct nfp_repr *repr, 265int nfp_abm_setup_cls_block(struct net_device *netdev, struct nfp_repr *repr,
266 struct tc_block_offload *f) 266 struct tc_block_offload *f)
267{ 267{
268 if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_EGRESS) 268 return flow_block_cb_setup_simple(f, NULL, nfp_abm_setup_tc_block_cb,
269 return -EOPNOTSUPP; 269 repr, repr, true);
270
271 switch (f->command) {
272 case TC_BLOCK_BIND:
273 return tcf_block_cb_register(f->block,
274 nfp_abm_setup_tc_block_cb,
275 repr, repr, f->extack);
276 case TC_BLOCK_UNBIND:
277 tcf_block_cb_unregister(f->block, nfp_abm_setup_tc_block_cb,
278 repr);
279 return 0;
280 default:
281 return -EOPNOTSUPP;
282 }
283} 270}
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.c b/drivers/net/ethernet/netronome/nfp/bpf/main.c
index 9c136da25221..0c93c84a188a 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/main.c
+++ b/drivers/net/ethernet/netronome/nfp/bpf/main.c
@@ -160,35 +160,16 @@ static int nfp_bpf_setup_tc_block_cb(enum tc_setup_type type,
160 return 0; 160 return 0;
161} 161}
162 162
163static int nfp_bpf_setup_tc_block(struct net_device *netdev,
164 struct tc_block_offload *f)
165{
166 struct nfp_net *nn = netdev_priv(netdev);
167
168 if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
169 return -EOPNOTSUPP;
170
171 switch (f->command) {
172 case TC_BLOCK_BIND:
173 return tcf_block_cb_register(f->block,
174 nfp_bpf_setup_tc_block_cb,
175 nn, nn, f->extack);
176 case TC_BLOCK_UNBIND:
177 tcf_block_cb_unregister(f->block,
178 nfp_bpf_setup_tc_block_cb,
179 nn);
180 return 0;
181 default:
182 return -EOPNOTSUPP;
183 }
184}
185
186static int nfp_bpf_setup_tc(struct nfp_app *app, struct net_device *netdev, 163static int nfp_bpf_setup_tc(struct nfp_app *app, struct net_device *netdev,
187 enum tc_setup_type type, void *type_data) 164 enum tc_setup_type type, void *type_data)
188{ 165{
166 struct nfp_net *nn = netdev_priv(netdev);
167
189 switch (type) { 168 switch (type) {
190 case TC_SETUP_BLOCK: 169 case TC_SETUP_BLOCK:
191 return nfp_bpf_setup_tc_block(netdev, type_data); 170 return flow_block_cb_setup_simple(type_data, NULL,
171 nfp_bpf_setup_tc_block_cb,
172 nn, nn, true);
192 default: 173 default:
193 return -EOPNOTSUPP; 174 return -EOPNOTSUPP;
194 } 175 }
diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c
index d4a29660751d..cba97ed3dd56 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
@@ -579,25 +579,6 @@ static int qede_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
579 } 579 }
580} 580}
581 581
582static int qede_setup_tc_block(struct qede_dev *edev,
583 struct tc_block_offload *f)
584{
585 if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
586 return -EOPNOTSUPP;
587
588 switch (f->command) {
589 case TC_BLOCK_BIND:
590 return tcf_block_cb_register(f->block,
591 qede_setup_tc_block_cb,
592 edev, edev, f->extack);
593 case TC_BLOCK_UNBIND:
594 tcf_block_cb_unregister(f->block, qede_setup_tc_block_cb, edev);
595 return 0;
596 default:
597 return -EOPNOTSUPP;
598 }
599}
600
601static int 582static int
602qede_setup_tc_offload(struct net_device *dev, enum tc_setup_type type, 583qede_setup_tc_offload(struct net_device *dev, enum tc_setup_type type,
603 void *type_data) 584 void *type_data)
@@ -607,7 +588,9 @@ qede_setup_tc_offload(struct net_device *dev, enum tc_setup_type type,
607 588
608 switch (type) { 589 switch (type) {
609 case TC_SETUP_BLOCK: 590 case TC_SETUP_BLOCK:
610 return qede_setup_tc_block(edev, type_data); 591 return flow_block_cb_setup_simple(type_data, NULL,
592 qede_setup_tc_block_cb,
593 edev, edev, true);
611 case TC_SETUP_QDISC_MQPRIO: 594 case TC_SETUP_QDISC_MQPRIO:
612 mqprio = type_data; 595 mqprio = type_data;
613 596
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index e4b06dc484b7..93ef80c16f07 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -3769,24 +3769,6 @@ static int stmmac_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
3769 return ret; 3769 return ret;
3770} 3770}
3771 3771
3772static int stmmac_setup_tc_block(struct stmmac_priv *priv,
3773 struct tc_block_offload *f)
3774{
3775 if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
3776 return -EOPNOTSUPP;
3777
3778 switch (f->command) {
3779 case TC_BLOCK_BIND:
3780 return tcf_block_cb_register(f->block, stmmac_setup_tc_block_cb,
3781 priv, priv, f->extack);
3782 case TC_BLOCK_UNBIND:
3783 tcf_block_cb_unregister(f->block, stmmac_setup_tc_block_cb, priv);
3784 return 0;
3785 default:
3786 return -EOPNOTSUPP;
3787 }
3788}
3789
3790static int stmmac_setup_tc(struct net_device *ndev, enum tc_setup_type type, 3772static int stmmac_setup_tc(struct net_device *ndev, enum tc_setup_type type,
3791 void *type_data) 3773 void *type_data)
3792{ 3774{
@@ -3794,7 +3776,9 @@ static int stmmac_setup_tc(struct net_device *ndev, enum tc_setup_type type,
3794 3776
3795 switch (type) { 3777 switch (type) {
3796 case TC_SETUP_BLOCK: 3778 case TC_SETUP_BLOCK:
3797 return stmmac_setup_tc_block(priv, type_data); 3779 return flow_block_cb_setup_simple(type_data, NULL,
3780 stmmac_setup_tc_block_cb,
3781 priv, priv, true);
3798 case TC_SETUP_QDISC_CBS: 3782 case TC_SETUP_QDISC_CBS:
3799 return stmmac_tc_setup_cbs(priv, priv, type_data); 3783 return stmmac_tc_setup_cbs(priv, priv, type_data);
3800 default: 3784 default:
diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c
index e5c8aa08e1cd..920dc79e9dc9 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)
78 return nsim_bpf_setup_tc_block_cb(type, type_data, cb_priv); 78 return nsim_bpf_setup_tc_block_cb(type, type_data, cb_priv);
79} 79}
80 80
81static int
82nsim_setup_tc_block(struct net_device *dev, struct tc_block_offload *f)
83{
84 struct netdevsim *ns = netdev_priv(dev);
85
86 if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
87 return -EOPNOTSUPP;
88
89 switch (f->command) {
90 case TC_BLOCK_BIND:
91 return tcf_block_cb_register(f->block, nsim_setup_tc_block_cb,
92 ns, ns, f->extack);
93 case TC_BLOCK_UNBIND:
94 tcf_block_cb_unregister(f->block, nsim_setup_tc_block_cb, ns);
95 return 0;
96 default:
97 return -EOPNOTSUPP;
98 }
99}
100
101static int nsim_set_vf_mac(struct net_device *dev, int vf, u8 *mac) 81static int nsim_set_vf_mac(struct net_device *dev, int vf, u8 *mac)
102{ 82{
103 struct netdevsim *ns = netdev_priv(dev); 83 struct netdevsim *ns = netdev_priv(dev);
@@ -226,9 +206,13 @@ static int nsim_set_vf_link_state(struct net_device *dev, int vf, int state)
226static int 206static int
227nsim_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data) 207nsim_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data)
228{ 208{
209 struct netdevsim *ns = netdev_priv(dev);
210
229 switch (type) { 211 switch (type) {
230 case TC_SETUP_BLOCK: 212 case TC_SETUP_BLOCK:
231 return nsim_setup_tc_block(dev, type_data); 213 return flow_block_cb_setup_simple(type_data, NULL,
214 nsim_setup_tc_block_cb,
215 ns, ns, true);
232 default: 216 default:
233 return -EOPNOTSUPP; 217 return -EOPNOTSUPP;
234 } 218 }
diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h
index a09e256d2b27..2430e4907fe9 100644
--- a/include/net/flow_offload.h
+++ b/include/net/flow_offload.h
@@ -3,6 +3,7 @@
3 3
4#include <linux/kernel.h> 4#include <linux/kernel.h>
5#include <net/flow_dissector.h> 5#include <net/flow_dissector.h>
6#include <net/sch_generic.h>
6 7
7struct flow_match { 8struct flow_match {
8 struct flow_dissector *dissector; 9 struct flow_dissector *dissector;
@@ -237,4 +238,30 @@ static inline void flow_stats_update(struct flow_stats *flow_stats,
237 flow_stats->lastused = max_t(u64, flow_stats->lastused, lastused); 238 flow_stats->lastused = max_t(u64, flow_stats->lastused, lastused);
238} 239}
239 240
241enum flow_block_command {
242 TC_BLOCK_BIND,
243 TC_BLOCK_UNBIND,
244};
245
246enum flow_block_binder_type {
247 TCF_BLOCK_BINDER_TYPE_UNSPEC,
248 TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS,
249 TCF_BLOCK_BINDER_TYPE_CLSACT_EGRESS,
250};
251
252struct tcf_block;
253struct netlink_ext_ack;
254
255struct flow_block_offload {
256 enum flow_block_command command;
257 enum flow_block_binder_type binder_type;
258 struct tcf_block *block;
259 struct list_head *driver_block_list;
260 struct netlink_ext_ack *extack;
261};
262
263int flow_block_cb_setup_simple(struct flow_block_offload *f,
264 struct list_head *driver_list, tc_setup_cb_t *cb,
265 void *cb_ident, void *cb_priv, bool ingress_only);
266
240#endif /* _NET_FLOW_OFFLOAD_H */ 267#endif /* _NET_FLOW_OFFLOAD_H */
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 1a7596ba0dbe..b6c306fa9541 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -26,11 +26,9 @@ struct tcf_walker {
26int register_tcf_proto_ops(struct tcf_proto_ops *ops); 26int register_tcf_proto_ops(struct tcf_proto_ops *ops);
27int unregister_tcf_proto_ops(struct tcf_proto_ops *ops); 27int unregister_tcf_proto_ops(struct tcf_proto_ops *ops);
28 28
29enum tcf_block_binder_type { 29#define tc_block_offload flow_block_offload
30 TCF_BLOCK_BINDER_TYPE_UNSPEC, 30#define tc_block_command flow_block_command
31 TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS, 31#define tcf_block_binder_type flow_block_binder_type
32 TCF_BLOCK_BINDER_TYPE_CLSACT_EGRESS,
33};
34 32
35struct tcf_block_ext_info { 33struct tcf_block_ext_info {
36 enum tcf_block_binder_type binder_type; 34 enum tcf_block_binder_type binder_type;
@@ -610,18 +608,6 @@ int tc_setup_cb_call(struct tcf_block *block, enum tc_setup_type type,
610 void *type_data, bool err_stop); 608 void *type_data, bool err_stop);
611unsigned int tcf_exts_num_actions(struct tcf_exts *exts); 609unsigned int tcf_exts_num_actions(struct tcf_exts *exts);
612 610
613enum tc_block_command {
614 TC_BLOCK_BIND,
615 TC_BLOCK_UNBIND,
616};
617
618struct tc_block_offload {
619 enum tc_block_command command;
620 enum tcf_block_binder_type binder_type;
621 struct tcf_block *block;
622 struct netlink_ext_ack *extack;
623};
624
625struct tc_cls_common_offload { 611struct tc_cls_common_offload {
626 u32 chain_index; 612 u32 chain_index;
627 __be16 protocol; 613 __be16 protocol;
diff --git a/net/core/flow_offload.c b/net/core/flow_offload.c
index f52fe0bc4017..e31c0fdb6b01 100644
--- a/net/core/flow_offload.c
+++ b/net/core/flow_offload.c
@@ -2,6 +2,7 @@
2#include <linux/kernel.h> 2#include <linux/kernel.h>
3#include <linux/slab.h> 3#include <linux/slab.h>
4#include <net/flow_offload.h> 4#include <net/flow_offload.h>
5#include <net/pkt_cls.h>
5 6
6struct flow_rule *flow_rule_alloc(unsigned int num_actions) 7struct flow_rule *flow_rule_alloc(unsigned int num_actions)
7{ 8{
@@ -164,3 +165,27 @@ void flow_rule_match_enc_opts(const struct flow_rule *rule,
164 FLOW_DISSECTOR_MATCH(rule, FLOW_DISSECTOR_KEY_ENC_OPTS, out); 165 FLOW_DISSECTOR_MATCH(rule, FLOW_DISSECTOR_KEY_ENC_OPTS, out);
165} 166}
166EXPORT_SYMBOL(flow_rule_match_enc_opts); 167EXPORT_SYMBOL(flow_rule_match_enc_opts);
168
169int flow_block_cb_setup_simple(struct flow_block_offload *f,
170 struct list_head *driver_block_list,
171 tc_setup_cb_t *cb, void *cb_ident, void *cb_priv,
172 bool ingress_only)
173{
174 if (ingress_only &&
175 f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
176 return -EOPNOTSUPP;
177
178 f->driver_block_list = driver_block_list;
179
180 switch (f->command) {
181 case TC_BLOCK_BIND:
182 return tcf_block_cb_register(f->block, cb, cb_ident, cb_priv,
183 f->extack);
184 case TC_BLOCK_UNBIND:
185 tcf_block_cb_unregister(f->block, cb, cb_ident);
186 return 0;
187 default:
188 return -EOPNOTSUPP;
189 }
190}
191EXPORT_SYMBOL(flow_block_cb_setup_simple);