Commit c034a177 authored by John Fastabend's avatar John Fastabend Committed by Alexei Starovoitov

bpf: bpftool, add flag to allow non-compat map definitions

Multiple map definition structures exist and user may have non-zero
fields in their definition that are not recognized by bpftool and
libbpf. The normal behavior is to then fail loading the map. Although
this is a good default behavior users may still want to load the map
for debugging or other reasons. This patch adds a --mapcompat flag
that can be used to override the default behavior and allow loading
the map even when it has additional non-zero fields.

For now the only user is 'bpftool prog' we can switch over other
subcommands as needed. The library exposes an API that consumes
a flags field now but I kept the original API around also in case
users of the API don't want to expose this. The flags field is an
int in case we need more control over how the API call handles
errors/features/etc in the future.
Signed-off-by: default avatarJohn Fastabend <john.fastabend@gmail.com>
Acked-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent b7d3826c
...@@ -57,6 +57,10 @@ OPTIONS ...@@ -57,6 +57,10 @@ OPTIONS
-p, --pretty -p, --pretty
Generate human-readable JSON output. Implies **-j**. Generate human-readable JSON output. Implies **-j**.
-m, --mapcompat
Allow loading maps with unknown map definitions.
SEE ALSO SEE ALSO
======== ========
**bpftool-map**\ (8), **bpftool-prog**\ (8), **bpftool-cgroup**\ (8) **bpftool-map**\ (8), **bpftool-prog**\ (8), **bpftool-cgroup**\ (8)
......
...@@ -184,7 +184,7 @@ _bpftool() ...@@ -184,7 +184,7 @@ _bpftool()
# Deal with options # Deal with options
if [[ ${words[cword]} == -* ]]; then if [[ ${words[cword]} == -* ]]; then
local c='--version --json --pretty --bpffs' local c='--version --json --pretty --bpffs --mapcompat'
COMPREPLY=( $( compgen -W "$c" -- "$cur" ) ) COMPREPLY=( $( compgen -W "$c" -- "$cur" ) )
return 0 return 0
fi fi
......
...@@ -55,6 +55,7 @@ json_writer_t *json_wtr; ...@@ -55,6 +55,7 @@ json_writer_t *json_wtr;
bool pretty_output; bool pretty_output;
bool json_output; bool json_output;
bool show_pinned; bool show_pinned;
int bpf_flags;
struct pinned_obj_table prog_table; struct pinned_obj_table prog_table;
struct pinned_obj_table map_table; struct pinned_obj_table map_table;
...@@ -341,6 +342,7 @@ int main(int argc, char **argv) ...@@ -341,6 +342,7 @@ int main(int argc, char **argv)
{ "pretty", no_argument, NULL, 'p' }, { "pretty", no_argument, NULL, 'p' },
{ "version", no_argument, NULL, 'V' }, { "version", no_argument, NULL, 'V' },
{ "bpffs", no_argument, NULL, 'f' }, { "bpffs", no_argument, NULL, 'f' },
{ "mapcompat", no_argument, NULL, 'm' },
{ 0 } { 0 }
}; };
int opt, ret; int opt, ret;
...@@ -355,7 +357,7 @@ int main(int argc, char **argv) ...@@ -355,7 +357,7 @@ int main(int argc, char **argv)
hash_init(map_table.table); hash_init(map_table.table);
opterr = 0; opterr = 0;
while ((opt = getopt_long(argc, argv, "Vhpjf", while ((opt = getopt_long(argc, argv, "Vhpjfm",
options, NULL)) >= 0) { options, NULL)) >= 0) {
switch (opt) { switch (opt) {
case 'V': case 'V':
...@@ -379,6 +381,9 @@ int main(int argc, char **argv) ...@@ -379,6 +381,9 @@ int main(int argc, char **argv)
case 'f': case 'f':
show_pinned = true; show_pinned = true;
break; break;
case 'm':
bpf_flags = MAPS_RELAX_COMPAT;
break;
default: default:
p_err("unrecognized option '%s'", argv[optind - 1]); p_err("unrecognized option '%s'", argv[optind - 1]);
if (json_output) if (json_output)
......
...@@ -74,7 +74,7 @@ ...@@ -74,7 +74,7 @@
#define HELP_SPEC_PROGRAM \ #define HELP_SPEC_PROGRAM \
"PROG := { id PROG_ID | pinned FILE | tag PROG_TAG }" "PROG := { id PROG_ID | pinned FILE | tag PROG_TAG }"
#define HELP_SPEC_OPTIONS \ #define HELP_SPEC_OPTIONS \
"OPTIONS := { {-j|--json} [{-p|--pretty}] | {-f|--bpffs} }" "OPTIONS := { {-j|--json} [{-p|--pretty}] | {-f|--bpffs} | {-m|--mapcompat}"
#define HELP_SPEC_MAP \ #define HELP_SPEC_MAP \
"MAP := { id MAP_ID | pinned FILE }" "MAP := { id MAP_ID | pinned FILE }"
...@@ -89,6 +89,7 @@ extern const char *bin_name; ...@@ -89,6 +89,7 @@ extern const char *bin_name;
extern json_writer_t *json_wtr; extern json_writer_t *json_wtr;
extern bool json_output; extern bool json_output;
extern bool show_pinned; extern bool show_pinned;
extern int bpf_flags;
extern struct pinned_obj_table prog_table; extern struct pinned_obj_table prog_table;
extern struct pinned_obj_table map_table; extern struct pinned_obj_table map_table;
......
...@@ -908,7 +908,7 @@ static int do_load(int argc, char **argv) ...@@ -908,7 +908,7 @@ static int do_load(int argc, char **argv)
} }
} }
obj = bpf_object__open_xattr(&attr); obj = __bpf_object__open_xattr(&attr, bpf_flags);
if (IS_ERR_OR_NULL(obj)) { if (IS_ERR_OR_NULL(obj)) {
p_err("failed to open object file"); p_err("failed to open object file");
goto err_free_reuse_maps; goto err_free_reuse_maps;
......
...@@ -69,6 +69,9 @@ struct bpf_load_program_attr { ...@@ -69,6 +69,9 @@ struct bpf_load_program_attr {
__u32 prog_ifindex; __u32 prog_ifindex;
}; };
/* Flags to direct loading requirements */
#define MAPS_RELAX_COMPAT 0x01
/* Recommend log buffer size */ /* Recommend log buffer size */
#define BPF_LOG_BUF_SIZE (256 * 1024) #define BPF_LOG_BUF_SIZE (256 * 1024)
int bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr, int bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr,
......
...@@ -562,8 +562,9 @@ static int compare_bpf_map(const void *_a, const void *_b) ...@@ -562,8 +562,9 @@ static int compare_bpf_map(const void *_a, const void *_b)
} }
static int static int
bpf_object__init_maps(struct bpf_object *obj) bpf_object__init_maps(struct bpf_object *obj, int flags)
{ {
bool strict = !(flags & MAPS_RELAX_COMPAT);
int i, map_idx, map_def_sz, nr_maps = 0; int i, map_idx, map_def_sz, nr_maps = 0;
Elf_Scn *scn; Elf_Scn *scn;
Elf_Data *data; Elf_Data *data;
...@@ -685,7 +686,8 @@ bpf_object__init_maps(struct bpf_object *obj) ...@@ -685,7 +686,8 @@ bpf_object__init_maps(struct bpf_object *obj)
"has unrecognized, non-zero " "has unrecognized, non-zero "
"options\n", "options\n",
obj->path, map_name); obj->path, map_name);
return -EINVAL; if (strict)
return -EINVAL;
} }
} }
memcpy(&obj->maps[map_idx].def, def, memcpy(&obj->maps[map_idx].def, def,
...@@ -716,7 +718,7 @@ static bool section_have_execinstr(struct bpf_object *obj, int idx) ...@@ -716,7 +718,7 @@ static bool section_have_execinstr(struct bpf_object *obj, int idx)
return false; return false;
} }
static int bpf_object__elf_collect(struct bpf_object *obj) static int bpf_object__elf_collect(struct bpf_object *obj, int flags)
{ {
Elf *elf = obj->efile.elf; Elf *elf = obj->efile.elf;
GElf_Ehdr *ep = &obj->efile.ehdr; GElf_Ehdr *ep = &obj->efile.ehdr;
...@@ -843,7 +845,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj) ...@@ -843,7 +845,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
return LIBBPF_ERRNO__FORMAT; return LIBBPF_ERRNO__FORMAT;
} }
if (obj->efile.maps_shndx >= 0) { if (obj->efile.maps_shndx >= 0) {
err = bpf_object__init_maps(obj); err = bpf_object__init_maps(obj, flags);
if (err) if (err)
goto out; goto out;
} }
...@@ -1515,7 +1517,7 @@ static int bpf_object__validate(struct bpf_object *obj, bool needs_kver) ...@@ -1515,7 +1517,7 @@ static int bpf_object__validate(struct bpf_object *obj, bool needs_kver)
static struct bpf_object * static struct bpf_object *
__bpf_object__open(const char *path, void *obj_buf, size_t obj_buf_sz, __bpf_object__open(const char *path, void *obj_buf, size_t obj_buf_sz,
bool needs_kver) bool needs_kver, int flags)
{ {
struct bpf_object *obj; struct bpf_object *obj;
int err; int err;
...@@ -1531,7 +1533,7 @@ __bpf_object__open(const char *path, void *obj_buf, size_t obj_buf_sz, ...@@ -1531,7 +1533,7 @@ __bpf_object__open(const char *path, void *obj_buf, size_t obj_buf_sz,
CHECK_ERR(bpf_object__elf_init(obj), err, out); CHECK_ERR(bpf_object__elf_init(obj), err, out);
CHECK_ERR(bpf_object__check_endianness(obj), err, out); CHECK_ERR(bpf_object__check_endianness(obj), err, out);
CHECK_ERR(bpf_object__elf_collect(obj), err, out); CHECK_ERR(bpf_object__elf_collect(obj, flags), err, out);
CHECK_ERR(bpf_object__collect_reloc(obj), err, out); CHECK_ERR(bpf_object__collect_reloc(obj), err, out);
CHECK_ERR(bpf_object__validate(obj, needs_kver), err, out); CHECK_ERR(bpf_object__validate(obj, needs_kver), err, out);
...@@ -1542,7 +1544,8 @@ __bpf_object__open(const char *path, void *obj_buf, size_t obj_buf_sz, ...@@ -1542,7 +1544,8 @@ __bpf_object__open(const char *path, void *obj_buf, size_t obj_buf_sz,
return ERR_PTR(err); return ERR_PTR(err);
} }
struct bpf_object *bpf_object__open_xattr(struct bpf_object_open_attr *attr) struct bpf_object *__bpf_object__open_xattr(struct bpf_object_open_attr *attr,
int flags)
{ {
/* param validation */ /* param validation */
if (!attr->file) if (!attr->file)
...@@ -1551,7 +1554,13 @@ struct bpf_object *bpf_object__open_xattr(struct bpf_object_open_attr *attr) ...@@ -1551,7 +1554,13 @@ struct bpf_object *bpf_object__open_xattr(struct bpf_object_open_attr *attr)
pr_debug("loading %s\n", attr->file); pr_debug("loading %s\n", attr->file);
return __bpf_object__open(attr->file, NULL, 0, return __bpf_object__open(attr->file, NULL, 0,
bpf_prog_type__needs_kver(attr->prog_type)); bpf_prog_type__needs_kver(attr->prog_type),
flags);
}
struct bpf_object *bpf_object__open_xattr(struct bpf_object_open_attr *attr)
{
return __bpf_object__open_xattr(attr, 0);
} }
struct bpf_object *bpf_object__open(const char *path) struct bpf_object *bpf_object__open(const char *path)
...@@ -1584,7 +1593,7 @@ struct bpf_object *bpf_object__open_buffer(void *obj_buf, ...@@ -1584,7 +1593,7 @@ struct bpf_object *bpf_object__open_buffer(void *obj_buf,
pr_debug("loading object '%s' from buffer\n", pr_debug("loading object '%s' from buffer\n",
name); name);
return __bpf_object__open(name, obj_buf, obj_buf_sz, true); return __bpf_object__open(name, obj_buf, obj_buf_sz, true, true);
} }
int bpf_object__unload(struct bpf_object *obj) int bpf_object__unload(struct bpf_object *obj)
......
...@@ -61,6 +61,8 @@ struct bpf_object_open_attr { ...@@ -61,6 +61,8 @@ struct bpf_object_open_attr {
struct bpf_object *bpf_object__open(const char *path); struct bpf_object *bpf_object__open(const char *path);
struct bpf_object *bpf_object__open_xattr(struct bpf_object_open_attr *attr); struct bpf_object *bpf_object__open_xattr(struct bpf_object_open_attr *attr);
struct bpf_object *__bpf_object__open_xattr(struct bpf_object_open_attr *attr,
int flags);
struct bpf_object *bpf_object__open_buffer(void *obj_buf, struct bpf_object *bpf_object__open_buffer(void *obj_buf,
size_t obj_buf_sz, size_t obj_buf_sz,
const char *name); const char *name);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment