Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'libbpf: use func name when pinning programs with LIBBPF_STRICT_SEC_NAME'

Stanislav Fomichev says:

====================

Commit 15669e1dcd75 ("selftests/bpf: Normalize all the rest SEC() uses")
broke flow dissector tests. With the strict section names, bpftool isn't
able to pin all programs of the objects (all section names are the
same now). To bring it back to life let's do the following:

- teach libbpf to pin by func name with LIBBPF_STRICT_SEC_NAME
- enable strict mode in bpftool (breaking cli change)
- fix custom flow_dissector loader to use strict mode
- fix flow_dissector tests to use new pin names (func vs sec)

v5:
- get rid of error when retrying with '/' (Quentin Monnet)

v4:
- fix comment spelling (Quentin Monnet)
- retry progtype without / (Quentin Monnet)

v3:
- clarify program pinning in LIBBPF_STRICT_SEC_NAME,
for real this time (Andrii Nakryiko)
- fix possible segfault in __bpf_program__pin_name (Andrii Nakryiko)

v2:
- add github issue (Andrii Nakryiko)
- remove sec_name from bpf_program.pin_name comment (Andrii Nakryiko)
- add cover letter (Andrii Nakryiko)
====================

Signed-off-by: Andrii Nakryiko <andrii@kernel.org>

+32 -22
+11 -2
tools/lib/bpf/libbpf.c
··· 285 285 size_t sub_insn_off; 286 286 287 287 char *name; 288 - /* sec_name with / replaced by _; makes recursive pinning 288 + /* name with / replaced by _; makes recursive pinning 289 289 * in bpf_object__pin_programs easier 290 290 */ 291 291 char *pin_name; ··· 618 618 { 619 619 char *name, *p; 620 620 621 - name = p = strdup(prog->sec_name); 621 + if (libbpf_mode & LIBBPF_STRICT_SEC_NAME) 622 + name = strdup(prog->name); 623 + else 624 + name = strdup(prog->sec_name); 625 + 626 + if (!name) 627 + return NULL; 628 + 629 + p = name; 630 + 622 631 while ((p = strchr(p, '/'))) 623 632 *p = '_'; 624 633
+3
tools/lib/bpf/libbpf_legacy.h
··· 52 52 * allowed, with LIBBPF_STRICT_SEC_PREFIX this will become 53 53 * unrecognized by libbpf and would have to be just SEC("xdp") and 54 54 * SEC("xdp") and SEC("perf_event"). 55 + * 56 + * Note, in this mode the program pin path will be based on the 57 + * function name instead of section name. 55 58 */ 56 59 LIBBPF_STRICT_SEC_NAME = 0x04, 57 60
+11 -7
tools/testing/selftests/bpf/flow_dissector_load.c
··· 17 17 const char *cfg_pin_path = "/sys/fs/bpf/flow_dissector"; 18 18 const char *cfg_map_name = "jmp_table"; 19 19 bool cfg_attach = true; 20 - char *cfg_section_name; 20 + char *cfg_prog_name; 21 21 char *cfg_path_name; 22 22 23 23 static void load_and_attach_program(void) ··· 25 25 int prog_fd, ret; 26 26 struct bpf_object *obj; 27 27 28 - ret = bpf_flow_load(&obj, cfg_path_name, cfg_section_name, 28 + ret = libbpf_set_strict_mode(LIBBPF_STRICT_ALL); 29 + if (ret) 30 + error(1, 0, "failed to enable libbpf strict mode: %d", ret); 31 + 32 + ret = bpf_flow_load(&obj, cfg_path_name, cfg_prog_name, 29 33 cfg_map_name, NULL, &prog_fd, NULL); 30 34 if (ret) 31 35 error(1, 0, "bpf_flow_load %s", cfg_path_name); ··· 79 75 break; 80 76 case 'p': 81 77 if (cfg_path_name) 82 - error(1, 0, "only one prog name can be given"); 78 + error(1, 0, "only one path can be given"); 83 79 84 80 cfg_path_name = optarg; 85 81 break; 86 82 case 's': 87 - if (cfg_section_name) 88 - error(1, 0, "only one section can be given"); 83 + if (cfg_prog_name) 84 + error(1, 0, "only one prog can be given"); 89 85 90 - cfg_section_name = optarg; 86 + cfg_prog_name = optarg; 91 87 break; 92 88 } 93 89 } ··· 98 94 if (cfg_attach && !cfg_path_name) 99 95 error(1, 0, "must provide a path to the BPF program"); 100 96 101 - if (cfg_attach && !cfg_section_name) 97 + if (cfg_attach && !cfg_prog_name) 102 98 error(1, 0, "must provide a section name"); 103 99 } 104 100
+2 -8
tools/testing/selftests/bpf/flow_dissector_load.h
··· 7 7 8 8 static inline int bpf_flow_load(struct bpf_object **obj, 9 9 const char *path, 10 - const char *section_name, 10 + const char *prog_name, 11 11 const char *map_name, 12 12 const char *keys_map_name, 13 13 int *prog_fd, ··· 23 23 if (ret) 24 24 return ret; 25 25 26 - main_prog = NULL; 27 - bpf_object__for_each_program(prog, *obj) { 28 - if (strcmp(section_name, bpf_program__section_name(prog)) == 0) { 29 - main_prog = prog; 30 - break; 31 - } 32 - } 26 + main_prog = bpf_object__find_program_by_name(*obj, prog_name); 33 27 if (!main_prog) 34 28 return -1; 35 29
+5 -5
tools/testing/selftests/bpf/test_flow_dissector.sh
··· 26 26 type flow_dissector 27 27 28 28 if ! unshare --net $bpftool prog attach pinned \ 29 - /sys/fs/bpf/flow/flow_dissector flow_dissector; then 29 + /sys/fs/bpf/flow/_dissect flow_dissector; then 30 30 echo "Unexpected unsuccessful attach in namespace" >&2 31 31 err=1 32 32 fi 33 33 34 - $bpftool prog attach pinned /sys/fs/bpf/flow/flow_dissector \ 34 + $bpftool prog attach pinned /sys/fs/bpf/flow/_dissect \ 35 35 flow_dissector 36 36 37 37 if unshare --net $bpftool prog attach pinned \ 38 - /sys/fs/bpf/flow/flow_dissector flow_dissector; then 38 + /sys/fs/bpf/flow/_dissect flow_dissector; then 39 39 echo "Unexpected successful attach in namespace" >&2 40 40 err=1 41 41 fi 42 42 43 43 if ! $bpftool prog detach pinned \ 44 - /sys/fs/bpf/flow/flow_dissector flow_dissector; then 44 + /sys/fs/bpf/flow/_dissect flow_dissector; then 45 45 echo "Failed to detach flow dissector" >&2 46 46 err=1 47 47 fi ··· 95 95 fi 96 96 97 97 # Attach BPF program 98 - ./flow_dissector_load -p bpf_flow.o -s flow_dissector 98 + ./flow_dissector_load -p bpf_flow.o -s _dissect 99 99 100 100 # Setup 101 101 tc qdisc add dev lo ingress