Skip to content

Commit

Permalink
bpftool: improve skeleton backwards compat with old buggy libbpfs
Browse files Browse the repository at this point in the history
Old versions of libbpf don't handle varying sizes of bpf_map_skeleton
struct correctly. As such, BPF skeleton generated by newest bpftool
might not be compatible with older libbpf (though only when libbpf is
used as a shared library), even though it, by design, should.

Going forward libbpf will be fixed, plus we'll release bug fixed
versions of relevant old libbpfs, but meanwhile try to mitigate from
bpftool side by conservatively assuming older and smaller definition of
bpf_map_skeleton, if possible. Meaning, if there are no struct_ops maps.

If there are struct_ops, then presumably user would like to have
auto-attaching logic and struct_ops map link placeholders, so use the
full bpf_map_skeleton definition in that case.

Acked-by: Quentin Monnet <qmo@kernel.org>
Co-developed-by: Mykyta Yatsenko <yatsenko@meta.com>
Signed-off-by: Mykyta Yatsenko <yatsenko@meta.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20240708204540.4188946-2-andrii@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
  • Loading branch information
anakryiko authored and qmonnet committed Jul 16, 2024
1 parent 6bcdeb8 commit 1b935a7
Showing 1 changed file with 32 additions and 14 deletions.
46 changes: 32 additions & 14 deletions src/gen.c
Original file line number Diff line number Diff line change
Expand Up @@ -852,24 +852,41 @@ codegen_maps_skeleton(struct bpf_object *obj, size_t map_cnt, bool mmaped, bool
{
struct bpf_map *map;
char ident[256];
size_t i;
size_t i, map_sz;

if (!map_cnt)
return;

/* for backward compatibility with old libbpf versions that don't
* handle new BPF skeleton with new struct bpf_map_skeleton definition
* that includes link field, avoid specifying new increased size,
* unless we absolutely have to (i.e., if there are struct_ops maps
* present)
*/
map_sz = offsetof(struct bpf_map_skeleton, link);
if (populate_links) {
bpf_object__for_each_map(map, obj) {
if (bpf_map__type(map) == BPF_MAP_TYPE_STRUCT_OPS) {
map_sz = sizeof(struct bpf_map_skeleton);
break;
}
}
}

codegen("\
\n\
\n\
\n\
/* maps */ \n\
s->map_cnt = %zu; \n\
s->map_skel_sz = sizeof(*s->maps); \n\
s->maps = (struct bpf_map_skeleton *)calloc(s->map_cnt, s->map_skel_sz);\n\
s->map_skel_sz = %zu; \n\
s->maps = (struct bpf_map_skeleton *)calloc(s->map_cnt,\n\
sizeof(*s->maps) > %zu ? sizeof(*s->maps) : %zu);\n\
if (!s->maps) { \n\
err = -ENOMEM; \n\
goto err; \n\
} \n\
",
map_cnt
map_cnt, map_sz, map_sz, map_sz
);
i = 0;
bpf_object__for_each_map(map, obj) {
Expand All @@ -878,23 +895,22 @@ codegen_maps_skeleton(struct bpf_object *obj, size_t map_cnt, bool mmaped, bool

codegen("\
\n\
\n\
s->maps[%zu].name = \"%s\"; \n\
s->maps[%zu].map = &obj->maps.%s; \n\
\n\
map = (struct bpf_map_skeleton *)((char *)s->maps + %zu * s->map_skel_sz);\n\
map->name = \"%s\"; \n\
map->map = &obj->maps.%s; \n\
",
i, bpf_map__name(map), i, ident);
i, bpf_map__name(map), ident);
/* memory-mapped internal maps */
if (mmaped && is_mmapable_map(map, ident, sizeof(ident))) {
printf("\ts->maps[%zu].mmaped = (void **)&obj->%s;\n",
i, ident);
printf("\tmap->mmaped = (void **)&obj->%s;\n", ident);
}

if (populate_links && bpf_map__type(map) == BPF_MAP_TYPE_STRUCT_OPS) {
codegen("\
\n\
s->maps[%zu].link = &obj->links.%s;\n\
",
i, ident);
map->link = &obj->links.%s; \n\
", ident);
}
i++;
}
Expand Down Expand Up @@ -1463,6 +1479,7 @@ static int do_skeleton(int argc, char **argv)
%1$s__create_skeleton(struct %1$s *obj) \n\
{ \n\
struct bpf_object_skeleton *s; \n\
struct bpf_map_skeleton *map __attribute__((unused));\n\
int err; \n\
\n\
s = (struct bpf_object_skeleton *)calloc(1, sizeof(*s));\n\
Expand Down Expand Up @@ -1753,6 +1770,7 @@ static int do_subskeleton(int argc, char **argv)
{ \n\
struct %1$s *obj; \n\
struct bpf_object_subskeleton *s; \n\
struct bpf_map_skeleton *map __attribute__((unused));\n\
int err; \n\
\n\
obj = (struct %1$s *)calloc(1, sizeof(*obj)); \n\
Expand Down

0 comments on commit 1b935a7

Please sign in to comment.