nfp: bpf: Convert ndo_setup_tc offloads to block callbacks
authorJiri Pirko <jiri@mellanox.com>
Thu, 19 Oct 2017 13:50:44 +0000 (15:50 +0200)
committerDavid S. Miller <davem@davemloft.net>
Sat, 21 Oct 2017 02:04:08 +0000 (03:04 +0100)
Benefit from the newly introduced block callback infrastructure and
convert ndo_setup_tc calls for bpf offloads to block callbacks.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/netronome/nfp/bpf/main.c

index 6e74f8d..64f97b3 100644 (file)
@@ -114,22 +114,58 @@ static void nfp_bpf_vnic_free(struct nfp_app *app, struct nfp_net *nn)
        kfree(nn->app_priv);
 }
 
-static int nfp_bpf_setup_tc(struct nfp_app *app, struct net_device *netdev,
-                           enum tc_setup_type type, void *type_data)
+static int nfp_bpf_setup_tc_block_cb(enum tc_setup_type type,
+                                    void *type_data, void *cb_priv)
 {
        struct tc_cls_bpf_offload *cls_bpf = type_data;
+       struct nfp_net *nn = cb_priv;
+
+       switch (type) {
+       case TC_SETUP_CLSBPF:
+               if (!nfp_net_ebpf_capable(nn) ||
+                   cls_bpf->common.protocol != htons(ETH_P_ALL) ||
+                   cls_bpf->common.chain_index)
+                       return -EOPNOTSUPP;
+               return nfp_net_bpf_offload(nn, cls_bpf);
+       default:
+               return -EOPNOTSUPP;
+       }
+}
+
+static int nfp_bpf_setup_tc_block(struct net_device *netdev,
+                                 struct tc_block_offload *f)
+{
        struct nfp_net *nn = netdev_priv(netdev);
 
-       if (type != TC_SETUP_CLSBPF || !nfp_net_ebpf_capable(nn) ||
-           !is_classid_clsact_ingress(cls_bpf->common.classid) ||
-           cls_bpf->common.protocol != htons(ETH_P_ALL) ||
-           cls_bpf->common.chain_index)
+       if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
                return -EOPNOTSUPP;
 
-       if (nn->dp.bpf_offload_xdp)
-               return -EBUSY;
+       switch (f->command) {
+       case TC_BLOCK_BIND:
+               return tcf_block_cb_register(f->block,
+                                            nfp_bpf_setup_tc_block_cb,
+                                            nn, nn);
+       case TC_BLOCK_UNBIND:
+               tcf_block_cb_unregister(f->block,
+                                       nfp_bpf_setup_tc_block_cb,
+                                       nn);
+               return 0;
+       default:
+               return -EOPNOTSUPP;
+       }
+}
 
-       return nfp_net_bpf_offload(nn, cls_bpf);
+static int nfp_bpf_setup_tc(struct nfp_app *app, struct net_device *netdev,
+                           enum tc_setup_type type, void *type_data)
+{
+       switch (type) {
+       case TC_SETUP_CLSBPF:
+               return 0; /* will be removed after conversion from ndo */
+       case TC_SETUP_BLOCK:
+               return nfp_bpf_setup_tc_block(netdev, type_data);
+       default:
+               return -EOPNOTSUPP;
+       }
 }
 
 static bool nfp_bpf_tc_busy(struct nfp_app *app, struct nfp_net *nn)