@@ -1,6 +1,20 @@
# kbuild trick to avoid linker error. Can be omitted if a module is built.
obj- := dummy.o
+INC_DIR = $(src)/include
+TOOLS_DIR = $(realpath $(srctree))/tools
+TOOLS_LIB_DIR = $(TOOLS_DIR)/lib
+LIBBPF_DIR = $(TOOLS_LIB_DIR)/bpf
+
+$(obj)/libbpf/libbpf.a:
+ $(Q)mkdir -p $(obj)/libbpf
+ $(MAKE) -C $(LIBBPF_DIR) O=$(realpath $(obj))/libbpf CFLAGS= LDFLAGS= V=1 $(realpath $(obj))/libbpf/libbpf.a
+
+HOSTCFLAGS += -I$(TOOLS_LIB_DIR) -I$(INC_DIR)
+HOSTLDFLAGS += -L$(obj)/libbpf
+HOSTCFLAGS += -I$(INC_DIR) -I$(TOOLS_LIB_DIR)
+HOST_LOADLIBES += -lelf -lbpf
+
# List of programs to build
hostprogs-y := test_verifier test_maps
hostprogs-y += sock_example
@@ -17,21 +31,27 @@ hostprogs-y += tracex6
hostprogs-y += trace_output
hostprogs-y += lathist
-test_verifier-objs := test_verifier.o libbpf.o
-test_maps-objs := test_maps.o libbpf.o
-sock_example-objs := sock_example.o libbpf.o
-fds_example-objs := bpf_load.o libbpf.o fds_example.o
-sockex1-objs := bpf_load.o libbpf.o sockex1_user.o
-sockex2-objs := bpf_load.o libbpf.o sockex2_user.o
-sockex3-objs := bpf_load.o libbpf.o sockex3_user.o
-tracex1-objs := bpf_load.o libbpf.o tracex1_user.o
-tracex2-objs := bpf_load.o libbpf.o tracex2_user.o
-tracex3-objs := bpf_load.o libbpf.o tracex3_user.o
-tracex4-objs := bpf_load.o libbpf.o tracex4_user.o
-tracex5-objs := bpf_load.o libbpf.o tracex5_user.o
-tracex6-objs := bpf_load.o libbpf.o tracex6_user.o
-trace_output-objs := bpf_load.o libbpf.o trace_output_user.o
-lathist-objs := bpf_load.o libbpf.o lathist_user.o
+test_verifier-objs := test_verifier.o
+test_maps-objs := test_maps.o
+sock_example-objs := sock_example.o utils.o
+fds_example-objs := utils.o fds_example.o
+sockex1-objs := utils.o sockex1_user.o
+sockex2-objs := utils.o sockex2_user.o
+sockex3-objs := utils.o sockex3_user.o
+tracex1-objs := utils.o tracex1_user.o
+tracex2-objs := utils.o tracex2_user.o
+tracex3-objs := utils.o tracex3_user.o
+tracex4-objs := utils.o tracex4_user.o
+tracex5-objs := utils.o tracex5_user.o
+tracex6-objs := utils.o tracex6_user.o
+trace_output-objs := utils.o trace_output_user.o
+lathist-objs := utils.o lathist_user.o
+
+define add_depend
+$(foreach m, $(notdir $1), \
+ $(eval $(obj)/$m: $(obj)/libbpf/libbpf.a))
+endef
+$(call add_depend, $(hostprogs-y))
# Tell kbuild to always build the programs
always := $(hostprogs-y)
@@ -50,19 +70,8 @@ always += lathist_kern.o
HOSTCFLAGS += -I$(objtree)/usr/include
-HOSTCFLAGS_bpf_load.o += -I$(objtree)/usr/include -Wno-unused-variable
-HOSTLOADLIBES_fds_example += -lelf
-HOSTLOADLIBES_sockex1 += -lelf
-HOSTLOADLIBES_sockex2 += -lelf
-HOSTLOADLIBES_sockex3 += -lelf
-HOSTLOADLIBES_tracex1 += -lelf
-HOSTLOADLIBES_tracex2 += -lelf
-HOSTLOADLIBES_tracex3 += -lelf
-HOSTLOADLIBES_tracex4 += -lelf -lrt
-HOSTLOADLIBES_tracex5 += -lelf
-HOSTLOADLIBES_tracex6 += -lelf
-HOSTLOADLIBES_trace_output += -lelf -lrt
-HOSTLOADLIBES_lathist += -lelf
+HOSTLOADLIBES_tracex4 += -lrt
+HOSTLOADLIBES_trace_output += -lrt
# point this to your LLVM backend with bpf support
LLC=$(srctree)/tools/bpf/llvm/bld/Debug+Asserts/bin/llc
@@ -12,8 +12,7 @@
#include <sys/types.h>
#include <sys/socket.h>
-#include "bpf_load.h"
-#include "libbpf.h"
+#include "utils.h"
#define BPF_F_PIN (1 << 0)
#define BPF_F_GET (1 << 1)
@@ -55,11 +54,14 @@ static int bpf_prog_create(const char *object)
};
if (object) {
- assert(!load_bpf_file((char *)object));
- return prog_fd[0];
+ struct bpf_object *obj = load_bpf_file((char *)object);
+
+ assert(obj);
+ return get_prog_fd(obj, 0);
} else {
- return bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER,
- insns, sizeof(insns), "GPL", 0);
+ return bpf_load_program(BPF_PROG_TYPE_SOCKET_FILTER,
+ insns, sizeof(insns) / sizeof(insns[0]),
+ "GPL", 0, NULL, 0);
}
}
@@ -73,22 +75,22 @@ static int bpf_do_map(const char *file, uint32_t flags, uint32_t key,
printf("bpf: map fd:%d (%s)\n", fd, strerror(errno));
assert(fd > 0);
- ret = bpf_obj_pin(fd, file);
+ ret = bpf_pin_object(fd, file);
printf("bpf: pin ret:(%d,%s)\n", ret, strerror(errno));
assert(ret == 0);
} else {
- fd = bpf_obj_get(file);
+ fd = bpf_get_pinned_object(file);
printf("bpf: get fd:%d (%s)\n", fd, strerror(errno));
assert(fd > 0);
}
if ((flags & BPF_F_KEY_VAL) == BPF_F_KEY_VAL) {
- ret = bpf_update_elem(fd, &key, &value, 0);
+ ret = bpf_map_update_elem(fd, &key, &value, 0);
printf("bpf: fd:%d u->(%u:%u) ret:(%d,%s)\n", fd, key, value,
ret, strerror(errno));
assert(ret == 0);
} else if (flags & BPF_F_KEY) {
- ret = bpf_lookup_elem(fd, &key, &value);
+ ret = bpf_map_lookup_elem(fd, &key, &value);
printf("bpf: fd:%d l->(%u):%u ret:(%d,%s)\n", fd, key, value,
ret, strerror(errno));
assert(ret == 0);
@@ -106,11 +108,11 @@ static int bpf_do_prog(const char *file, uint32_t flags, const char *object)
printf("bpf: prog fd:%d (%s)\n", fd, strerror(errno));
assert(fd > 0);
- ret = bpf_obj_pin(fd, file);
+ ret = bpf_pin_object(fd, file);
printf("bpf: pin ret:(%d,%s)\n", ret, strerror(errno));
assert(ret == 0);
} else {
- fd = bpf_obj_get(file);
+ fd = bpf_get_pinned_object(file);
printf("bpf: get fd:%d (%s)\n", fd, strerror(errno));
assert(fd > 0);
}
@@ -10,8 +10,7 @@
#include <stdlib.h>
#include <signal.h>
#include <linux/bpf.h>
-#include "libbpf.h"
-#include "bpf_load.h"
+#include "utils.h"
#define MAX_ENTRIES 20
#define MAX_CPU 4
@@ -73,7 +72,7 @@ static void get_data(int fd)
for (c = 0; c < MAX_CPU; c++) {
for (i = 0; i < MAX_ENTRIES; i++) {
key = c * MAX_ENTRIES + i;
- bpf_lookup_elem(fd, &key, &value);
+ bpf_map_lookup_elem(fd, &key, &value);
cpu_hist[c].data[i] = value;
if (value > cpu_hist[c].max)
@@ -85,16 +84,16 @@ static void get_data(int fd)
int main(int argc, char **argv)
{
char filename[256];
+ struct bpf_object *obj;
snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
- if (load_bpf_file(filename)) {
- printf("%s", bpf_log_buf);
+ obj = load_bpf_file(filename);
+ if (!obj)
return 1;
- }
while (1) {
- get_data(map_fd[1]);
+ get_data(get_map_fd(obj, 1));
print_hist();
sleep(5);
}
@@ -26,7 +26,7 @@
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <stddef.h>
-#include "libbpf.h"
+#include "utils.h"
static int test_sock(void)
{
@@ -55,8 +55,9 @@ static int test_sock(void)
BPF_EXIT_INSN(),
};
- prog_fd = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, prog, sizeof(prog),
- "GPL", 0);
+ prog_fd = bpf_load_program(BPF_PROG_TYPE_SOCKET_FILTER, prog,
+ sizeof(prog) / sizeof(prog[0]),
+ "GPL", 0, NULL, 0);
if (prog_fd < 0) {
printf("failed to load prog '%s'\n", strerror(errno));
goto cleanup;
@@ -72,13 +73,13 @@ static int test_sock(void)
for (i = 0; i < 10; i++) {
key = IPPROTO_TCP;
- assert(bpf_lookup_elem(map_fd, &key, &tcp_cnt) == 0);
+ assert(bpf_map_lookup_elem(map_fd, &key, &tcp_cnt) == 0);
key = IPPROTO_UDP;
- assert(bpf_lookup_elem(map_fd, &key, &udp_cnt) == 0);
+ assert(bpf_map_lookup_elem(map_fd, &key, &udp_cnt) == 0);
key = IPPROTO_ICMP;
- assert(bpf_lookup_elem(map_fd, &key, &icmp_cnt) == 0);
+ assert(bpf_map_lookup_elem(map_fd, &key, &icmp_cnt) == 0);
printf("TCP %lld UDP %lld ICMP %lld packets\n",
tcp_cnt, udp_cnt, icmp_cnt);
@@ -2,6 +2,7 @@
#include <uapi/linux/if_ether.h>
#include <uapi/linux/if_packet.h>
#include <uapi/linux/ip.h>
+#include <linux/version.h>
#include "bpf_helpers.h"
struct bpf_map_def SEC("maps") my_map = {
@@ -27,3 +28,4 @@ int bpf_prog1(struct __sk_buff *skb)
return 0;
}
char _license[] SEC("license") = "GPL";
+int _version SEC("version") = LINUX_VERSION_CODE;
@@ -1,28 +1,33 @@
#include <stdio.h>
#include <assert.h>
-#include <linux/bpf.h>
-#include "libbpf.h"
-#include "bpf_load.h"
#include <unistd.h>
#include <arpa/inet.h>
+#include "utils.h"
int main(int ac, char **argv)
{
char filename[256];
FILE *f;
- int i, sock;
+ int i, sock, map_fd, prog_fd;
+ struct bpf_object *obj;
snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
- if (load_bpf_file(filename)) {
- printf("%s", bpf_log_buf);
+ obj = load_bpf_file(filename);
+ if (!obj)
+ return 1;
+
+ map_fd = get_map_fd(obj, 0);
+ prog_fd = get_prog_fd(obj, 0);
+ if (map_fd < 0 || prog_fd < 0) {
+ fprintf(stderr, "failed to get file descriptor\n");
return 1;
}
sock = open_raw_sock("lo");
- assert(setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, prog_fd,
- sizeof(prog_fd[0])) == 0);
+ assert(setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, &prog_fd,
+ sizeof(prog_fd)) == 0);
f = popen("ping -c5 localhost", "r");
(void) f;
@@ -32,13 +37,13 @@ int main(int ac, char **argv)
int key;
key = IPPROTO_TCP;
- assert(bpf_lookup_elem(map_fd[0], &key, &tcp_cnt) == 0);
+ assert(bpf_map_lookup_elem(map_fd, &key, &tcp_cnt) == 0);
key = IPPROTO_UDP;
- assert(bpf_lookup_elem(map_fd[0], &key, &udp_cnt) == 0);
+ assert(bpf_map_lookup_elem(map_fd, &key, &udp_cnt) == 0);
key = IPPROTO_ICMP;
- assert(bpf_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",
tcp_cnt, udp_cnt, icmp_cnt);
@@ -6,6 +6,7 @@
#include <uapi/linux/ip.h>
#include <uapi/linux/ipv6.h>
#include <uapi/linux/if_tunnel.h>
+#include <linux/version.h>
#define IP_MF 0x2000
#define IP_OFFSET 0x1FFF
@@ -219,3 +220,4 @@ int bpf_prog2(struct __sk_buff *skb)
}
char _license[] SEC("license") = "GPL";
+int _version SEC("version") = LINUX_VERSION_CODE;
@@ -1,10 +1,9 @@
#include <stdio.h>
#include <assert.h>
-#include <linux/bpf.h>
-#include "libbpf.h"
-#include "bpf_load.h"
#include <unistd.h>
#include <arpa/inet.h>
+#include <bpf/bpf.h>
+#include "utils.h"
struct pair {
__u64 packets;
@@ -15,19 +14,26 @@ int main(int ac, char **argv)
{
char filename[256];
FILE *f;
- int i, sock;
+ int i, sock, map_fd, prog_fd;
+ struct bpf_object *obj;
snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
- if (load_bpf_file(filename)) {
- printf("%s", bpf_log_buf);
+ obj = load_bpf_file(filename);
+ if (!obj)
+ return 1;
+
+ map_fd = get_map_fd(obj, 0);
+ prog_fd = get_prog_fd(obj, 0);
+ if (map_fd < 0 || prog_fd < 0) {
+ fprintf(stderr, "failed to get file descriptor\n");
return 1;
}
sock = open_raw_sock("lo");
- assert(setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, prog_fd,
- sizeof(prog_fd[0])) == 0);
+ assert(setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, &prog_fd,
+ sizeof(prog_fd)) == 0);
f = popen("ping -c5 localhost", "r");
(void) f;
@@ -36,8 +42,8 @@ int main(int ac, char **argv)
int key = 0, next_key;
struct pair value;
- while (bpf_get_next_key(map_fd[0], &key, &next_key) == 0) {
- bpf_lookup_elem(map_fd[0], &next_key, &value);
+ while (bpf_map_get_next_key(map_fd, &key, &next_key) == 0) {
+ bpf_map_lookup_elem(map_fd, &next_key, &value);
printf("ip %s bytes %lld packets %lld\n",
inet_ntoa((struct in_addr){htonl(next_key)}),
value.bytes, value.packets);
@@ -13,6 +13,7 @@
#include <uapi/linux/ipv6.h>
#include <uapi/linux/if_tunnel.h>
#include <uapi/linux/mpls.h>
+#include <linux/version.h>
#define IP_MF 0x2000
#define IP_OFFSET 0x1FFF
@@ -288,3 +289,4 @@ int main_prog(struct __sk_buff *skb)
}
char _license[] SEC("license") = "GPL";
+int _version SEC("version") = LINUX_VERSION_CODE;
@@ -1,10 +1,10 @@
#include <stdio.h>
#include <assert.h>
#include <linux/bpf.h>
-#include "libbpf.h"
-#include "bpf_load.h"
#include <unistd.h>
#include <arpa/inet.h>
+#include <bpf/bpf.h>
+#include "utils.h"
struct flow_keys {
__be32 src;
@@ -25,18 +25,25 @@ int main(int argc, char **argv)
{
char filename[256];
FILE *f;
- int i, sock;
+ int i, sock, map_fd, prog_fd;
+ struct bpf_object *obj;
snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
- if (load_bpf_file(filename)) {
- printf("%s", bpf_log_buf);
+ obj = load_bpf_file(filename);
+ if (!obj)
+ return 1;
+
+ map_fd = get_map_fd(obj, 2);
+ prog_fd = get_prog_fd(obj, 4);
+ if (map_fd < 0 || prog_fd < 0) {
+ fprintf(stderr, "failed to get file descriptor\n");
return 1;
}
sock = open_raw_sock("lo");
- assert(setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, &prog_fd[4],
+ assert(setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, &prog_fd,
sizeof(__u32)) == 0);
if (argc > 1)
@@ -51,8 +58,8 @@ int main(int argc, char **argv)
sleep(1);
printf("IP src.port -> dst.port bytes packets\n");
- while (bpf_get_next_key(map_fd[2], &key, &next_key) == 0) {
- bpf_lookup_elem(map_fd[2], &next_key, &value);
+ while (bpf_map_get_next_key(map_fd, &key, &next_key) == 0) {
+ bpf_map_lookup_elem(map_fd, &next_key, &value);
printf("%s.%05d -> %s.%05d %12lld %12lld\n",
inet_ntoa((struct in_addr){htonl(next_key.src)}),
next_key.port16[0],
@@ -15,7 +15,7 @@
#include <assert.h>
#include <sys/wait.h>
#include <stdlib.h>
-#include "libbpf.h"
+#include "utils.h"
/* sanity tests for map API */
static void test_hashmap_sanity(int i, void *data)
@@ -32,59 +32,59 @@ static void test_hashmap_sanity(int i, void *data)
key = 1;
value = 1234;
/* insert key=1 element */
- assert(bpf_update_elem(map_fd, &key, &value, BPF_ANY) == 0);
+ assert(bpf_map_update_elem(map_fd, &key, &value, BPF_ANY) == 0);
value = 0;
/* BPF_NOEXIST means: add new element if it doesn't exist */
- assert(bpf_update_elem(map_fd, &key, &value, BPF_NOEXIST) == -1 &&
+ assert(bpf_map_update_elem(map_fd, &key, &value, BPF_NOEXIST) == -1 &&
/* key=1 already exists */
errno == EEXIST);
- assert(bpf_update_elem(map_fd, &key, &value, -1) == -1 && errno == EINVAL);
+ assert(bpf_map_update_elem(map_fd, &key, &value, -1) == -1 && errno == EINVAL);
/* check that key=1 can be found */
- assert(bpf_lookup_elem(map_fd, &key, &value) == 0 && value == 1234);
+ assert(bpf_map_lookup_elem(map_fd, &key, &value) == 0 && value == 1234);
key = 2;
/* check that key=2 is not found */
- assert(bpf_lookup_elem(map_fd, &key, &value) == -1 && errno == ENOENT);
+ assert(bpf_map_lookup_elem(map_fd, &key, &value) == -1 && errno == ENOENT);
/* BPF_EXIST means: update existing element */
- assert(bpf_update_elem(map_fd, &key, &value, BPF_EXIST) == -1 &&
+ assert(bpf_map_update_elem(map_fd, &key, &value, BPF_EXIST) == -1 &&
/* key=2 is not there */
errno == ENOENT);
/* insert key=2 element */
- assert(bpf_update_elem(map_fd, &key, &value, BPF_NOEXIST) == 0);
+ assert(bpf_map_update_elem(map_fd, &key, &value, BPF_NOEXIST) == 0);
/* key=1 and key=2 were inserted, check that key=0 cannot be inserted
* due to max_entries limit
*/
key = 0;
- assert(bpf_update_elem(map_fd, &key, &value, BPF_NOEXIST) == -1 &&
+ assert(bpf_map_update_elem(map_fd, &key, &value, BPF_NOEXIST) == -1 &&
errno == E2BIG);
/* check that key = 0 doesn't exist */
- assert(bpf_delete_elem(map_fd, &key) == -1 && errno == ENOENT);
+ assert(bpf_map_delete_elem(map_fd, &key) == -1 && errno == ENOENT);
/* iterate over two elements */
- assert(bpf_get_next_key(map_fd, &key, &next_key) == 0 &&
+ assert(bpf_map_get_next_key(map_fd, &key, &next_key) == 0 &&
(next_key == 1 || next_key == 2));
- assert(bpf_get_next_key(map_fd, &next_key, &next_key) == 0 &&
+ assert(bpf_map_get_next_key(map_fd, &next_key, &next_key) == 0 &&
(next_key == 1 || next_key == 2));
- assert(bpf_get_next_key(map_fd, &next_key, &next_key) == -1 &&
+ assert(bpf_map_get_next_key(map_fd, &next_key, &next_key) == -1 &&
errno == ENOENT);
/* delete both elements */
key = 1;
- assert(bpf_delete_elem(map_fd, &key) == 0);
+ assert(bpf_map_delete_elem(map_fd, &key) == 0);
key = 2;
- assert(bpf_delete_elem(map_fd, &key) == 0);
- assert(bpf_delete_elem(map_fd, &key) == -1 && errno == ENOENT);
+ assert(bpf_map_delete_elem(map_fd, &key) == 0);
+ assert(bpf_map_delete_elem(map_fd, &key) == -1 && errno == ENOENT);
key = 0;
/* check that map is empty */
- assert(bpf_get_next_key(map_fd, &key, &next_key) == -1 &&
+ assert(bpf_map_get_next_key(map_fd, &key, &next_key) == -1 &&
errno == ENOENT);
close(map_fd);
}
@@ -103,41 +103,41 @@ static void test_arraymap_sanity(int i, void *data)
key = 1;
value = 1234;
/* insert key=1 element */
- assert(bpf_update_elem(map_fd, &key, &value, BPF_ANY) == 0);
+ assert(bpf_map_update_elem(map_fd, &key, &value, BPF_ANY) == 0);
value = 0;
- assert(bpf_update_elem(map_fd, &key, &value, BPF_NOEXIST) == -1 &&
+ assert(bpf_map_update_elem(map_fd, &key, &value, BPF_NOEXIST) == -1 &&
errno == EEXIST);
/* check that key=1 can be found */
- assert(bpf_lookup_elem(map_fd, &key, &value) == 0 && value == 1234);
+ assert(bpf_map_lookup_elem(map_fd, &key, &value) == 0 && value == 1234);
key = 0;
/* check that key=0 is also found and zero initialized */
- assert(bpf_lookup_elem(map_fd, &key, &value) == 0 && value == 0);
+ assert(bpf_map_lookup_elem(map_fd, &key, &value) == 0 && value == 0);
/* key=0 and key=1 were inserted, check that key=2 cannot be inserted
* due to max_entries limit
*/
key = 2;
- assert(bpf_update_elem(map_fd, &key, &value, BPF_EXIST) == -1 &&
+ assert(bpf_map_update_elem(map_fd, &key, &value, BPF_EXIST) == -1 &&
errno == E2BIG);
/* check that key = 2 doesn't exist */
- assert(bpf_lookup_elem(map_fd, &key, &value) == -1 && errno == ENOENT);
+ assert(bpf_map_lookup_elem(map_fd, &key, &value) == -1 && errno == ENOENT);
/* iterate over two elements */
- assert(bpf_get_next_key(map_fd, &key, &next_key) == 0 &&
+ assert(bpf_map_get_next_key(map_fd, &key, &next_key) == 0 &&
next_key == 0);
- assert(bpf_get_next_key(map_fd, &next_key, &next_key) == 0 &&
+ assert(bpf_map_get_next_key(map_fd, &next_key, &next_key) == 0 &&
next_key == 1);
- assert(bpf_get_next_key(map_fd, &next_key, &next_key) == -1 &&
+ assert(bpf_map_get_next_key(map_fd, &next_key, &next_key) == -1 &&
errno == ENOENT);
/* delete shouldn't succeed */
key = 1;
- assert(bpf_delete_elem(map_fd, &key) == -1 && errno == EINVAL);
+ assert(bpf_map_delete_elem(map_fd, &key) == -1 && errno == EINVAL);
close(map_fd);
}
@@ -163,21 +163,21 @@ static void test_map_large(void)
for (i = 0; i < MAP_SIZE; i++) {
key = (struct bigkey) {.c = i};
value = i;
- assert(bpf_update_elem(map_fd, &key, &value, BPF_NOEXIST) == 0);
+ assert(bpf_map_update_elem(map_fd, &key, &value, BPF_NOEXIST) == 0);
}
key.c = -1;
- assert(bpf_update_elem(map_fd, &key, &value, BPF_NOEXIST) == -1 &&
+ assert(bpf_map_update_elem(map_fd, &key, &value, BPF_NOEXIST) == -1 &&
errno == E2BIG);
/* iterate through all elements */
for (i = 0; i < MAP_SIZE; i++)
- assert(bpf_get_next_key(map_fd, &key, &key) == 0);
- assert(bpf_get_next_key(map_fd, &key, &key) == -1 && errno == ENOENT);
+ assert(bpf_map_get_next_key(map_fd, &key, &key) == 0);
+ assert(bpf_map_get_next_key(map_fd, &key, &key) == -1 && errno == ENOENT);
key.c = 0;
- assert(bpf_lookup_elem(map_fd, &key, &value) == 0 && value == 0);
+ assert(bpf_map_lookup_elem(map_fd, &key, &value) == 0 && value == 0);
key.a = 1;
- assert(bpf_lookup_elem(map_fd, &key, &value) == -1 && errno == ENOENT);
+ assert(bpf_map_lookup_elem(map_fd, &key, &value) == -1 && errno == ENOENT);
close(map_fd);
}
@@ -225,9 +225,9 @@ static void do_work(int fn, void *data)
for (i = fn; i < MAP_SIZE; i += TASKS) {
key = value = i;
if (do_update)
- assert(bpf_update_elem(map_fd, &key, &value, BPF_NOEXIST) == 0);
+ assert(bpf_map_update_elem(map_fd, &key, &value, BPF_NOEXIST) == 0);
else
- assert(bpf_delete_elem(map_fd, &key) == 0);
+ assert(bpf_map_delete_elem(map_fd, &key) == 0);
}
}
@@ -254,19 +254,19 @@ static void test_map_parallel(void)
run_parallel(TASKS, do_work, data);
/* check that key=0 is already there */
- assert(bpf_update_elem(map_fd, &key, &value, BPF_NOEXIST) == -1 &&
+ assert(bpf_map_update_elem(map_fd, &key, &value, BPF_NOEXIST) == -1 &&
errno == EEXIST);
/* check that all elements were inserted */
key = -1;
for (i = 0; i < MAP_SIZE; i++)
- assert(bpf_get_next_key(map_fd, &key, &key) == 0);
- assert(bpf_get_next_key(map_fd, &key, &key) == -1 && errno == ENOENT);
+ assert(bpf_map_get_next_key(map_fd, &key, &key) == 0);
+ assert(bpf_map_get_next_key(map_fd, &key, &key) == -1 && errno == ENOENT);
/* another check for all elements */
for (i = 0; i < MAP_SIZE; i++) {
key = MAP_SIZE - i - 1;
- assert(bpf_lookup_elem(map_fd, &key, &value) == 0 &&
+ assert(bpf_map_lookup_elem(map_fd, &key, &value) == 0 &&
value == key);
}
@@ -276,7 +276,7 @@ static void test_map_parallel(void)
/* nothing should be left */
key = -1;
- assert(bpf_get_next_key(map_fd, &key, &key) == -1 && errno == ENOENT);
+ assert(bpf_map_get_next_key(map_fd, &key, &key) == -1 && errno == ENOENT);
}
int main(void)
@@ -17,13 +17,17 @@
#include <stddef.h>
#include <stdbool.h>
#include <sys/resource.h>
-#include "libbpf.h"
+#include "utils.h"
+#include <bpf/bpf.h>
#define MAX_INSNS 512
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
#define MAX_FIXUPS 8
+#define LOG_BUF_SIZE 65536
+static char bpf_log_buf[LOG_BUF_SIZE];
+
struct bpf_test {
const char *descr;
struct bpf_insn insns[MAX_INSNS];
@@ -1250,9 +1254,10 @@ static int test(void)
}
printf("#%d %s ", i, tests[i].descr);
- prog_fd = bpf_prog_load(prog_type ?: BPF_PROG_TYPE_SOCKET_FILTER,
- prog, prog_len * sizeof(struct bpf_insn),
- "GPL", 0);
+ bpf_log_buf[0] = '\0';
+ prog_fd = bpf_load_program(prog_type ?: BPF_PROG_TYPE_SOCKET_FILTER,
+ prog, prog_len, "GPL", 0,
+ bpf_log_buf, sizeof(bpf_log_buf));
if (unpriv && tests[i].result_unpriv != UNDEF)
expected_result = tests[i].result_unpriv;
@@ -19,8 +19,7 @@
#include <sys/mman.h>
#include <time.h>
#include <signal.h>
-#include "libbpf.h"
-#include "bpf_load.h"
+#include "utils.h"
static int pmu_fd;
@@ -61,7 +60,7 @@ struct perf_event_sample {
char data[];
};
-void perf_event_read(print_fn fn)
+static void perf_event_read(print_fn fn)
{
__u64 data_tail = header->data_tail;
__u64 data_head = header->data_head;
@@ -150,7 +149,7 @@ static void print_bpf_output(void *data, int size)
}
}
-static void test_bpf_perf_event(void)
+static void test_bpf_perf_event(int map_fd)
{
struct perf_event_attr attr = {
.sample_type = PERF_SAMPLE_RAW,
@@ -162,7 +161,7 @@ static void test_bpf_perf_event(void)
pmu_fd = perf_event_open(&attr, -1/*pid*/, 0/*cpu*/, -1/*group_fd*/, 0);
assert(pmu_fd >= 0);
- assert(bpf_update_elem(map_fd[0], &key, &pmu_fd, BPF_ANY) == 0);
+ assert(bpf_map_update_elem(map_fd, &key, &pmu_fd, BPF_ANY) == 0);
ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0);
}
@@ -170,15 +169,15 @@ int main(int argc, char **argv)
{
char filename[256];
FILE *f;
+ struct bpf_object *obj;
snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
- if (load_bpf_file(filename)) {
- printf("%s", bpf_log_buf);
+ obj = load_bpf_file(filename);
+ if (!obj)
return 1;
- }
- test_bpf_perf_event();
+ test_bpf_perf_event(get_map_fd(obj, 0));
if (perf_event_mmap(pmu_fd) < 0)
return 1;
@@ -1,20 +1,19 @@
#include <stdio.h>
#include <linux/bpf.h>
#include <unistd.h>
-#include "libbpf.h"
-#include "bpf_load.h"
+#include "utils.h"
int main(int ac, char **argv)
{
FILE *f;
char filename[256];
+ struct bpf_object *obj;
snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
- if (load_bpf_file(filename)) {
- printf("%s", bpf_log_buf);
+ obj = load_bpf_file(filename);
+ if (!obj)
return 1;
- }
f = popen("taskset 1 ping -c5 localhost", "r");
(void) f;
@@ -4,8 +4,9 @@
#include <signal.h>
#include <linux/bpf.h>
#include <string.h>
-#include "libbpf.h"
-#include "bpf_load.h"
+#include <bpf/libbpf.h>
+#include <bpf/bpf.h>
+#include "utils.h"
#define MAX_INDEX 64
#define MAX_STARS 38
@@ -44,12 +45,12 @@ static void print_hist_for_pid(int fd, void *task)
long max_value = 0;
int i, ind;
- while (bpf_get_next_key(fd, &key, &next_key) == 0) {
+ while (bpf_map_get_next_key(fd, &key, &next_key) == 0) {
if (memcmp(&next_key, task, SIZE)) {
key = next_key;
continue;
}
- bpf_lookup_elem(fd, &next_key, &value);
+ bpf_map_lookup_elem(fd, &next_key, &value);
ind = next_key.index;
data[ind] = value;
if (value && ind > max_ind)
@@ -76,7 +77,7 @@ static void print_hist(int fd)
int task_cnt = 0;
int i;
- while (bpf_get_next_key(fd, &key, &next_key) == 0) {
+ while (bpf_map_get_next_key(fd, &key, &next_key) == 0) {
int found = 0;
for (i = 0; i < task_cnt; i++)
@@ -97,9 +98,11 @@ static void print_hist(int fd)
}
+static int hist_map_fd;
+
static void int_exit(int sig)
{
- print_hist(map_fd[1]);
+ print_hist(hist_map_fd);
exit(0);
}
@@ -108,7 +111,8 @@ int main(int ac, char **argv)
char filename[256];
long key, next_key, value;
FILE *f;
- int i;
+ int i, map_fd;
+ struct bpf_object *obj;
snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
@@ -122,15 +126,16 @@ int main(int ac, char **argv)
f = popen("dd if=/dev/zero of=/dev/null count=5000000", "r");
(void) f;
- if (load_bpf_file(filename)) {
- printf("%s", bpf_log_buf);
+ obj = load_bpf_file(filename);
+ if (!obj)
return 1;
- }
+ map_fd = get_map_fd(obj, 0);
+ hist_map_fd = get_map_fd(obj, 1);
for (i = 0; i < 5; i++) {
key = 0;
- while (bpf_get_next_key(map_fd[0], &key, &next_key) == 0) {
- bpf_lookup_elem(map_fd[0], &next_key, &value);
+ while (bpf_map_get_next_key(map_fd, &key, &next_key) == 0) {
+ bpf_map_lookup_elem(map_fd, &next_key, &value);
printf("location 0x%lx count %ld\n", next_key, value);
key = next_key;
}
@@ -138,7 +143,7 @@ int main(int ac, char **argv)
printf("\n");
sleep(1);
}
- print_hist(map_fd[1]);
+ print_hist(hist_map_fd);
return 0;
}
@@ -11,8 +11,7 @@
#include <stdbool.h>
#include <string.h>
#include <linux/bpf.h>
-#include "libbpf.h"
-#include "bpf_load.h"
+#include "utils.h"
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
@@ -24,7 +23,7 @@ static void clear_stats(int fd)
__u64 value = 0;
for (key = 0; key < SLOTS; key++)
- bpf_update_elem(fd, &key, &value, BPF_ANY);
+ bpf_map_update_elem(fd, &key, &value, BPF_ANY);
}
const char *color[] = {
@@ -83,7 +82,7 @@ static void print_hist(int fd)
for (key = 0; key < SLOTS; key++) {
value = 0;
- bpf_lookup_elem(fd, &key, &value);
+ bpf_map_lookup_elem(fd, &key, &value);
cnt[key] = value;
total_events += value;
if (value > max_cnt)
@@ -105,13 +104,13 @@ int main(int ac, char **argv)
{
char filename[256];
int i;
+ struct bpf_object *obj;
snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
- if (load_bpf_file(filename)) {
- printf("%s", bpf_log_buf);
+ obj = load_bpf_file(filename);
+ if (!obj)
return 1;
- }
for (i = 1; i < ac; i++) {
if (strcmp(argv[i], "-a") == 0) {
@@ -142,7 +141,7 @@ int main(int ac, char **argv)
for (i = 0; ; i++) {
if (i % 20 == 0)
print_banner();
- print_hist(map_fd[1]);
+ print_hist(get_map_fd(obj, 1));
sleep(2);
}
@@ -12,8 +12,7 @@
#include <string.h>
#include <time.h>
#include <linux/bpf.h>
-#include "libbpf.h"
-#include "bpf_load.h"
+#include "utils.h"
struct pair {
long long val;
@@ -37,8 +36,8 @@ static void print_old_objects(int fd)
key = write(1, "\e[1;1H\e[2J", 12); /* clear screen */
key = -1;
- while (bpf_get_next_key(map_fd[0], &key, &next_key) == 0) {
- bpf_lookup_elem(map_fd[0], &next_key, &v);
+ while (bpf_map_get_next_key(fd, &key, &next_key) == 0) {
+ bpf_map_lookup_elem(fd, &next_key, &v);
key = next_key;
if (val - v.val < 1000000000ll)
/* object was allocated more then 1 sec ago */
@@ -51,17 +50,17 @@ static void print_old_objects(int fd)
int main(int ac, char **argv)
{
char filename[256];
+ struct bpf_object *obj;
int i;
snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
- if (load_bpf_file(filename)) {
- printf("%s", bpf_log_buf);
+ obj = load_bpf_file(filename);
+ if (!obj)
return 1;
- }
for (i = 0; ; i++) {
- print_old_objects(map_fd[1]);
+ print_old_objects(get_map_fd(obj, 0));
sleep(1);
}
@@ -4,8 +4,7 @@
#include <linux/filter.h>
#include <linux/seccomp.h>
#include <sys/prctl.h>
-#include "libbpf.h"
-#include "bpf_load.h"
+#include "utils.h"
/* install fake seccomp program to enable seccomp code path inside the kernel,
* so that our kprobe attached to seccomp_phase1() can be triggered
@@ -27,13 +26,13 @@ int main(int ac, char **argv)
{
FILE *f;
char filename[256];
+ struct bpf_object *obj;
snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
- if (load_bpf_file(filename)) {
- printf("%s", bpf_log_buf);
+ obj = load_bpf_file(filename);
+ if (!obj)
return 1;
- }
install_accept_all_seccomp();
@@ -8,12 +8,11 @@
#include <sys/ioctl.h>
#include <linux/perf_event.h>
#include <linux/bpf.h>
-#include "libbpf.h"
-#include "bpf_load.h"
+#include "utils.h"
#define SAMPLE_PERIOD 0x7fffffffffffffffULL
-static void test_bpf_perf_event(void)
+static void test_bpf_perf_event(int map_fd)
{
int nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
int *pmu_fd = malloc(nr_cpus * sizeof(int));
@@ -36,7 +35,7 @@ static void test_bpf_perf_event(void)
goto exit;
}
- bpf_update_elem(map_fd[0], &i, &pmu_fd[i], BPF_ANY);
+ bpf_map_update_elem(map_fd, &i, &pmu_fd[i], BPF_ANY);
ioctl(pmu_fd[i], PERF_EVENT_IOC_ENABLE, 0);
}
@@ -50,22 +49,21 @@ static void test_bpf_perf_event(void)
exit:
for (i = 0; i < nr_cpus; i++)
close(pmu_fd[i]);
- close(map_fd[0]);
free(pmu_fd);
}
int main(int argc, char **argv)
{
char filename[256];
+ struct bpf_object *obj;
snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
- if (load_bpf_file(filename)) {
- printf("%s", bpf_log_buf);
+ obj = load_bpf_file(filename);
+ if (!obj)
return 1;
- }
- test_bpf_perf_event();
+ test_bpf_perf_event(get_map_fd(obj, 0));
read_trace_pipe();
return 0;
Since we already have libbpf in tools/lib, there's no need to maintain a duplicate BPF loading and operations library in samples. This patch utilises previous introduced utils.[ch], which calls libbpf to do these work. The main changing in this relative large patch is very simple: 1. Makefile modification, makes all hostprogs depend on libbpf.a. Add include and library searching patch and rules for linker. Remove old bpf_load.o and libbpf.o, replaces them with utils.o 2. Make sure there are correct 'version' section so the BPF source files can be loaded by libbpf. 3. Uses API provided by utils.h and libbpf. Signed-off-by: Wang Nan <wangnan0@huawei.com> Cc: Alexei Starovoitov <ast@kernel.org> Cc: Alex Gartrell <agartrell@fb.com> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Brenden Blanco <bblanco@plumgrid.com> Cc: Daniel Borkmann <daniel@iogearbox.net> Cc: Daniel Wagner <daniel.wagner@bmw-carit.de> Cc: David S. Miller <davem@davemloft.net> Cc: Ingo Molnar <mingo@kernel.org> Cc: Kaixu Xia <xiakaixu@huawei.com> Cc: Michael Holzheu <holzheu@linux.vnet.ibm.com> Cc: Yang Shi <yang.shi@linaro.org> --- samples/bpf/Makefile | 65 ++++++++++++++++++--------------- samples/bpf/fds_example.c | 26 +++++++------- samples/bpf/lathist_user.c | 13 ++++--- samples/bpf/sock_example.c | 13 +++---- samples/bpf/sockex1_kern.c | 2 ++ samples/bpf/sockex1_user.c | 27 ++++++++------ samples/bpf/sockex2_kern.c | 2 ++ samples/bpf/sockex2_user.c | 26 ++++++++------ samples/bpf/sockex3_kern.c | 2 ++ samples/bpf/sockex3_user.c | 23 +++++++----- samples/bpf/test_maps.c | 80 ++++++++++++++++++++--------------------- samples/bpf/test_verifier.c | 13 ++++--- samples/bpf/trace_output_user.c | 17 +++++---- samples/bpf/tracex1_user.c | 9 +++-- samples/bpf/tracex2_user.c | 31 +++++++++------- samples/bpf/tracex3_user.c | 15 ++++---- samples/bpf/tracex4_user.c | 15 ++++---- samples/bpf/tracex5_user.c | 9 +++-- samples/bpf/tracex6_user.c | 16 ++++----- 19 files changed, 221 insertions(+), 183 deletions(-) -- 1.8.3.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/