Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
Alexei Starovoitov says: ==================== pull-request: bpf 2019-12-05 The following pull-request contains BPF updates for your *net* tree. We've added 6 non-merge commits during the last 1 day(s) which contain a total of 14 files changed, 116 insertions(+), 37 deletions(-). The main changes are: 1) three selftests fixes, from Stanislav. 2) one samples fix, from Jesper. 3) one verifier fix, from Yonghong. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
ae72555b41
@ -9636,7 +9636,10 @@ static int check_attach_btf_id(struct bpf_verifier_env *env)
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
addr = (long) tgt_prog->aux->func[subprog]->bpf_func;
|
||||
if (subprog == 0)
|
||||
addr = (long) tgt_prog->bpf_func;
|
||||
else
|
||||
addr = (long) tgt_prog->aux->func[subprog]->bpf_func;
|
||||
} else {
|
||||
addr = kallsyms_lookup_name(tname);
|
||||
if (!addr) {
|
||||
|
@ -489,9 +489,9 @@ int main(int argc, char **argv)
|
||||
if (bpf_prog_load_xattr(&prog_load_attr, &obj, &prog_fd))
|
||||
return EXIT_FAIL;
|
||||
|
||||
map = bpf_map__next(NULL, obj);
|
||||
stats_global_map = bpf_map__next(map, obj);
|
||||
rx_queue_index_map = bpf_map__next(stats_global_map, obj);
|
||||
map = bpf_object__find_map_by_name(obj, "config_map");
|
||||
stats_global_map = bpf_object__find_map_by_name(obj, "stats_global_map");
|
||||
rx_queue_index_map = bpf_object__find_map_by_name(obj, "rx_queue_index_map");
|
||||
if (!map || !stats_global_map || !rx_queue_index_map) {
|
||||
printf("finding a map in obj file failed\n");
|
||||
return EXIT_FAIL;
|
||||
|
1
tools/lib/bpf/.gitignore
vendored
1
tools/lib/bpf/.gitignore
vendored
@ -1,7 +1,6 @@
|
||||
libbpf_version.h
|
||||
libbpf.pc
|
||||
FEATURE-DUMP.libbpf
|
||||
test_libbpf
|
||||
libbpf.so.*
|
||||
TAGS
|
||||
tags
|
||||
|
@ -152,7 +152,7 @@ GLOBAL_SYM_COUNT = $(shell readelf -s --wide $(BPF_IN_SHARED) | \
|
||||
VERSIONED_SYM_COUNT = $(shell readelf -s --wide $(OUTPUT)libbpf.so | \
|
||||
grep -Eo '[^ ]+@LIBBPF_' | cut -d@ -f1 | sort -u | wc -l)
|
||||
|
||||
CMD_TARGETS = $(LIB_TARGET) $(PC_FILE) $(OUTPUT)test_libbpf
|
||||
CMD_TARGETS = $(LIB_TARGET) $(PC_FILE)
|
||||
|
||||
all: fixdep
|
||||
$(Q)$(MAKE) all_cmd
|
||||
@ -196,9 +196,6 @@ $(OUTPUT)libbpf.so.$(LIBBPF_VERSION): $(BPF_IN_SHARED)
|
||||
$(OUTPUT)libbpf.a: $(BPF_IN_STATIC)
|
||||
$(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^
|
||||
|
||||
$(OUTPUT)test_libbpf: test_libbpf.c $(OUTPUT)libbpf.a
|
||||
$(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(INCLUDES) $^ -lelf -o $@
|
||||
|
||||
$(OUTPUT)libbpf.pc:
|
||||
$(QUIET_GEN)sed -e "s|@PREFIX@|$(prefix)|" \
|
||||
-e "s|@LIBDIR@|$(libdir_SQ)|" \
|
||||
|
1
tools/testing/selftests/bpf/.gitignore
vendored
1
tools/testing/selftests/bpf/.gitignore
vendored
@ -37,5 +37,6 @@ libbpf.so.*
|
||||
test_hashmap
|
||||
test_btf_dump
|
||||
xdping
|
||||
test_cpp
|
||||
/no_alu32
|
||||
/bpf_gcc
|
||||
|
@ -71,7 +71,7 @@ TEST_PROGS_EXTENDED := with_addr.sh \
|
||||
# Compile but not part of 'make run_tests'
|
||||
TEST_GEN_PROGS_EXTENDED = test_sock_addr test_skb_cgroup_id_user \
|
||||
flow_dissector_load test_flow_dissector test_tcp_check_syncookie_user \
|
||||
test_lirc_mode2_user xdping
|
||||
test_lirc_mode2_user xdping test_cpp
|
||||
|
||||
TEST_CUSTOM_PROGS = urandom_read
|
||||
|
||||
@ -317,6 +317,10 @@ verifier/tests.h: verifier/*.c
|
||||
$(OUTPUT)/test_verifier: test_verifier.c verifier/tests.h $(BPFOBJ) | $(OUTPUT)
|
||||
$(CC) $(CFLAGS) $(filter %.a %.o %.c,$^) $(LDLIBS) -o $@
|
||||
|
||||
# Make sure we are able to include and link libbpf against c++.
|
||||
$(OUTPUT)/test_cpp: test_cpp.cpp $(BPFOBJ)
|
||||
$(CXX) $(CFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
EXTRA_CLEAN := $(TEST_CUSTOM_PROGS) \
|
||||
prog_tests/tests.h map_tests/tests.h verifier/tests.h \
|
||||
feature $(OUTPUT)/*.o $(OUTPUT)/no_alu32 $(OUTPUT)/bpf_gcc
|
||||
|
@ -2,25 +2,21 @@
|
||||
/* Copyright (c) 2019 Facebook */
|
||||
#include <test_progs.h>
|
||||
|
||||
#define PROG_CNT 3
|
||||
|
||||
void test_fexit_bpf2bpf(void)
|
||||
static void test_fexit_bpf2bpf_common(const char *obj_file,
|
||||
const char *target_obj_file,
|
||||
int prog_cnt,
|
||||
const char **prog_name)
|
||||
{
|
||||
const char *prog_name[PROG_CNT] = {
|
||||
"fexit/test_pkt_access",
|
||||
"fexit/test_pkt_access_subprog1",
|
||||
"fexit/test_pkt_access_subprog2",
|
||||
};
|
||||
struct bpf_object *obj = NULL, *pkt_obj;
|
||||
int err, pkt_fd, i;
|
||||
struct bpf_link *link[PROG_CNT] = {};
|
||||
struct bpf_program *prog[PROG_CNT];
|
||||
struct bpf_link **link = NULL;
|
||||
struct bpf_program **prog = NULL;
|
||||
__u32 duration, retval;
|
||||
struct bpf_map *data_map;
|
||||
const int zero = 0;
|
||||
u64 result[PROG_CNT];
|
||||
u64 *result = NULL;
|
||||
|
||||
err = bpf_prog_load("./test_pkt_access.o", BPF_PROG_TYPE_UNSPEC,
|
||||
err = bpf_prog_load(target_obj_file, BPF_PROG_TYPE_UNSPEC,
|
||||
&pkt_obj, &pkt_fd);
|
||||
if (CHECK(err, "prog_load sched cls", "err %d errno %d\n", err, errno))
|
||||
return;
|
||||
@ -28,7 +24,14 @@ void test_fexit_bpf2bpf(void)
|
||||
.attach_prog_fd = pkt_fd,
|
||||
);
|
||||
|
||||
obj = bpf_object__open_file("./fexit_bpf2bpf.o", &opts);
|
||||
link = calloc(sizeof(struct bpf_link *), prog_cnt);
|
||||
prog = calloc(sizeof(struct bpf_program *), prog_cnt);
|
||||
result = malloc(prog_cnt * sizeof(u64));
|
||||
if (CHECK(!link || !prog || !result, "alloc_memory",
|
||||
"failed to alloc memory"))
|
||||
goto close_prog;
|
||||
|
||||
obj = bpf_object__open_file(obj_file, &opts);
|
||||
if (CHECK(IS_ERR_OR_NULL(obj), "obj_open",
|
||||
"failed to open fexit_bpf2bpf: %ld\n",
|
||||
PTR_ERR(obj)))
|
||||
@ -38,7 +41,7 @@ void test_fexit_bpf2bpf(void)
|
||||
if (CHECK(err, "obj_load", "err %d\n", err))
|
||||
goto close_prog;
|
||||
|
||||
for (i = 0; i < PROG_CNT; i++) {
|
||||
for (i = 0; i < prog_cnt; i++) {
|
||||
prog[i] = bpf_object__find_program_by_title(obj, prog_name[i]);
|
||||
if (CHECK(!prog[i], "find_prog", "prog %s not found\n", prog_name[i]))
|
||||
goto close_prog;
|
||||
@ -56,21 +59,54 @@ void test_fexit_bpf2bpf(void)
|
||||
"err %d errno %d retval %d duration %d\n",
|
||||
err, errno, retval, duration);
|
||||
|
||||
err = bpf_map_lookup_elem(bpf_map__fd(data_map), &zero, &result);
|
||||
err = bpf_map_lookup_elem(bpf_map__fd(data_map), &zero, result);
|
||||
if (CHECK(err, "get_result",
|
||||
"failed to get output data: %d\n", err))
|
||||
goto close_prog;
|
||||
|
||||
for (i = 0; i < PROG_CNT; i++)
|
||||
for (i = 0; i < prog_cnt; i++)
|
||||
if (CHECK(result[i] != 1, "result", "fexit_bpf2bpf failed err %ld\n",
|
||||
result[i]))
|
||||
goto close_prog;
|
||||
|
||||
close_prog:
|
||||
for (i = 0; i < PROG_CNT; i++)
|
||||
for (i = 0; i < prog_cnt; i++)
|
||||
if (!IS_ERR_OR_NULL(link[i]))
|
||||
bpf_link__destroy(link[i]);
|
||||
if (!IS_ERR_OR_NULL(obj))
|
||||
bpf_object__close(obj);
|
||||
bpf_object__close(pkt_obj);
|
||||
free(link);
|
||||
free(prog);
|
||||
free(result);
|
||||
}
|
||||
|
||||
static void test_target_no_callees(void)
|
||||
{
|
||||
const char *prog_name[] = {
|
||||
"fexit/test_pkt_md_access",
|
||||
};
|
||||
test_fexit_bpf2bpf_common("./fexit_bpf2bpf_simple.o",
|
||||
"./test_pkt_md_access.o",
|
||||
ARRAY_SIZE(prog_name),
|
||||
prog_name);
|
||||
}
|
||||
|
||||
static void test_target_yes_callees(void)
|
||||
{
|
||||
const char *prog_name[] = {
|
||||
"fexit/test_pkt_access",
|
||||
"fexit/test_pkt_access_subprog1",
|
||||
"fexit/test_pkt_access_subprog2",
|
||||
};
|
||||
test_fexit_bpf2bpf_common("./fexit_bpf2bpf.o",
|
||||
"./test_pkt_access.o",
|
||||
ARRAY_SIZE(prog_name),
|
||||
prog_name);
|
||||
}
|
||||
|
||||
void test_fexit_bpf2bpf(void)
|
||||
{
|
||||
test_target_no_callees();
|
||||
test_target_yes_callees();
|
||||
}
|
||||
|
26
tools/testing/selftests/bpf/progs/fexit_bpf2bpf_simple.c
Normal file
26
tools/testing/selftests/bpf/progs/fexit_bpf2bpf_simple.c
Normal file
@ -0,0 +1,26 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2019 Facebook */
|
||||
#include <linux/bpf.h>
|
||||
#include "bpf_helpers.h"
|
||||
#include "bpf_trace_helpers.h"
|
||||
|
||||
struct sk_buff {
|
||||
unsigned int len;
|
||||
};
|
||||
|
||||
__u64 test_result = 0;
|
||||
BPF_TRACE_2("fexit/test_pkt_md_access", test_main2,
|
||||
struct sk_buff *, skb, int, ret)
|
||||
{
|
||||
int len;
|
||||
|
||||
__builtin_preserve_access_index(({
|
||||
len = skb->len;
|
||||
}));
|
||||
if (len != 74 || ret != 0)
|
||||
return 0;
|
||||
|
||||
test_result = 1;
|
||||
return 0;
|
||||
}
|
||||
char _license[] SEC("license") = "GPL";
|
@ -27,8 +27,8 @@ int _version SEC("version") = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
SEC("test1")
|
||||
int process(struct __sk_buff *skb)
|
||||
SEC("classifier/test_pkt_md_access")
|
||||
int test_pkt_md_access(struct __sk_buff *skb)
|
||||
{
|
||||
TEST_FIELD(__u8, len, 0xFF);
|
||||
TEST_FIELD(__u16, len, 0xFFFF);
|
||||
|
@ -131,6 +131,7 @@ int bpf_testcb(struct bpf_sock_ops *skops)
|
||||
g.bytes_received = skops->bytes_received;
|
||||
g.bytes_acked = skops->bytes_acked;
|
||||
}
|
||||
g.num_close_events++;
|
||||
bpf_map_update_elem(&global_map, &key, &g,
|
||||
BPF_ANY);
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ int check_ancestor_cgroup_ids(int prog_id)
|
||||
int err = 0;
|
||||
int map_fd;
|
||||
|
||||
expected_ids[0] = 0x100000001; /* root cgroup */
|
||||
expected_ids[0] = get_cgroup_id("/.."); /* root cgroup */
|
||||
expected_ids[1] = get_cgroup_id("");
|
||||
expected_ids[2] = get_cgroup_id(CGROUP_PATH);
|
||||
expected_ids[3] = 0; /* non-existent cgroup */
|
||||
|
@ -13,5 +13,6 @@ struct tcpbpf_globals {
|
||||
__u64 bytes_received;
|
||||
__u64 bytes_acked;
|
||||
__u32 num_listen;
|
||||
__u32 num_close_events;
|
||||
};
|
||||
#endif
|
||||
|
@ -16,6 +16,9 @@
|
||||
|
||||
#include "test_tcpbpf.h"
|
||||
|
||||
/* 3 comes from one listening socket + both ends of the connection */
|
||||
#define EXPECTED_CLOSE_EVENTS 3
|
||||
|
||||
#define EXPECT_EQ(expected, actual, fmt) \
|
||||
do { \
|
||||
if ((expected) != (actual)) { \
|
||||
@ -23,13 +26,14 @@
|
||||
" Actual: %" fmt "\n" \
|
||||
" Expected: %" fmt "\n", \
|
||||
(actual), (expected)); \
|
||||
goto err; \
|
||||
ret--; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
int verify_result(const struct tcpbpf_globals *result)
|
||||
{
|
||||
__u32 expected_events;
|
||||
int ret = 0;
|
||||
|
||||
expected_events = ((1 << BPF_SOCK_OPS_TIMEOUT_INIT) |
|
||||
(1 << BPF_SOCK_OPS_RWND_INIT) |
|
||||
@ -48,15 +52,15 @@ int verify_result(const struct tcpbpf_globals *result)
|
||||
EXPECT_EQ(0x80, result->bad_cb_test_rv, PRIu32);
|
||||
EXPECT_EQ(0, result->good_cb_test_rv, PRIu32);
|
||||
EXPECT_EQ(1, result->num_listen, PRIu32);
|
||||
EXPECT_EQ(EXPECTED_CLOSE_EVENTS, result->num_close_events, PRIu32);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int verify_sockopt_result(int sock_map_fd)
|
||||
{
|
||||
__u32 key = 0;
|
||||
int ret = 0;
|
||||
int res;
|
||||
int rv;
|
||||
|
||||
@ -69,9 +73,7 @@ int verify_sockopt_result(int sock_map_fd)
|
||||
rv = bpf_map_lookup_elem(sock_map_fd, &key, &res);
|
||||
EXPECT_EQ(0, rv, "d");
|
||||
EXPECT_EQ(1, res, "d");
|
||||
return 0;
|
||||
err:
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bpf_find_map(const char *test, struct bpf_object *obj,
|
||||
@ -96,6 +98,7 @@ int main(int argc, char **argv)
|
||||
int error = EXIT_FAILURE;
|
||||
struct bpf_object *obj;
|
||||
int cg_fd = -1;
|
||||
int retry = 10;
|
||||
__u32 key = 0;
|
||||
int rv;
|
||||
|
||||
@ -134,12 +137,20 @@ int main(int argc, char **argv)
|
||||
if (sock_map_fd < 0)
|
||||
goto err;
|
||||
|
||||
retry_lookup:
|
||||
rv = bpf_map_lookup_elem(map_fd, &key, &g);
|
||||
if (rv != 0) {
|
||||
printf("FAILED: bpf_map_lookup_elem returns %d\n", rv);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (g.num_close_events != EXPECTED_CLOSE_EVENTS && retry--) {
|
||||
printf("Unexpected number of close events (%d), retrying!\n",
|
||||
g.num_close_events);
|
||||
usleep(100);
|
||||
goto retry_lookup;
|
||||
}
|
||||
|
||||
if (verify_result(&g)) {
|
||||
printf("FAILED: Wrong stats\n");
|
||||
goto err;
|
||||
|
Loading…
Reference in New Issue
Block a user