/* only called from syscall */ static int prog_array_map_update_elem(struct bpf_map *map, void *key, void *value, u64 map_flags) { struct bpf_array *array = container_of(map, struct bpf_array, map); struct bpf_prog *prog, *old_prog; u32 index = *(u32 *)key, ufd; if (map_flags != BPF_ANY) return -EINVAL; if (index >= array->map.max_entries) return -E2BIG; ufd = *(u32 *)value; prog = bpf_prog_get(ufd); if (IS_ERR(prog)) return PTR_ERR(prog); if (!bpf_prog_array_compatible(array, prog)) { bpf_prog_put(prog); return -EINVAL; } old_prog = xchg(array->prog + index, prog); if (old_prog) bpf_prog_put_rcu(old_prog); return 0; }
static void *prog_fd_array_get_ptr(struct bpf_map *map, int fd) { struct bpf_array *array = container_of(map, struct bpf_array, map); struct bpf_prog *prog = bpf_prog_get(fd); if (IS_ERR(prog)) return prog; if (!bpf_prog_array_compatible(array, prog)) { bpf_prog_put(prog); return ERR_PTR(-EINVAL); } return prog; }