xref: /linux-6.15/kernel/bpf/offload.c (revision 89bbc53a)
1 /*
2  * Copyright (C) 2017-2018 Netronome Systems, Inc.
3  *
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
6  * source tree.
7  *
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.
14  */
15 
16 #include <linux/bpf.h>
17 #include <linux/bpf_verifier.h>
18 #include <linux/bug.h>
19 #include <linux/kdev_t.h>
20 #include <linux/list.h>
21 #include <linux/lockdep.h>
22 #include <linux/netdevice.h>
23 #include <linux/printk.h>
24 #include <linux/proc_ns.h>
25 #include <linux/rhashtable.h>
26 #include <linux/rtnetlink.h>
27 #include <linux/rwsem.h>
28 
29 /* Protects offdevs, members of bpf_offload_netdev and offload members
30  * of all progs.
31  * RTNL lock cannot be taken when holding this lock.
32  */
33 static DECLARE_RWSEM(bpf_devs_lock);
34 
35 struct bpf_offload_dev {
36 	const struct bpf_prog_offload_ops *ops;
37 	struct list_head netdevs;
38 	void *priv;
39 };
40 
41 struct bpf_offload_netdev {
42 	struct rhash_head l;
43 	struct net_device *netdev;
44 	struct bpf_offload_dev *offdev;
45 	struct list_head progs;
46 	struct list_head maps;
47 	struct list_head offdev_netdevs;
48 };
49 
50 static const struct rhashtable_params offdevs_params = {
51 	.nelem_hint		= 4,
52 	.key_len		= sizeof(struct net_device *),
53 	.key_offset		= offsetof(struct bpf_offload_netdev, netdev),
54 	.head_offset		= offsetof(struct bpf_offload_netdev, l),
55 	.automatic_shrinking	= true,
56 };
57 
58 static struct rhashtable offdevs;
59 
60 static int bpf_dev_offload_check(struct net_device *netdev)
61 {
62 	if (!netdev)
63 		return -EINVAL;
64 	if (!netdev->netdev_ops->ndo_bpf)
65 		return -EOPNOTSUPP;
66 	return 0;
67 }
68 
69 static struct bpf_offload_netdev *
70 bpf_offload_find_netdev(struct net_device *netdev)
71 {
72 	lockdep_assert_held(&bpf_devs_lock);
73 
74 	return rhashtable_lookup_fast(&offdevs, &netdev, offdevs_params);
75 }
76 
77 static int __bpf_offload_dev_netdev_register(struct bpf_offload_dev *offdev,
78 					     struct net_device *netdev)
79 {
80 	struct bpf_offload_netdev *ondev;
81 	int err;
82 
83 	ondev = kzalloc(sizeof(*ondev), GFP_KERNEL);
84 	if (!ondev)
85 		return -ENOMEM;
86 
87 	ondev->netdev = netdev;
88 	ondev->offdev = offdev;
89 	INIT_LIST_HEAD(&ondev->progs);
90 	INIT_LIST_HEAD(&ondev->maps);
91 
92 	down_write(&bpf_devs_lock);
93 	err = rhashtable_insert_fast(&offdevs, &ondev->l, offdevs_params);
94 	if (err) {
95 		netdev_warn(netdev, "failed to register for BPF offload\n");
96 		goto err_unlock_free;
97 	}
98 
99 	list_add(&ondev->offdev_netdevs, &offdev->netdevs);
100 	up_write(&bpf_devs_lock);
101 	return 0;
102 
103 err_unlock_free:
104 	up_write(&bpf_devs_lock);
105 	kfree(ondev);
106 	return err;
107 }
108 
109 static void __bpf_prog_offload_destroy(struct bpf_prog *prog)
110 {
111 	struct bpf_prog_offload *offload = prog->aux->offload;
112 
113 	if (offload->dev_state)
114 		offload->offdev->ops->destroy(prog);
115 
116 	/* Make sure BPF_PROG_GET_NEXT_ID can't find this dead program */
117 	bpf_prog_free_id(prog, true);
118 
119 	list_del_init(&offload->offloads);
120 	kfree(offload);
121 	prog->aux->offload = NULL;
122 }
123 
124 static int bpf_map_offload_ndo(struct bpf_offloaded_map *offmap,
125 			       enum bpf_netdev_command cmd)
126 {
127 	struct netdev_bpf data = {};
128 	struct net_device *netdev;
129 
130 	ASSERT_RTNL();
131 
132 	data.command = cmd;
133 	data.offmap = offmap;
134 	/* Caller must make sure netdev is valid */
135 	netdev = offmap->netdev;
136 
137 	return netdev->netdev_ops->ndo_bpf(netdev, &data);
138 }
139 
140 static void __bpf_map_offload_destroy(struct bpf_offloaded_map *offmap)
141 {
142 	WARN_ON(bpf_map_offload_ndo(offmap, BPF_OFFLOAD_MAP_FREE));
143 	/* Make sure BPF_MAP_GET_NEXT_ID can't find this dead map */
144 	bpf_map_free_id(&offmap->map, true);
145 	list_del_init(&offmap->offloads);
146 	offmap->netdev = NULL;
147 }
148 
149 static void __bpf_offload_dev_netdev_unregister(struct bpf_offload_dev *offdev,
150 						struct net_device *netdev)
151 {
152 	struct bpf_offload_netdev *ondev, *altdev;
153 	struct bpf_offloaded_map *offmap, *mtmp;
154 	struct bpf_prog_offload *offload, *ptmp;
155 
156 	ASSERT_RTNL();
157 
158 	down_write(&bpf_devs_lock);
159 	ondev = rhashtable_lookup_fast(&offdevs, &netdev, offdevs_params);
160 	if (WARN_ON(!ondev))
161 		goto unlock;
162 
163 	WARN_ON(rhashtable_remove_fast(&offdevs, &ondev->l, offdevs_params));
164 	list_del(&ondev->offdev_netdevs);
165 
166 	/* Try to move the objects to another netdev of the device */
167 	altdev = list_first_entry_or_null(&offdev->netdevs,
168 					  struct bpf_offload_netdev,
169 					  offdev_netdevs);
170 	if (altdev) {
171 		list_for_each_entry(offload, &ondev->progs, offloads)
172 			offload->netdev = altdev->netdev;
173 		list_splice_init(&ondev->progs, &altdev->progs);
174 
175 		list_for_each_entry(offmap, &ondev->maps, offloads)
176 			offmap->netdev = altdev->netdev;
177 		list_splice_init(&ondev->maps, &altdev->maps);
178 	} else {
179 		list_for_each_entry_safe(offload, ptmp, &ondev->progs, offloads)
180 			__bpf_prog_offload_destroy(offload->prog);
181 		list_for_each_entry_safe(offmap, mtmp, &ondev->maps, offloads)
182 			__bpf_map_offload_destroy(offmap);
183 	}
184 
185 	WARN_ON(!list_empty(&ondev->progs));
186 	WARN_ON(!list_empty(&ondev->maps));
187 	kfree(ondev);
188 unlock:
189 	up_write(&bpf_devs_lock);
190 }
191 
192 int bpf_prog_offload_init(struct bpf_prog *prog, union bpf_attr *attr)
193 {
194 	struct bpf_offload_netdev *ondev;
195 	struct bpf_prog_offload *offload;
196 	int err;
197 
198 	if (attr->prog_type != BPF_PROG_TYPE_SCHED_CLS &&
199 	    attr->prog_type != BPF_PROG_TYPE_XDP)
200 		return -EINVAL;
201 
202 	if (attr->prog_flags)
203 		return -EINVAL;
204 
205 	offload = kzalloc(sizeof(*offload), GFP_USER);
206 	if (!offload)
207 		return -ENOMEM;
208 
209 	offload->prog = prog;
210 
211 	offload->netdev = dev_get_by_index(current->nsproxy->net_ns,
212 					   attr->prog_ifindex);
213 	err = bpf_dev_offload_check(offload->netdev);
214 	if (err)
215 		goto err_maybe_put;
216 
217 	down_write(&bpf_devs_lock);
218 	ondev = bpf_offload_find_netdev(offload->netdev);
219 	if (!ondev) {
220 		err = -EINVAL;
221 		goto err_unlock;
222 	}
223 	offload->offdev = ondev->offdev;
224 	prog->aux->offload = offload;
225 	list_add_tail(&offload->offloads, &ondev->progs);
226 	dev_put(offload->netdev);
227 	up_write(&bpf_devs_lock);
228 
229 	return 0;
230 err_unlock:
231 	up_write(&bpf_devs_lock);
232 err_maybe_put:
233 	if (offload->netdev)
234 		dev_put(offload->netdev);
235 	kfree(offload);
236 	return err;
237 }
238 
239 int bpf_prog_offload_verifier_prep(struct bpf_prog *prog)
240 {
241 	struct bpf_prog_offload *offload;
242 	int ret = -ENODEV;
243 
244 	down_read(&bpf_devs_lock);
245 	offload = prog->aux->offload;
246 	if (offload) {
247 		ret = offload->offdev->ops->prepare(prog);
248 		offload->dev_state = !ret;
249 	}
250 	up_read(&bpf_devs_lock);
251 
252 	return ret;
253 }
254 
255 int bpf_prog_offload_verify_insn(struct bpf_verifier_env *env,
256 				 int insn_idx, int prev_insn_idx)
257 {
258 	struct bpf_prog_offload *offload;
259 	int ret = -ENODEV;
260 
261 	down_read(&bpf_devs_lock);
262 	offload = env->prog->aux->offload;
263 	if (offload)
264 		ret = offload->offdev->ops->insn_hook(env, insn_idx,
265 						      prev_insn_idx);
266 	up_read(&bpf_devs_lock);
267 
268 	return ret;
269 }
270 
271 int bpf_prog_offload_finalize(struct bpf_verifier_env *env)
272 {
273 	struct bpf_prog_offload *offload;
274 	int ret = -ENODEV;
275 
276 	down_read(&bpf_devs_lock);
277 	offload = env->prog->aux->offload;
278 	if (offload) {
279 		if (offload->offdev->ops->finalize)
280 			ret = offload->offdev->ops->finalize(env);
281 		else
282 			ret = 0;
283 	}
284 	up_read(&bpf_devs_lock);
285 
286 	return ret;
287 }
288 
289 void
290 bpf_prog_offload_replace_insn(struct bpf_verifier_env *env, u32 off,
291 			      struct bpf_insn *insn)
292 {
293 	const struct bpf_prog_offload_ops *ops;
294 	struct bpf_prog_offload *offload;
295 	int ret = -EOPNOTSUPP;
296 
297 	down_read(&bpf_devs_lock);
298 	offload = env->prog->aux->offload;
299 	if (offload) {
300 		ops = offload->offdev->ops;
301 		if (!offload->opt_failed && ops->replace_insn)
302 			ret = ops->replace_insn(env, off, insn);
303 		offload->opt_failed |= ret;
304 	}
305 	up_read(&bpf_devs_lock);
306 }
307 
308 void
309 bpf_prog_offload_remove_insns(struct bpf_verifier_env *env, u32 off, u32 cnt)
310 {
311 	struct bpf_prog_offload *offload;
312 	int ret = -EOPNOTSUPP;
313 
314 	down_read(&bpf_devs_lock);
315 	offload = env->prog->aux->offload;
316 	if (offload) {
317 		if (!offload->opt_failed && offload->offdev->ops->remove_insns)
318 			ret = offload->offdev->ops->remove_insns(env, off, cnt);
319 		offload->opt_failed |= ret;
320 	}
321 	up_read(&bpf_devs_lock);
322 }
323 
324 void bpf_prog_offload_destroy(struct bpf_prog *prog)
325 {
326 	down_write(&bpf_devs_lock);
327 	if (prog->aux->offload)
328 		__bpf_prog_offload_destroy(prog);
329 	up_write(&bpf_devs_lock);
330 }
331 
332 static int bpf_prog_offload_translate(struct bpf_prog *prog)
333 {
334 	struct bpf_prog_offload *offload;
335 	int ret = -ENODEV;
336 
337 	down_read(&bpf_devs_lock);
338 	offload = prog->aux->offload;
339 	if (offload)
340 		ret = offload->offdev->ops->translate(prog);
341 	up_read(&bpf_devs_lock);
342 
343 	return ret;
344 }
345 
346 static unsigned int bpf_prog_warn_on_exec(const void *ctx,
347 					  const struct bpf_insn *insn)
348 {
349 	WARN(1, "attempt to execute device eBPF program on the host!");
350 	return 0;
351 }
352 
353 int bpf_prog_offload_compile(struct bpf_prog *prog)
354 {
355 	prog->bpf_func = bpf_prog_warn_on_exec;
356 
357 	return bpf_prog_offload_translate(prog);
358 }
359 
360 struct ns_get_path_bpf_prog_args {
361 	struct bpf_prog *prog;
362 	struct bpf_prog_info *info;
363 };
364 
365 static struct ns_common *bpf_prog_offload_info_fill_ns(void *private_data)
366 {
367 	struct ns_get_path_bpf_prog_args *args = private_data;
368 	struct bpf_prog_aux *aux = args->prog->aux;
369 	struct ns_common *ns;
370 	struct net *net;
371 
372 	rtnl_lock();
373 	down_read(&bpf_devs_lock);
374 
375 	if (aux->offload) {
376 		args->info->ifindex = aux->offload->netdev->ifindex;
377 		net = dev_net(aux->offload->netdev);
378 		get_net(net);
379 		ns = &net->ns;
380 	} else {
381 		args->info->ifindex = 0;
382 		ns = NULL;
383 	}
384 
385 	up_read(&bpf_devs_lock);
386 	rtnl_unlock();
387 
388 	return ns;
389 }
390 
391 int bpf_prog_offload_info_fill(struct bpf_prog_info *info,
392 			       struct bpf_prog *prog)
393 {
394 	struct ns_get_path_bpf_prog_args args = {
395 		.prog	= prog,
396 		.info	= info,
397 	};
398 	struct bpf_prog_aux *aux = prog->aux;
399 	struct inode *ns_inode;
400 	struct path ns_path;
401 	char __user *uinsns;
402 	int res;
403 	u32 ulen;
404 
405 	res = ns_get_path_cb(&ns_path, bpf_prog_offload_info_fill_ns, &args);
406 	if (res) {
407 		if (!info->ifindex)
408 			return -ENODEV;
409 		return res;
410 	}
411 
412 	down_read(&bpf_devs_lock);
413 
414 	if (!aux->offload) {
415 		up_read(&bpf_devs_lock);
416 		return -ENODEV;
417 	}
418 
419 	ulen = info->jited_prog_len;
420 	info->jited_prog_len = aux->offload->jited_len;
421 	if (info->jited_prog_len && ulen) {
422 		uinsns = u64_to_user_ptr(info->jited_prog_insns);
423 		ulen = min_t(u32, info->jited_prog_len, ulen);
424 		if (copy_to_user(uinsns, aux->offload->jited_image, ulen)) {
425 			up_read(&bpf_devs_lock);
426 			return -EFAULT;
427 		}
428 	}
429 
430 	up_read(&bpf_devs_lock);
431 
432 	ns_inode = ns_path.dentry->d_inode;
433 	info->netns_dev = new_encode_dev(ns_inode->i_sb->s_dev);
434 	info->netns_ino = ns_inode->i_ino;
435 	path_put(&ns_path);
436 
437 	return 0;
438 }
439 
440 const struct bpf_prog_ops bpf_offload_prog_ops = {
441 };
442 
443 struct bpf_map *bpf_map_offload_map_alloc(union bpf_attr *attr)
444 {
445 	struct net *net = current->nsproxy->net_ns;
446 	struct bpf_offload_netdev *ondev;
447 	struct bpf_offloaded_map *offmap;
448 	int err;
449 
450 	if (!capable(CAP_SYS_ADMIN))
451 		return ERR_PTR(-EPERM);
452 	if (attr->map_type != BPF_MAP_TYPE_ARRAY &&
453 	    attr->map_type != BPF_MAP_TYPE_HASH)
454 		return ERR_PTR(-EINVAL);
455 
456 	offmap = bpf_map_area_alloc(sizeof(*offmap), NUMA_NO_NODE);
457 	if (!offmap)
458 		return ERR_PTR(-ENOMEM);
459 
460 	bpf_map_init_from_attr(&offmap->map, attr);
461 
462 	rtnl_lock();
463 	down_write(&bpf_devs_lock);
464 	offmap->netdev = __dev_get_by_index(net, attr->map_ifindex);
465 	err = bpf_dev_offload_check(offmap->netdev);
466 	if (err)
467 		goto err_unlock;
468 
469 	ondev = bpf_offload_find_netdev(offmap->netdev);
470 	if (!ondev) {
471 		err = -EINVAL;
472 		goto err_unlock;
473 	}
474 
475 	err = bpf_map_offload_ndo(offmap, BPF_OFFLOAD_MAP_ALLOC);
476 	if (err)
477 		goto err_unlock;
478 
479 	list_add_tail(&offmap->offloads, &ondev->maps);
480 	up_write(&bpf_devs_lock);
481 	rtnl_unlock();
482 
483 	return &offmap->map;
484 
485 err_unlock:
486 	up_write(&bpf_devs_lock);
487 	rtnl_unlock();
488 	bpf_map_area_free(offmap);
489 	return ERR_PTR(err);
490 }
491 
492 void bpf_map_offload_map_free(struct bpf_map *map)
493 {
494 	struct bpf_offloaded_map *offmap = map_to_offmap(map);
495 
496 	rtnl_lock();
497 	down_write(&bpf_devs_lock);
498 	if (offmap->netdev)
499 		__bpf_map_offload_destroy(offmap);
500 	up_write(&bpf_devs_lock);
501 	rtnl_unlock();
502 
503 	bpf_map_area_free(offmap);
504 }
505 
506 int bpf_map_offload_lookup_elem(struct bpf_map *map, void *key, void *value)
507 {
508 	struct bpf_offloaded_map *offmap = map_to_offmap(map);
509 	int ret = -ENODEV;
510 
511 	down_read(&bpf_devs_lock);
512 	if (offmap->netdev)
513 		ret = offmap->dev_ops->map_lookup_elem(offmap, key, value);
514 	up_read(&bpf_devs_lock);
515 
516 	return ret;
517 }
518 
519 int bpf_map_offload_update_elem(struct bpf_map *map,
520 				void *key, void *value, u64 flags)
521 {
522 	struct bpf_offloaded_map *offmap = map_to_offmap(map);
523 	int ret = -ENODEV;
524 
525 	if (unlikely(flags > BPF_EXIST))
526 		return -EINVAL;
527 
528 	down_read(&bpf_devs_lock);
529 	if (offmap->netdev)
530 		ret = offmap->dev_ops->map_update_elem(offmap, key, value,
531 						       flags);
532 	up_read(&bpf_devs_lock);
533 
534 	return ret;
535 }
536 
537 int bpf_map_offload_delete_elem(struct bpf_map *map, void *key)
538 {
539 	struct bpf_offloaded_map *offmap = map_to_offmap(map);
540 	int ret = -ENODEV;
541 
542 	down_read(&bpf_devs_lock);
543 	if (offmap->netdev)
544 		ret = offmap->dev_ops->map_delete_elem(offmap, key);
545 	up_read(&bpf_devs_lock);
546 
547 	return ret;
548 }
549 
550 int bpf_map_offload_get_next_key(struct bpf_map *map, void *key, void *next_key)
551 {
552 	struct bpf_offloaded_map *offmap = map_to_offmap(map);
553 	int ret = -ENODEV;
554 
555 	down_read(&bpf_devs_lock);
556 	if (offmap->netdev)
557 		ret = offmap->dev_ops->map_get_next_key(offmap, key, next_key);
558 	up_read(&bpf_devs_lock);
559 
560 	return ret;
561 }
562 
563 struct ns_get_path_bpf_map_args {
564 	struct bpf_offloaded_map *offmap;
565 	struct bpf_map_info *info;
566 };
567 
568 static struct ns_common *bpf_map_offload_info_fill_ns(void *private_data)
569 {
570 	struct ns_get_path_bpf_map_args *args = private_data;
571 	struct ns_common *ns;
572 	struct net *net;
573 
574 	rtnl_lock();
575 	down_read(&bpf_devs_lock);
576 
577 	if (args->offmap->netdev) {
578 		args->info->ifindex = args->offmap->netdev->ifindex;
579 		net = dev_net(args->offmap->netdev);
580 		get_net(net);
581 		ns = &net->ns;
582 	} else {
583 		args->info->ifindex = 0;
584 		ns = NULL;
585 	}
586 
587 	up_read(&bpf_devs_lock);
588 	rtnl_unlock();
589 
590 	return ns;
591 }
592 
593 int bpf_map_offload_info_fill(struct bpf_map_info *info, struct bpf_map *map)
594 {
595 	struct ns_get_path_bpf_map_args args = {
596 		.offmap	= map_to_offmap(map),
597 		.info	= info,
598 	};
599 	struct inode *ns_inode;
600 	struct path ns_path;
601 	int res;
602 
603 	res = ns_get_path_cb(&ns_path, bpf_map_offload_info_fill_ns, &args);
604 	if (res) {
605 		if (!info->ifindex)
606 			return -ENODEV;
607 		return res;
608 	}
609 
610 	ns_inode = ns_path.dentry->d_inode;
611 	info->netns_dev = new_encode_dev(ns_inode->i_sb->s_dev);
612 	info->netns_ino = ns_inode->i_ino;
613 	path_put(&ns_path);
614 
615 	return 0;
616 }
617 
618 static bool __bpf_offload_dev_match(struct bpf_prog *prog,
619 				    struct net_device *netdev)
620 {
621 	struct bpf_offload_netdev *ondev1, *ondev2;
622 	struct bpf_prog_offload *offload;
623 
624 	if (!bpf_prog_is_offloaded(prog->aux))
625 		return false;
626 
627 	offload = prog->aux->offload;
628 	if (!offload)
629 		return false;
630 	if (offload->netdev == netdev)
631 		return true;
632 
633 	ondev1 = bpf_offload_find_netdev(offload->netdev);
634 	ondev2 = bpf_offload_find_netdev(netdev);
635 
636 	return ondev1 && ondev2 && ondev1->offdev == ondev2->offdev;
637 }
638 
639 bool bpf_offload_dev_match(struct bpf_prog *prog, struct net_device *netdev)
640 {
641 	bool ret;
642 
643 	down_read(&bpf_devs_lock);
644 	ret = __bpf_offload_dev_match(prog, netdev);
645 	up_read(&bpf_devs_lock);
646 
647 	return ret;
648 }
649 EXPORT_SYMBOL_GPL(bpf_offload_dev_match);
650 
651 bool bpf_offload_prog_map_match(struct bpf_prog *prog, struct bpf_map *map)
652 {
653 	struct bpf_offloaded_map *offmap;
654 	bool ret;
655 
656 	if (!bpf_map_is_offloaded(map))
657 		return bpf_map_offload_neutral(map);
658 	offmap = map_to_offmap(map);
659 
660 	down_read(&bpf_devs_lock);
661 	ret = __bpf_offload_dev_match(prog, offmap->netdev);
662 	up_read(&bpf_devs_lock);
663 
664 	return ret;
665 }
666 
667 int bpf_offload_dev_netdev_register(struct bpf_offload_dev *offdev,
668 				    struct net_device *netdev)
669 {
670 	return __bpf_offload_dev_netdev_register(offdev, netdev);
671 }
672 EXPORT_SYMBOL_GPL(bpf_offload_dev_netdev_register);
673 
674 void bpf_offload_dev_netdev_unregister(struct bpf_offload_dev *offdev,
675 				       struct net_device *netdev)
676 {
677 	__bpf_offload_dev_netdev_unregister(offdev, netdev);
678 }
679 EXPORT_SYMBOL_GPL(bpf_offload_dev_netdev_unregister);
680 
681 struct bpf_offload_dev *
682 bpf_offload_dev_create(const struct bpf_prog_offload_ops *ops, void *priv)
683 {
684 	struct bpf_offload_dev *offdev;
685 
686 	offdev = kzalloc(sizeof(*offdev), GFP_KERNEL);
687 	if (!offdev)
688 		return ERR_PTR(-ENOMEM);
689 
690 	offdev->ops = ops;
691 	offdev->priv = priv;
692 	INIT_LIST_HEAD(&offdev->netdevs);
693 
694 	return offdev;
695 }
696 EXPORT_SYMBOL_GPL(bpf_offload_dev_create);
697 
698 void bpf_offload_dev_destroy(struct bpf_offload_dev *offdev)
699 {
700 	WARN_ON(!list_empty(&offdev->netdevs));
701 	kfree(offdev);
702 }
703 EXPORT_SYMBOL_GPL(bpf_offload_dev_destroy);
704 
705 void *bpf_offload_dev_priv(struct bpf_offload_dev *offdev)
706 {
707 	return offdev->priv;
708 }
709 EXPORT_SYMBOL_GPL(bpf_offload_dev_priv);
710 
711 static int __init bpf_offload_init(void)
712 {
713 	return rhashtable_init(&offdevs, &offdevs_params);
714 }
715 
716 late_initcall(bpf_offload_init);
717