Merge branch 'bpf-samples-improvements'

Jakub Kicinski says:

====================
This set is next part of a quest to get rid of the bpf_load
ELF loader.  It fixes some minor issues with the samples and
starts the conversion.

First patch fixes ping invocations, ping localhost defaults
to IPv6 on modern setups. Next load_sock_ops sample is removed
and users are directed towards using bpftool directly.

Patch 4 removes the use of bpf_load from samples which don't
need the auto-attachment functionality at all.

Patch 5 improves symbol counting in libbpf, it's not currently
an issue but it will be when anyone adds a symbol with a long
name. Let's make sure that person doesn't have to spend time
scratching their head and wondering why .a and .so symbol
counts don't match.

v2: - specify prog_type where possible (Andrii).
====================

Acked-by: Song Liu <songliubraving@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
This commit is contained in:
Daniel Borkmann 2019-03-01 00:53:46 +01:00
commit 74b3881908
24 changed files with 69 additions and 156 deletions

View file

@ -1,7 +1,6 @@
cpustat cpustat
fds_example fds_example
lathist lathist
load_sock_ops
lwt_len_hist lwt_len_hist
map_perf_test map_perf_test
offwaketime offwaketime

View file

@ -40,7 +40,6 @@ hostprogs-y += lwt_len_hist
hostprogs-y += xdp_tx_iptunnel hostprogs-y += xdp_tx_iptunnel
hostprogs-y += test_map_in_map hostprogs-y += test_map_in_map
hostprogs-y += per_socket_stats_example hostprogs-y += per_socket_stats_example
hostprogs-y += load_sock_ops
hostprogs-y += xdp_redirect hostprogs-y += xdp_redirect
hostprogs-y += xdp_redirect_map hostprogs-y += xdp_redirect_map
hostprogs-y += xdp_redirect_cpu hostprogs-y += xdp_redirect_cpu
@ -60,9 +59,9 @@ LIBBPF = $(TOOLS_PATH)/lib/bpf/libbpf.a
CGROUP_HELPERS := ../../tools/testing/selftests/bpf/cgroup_helpers.o CGROUP_HELPERS := ../../tools/testing/selftests/bpf/cgroup_helpers.o
TRACE_HELPERS := ../../tools/testing/selftests/bpf/trace_helpers.o TRACE_HELPERS := ../../tools/testing/selftests/bpf/trace_helpers.o
fds_example-objs := bpf_load.o fds_example.o fds_example-objs := fds_example.o
sockex1-objs := bpf_load.o sockex1_user.o sockex1-objs := sockex1_user.o
sockex2-objs := bpf_load.o sockex2_user.o sockex2-objs := sockex2_user.o
sockex3-objs := bpf_load.o sockex3_user.o sockex3-objs := bpf_load.o sockex3_user.o
tracex1-objs := bpf_load.o tracex1_user.o tracex1-objs := bpf_load.o tracex1_user.o
tracex2-objs := bpf_load.o tracex2_user.o tracex2-objs := bpf_load.o tracex2_user.o
@ -71,7 +70,6 @@ tracex4-objs := bpf_load.o tracex4_user.o
tracex5-objs := bpf_load.o tracex5_user.o tracex5-objs := bpf_load.o tracex5_user.o
tracex6-objs := bpf_load.o tracex6_user.o tracex6-objs := bpf_load.o tracex6_user.o
tracex7-objs := bpf_load.o tracex7_user.o tracex7-objs := bpf_load.o tracex7_user.o
load_sock_ops-objs := bpf_load.o load_sock_ops.o
test_probe_write_user-objs := bpf_load.o test_probe_write_user_user.o test_probe_write_user-objs := bpf_load.o test_probe_write_user_user.o
trace_output-objs := bpf_load.o trace_output_user.o $(TRACE_HELPERS) trace_output-objs := bpf_load.o trace_output_user.o $(TRACE_HELPERS)
lathist-objs := bpf_load.o lathist_user.o lathist-objs := bpf_load.o lathist_user.o

View file

@ -14,8 +14,8 @@
#include <bpf/bpf.h> #include <bpf/bpf.h>
#include "bpf/libbpf.h"
#include "bpf_insn.h" #include "bpf_insn.h"
#include "bpf_load.h"
#include "sock_example.h" #include "sock_example.h"
#define BPF_F_PIN (1 << 0) #define BPF_F_PIN (1 << 0)
@ -57,10 +57,14 @@ static int bpf_prog_create(const char *object)
BPF_EXIT_INSN(), BPF_EXIT_INSN(),
}; };
size_t insns_cnt = sizeof(insns) / sizeof(struct bpf_insn); size_t insns_cnt = sizeof(insns) / sizeof(struct bpf_insn);
char bpf_log_buf[BPF_LOG_BUF_SIZE];
struct bpf_object *obj;
int prog_fd;
if (object) { if (object) {
assert(!load_bpf_file((char *)object)); assert(!bpf_prog_load(object, BPF_PROG_TYPE_UNSPEC,
return prog_fd[0]; &obj, &prog_fd));
return prog_fd;
} else { } else {
return bpf_load_program(BPF_PROG_TYPE_SOCKET_FILTER, return bpf_load_program(BPF_PROG_TYPE_SOCKET_FILTER,
insns, insns_cnt, "GPL", 0, insns, insns_cnt, "GPL", 0,

View file

@ -1,97 +0,0 @@
/* Copyright (c) 2017 Facebook
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <linux/bpf.h>
#include <bpf/bpf.h>
#include "bpf_load.h"
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/unistd.h>
static void usage(char *pname)
{
printf("USAGE:\n %s [-l] <cg-path> <prog filename>\n", pname);
printf("\tLoad and attach a sock_ops program to the specified "
"cgroup\n");
printf("\tIf \"-l\" is used, the program will continue to run\n");
printf("\tprinting the BPF log buffer\n");
printf("\tIf the specified filename does not end in \".o\", it\n");
printf("\tappends \"_kern.o\" to the name\n");
printf("\n");
printf(" %s -r <cg-path>\n", pname);
printf("\tDetaches the currently attached sock_ops program\n");
printf("\tfrom the specified cgroup\n");
printf("\n");
exit(1);
}
int main(int argc, char **argv)
{
int logFlag = 0;
int error = 0;
char *cg_path;
char fn[500];
char *prog;
int cg_fd;
if (argc < 3)
usage(argv[0]);
if (!strcmp(argv[1], "-r")) {
cg_path = argv[2];
cg_fd = open(cg_path, O_DIRECTORY, O_RDONLY);
error = bpf_prog_detach(cg_fd, BPF_CGROUP_SOCK_OPS);
if (error) {
printf("ERROR: bpf_prog_detach: %d (%s)\n",
error, strerror(errno));
return 2;
}
return 0;
} else if (!strcmp(argv[1], "-h")) {
usage(argv[0]);
} else if (!strcmp(argv[1], "-l")) {
logFlag = 1;
if (argc < 4)
usage(argv[0]);
}
prog = argv[argc - 1];
cg_path = argv[argc - 2];
if (strlen(prog) > 480) {
fprintf(stderr, "ERROR: program name too long (> 480 chars)\n");
return 3;
}
cg_fd = open(cg_path, O_DIRECTORY, O_RDONLY);
if (!strcmp(prog + strlen(prog)-2, ".o"))
strcpy(fn, prog);
else
sprintf(fn, "%s_kern.o", prog);
if (logFlag)
printf("loading bpf file:%s\n", fn);
if (load_bpf_file(fn)) {
printf("ERROR: load_bpf_file failed for: %s\n", fn);
printf("%s", bpf_log_buf);
return 4;
}
if (logFlag)
printf("TCP BPF Loaded %s\n", fn);
error = bpf_prog_attach(prog_fd[0], cg_fd, BPF_CGROUP_SOCK_OPS, 0);
if (error) {
printf("ERROR: bpf_prog_attach: %d (%s)\n",
error, strerror(errno));
return 5;
} else if (logFlag) {
read_trace_pipe();
}
return error;
}

View file

@ -99,7 +99,7 @@ int main(void)
{ {
FILE *f; FILE *f;
f = popen("ping -c5 localhost", "r"); f = popen("ping -4 -c5 localhost", "r");
(void)f; (void)f;
return test_sock(); return test_sock();

View file

@ -3,30 +3,33 @@
#include <assert.h> #include <assert.h>
#include <linux/bpf.h> #include <linux/bpf.h>
#include <bpf/bpf.h> #include <bpf/bpf.h>
#include "bpf_load.h" #include "bpf/libbpf.h"
#include "sock_example.h" #include "sock_example.h"
#include <unistd.h> #include <unistd.h>
#include <arpa/inet.h> #include <arpa/inet.h>
int main(int ac, char **argv) int main(int ac, char **argv)
{ {
struct bpf_object *obj;
int map_fd, prog_fd;
char filename[256]; char filename[256];
FILE *f;
int i, sock; int i, sock;
FILE *f;
snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
if (load_bpf_file(filename)) { if (bpf_prog_load(filename, BPF_PROG_TYPE_SOCKET_FILTER,
printf("%s", bpf_log_buf); &obj, &prog_fd))
return 1; return 1;
}
map_fd = bpf_object__find_map_fd_by_name(obj, "my_map");
sock = open_raw_sock("lo"); sock = open_raw_sock("lo");
assert(setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, prog_fd, assert(setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, &prog_fd,
sizeof(prog_fd[0])) == 0); sizeof(prog_fd)) == 0);
f = popen("ping -c5 localhost", "r"); f = popen("ping -4 -c5 localhost", "r");
(void) f; (void) f;
for (i = 0; i < 5; i++) { for (i = 0; i < 5; i++) {
@ -34,13 +37,13 @@ int main(int ac, char **argv)
int key; int key;
key = IPPROTO_TCP; key = IPPROTO_TCP;
assert(bpf_map_lookup_elem(map_fd[0], &key, &tcp_cnt) == 0); assert(bpf_map_lookup_elem(map_fd, &key, &tcp_cnt) == 0);
key = IPPROTO_UDP; key = IPPROTO_UDP;
assert(bpf_map_lookup_elem(map_fd[0], &key, &udp_cnt) == 0); assert(bpf_map_lookup_elem(map_fd, &key, &udp_cnt) == 0);
key = IPPROTO_ICMP; key = IPPROTO_ICMP;
assert(bpf_map_lookup_elem(map_fd[0], &key, &icmp_cnt) == 0); assert(bpf_map_lookup_elem(map_fd, &key, &icmp_cnt) == 0);
printf("TCP %lld UDP %lld ICMP %lld bytes\n", printf("TCP %lld UDP %lld ICMP %lld bytes\n",
tcp_cnt, udp_cnt, icmp_cnt); tcp_cnt, udp_cnt, icmp_cnt);

View file

@ -3,7 +3,7 @@
#include <assert.h> #include <assert.h>
#include <linux/bpf.h> #include <linux/bpf.h>
#include <bpf/bpf.h> #include <bpf/bpf.h>
#include "bpf_load.h" #include "bpf/libbpf.h"
#include "sock_example.h" #include "sock_example.h"
#include <unistd.h> #include <unistd.h>
#include <arpa/inet.h> #include <arpa/inet.h>
@ -17,32 +17,35 @@ struct pair {
int main(int ac, char **argv) int main(int ac, char **argv)
{ {
struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY}; struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
struct bpf_object *obj;
int map_fd, prog_fd;
char filename[256]; char filename[256];
FILE *f;
int i, sock; int i, sock;
FILE *f;
snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
setrlimit(RLIMIT_MEMLOCK, &r); setrlimit(RLIMIT_MEMLOCK, &r);
if (load_bpf_file(filename)) { if (bpf_prog_load(filename, BPF_PROG_TYPE_SOCKET_FILTER,
printf("%s", bpf_log_buf); &obj, &prog_fd))
return 1; return 1;
}
map_fd = bpf_object__find_map_fd_by_name(obj, "hash_map");
sock = open_raw_sock("lo"); sock = open_raw_sock("lo");
assert(setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, prog_fd, assert(setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, &prog_fd,
sizeof(prog_fd[0])) == 0); sizeof(prog_fd)) == 0);
f = popen("ping -c5 localhost", "r"); f = popen("ping -4 -c5 localhost", "r");
(void) f; (void) f;
for (i = 0; i < 5; i++) { for (i = 0; i < 5; i++) {
int key = 0, next_key; int key = 0, next_key;
struct pair value; struct pair value;
while (bpf_map_get_next_key(map_fd[0], &key, &next_key) == 0) { while (bpf_map_get_next_key(map_fd, &key, &next_key) == 0) {
bpf_map_lookup_elem(map_fd[0], &next_key, &value); bpf_map_lookup_elem(map_fd, &next_key, &value);
printf("ip %s bytes %lld packets %lld\n", printf("ip %s bytes %lld packets %lld\n",
inet_ntoa((struct in_addr){htonl(next_key)}), inet_ntoa((struct in_addr){htonl(next_key)}),
value.bytes, value.packets); value.bytes, value.packets);

View file

@ -58,7 +58,7 @@ int main(int argc, char **argv)
sizeof(__u32)) == 0); sizeof(__u32)) == 0);
if (argc > 1) if (argc > 1)
f = popen("ping -c5 localhost", "r"); f = popen("ping -4 -c5 localhost", "r");
else else
f = popen("netperf -l 4 localhost", "r"); f = popen("netperf -l 4 localhost", "r");
(void) f; (void) f;

View file

@ -7,7 +7,7 @@
* BPF program to set base_rtt to 80us when host is running TCP-NV and * BPF program to set base_rtt to 80us when host is running TCP-NV and
* both hosts are in the same datacenter (as determined by IPv6 prefix). * both hosts are in the same datacenter (as determined by IPv6 prefix).
* *
* Use load_sock_ops to load this BPF program. * Use "bpftool cgroup attach $cg sock_ops $prog" to load this BPF program.
*/ */
#include <uapi/linux/bpf.h> #include <uapi/linux/bpf.h>

View file

@ -8,14 +8,16 @@ a cgroupv2 and attach a bash shell to the group.
bash bash
echo $$ >> /tmp/cgroupv2/foo/cgroup.procs echo $$ >> /tmp/cgroupv2/foo/cgroup.procs
Anything that runs under this shell belongs to the foo cgroupv2 To load Anything that runs under this shell belongs to the foo cgroupv2. To load
(attach) one of the tcp_*_kern.o programs: (attach) one of the tcp_*_kern.o programs:
./load_sock_ops -l /tmp/cgroupv2/foo tcp_basertt_kern.o bpftool prog load tcp_basertt_kern.o /sys/fs/bpf/tcp_prog
bpftool cgroup attach /tmp/cgroupv2/foo sock_ops pinned /sys/fs/bpf/tcp_prog
bpftool prog tracelog
If the "-l" flag is used, the load_sock_ops program will continue to run "bpftool prog tracelog" will continue to run printing the BPF log buffer.
printing the BPF log buffer. The tcp_*_kern.o programs use special print The tcp_*_kern.o programs use special print functions to print logging
functions to print logging information (if enabled by the ifdef). information (if enabled by the ifdef).
If using netperf/netserver to create traffic, you need to run them under the If using netperf/netserver to create traffic, you need to run them under the
cgroupv2 to which the BPF programs are attached (i.e. under bash shell cgroupv2 to which the BPF programs are attached (i.e. under bash shell
@ -23,4 +25,4 @@ attached to the cgroupv2).
To remove (unattach) a socket_ops BPF program from a cgroupv2: To remove (unattach) a socket_ops BPF program from a cgroupv2:
./load_sock_ops -r /tmp/cgroupv2/foo bpftool cgroup attach /tmp/cgroupv2/foo sock_ops pinned /sys/fs/bpf/tcp_prog

View file

@ -9,7 +9,7 @@
* doing appropriate checks that indicate the hosts are far enough * doing appropriate checks that indicate the hosts are far enough
* away (i.e. large RTT). * away (i.e. large RTT).
* *
* Use load_sock_ops to load this BPF program. * Use "bpftool cgroup attach $cg sock_ops $prog" to load this BPF program.
*/ */
#include <uapi/linux/bpf.h> #include <uapi/linux/bpf.h>

View file

@ -9,7 +9,7 @@
* the same datacenter. For his example, we assume they are within the same * the same datacenter. For his example, we assume they are within the same
* datacenter when the first 5.5 bytes of their IPv6 addresses are the same. * datacenter when the first 5.5 bytes of their IPv6 addresses are the same.
* *
* Use load_sock_ops to load this BPF program. * Use "bpftool cgroup attach $cg sock_ops $prog" to load this BPF program.
*/ */
#include <uapi/linux/bpf.h> #include <uapi/linux/bpf.h>

View file

@ -7,7 +7,7 @@
* BPF program to set congestion control to dctcp when both hosts are * BPF program to set congestion control to dctcp when both hosts are
* in the same datacenter (as deteremined by IPv6 prefix). * in the same datacenter (as deteremined by IPv6 prefix).
* *
* Use load_sock_ops to load this BPF program. * Use "bpftool cgroup attach $cg sock_ops $prog" to load this BPF program.
*/ */
#include <uapi/linux/bpf.h> #include <uapi/linux/bpf.h>

View file

@ -9,7 +9,7 @@
* would usually be done after doing appropriate checks that indicate * would usually be done after doing appropriate checks that indicate
* the hosts are far enough away (i.e. large RTT). * the hosts are far enough away (i.e. large RTT).
* *
* Use load_sock_ops to load this BPF program. * Use "bpftool cgroup attach $cg sock_ops $prog" to load this BPF program.
*/ */
#include <uapi/linux/bpf.h> #include <uapi/linux/bpf.h>

View file

@ -8,7 +8,7 @@
* and the first 5.5 bytes of the IPv6 addresses are not the same (in this * and the first 5.5 bytes of the IPv6 addresses are not the same (in this
* example that means both hosts are not the same datacenter). * example that means both hosts are not the same datacenter).
* *
* Use load_sock_ops to load this BPF program. * Use "bpftool cgroup attach $cg sock_ops $prog" to load this BPF program.
*/ */
#include <uapi/linux/bpf.h> #include <uapi/linux/bpf.h>

View file

@ -8,7 +8,7 @@
* and the first 5.5 bytes of the IPv6 addresses are the same (in this example * and the first 5.5 bytes of the IPv6 addresses are the same (in this example
* that means both hosts are in the same datacenter). * that means both hosts are in the same datacenter).
* *
* Use load_sock_ops to load this BPF program. * Use "bpftool cgroup attach $cg sock_ops $prog" to load this BPF program.
*/ */
#include <uapi/linux/bpf.h> #include <uapi/linux/bpf.h>

View file

@ -4,7 +4,7 @@
* *
* BPF program to automatically reflect TOS option from received syn packet * BPF program to automatically reflect TOS option from received syn packet
* *
* Use load_sock_ops to load this BPF program. * Use "bpftool cgroup attach $cg sock_ops $prog" to load this BPF program.
*/ */
#include <uapi/linux/bpf.h> #include <uapi/linux/bpf.h>

View file

@ -131,7 +131,7 @@ int main(int ac, char **argv)
signal(SIGTERM, int_exit); signal(SIGTERM, int_exit);
/* start 'ping' in the background to have some kfree_skb events */ /* start 'ping' in the background to have some kfree_skb events */
f = popen("ping -c5 localhost", "r"); f = popen("ping -4 -c5 localhost", "r");
(void) f; (void) f;
/* start 'dd' in the background to have plenty of 'write' syscalls */ /* start 'dd' in the background to have plenty of 'write' syscalls */

View file

@ -1053,7 +1053,7 @@ static int load_with_options(int argc, char **argv, bool first_prog_only)
j = 0; j = 0;
while (j < old_map_fds && map_replace[j].name) { while (j < old_map_fds && map_replace[j].name) {
i = 0; i = 0;
bpf_map__for_each(map, obj) { bpf_object__for_each_map(map, obj) {
if (!strcmp(bpf_map__name(map), map_replace[j].name)) { if (!strcmp(bpf_map__name(map), map_replace[j].name)) {
map_replace[j].idx = i; map_replace[j].idx = i;
break; break;
@ -1074,7 +1074,7 @@ static int load_with_options(int argc, char **argv, bool first_prog_only)
/* Set ifindex and name reuse */ /* Set ifindex and name reuse */
j = 0; j = 0;
idx = 0; idx = 0;
bpf_map__for_each(map, obj) { bpf_object__for_each_map(map, obj) {
if (!bpf_map__is_offload_neutral(map)) if (!bpf_map__is_offload_neutral(map))
bpf_map__set_ifindex(map, ifindex); bpf_map__set_ifindex(map, ifindex);

View file

@ -132,9 +132,9 @@ BPF_IN := $(OUTPUT)libbpf-in.o
LIB_FILE := $(addprefix $(OUTPUT),$(LIB_FILE)) LIB_FILE := $(addprefix $(OUTPUT),$(LIB_FILE))
VERSION_SCRIPT := libbpf.map VERSION_SCRIPT := libbpf.map
GLOBAL_SYM_COUNT = $(shell readelf -s $(BPF_IN) | \ GLOBAL_SYM_COUNT = $(shell readelf -s --wide $(BPF_IN) | \
awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {s++} END{print s}') awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {s++} END{print s}')
VERSIONED_SYM_COUNT = $(shell readelf -s $(OUTPUT)libbpf.so | \ VERSIONED_SYM_COUNT = $(shell readelf -s --wide $(OUTPUT)libbpf.so | \
grep -Eo '[^ ]+@LIBBPF_' | cut -d@ -f1 | sort -u | wc -l) grep -Eo '[^ ]+@LIBBPF_' | cut -d@ -f1 | sort -u | wc -l)
CMD_TARGETS = $(LIB_FILE) CMD_TARGETS = $(LIB_FILE)

View file

@ -2100,7 +2100,7 @@ int bpf_object__pin_maps(struct bpf_object *obj, const char *path)
if (err) if (err)
return err; return err;
bpf_map__for_each(map, obj) { bpf_object__for_each_map(map, obj) {
char buf[PATH_MAX]; char buf[PATH_MAX];
int len; int len;
@ -2147,7 +2147,7 @@ int bpf_object__unpin_maps(struct bpf_object *obj, const char *path)
if (!obj) if (!obj)
return -ENOENT; return -ENOENT;
bpf_map__for_each(map, obj) { bpf_object__for_each_map(map, obj) {
char buf[PATH_MAX]; char buf[PATH_MAX];
int len; int len;
@ -2835,7 +2835,7 @@ bpf_object__find_map_by_name(struct bpf_object *obj, const char *name)
{ {
struct bpf_map *pos; struct bpf_map *pos;
bpf_map__for_each(pos, obj) { bpf_object__for_each_map(pos, obj) {
if (pos->name && !strcmp(pos->name, name)) if (pos->name && !strcmp(pos->name, name))
return pos; return pos;
} }
@ -2928,7 +2928,7 @@ int bpf_prog_load_xattr(const struct bpf_prog_load_attr *attr,
first_prog = prog; first_prog = prog;
} }
bpf_map__for_each(map, obj) { bpf_object__for_each_map(map, obj) {
if (!bpf_map__is_offload_neutral(map)) if (!bpf_map__is_offload_neutral(map))
map->map_ifindex = attr->ifindex; map->map_ifindex = attr->ifindex;
} }

View file

@ -278,10 +278,11 @@ bpf_object__find_map_by_offset(struct bpf_object *obj, size_t offset);
LIBBPF_API struct bpf_map * LIBBPF_API struct bpf_map *
bpf_map__next(struct bpf_map *map, struct bpf_object *obj); bpf_map__next(struct bpf_map *map, struct bpf_object *obj);
#define bpf_map__for_each(pos, obj) \ #define bpf_object__for_each_map(pos, obj) \
for ((pos) = bpf_map__next(NULL, (obj)); \ for ((pos) = bpf_map__next(NULL, (obj)); \
(pos) != NULL; \ (pos) != NULL; \
(pos) = bpf_map__next((pos), (obj))) (pos) = bpf_map__next((pos), (obj)))
#define bpf_map__for_each bpf_object__for_each_map
LIBBPF_API struct bpf_map * LIBBPF_API struct bpf_map *
bpf_map__prev(struct bpf_map *map, struct bpf_object *obj); bpf_map__prev(struct bpf_map *map, struct bpf_object *obj);

View file

@ -1489,7 +1489,7 @@ apply_obj_config_object(struct bpf_object *obj)
struct bpf_map *map; struct bpf_map *map;
int err; int err;
bpf_map__for_each(map, obj) { bpf_object__for_each_map(map, obj) {
err = apply_obj_config_map(map); err = apply_obj_config_map(map);
if (err) if (err)
return err; return err;
@ -1513,7 +1513,7 @@ int bpf__apply_obj_config(void)
#define bpf__for_each_map(pos, obj, objtmp) \ #define bpf__for_each_map(pos, obj, objtmp) \
bpf_object__for_each_safe(obj, objtmp) \ bpf_object__for_each_safe(obj, objtmp) \
bpf_map__for_each(pos, obj) bpf_object__for_each_map(pos, obj)
#define bpf__for_each_map_named(pos, obj, objtmp, name) \ #define bpf__for_each_map_named(pos, obj, objtmp, name) \
bpf__for_each_map(pos, obj, objtmp) \ bpf__for_each_map(pos, obj, objtmp) \

View file

@ -67,7 +67,7 @@ int test_walk_maps(struct bpf_object *obj, bool verbose)
struct bpf_map *map; struct bpf_map *map;
int cnt = 0; int cnt = 0;
bpf_map__for_each(map, obj) { bpf_object__for_each_map(map, obj) {
cnt++; cnt++;
if (verbose) if (verbose)
printf("Map (count:%d) name: %s\n", cnt, printf("Map (count:%d) name: %s\n", cnt,