2 * Copyright (C) 2017 Netronome Systems, Inc.
4 * This software is licensed under the GNU General License Version 2,
5 * June 1991 as shown in the file COPYING in the top-level directory of this
8 * THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS"
9 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
10 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
11 * FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
12 * OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME
13 * THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16 #include <linux/bpf.h>
17 #include <linux/bpf_verifier.h>
18 #include <linux/bug.h>
19 #include <linux/list.h>
20 #include <linux/netdevice.h>
21 #include <linux/printk.h>
22 #include <linux/rtnetlink.h>
23 #include <linux/rwsem.h>
25 /* Protects bpf_prog_offload_devs and offload members of all progs.
26 * RTNL lock cannot be taken when holding this lock.
28 static DECLARE_RWSEM(bpf_devs_lock
);
29 static LIST_HEAD(bpf_prog_offload_devs
);
31 int bpf_prog_offload_init(struct bpf_prog
*prog
, union bpf_attr
*attr
)
33 struct bpf_dev_offload
*offload
;
35 if (attr
->prog_type
!= BPF_PROG_TYPE_SCHED_CLS
&&
36 attr
->prog_type
!= BPF_PROG_TYPE_XDP
)
42 offload
= kzalloc(sizeof(*offload
), GFP_USER
);
47 init_waitqueue_head(&offload
->verifier_done
);
49 offload
->netdev
= dev_get_by_index(current
->nsproxy
->net_ns
,
54 down_write(&bpf_devs_lock
);
55 if (offload
->netdev
->reg_state
!= NETREG_REGISTERED
)
57 prog
->aux
->offload
= offload
;
58 list_add_tail(&offload
->offloads
, &bpf_prog_offload_devs
);
59 dev_put(offload
->netdev
);
60 up_write(&bpf_devs_lock
);
64 up_write(&bpf_devs_lock
);
65 dev_put(offload
->netdev
);
71 static int __bpf_offload_ndo(struct bpf_prog
*prog
, enum bpf_netdev_command cmd
,
72 struct netdev_bpf
*data
)
74 struct net_device
*netdev
= prog
->aux
->offload
->netdev
;
80 if (!netdev
->netdev_ops
->ndo_bpf
)
85 return netdev
->netdev_ops
->ndo_bpf(netdev
, data
);
88 int bpf_prog_offload_verifier_prep(struct bpf_verifier_env
*env
)
90 struct netdev_bpf data
= {};
93 data
.verifier
.prog
= env
->prog
;
96 err
= __bpf_offload_ndo(env
->prog
, BPF_OFFLOAD_VERIFIER_PREP
, &data
);
100 env
->dev_ops
= data
.verifier
.ops
;
102 env
->prog
->aux
->offload
->dev_state
= true;
103 env
->prog
->aux
->offload
->verifier_running
= true;
109 static void __bpf_prog_offload_destroy(struct bpf_prog
*prog
)
111 struct bpf_dev_offload
*offload
= prog
->aux
->offload
;
112 struct netdev_bpf data
= {};
114 /* Caution - if netdev is destroyed before the program, this function
115 * will be called twice.
118 data
.offload
.prog
= prog
;
120 if (offload
->verifier_running
)
121 wait_event(offload
->verifier_done
, !offload
->verifier_running
);
123 if (offload
->dev_state
)
124 WARN_ON(__bpf_offload_ndo(prog
, BPF_OFFLOAD_DESTROY
, &data
));
126 offload
->dev_state
= false;
127 list_del_init(&offload
->offloads
);
128 offload
->netdev
= NULL
;
131 void bpf_prog_offload_destroy(struct bpf_prog
*prog
)
133 struct bpf_dev_offload
*offload
= prog
->aux
->offload
;
135 offload
->verifier_running
= false;
136 wake_up(&offload
->verifier_done
);
139 down_write(&bpf_devs_lock
);
140 __bpf_prog_offload_destroy(prog
);
141 up_write(&bpf_devs_lock
);
147 static int bpf_prog_offload_translate(struct bpf_prog
*prog
)
149 struct bpf_dev_offload
*offload
= prog
->aux
->offload
;
150 struct netdev_bpf data
= {};
153 data
.offload
.prog
= prog
;
155 offload
->verifier_running
= false;
156 wake_up(&offload
->verifier_done
);
159 ret
= __bpf_offload_ndo(prog
, BPF_OFFLOAD_TRANSLATE
, &data
);
165 static unsigned int bpf_prog_warn_on_exec(const void *ctx
,
166 const struct bpf_insn
*insn
)
168 WARN(1, "attempt to execute device eBPF program on the host!");
172 int bpf_prog_offload_compile(struct bpf_prog
*prog
)
174 prog
->bpf_func
= bpf_prog_warn_on_exec
;
176 return bpf_prog_offload_translate(prog
);
179 const struct bpf_prog_ops bpf_offload_prog_ops
= {
182 static int bpf_offload_notification(struct notifier_block
*notifier
,
183 ulong event
, void *ptr
)
185 struct net_device
*netdev
= netdev_notifier_info_to_dev(ptr
);
186 struct bpf_dev_offload
*offload
, *tmp
;
191 case NETDEV_UNREGISTER
:
192 /* ignore namespace changes */
193 if (netdev
->reg_state
!= NETREG_UNREGISTERING
)
196 down_write(&bpf_devs_lock
);
197 list_for_each_entry_safe(offload
, tmp
, &bpf_prog_offload_devs
,
199 if (offload
->netdev
== netdev
)
200 __bpf_prog_offload_destroy(offload
->prog
);
202 up_write(&bpf_devs_lock
);
210 static struct notifier_block bpf_offload_notifier
= {
211 .notifier_call
= bpf_offload_notification
,
214 static int __init
bpf_offload_init(void)
216 register_netdevice_notifier(&bpf_offload_notifier
);
220 subsys_initcall(bpf_offload_init
);