aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/bpf/offload.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/kernel/bpf/offload.c b/kernel/bpf/offload.c
index 001ddfde7874..cdd1e19a668b 100644
--- a/kernel/bpf/offload.c
+++ b/kernel/bpf/offload.c
@@ -30,9 +30,19 @@
30static DECLARE_RWSEM(bpf_devs_lock); 30static DECLARE_RWSEM(bpf_devs_lock);
31static LIST_HEAD(bpf_prog_offload_devs); 31static LIST_HEAD(bpf_prog_offload_devs);
32 32
33static int bpf_dev_offload_check(struct net_device *netdev)
34{
35 if (!netdev)
36 return -EINVAL;
37 if (!netdev->netdev_ops->ndo_bpf)
38 return -EOPNOTSUPP;
39 return 0;
40}
41
33int bpf_prog_offload_init(struct bpf_prog *prog, union bpf_attr *attr) 42int bpf_prog_offload_init(struct bpf_prog *prog, union bpf_attr *attr)
34{ 43{
35 struct bpf_prog_offload *offload; 44 struct bpf_prog_offload *offload;
45 int err;
36 46
37 if (attr->prog_type != BPF_PROG_TYPE_SCHED_CLS && 47 if (attr->prog_type != BPF_PROG_TYPE_SCHED_CLS &&
38 attr->prog_type != BPF_PROG_TYPE_XDP) 48 attr->prog_type != BPF_PROG_TYPE_XDP)
@@ -49,12 +59,15 @@ int bpf_prog_offload_init(struct bpf_prog *prog, union bpf_attr *attr)
49 59
50 offload->netdev = dev_get_by_index(current->nsproxy->net_ns, 60 offload->netdev = dev_get_by_index(current->nsproxy->net_ns,
51 attr->prog_ifindex); 61 attr->prog_ifindex);
52 if (!offload->netdev) 62 err = bpf_dev_offload_check(offload->netdev);
53 goto err_free; 63 if (err)
64 goto err_maybe_put;
54 65
55 down_write(&bpf_devs_lock); 66 down_write(&bpf_devs_lock);
56 if (offload->netdev->reg_state != NETREG_REGISTERED) 67 if (offload->netdev->reg_state != NETREG_REGISTERED) {
68 err = -EINVAL;
57 goto err_unlock; 69 goto err_unlock;
70 }
58 prog->aux->offload = offload; 71 prog->aux->offload = offload;
59 list_add_tail(&offload->offloads, &bpf_prog_offload_devs); 72 list_add_tail(&offload->offloads, &bpf_prog_offload_devs);
60 dev_put(offload->netdev); 73 dev_put(offload->netdev);
@@ -63,10 +76,11 @@ int bpf_prog_offload_init(struct bpf_prog *prog, union bpf_attr *attr)
63 return 0; 76 return 0;
64err_unlock: 77err_unlock:
65 up_write(&bpf_devs_lock); 78 up_write(&bpf_devs_lock);
66 dev_put(offload->netdev); 79err_maybe_put:
67err_free: 80 if (offload->netdev)
81 dev_put(offload->netdev);
68 kfree(offload); 82 kfree(offload);
69 return -EINVAL; 83 return err;
70} 84}
71 85
72static int __bpf_offload_ndo(struct bpf_prog *prog, enum bpf_netdev_command cmd, 86static int __bpf_offload_ndo(struct bpf_prog *prog, enum bpf_netdev_command cmd,
@@ -80,8 +94,6 @@ static int __bpf_offload_ndo(struct bpf_prog *prog, enum bpf_netdev_command cmd,
80 if (!offload) 94 if (!offload)
81 return -ENODEV; 95 return -ENODEV;
82 netdev = offload->netdev; 96 netdev = offload->netdev;
83 if (!netdev->netdev_ops->ndo_bpf)
84 return -EOPNOTSUPP;
85 97
86 data->command = cmd; 98 data->command = cmd;
87 99