bpftool: Use libbpf_bpf_prog_type_str
authorDaniel Müller <deso@posteo.net>
Mon, 23 May 2022 23:04:19 +0000 (23:04 +0000)
committerAndrii Nakryiko <andrii@kernel.org>
Thu, 2 Jun 2022 23:26:18 +0000 (16:26 -0700)
This change switches bpftool over to using the recently introduced
libbpf_bpf_prog_type_str function instead of maintaining its own string
representation for the bpf_prog_type enum.

Signed-off-by: Daniel Müller <deso@posteo.net>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Yonghong Song <yhs@fb.com>
Acked-by: Quentin Monnet <quentin@isovalent.com>
Link: https://lore.kernel.org/bpf/20220523230428.3077108-4-deso@posteo.net
tools/bpf/bpftool/feature.c
tools/bpf/bpftool/link.c
tools/bpf/bpftool/main.h
tools/bpf/bpftool/map.c
tools/bpf/bpftool/prog.c
tools/testing/selftests/bpf/test_bpftool_synctypes.py

index d12f460..02753f9 100644 (file)
@@ -548,8 +548,8 @@ static bool probe_prog_type_ifindex(enum bpf_prog_type prog_type, __u32 ifindex)
 }
 
 static void
-probe_prog_type(enum bpf_prog_type prog_type, bool *supported_types,
-               const char *define_prefix, __u32 ifindex)
+probe_prog_type(enum bpf_prog_type prog_type, const char *prog_type_str,
+               bool *supported_types, const char *define_prefix, __u32 ifindex)
 {
        char feat_name[128], plain_desc[128], define_name[128];
        const char *plain_comment = "eBPF program_type ";
@@ -580,20 +580,16 @@ probe_prog_type(enum bpf_prog_type prog_type, bool *supported_types,
 
        supported_types[prog_type] |= res;
 
-       if (!prog_type_name[prog_type]) {
-               p_info("program type name not found (type %d)", prog_type);
-               return;
-       }
        maxlen = sizeof(plain_desc) - strlen(plain_comment) - 1;
-       if (strlen(prog_type_name[prog_type]) > maxlen) {
+       if (strlen(prog_type_str) > maxlen) {
                p_info("program type name too long");
                return;
        }
 
-       sprintf(feat_name, "have_%s_prog_type", prog_type_name[prog_type]);
-       sprintf(define_name, "%s_prog_type", prog_type_name[prog_type]);
+       sprintf(feat_name, "have_%s_prog_type", prog_type_str);
+       sprintf(define_name, "%s_prog_type", prog_type_str);
        uppercase(define_name, sizeof(define_name));
-       sprintf(plain_desc, "%s%s", plain_comment, prog_type_name[prog_type]);
+       sprintf(plain_desc, "%s%s", plain_comment, prog_type_str);
        print_bool_feature(feat_name, plain_desc, define_name, res,
                           define_prefix);
 }
@@ -728,10 +724,10 @@ probe_helper_for_progtype(enum bpf_prog_type prog_type, bool supported_type,
 }
 
 static void
-probe_helpers_for_progtype(enum bpf_prog_type prog_type, bool supported_type,
+probe_helpers_for_progtype(enum bpf_prog_type prog_type,
+                          const char *prog_type_str, bool supported_type,
                           const char *define_prefix, __u32 ifindex)
 {
-       const char *ptype_name = prog_type_name[prog_type];
        char feat_name[128];
        unsigned int id;
        bool probe_res = false;
@@ -747,12 +743,12 @@ probe_helpers_for_progtype(enum bpf_prog_type prog_type, bool supported_type,
                }
 
        if (json_output) {
-               sprintf(feat_name, "%s_available_helpers", ptype_name);
+               sprintf(feat_name, "%s_available_helpers", prog_type_str);
                jsonw_name(json_wtr, feat_name);
                jsonw_start_array(json_wtr);
        } else if (!define_prefix) {
                printf("eBPF helpers supported for program type %s:",
-                      ptype_name);
+                      prog_type_str);
        }
 
        for (id = 1; id < ARRAY_SIZE(helper_name); id++) {
@@ -768,7 +764,7 @@ probe_helpers_for_progtype(enum bpf_prog_type prog_type, bool supported_type,
                        /* fallthrough */
                default:
                        probe_res |= probe_helper_for_progtype(prog_type, supported_type,
-                                                 define_prefix, id, ptype_name,
+                                                 define_prefix, id, prog_type_str,
                                                  ifindex);
                }
        }
@@ -943,15 +939,24 @@ static void
 section_program_types(bool *supported_types, const char *define_prefix,
                      __u32 ifindex)
 {
-       unsigned int i;
+       unsigned int prog_type = BPF_PROG_TYPE_UNSPEC;
+       const char *prog_type_str;
 
        print_start_section("program_types",
                            "Scanning eBPF program types...",
                            "/*** eBPF program types ***/",
                            define_prefix);
 
-       for (i = BPF_PROG_TYPE_UNSPEC + 1; i < prog_type_name_size; i++)
-               probe_prog_type(i, supported_types, define_prefix, ifindex);
+       while (true) {
+               prog_type++;
+               prog_type_str = libbpf_bpf_prog_type_str(prog_type);
+               /* libbpf will return NULL for variants unknown to it. */
+               if (!prog_type_str)
+                       break;
+
+               probe_prog_type(prog_type, prog_type_str, supported_types, define_prefix,
+                               ifindex);
+       }
 
        print_end_section();
 }
@@ -974,7 +979,8 @@ static void section_map_types(const char *define_prefix, __u32 ifindex)
 static void
 section_helpers(bool *supported_types, const char *define_prefix, __u32 ifindex)
 {
-       unsigned int i;
+       unsigned int prog_type = BPF_PROG_TYPE_UNSPEC;
+       const char *prog_type_str;
 
        print_start_section("helpers",
                            "Scanning eBPF helper functions...",
@@ -996,9 +1002,18 @@ section_helpers(bool *supported_types, const char *define_prefix, __u32 ifindex)
                       "        %sBPF__PROG_TYPE_ ## prog_type ## __HELPER_ ## helper\n",
                       define_prefix, define_prefix, define_prefix,
                       define_prefix);
-       for (i = BPF_PROG_TYPE_UNSPEC + 1; i < prog_type_name_size; i++)
-               probe_helpers_for_progtype(i, supported_types[i], define_prefix,
+       while (true) {
+               prog_type++;
+               prog_type_str = libbpf_bpf_prog_type_str(prog_type);
+               /* libbpf will return NULL for variants unknown to it. */
+               if (!prog_type_str)
+                       break;
+
+               probe_helpers_for_progtype(prog_type, prog_type_str,
+                                          supported_types[prog_type],
+                                          define_prefix,
                                           ifindex);
+       }
 
        print_end_section();
 }
index 6353a78..e271084 100644 (file)
@@ -121,6 +121,7 @@ static int get_prog_info(int prog_id, struct bpf_prog_info *info)
 static int show_link_close_json(int fd, struct bpf_link_info *info)
 {
        struct bpf_prog_info prog_info;
+       const char *prog_type_str;
        int err;
 
        jsonw_start_object(json_wtr);
@@ -137,12 +138,12 @@ static int show_link_close_json(int fd, struct bpf_link_info *info)
                if (err)
                        return err;
 
-               if (prog_info.type < prog_type_name_size)
-                       jsonw_string_field(json_wtr, "prog_type",
-                                          prog_type_name[prog_info.type]);
+               prog_type_str = libbpf_bpf_prog_type_str(prog_info.type);
+               /* libbpf will return NULL for variants unknown to it. */
+               if (prog_type_str)
+                       jsonw_string_field(json_wtr, "prog_type", prog_type_str);
                else
-                       jsonw_uint_field(json_wtr, "prog_type",
-                                        prog_info.type);
+                       jsonw_uint_field(json_wtr, "prog_type", prog_info.type);
 
                show_link_attach_type_json(info->tracing.attach_type,
                                           json_wtr);
@@ -214,6 +215,7 @@ static void show_iter_plain(struct bpf_link_info *info)
 static int show_link_close_plain(int fd, struct bpf_link_info *info)
 {
        struct bpf_prog_info prog_info;
+       const char *prog_type_str;
        int err;
 
        show_link_header_plain(info);
@@ -228,9 +230,10 @@ static int show_link_close_plain(int fd, struct bpf_link_info *info)
                if (err)
                        return err;
 
-               if (prog_info.type < prog_type_name_size)
-                       printf("\n\tprog_type %s  ",
-                              prog_type_name[prog_info.type]);
+               prog_type_str = libbpf_bpf_prog_type_str(prog_info.type);
+               /* libbpf will return NULL for variants unknown to it. */
+               if (prog_type_str)
+                       printf("\n\tprog_type %s  ", prog_type_str);
                else
                        printf("\n\tprog_type %u  ", prog_info.type);
 
index aa99ffa..74204d0 100644 (file)
@@ -63,9 +63,6 @@ static inline void *u64_to_ptr(__u64 ptr)
 #define HELP_SPEC_LINK                                                 \
        "LINK := { id LINK_ID | pinned FILE }"
 
-extern const char * const prog_type_name[];
-extern const size_t prog_type_name_size;
-
 extern const char * const attach_type_name[__MAX_BPF_ATTACH_TYPE];
 
 extern const char * const map_type_name[];
index 877387e..70a1fd5 100644 (file)
@@ -513,10 +513,12 @@ static int show_map_close_json(int fd, struct bpf_map_info *info)
 
                if (owner_prog_type) {
                        unsigned int prog_type = atoi(owner_prog_type);
+                       const char *prog_type_str;
 
-                       if (prog_type < prog_type_name_size)
+                       prog_type_str = libbpf_bpf_prog_type_str(prog_type);
+                       if (prog_type_str)
                                jsonw_string_field(json_wtr, "owner_prog_type",
-                                                  prog_type_name[prog_type]);
+                                                  prog_type_str);
                        else
                                jsonw_uint_field(json_wtr, "owner_prog_type",
                                                 prog_type);
@@ -597,10 +599,11 @@ static int show_map_close_plain(int fd, struct bpf_map_info *info)
                        printf("\n\t");
                if (owner_prog_type) {
                        unsigned int prog_type = atoi(owner_prog_type);
+                       const char *prog_type_str;
 
-                       if (prog_type < prog_type_name_size)
-                               printf("owner_prog_type %s  ",
-                                      prog_type_name[prog_type]);
+                       prog_type_str = libbpf_bpf_prog_type_str(prog_type);
+                       if (prog_type_str)
+                               printf("owner_prog_type %s  ", prog_type_str);
                        else
                                printf("owner_prog_type %d  ", prog_type);
                }
index 5c2c63d..39e1e71 100644 (file)
 #define BPF_METADATA_PREFIX "bpf_metadata_"
 #define BPF_METADATA_PREFIX_LEN (sizeof(BPF_METADATA_PREFIX) - 1)
 
-const char * const prog_type_name[] = {
-       [BPF_PROG_TYPE_UNSPEC]                  = "unspec",
-       [BPF_PROG_TYPE_SOCKET_FILTER]           = "socket_filter",
-       [BPF_PROG_TYPE_KPROBE]                  = "kprobe",
-       [BPF_PROG_TYPE_SCHED_CLS]               = "sched_cls",
-       [BPF_PROG_TYPE_SCHED_ACT]               = "sched_act",
-       [BPF_PROG_TYPE_TRACEPOINT]              = "tracepoint",
-       [BPF_PROG_TYPE_XDP]                     = "xdp",
-       [BPF_PROG_TYPE_PERF_EVENT]              = "perf_event",
-       [BPF_PROG_TYPE_CGROUP_SKB]              = "cgroup_skb",
-       [BPF_PROG_TYPE_CGROUP_SOCK]             = "cgroup_sock",
-       [BPF_PROG_TYPE_LWT_IN]                  = "lwt_in",
-       [BPF_PROG_TYPE_LWT_OUT]                 = "lwt_out",
-       [BPF_PROG_TYPE_LWT_XMIT]                = "lwt_xmit",
-       [BPF_PROG_TYPE_SOCK_OPS]                = "sock_ops",
-       [BPF_PROG_TYPE_SK_SKB]                  = "sk_skb",
-       [BPF_PROG_TYPE_CGROUP_DEVICE]           = "cgroup_device",
-       [BPF_PROG_TYPE_SK_MSG]                  = "sk_msg",
-       [BPF_PROG_TYPE_RAW_TRACEPOINT]          = "raw_tracepoint",
-       [BPF_PROG_TYPE_CGROUP_SOCK_ADDR]        = "cgroup_sock_addr",
-       [BPF_PROG_TYPE_LWT_SEG6LOCAL]           = "lwt_seg6local",
-       [BPF_PROG_TYPE_LIRC_MODE2]              = "lirc_mode2",
-       [BPF_PROG_TYPE_SK_REUSEPORT]            = "sk_reuseport",
-       [BPF_PROG_TYPE_FLOW_DISSECTOR]          = "flow_dissector",
-       [BPF_PROG_TYPE_CGROUP_SYSCTL]           = "cgroup_sysctl",
-       [BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE] = "raw_tracepoint_writable",
-       [BPF_PROG_TYPE_CGROUP_SOCKOPT]          = "cgroup_sockopt",
-       [BPF_PROG_TYPE_TRACING]                 = "tracing",
-       [BPF_PROG_TYPE_STRUCT_OPS]              = "struct_ops",
-       [BPF_PROG_TYPE_EXT]                     = "ext",
-       [BPF_PROG_TYPE_LSM]                     = "lsm",
-       [BPF_PROG_TYPE_SK_LOOKUP]               = "sk_lookup",
-       [BPF_PROG_TYPE_SYSCALL]                 = "syscall",
-};
-
-const size_t prog_type_name_size = ARRAY_SIZE(prog_type_name);
-
 enum dump_mode {
        DUMP_JITED,
        DUMP_XLATED,
@@ -428,12 +391,14 @@ out_free:
 
 static void print_prog_header_json(struct bpf_prog_info *info, int fd)
 {
+       const char *prog_type_str;
        char prog_name[MAX_PROG_FULL_NAME];
 
        jsonw_uint_field(json_wtr, "id", info->id);
-       if (info->type < ARRAY_SIZE(prog_type_name))
-               jsonw_string_field(json_wtr, "type",
-                                  prog_type_name[info->type]);
+       prog_type_str = libbpf_bpf_prog_type_str(info->type);
+
+       if (prog_type_str)
+               jsonw_string_field(json_wtr, "type", prog_type_str);
        else
                jsonw_uint_field(json_wtr, "type", info->type);
 
@@ -515,11 +480,13 @@ static void print_prog_json(struct bpf_prog_info *info, int fd)
 
 static void print_prog_header_plain(struct bpf_prog_info *info, int fd)
 {
+       const char *prog_type_str;
        char prog_name[MAX_PROG_FULL_NAME];
 
        printf("%u: ", info->id);
-       if (info->type < ARRAY_SIZE(prog_type_name))
-               printf("%s  ", prog_type_name[info->type]);
+       prog_type_str = libbpf_bpf_prog_type_str(info->type);
+       if (prog_type_str)
+               printf("%s  ", prog_type_str);
        else
                printf("type %u  ", info->type);
 
index c0e7acd..1f0ff78 100755 (executable)
@@ -333,9 +333,6 @@ class ProgFileExtractor(SourceFileExtractor):
     """
     filename = os.path.join(BPFTOOL_DIR, 'prog.c')
 
-    def get_prog_types(self):
-        return self.get_types_from_array('prog_type_name')
-
     def get_attach_types(self):
         return self.get_types_from_array('attach_type_strings')
 
@@ -533,16 +530,6 @@ def main():
     verify(source_map_types, bashcomp_map_types,
             f'Comparing {MapFileExtractor.filename} (map_type_name) and {BashcompExtractor.filename} (BPFTOOL_MAP_CREATE_TYPES):')
 
-    # Program types (enum)
-
-    ref = bpf_info.get_prog_types()
-
-    prog_info = ProgFileExtractor()
-    prog_types = set(prog_info.get_prog_types().keys())
-
-    verify(ref, prog_types,
-            f'Comparing BPF header (enum bpf_prog_type) and {ProgFileExtractor.filename} (prog_type_name):')
-
     # Attach types (enum)
 
     ref = bpf_info.get_attach_types()
@@ -556,6 +543,7 @@ def main():
 
     # Attach types (names)
 
+    prog_info = ProgFileExtractor()
     source_prog_attach_types = set(prog_info.get_attach_types().values())
 
     help_prog_attach_types = prog_info.get_prog_attach_help()