From: Wang Nan <wangnan0@huawei.com>
To: <ast@kernel.org>, <agartrell@fb.com>, <acme@redhat.com>,
<bblanco@plumgrid.com>, <daniel@iogearbox.net>,
<daniel.wagner@bmw-carit.de>, <davem@davemloft.net>,
<mingo@kernel.org>, <jolsa@kernel.org>, <xiakaixu@huawei.com>,
<holzheu@linux.vnet.ibm.com>, <yang.shi@linaro.org>
Cc: <linux-kernel@vger.kernel.org>, <pi3orama@163.com>,
Wang Nan <wangnan0@huawei.com>
Subject: [PATCH 09/10] bpf samples: Uses libbpf in tools/lib to deal with BPF operations
Date: Thu, 17 Dec 2015 05:23:13 +0000 [thread overview]
Message-ID: <1450329794-161948-10-git-send-email-wangnan0@huawei.com> (raw)
In-Reply-To: <1450329794-161948-1-git-send-email-wangnan0@huawei.com>
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(-)
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index edd638b..edb7c04 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -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
diff --git a/samples/bpf/fds_example.c b/samples/bpf/fds_example.c
index e2fd16c..bdcfce0 100644
--- a/samples/bpf/fds_example.c
+++ b/samples/bpf/fds_example.c
@@ -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);
}
diff --git a/samples/bpf/lathist_user.c b/samples/bpf/lathist_user.c
index 65da8c1..9160af8 100644
--- a/samples/bpf/lathist_user.c
+++ b/samples/bpf/lathist_user.c
@@ -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);
}
diff --git a/samples/bpf/sock_example.c b/samples/bpf/sock_example.c
index a0ce251..a6a875f 100644
--- a/samples/bpf/sock_example.c
+++ b/samples/bpf/sock_example.c
@@ -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);
diff --git a/samples/bpf/sockex1_kern.c b/samples/bpf/sockex1_kern.c
index ed18e9a..0ab3d9a 100644
--- a/samples/bpf/sockex1_kern.c
+++ b/samples/bpf/sockex1_kern.c
@@ -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;
diff --git a/samples/bpf/sockex1_user.c b/samples/bpf/sockex1_user.c
index 678ce46..d1ece36 100644
--- a/samples/bpf/sockex1_user.c
+++ b/samples/bpf/sockex1_user.c
@@ -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);
diff --git a/samples/bpf/sockex2_kern.c b/samples/bpf/sockex2_kern.c
index ba0e177..46e2e77 100644
--- a/samples/bpf/sockex2_kern.c
+++ b/samples/bpf/sockex2_kern.c
@@ -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;
diff --git a/samples/bpf/sockex2_user.c b/samples/bpf/sockex2_user.c
index 29a276d..3df6442 100644
--- a/samples/bpf/sockex2_user.c
+++ b/samples/bpf/sockex2_user.c
@@ -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);
diff --git a/samples/bpf/sockex3_kern.c b/samples/bpf/sockex3_kern.c
index 41ae2fd..6ac0d17 100644
--- a/samples/bpf/sockex3_kern.c
+++ b/samples/bpf/sockex3_kern.c
@@ -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;
diff --git a/samples/bpf/sockex3_user.c b/samples/bpf/sockex3_user.c
index 2617772..99a7126 100644
--- a/samples/bpf/sockex3_user.c
+++ b/samples/bpf/sockex3_user.c
@@ -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],
diff --git a/samples/bpf/test_maps.c b/samples/bpf/test_maps.c
index 6299ee9..435d55e 100644
--- a/samples/bpf/test_maps.c
+++ b/samples/bpf/test_maps.c
@@ -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)
diff --git a/samples/bpf/test_verifier.c b/samples/bpf/test_verifier.c
index 563c507..0566fc0 100644
--- a/samples/bpf/test_verifier.c
+++ b/samples/bpf/test_verifier.c
@@ -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;
diff --git a/samples/bpf/trace_output_user.c b/samples/bpf/trace_output_user.c
index 661a7d0..4ef02cb 100644
--- a/samples/bpf/trace_output_user.c
+++ b/samples/bpf/trace_output_user.c
@@ -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;
diff --git a/samples/bpf/tracex1_user.c b/samples/bpf/tracex1_user.c
index 31a4818..0652339 100644
--- a/samples/bpf/tracex1_user.c
+++ b/samples/bpf/tracex1_user.c
@@ -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;
diff --git a/samples/bpf/tracex2_user.c b/samples/bpf/tracex2_user.c
index cd0241c..86700bb 100644
--- a/samples/bpf/tracex2_user.c
+++ b/samples/bpf/tracex2_user.c
@@ -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;
}
diff --git a/samples/bpf/tracex3_user.c b/samples/bpf/tracex3_user.c
index 0aaa933..4c26a6f 100644
--- a/samples/bpf/tracex3_user.c
+++ b/samples/bpf/tracex3_user.c
@@ -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);
}
diff --git a/samples/bpf/tracex4_user.c b/samples/bpf/tracex4_user.c
index bc4a3bd..273bd33 100644
--- a/samples/bpf/tracex4_user.c
+++ b/samples/bpf/tracex4_user.c
@@ -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);
}
diff --git a/samples/bpf/tracex5_user.c b/samples/bpf/tracex5_user.c
index a04dd3c..bcbd7fc 100644
--- a/samples/bpf/tracex5_user.c
+++ b/samples/bpf/tracex5_user.c
@@ -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();
diff --git a/samples/bpf/tracex6_user.c b/samples/bpf/tracex6_user.c
index 8ea4976..a400e31 100644
--- a/samples/bpf/tracex6_user.c
+++ b/samples/bpf/tracex6_user.c
@@ -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;
--
1.8.3.4
next prev parent reply other threads:[~2015-12-17 5:30 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-12-17 5:23 [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do " Wang Nan
2015-12-17 5:23 ` [PATCH 01/10] bpf samples: bpf: Fix tracex5_kern.c compiling error Wang Nan
2015-12-17 5:23 ` [PATCH 02/10] bpf tools: Define LD and RM in Makefile for 'make -R' Wang Nan
2015-12-17 5:23 ` [PATCH 03/10] bpf tools: Add const decoretor to 'license' and 'insns' for bpf_load_program() Wang Nan
2015-12-17 5:23 ` [PATCH 04/10] bpf tools: Switch to uapi style type names Wang Nan
2015-12-17 5:23 ` [PATCH 05/10] bpf tools: Support load different type of programs Wang Nan
2015-12-17 5:23 ` [PATCH 06/10] bpf tools: Support new map operations Wang Nan
2015-12-17 6:06 ` Wangnan (F)
2015-12-17 6:09 ` [PATCH v2 " Wang Nan
2015-12-17 5:23 ` [PATCH 07/10] bpf tools: Support BPF_OBJ_PIN and BPF_OBJ_GET Wang Nan
2015-12-17 5:23 ` [PATCH 08/10] bpf samples: Add utils.[ch] for using BPF Wang Nan
2015-12-17 23:11 ` Alexei Starovoitov
2015-12-18 1:47 ` Wangnan (F)
2015-12-18 6:19 ` Alexei Starovoitov
2015-12-18 7:04 ` Wangnan (F)
2015-12-18 7:10 ` Wangnan (F)
2015-12-18 10:57 ` Daniel Borkmann
2015-12-18 11:18 ` pi3orama
2015-12-18 11:24 ` Daniel Borkmann
2015-12-19 0:35 ` Alexei Starovoitov
2015-12-17 5:23 ` Wang Nan [this message]
2015-12-17 5:23 ` [PATCH 10/10] bpf samples: Remove old BPF helpers Wang Nan
2015-12-17 6:38 ` [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations Daniel Wagner
2015-12-17 6:51 ` Wangnan (F)
2015-12-17 7:03 ` Daniel Wagner
2015-12-17 8:29 ` Daniel Wagner
2015-12-17 10:09 ` Wangnan (F)
2015-12-17 13:46 ` Daniel Wagner
2015-12-18 3:04 ` Wangnan (F)
2015-12-18 8:49 ` Daniel Wagner
2015-12-18 10:56 ` [PATCH] tools build: Output more data during feature detection Wang Nan
2015-12-18 11:03 ` [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations Wangnan (F)
2015-12-18 12:55 ` Daniel Wagner
2015-12-18 14:13 ` pi3orama
[not found] ` <66E52D4A-BA1C-456A-8E6F-975E07C083EE@163.com>
2015-12-18 14:22 ` Daniel Wagner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1450329794-161948-10-git-send-email-wangnan0@huawei.com \
--to=wangnan0@huawei.com \
--cc=acme@redhat.com \
--cc=agartrell@fb.com \
--cc=ast@kernel.org \
--cc=bblanco@plumgrid.com \
--cc=daniel.wagner@bmw-carit.de \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=holzheu@linux.vnet.ibm.com \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=pi3orama@163.com \
--cc=xiakaixu@huawei.com \
--cc=yang.shi@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®