Skip to content

Commit

Permalink
Add a test that exercises a basic sockmap / sockhash iteration. For
Browse files Browse the repository at this point in the history
now we simply count the number of elements seen. Once sockmap update
from iterators works we can extend this to perform a full copy.

Signed-off-by: Lorenz Bauer <lmb@cloudflare.com>
---
 .../selftests/bpf/prog_tests/sockmap_basic.c  | 89 +++++++++++++++++++
 tools/testing/selftests/bpf/progs/bpf_iter.h  |  9 ++
 .../selftests/bpf/progs/bpf_iter_sockmap.c    | 43 +++++++++
 .../selftests/bpf/progs/bpf_iter_sockmap.h    |  3 +
 4 files changed, 144 insertions(+)
 create mode 100644 tools/testing/selftests/bpf/progs/bpf_iter_sockmap.c
 create mode 100644 tools/testing/selftests/bpf/progs/bpf_iter_sockmap.h
  • Loading branch information
lmb authored and kernel-patches-bot committed Sep 9, 2020
1 parent f7bac72 commit 74636e2
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 0 deletions.
89 changes: 89 additions & 0 deletions tools/testing/selftests/bpf/prog_tests/sockmap_basic.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
#include "test_skmsg_load_helpers.skel.h"
#include "test_sockmap_update.skel.h"
#include "test_sockmap_invalid_update.skel.h"
#include "bpf_iter_sockmap.skel.h"

#include "progs/bpf_iter_sockmap.h"

#define TCP_REPAIR 19 /* TCP sock is under repair right now */

Expand Down Expand Up @@ -171,6 +174,88 @@ static void test_sockmap_invalid_update(void)
test_sockmap_invalid_update__destroy(skel);
}

static void test_sockmap_iter(enum bpf_map_type map_type)
{
DECLARE_LIBBPF_OPTS(bpf_iter_attach_opts, opts);
int err, len, src_fd, iter_fd, duration;
union bpf_iter_link_info linfo = {0};
__s64 sock_fd[SOCKMAP_MAX_ENTRIES];
__u32 i, num_sockets, max_elems;
struct bpf_iter_sockmap *skel;
struct bpf_link *link;
struct bpf_map *src;
char buf[64];

skel = bpf_iter_sockmap__open_and_load();
if (CHECK(!skel, "bpf_iter_sockmap__open_and_load", "skeleton open_and_load failed\n"))
return;

for (i = 0; i < ARRAY_SIZE(sock_fd); i++)
sock_fd[i] = -1;

/* Make sure we have at least one "empty" entry to test iteration of
* an empty slot.
*/
num_sockets = ARRAY_SIZE(sock_fd) - 1;

if (map_type == BPF_MAP_TYPE_SOCKMAP) {
src = skel->maps.sockmap;
max_elems = bpf_map__max_entries(src);
} else {
src = skel->maps.sockhash;
max_elems = num_sockets;
}

src_fd = bpf_map__fd(src);

for (i = 0; i < num_sockets; i++) {
sock_fd[i] = connected_socket_v4();
if (CHECK(sock_fd[i] == -1, "connected_socket_v4", "cannot connect\n"))
goto out;

err = bpf_map_update_elem(src_fd, &i, &sock_fd[i], BPF_NOEXIST);
if (CHECK(err, "map_update", "failed: %s\n", strerror(errno)))
goto out;
}

linfo.map.map_fd = src_fd;
opts.link_info = &linfo;
opts.link_info_len = sizeof(linfo);
link = bpf_program__attach_iter(skel->progs.count_elems, &opts);
if (CHECK(IS_ERR(link), "attach_iter", "attach_iter failed\n"))
goto out;

iter_fd = bpf_iter_create(bpf_link__fd(link));
if (CHECK(iter_fd < 0, "create_iter", "create_iter failed\n"))
goto free_link;

/* do some tests */
while ((len = read(iter_fd, buf, sizeof(buf))) > 0)
;
if (CHECK(len < 0, "read", "failed: %s\n", strerror(errno)))
goto close_iter;

/* test results */
if (CHECK(skel->bss->elems != max_elems, "elems", "got %u expected %u\n",
skel->bss->elems, max_elems))
goto close_iter;

if (CHECK(skel->bss->socks != num_sockets, "socks", "got %u expected %u\n",
skel->bss->socks, num_sockets))
goto close_iter;

close_iter:
close(iter_fd);
free_link:
bpf_link__destroy(link);
out:
for (i = 0; i < num_sockets; i++) {
if (sock_fd[i] >= 0)
close(sock_fd[i]);
}
bpf_iter_sockmap__destroy(skel);
}

void test_sockmap_basic(void)
{
if (test__start_subtest("sockmap create_update_free"))
Expand All @@ -187,4 +272,8 @@ void test_sockmap_basic(void)
test_sockmap_update(BPF_MAP_TYPE_SOCKHASH);
if (test__start_subtest("sockmap update in unsafe context"))
test_sockmap_invalid_update();
if (test__start_subtest("sockmap iter"))
test_sockmap_iter(BPF_MAP_TYPE_SOCKMAP);
if (test__start_subtest("sockhash iter"))
test_sockmap_iter(BPF_MAP_TYPE_SOCKHASH);
}
9 changes: 9 additions & 0 deletions tools/testing/selftests/bpf/progs/bpf_iter.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#define udp6_sock udp6_sock___not_used
#define bpf_iter__bpf_map_elem bpf_iter__bpf_map_elem___not_used
#define bpf_iter__bpf_sk_storage_map bpf_iter__bpf_sk_storage_map___not_used
#define bpf_iter__sockmap bpf_iter__sockmap___not_used
#include "vmlinux.h"
#undef bpf_iter_meta
#undef bpf_iter__bpf_map
Expand All @@ -26,6 +27,7 @@
#undef udp6_sock
#undef bpf_iter__bpf_map_elem
#undef bpf_iter__bpf_sk_storage_map
#undef bpf_iter__sockmap

struct bpf_iter_meta {
struct seq_file *seq;
Expand Down Expand Up @@ -96,3 +98,10 @@ struct bpf_iter__bpf_sk_storage_map {
struct sock *sk;
void *value;
};

struct bpf_iter__sockmap {
struct bpf_iter_meta *meta;
struct bpf_map *map;
void *key;
struct sock *sk;
};
43 changes: 43 additions & 0 deletions tools/testing/selftests/bpf/progs/bpf_iter_sockmap.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2020 Cloudflare */
#include "bpf_iter.h"
#include "bpf_tracing_net.h"
#include "bpf_iter_sockmap.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <errno.h>

char _license[] SEC("license") = "GPL";

struct {
__uint(type, BPF_MAP_TYPE_SOCKMAP);
__uint(max_entries, SOCKMAP_MAX_ENTRIES);
__type(key, __u32);
__type(value, __u64);
} sockmap SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_SOCKHASH);
__uint(max_entries, SOCKMAP_MAX_ENTRIES);
__type(key, __u32);
__type(value, __u64);
} sockhash SEC(".maps");

__u32 elems = 0;
__u32 socks = 0;

SEC("iter/sockmap")
int count_elems(struct bpf_iter__sockmap *ctx)
{
struct sock *sk = ctx->sk;
__u32 tmp, *key = ctx->key;
int ret;

if (key)
elems++;

if (sk)
socks++;

return 0;
}
3 changes: 3 additions & 0 deletions tools/testing/selftests/bpf/progs/bpf_iter_sockmap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/* SPDX-License-Identifier: GPL-2.0 */

#define SOCKMAP_MAX_ENTRIES (64)

0 comments on commit 74636e2

Please sign in to comment.