tools/bpftool: Move map/prog parsing logic into common
authorAndrii Nakryiko <andriin@fb.com>
Fri, 19 Jun 2020 23:16:58 +0000 (16:16 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Tue, 23 Jun 2020 00:01:48 +0000 (17:01 -0700)
Move functions that parse map and prog by id/tag/name/etc outside of
map.c/prog.c, respectively. These functions are used outside of those files
and are generic enough to be in common. This also makes heavy-weight map.c and
prog.c more decoupled from the rest of bpftool files and facilitates more
lightweight bootstrap bpftool variant.

Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Reviewed-by: Quentin Monnet <quentin@isovalent.com>
Link: https://lore.kernel.org/bpf/20200619231703.738941-5-andriin@fb.com
tools/bpf/bpftool/common.c
tools/bpf/bpftool/main.h
tools/bpf/bpftool/map.c
tools/bpf/bpftool/prog.c

index c47bdc6..6c864c3 100644 (file)
@@ -581,3 +581,311 @@ print_all_levels(__maybe_unused enum libbpf_print_level level,
 {
        return vfprintf(stderr, format, args);
 }
+
+static int prog_fd_by_nametag(void *nametag, int **fds, bool tag)
+{
+       unsigned int id = 0;
+       int fd, nb_fds = 0;
+       void *tmp;
+       int err;
+
+       while (true) {
+               struct bpf_prog_info info = {};
+               __u32 len = sizeof(info);
+
+               err = bpf_prog_get_next_id(id, &id);
+               if (err) {
+                       if (errno != ENOENT) {
+                               p_err("%s", strerror(errno));
+                               goto err_close_fds;
+                       }
+                       return nb_fds;
+               }
+
+               fd = bpf_prog_get_fd_by_id(id);
+               if (fd < 0) {
+                       p_err("can't get prog by id (%u): %s",
+                             id, strerror(errno));
+                       goto err_close_fds;
+               }
+
+               err = bpf_obj_get_info_by_fd(fd, &info, &len);
+               if (err) {
+                       p_err("can't get prog info (%u): %s",
+                             id, strerror(errno));
+                       goto err_close_fd;
+               }
+
+               if ((tag && memcmp(nametag, info.tag, BPF_TAG_SIZE)) ||
+                   (!tag && strncmp(nametag, info.name, BPF_OBJ_NAME_LEN))) {
+                       close(fd);
+                       continue;
+               }
+
+               if (nb_fds > 0) {
+                       tmp = realloc(*fds, (nb_fds + 1) * sizeof(int));
+                       if (!tmp) {
+                               p_err("failed to realloc");
+                               goto err_close_fd;
+                       }
+                       *fds = tmp;
+               }
+               (*fds)[nb_fds++] = fd;
+       }
+
+err_close_fd:
+       close(fd);
+err_close_fds:
+       while (--nb_fds >= 0)
+               close((*fds)[nb_fds]);
+       return -1;
+}
+
+int prog_parse_fds(int *argc, char ***argv, int **fds)
+{
+       if (is_prefix(**argv, "id")) {
+               unsigned int id;
+               char *endptr;
+
+               NEXT_ARGP();
+
+               id = strtoul(**argv, &endptr, 0);
+               if (*endptr) {
+                       p_err("can't parse %s as ID", **argv);
+                       return -1;
+               }
+               NEXT_ARGP();
+
+               (*fds)[0] = bpf_prog_get_fd_by_id(id);
+               if ((*fds)[0] < 0) {
+                       p_err("get by id (%u): %s", id, strerror(errno));
+                       return -1;
+               }
+               return 1;
+       } else if (is_prefix(**argv, "tag")) {
+               unsigned char tag[BPF_TAG_SIZE];
+
+               NEXT_ARGP();
+
+               if (sscanf(**argv, BPF_TAG_FMT, tag, tag + 1, tag + 2,
+                          tag + 3, tag + 4, tag + 5, tag + 6, tag + 7)
+                   != BPF_TAG_SIZE) {
+                       p_err("can't parse tag");
+                       return -1;
+               }
+               NEXT_ARGP();
+
+               return prog_fd_by_nametag(tag, fds, true);
+       } else if (is_prefix(**argv, "name")) {
+               char *name;
+
+               NEXT_ARGP();
+
+               name = **argv;
+               if (strlen(name) > BPF_OBJ_NAME_LEN - 1) {
+                       p_err("can't parse name");
+                       return -1;
+               }
+               NEXT_ARGP();
+
+               return prog_fd_by_nametag(name, fds, false);
+       } else if (is_prefix(**argv, "pinned")) {
+               char *path;
+
+               NEXT_ARGP();
+
+               path = **argv;
+               NEXT_ARGP();
+
+               (*fds)[0] = open_obj_pinned_any(path, BPF_OBJ_PROG);
+               if ((*fds)[0] < 0)
+                       return -1;
+               return 1;
+       }
+
+       p_err("expected 'id', 'tag', 'name' or 'pinned', got: '%s'?", **argv);
+       return -1;
+}
+
+int prog_parse_fd(int *argc, char ***argv)
+{
+       int *fds = NULL;
+       int nb_fds, fd;
+
+       fds = malloc(sizeof(int));
+       if (!fds) {
+               p_err("mem alloc failed");
+               return -1;
+       }
+       nb_fds = prog_parse_fds(argc, argv, &fds);
+       if (nb_fds != 1) {
+               if (nb_fds > 1) {
+                       p_err("several programs match this handle");
+                       while (nb_fds--)
+                               close(fds[nb_fds]);
+               }
+               fd = -1;
+               goto exit_free;
+       }
+
+       fd = fds[0];
+exit_free:
+       free(fds);
+       return fd;
+}
+
+static int map_fd_by_name(char *name, int **fds)
+{
+       unsigned int id = 0;
+       int fd, nb_fds = 0;
+       void *tmp;
+       int err;
+
+       while (true) {
+               struct bpf_map_info info = {};
+               __u32 len = sizeof(info);
+
+               err = bpf_map_get_next_id(id, &id);
+               if (err) {
+                       if (errno != ENOENT) {
+                               p_err("%s", strerror(errno));
+                               goto err_close_fds;
+                       }
+                       return nb_fds;
+               }
+
+               fd = bpf_map_get_fd_by_id(id);
+               if (fd < 0) {
+                       p_err("can't get map by id (%u): %s",
+                             id, strerror(errno));
+                       goto err_close_fds;
+               }
+
+               err = bpf_obj_get_info_by_fd(fd, &info, &len);
+               if (err) {
+                       p_err("can't get map info (%u): %s",
+                             id, strerror(errno));
+                       goto err_close_fd;
+               }
+
+               if (strncmp(name, info.name, BPF_OBJ_NAME_LEN)) {
+                       close(fd);
+                       continue;
+               }
+
+               if (nb_fds > 0) {
+                       tmp = realloc(*fds, (nb_fds + 1) * sizeof(int));
+                       if (!tmp) {
+                               p_err("failed to realloc");
+                               goto err_close_fd;
+                       }
+                       *fds = tmp;
+               }
+               (*fds)[nb_fds++] = fd;
+       }
+
+err_close_fd:
+       close(fd);
+err_close_fds:
+       while (--nb_fds >= 0)
+               close((*fds)[nb_fds]);
+       return -1;
+}
+
+int map_parse_fds(int *argc, char ***argv, int **fds)
+{
+       if (is_prefix(**argv, "id")) {
+               unsigned int id;
+               char *endptr;
+
+               NEXT_ARGP();
+
+               id = strtoul(**argv, &endptr, 0);
+               if (*endptr) {
+                       p_err("can't parse %s as ID", **argv);
+                       return -1;
+               }
+               NEXT_ARGP();
+
+               (*fds)[0] = bpf_map_get_fd_by_id(id);
+               if ((*fds)[0] < 0) {
+                       p_err("get map by id (%u): %s", id, strerror(errno));
+                       return -1;
+               }
+               return 1;
+       } else if (is_prefix(**argv, "name")) {
+               char *name;
+
+               NEXT_ARGP();
+
+               name = **argv;
+               if (strlen(name) > BPF_OBJ_NAME_LEN - 1) {
+                       p_err("can't parse name");
+                       return -1;
+               }
+               NEXT_ARGP();
+
+               return map_fd_by_name(name, fds);
+       } else if (is_prefix(**argv, "pinned")) {
+               char *path;
+
+               NEXT_ARGP();
+
+               path = **argv;
+               NEXT_ARGP();
+
+               (*fds)[0] = open_obj_pinned_any(path, BPF_OBJ_MAP);
+               if ((*fds)[0] < 0)
+                       return -1;
+               return 1;
+       }
+
+       p_err("expected 'id', 'name' or 'pinned', got: '%s'?", **argv);
+       return -1;
+}
+
+int map_parse_fd(int *argc, char ***argv)
+{
+       int *fds = NULL;
+       int nb_fds, fd;
+
+       fds = malloc(sizeof(int));
+       if (!fds) {
+               p_err("mem alloc failed");
+               return -1;
+       }
+       nb_fds = map_parse_fds(argc, argv, &fds);
+       if (nb_fds != 1) {
+               if (nb_fds > 1) {
+                       p_err("several maps match this handle");
+                       while (nb_fds--)
+                               close(fds[nb_fds]);
+               }
+               fd = -1;
+               goto exit_free;
+       }
+
+       fd = fds[0];
+exit_free:
+       free(fds);
+       return fd;
+}
+
+int map_parse_fd_and_info(int *argc, char ***argv, void *info, __u32 *info_len)
+{
+       int err;
+       int fd;
+
+       fd = map_parse_fd(argc, argv);
+       if (fd < 0)
+               return -1;
+
+       err = bpf_obj_get_info_by_fd(fd, info, info_len);
+       if (err) {
+               p_err("can't get map info: %s", strerror(errno));
+               close(fd);
+               return err;
+       }
+
+       return fd;
+}
index 5cdf0bc..4338ab9 100644 (file)
@@ -210,7 +210,9 @@ int do_iter(int argc, char **argv);
 
 int parse_u32_arg(int *argc, char ***argv, __u32 *val, const char *what);
 int prog_parse_fd(int *argc, char ***argv);
+int prog_parse_fds(int *argc, char ***argv, int **fds);
 int map_parse_fd(int *argc, char ***argv);
+int map_parse_fds(int *argc, char ***argv, int **fds);
 int map_parse_fd_and_info(int *argc, char ***argv, void *info, __u32 *info_len);
 
 struct bpf_prog_linfo;
index c5fac80..b9eee19 100644 (file)
@@ -92,162 +92,6 @@ static void *alloc_value(struct bpf_map_info *info)
                return malloc(info->value_size);
 }
 
-static int map_fd_by_name(char *name, int **fds)
-{
-       unsigned int id = 0;
-       int fd, nb_fds = 0;
-       void *tmp;
-       int err;
-
-       while (true) {
-               struct bpf_map_info info = {};
-               __u32 len = sizeof(info);
-
-               err = bpf_map_get_next_id(id, &id);
-               if (err) {
-                       if (errno != ENOENT) {
-                               p_err("%s", strerror(errno));
-                               goto err_close_fds;
-                       }
-                       return nb_fds;
-               }
-
-               fd = bpf_map_get_fd_by_id(id);
-               if (fd < 0) {
-                       p_err("can't get map by id (%u): %s",
-                             id, strerror(errno));
-                       goto err_close_fds;
-               }
-
-               err = bpf_obj_get_info_by_fd(fd, &info, &len);
-               if (err) {
-                       p_err("can't get map info (%u): %s",
-                             id, strerror(errno));
-                       goto err_close_fd;
-               }
-
-               if (strncmp(name, info.name, BPF_OBJ_NAME_LEN)) {
-                       close(fd);
-                       continue;
-               }
-
-               if (nb_fds > 0) {
-                       tmp = realloc(*fds, (nb_fds + 1) * sizeof(int));
-                       if (!tmp) {
-                               p_err("failed to realloc");
-                               goto err_close_fd;
-                       }
-                       *fds = tmp;
-               }
-               (*fds)[nb_fds++] = fd;
-       }
-
-err_close_fd:
-       close(fd);
-err_close_fds:
-       while (--nb_fds >= 0)
-               close((*fds)[nb_fds]);
-       return -1;
-}
-
-static int map_parse_fds(int *argc, char ***argv, int **fds)
-{
-       if (is_prefix(**argv, "id")) {
-               unsigned int id;
-               char *endptr;
-
-               NEXT_ARGP();
-
-               id = strtoul(**argv, &endptr, 0);
-               if (*endptr) {
-                       p_err("can't parse %s as ID", **argv);
-                       return -1;
-               }
-               NEXT_ARGP();
-
-               (*fds)[0] = bpf_map_get_fd_by_id(id);
-               if ((*fds)[0] < 0) {
-                       p_err("get map by id (%u): %s", id, strerror(errno));
-                       return -1;
-               }
-               return 1;
-       } else if (is_prefix(**argv, "name")) {
-               char *name;
-
-               NEXT_ARGP();
-
-               name = **argv;
-               if (strlen(name) > BPF_OBJ_NAME_LEN - 1) {
-                       p_err("can't parse name");
-                       return -1;
-               }
-               NEXT_ARGP();
-
-               return map_fd_by_name(name, fds);
-       } else if (is_prefix(**argv, "pinned")) {
-               char *path;
-
-               NEXT_ARGP();
-
-               path = **argv;
-               NEXT_ARGP();
-
-               (*fds)[0] = open_obj_pinned_any(path, BPF_OBJ_MAP);
-               if ((*fds)[0] < 0)
-                       return -1;
-               return 1;
-       }
-
-       p_err("expected 'id', 'name' or 'pinned', got: '%s'?", **argv);
-       return -1;
-}
-
-int map_parse_fd(int *argc, char ***argv)
-{
-       int *fds = NULL;
-       int nb_fds, fd;
-
-       fds = malloc(sizeof(int));
-       if (!fds) {
-               p_err("mem alloc failed");
-               return -1;
-       }
-       nb_fds = map_parse_fds(argc, argv, &fds);
-       if (nb_fds != 1) {
-               if (nb_fds > 1) {
-                       p_err("several maps match this handle");
-                       while (nb_fds--)
-                               close(fds[nb_fds]);
-               }
-               fd = -1;
-               goto exit_free;
-       }
-
-       fd = fds[0];
-exit_free:
-       free(fds);
-       return fd;
-}
-
-int map_parse_fd_and_info(int *argc, char ***argv, void *info, __u32 *info_len)
-{
-       int err;
-       int fd;
-
-       fd = map_parse_fd(argc, argv);
-       if (fd < 0)
-               return -1;
-
-       err = bpf_obj_get_info_by_fd(fd, info, info_len);
-       if (err) {
-               p_err("can't get map info: %s", strerror(errno));
-               close(fd);
-               return err;
-       }
-
-       return fd;
-}
-
 static int do_dump_btf(const struct btf_dumper *d,
                       struct bpf_map_info *map_info, void *key,
                       void *value)
index a5eff83..53d4761 100644 (file)
@@ -86,158 +86,6 @@ static void print_boot_time(__u64 nsecs, char *buf, unsigned int size)
                strftime(buf, size, "%FT%T%z", &load_tm);
 }
 
-static int prog_fd_by_nametag(void *nametag, int **fds, bool tag)
-{
-       unsigned int id = 0;
-       int fd, nb_fds = 0;
-       void *tmp;
-       int err;
-
-       while (true) {
-               struct bpf_prog_info info = {};
-               __u32 len = sizeof(info);
-
-               err = bpf_prog_get_next_id(id, &id);
-               if (err) {
-                       if (errno != ENOENT) {
-                               p_err("%s", strerror(errno));
-                               goto err_close_fds;
-                       }
-                       return nb_fds;
-               }
-
-               fd = bpf_prog_get_fd_by_id(id);
-               if (fd < 0) {
-                       p_err("can't get prog by id (%u): %s",
-                             id, strerror(errno));
-                       goto err_close_fds;
-               }
-
-               err = bpf_obj_get_info_by_fd(fd, &info, &len);
-               if (err) {
-                       p_err("can't get prog info (%u): %s",
-                             id, strerror(errno));
-                       goto err_close_fd;
-               }
-
-               if ((tag && memcmp(nametag, info.tag, BPF_TAG_SIZE)) ||
-                   (!tag && strncmp(nametag, info.name, BPF_OBJ_NAME_LEN))) {
-                       close(fd);
-                       continue;
-               }
-
-               if (nb_fds > 0) {
-                       tmp = realloc(*fds, (nb_fds + 1) * sizeof(int));
-                       if (!tmp) {
-                               p_err("failed to realloc");
-                               goto err_close_fd;
-                       }
-                       *fds = tmp;
-               }
-               (*fds)[nb_fds++] = fd;
-       }
-
-err_close_fd:
-       close(fd);
-err_close_fds:
-       while (--nb_fds >= 0)
-               close((*fds)[nb_fds]);
-       return -1;
-}
-
-static int prog_parse_fds(int *argc, char ***argv, int **fds)
-{
-       if (is_prefix(**argv, "id")) {
-               unsigned int id;
-               char *endptr;
-
-               NEXT_ARGP();
-
-               id = strtoul(**argv, &endptr, 0);
-               if (*endptr) {
-                       p_err("can't parse %s as ID", **argv);
-                       return -1;
-               }
-               NEXT_ARGP();
-
-               (*fds)[0] = bpf_prog_get_fd_by_id(id);
-               if ((*fds)[0] < 0) {
-                       p_err("get by id (%u): %s", id, strerror(errno));
-                       return -1;
-               }
-               return 1;
-       } else if (is_prefix(**argv, "tag")) {
-               unsigned char tag[BPF_TAG_SIZE];
-
-               NEXT_ARGP();
-
-               if (sscanf(**argv, BPF_TAG_FMT, tag, tag + 1, tag + 2,
-                          tag + 3, tag + 4, tag + 5, tag + 6, tag + 7)
-                   != BPF_TAG_SIZE) {
-                       p_err("can't parse tag");
-                       return -1;
-               }
-               NEXT_ARGP();
-
-               return prog_fd_by_nametag(tag, fds, true);
-       } else if (is_prefix(**argv, "name")) {
-               char *name;
-
-               NEXT_ARGP();
-
-               name = **argv;
-               if (strlen(name) > BPF_OBJ_NAME_LEN - 1) {
-                       p_err("can't parse name");
-                       return -1;
-               }
-               NEXT_ARGP();
-
-               return prog_fd_by_nametag(name, fds, false);
-       } else if (is_prefix(**argv, "pinned")) {
-               char *path;
-
-               NEXT_ARGP();
-
-               path = **argv;
-               NEXT_ARGP();
-
-               (*fds)[0] = open_obj_pinned_any(path, BPF_OBJ_PROG);
-               if ((*fds)[0] < 0)
-                       return -1;
-               return 1;
-       }
-
-       p_err("expected 'id', 'tag', 'name' or 'pinned', got: '%s'?", **argv);
-       return -1;
-}
-
-int prog_parse_fd(int *argc, char ***argv)
-{
-       int *fds = NULL;
-       int nb_fds, fd;
-
-       fds = malloc(sizeof(int));
-       if (!fds) {
-               p_err("mem alloc failed");
-               return -1;
-       }
-       nb_fds = prog_parse_fds(argc, argv, &fds);
-       if (nb_fds != 1) {
-               if (nb_fds > 1) {
-                       p_err("several programs match this handle");
-                       while (nb_fds--)
-                               close(fds[nb_fds]);
-               }
-               fd = -1;
-               goto exit_free;
-       }
-
-       fd = fds[0];
-exit_free:
-       free(fds);
-       return fd;
-}
-
 static void show_prog_maps(int fd, __u32 num_maps)
 {
        struct bpf_prog_info info = {};