Skip to content

Commit ef15314

Browse files
zhuyifei1999Alexei Starovoitov
authored and
Alexei Starovoitov
committed
bpf: Add BPF_PROG_BIND_MAP syscall
This syscall binds a map to a program. Returns success if the map is already bound to the program. Signed-off-by: YiFei Zhu <[email protected]> Signed-off-by: Stanislav Fomichev <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Acked-by: Andrii Nakryiko <[email protected]> Cc: YiFei Zhu <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent 984fe94 commit ef15314

File tree

3 files changed

+77
-0
lines changed

3 files changed

+77
-0
lines changed

include/uapi/linux/bpf.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ enum bpf_cmd {
124124
BPF_ENABLE_STATS,
125125
BPF_ITER_CREATE,
126126
BPF_LINK_DETACH,
127+
BPF_PROG_BIND_MAP,
127128
};
128129

129130
enum bpf_map_type {
@@ -658,6 +659,12 @@ union bpf_attr {
658659
__u32 flags;
659660
} iter_create;
660661

662+
struct { /* struct used by BPF_PROG_BIND_MAP command */
663+
__u32 prog_fd;
664+
__u32 map_fd;
665+
__u32 flags; /* extra flags */
666+
} prog_bind_map;
667+
661668
} __attribute__((aligned(8)));
662669

663670
/* The description below is an attempt at providing documentation to eBPF

kernel/bpf/syscall.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4161,6 +4161,66 @@ static int bpf_iter_create(union bpf_attr *attr)
41614161
return err;
41624162
}
41634163

4164+
#define BPF_PROG_BIND_MAP_LAST_FIELD prog_bind_map.flags
4165+
4166+
static int bpf_prog_bind_map(union bpf_attr *attr)
4167+
{
4168+
struct bpf_prog *prog;
4169+
struct bpf_map *map;
4170+
struct bpf_map **used_maps_old, **used_maps_new;
4171+
int i, ret = 0;
4172+
4173+
if (CHECK_ATTR(BPF_PROG_BIND_MAP))
4174+
return -EINVAL;
4175+
4176+
if (attr->prog_bind_map.flags)
4177+
return -EINVAL;
4178+
4179+
prog = bpf_prog_get(attr->prog_bind_map.prog_fd);
4180+
if (IS_ERR(prog))
4181+
return PTR_ERR(prog);
4182+
4183+
map = bpf_map_get(attr->prog_bind_map.map_fd);
4184+
if (IS_ERR(map)) {
4185+
ret = PTR_ERR(map);
4186+
goto out_prog_put;
4187+
}
4188+
4189+
mutex_lock(&prog->aux->used_maps_mutex);
4190+
4191+
used_maps_old = prog->aux->used_maps;
4192+
4193+
for (i = 0; i < prog->aux->used_map_cnt; i++)
4194+
if (used_maps_old[i] == map)
4195+
goto out_unlock;
4196+
4197+
used_maps_new = kmalloc_array(prog->aux->used_map_cnt + 1,
4198+
sizeof(used_maps_new[0]),
4199+
GFP_KERNEL);
4200+
if (!used_maps_new) {
4201+
ret = -ENOMEM;
4202+
goto out_unlock;
4203+
}
4204+
4205+
memcpy(used_maps_new, used_maps_old,
4206+
sizeof(used_maps_old[0]) * prog->aux->used_map_cnt);
4207+
used_maps_new[prog->aux->used_map_cnt] = map;
4208+
4209+
prog->aux->used_map_cnt++;
4210+
prog->aux->used_maps = used_maps_new;
4211+
4212+
kfree(used_maps_old);
4213+
4214+
out_unlock:
4215+
mutex_unlock(&prog->aux->used_maps_mutex);
4216+
4217+
if (ret)
4218+
bpf_map_put(map);
4219+
out_prog_put:
4220+
bpf_prog_put(prog);
4221+
return ret;
4222+
}
4223+
41644224
SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, size)
41654225
{
41664226
union bpf_attr attr;
@@ -4294,6 +4354,9 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, siz
42944354
case BPF_LINK_DETACH:
42954355
err = link_detach(&attr);
42964356
break;
4357+
case BPF_PROG_BIND_MAP:
4358+
err = bpf_prog_bind_map(&attr);
4359+
break;
42974360
default:
42984361
err = -EINVAL;
42994362
break;

tools/include/uapi/linux/bpf.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ enum bpf_cmd {
124124
BPF_ENABLE_STATS,
125125
BPF_ITER_CREATE,
126126
BPF_LINK_DETACH,
127+
BPF_PROG_BIND_MAP,
127128
};
128129

129130
enum bpf_map_type {
@@ -658,6 +659,12 @@ union bpf_attr {
658659
__u32 flags;
659660
} iter_create;
660661

662+
struct { /* struct used by BPF_PROG_BIND_MAP command */
663+
__u32 prog_fd;
664+
__u32 map_fd;
665+
__u32 flags; /* extra flags */
666+
} prog_bind_map;
667+
661668
} __attribute__((aligned(8)));
662669

663670
/* The description below is an attempt at providing documentation to eBPF

0 commit comments

Comments
 (0)