netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 net-next 0/7] bpf: Add option to set mark and priority in cgroup sock programs
@ 2017-08-31 22:05 David Ahern
  2017-08-31 22:05 ` [PATCH v3 net-next 1/7] bpf: Add mark and priority to sock options that can be set David Ahern
                   ` (7 more replies)
  0 siblings, 8 replies; 16+ messages in thread
From: David Ahern @ 2017-08-31 22:05 UTC (permalink / raw)
  To: netdev, daniel, ast; +Cc: David Ahern

Add option to set mark and priority in addition to bound device for newly
created sockets. Also, allow the bpf programs to use the get_current_uid_gid
helper meaning socket marks, priority and device can be set based on the
uid/gid of the running process.

Sample programs are updated to demonstrate the new options.

v3
- no changes to Patches 1 and 2 which Alexei acked in previous versions
- dropped change related to recursive programs in a cgroup
- updated tests per dropped patch

v2
- added flag to control recursive behavior as requested by Alexei
- added comment to sock_filter_func_proto regarding use of
  get_current_uid_gid helper
- updated test programs for recursive option

David Ahern (7):
  bpf: Add mark and priority to sock options that can be set
  bpf: Allow cgroup sock filters to use get_current_uid_gid helper
  samples/bpf: Update sock test to allow setting mark and priority
  samples/bpf: Add detach option to test_cgrp2_sock
  samples/bpf: Add option to dump socket settings
  samples/bpf: Update cgrp2 socket tests
  samples/bpf: Update cgroup socket examples to use uid gid helper

 include/uapi/linux/bpf.h       |   2 +
 net/core/filter.c              |  42 ++++++-
 samples/bpf/sock_flags_kern.c  |   5 +
 samples/bpf/test_cgrp2_sock.c  | 255 ++++++++++++++++++++++++++++++++++++-----
 samples/bpf/test_cgrp2_sock.sh | 162 ++++++++++++++++++++------
 5 files changed, 401 insertions(+), 65 deletions(-)

-- 
2.1.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v3 net-next 1/7] bpf: Add mark and priority to sock options that can be set
  2017-08-31 22:05 [PATCH v3 net-next 0/7] bpf: Add option to set mark and priority in cgroup sock programs David Ahern
@ 2017-08-31 22:05 ` David Ahern
  2017-08-31 22:21   ` Daniel Borkmann
  2017-08-31 22:05 ` [PATCH v3 net-next 2/7] bpf: Allow cgroup sock filters to use get_current_uid_gid helper David Ahern
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 16+ messages in thread
From: David Ahern @ 2017-08-31 22:05 UTC (permalink / raw)
  To: netdev, daniel, ast; +Cc: David Ahern

Add socket mark and priority to fields that can be set by
ebpf program when a socket is created.

Signed-off-by: David Ahern <dsahern@gmail.com>
Acked-by: Alexei Starovoitov <ast@kernel.org>
---
 include/uapi/linux/bpf.h |  2 ++
 net/core/filter.c        | 26 ++++++++++++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index d46cf326b95f..e9c89e20adff 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -758,6 +758,8 @@ struct bpf_sock {
 	__u32 family;
 	__u32 type;
 	__u32 protocol;
+	__u32 mark;
+	__u32 priority;
 };
 
 #define XDP_PACKET_HEADROOM 256
diff --git a/net/core/filter.c b/net/core/filter.c
index c6a37fe0285b..f51b9690adf3 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -3455,6 +3455,10 @@ static bool sock_filter_is_valid_access(int off, int size,
 		switch (off) {
 		case offsetof(struct bpf_sock, bound_dev_if):
 			break;
+		case offsetof(struct bpf_sock, mark):
+			break;
+		case offsetof(struct bpf_sock, priority):
+			break;
 		default:
 			return false;
 		}
@@ -3958,6 +3962,28 @@ static u32 sock_filter_convert_ctx_access(enum bpf_access_type type,
 				      offsetof(struct sock, sk_bound_dev_if));
 		break;
 
+	case offsetof(struct bpf_sock, mark):
+		BUILD_BUG_ON(FIELD_SIZEOF(struct sock, sk_mark) != 4);
+
+		if (type == BPF_WRITE)
+			*insn++ = BPF_STX_MEM(BPF_W, si->dst_reg, si->src_reg,
+					offsetof(struct sock, sk_mark));
+		else
+			*insn++ = BPF_LDX_MEM(BPF_W, si->dst_reg, si->src_reg,
+				      offsetof(struct sock, sk_mark));
+		break;
+
+	case offsetof(struct bpf_sock, priority):
+		BUILD_BUG_ON(FIELD_SIZEOF(struct sock, sk_priority) != 4);
+
+		if (type == BPF_WRITE)
+			*insn++ = BPF_STX_MEM(BPF_W, si->dst_reg, si->src_reg,
+					offsetof(struct sock, sk_priority));
+		else
+			*insn++ = BPF_LDX_MEM(BPF_W, si->dst_reg, si->src_reg,
+				      offsetof(struct sock, sk_priority));
+		break;
+
 	case offsetof(struct bpf_sock, family):
 		BUILD_BUG_ON(FIELD_SIZEOF(struct sock, sk_family) != 2);
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v3 net-next 2/7] bpf: Allow cgroup sock filters to use get_current_uid_gid helper
  2017-08-31 22:05 [PATCH v3 net-next 0/7] bpf: Add option to set mark and priority in cgroup sock programs David Ahern
  2017-08-31 22:05 ` [PATCH v3 net-next 1/7] bpf: Add mark and priority to sock options that can be set David Ahern
@ 2017-08-31 22:05 ` David Ahern
  2017-08-31 22:22   ` Daniel Borkmann
  2017-08-31 22:05 ` [PATCH v3 net-next 3/7] samples/bpf: Update sock test to allow setting mark and priority David Ahern
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 16+ messages in thread
From: David Ahern @ 2017-08-31 22:05 UTC (permalink / raw)
  To: netdev, daniel, ast; +Cc: David Ahern

Allow BPF programs run on sock create to use the get_current_uid_gid
helper. IPv4 and IPv6 sockets are created in a process context so
there is always a valid uid/gid

Signed-off-by: David Ahern <dsahern@gmail.com>
Acked-by: Alexei Starovoitov <ast@kernel.org>
---
 net/core/filter.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/net/core/filter.c b/net/core/filter.c
index f51b9690adf3..9dad3e7e2e10 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -3150,6 +3150,20 @@ bpf_base_func_proto(enum bpf_func_id func_id)
 }
 
 static const struct bpf_func_proto *
+sock_filter_func_proto(enum bpf_func_id func_id)
+{
+	switch (func_id) {
+	/* inet and inet6 sockets are created in a process
+	 * context so there is always a valid uid/gid
+	 */
+	case BPF_FUNC_get_current_uid_gid:
+		return &bpf_get_current_uid_gid_proto;
+	default:
+		return bpf_base_func_proto(func_id);
+	}
+}
+
+static const struct bpf_func_proto *
 sk_filter_func_proto(enum bpf_func_id func_id)
 {
 	switch (func_id) {
@@ -4233,7 +4247,7 @@ const struct bpf_verifier_ops lwt_xmit_prog_ops = {
 };
 
 const struct bpf_verifier_ops cg_sock_prog_ops = {
-	.get_func_proto		= bpf_base_func_proto,
+	.get_func_proto		= sock_filter_func_proto,
 	.is_valid_access	= sock_filter_is_valid_access,
 	.convert_ctx_access	= sock_filter_convert_ctx_access,
 };
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v3 net-next 3/7] samples/bpf: Update sock test to allow setting mark and priority
  2017-08-31 22:05 [PATCH v3 net-next 0/7] bpf: Add option to set mark and priority in cgroup sock programs David Ahern
  2017-08-31 22:05 ` [PATCH v3 net-next 1/7] bpf: Add mark and priority to sock options that can be set David Ahern
  2017-08-31 22:05 ` [PATCH v3 net-next 2/7] bpf: Allow cgroup sock filters to use get_current_uid_gid helper David Ahern
@ 2017-08-31 22:05 ` David Ahern
  2017-09-01  1:38   ` Alexei Starovoitov
  2017-08-31 22:05 ` [PATCH v3 net-next 4/7] samples/bpf: Add detach option to test_cgrp2_sock David Ahern
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 16+ messages in thread
From: David Ahern @ 2017-08-31 22:05 UTC (permalink / raw)
  To: netdev, daniel, ast; +Cc: David Ahern

Update sock test to set mark and priority on socket create.

Signed-off-by: David Ahern <dsahern@gmail.com>
---
 samples/bpf/test_cgrp2_sock.c  | 134 ++++++++++++++++++++++++++++++++++++-----
 samples/bpf/test_cgrp2_sock.sh |   2 +-
 2 files changed, 119 insertions(+), 17 deletions(-)

diff --git a/samples/bpf/test_cgrp2_sock.c b/samples/bpf/test_cgrp2_sock.c
index c3cfb23e23b5..681abbe6c85e 100644
--- a/samples/bpf/test_cgrp2_sock.c
+++ b/samples/bpf/test_cgrp2_sock.c
@@ -19,59 +19,161 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <net/if.h>
+#include <inttypes.h>
 #include <linux/bpf.h>
 
 #include "libbpf.h"
 
 char bpf_log_buf[BPF_LOG_BUF_SIZE];
 
-static int prog_load(int idx)
+static int prog_load(__u32 idx, __u32 mark, __u32 prio)
 {
-	struct bpf_insn prog[] = {
+	/* save pointer to context */
+	struct bpf_insn prog_start[] = {
 		BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
+	};
+	struct bpf_insn prog_end[] = {
+		BPF_MOV64_IMM(BPF_REG_0, 1), /* r0 = verdict */
+		BPF_EXIT_INSN(),
+	};
+
+	/* set sk_bound_dev_if on socket */
+	struct bpf_insn prog_dev[] = {
 		BPF_MOV64_IMM(BPF_REG_3, idx),
 		BPF_MOV64_IMM(BPF_REG_2, offsetof(struct bpf_sock, bound_dev_if)),
 		BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3, offsetof(struct bpf_sock, bound_dev_if)),
-		BPF_MOV64_IMM(BPF_REG_0, 1), /* r0 = verdict */
-		BPF_EXIT_INSN(),
 	};
-	size_t insns_cnt = sizeof(prog) / sizeof(struct bpf_insn);
 
-	return bpf_load_program(BPF_PROG_TYPE_CGROUP_SOCK, prog, insns_cnt,
+	/* set mark on socket */
+	struct bpf_insn prog_mark[] = {
+		BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
+		BPF_MOV64_IMM(BPF_REG_3, mark),
+		BPF_MOV64_IMM(BPF_REG_2, offsetof(struct bpf_sock, mark)),
+		BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3, offsetof(struct bpf_sock, mark)),
+	};
+
+	/* set priority on socket */
+	struct bpf_insn prog_prio[] = {
+		BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
+		BPF_MOV64_IMM(BPF_REG_3, prio),
+		BPF_MOV64_IMM(BPF_REG_2, offsetof(struct bpf_sock, priority)),
+		BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3, offsetof(struct bpf_sock, priority)),
+	};
+
+	struct bpf_insn *prog;
+	size_t insns_cnt;
+	void *p;
+	int ret;
+
+	insns_cnt = sizeof(prog_start) + sizeof(prog_end);
+	if (idx)
+		insns_cnt += sizeof(prog_dev);
+
+	if (mark)
+		insns_cnt += sizeof(prog_mark);
+
+	if (prio)
+		insns_cnt += sizeof(prog_prio);
+
+	p = prog = malloc(insns_cnt);
+	if (!prog) {
+		fprintf(stderr, "Failed to allocate memory for instructions\n");
+		return EXIT_FAILURE;
+	}
+
+	memcpy(p, prog_start, sizeof(prog_start));
+	p += sizeof(prog_start);
+
+	if (idx) {
+		memcpy(p, prog_dev, sizeof(prog_dev));
+		p += sizeof(prog_dev);
+	}
+
+	if (mark) {
+		memcpy(p, prog_mark, sizeof(prog_mark));
+		p += sizeof(prog_mark);
+	}
+
+	if (prio) {
+		memcpy(p, prog_prio, sizeof(prog_prio));
+		p += sizeof(prog_prio);
+	}
+
+	memcpy(p, prog_end, sizeof(prog_end));
+	p += sizeof(prog_end);
+
+	insns_cnt /= sizeof(struct bpf_insn);
+
+	ret = bpf_load_program(BPF_PROG_TYPE_CGROUP_SOCK, prog, insns_cnt,
 				"GPL", 0, bpf_log_buf, BPF_LOG_BUF_SIZE);
+
+	free(prog);
+
+	return ret;
 }
 
 static int usage(const char *argv0)
 {
-	printf("Usage: %s cg-path device-index\n", argv0);
+	printf("Usage: %s -b bind-to-dev -m mark -p prio cg-path\n", argv0);
 	return EXIT_FAILURE;
 }
 
 int main(int argc, char **argv)
 {
+	__u32 idx = 0, mark = 0, prio = 0;
+	const char *cgrp_path = NULL;
 	int cg_fd, prog_fd, ret;
-	unsigned int idx;
+	int rc;
+
+	while ((rc = getopt(argc, argv, "b:m:p:")) != -1) {
+		switch (rc) {
+		case 'b':
+			idx = if_nametoindex(optarg);
+			if (!idx) {
+				idx = strtoumax(optarg, NULL, 0);
+				if (!idx) {
+					printf("Invalid device name\n");
+					return EXIT_FAILURE;
+				}
+			}
+			break;
+		case 'm':
+			mark = strtoumax(optarg, NULL, 0);
+			break;
+		case 'p':
+			prio = strtoumax(optarg, NULL, 0);
+			break;
+		default:
+			return usage(argv[0]);
+		}
+	}
 
-	if (argc < 2)
+	if (optind == argc)
 		return usage(argv[0]);
 
-	idx = if_nametoindex(argv[2]);
-	if (!idx) {
-		printf("Invalid device name\n");
+	cgrp_path = argv[optind];
+	if (!cgrp_path) {
+		fprintf(stderr, "cgroup path not given\n");
 		return EXIT_FAILURE;
 	}
 
-	cg_fd = open(argv[1], O_DIRECTORY | O_RDONLY);
+	if (!idx && !mark && !prio) {
+		fprintf(stderr,
+			"One of device, mark or priority must be given\n");
+		return EXIT_FAILURE;
+	}
+
+	cg_fd = open(cgrp_path, O_DIRECTORY | O_RDONLY);
 	if (cg_fd < 0) {
 		printf("Failed to open cgroup path: '%s'\n", strerror(errno));
 		return EXIT_FAILURE;
 	}
 
-	prog_fd = prog_load(idx);
-	printf("Output from kernel verifier:\n%s\n-------\n", bpf_log_buf);
-
+	prog_fd = prog_load(idx, mark, prio);
 	if (prog_fd < 0) {
 		printf("Failed to load prog: '%s'\n", strerror(errno));
+		printf("Output from kernel verifier:\n%s\n-------\n",
+		       bpf_log_buf);
 		return EXIT_FAILURE;
 	}
 
diff --git a/samples/bpf/test_cgrp2_sock.sh b/samples/bpf/test_cgrp2_sock.sh
index 925fd467c7cc..1153c33e8964 100755
--- a/samples/bpf/test_cgrp2_sock.sh
+++ b/samples/bpf/test_cgrp2_sock.sh
@@ -20,7 +20,7 @@ function attach_bpf {
 	mkdir -p /tmp/cgroupv2
 	mount -t cgroup2 none /tmp/cgroupv2
 	mkdir -p /tmp/cgroupv2/foo
-	test_cgrp2_sock /tmp/cgroupv2/foo foo
+	test_cgrp2_sock -b foo /tmp/cgroupv2/foo
 	echo $$ >> /tmp/cgroupv2/foo/cgroup.procs
 }
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v3 net-next 4/7] samples/bpf: Add detach option to test_cgrp2_sock
  2017-08-31 22:05 [PATCH v3 net-next 0/7] bpf: Add option to set mark and priority in cgroup sock programs David Ahern
                   ` (2 preceding siblings ...)
  2017-08-31 22:05 ` [PATCH v3 net-next 3/7] samples/bpf: Update sock test to allow setting mark and priority David Ahern
@ 2017-08-31 22:05 ` David Ahern
  2017-09-01  1:39   ` Alexei Starovoitov
  2017-08-31 22:05 ` [PATCH v3 net-next 5/7] samples/bpf: Add option to dump socket settings David Ahern
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 16+ messages in thread
From: David Ahern @ 2017-08-31 22:05 UTC (permalink / raw)
  To: netdev, daniel, ast; +Cc: David Ahern

Add option to detach programs from a cgroup.

Signed-off-by: David Ahern <dsahern@gmail.com>
---
 samples/bpf/test_cgrp2_sock.c | 50 ++++++++++++++++++++++++++++++-------------
 1 file changed, 35 insertions(+), 15 deletions(-)

diff --git a/samples/bpf/test_cgrp2_sock.c b/samples/bpf/test_cgrp2_sock.c
index 681abbe6c85e..15396761c5cc 100644
--- a/samples/bpf/test_cgrp2_sock.c
+++ b/samples/bpf/test_cgrp2_sock.c
@@ -114,7 +114,12 @@ static int prog_load(__u32 idx, __u32 mark, __u32 prio)
 
 static int usage(const char *argv0)
 {
-	printf("Usage: %s -b bind-to-dev -m mark -p prio cg-path\n", argv0);
+	printf("Usage:\n");
+	printf("  Attach a program\n");
+	printf("  %s -b bind-to-dev -m mark -p prio cg-path\n", argv0);
+	printf("\n");
+	printf("  Detach a program\n");
+	printf("  %s -d cg-path\n", argv0);
 	return EXIT_FAILURE;
 }
 
@@ -123,10 +128,14 @@ int main(int argc, char **argv)
 	__u32 idx = 0, mark = 0, prio = 0;
 	const char *cgrp_path = NULL;
 	int cg_fd, prog_fd, ret;
+	int do_attach = 1;
 	int rc;
 
-	while ((rc = getopt(argc, argv, "b:m:p:")) != -1) {
+	while ((rc = getopt(argc, argv, "db:m:p:")) != -1) {
 		switch (rc) {
+		case 'd':
+			do_attach = 0;
+			break;
 		case 'b':
 			idx = if_nametoindex(optarg);
 			if (!idx) {
@@ -157,7 +166,7 @@ int main(int argc, char **argv)
 		return EXIT_FAILURE;
 	}
 
-	if (!idx && !mark && !prio) {
+	if (do_attach && !idx && !mark && !prio) {
 		fprintf(stderr,
 			"One of device, mark or priority must be given\n");
 		return EXIT_FAILURE;
@@ -169,20 +178,31 @@ int main(int argc, char **argv)
 		return EXIT_FAILURE;
 	}
 
-	prog_fd = prog_load(idx, mark, prio);
-	if (prog_fd < 0) {
-		printf("Failed to load prog: '%s'\n", strerror(errno));
-		printf("Output from kernel verifier:\n%s\n-------\n",
-		       bpf_log_buf);
-		return EXIT_FAILURE;
-	}
+	if (do_attach) {
+		prog_fd = prog_load(idx, mark, prio);
+		if (prog_fd < 0) {
+			printf("Failed to load prog: '%s'\n", strerror(errno));
+			printf("Output from kernel verifier:\n%s\n-------\n",
+			       bpf_log_buf);
+			return EXIT_FAILURE;
+		}
 
-	ret = bpf_prog_attach(prog_fd, cg_fd, BPF_CGROUP_INET_SOCK_CREATE, 0);
-	if (ret < 0) {
-		printf("Failed to attach prog to cgroup: '%s'\n",
-		       strerror(errno));
-		return EXIT_FAILURE;
+		ret = bpf_prog_attach(prog_fd, cg_fd,
+				      BPF_CGROUP_INET_SOCK_CREATE, 0);
+		if (ret < 0) {
+			printf("Failed to attach prog to cgroup: '%s'\n",
+			       strerror(errno));
+			return EXIT_FAILURE;
+		}
+	} else {
+		ret = bpf_prog_detach(cg_fd, BPF_CGROUP_INET_SOCK_CREATE);
+		if (ret < 0) {
+			printf("Failed to detach prog from cgroup: '%s'\n",
+			       strerror(errno));
+			return EXIT_FAILURE;
+		}
 	}
 
+	close(cg_fd);
 	return EXIT_SUCCESS;
 }
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v3 net-next 5/7] samples/bpf: Add option to dump socket settings
  2017-08-31 22:05 [PATCH v3 net-next 0/7] bpf: Add option to set mark and priority in cgroup sock programs David Ahern
                   ` (3 preceding siblings ...)
  2017-08-31 22:05 ` [PATCH v3 net-next 4/7] samples/bpf: Add detach option to test_cgrp2_sock David Ahern
@ 2017-08-31 22:05 ` David Ahern
  2017-09-01  1:39   ` Alexei Starovoitov
  2017-08-31 22:05 ` [PATCH v3 net-next 6/7] samples/bpf: Update cgrp2 socket tests David Ahern
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 16+ messages in thread
From: David Ahern @ 2017-08-31 22:05 UTC (permalink / raw)
  To: netdev, daniel, ast; +Cc: David Ahern

Add option to dump socket settings. Will be used in the next patch
to verify bpf programs are correctly setting mark, priority and
device based on the cgroup attachment for the program run.

Signed-off-by: David Ahern <dsahern@gmail.com>
---
 samples/bpf/test_cgrp2_sock.c | 75 +++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 73 insertions(+), 2 deletions(-)

diff --git a/samples/bpf/test_cgrp2_sock.c b/samples/bpf/test_cgrp2_sock.c
index 15396761c5cc..5a688837720c 100644
--- a/samples/bpf/test_cgrp2_sock.c
+++ b/samples/bpf/test_cgrp2_sock.c
@@ -112,6 +112,70 @@ static int prog_load(__u32 idx, __u32 mark, __u32 prio)
 	return ret;
 }
 
+static int get_bind_to_device(int sd, char *name, size_t len)
+{
+	socklen_t optlen = len;
+	int rc;
+
+	name[0] = '\0';
+	rc = getsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, name, &optlen);
+	if (rc < 0)
+		perror("setsockopt(SO_BINDTODEVICE)");
+
+	return rc;
+}
+
+static unsigned int get_somark(int sd)
+{
+	unsigned int mark = 0;
+	socklen_t optlen = sizeof(mark);
+	int rc;
+
+	rc = getsockopt(sd, SOL_SOCKET, SO_MARK, &mark, &optlen);
+	if (rc < 0)
+		perror("getsockopt(SO_MARK)");
+
+	return mark;
+}
+
+static unsigned int get_priority(int sd)
+{
+	unsigned int prio = 0;
+	socklen_t optlen = sizeof(prio);
+	int rc;
+
+	rc = getsockopt(sd, SOL_SOCKET, SO_PRIORITY, &prio, &optlen);
+	if (rc < 0)
+		perror("getsockopt(SO_PRIORITY)");
+
+	return prio;
+}
+
+static int show_sockopts(int family)
+{
+	unsigned int mark, prio;
+	char name[16];
+	int sd;
+
+	sd = socket(family, SOCK_DGRAM, 17);
+	if (sd < 0) {
+		perror("socket");
+		return 1;
+	}
+
+	if (get_bind_to_device(sd, name, sizeof(name)) < 0)
+		return 1;
+
+	mark = get_somark(sd);
+	prio = get_priority(sd);
+
+	close(sd);
+
+	printf("sd %d: dev %s, mark %u, priority %u\n", sd, name, mark, prio);
+
+	return 0;
+}
+
 static int usage(const char *argv0)
 {
 	printf("Usage:\n");
@@ -120,6 +184,9 @@ static int usage(const char *argv0)
 	printf("\n");
 	printf("  Detach a program\n");
 	printf("  %s -d cg-path\n", argv0);
+	printf("\n");
+	printf("  Show inherited socket settings (mark, priority, and device)\n");
+	printf("  %s [-6]\n", argv0);
 	return EXIT_FAILURE;
 }
 
@@ -128,10 +195,11 @@ int main(int argc, char **argv)
 	__u32 idx = 0, mark = 0, prio = 0;
 	const char *cgrp_path = NULL;
 	int cg_fd, prog_fd, ret;
+	int family = PF_INET;
 	int do_attach = 1;
 	int rc;
 
-	while ((rc = getopt(argc, argv, "db:m:p:")) != -1) {
+	while ((rc = getopt(argc, argv, "db:m:p:6")) != -1) {
 		switch (rc) {
 		case 'd':
 			do_attach = 0;
@@ -152,13 +220,16 @@ int main(int argc, char **argv)
 		case 'p':
 			prio = strtoumax(optarg, NULL, 0);
 			break;
+		case '6':
+			family = PF_INET6;
+			break;
 		default:
 			return usage(argv[0]);
 		}
 	}
 
 	if (optind == argc)
-		return usage(argv[0]);
+		return show_sockopts(family);
 
 	cgrp_path = argv[optind];
 	if (!cgrp_path) {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v3 net-next 6/7] samples/bpf: Update cgrp2 socket tests
  2017-08-31 22:05 [PATCH v3 net-next 0/7] bpf: Add option to set mark and priority in cgroup sock programs David Ahern
                   ` (4 preceding siblings ...)
  2017-08-31 22:05 ` [PATCH v3 net-next 5/7] samples/bpf: Add option to dump socket settings David Ahern
@ 2017-08-31 22:05 ` David Ahern
  2017-09-01  1:40   ` Alexei Starovoitov
  2017-08-31 22:05 ` [PATCH v3 net-next 7/7] samples/bpf: Update cgroup socket examples to use uid gid helper David Ahern
  2017-09-01  5:06 ` [PATCH v3 net-next 0/7] bpf: Add option to set mark and priority in cgroup sock programs David Miller
  7 siblings, 1 reply; 16+ messages in thread
From: David Ahern @ 2017-08-31 22:05 UTC (permalink / raw)
  To: netdev, daniel, ast; +Cc: David Ahern

Update cgrp2 bpf sock tests to check that device, mark and priority
can all be set on a socket via bpf programs attached to a cgroup.

Signed-off-by: David Ahern <dsahern@gmail.com>
---
 samples/bpf/test_cgrp2_sock.sh | 162 +++++++++++++++++++++++++++++++----------
 1 file changed, 124 insertions(+), 38 deletions(-)

diff --git a/samples/bpf/test_cgrp2_sock.sh b/samples/bpf/test_cgrp2_sock.sh
index 1153c33e8964..a81f38eef417 100755
--- a/samples/bpf/test_cgrp2_sock.sh
+++ b/samples/bpf/test_cgrp2_sock.sh
@@ -1,47 +1,133 @@
-#!/bin/bash
-
-function config_device {
-	ip netns add at_ns0
-	ip link add veth0 type veth peer name veth0b
-	ip link set veth0b up
-	ip link set veth0 netns at_ns0
-	ip netns exec at_ns0 ip addr add 172.16.1.100/24 dev veth0
-	ip netns exec at_ns0 ip addr add 2401:db00::1/64 dev veth0 nodad
-	ip netns exec at_ns0 ip link set dev veth0 up
-	ip link add foo type vrf table 1234
-	ip link set foo up
-	ip addr add 172.16.1.101/24 dev veth0b
-	ip addr add 2401:db00::2/64 dev veth0b nodad
-	ip link set veth0b master foo
+#!/bin/sh
+
+# Test various socket options that can be set by attaching programs to cgroups.
+
+CGRP_MNT="/tmp/cgroupv2-test_cgrp2_sock"
+
+################################################################################
+#
+print_result()
+{
+	local rc=$1
+	local status=" OK "
+
+	[ $rc -ne 0 ] && status="FAIL"
+
+	printf "%-50s    [%4s]\n" "$2" "$status"
 }
 
-function attach_bpf {
-	rm -rf /tmp/cgroupv2
-	mkdir -p /tmp/cgroupv2
-	mount -t cgroup2 none /tmp/cgroupv2
-	mkdir -p /tmp/cgroupv2/foo
-	test_cgrp2_sock -b foo /tmp/cgroupv2/foo
-	echo $$ >> /tmp/cgroupv2/foo/cgroup.procs
+check_sock()
+{
+	out=$(test_cgrp2_sock)
+	echo $out | grep -q "$1"
+	if [ $? -ne 0 ]; then
+		print_result 1 "IPv4: $2"
+		echo "    expected: $1"
+		echo "        have: $out"
+		rc=1
+	else
+		print_result 0 "IPv4: $2"
+	fi
 }
 
-function cleanup {
-	set +ex
-	ip netns delete at_ns0
-	ip link del veth0
-	ip link del foo
-	umount /tmp/cgroupv2
-	rm -rf /tmp/cgroupv2
-	set -ex
+check_sock6()
+{
+	out=$(test_cgrp2_sock -6)
+	echo $out | grep -q "$1"
+	if [ $? -ne 0 ]; then
+		print_result 1 "IPv6: $2"
+		echo "    expected: $1"
+		echo "        have: $out"
+		rc=1
+	else
+		print_result 0 "IPv6: $2"
+	fi
 }
 
-function do_test {
-	ping -c1 -w1 172.16.1.100
-	ping6 -c1 -w1 2401:db00::1
+################################################################################
+#
+
+cleanup()
+{
+	echo $$ >> ${CGRP_MNT}/cgroup.procs
+	rmdir ${CGRP_MNT}/sockopts
 }
 
+cleanup_and_exit()
+{
+	local rc=$1
+	local msg="$2"
+
+	[ -n "$msg" ] && echo "ERROR: $msg"
+
+	ip li del cgrp2_sock
+	umount ${CGRP_MNT}
+
+	exit $rc
+}
+
+
+################################################################################
+# main
+
+rc=0
+
+ip li add cgrp2_sock type dummy 2>/dev/null
+
+set -e
+mkdir -p ${CGRP_MNT}
+mount -t cgroup2 none ${CGRP_MNT}
+set +e
+
+
+# make sure we have a known start point
 cleanup 2>/dev/null
-config_device
-attach_bpf
-do_test
-cleanup
-echo "*** PASS ***"
+
+mkdir -p ${CGRP_MNT}/sockopts
+[ $? -ne 0 ] && cleanup_and_exit 1 "Failed to create cgroup hierarchy"
+
+
+# set pid into cgroup
+echo $$ > ${CGRP_MNT}/sockopts/cgroup.procs
+
+# no bpf program attached, so socket should show no settings
+check_sock "dev , mark 0, priority 0" "No programs attached"
+check_sock6 "dev , mark 0, priority 0" "No programs attached"
+
+# verify device is set
+#
+test_cgrp2_sock -b cgrp2_sock ${CGRP_MNT}/sockopts
+if [ $? -ne 0 ]; then
+	cleanup_and_exit 1 "Failed to install program to set device"
+fi
+check_sock "dev cgrp2_sock, mark 0, priority 0" "Device set"
+check_sock6 "dev cgrp2_sock, mark 0, priority 0" "Device set"
+
+# verify mark is set
+#
+test_cgrp2_sock -m 666 ${CGRP_MNT}/sockopts
+if [ $? -ne 0 ]; then
+	cleanup_and_exit 1 "Failed to install program to set mark"
+fi
+check_sock "dev , mark 666, priority 0" "Mark set"
+check_sock6 "dev , mark 666, priority 0" "Mark set"
+
+# verify priority is set
+#
+test_cgrp2_sock -p 123 ${CGRP_MNT}/sockopts
+if [ $? -ne 0 ]; then
+	cleanup_and_exit 1 "Failed to install program to set priority"
+fi
+check_sock "dev , mark 0, priority 123" "Priority set"
+check_sock6 "dev , mark 0, priority 123" "Priority set"
+
+# all 3 at once
+#
+test_cgrp2_sock -b cgrp2_sock -m 666 -p 123 ${CGRP_MNT}/sockopts
+if [ $? -ne 0 ]; then
+	cleanup_and_exit 1 "Failed to install program to set device, mark and priority"
+fi
+check_sock "dev cgrp2_sock, mark 666, priority 123" "Priority set"
+check_sock6 "dev cgrp2_sock, mark 666, priority 123" "Priority set"
+
+cleanup_and_exit $rc
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v3 net-next 7/7] samples/bpf: Update cgroup socket examples to use uid gid helper
  2017-08-31 22:05 [PATCH v3 net-next 0/7] bpf: Add option to set mark and priority in cgroup sock programs David Ahern
                   ` (5 preceding siblings ...)
  2017-08-31 22:05 ` [PATCH v3 net-next 6/7] samples/bpf: Update cgrp2 socket tests David Ahern
@ 2017-08-31 22:05 ` David Ahern
  2017-09-01  1:41   ` Alexei Starovoitov
  2017-09-01  5:06 ` [PATCH v3 net-next 0/7] bpf: Add option to set mark and priority in cgroup sock programs David Miller
  7 siblings, 1 reply; 16+ messages in thread
From: David Ahern @ 2017-08-31 22:05 UTC (permalink / raw)
  To: netdev, daniel, ast; +Cc: David Ahern

Signed-off-by: David Ahern <dsahern@gmail.com>
---
 samples/bpf/sock_flags_kern.c |  5 +++++
 samples/bpf/test_cgrp2_sock.c | 12 +++++++++++-
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/samples/bpf/sock_flags_kern.c b/samples/bpf/sock_flags_kern.c
index 533dd11a6baa..05dcdf8a4baa 100644
--- a/samples/bpf/sock_flags_kern.c
+++ b/samples/bpf/sock_flags_kern.c
@@ -9,8 +9,13 @@ SEC("cgroup/sock1")
 int bpf_prog1(struct bpf_sock *sk)
 {
 	char fmt[] = "socket: family %d type %d protocol %d\n";
+	char fmt2[] = "socket: uid %u gid %u\n";
+	__u64 gid_uid = bpf_get_current_uid_gid();
+	__u32 uid = gid_uid & 0xffffffff;
+	__u32 gid = gid_uid >> 32;
 
 	bpf_trace_printk(fmt, sizeof(fmt), sk->family, sk->type, sk->protocol);
+	bpf_trace_printk(fmt2, sizeof(fmt2), uid, gid);
 
 	/* block PF_INET6, SOCK_RAW, IPPROTO_ICMPV6 sockets
 	 * ie., make ping6 fail
diff --git a/samples/bpf/test_cgrp2_sock.c b/samples/bpf/test_cgrp2_sock.c
index 5a688837720c..e79594dd629b 100644
--- a/samples/bpf/test_cgrp2_sock.c
+++ b/samples/bpf/test_cgrp2_sock.c
@@ -46,8 +46,18 @@ static int prog_load(__u32 idx, __u32 mark, __u32 prio)
 
 	/* set mark on socket */
 	struct bpf_insn prog_mark[] = {
-		BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
+		/* get uid of process */
+		BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+			     BPF_FUNC_get_current_uid_gid),
+		BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xffffffff),
+
+		/* if uid is 0, use given mark, else use the uid as the mark */
+		BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
+		BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
 		BPF_MOV64_IMM(BPF_REG_3, mark),
+
+		/* set the mark on the new socket */
+		BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
 		BPF_MOV64_IMM(BPF_REG_2, offsetof(struct bpf_sock, mark)),
 		BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3, offsetof(struct bpf_sock, mark)),
 	};
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH v3 net-next 1/7] bpf: Add mark and priority to sock options that can be set
  2017-08-31 22:05 ` [PATCH v3 net-next 1/7] bpf: Add mark and priority to sock options that can be set David Ahern
@ 2017-08-31 22:21   ` Daniel Borkmann
  0 siblings, 0 replies; 16+ messages in thread
From: Daniel Borkmann @ 2017-08-31 22:21 UTC (permalink / raw)
  To: David Ahern, netdev, ast

On 09/01/2017 12:05 AM, David Ahern wrote:
> Add socket mark and priority to fields that can be set by
> ebpf program when a socket is created.
>
> Signed-off-by: David Ahern <dsahern@gmail.com>
> Acked-by: Alexei Starovoitov <ast@kernel.org>
> ---
>   include/uapi/linux/bpf.h |  2 ++
>   net/core/filter.c        | 26 ++++++++++++++++++++++++++
>   2 files changed, 28 insertions(+)
>
> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> index d46cf326b95f..e9c89e20adff 100644
> --- a/include/uapi/linux/bpf.h
> +++ b/include/uapi/linux/bpf.h
> @@ -758,6 +758,8 @@ struct bpf_sock {
>   	__u32 family;
>   	__u32 type;
>   	__u32 protocol;
> +	__u32 mark;
> +	__u32 priority;
>   };
>
>   #define XDP_PACKET_HEADROOM 256
> diff --git a/net/core/filter.c b/net/core/filter.c
> index c6a37fe0285b..f51b9690adf3 100644
> --- a/net/core/filter.c
> +++ b/net/core/filter.c
> @@ -3455,6 +3455,10 @@ static bool sock_filter_is_valid_access(int off, int size,
>   		switch (off) {
>   		case offsetof(struct bpf_sock, bound_dev_if):
>   			break;
> +		case offsetof(struct bpf_sock, mark):
> +			break;
> +		case offsetof(struct bpf_sock, priority):
> +			break;

Can also be follow-up, but please do keep this consistent
to all the other *_is_valid_access() helpers, meaning:

	switch (off) {
	case offsetof(struct bpf_sock, bound_dev_if):
	case offsetof(struct bpf_sock, mark):
	case offsetof(struct bpf_sock, priority):
		break;
	default:
		return false;
	}

Rest:

Acked-by: Daniel Borkmann <daniel@iogearbox.net>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v3 net-next 2/7] bpf: Allow cgroup sock filters to use get_current_uid_gid helper
  2017-08-31 22:05 ` [PATCH v3 net-next 2/7] bpf: Allow cgroup sock filters to use get_current_uid_gid helper David Ahern
@ 2017-08-31 22:22   ` Daniel Borkmann
  0 siblings, 0 replies; 16+ messages in thread
From: Daniel Borkmann @ 2017-08-31 22:22 UTC (permalink / raw)
  To: David Ahern, netdev, ast

On 09/01/2017 12:05 AM, David Ahern wrote:
> Allow BPF programs run on sock create to use the get_current_uid_gid
> helper. IPv4 and IPv6 sockets are created in a process context so
> there is always a valid uid/gid
>
> Signed-off-by: David Ahern <dsahern@gmail.com>
> Acked-by: Alexei Starovoitov <ast@kernel.org>

Acked-by: Daniel Borkmann <daniel@iogearbox.net>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v3 net-next 3/7] samples/bpf: Update sock test to allow setting mark and priority
  2017-08-31 22:05 ` [PATCH v3 net-next 3/7] samples/bpf: Update sock test to allow setting mark and priority David Ahern
@ 2017-09-01  1:38   ` Alexei Starovoitov
  0 siblings, 0 replies; 16+ messages in thread
From: Alexei Starovoitov @ 2017-09-01  1:38 UTC (permalink / raw)
  To: David Ahern; +Cc: netdev, daniel, ast

On Thu, Aug 31, 2017 at 03:05:46PM -0700, David Ahern wrote:
> Update sock test to set mark and priority on socket create.
> 
> Signed-off-by: David Ahern <dsahern@gmail.com>

Acked-by: Alexei Starovoitov <ast@kernel.org>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v3 net-next 4/7] samples/bpf: Add detach option to test_cgrp2_sock
  2017-08-31 22:05 ` [PATCH v3 net-next 4/7] samples/bpf: Add detach option to test_cgrp2_sock David Ahern
@ 2017-09-01  1:39   ` Alexei Starovoitov
  0 siblings, 0 replies; 16+ messages in thread
From: Alexei Starovoitov @ 2017-09-01  1:39 UTC (permalink / raw)
  To: David Ahern; +Cc: netdev, daniel, ast

On Thu, Aug 31, 2017 at 03:05:47PM -0700, David Ahern wrote:
> Add option to detach programs from a cgroup.
> 
> Signed-off-by: David Ahern <dsahern@gmail.com>

Acked-by: Alexei Starovoitov <ast@kernel.org>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v3 net-next 5/7] samples/bpf: Add option to dump socket settings
  2017-08-31 22:05 ` [PATCH v3 net-next 5/7] samples/bpf: Add option to dump socket settings David Ahern
@ 2017-09-01  1:39   ` Alexei Starovoitov
  0 siblings, 0 replies; 16+ messages in thread
From: Alexei Starovoitov @ 2017-09-01  1:39 UTC (permalink / raw)
  To: David Ahern; +Cc: netdev, daniel, ast

On Thu, Aug 31, 2017 at 03:05:48PM -0700, David Ahern wrote:
> Add option to dump socket settings. Will be used in the next patch
> to verify bpf programs are correctly setting mark, priority and
> device based on the cgroup attachment for the program run.
> 
> Signed-off-by: David Ahern <dsahern@gmail.com>

Acked-by: Alexei Starovoitov <ast@kernel.org>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v3 net-next 6/7] samples/bpf: Update cgrp2 socket tests
  2017-08-31 22:05 ` [PATCH v3 net-next 6/7] samples/bpf: Update cgrp2 socket tests David Ahern
@ 2017-09-01  1:40   ` Alexei Starovoitov
  0 siblings, 0 replies; 16+ messages in thread
From: Alexei Starovoitov @ 2017-09-01  1:40 UTC (permalink / raw)
  To: David Ahern; +Cc: netdev, daniel, ast

On Thu, Aug 31, 2017 at 03:05:49PM -0700, David Ahern wrote:
> Update cgrp2 bpf sock tests to check that device, mark and priority
> can all be set on a socket via bpf programs attached to a cgroup.
> 
> Signed-off-by: David Ahern <dsahern@gmail.com>

Acked-by: Alexei Starovoitov <ast@kernel.org>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v3 net-next 7/7] samples/bpf: Update cgroup socket examples to use uid gid helper
  2017-08-31 22:05 ` [PATCH v3 net-next 7/7] samples/bpf: Update cgroup socket examples to use uid gid helper David Ahern
@ 2017-09-01  1:41   ` Alexei Starovoitov
  0 siblings, 0 replies; 16+ messages in thread
From: Alexei Starovoitov @ 2017-09-01  1:41 UTC (permalink / raw)
  To: David Ahern; +Cc: netdev, daniel, ast

On Thu, Aug 31, 2017 at 03:05:50PM -0700, David Ahern wrote:
> Signed-off-by: David Ahern <dsahern@gmail.com>

Acked-by: Alexei Starovoitov <ast@kernel.org>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v3 net-next 0/7] bpf: Add option to set mark and priority in cgroup sock programs
  2017-08-31 22:05 [PATCH v3 net-next 0/7] bpf: Add option to set mark and priority in cgroup sock programs David Ahern
                   ` (6 preceding siblings ...)
  2017-08-31 22:05 ` [PATCH v3 net-next 7/7] samples/bpf: Update cgroup socket examples to use uid gid helper David Ahern
@ 2017-09-01  5:06 ` David Miller
  7 siblings, 0 replies; 16+ messages in thread
From: David Miller @ 2017-09-01  5:06 UTC (permalink / raw)
  To: dsahern; +Cc: netdev, daniel, ast

From: David Ahern <dsahern@gmail.com>
Date: Thu, 31 Aug 2017 15:05:43 -0700

> Add option to set mark and priority in addition to bound device for newly
> created sockets. Also, allow the bpf programs to use the get_current_uid_gid
> helper meaning socket marks, priority and device can be set based on the
> uid/gid of the running process.
> 
> Sample programs are updated to demonstrate the new options.
> 
> v3
> - no changes to Patches 1 and 2 which Alexei acked in previous versions
> - dropped change related to recursive programs in a cgroup
> - updated tests per dropped patch
> 
> v2
> - added flag to control recursive behavior as requested by Alexei
> - added comment to sock_filter_func_proto regarding use of
>   get_current_uid_gid helper
> - updated test programs for recursive option

Series applied, please follow up to Daniel's feedback.

Thanks.

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2017-09-01  5:06 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-31 22:05 [PATCH v3 net-next 0/7] bpf: Add option to set mark and priority in cgroup sock programs David Ahern
2017-08-31 22:05 ` [PATCH v3 net-next 1/7] bpf: Add mark and priority to sock options that can be set David Ahern
2017-08-31 22:21   ` Daniel Borkmann
2017-08-31 22:05 ` [PATCH v3 net-next 2/7] bpf: Allow cgroup sock filters to use get_current_uid_gid helper David Ahern
2017-08-31 22:22   ` Daniel Borkmann
2017-08-31 22:05 ` [PATCH v3 net-next 3/7] samples/bpf: Update sock test to allow setting mark and priority David Ahern
2017-09-01  1:38   ` Alexei Starovoitov
2017-08-31 22:05 ` [PATCH v3 net-next 4/7] samples/bpf: Add detach option to test_cgrp2_sock David Ahern
2017-09-01  1:39   ` Alexei Starovoitov
2017-08-31 22:05 ` [PATCH v3 net-next 5/7] samples/bpf: Add option to dump socket settings David Ahern
2017-09-01  1:39   ` Alexei Starovoitov
2017-08-31 22:05 ` [PATCH v3 net-next 6/7] samples/bpf: Update cgrp2 socket tests David Ahern
2017-09-01  1:40   ` Alexei Starovoitov
2017-08-31 22:05 ` [PATCH v3 net-next 7/7] samples/bpf: Update cgroup socket examples to use uid gid helper David Ahern
2017-09-01  1:41   ` Alexei Starovoitov
2017-09-01  5:06 ` [PATCH v3 net-next 0/7] bpf: Add option to set mark and priority in cgroup sock programs David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).