[bpf-next,v2,15/18] bpf: sockmap sample support for bpf_msg_cork_bytes()

Message ID 20180312192421.8039.90630.stgit@john-Precision-Tower-5810
State Changes Requested
Delegated to: BPF Maintainers
Headers show
Series
  • bpf,sockmap: sendmsg/sendfile ULP
Related show

Commit Message

John Fastabend March 12, 2018, 7:24 p.m.
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 <john.fastabend@gmail.com>
---
 include/uapi/linux/bpf_common.h           |    7 ++--
 samples/sockmap/sockmap_kern.c            |   53 +++++++++++++++++++++++++----
 samples/sockmap/sockmap_user.c            |   19 ++++++++++
 tools/include/uapi/linux/bpf.h            |    3 +-
 tools/testing/selftests/bpf/bpf_helpers.h |    2 +
 5 files changed, 71 insertions(+), 13 deletions(-)

Comments

David Miller March 15, 2018, 6:42 p.m. | #1
From: John Fastabend <john.fastabend@gmail.com>
Date: Mon, 12 Mar 2018 12:24:21 -0700

> 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 <john.fastabend@gmail.com>

Acked-by: David S. Miller <davem@davemloft.net>
Alexei Starovoitov March 15, 2018, 8:15 p.m. | #2
On Mon, Mar 12, 2018 at 12:24:21PM -0700, John Fastabend wrote:
> 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 <john.fastabend@gmail.com>
> ---
>  include/uapi/linux/bpf_common.h           |    7 ++--
>  samples/sockmap/sockmap_kern.c            |   53 +++++++++++++++++++++++++----
>  samples/sockmap/sockmap_user.c            |   19 ++++++++++
>  tools/include/uapi/linux/bpf.h            |    3 +-
>  tools/testing/selftests/bpf/bpf_helpers.h |    2 +
>  5 files changed, 71 insertions(+), 13 deletions(-)
> 
> diff --git a/include/uapi/linux/bpf_common.h b/include/uapi/linux/bpf_common.h
> index ee97668..18be907 100644
> --- a/include/uapi/linux/bpf_common.h
> +++ b/include/uapi/linux/bpf_common.h
> @@ -15,10 +15,9 @@
>  
>  /* ld/ldx fields */
>  #define BPF_SIZE(code)  ((code) & 0x18)
> -#define		BPF_W		0x00 /* 32-bit */
> -#define		BPF_H		0x08 /* 16-bit */
> -#define		BPF_B		0x10 /*  8-bit */
> -/* eBPF		BPF_DW		0x18    64-bit */
> +#define		BPF_W		0x00
> +#define		BPF_H		0x08
> +#define		BPF_B		0x10

this hunk seems wrong here. Botched rebase?
John Fastabend March 15, 2018, 10:04 p.m. | #3
On 03/15/2018 01:15 PM, Alexei Starovoitov wrote:
> On Mon, Mar 12, 2018 at 12:24:21PM -0700, John Fastabend wrote:
>> 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 <john.fastabend@gmail.com>
>> ---
>>  include/uapi/linux/bpf_common.h           |    7 ++--
>>  samples/sockmap/sockmap_kern.c            |   53 +++++++++++++++++++++++++----
>>  samples/sockmap/sockmap_user.c            |   19 ++++++++++
>>  tools/include/uapi/linux/bpf.h            |    3 +-
>>  tools/testing/selftests/bpf/bpf_helpers.h |    2 +
>>  5 files changed, 71 insertions(+), 13 deletions(-)
>>
>> diff --git a/include/uapi/linux/bpf_common.h b/include/uapi/linux/bpf_common.h
>> index ee97668..18be907 100644
>> --- a/include/uapi/linux/bpf_common.h
>> +++ b/include/uapi/linux/bpf_common.h
>> @@ -15,10 +15,9 @@
>>  
>>  /* ld/ldx fields */
>>  #define BPF_SIZE(code)  ((code) & 0x18)
>> -#define		BPF_W		0x00 /* 32-bit */
>> -#define		BPF_H		0x08 /* 16-bit */
>> -#define		BPF_B		0x10 /*  8-bit */
>> -/* eBPF		BPF_DW		0x18    64-bit */
>> +#define		BPF_W		0x00
>> +#define		BPF_H		0x08
>> +#define		BPF_B		0x10
> 
> this hunk seems wrong here. Botched rebase?
> 

Yep this hunk has nothing to do with my work so will
remove this hunk.

Patch

diff --git a/include/uapi/linux/bpf_common.h b/include/uapi/linux/bpf_common.h
index ee97668..18be907 100644
--- a/include/uapi/linux/bpf_common.h
+++ b/include/uapi/linux/bpf_common.h
@@ -15,10 +15,9 @@ 
 
 /* ld/ldx fields */
 #define BPF_SIZE(code)  ((code) & 0x18)
-#define		BPF_W		0x00 /* 32-bit */
-#define		BPF_H		0x08 /* 16-bit */
-#define		BPF_B		0x10 /*  8-bit */
-/* eBPF		BPF_DW		0x18    64-bit */
+#define		BPF_W		0x00
+#define		BPF_H		0x08
+#define		BPF_B		0x10
 #define BPF_MODE(code)  ((code) & 0xe0)
 #define		BPF_IMM		0x00
 #define		BPF_ABS		0x20
diff --git a/samples/sockmap/sockmap_kern.c b/samples/sockmap/sockmap_kern.c
index 5a51f15..1c430926 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",
-		   (__u32)data_end - (__u32)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",
+		   (__u32)data_end - (__u32)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",
-		   (__u32)data_end - (__u32)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",
+		   (__u32)data_end - (__u32)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 (((__u32)data_end - (__u32)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 41774ec..4e0a3d8 100644
--- a/samples/sockmap/sockmap_user.c
+++ b/samples/sockmap/sockmap_user.c
@@ -60,6 +60,7 @@ 
 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 @@ 
 	{"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 @@  int main(int argc, char **argv)
 		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 @@  int main(int argc, char **argv)
 				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);
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 609456f..ce07a13 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -770,7 +770,8 @@  enum bpf_attach_type {
 	FN(override_return),		\
 	FN(sock_ops_cb_flags_set),	\
 	FN(msg_redirect_map),		\
-	FN(msg_apply_bytes),
+	FN(msg_apply_bytes),		\
+	FN(msg_cork_bytes),
 
 /* integer value in 'imm' field of BPF_CALL instruction selects which helper
  * function eBPF program intends to call
diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h
index 4713de4..b5b45ff 100644
--- a/tools/testing/selftests/bpf/bpf_helpers.h
+++ b/tools/testing/selftests/bpf/bpf_helpers.h
@@ -90,6 +90,8 @@  static int (*bpf_msg_redirect_map)(void *ctx, void *map, int key, int flags) =
 	(void *) BPF_FUNC_msg_redirect_map;
 static int (*bpf_msg_apply_bytes)(void *ctx, int len) =
 	(void *) BPF_FUNC_msg_apply_bytes;
+static int (*bpf_msg_cork_bytes)(void *ctx, int len) =
+	(void *) BPF_FUNC_msg_cork_bytes;
 
 /* llvm builtin functions that eBPF C program may use to
  * emit BPF_LD_ABS and BPF_LD_IND instructions