Lines Matching +full:ns +full:-
5 * June 1991 as shown in the file COPYING in the top-level directory of this
41 struct netdevsim *ns; member
53 const char **str = file->private; in nsim_bpf_string_show()
68 state = env->prog->aux->offload->dev_priv; in nsim_bpf_verify_insn()
69 if (state->nsim_dev->bpf_bind_verifier_delay && !insn_idx) in nsim_bpf_verify_insn()
70 msleep(state->nsim_dev->bpf_bind_verifier_delay); in nsim_bpf_verify_insn()
72 if (insn_idx == env->prog->len - 1) { in nsim_bpf_verify_insn()
75 if (!state->nsim_dev->bpf_bind_verifier_accept) in nsim_bpf_verify_insn()
76 ret = -EOPNOTSUPP; in nsim_bpf_verify_insn()
87 static bool nsim_xdp_offload_active(struct netdevsim *ns) in nsim_xdp_offload_active() argument
89 return ns->xdp_hw.prog; in nsim_xdp_offload_active()
96 if (!prog || !bpf_prog_is_offloaded(prog->aux)) in nsim_prog_set_loaded()
99 state = prog->aux->offload->dev_priv; in nsim_prog_set_loaded()
100 state->is_loaded = loaded; in nsim_prog_set_loaded()
104 nsim_bpf_offload(struct netdevsim *ns, struct bpf_prog *prog, bool oldprog) in nsim_bpf_offload() argument
106 nsim_prog_set_loaded(ns->bpf_offloaded, false); in nsim_bpf_offload()
108 WARN(!!ns->bpf_offloaded != oldprog, in nsim_bpf_offload()
111 ns->bpf_offloaded = prog; in nsim_bpf_offload()
112 ns->bpf_offloaded_id = prog ? prog->aux->id : 0; in nsim_bpf_offload()
122 struct bpf_prog *prog = cls_bpf->prog; in nsim_bpf_setup_tc_block_cb()
123 struct netdevsim *ns = cb_priv; in nsim_bpf_setup_tc_block_cb() local
127 NSIM_EA(cls_bpf->common.extack, in nsim_bpf_setup_tc_block_cb()
129 return -EOPNOTSUPP; in nsim_bpf_setup_tc_block_cb()
132 if (!tc_cls_can_offload_and_chain0(ns->netdev, &cls_bpf->common)) in nsim_bpf_setup_tc_block_cb()
133 return -EOPNOTSUPP; in nsim_bpf_setup_tc_block_cb()
135 if (cls_bpf->common.protocol != htons(ETH_P_ALL)) { in nsim_bpf_setup_tc_block_cb()
136 NSIM_EA(cls_bpf->common.extack, in nsim_bpf_setup_tc_block_cb()
138 return -EOPNOTSUPP; in nsim_bpf_setup_tc_block_cb()
141 if (!ns->bpf_tc_accept) { in nsim_bpf_setup_tc_block_cb()
142 NSIM_EA(cls_bpf->common.extack, in nsim_bpf_setup_tc_block_cb()
144 return -EOPNOTSUPP; in nsim_bpf_setup_tc_block_cb()
147 if (prog && !prog->aux->offload && !ns->bpf_tc_non_bound_accept) { in nsim_bpf_setup_tc_block_cb()
148 NSIM_EA(cls_bpf->common.extack, in nsim_bpf_setup_tc_block_cb()
150 return -EOPNOTSUPP; in nsim_bpf_setup_tc_block_cb()
153 if (cls_bpf->command != TC_CLSBPF_OFFLOAD) in nsim_bpf_setup_tc_block_cb()
154 return -EOPNOTSUPP; in nsim_bpf_setup_tc_block_cb()
156 oldprog = cls_bpf->oldprog; in nsim_bpf_setup_tc_block_cb()
159 if (ns->bpf_offloaded != oldprog) { in nsim_bpf_setup_tc_block_cb()
161 if (!cls_bpf->prog) in nsim_bpf_setup_tc_block_cb()
163 if (ns->bpf_offloaded) { in nsim_bpf_setup_tc_block_cb()
164 NSIM_EA(cls_bpf->common.extack, in nsim_bpf_setup_tc_block_cb()
166 return -EBUSY; in nsim_bpf_setup_tc_block_cb()
170 return nsim_bpf_offload(ns, cls_bpf->prog, oldprog); in nsim_bpf_setup_tc_block_cb()
173 int nsim_bpf_disable_tc(struct netdevsim *ns) in nsim_bpf_disable_tc() argument
175 if (ns->bpf_offloaded && !nsim_xdp_offload_active(ns)) in nsim_bpf_disable_tc()
176 return -EBUSY; in nsim_bpf_disable_tc()
180 static int nsim_xdp_offload_prog(struct netdevsim *ns, struct netdev_bpf *bpf) in nsim_xdp_offload_prog() argument
182 if (!nsim_xdp_offload_active(ns) && !bpf->prog) in nsim_xdp_offload_prog()
184 if (!nsim_xdp_offload_active(ns) && bpf->prog && ns->bpf_offloaded) { in nsim_xdp_offload_prog()
185 NSIM_EA(bpf->extack, "TC program is already loaded"); in nsim_xdp_offload_prog()
186 return -EBUSY; in nsim_xdp_offload_prog()
189 return nsim_bpf_offload(ns, bpf->prog, nsim_xdp_offload_active(ns)); in nsim_xdp_offload_prog()
193 nsim_xdp_set_prog(struct netdevsim *ns, struct netdev_bpf *bpf, in nsim_xdp_set_prog() argument
198 if (bpf->command == XDP_SETUP_PROG && !ns->bpf_xdpdrv_accept) { in nsim_xdp_set_prog()
199 NSIM_EA(bpf->extack, "driver XDP disabled in DebugFS"); in nsim_xdp_set_prog()
200 return -EOPNOTSUPP; in nsim_xdp_set_prog()
202 if (bpf->command == XDP_SETUP_PROG_HW && !ns->bpf_xdpoffload_accept) { in nsim_xdp_set_prog()
203 NSIM_EA(bpf->extack, "XDP offload disabled in DebugFS"); in nsim_xdp_set_prog()
204 return -EOPNOTSUPP; in nsim_xdp_set_prog()
207 if (bpf->command == XDP_SETUP_PROG_HW) { in nsim_xdp_set_prog()
208 err = nsim_xdp_offload_prog(ns, bpf); in nsim_xdp_set_prog()
227 return -ENOMEM; in nsim_bpf_create_prog()
229 state->nsim_dev = nsim_dev; in nsim_bpf_create_prog()
230 state->prog = prog; in nsim_bpf_create_prog()
231 state->state = "verify"; in nsim_bpf_create_prog()
234 sprintf(name, "%u", nsim_dev->prog_id_gen++); in nsim_bpf_create_prog()
235 state->ddir = debugfs_create_dir(name, nsim_dev->ddir_bpf_bound_progs); in nsim_bpf_create_prog()
236 if (IS_ERR(state->ddir)) { in nsim_bpf_create_prog()
237 ret = PTR_ERR(state->ddir); in nsim_bpf_create_prog()
242 debugfs_create_u32("id", 0400, state->ddir, &prog->aux->id); in nsim_bpf_create_prog()
243 debugfs_create_file("state", 0400, state->ddir, in nsim_bpf_create_prog()
244 &state->state, &nsim_bpf_string_fops); in nsim_bpf_create_prog()
245 debugfs_create_bool("loaded", 0400, state->ddir, &state->is_loaded); in nsim_bpf_create_prog()
247 list_add_tail(&state->l, &nsim_dev->bpf_bound_progs); in nsim_bpf_create_prog()
249 prog->aux->offload->dev_priv = state; in nsim_bpf_create_prog()
257 bpf_offload_dev_priv(prog->aux->offload->offdev); in nsim_bpf_verifier_prep()
259 if (!nsim_dev->bpf_bind_accept) in nsim_bpf_verifier_prep()
260 return -EOPNOTSUPP; in nsim_bpf_verifier_prep()
267 struct nsim_bpf_bound_prog *state = prog->aux->offload->dev_priv; in nsim_bpf_translate()
269 state->state = "xlated"; in nsim_bpf_translate()
277 state = prog->aux->offload->dev_priv; in nsim_bpf_destroy_prog()
278 WARN(state->is_loaded, in nsim_bpf_destroy_prog()
280 debugfs_remove_recursive(state->ddir); in nsim_bpf_destroy_prog()
281 list_del(&state->l); in nsim_bpf_destroy_prog()
293 static int nsim_setup_prog_checks(struct netdevsim *ns, struct netdev_bpf *bpf) in nsim_setup_prog_checks() argument
295 if (bpf->prog && bpf->prog->aux->offload) { in nsim_setup_prog_checks()
296 NSIM_EA(bpf->extack, "attempt to load offloaded prog to drv"); in nsim_setup_prog_checks()
297 return -EINVAL; in nsim_setup_prog_checks()
299 if (bpf->prog && !bpf->prog->aux->xdp_has_frags && in nsim_setup_prog_checks()
300 ns->netdev->mtu > NSIM_XDP_MAX_MTU) { in nsim_setup_prog_checks()
301 NSIM_EA(bpf->extack, "MTU too large w/ XDP enabled"); in nsim_setup_prog_checks()
302 return -EINVAL; in nsim_setup_prog_checks()
308 nsim_setup_prog_hw_checks(struct netdevsim *ns, struct netdev_bpf *bpf) in nsim_setup_prog_hw_checks() argument
312 if (!bpf->prog) in nsim_setup_prog_hw_checks()
315 if (!bpf_prog_is_offloaded(bpf->prog->aux)) { in nsim_setup_prog_hw_checks()
316 NSIM_EA(bpf->extack, "xdpoffload of non-bound program"); in nsim_setup_prog_hw_checks()
317 return -EINVAL; in nsim_setup_prog_hw_checks()
320 state = bpf->prog->aux->offload->dev_priv; in nsim_setup_prog_hw_checks()
321 if (WARN_ON(strcmp(state->state, "xlated"))) { in nsim_setup_prog_hw_checks()
322 NSIM_EA(bpf->extack, "offloading program in bad state"); in nsim_setup_prog_hw_checks()
323 return -EINVAL; in nsim_setup_prog_hw_checks()
331 return e->key && !memcmp(key, e->key, map->key_size); in nsim_map_key_match()
336 struct nsim_bpf_bound_map *nmap = offmap->dev_priv; in nsim_map_key_find()
339 for (i = 0; i < ARRAY_SIZE(nmap->entry); i++) in nsim_map_key_find()
340 if (nsim_map_key_match(&offmap->map, &nmap->entry[i], key)) in nsim_map_key_find()
343 return -ENOENT; in nsim_map_key_find()
349 struct nsim_bpf_bound_map *nmap = offmap->dev_priv; in nsim_map_alloc_elem()
351 nmap->entry[idx].key = kmalloc(offmap->map.key_size, in nsim_map_alloc_elem()
353 if (!nmap->entry[idx].key) in nsim_map_alloc_elem()
354 return -ENOMEM; in nsim_map_alloc_elem()
355 nmap->entry[idx].value = kmalloc(offmap->map.value_size, in nsim_map_alloc_elem()
357 if (!nmap->entry[idx].value) { in nsim_map_alloc_elem()
358 kfree(nmap->entry[idx].key); in nsim_map_alloc_elem()
359 nmap->entry[idx].key = NULL; in nsim_map_alloc_elem()
360 return -ENOMEM; in nsim_map_alloc_elem()
370 struct nsim_bpf_bound_map *nmap = offmap->dev_priv; in nsim_map_get_next_key()
371 int idx = -ENOENT; in nsim_map_get_next_key()
373 mutex_lock(&nmap->mutex); in nsim_map_get_next_key()
377 if (idx == -ENOENT) in nsim_map_get_next_key()
382 for (; idx < ARRAY_SIZE(nmap->entry); idx++) { in nsim_map_get_next_key()
383 if (nmap->entry[idx].key) { in nsim_map_get_next_key()
384 memcpy(next_key, nmap->entry[idx].key, in nsim_map_get_next_key()
385 offmap->map.key_size); in nsim_map_get_next_key()
390 mutex_unlock(&nmap->mutex); in nsim_map_get_next_key()
392 if (idx == ARRAY_SIZE(nmap->entry)) in nsim_map_get_next_key()
393 return -ENOENT; in nsim_map_get_next_key()
400 struct nsim_bpf_bound_map *nmap = offmap->dev_priv; in nsim_map_lookup_elem()
403 mutex_lock(&nmap->mutex); in nsim_map_lookup_elem()
407 memcpy(value, nmap->entry[idx].value, offmap->map.value_size); in nsim_map_lookup_elem()
409 mutex_unlock(&nmap->mutex); in nsim_map_lookup_elem()
418 struct nsim_bpf_bound_map *nmap = offmap->dev_priv; in nsim_map_update_elem()
421 mutex_lock(&nmap->mutex); in nsim_map_update_elem()
429 err = -EEXIST; in nsim_map_update_elem()
434 for (idx = 0; idx < ARRAY_SIZE(nmap->entry); idx++) in nsim_map_update_elem()
435 if (!nmap->entry[idx].key) in nsim_map_update_elem()
437 if (idx == ARRAY_SIZE(nmap->entry)) { in nsim_map_update_elem()
438 err = -E2BIG; in nsim_map_update_elem()
447 memcpy(nmap->entry[idx].key, key, offmap->map.key_size); in nsim_map_update_elem()
448 memcpy(nmap->entry[idx].value, value, offmap->map.value_size); in nsim_map_update_elem()
450 mutex_unlock(&nmap->mutex); in nsim_map_update_elem()
457 struct nsim_bpf_bound_map *nmap = offmap->dev_priv; in nsim_map_delete_elem()
460 if (offmap->map.map_type == BPF_MAP_TYPE_ARRAY) in nsim_map_delete_elem()
461 return -EINVAL; in nsim_map_delete_elem()
463 mutex_lock(&nmap->mutex); in nsim_map_delete_elem()
467 kfree(nmap->entry[idx].key); in nsim_map_delete_elem()
468 kfree(nmap->entry[idx].value); in nsim_map_delete_elem()
469 memset(&nmap->entry[idx], 0, sizeof(nmap->entry[idx])); in nsim_map_delete_elem()
472 mutex_unlock(&nmap->mutex); in nsim_map_delete_elem()
485 nsim_bpf_map_alloc(struct netdevsim *ns, struct bpf_offloaded_map *offmap) in nsim_bpf_map_alloc() argument
490 if (WARN_ON(offmap->map.map_type != BPF_MAP_TYPE_ARRAY && in nsim_bpf_map_alloc()
491 offmap->map.map_type != BPF_MAP_TYPE_HASH)) in nsim_bpf_map_alloc()
492 return -EINVAL; in nsim_bpf_map_alloc()
493 if (offmap->map.max_entries > NSIM_BPF_MAX_KEYS) in nsim_bpf_map_alloc()
494 return -ENOMEM; in nsim_bpf_map_alloc()
495 if (offmap->map.map_flags) in nsim_bpf_map_alloc()
496 return -EINVAL; in nsim_bpf_map_alloc()
500 return -ENOMEM; in nsim_bpf_map_alloc()
502 offmap->dev_priv = nmap; in nsim_bpf_map_alloc()
503 nmap->ns = ns; in nsim_bpf_map_alloc()
504 nmap->map = offmap; in nsim_bpf_map_alloc()
505 mutex_init(&nmap->mutex); in nsim_bpf_map_alloc()
507 if (offmap->map.map_type == BPF_MAP_TYPE_ARRAY) { in nsim_bpf_map_alloc()
508 for (i = 0; i < ARRAY_SIZE(nmap->entry); i++) { in nsim_bpf_map_alloc()
514 key = nmap->entry[i].key; in nsim_bpf_map_alloc()
516 memset(nmap->entry[i].value, 0, offmap->map.value_size); in nsim_bpf_map_alloc()
520 offmap->dev_ops = &nsim_bpf_map_ops; in nsim_bpf_map_alloc()
521 list_add_tail(&nmap->l, &ns->nsim_dev->bpf_bound_maps); in nsim_bpf_map_alloc()
526 while (--i >= 0) { in nsim_bpf_map_alloc()
527 kfree(nmap->entry[i].key); in nsim_bpf_map_alloc()
528 kfree(nmap->entry[i].value); in nsim_bpf_map_alloc()
536 struct nsim_bpf_bound_map *nmap = offmap->dev_priv; in nsim_bpf_map_free()
539 for (i = 0; i < ARRAY_SIZE(nmap->entry); i++) { in nsim_bpf_map_free()
540 kfree(nmap->entry[i].key); in nsim_bpf_map_free()
541 kfree(nmap->entry[i].value); in nsim_bpf_map_free()
543 list_del_init(&nmap->l); in nsim_bpf_map_free()
544 mutex_destroy(&nmap->mutex); in nsim_bpf_map_free()
550 struct netdevsim *ns = netdev_priv(dev); in nsim_bpf() local
555 switch (bpf->command) { in nsim_bpf()
557 err = nsim_setup_prog_checks(ns, bpf); in nsim_bpf()
561 return nsim_xdp_set_prog(ns, bpf, &ns->xdp); in nsim_bpf()
563 err = nsim_setup_prog_hw_checks(ns, bpf); in nsim_bpf()
567 return nsim_xdp_set_prog(ns, bpf, &ns->xdp_hw); in nsim_bpf()
569 if (!ns->bpf_map_accept) in nsim_bpf()
570 return -EOPNOTSUPP; in nsim_bpf()
572 return nsim_bpf_map_alloc(ns, bpf->offmap); in nsim_bpf()
574 nsim_bpf_map_free(bpf->offmap); in nsim_bpf()
577 return -EINVAL; in nsim_bpf()
585 INIT_LIST_HEAD(&nsim_dev->bpf_bound_progs); in nsim_bpf_dev_init()
586 INIT_LIST_HEAD(&nsim_dev->bpf_bound_maps); in nsim_bpf_dev_init()
588 nsim_dev->ddir_bpf_bound_progs = debugfs_create_dir("bpf_bound_progs", in nsim_bpf_dev_init()
589 nsim_dev->ddir); in nsim_bpf_dev_init()
590 if (IS_ERR(nsim_dev->ddir_bpf_bound_progs)) in nsim_bpf_dev_init()
591 return PTR_ERR(nsim_dev->ddir_bpf_bound_progs); in nsim_bpf_dev_init()
593 nsim_dev->bpf_dev = bpf_offload_dev_create(&nsim_bpf_dev_ops, nsim_dev); in nsim_bpf_dev_init()
594 err = PTR_ERR_OR_ZERO(nsim_dev->bpf_dev); in nsim_bpf_dev_init()
598 nsim_dev->bpf_bind_accept = true; in nsim_bpf_dev_init()
599 debugfs_create_bool("bpf_bind_accept", 0600, nsim_dev->ddir, in nsim_bpf_dev_init()
600 &nsim_dev->bpf_bind_accept); in nsim_bpf_dev_init()
601 debugfs_create_u32("bpf_bind_verifier_delay", 0600, nsim_dev->ddir, in nsim_bpf_dev_init()
602 &nsim_dev->bpf_bind_verifier_delay); in nsim_bpf_dev_init()
603 nsim_dev->bpf_bind_verifier_accept = true; in nsim_bpf_dev_init()
604 debugfs_create_bool("bpf_bind_verifier_accept", 0600, nsim_dev->ddir, in nsim_bpf_dev_init()
605 &nsim_dev->bpf_bind_verifier_accept); in nsim_bpf_dev_init()
611 WARN_ON(!list_empty(&nsim_dev->bpf_bound_progs)); in nsim_bpf_dev_exit()
612 WARN_ON(!list_empty(&nsim_dev->bpf_bound_maps)); in nsim_bpf_dev_exit()
613 bpf_offload_dev_destroy(nsim_dev->bpf_dev); in nsim_bpf_dev_exit()
616 int nsim_bpf_init(struct netdevsim *ns) in nsim_bpf_init() argument
618 struct dentry *ddir = ns->nsim_dev_port->ddir; in nsim_bpf_init()
621 err = bpf_offload_dev_netdev_register(ns->nsim_dev->bpf_dev, in nsim_bpf_init()
622 ns->netdev); in nsim_bpf_init()
627 &ns->bpf_offloaded_id); in nsim_bpf_init()
629 ns->bpf_tc_accept = true; in nsim_bpf_init()
631 &ns->bpf_tc_accept); in nsim_bpf_init()
633 &ns->bpf_tc_non_bound_accept); in nsim_bpf_init()
634 ns->bpf_xdpdrv_accept = true; in nsim_bpf_init()
636 &ns->bpf_xdpdrv_accept); in nsim_bpf_init()
637 ns->bpf_xdpoffload_accept = true; in nsim_bpf_init()
639 &ns->bpf_xdpoffload_accept); in nsim_bpf_init()
641 ns->bpf_map_accept = true; in nsim_bpf_init()
643 &ns->bpf_map_accept); in nsim_bpf_init()
648 void nsim_bpf_uninit(struct netdevsim *ns) in nsim_bpf_uninit() argument
650 WARN_ON(ns->xdp.prog); in nsim_bpf_uninit()
651 WARN_ON(ns->xdp_hw.prog); in nsim_bpf_uninit()
652 WARN_ON(ns->bpf_offloaded); in nsim_bpf_uninit()
653 bpf_offload_dev_netdev_unregister(ns->nsim_dev->bpf_dev, ns->netdev); in nsim_bpf_uninit()