Commit 82a86168 authored by John Fastabend's avatar John Fastabend Committed by Daniel Borkmann

bpf: add map tests for BPF_PROG_TYPE_SK_MSG

Add map tests to attach BPF_PROG_TYPE_SK_MSG types to a sockmap.
Signed-off-by: default avatarJohn Fastabend <john.fastabend@gmail.com>
Acked-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
parent 015632bb
...@@ -133,6 +133,7 @@ enum bpf_prog_type { ...@@ -133,6 +133,7 @@ enum bpf_prog_type {
BPF_PROG_TYPE_SOCK_OPS, BPF_PROG_TYPE_SOCK_OPS,
BPF_PROG_TYPE_SK_SKB, BPF_PROG_TYPE_SK_SKB,
BPF_PROG_TYPE_CGROUP_DEVICE, BPF_PROG_TYPE_CGROUP_DEVICE,
BPF_PROG_TYPE_SK_MSG,
}; };
enum bpf_attach_type { enum bpf_attach_type {
...@@ -143,6 +144,7 @@ enum bpf_attach_type { ...@@ -143,6 +144,7 @@ enum bpf_attach_type {
BPF_SK_SKB_STREAM_PARSER, BPF_SK_SKB_STREAM_PARSER,
BPF_SK_SKB_STREAM_VERDICT, BPF_SK_SKB_STREAM_VERDICT,
BPF_CGROUP_DEVICE, BPF_CGROUP_DEVICE,
BPF_SK_MSG_VERDICT,
__MAX_BPF_ATTACH_TYPE __MAX_BPF_ATTACH_TYPE
}; };
...@@ -941,6 +943,14 @@ enum sk_action { ...@@ -941,6 +943,14 @@ enum sk_action {
SK_PASS, SK_PASS,
}; };
/* user accessible metadata for SK_MSG packet hook, new fields must
* be added to the end of this structure
*/
struct sk_msg_md {
void *data;
void *data_end;
};
#define BPF_TAG_SIZE 8 #define BPF_TAG_SIZE 8
struct bpf_prog_info { struct bpf_prog_info {
......
...@@ -29,7 +29,8 @@ TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test ...@@ -29,7 +29,8 @@ TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test
test_pkt_md_access.o test_xdp_redirect.o test_xdp_meta.o sockmap_parse_prog.o \ test_pkt_md_access.o test_xdp_redirect.o test_xdp_meta.o sockmap_parse_prog.o \
sockmap_verdict_prog.o dev_cgroup.o sample_ret0.o test_tracepoint.o \ sockmap_verdict_prog.o dev_cgroup.o sample_ret0.o test_tracepoint.o \
test_l4lb_noinline.o test_xdp_noinline.o test_stacktrace_map.o \ test_l4lb_noinline.o test_xdp_noinline.o test_stacktrace_map.o \
sample_map_ret0.o test_tcpbpf_kern.o test_stacktrace_build_id.o sample_map_ret0.o test_tcpbpf_kern.o test_stacktrace_build_id.o \
sockmap_tcp_msg_prog.o
# Order correspond to 'make run_tests' order # Order correspond to 'make run_tests' order
TEST_PROGS := test_kmod.sh \ TEST_PROGS := test_kmod.sh \
......
...@@ -123,6 +123,8 @@ static int (*bpf_skb_under_cgroup)(void *ctx, void *map, int index) = ...@@ -123,6 +123,8 @@ static int (*bpf_skb_under_cgroup)(void *ctx, void *map, int index) =
(void *) BPF_FUNC_skb_under_cgroup; (void *) BPF_FUNC_skb_under_cgroup;
static int (*bpf_skb_change_head)(void *, int len, int flags) = static int (*bpf_skb_change_head)(void *, int len, int flags) =
(void *) BPF_FUNC_skb_change_head; (void *) BPF_FUNC_skb_change_head;
static int (*bpf_skb_pull_data)(void *, int len) =
(void *) BPF_FUNC_skb_pull_data;
/* Scan the ARCH passed in from ARCH env variable (see Makefile) */ /* Scan the ARCH passed in from ARCH env variable (see Makefile) */
#if defined(__TARGET_ARCH_x86) #if defined(__TARGET_ARCH_x86)
......
...@@ -20,14 +20,25 @@ int bpf_prog1(struct __sk_buff *skb) ...@@ -20,14 +20,25 @@ int bpf_prog1(struct __sk_buff *skb)
__u32 lport = skb->local_port; __u32 lport = skb->local_port;
__u32 rport = skb->remote_port; __u32 rport = skb->remote_port;
__u8 *d = data; __u8 *d = data;
__u32 len = (__u32) data_end - (__u32) data;
int err;
if (data + 10 > data_end) {
err = bpf_skb_pull_data(skb, 10);
if (err)
return SK_DROP;
data_end = (void *)(long)skb->data_end;
data = (void *)(long)skb->data;
if (data + 10 > data_end) if (data + 10 > data_end)
return skb->len; return SK_DROP;
}
/* This write/read is a bit pointless but tests the verifier and /* This write/read is a bit pointless but tests the verifier and
* strparser handler for read/write pkt data and access into sk * strparser handler for read/write pkt data and access into sk
* fields. * fields.
*/ */
d = data;
d[7] = 1; d[7] = 1;
return skb->len; return skb->len;
} }
......
#include <linux/bpf.h>
#include "bpf_helpers.h"
#include "bpf_util.h"
#include "bpf_endian.h"
int _version SEC("version") = 1;
#define bpf_printk(fmt, ...) \
({ \
char ____fmt[] = fmt; \
bpf_trace_printk(____fmt, sizeof(____fmt), \
##__VA_ARGS__); \
})
SEC("sk_msg1")
int bpf_prog1(struct sk_msg_md *msg)
{
void *data_end = (void *)(long) msg->data_end;
void *data = (void *)(long) msg->data;
char *d;
if (data + 8 > data_end)
return SK_DROP;
bpf_printk("data length %i\n", (__u64)msg->data_end - (__u64)msg->data);
d = (char *)data;
bpf_printk("hello sendmsg hook %i %i\n", d[0], d[1]);
return SK_PASS;
}
char _license[] SEC("license") = "GPL";
...@@ -26,6 +26,13 @@ struct bpf_map_def SEC("maps") sock_map_tx = { ...@@ -26,6 +26,13 @@ struct bpf_map_def SEC("maps") sock_map_tx = {
.max_entries = 20, .max_entries = 20,
}; };
struct bpf_map_def SEC("maps") sock_map_msg = {
.type = BPF_MAP_TYPE_SOCKMAP,
.key_size = sizeof(int),
.value_size = sizeof(int),
.max_entries = 20,
};
struct bpf_map_def SEC("maps") sock_map_break = { struct bpf_map_def SEC("maps") sock_map_break = {
.type = BPF_MAP_TYPE_ARRAY, .type = BPF_MAP_TYPE_ARRAY,
.key_size = sizeof(int), .key_size = sizeof(int),
......
...@@ -464,15 +464,17 @@ static void test_devmap(int task, void *data) ...@@ -464,15 +464,17 @@ static void test_devmap(int task, void *data)
#include <linux/err.h> #include <linux/err.h>
#define SOCKMAP_PARSE_PROG "./sockmap_parse_prog.o" #define SOCKMAP_PARSE_PROG "./sockmap_parse_prog.o"
#define SOCKMAP_VERDICT_PROG "./sockmap_verdict_prog.o" #define SOCKMAP_VERDICT_PROG "./sockmap_verdict_prog.o"
#define SOCKMAP_TCP_MSG_PROG "./sockmap_tcp_msg_prog.o"
static void test_sockmap(int tasks, void *data) static void test_sockmap(int tasks, void *data)
{ {
int one = 1, map_fd_rx = 0, map_fd_tx = 0, map_fd_break, s, sc, rc; struct bpf_map *bpf_map_rx, *bpf_map_tx, *bpf_map_msg, *bpf_map_break;
struct bpf_map *bpf_map_rx, *bpf_map_tx, *bpf_map_break; int map_fd_msg = 0, map_fd_rx = 0, map_fd_tx = 0, map_fd_break;
int ports[] = {50200, 50201, 50202, 50204}; int ports[] = {50200, 50201, 50202, 50204};
int err, i, fd, udp, sfd[6] = {0xdeadbeef}; int err, i, fd, udp, sfd[6] = {0xdeadbeef};
u8 buf[20] = {0x0, 0x5, 0x3, 0x2, 0x1, 0x0}; u8 buf[20] = {0x0, 0x5, 0x3, 0x2, 0x1, 0x0};
int parse_prog, verdict_prog; int parse_prog, verdict_prog, msg_prog;
struct sockaddr_in addr; struct sockaddr_in addr;
int one = 1, s, sc, rc;
struct bpf_object *obj; struct bpf_object *obj;
struct timeval to; struct timeval to;
__u32 key, value; __u32 key, value;
...@@ -584,6 +586,12 @@ static void test_sockmap(int tasks, void *data) ...@@ -584,6 +586,12 @@ static void test_sockmap(int tasks, void *data)
goto out_sockmap; goto out_sockmap;
} }
err = bpf_prog_attach(-1, fd, BPF_SK_MSG_VERDICT, 0);
if (!err) {
printf("Failed invalid msg verdict prog attach\n");
goto out_sockmap;
}
err = bpf_prog_attach(-1, fd, __MAX_BPF_ATTACH_TYPE, 0); err = bpf_prog_attach(-1, fd, __MAX_BPF_ATTACH_TYPE, 0);
if (!err) { if (!err) {
printf("Failed unknown prog attach\n"); printf("Failed unknown prog attach\n");
...@@ -602,6 +610,12 @@ static void test_sockmap(int tasks, void *data) ...@@ -602,6 +610,12 @@ static void test_sockmap(int tasks, void *data)
goto out_sockmap; goto out_sockmap;
} }
err = bpf_prog_detach(fd, BPF_SK_MSG_VERDICT);
if (err) {
printf("Failed empty msg verdict prog detach\n");
goto out_sockmap;
}
err = bpf_prog_detach(fd, __MAX_BPF_ATTACH_TYPE); err = bpf_prog_detach(fd, __MAX_BPF_ATTACH_TYPE);
if (!err) { if (!err) {
printf("Detach invalid prog successful\n"); printf("Detach invalid prog successful\n");
...@@ -616,6 +630,13 @@ static void test_sockmap(int tasks, void *data) ...@@ -616,6 +630,13 @@ static void test_sockmap(int tasks, void *data)
goto out_sockmap; goto out_sockmap;
} }
err = bpf_prog_load(SOCKMAP_TCP_MSG_PROG,
BPF_PROG_TYPE_SK_MSG, &obj, &msg_prog);
if (err) {
printf("Failed to load SK_SKB msg prog\n");
goto out_sockmap;
}
err = bpf_prog_load(SOCKMAP_VERDICT_PROG, err = bpf_prog_load(SOCKMAP_VERDICT_PROG,
BPF_PROG_TYPE_SK_SKB, &obj, &verdict_prog); BPF_PROG_TYPE_SK_SKB, &obj, &verdict_prog);
if (err) { if (err) {
...@@ -631,7 +652,7 @@ static void test_sockmap(int tasks, void *data) ...@@ -631,7 +652,7 @@ static void test_sockmap(int tasks, void *data)
map_fd_rx = bpf_map__fd(bpf_map_rx); map_fd_rx = bpf_map__fd(bpf_map_rx);
if (map_fd_rx < 0) { if (map_fd_rx < 0) {
printf("Failed to get map fd\n"); printf("Failed to get map rx fd\n");
goto out_sockmap; goto out_sockmap;
} }
...@@ -647,6 +668,18 @@ static void test_sockmap(int tasks, void *data) ...@@ -647,6 +668,18 @@ static void test_sockmap(int tasks, void *data)
goto out_sockmap; goto out_sockmap;
} }
bpf_map_msg = bpf_object__find_map_by_name(obj, "sock_map_msg");
if (IS_ERR(bpf_map_msg)) {
printf("Failed to load map msg from msg_verdict prog\n");
goto out_sockmap;
}
map_fd_msg = bpf_map__fd(bpf_map_msg);
if (map_fd_msg < 0) {
printf("Failed to get map msg fd\n");
goto out_sockmap;
}
bpf_map_break = bpf_object__find_map_by_name(obj, "sock_map_break"); bpf_map_break = bpf_object__find_map_by_name(obj, "sock_map_break");
if (IS_ERR(bpf_map_break)) { if (IS_ERR(bpf_map_break)) {
printf("Failed to load map tx from verdict prog\n"); printf("Failed to load map tx from verdict prog\n");
...@@ -680,6 +713,12 @@ static void test_sockmap(int tasks, void *data) ...@@ -680,6 +713,12 @@ static void test_sockmap(int tasks, void *data)
goto out_sockmap; goto out_sockmap;
} }
err = bpf_prog_attach(msg_prog, map_fd_msg, BPF_SK_MSG_VERDICT, 0);
if (err) {
printf("Failed msg verdict bpf prog attach\n");
goto out_sockmap;
}
err = bpf_prog_attach(verdict_prog, map_fd_rx, err = bpf_prog_attach(verdict_prog, map_fd_rx,
__MAX_BPF_ATTACH_TYPE, 0); __MAX_BPF_ATTACH_TYPE, 0);
if (!err) { if (!err) {
...@@ -719,6 +758,14 @@ static void test_sockmap(int tasks, void *data) ...@@ -719,6 +758,14 @@ static void test_sockmap(int tasks, void *data)
} }
} }
/* Put sfd[2] (sending fd below) into msg map to test sendmsg bpf */
i = 0;
err = bpf_map_update_elem(map_fd_msg, &i, &sfd[2], BPF_ANY);
if (err) {
printf("Failed map_fd_msg update sockmap %i\n", err);
goto out_sockmap;
}
/* Test map send/recv */ /* Test map send/recv */
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
buf[0] = i; buf[0] = i;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment