Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpf: Enable bpf_skc_to_* sock casting helper to networking prog type #110

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
bpf: selftest: Use bpf_skc_to_tcp_sock() in the sock_fields test
This test uses bpf_skc_to_tcp_sock() to get a kernel tcp_sock ptr "ktp".
Access the ktp->lsndtime and also pass ktp to bpf_sk_storage_get().

It also exercises the bpf_sk_cgroup_id() and bpf_sk_ancestor_cgroup_id()
with the "ktp".  To do that, a parent cgroup and a child cgroup are
created.  The bpf prog is attached to the child cgroup.

Signed-off-by: Martin KaFai Lau <kafai@fb.com>
  • Loading branch information
iamkafai authored and kernel-patches-bot committed Sep 25, 2020
commit 1676417dbacced4ca16d083683957301eadc58be
40 changes: 33 additions & 7 deletions tools/testing/selftests/bpf/prog_tests/sock_fields.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,17 @@ struct bpf_spinlock_cnt {
__u32 cnt;
};

#define TEST_CGROUP "/test-bpf-sock-fields"
#define PARENT_CGROUP "/test-bpf-sock-fields"
#define CHILD_CGROUP "/test-bpf-sock-fields/child"
#define DATA "Hello BPF!"
#define DATA_LEN sizeof(DATA)

static struct sockaddr_in6 srv_sa6, cli_sa6;
static int sk_pkt_out_cnt10_fd;
struct test_sock_fields *skel;
static int sk_pkt_out_cnt_fd;
static __u64 parent_cg_id;
static __u64 child_cg_id;
static int linum_map_fd;
static __u32 duration;

Expand Down Expand Up @@ -142,6 +145,8 @@ static void check_result(void)
"srv_sk", "Unexpected. Check srv_sk output. egress_linum:%u\n",
egress_linum);

CHECK(!skel->bss->lsndtime, "srv_tp", "Unexpected lsndtime:0\n");

CHECK(cli_sk.state == 10 ||
!cli_sk.state ||
cli_sk.family != AF_INET6 ||
Expand Down Expand Up @@ -178,6 +183,14 @@ static void check_result(void)
cli_tp.bytes_received < 2 * DATA_LEN,
"cli_tp", "Unexpected. Check cli_tp output. egress_linum:%u\n",
egress_linum);

CHECK(skel->bss->parent_cg_id != parent_cg_id,
"parent_cg_id", "%zu != %zu\n",
(size_t)skel->bss->parent_cg_id, (size_t)parent_cg_id);

CHECK(skel->bss->child_cg_id != child_cg_id,
"child_cg_id", "%zu != %zu\n",
(size_t)skel->bss->child_cg_id, (size_t)child_cg_id);
}

static void check_sk_pkt_out_cnt(int accept_fd, int cli_fd)
Expand Down Expand Up @@ -319,25 +332,35 @@ static void test(void)
void test_sock_fields(void)
{
struct bpf_link *egress_link = NULL, *ingress_link = NULL;
int cgroup_fd;
int parent_cg_fd = -1, child_cg_fd = -1;

/* Create a cgroup, get fd, and join it */
cgroup_fd = test__join_cgroup(TEST_CGROUP);
if (CHECK_FAIL(cgroup_fd < 0))
parent_cg_fd = test__join_cgroup(PARENT_CGROUP);
if (CHECK_FAIL(parent_cg_fd < 0))
return;
parent_cg_id = get_cgroup_id(PARENT_CGROUP);
if (CHECK_FAIL(!parent_cg_id))
goto done;

child_cg_fd = test__join_cgroup(CHILD_CGROUP);
if (CHECK_FAIL(child_cg_fd < 0))
goto done;
child_cg_id = get_cgroup_id(CHILD_CGROUP);
if (CHECK_FAIL(!child_cg_id))
goto done;

skel = test_sock_fields__open_and_load();
if (CHECK(!skel, "test_sock_fields__open_and_load", "failed\n"))
goto done;

egress_link = bpf_program__attach_cgroup(skel->progs.egress_read_sock_fields,
cgroup_fd);
child_cg_fd);
if (CHECK(IS_ERR(egress_link), "attach_cgroup(egress)", "err:%ld\n",
PTR_ERR(egress_link)))
goto done;

ingress_link = bpf_program__attach_cgroup(skel->progs.ingress_read_sock_fields,
cgroup_fd);
child_cg_fd);
if (CHECK(IS_ERR(ingress_link), "attach_cgroup(ingress)", "err:%ld\n",
PTR_ERR(ingress_link)))
goto done;
Expand All @@ -352,5 +375,8 @@ void test_sock_fields(void)
bpf_link__destroy(egress_link);
bpf_link__destroy(ingress_link);
test_sock_fields__destroy(skel);
close(cgroup_fd);
if (child_cg_fd != -1)
close(child_cg_fd);
if (parent_cg_fd != -1)
close(parent_cg_fd);
}
24 changes: 22 additions & 2 deletions tools/testing/selftests/bpf/progs/test_sock_fields.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <bpf/bpf_helpers.h>
#include <bpf/bpf_endian.h>
#include "bpf_tcp_helpers.h"

enum bpf_linum_array_idx {
EGRESS_LINUM_IDX,
Expand Down Expand Up @@ -47,6 +48,9 @@ struct bpf_tcp_sock srv_tp = {};
struct bpf_sock listen_sk = {};
struct bpf_sock srv_sk = {};
struct bpf_sock cli_sk = {};
__u64 parent_cg_id = 0;
__u64 child_cg_id = 0;
__u64 lsndtime = 0;

static bool is_loopback6(__u32 *a6)
{
Expand Down Expand Up @@ -121,6 +125,7 @@ int egress_read_sock_fields(struct __sk_buff *skb)
struct bpf_tcp_sock *tp, *tp_ret;
struct bpf_sock *sk, *sk_ret;
__u32 linum, linum_idx;
struct tcp_sock *ktp;

linum_idx = EGRESS_LINUM_IDX;

Expand Down Expand Up @@ -165,9 +170,24 @@ int egress_read_sock_fields(struct __sk_buff *skb)
tpcpy(tp_ret, tp);

if (sk_ret == &srv_sk) {
ktp = bpf_skc_to_tcp_sock(sk);

if (!ktp)
RET_LOG();

lsndtime = ktp->lsndtime;

child_cg_id = bpf_sk_cgroup_id(ktp);
if (!child_cg_id)
RET_LOG();

parent_cg_id = bpf_sk_ancestor_cgroup_id(ktp, 2);
if (!parent_cg_id)
RET_LOG();

/* The userspace has created it for srv sk */
pkt_out_cnt = bpf_sk_storage_get(&sk_pkt_out_cnt, sk, 0, 0);
pkt_out_cnt10 = bpf_sk_storage_get(&sk_pkt_out_cnt10, sk,
pkt_out_cnt = bpf_sk_storage_get(&sk_pkt_out_cnt, ktp, 0, 0);
pkt_out_cnt10 = bpf_sk_storage_get(&sk_pkt_out_cnt10, ktp,
0, 0);
} else {
pkt_out_cnt = bpf_sk_storage_get(&sk_pkt_out_cnt, sk,
Expand Down