Skip to content

Commit 992c422

Browse files
anakryikoborkmann
authored andcommitted
libbpf: Unify low-level map creation APIs w/ new bpf_map_create()
Mark the entire zoo of low-level map creation APIs for deprecation in libbpf 0.7 ([0]) and introduce a new bpf_map_create() API that is OPTS-based (and thus future-proof) and matches the BPF_MAP_CREATE command name. While at it, ensure that gen_loader sends map_extra field. Also remove now unneeded btf_key_type_id/btf_value_type_id logic that libbpf is doing anyways. [0] Closes: libbpf/libbpf#282 Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20211124193233.3115996-2-andrii@kernel.org
1 parent e4f7ac9 commit 992c422

File tree

7 files changed

+126
-153
lines changed

7 files changed

+126
-153
lines changed

tools/lib/bpf/bpf.c

Lines changed: 58 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -88,146 +88,122 @@ static inline int sys_bpf_prog_load(union bpf_attr *attr, unsigned int size, int
8888
return fd;
8989
}
9090

91-
int libbpf__bpf_create_map_xattr(const struct bpf_create_map_params *create_attr)
91+
int bpf_map_create(enum bpf_map_type map_type,
92+
const char *map_name,
93+
__u32 key_size,
94+
__u32 value_size,
95+
__u32 max_entries,
96+
const struct bpf_map_create_opts *opts)
9297
{
98+
const size_t attr_sz = offsetofend(union bpf_attr, map_extra);
9399
union bpf_attr attr;
94100
int fd;
95101

96-
memset(&attr, '\0', sizeof(attr));
97-
98-
attr.map_type = create_attr->map_type;
99-
attr.key_size = create_attr->key_size;
100-
attr.value_size = create_attr->value_size;
101-
attr.max_entries = create_attr->max_entries;
102-
attr.map_flags = create_attr->map_flags;
103-
if (create_attr->name)
104-
memcpy(attr.map_name, create_attr->name,
105-
min(strlen(create_attr->name), BPF_OBJ_NAME_LEN - 1));
106-
attr.numa_node = create_attr->numa_node;
107-
attr.btf_fd = create_attr->btf_fd;
108-
attr.btf_key_type_id = create_attr->btf_key_type_id;
109-
attr.btf_value_type_id = create_attr->btf_value_type_id;
110-
attr.map_ifindex = create_attr->map_ifindex;
111-
if (attr.map_type == BPF_MAP_TYPE_STRUCT_OPS)
112-
attr.btf_vmlinux_value_type_id =
113-
create_attr->btf_vmlinux_value_type_id;
114-
else
115-
attr.inner_map_fd = create_attr->inner_map_fd;
116-
attr.map_extra = create_attr->map_extra;
102+
memset(&attr, 0, attr_sz);
103+
104+
if (!OPTS_VALID(opts, bpf_map_create_opts))
105+
return libbpf_err(-EINVAL);
117106

118-
fd = sys_bpf_fd(BPF_MAP_CREATE, &attr, sizeof(attr));
107+
attr.map_type = map_type;
108+
if (map_name)
109+
strncat(attr.map_name, map_name, sizeof(attr.map_name) - 1);
110+
attr.key_size = key_size;
111+
attr.value_size = value_size;
112+
attr.max_entries = max_entries;
113+
114+
attr.btf_fd = OPTS_GET(opts, btf_fd, 0);
115+
attr.btf_key_type_id = OPTS_GET(opts, btf_key_type_id, 0);
116+
attr.btf_value_type_id = OPTS_GET(opts, btf_value_type_id, 0);
117+
attr.btf_vmlinux_value_type_id = OPTS_GET(opts, btf_vmlinux_value_type_id, 0);
118+
119+
attr.inner_map_fd = OPTS_GET(opts, inner_map_fd, 0);
120+
attr.map_flags = OPTS_GET(opts, map_flags, 0);
121+
attr.map_extra = OPTS_GET(opts, map_extra, 0);
122+
attr.numa_node = OPTS_GET(opts, numa_node, 0);
123+
attr.map_ifindex = OPTS_GET(opts, map_ifindex, 0);
124+
125+
fd = sys_bpf_fd(BPF_MAP_CREATE, &attr, attr_sz);
119126
return libbpf_err_errno(fd);
120127
}
121128

122129
int bpf_create_map_xattr(const struct bpf_create_map_attr *create_attr)
123130
{
124-
struct bpf_create_map_params p = {};
131+
LIBBPF_OPTS(bpf_map_create_opts, p);
125132

126-
p.map_type = create_attr->map_type;
127-
p.key_size = create_attr->key_size;
128-
p.value_size = create_attr->value_size;
129-
p.max_entries = create_attr->max_entries;
130133
p.map_flags = create_attr->map_flags;
131-
p.name = create_attr->name;
132134
p.numa_node = create_attr->numa_node;
133135
p.btf_fd = create_attr->btf_fd;
134136
p.btf_key_type_id = create_attr->btf_key_type_id;
135137
p.btf_value_type_id = create_attr->btf_value_type_id;
136138
p.map_ifindex = create_attr->map_ifindex;
137-
if (p.map_type == BPF_MAP_TYPE_STRUCT_OPS)
138-
p.btf_vmlinux_value_type_id =
139-
create_attr->btf_vmlinux_value_type_id;
139+
if (create_attr->map_type == BPF_MAP_TYPE_STRUCT_OPS)
140+
p.btf_vmlinux_value_type_id = create_attr->btf_vmlinux_value_type_id;
140141
else
141142
p.inner_map_fd = create_attr->inner_map_fd;
142143

143-
return libbpf__bpf_create_map_xattr(&p);
144+
return bpf_map_create(create_attr->map_type, create_attr->name,
145+
create_attr->key_size, create_attr->value_size,
146+
create_attr->max_entries, &p);
144147
}
145148

146149
int bpf_create_map_node(enum bpf_map_type map_type, const char *name,
147150
int key_size, int value_size, int max_entries,
148151
__u32 map_flags, int node)
149152
{
150-
struct bpf_create_map_attr map_attr = {};
151-
152-
map_attr.name = name;
153-
map_attr.map_type = map_type;
154-
map_attr.map_flags = map_flags;
155-
map_attr.key_size = key_size;
156-
map_attr.value_size = value_size;
157-
map_attr.max_entries = max_entries;
153+
LIBBPF_OPTS(bpf_map_create_opts, opts);
154+
155+
opts.map_flags = map_flags;
158156
if (node >= 0) {
159-
map_attr.numa_node = node;
160-
map_attr.map_flags |= BPF_F_NUMA_NODE;
157+
opts.numa_node = node;
158+
opts.map_flags |= BPF_F_NUMA_NODE;
161159
}
162160

163-
return bpf_create_map_xattr(&map_attr);
161+
return bpf_map_create(map_type, name, key_size, value_size, max_entries, &opts);
164162
}
165163

166164
int bpf_create_map(enum bpf_map_type map_type, int key_size,
167165
int value_size, int max_entries, __u32 map_flags)
168166
{
169-
struct bpf_create_map_attr map_attr = {};
170-
171-
map_attr.map_type = map_type;
172-
map_attr.map_flags = map_flags;
173-
map_attr.key_size = key_size;
174-
map_attr.value_size = value_size;
175-
map_attr.max_entries = max_entries;
167+
LIBBPF_OPTS(bpf_map_create_opts, opts, .map_flags = map_flags);
176168

177-
return bpf_create_map_xattr(&map_attr);
169+
return bpf_map_create(map_type, NULL, key_size, value_size, max_entries, &opts);
178170
}
179171

180172
int bpf_create_map_name(enum bpf_map_type map_type, const char *name,
181173
int key_size, int value_size, int max_entries,
182174
__u32 map_flags)
183175
{
184-
struct bpf_create_map_attr map_attr = {};
176+
LIBBPF_OPTS(bpf_map_create_opts, opts, .map_flags = map_flags);
185177

186-
map_attr.name = name;
187-
map_attr.map_type = map_type;
188-
map_attr.map_flags = map_flags;
189-
map_attr.key_size = key_size;
190-
map_attr.value_size = value_size;
191-
map_attr.max_entries = max_entries;
192-
193-
return bpf_create_map_xattr(&map_attr);
178+
return bpf_map_create(map_type, name, key_size, value_size, max_entries, &opts);
194179
}
195180

196181
int bpf_create_map_in_map_node(enum bpf_map_type map_type, const char *name,
197182
int key_size, int inner_map_fd, int max_entries,
198183
__u32 map_flags, int node)
199184
{
200-
union bpf_attr attr;
201-
int fd;
202-
203-
memset(&attr, '\0', sizeof(attr));
204-
205-
attr.map_type = map_type;
206-
attr.key_size = key_size;
207-
attr.value_size = 4;
208-
attr.inner_map_fd = inner_map_fd;
209-
attr.max_entries = max_entries;
210-
attr.map_flags = map_flags;
211-
if (name)
212-
memcpy(attr.map_name, name,
213-
min(strlen(name), BPF_OBJ_NAME_LEN - 1));
185+
LIBBPF_OPTS(bpf_map_create_opts, opts);
214186

187+
opts.inner_map_fd = inner_map_fd;
188+
opts.map_flags = map_flags;
215189
if (node >= 0) {
216-
attr.map_flags |= BPF_F_NUMA_NODE;
217-
attr.numa_node = node;
190+
opts.map_flags |= BPF_F_NUMA_NODE;
191+
opts.numa_node = node;
218192
}
219193

220-
fd = sys_bpf_fd(BPF_MAP_CREATE, &attr, sizeof(attr));
221-
return libbpf_err_errno(fd);
194+
return bpf_map_create(map_type, name, key_size, 4, max_entries, &opts);
222195
}
223196

224197
int bpf_create_map_in_map(enum bpf_map_type map_type, const char *name,
225198
int key_size, int inner_map_fd, int max_entries,
226199
__u32 map_flags)
227200
{
228-
return bpf_create_map_in_map_node(map_type, name, key_size,
229-
inner_map_fd, max_entries, map_flags,
230-
-1);
201+
LIBBPF_OPTS(bpf_map_create_opts, opts,
202+
.inner_map_fd = inner_map_fd,
203+
.map_flags = map_flags,
204+
);
205+
206+
return bpf_map_create(map_type, name, key_size, 4, max_entries, &opts);
231207
}
232208

233209
static void *

tools/lib/bpf/bpf.h

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,30 @@
3535
extern "C" {
3636
#endif
3737

38+
struct bpf_map_create_opts {
39+
size_t sz; /* size of this struct for forward/backward compatibility */
40+
41+
__u32 btf_fd;
42+
__u32 btf_key_type_id;
43+
__u32 btf_value_type_id;
44+
__u32 btf_vmlinux_value_type_id;
45+
46+
int inner_map_fd;
47+
int map_flags;
48+
__u64 map_extra;
49+
50+
int numa_node;
51+
int map_ifindex;
52+
};
53+
#define bpf_map_create_opts__last_field map_ifindex
54+
55+
LIBBPF_API int bpf_map_create(enum bpf_map_type map_type,
56+
const char *map_name,
57+
__u32 key_size,
58+
__u32 value_size,
59+
__u32 max_entries,
60+
const struct bpf_map_create_opts *opts);
61+
3862
struct bpf_create_map_attr {
3963
const char *name;
4064
enum bpf_map_type map_type;
@@ -53,20 +77,25 @@ struct bpf_create_map_attr {
5377
};
5478
};
5579

56-
LIBBPF_API int
57-
bpf_create_map_xattr(const struct bpf_create_map_attr *create_attr);
80+
LIBBPF_DEPRECATED_SINCE(0, 7, "use bpf_map_create() instead")
81+
LIBBPF_API int bpf_create_map_xattr(const struct bpf_create_map_attr *create_attr);
82+
LIBBPF_DEPRECATED_SINCE(0, 7, "use bpf_map_create() instead")
5883
LIBBPF_API int bpf_create_map_node(enum bpf_map_type map_type, const char *name,
5984
int key_size, int value_size,
6085
int max_entries, __u32 map_flags, int node);
86+
LIBBPF_DEPRECATED_SINCE(0, 7, "use bpf_map_create() instead")
6187
LIBBPF_API int bpf_create_map_name(enum bpf_map_type map_type, const char *name,
6288
int key_size, int value_size,
6389
int max_entries, __u32 map_flags);
90+
LIBBPF_DEPRECATED_SINCE(0, 7, "use bpf_map_create() instead")
6491
LIBBPF_API int bpf_create_map(enum bpf_map_type map_type, int key_size,
6592
int value_size, int max_entries, __u32 map_flags);
93+
LIBBPF_DEPRECATED_SINCE(0, 7, "use bpf_map_create() instead")
6694
LIBBPF_API int bpf_create_map_in_map_node(enum bpf_map_type map_type,
6795
const char *name, int key_size,
6896
int inner_map_fd, int max_entries,
6997
__u32 map_flags, int node);
98+
LIBBPF_DEPRECATED_SINCE(0, 7, "use bpf_map_create() instead")
7099
LIBBPF_API int bpf_create_map_in_map(enum bpf_map_type map_type,
71100
const char *name, int key_size,
72101
int inner_map_fd, int max_entries,

tools/lib/bpf/bpf_gen_internal.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,10 @@ void bpf_gen__init(struct bpf_gen *gen, int log_level);
5151
int bpf_gen__finish(struct bpf_gen *gen);
5252
void bpf_gen__free(struct bpf_gen *gen);
5353
void bpf_gen__load_btf(struct bpf_gen *gen, const void *raw_data, __u32 raw_size);
54-
void bpf_gen__map_create(struct bpf_gen *gen, struct bpf_create_map_params *map_attr, int map_idx);
54+
void bpf_gen__map_create(struct bpf_gen *gen,
55+
enum bpf_map_type map_type, const char *map_name,
56+
__u32 key_size, __u32 value_size, __u32 max_entries,
57+
struct bpf_map_create_opts *map_attr, int map_idx);
5558
void bpf_gen__prog_load(struct bpf_gen *gen,
5659
enum bpf_prog_type prog_type, const char *prog_name,
5760
const char *license, struct bpf_insn *insns, size_t insn_cnt,

tools/lib/bpf/gen_loader.c

Lines changed: 16 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -432,47 +432,33 @@ void bpf_gen__load_btf(struct bpf_gen *gen, const void *btf_raw_data,
432432
}
433433

434434
void bpf_gen__map_create(struct bpf_gen *gen,
435-
struct bpf_create_map_params *map_attr, int map_idx)
435+
enum bpf_map_type map_type,
436+
const char *map_name,
437+
__u32 key_size, __u32 value_size, __u32 max_entries,
438+
struct bpf_map_create_opts *map_attr, int map_idx)
436439
{
437-
int attr_size = offsetofend(union bpf_attr, btf_vmlinux_value_type_id);
440+
int attr_size = offsetofend(union bpf_attr, map_extra);
438441
bool close_inner_map_fd = false;
439442
int map_create_attr, idx;
440443
union bpf_attr attr;
441444

442445
memset(&attr, 0, attr_size);
443-
attr.map_type = map_attr->map_type;
444-
attr.key_size = map_attr->key_size;
445-
attr.value_size = map_attr->value_size;
446+
attr.map_type = map_type;
447+
attr.key_size = key_size;
448+
attr.value_size = value_size;
446449
attr.map_flags = map_attr->map_flags;
447450
attr.map_extra = map_attr->map_extra;
448-
memcpy(attr.map_name, map_attr->name,
449-
min((unsigned)strlen(map_attr->name), BPF_OBJ_NAME_LEN - 1));
451+
if (map_name)
452+
memcpy(attr.map_name, map_name,
453+
min((unsigned)strlen(map_name), BPF_OBJ_NAME_LEN - 1));
450454
attr.numa_node = map_attr->numa_node;
451455
attr.map_ifindex = map_attr->map_ifindex;
452-
attr.max_entries = map_attr->max_entries;
453-
switch (attr.map_type) {
454-
case BPF_MAP_TYPE_PERF_EVENT_ARRAY:
455-
case BPF_MAP_TYPE_CGROUP_ARRAY:
456-
case BPF_MAP_TYPE_STACK_TRACE:
457-
case BPF_MAP_TYPE_ARRAY_OF_MAPS:
458-
case BPF_MAP_TYPE_HASH_OF_MAPS:
459-
case BPF_MAP_TYPE_DEVMAP:
460-
case BPF_MAP_TYPE_DEVMAP_HASH:
461-
case BPF_MAP_TYPE_CPUMAP:
462-
case BPF_MAP_TYPE_XSKMAP:
463-
case BPF_MAP_TYPE_SOCKMAP:
464-
case BPF_MAP_TYPE_SOCKHASH:
465-
case BPF_MAP_TYPE_QUEUE:
466-
case BPF_MAP_TYPE_STACK:
467-
case BPF_MAP_TYPE_RINGBUF:
468-
break;
469-
default:
470-
attr.btf_key_type_id = map_attr->btf_key_type_id;
471-
attr.btf_value_type_id = map_attr->btf_value_type_id;
472-
}
456+
attr.max_entries = max_entries;
457+
attr.btf_key_type_id = map_attr->btf_key_type_id;
458+
attr.btf_value_type_id = map_attr->btf_value_type_id;
473459

474460
pr_debug("gen: map_create: %s idx %d type %d value_type_id %d\n",
475-
attr.map_name, map_idx, map_attr->map_type, attr.btf_value_type_id);
461+
attr.map_name, map_idx, map_type, attr.btf_value_type_id);
476462

477463
map_create_attr = add_data(gen, &attr, attr_size);
478464
if (attr.btf_value_type_id)
@@ -499,7 +485,7 @@ void bpf_gen__map_create(struct bpf_gen *gen,
499485
/* emit MAP_CREATE command */
500486
emit_sys_bpf(gen, BPF_MAP_CREATE, map_create_attr, attr_size);
501487
debug_ret(gen, "map_create %s idx %d type %d value_size %d value_btf_id %d",
502-
attr.map_name, map_idx, map_attr->map_type, attr.value_size,
488+
attr.map_name, map_idx, map_type, value_size,
503489
attr.btf_value_type_id);
504490
emit_check_err(gen);
505491
/* remember map_fd in the stack, if successful */

0 commit comments

Comments
 (0)