Introduce bpf_map_get_xdp_prog to load an eBPF program on CPUMAP/DEVMAP entries since both of them share the same code. Signed-off-by: Lorenzo Bianconi <lorenzo@xxxxxxxxxx> --- include/linux/bpf.h | 2 ++ kernel/bpf/core.c | 17 +++++++++++++++++ kernel/bpf/cpumap.c | 12 ++++-------- kernel/bpf/devmap.c | 16 ++++++---------- 4 files changed, 29 insertions(+), 18 deletions(-) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 26bf8c865103..891936b54b55 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -1910,6 +1910,8 @@ static inline struct bpf_prog *bpf_prog_get_type(u32 ufd, return bpf_prog_get_type_dev(ufd, type, false); } +struct bpf_prog *bpf_map_get_xdp_prog(struct bpf_map *map, int fd, + enum bpf_attach_type attach_type); void __bpf_free_used_maps(struct bpf_prog_aux *aux, struct bpf_map **used_maps, u32 len); diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index dee91a2eea7b..7e72c21b6589 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -2228,6 +2228,23 @@ void __bpf_free_used_maps(struct bpf_prog_aux *aux, } } +struct bpf_prog *bpf_map_get_xdp_prog(struct bpf_map *map, int fd, + enum bpf_attach_type attach_type) +{ + struct bpf_prog *prog; + + prog = bpf_prog_get_type(fd, BPF_PROG_TYPE_XDP); + if (IS_ERR(prog)) + return prog; + + if (prog->expected_attach_type != attach_type) { + bpf_prog_put(prog); + return ERR_PTR(-EINVAL); + } + + return prog; +} + static void bpf_free_used_maps(struct bpf_prog_aux *aux) { __bpf_free_used_maps(aux, aux->used_maps, aux->used_map_cnt); diff --git a/kernel/bpf/cpumap.c b/kernel/bpf/cpumap.c index 585b2b77ccc4..0b3e561e0c2a 100644 --- a/kernel/bpf/cpumap.c +++ b/kernel/bpf/cpumap.c @@ -397,19 +397,15 @@ static int cpu_map_kthread_run(void *data) return 0; } -static int __cpu_map_load_bpf_program(struct bpf_cpu_map_entry *rcpu, int fd) +static int __cpu_map_load_bpf_program(struct bpf_cpu_map_entry *rcpu, + struct bpf_map *map, int fd) { struct bpf_prog *prog; - prog = bpf_prog_get_type(fd, BPF_PROG_TYPE_XDP); + prog = bpf_map_get_xdp_prog(map, fd, BPF_XDP_CPUMAP); if (IS_ERR(prog)) return PTR_ERR(prog); - if (prog->expected_attach_type != BPF_XDP_CPUMAP) { - bpf_prog_put(prog); - return -EINVAL; - } - rcpu->value.bpf_prog.id = prog->aux->id; rcpu->prog = prog; @@ -457,7 +453,7 @@ __cpu_map_entry_alloc(struct bpf_map *map, struct bpf_cpumap_val *value, rcpu->map_id = map->id; rcpu->value.qsize = value->qsize; - if (fd > 0 && __cpu_map_load_bpf_program(rcpu, fd)) + if (fd > 0 && __cpu_map_load_bpf_program(rcpu, map, fd)) goto free_ptr_ring; /* Setup kthread */ diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c index f02d04540c0c..59df0745f72d 100644 --- a/kernel/bpf/devmap.c +++ b/kernel/bpf/devmap.c @@ -864,12 +864,12 @@ static struct bpf_dtab_netdev *__dev_map_alloc_node(struct net *net, goto err_out; if (val->bpf_prog.fd > 0) { - prog = bpf_prog_get_type_dev(val->bpf_prog.fd, - BPF_PROG_TYPE_XDP, false); - if (IS_ERR(prog)) - goto err_put_dev; - if (prog->expected_attach_type != BPF_XDP_DEVMAP) - goto err_put_prog; + prog = bpf_map_get_xdp_prog(&dtab->map, val->bpf_prog.fd, + BPF_XDP_DEVMAP); + if (IS_ERR(prog)) { + dev_put(dev->dev); + goto err_out; + } } dev->idx = idx; @@ -884,10 +884,6 @@ static struct bpf_dtab_netdev *__dev_map_alloc_node(struct net *net, dev->val.ifindex = val->ifindex; return dev; -err_put_prog: - bpf_prog_put(prog); -err_put_dev: - dev_put(dev->dev); err_out: kfree(dev); return ERR_PTR(-EINVAL); -- 2.31.1