]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/commitdiff
bpf: bpftool, add flag to allow non-compat map definitions
authorJohn Fastabend <john.fastabend@gmail.com>
Mon, 15 Oct 2018 18:19:55 +0000 (11:19 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Mon, 15 Oct 2018 23:13:14 +0000 (16:13 -0700)
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: John Fastabend <john.fastabend@gmail.com>
Acked-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/bpf/bpftool/Documentation/bpftool.rst
tools/bpf/bpftool/bash-completion/bpftool
tools/bpf/bpftool/main.c
tools/bpf/bpftool/main.h
tools/bpf/bpftool/prog.c
tools/lib/bpf/bpf.h
tools/lib/bpf/libbpf.c
tools/lib/bpf/libbpf.h

index 25c08728ca8002598d14ec2ed326417c9400c4b2..65488317fefa54d5c79d3554efa6aa15f261020c 100644 (file)
@@ -57,6 +57,10 @@ OPTIONS
        -p, --pretty
                  Generate human-readable JSON output. Implies **-j**.
 
+       -m, --mapcompat
+                 Allow loading maps with unknown map definitions.
+
+
 SEE ALSO
 ========
        **bpftool-map**\ (8), **bpftool-prog**\ (8), **bpftool-cgroup**\ (8)
index 0826519318249cae3566df48dc67f7261463c3e6..ac85207cba8deb36d83d5d274be103e5898a3c28 100644 (file)
@@ -184,7 +184,7 @@ _bpftool()
 
     # Deal with options
     if [[ ${words[cword]} == -* ]]; then
-        local c='--version --json --pretty --bpffs'
+        local c='--version --json --pretty --bpffs --mapcompat'
         COMPREPLY=( $( compgen -W "$c" -- "$cur" ) )
         return 0
     fi
index 79dc3f1935470f9fc3bda5a4afc5e91d7fb0f5f9..828dde30e9ecd17f5fb6df5312cc96356d7e3f4c 100644 (file)
@@ -55,6 +55,7 @@ json_writer_t *json_wtr;
 bool pretty_output;
 bool json_output;
 bool show_pinned;
+int bpf_flags;
 struct pinned_obj_table prog_table;
 struct pinned_obj_table map_table;
 
@@ -341,6 +342,7 @@ int main(int argc, char **argv)
                { "pretty",     no_argument,    NULL,   'p' },
                { "version",    no_argument,    NULL,   'V' },
                { "bpffs",      no_argument,    NULL,   'f' },
+               { "mapcompat",  no_argument,    NULL,   'm' },
                { 0 }
        };
        int opt, ret;
@@ -355,7 +357,7 @@ int main(int argc, char **argv)
        hash_init(map_table.table);
 
        opterr = 0;
-       while ((opt = getopt_long(argc, argv, "Vhpjf",
+       while ((opt = getopt_long(argc, argv, "Vhpjfm",
                                  options, NULL)) >= 0) {
                switch (opt) {
                case 'V':
@@ -379,6 +381,9 @@ int main(int argc, char **argv)
                case 'f':
                        show_pinned = true;
                        break;
+               case 'm':
+                       bpf_flags = MAPS_RELAX_COMPAT;
+                       break;
                default:
                        p_err("unrecognized option '%s'", argv[optind - 1]);
                        if (json_output)
index 40492cdc4e532d47c3d0b5740437b8475d587f58..91fd697303cb31fb9a86f4c729aa6a457dd7191c 100644 (file)
@@ -74,7 +74,7 @@
 #define HELP_SPEC_PROGRAM                                              \
        "PROG := { id PROG_ID | pinned FILE | tag PROG_TAG }"
 #define HELP_SPEC_OPTIONS                                              \
-       "OPTIONS := { {-j|--json} [{-p|--pretty}] | {-f|--bpffs} }"
+       "OPTIONS := { {-j|--json} [{-p|--pretty}] | {-f|--bpffs} | {-m|--mapcompat}"
 #define HELP_SPEC_MAP                                                  \
        "MAP := { id MAP_ID | pinned FILE }"
 
@@ -89,6 +89,7 @@ extern const char *bin_name;
 extern json_writer_t *json_wtr;
 extern bool json_output;
 extern bool show_pinned;
+extern int bpf_flags;
 extern struct pinned_obj_table prog_table;
 extern struct pinned_obj_table map_table;
 
index 99ab42c56724e24efe5a9ac3ac8d50c453a0d17c..335028968dfb95b1f89ec08b3c168bd6f726b582 100644 (file)
@@ -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)) {
                p_err("failed to open object file");
                goto err_free_reuse_maps;
index 87520a87a75f1875f6dcd2607a3dba88bfd4093d..69a4d40c42273e4c45d6c8f054487fcea2c8dfac 100644 (file)
@@ -69,6 +69,9 @@ struct bpf_load_program_attr {
        __u32 prog_ifindex;
 };
 
+/* Flags to direct loading requirements */
+#define MAPS_RELAX_COMPAT      0x01
+
 /* Recommend log buffer size */
 #define BPF_LOG_BUF_SIZE (256 * 1024)
 int bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr,
index 176cf55237281cbd49b62f875347af58efab3de4..bd71efcc53bed29e8445e54102e19cb45ef5a9ef 100644 (file)
@@ -562,8 +562,9 @@ static int compare_bpf_map(const void *_a, const void *_b)
 }
 
 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;
        Elf_Scn *scn;
        Elf_Data *data;
@@ -685,7 +686,8 @@ bpf_object__init_maps(struct bpf_object *obj)
                                                   "has unrecognized, non-zero "
                                                   "options\n",
                                                   obj->path, map_name);
-                                       return -EINVAL;
+                                       if (strict)
+                                               return -EINVAL;
                                }
                        }
                        memcpy(&obj->maps[map_idx].def, def,
@@ -716,7 +718,7 @@ static bool section_have_execinstr(struct bpf_object *obj, int idx)
        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;
        GElf_Ehdr *ep = &obj->efile.ehdr;
@@ -843,7 +845,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
                return LIBBPF_ERRNO__FORMAT;
        }
        if (obj->efile.maps_shndx >= 0) {
-               err = bpf_object__init_maps(obj);
+               err = bpf_object__init_maps(obj, flags);
                if (err)
                        goto out;
        }
@@ -1515,7 +1517,7 @@ static int bpf_object__validate(struct bpf_object *obj, bool needs_kver)
 
 static struct bpf_object *
 __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;
        int err;
@@ -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__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__validate(obj, needs_kver), err, out);
 
@@ -1542,7 +1544,8 @@ out:
        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 */
        if (!attr->file)
@@ -1551,7 +1554,13 @@ struct bpf_object *bpf_object__open_xattr(struct bpf_object_open_attr *attr)
        pr_debug("loading %s\n", attr->file);
 
        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)
@@ -1584,7 +1593,7 @@ struct bpf_object *bpf_object__open_buffer(void *obj_buf,
        pr_debug("loading object '%s' from buffer\n",
                 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)
index 8af8d36639910bd625cd17eb4c29a8084e60cf8f..7e9c801a9fddbfbb51b9a1fa5989b6d974ab8d45 100644 (file)
@@ -61,6 +61,8 @@ struct bpf_object_open_attr {
 
 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,
+                                           int flags);
 struct bpf_object *bpf_object__open_buffer(void *obj_buf,
                                           size_t obj_buf_sz,
                                           const char *name);