From 468b3fdea8826b232a570d95ba45272eb38919cb Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Sun, 18 Mar 2018 12:58:02 -0700 Subject: bpf: sockmap sample support for bpf_msg_cork_bytes() Add sample application support for the bpf_msg_cork_bytes helper. This lets the user specify how many bytes each verdict should apply to. Similar to apply_bytes() tests these can be run as a stand-alone test when used without other options or inline with other tests by using the txmsg_cork option along with any of the basic tests txmsg, txmsg_redir, txmsg_drop. Signed-off-by: John Fastabend Acked-by: David S. Miller Signed-off-by: Daniel Borkmann --- samples/sockmap/sockmap_kern.c | 53 +++++++++++++++++++++++++++++++++++------- samples/sockmap/sockmap_user.c | 19 +++++++++++++++ 2 files changed, 64 insertions(+), 8 deletions(-) (limited to 'samples') diff --git a/samples/sockmap/sockmap_kern.c b/samples/sockmap/sockmap_kern.c index 205ec36449d1..735226794ce1 100644 --- a/samples/sockmap/sockmap_kern.c +++ b/samples/sockmap/sockmap_kern.c @@ -64,6 +64,13 @@ struct bpf_map_def SEC("maps") sock_apply_bytes = { .max_entries = 1 }; +struct bpf_map_def SEC("maps") sock_cork_bytes = { + .type = BPF_MAP_TYPE_ARRAY, + .key_size = sizeof(int), + .value_size = sizeof(int), + .max_entries = 1 +}; + SEC("sk_skb1") int bpf_prog1(struct __sk_buff *skb) { @@ -135,6 +142,9 @@ int bpf_prog4(struct sk_msg_md *msg) bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero); if (bytes) bpf_msg_apply_bytes(msg, *bytes); + bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero); + if (bytes) + bpf_msg_cork_bytes(msg, *bytes); return SK_PASS; } @@ -143,13 +153,16 @@ int bpf_prog5(struct sk_msg_md *msg) { void *data_end = (void *)(long) msg->data_end; void *data = (void *)(long) msg->data; - int *bytes, err = 0, zero = 0; + int *bytes, err1 = -1, err2 = -1, zero = 0; bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero); if (bytes) - err = bpf_msg_apply_bytes(msg, *bytes); - bpf_printk("sk_msg2: data length %i err %i\n", - (__u64)data_end - (__u64)data, err); + err1 = bpf_msg_apply_bytes(msg, *bytes); + bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero); + if (bytes) + err2 = bpf_msg_cork_bytes(msg, *bytes); + bpf_printk("sk_msg2: data length %i err1 %i err2 %i\n", + (__u64)data_end - (__u64)data, err1, err2); return SK_PASS; } @@ -163,6 +176,9 @@ int bpf_prog6(struct sk_msg_md *msg) bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero); if (bytes) bpf_msg_apply_bytes(msg, *bytes); + bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero); + if (bytes) + bpf_msg_cork_bytes(msg, *bytes); return bpf_msg_redirect_map(msg, &sock_map_redir, zero, 0); } @@ -171,13 +187,17 @@ int bpf_prog7(struct sk_msg_md *msg) { void *data_end = (void *)(long) msg->data_end; void *data = (void *)(long) msg->data; - int *bytes, err = 0, zero = 0; + int *bytes, err1 = 0, err2 = 0, zero = 0; bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero); if (bytes) - err = bpf_msg_apply_bytes(msg, *bytes); - bpf_printk("sk_msg3: redirect(%iB) err=%i\n", - (__u64)data_end - (__u64)data, err); + err1 = bpf_msg_apply_bytes(msg, *bytes); + bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero); + if (bytes) + err2 = bpf_msg_cork_bytes(msg, *bytes); + + bpf_printk("sk_msg3: redirect(%iB) err1=%i err2=%i\n", + (__u64)data_end - (__u64)data, err1, err2); return bpf_msg_redirect_map(msg, &sock_map_redir, zero, 0); } @@ -198,5 +218,22 @@ int bpf_prog8(struct sk_msg_md *msg) } return SK_PASS; } +SEC("sk_msg6") +int bpf_prog9(struct sk_msg_md *msg) +{ + void *data_end = (void *)(long) msg->data_end; + void *data = (void *)(long) msg->data; + int ret = 0, *bytes, zero = 0; + + bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero); + if (bytes) { + if (((__u64)data_end - (__u64)data) >= *bytes) + return SK_PASS; + ret = bpf_msg_cork_bytes(msg, *bytes); + if (ret) + return SK_DROP; + } + return SK_PASS; +} char _license[] SEC("license") = "GPL"; diff --git a/samples/sockmap/sockmap_user.c b/samples/sockmap/sockmap_user.c index 41774ec0f0b3..4e0a3d87881f 100644 --- a/samples/sockmap/sockmap_user.c +++ b/samples/sockmap/sockmap_user.c @@ -60,6 +60,7 @@ int txmsg_noisy; int txmsg_redir; int txmsg_redir_noisy; int txmsg_apply; +int txmsg_cork; static const struct option long_options[] = { {"help", no_argument, NULL, 'h' }, @@ -75,6 +76,7 @@ static const struct option long_options[] = { {"txmsg_redir", no_argument, &txmsg_redir, 1 }, {"txmsg_redir_noisy", no_argument, &txmsg_redir_noisy, 1}, {"txmsg_apply", required_argument, NULL, 'a'}, + {"txmsg_cork", required_argument, NULL, 'k'}, {0, 0, NULL, 0 } }; @@ -551,6 +553,9 @@ int main(int argc, char **argv) case 'a': txmsg_apply = atoi(optarg); break; + case 'k': + txmsg_cork = atoi(optarg); + break; case 'c': cg_fd = open(optarg, O_DIRECTORY, O_RDONLY); if (cg_fd < 0) { @@ -671,6 +676,8 @@ run: tx_prog_fd = prog_fd[6]; else if (txmsg_apply) tx_prog_fd = prog_fd[7]; + else if (txmsg_cork) + tx_prog_fd = prog_fd[8]; else tx_prog_fd = 0; @@ -716,6 +723,18 @@ run: return err; } } + + if (txmsg_cork) { + err = bpf_map_update_elem(map_fd[4], + &i, &txmsg_cork, BPF_ANY); + if (err) { + fprintf(stderr, + "ERROR: bpf_map_update_elem (cork_bytes): %d (%s\n", + err, strerror(errno)); + return err; + } + } + } if (test == PING_PONG) err = forever_ping_pong(rate, &options); -- cgit v1.2.3