Skip to contentSkip to conversation

Support bpf_get_socket_cookie in more prog types

PATCH Applied Andrey Ignatov 3 participants 7 messages Jul 31, 2018

Subsystems (6)
lore
Share & tools
lore
#0 lore raw

v2 cover Support bpf_get_socket_cookie in more prog types

v1->v2:
- simplify attach_type guessing logic in selftest.

This patch set adds support to call bpf_get_socket_cookie() helper from two more program types:
* BPF_PROG_TYPE_CGROUP_SOCK_ADDR;
* BPF_PROG_TYPE_SOCK_OPS.

Patch 1 adds kernel support and provides more details. Patch 2 syncs UAPI changes to tools/.
Patch 3 adds missing helper to bpf_helpers.h. Patch 4 adds selftest for new functionality.

Andrey Ignatov (4):
bpf: Support bpf_get_socket_cookie in more prog types
bpf: Sync bpf.h to tools/
selftests/bpf: Add bpf_get_socket_cookie to bpf_helpers.h selftests/bpf: Test for get_socket_cookie

 include/uapi/linux/bpf.h                      |  14 ++
 net/core/filter.c                             |  28 +++
 tools/include/uapi/linux/bpf.h                |  14 ++
 tools/testing/selftests/bpf/Makefile          |   6 +-
 tools/testing/selftests/bpf/bpf_helpers.h     |   2 +
 .../selftests/bpf/socket_cookie_prog.c        |  60 +++++
 .../selftests/bpf/test_socket_cookie.c        | 225 ++++++++++++++++++
 7 files changed, 347 insertions(+), 2 deletions(-)
 create mode 100644 tools/testing/selftests/bpf/socket_cookie_prog.c
 create mode 100644 tools/testing/selftests/bpf/test_socket_cookie.c
Signature · 1 line
2.17.1
#1 lore raw

PATCH v2 1/4 bpf: Support bpf_get_socket_cookie in more prog types

bpf_get_socket_cookie() helper can be used to identify skb that correspond to the same socket.

Though socket cookie can be useful in many other use-cases where socket is available in program context. Specifically BPF_PROG_TYPE_CGROUP_SOCK_ADDR and BPF_PROG_TYPE_SOCK_OPS programs can benefit from it so that one of them can augment a value in a map prepared earlier by other program for the same socket.

The patch adds support to call bpf_get_socket_cookie() from BPF_PROG_TYPE_CGROUP_SOCK_ADDR and BPF_PROG_TYPE_SOCK_OPS.

It doesn't introduce new helpers. Instead it reuses same helper name bpf_get_socket_cookie() but adds support to this helper to accept struct bpf_sock_addr and struct bpf_sock_ops.

Documentation in bpf.h is changed in a way that should not break automatic generation of markdown.

---
 include/uapi/linux/bpf.h | 14 ++++++++++++++
 net/core/filter.c        | 28 ++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+)
include/uapi/linux/bpf.h +14 -0
index 870113916cac..0ebaaf7f3568 100644
@@ -1371,6 +1371,20 @@ union bpf_attr {
  * 		A 8-byte long non-decreasing number on success, or 0 if the
  * 		socket field is missing inside *skb*.
  *
+ * u64 bpf_get_socket_cookie(struct bpf_sock_addr *ctx)
+ * 	Description
+ * 		Equivalent to bpf_get_socket_cookie() helper that accepts
+ * 		*skb*, but gets socket from **struct bpf_sock_addr** contex.
+ * 	Return
+ * 		A 8-byte long non-decreasing number.
+ *
+ * u64 bpf_get_socket_cookie(struct bpf_sock_ops *ctx)
+ * 	Description
+ * 		Equivalent to bpf_get_socket_cookie() helper that accepts
+ * 		*skb*, but gets socket from **struct bpf_sock_ops** contex.
+ * 	Return
+ * 		A 8-byte long non-decreasing number.
+ *
  * u32 bpf_get_socket_uid(struct sk_buff *skb)
  * 	Return
  * 		The owner UID of the socket associated to *skb*. If the socket
net/core/filter.c +28 -0
index 104d560946da..0b3c59468282 100644
@@ -3812,6 +3812,30 @@ static const struct bpf_func_proto bpf_get_socket_cookie_proto = {
 	.arg1_type      = ARG_PTR_TO_CTX,
 };
 
+BPF_CALL_1(bpf_get_socket_cookie_sock_addr, struct bpf_sock_addr_kern *, ctx)
+{
+	return sock_gen_cookie(ctx->sk);
+}
+
+static const struct bpf_func_proto bpf_get_socket_cookie_sock_addr_proto = {
+	.func		= bpf_get_socket_cookie_sock_addr,
+	.gpl_only	= false,
+	.ret_type	= RET_INTEGER,
+	.arg1_type	= ARG_PTR_TO_CTX,
+};
+
+BPF_CALL_1(bpf_get_socket_cookie_sock_ops, struct bpf_sock_ops_kern *, ctx)
+{
+	return sock_gen_cookie(ctx->sk);
+}
+
+static const struct bpf_func_proto bpf_get_socket_cookie_sock_ops_proto = {
+	.func		= bpf_get_socket_cookie_sock_ops,
+	.gpl_only	= false,
+	.ret_type	= RET_INTEGER,
+	.arg1_type	= ARG_PTR_TO_CTX,
+};
+
 BPF_CALL_1(bpf_get_socket_uid, struct sk_buff *, skb)
 {
 	struct sock *sk = sk_to_full_sk(skb->sk);
@@ -4788,6 +4812,8 @@ sock_addr_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
 		default:
 			return NULL;
 		}
+	case BPF_FUNC_get_socket_cookie:
+		return &bpf_get_socket_cookie_sock_addr_proto;
 	default:
 		return bpf_base_func_proto(func_id);
 	}
@@ -4930,6 +4956,8 @@ sock_ops_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
 		return &bpf_sock_map_update_proto;
 	case BPF_FUNC_sock_hash_update:
 		return &bpf_sock_hash_update_proto;
+	case BPF_FUNC_get_socket_cookie:
+		return &bpf_get_socket_cookie_sock_ops_proto;
 	default:
 		return bpf_base_func_proto(func_id);
 	}
Signature · 1 line
2.17.1
#2 lore raw

PATCH v2 2/4 bpf: Sync bpf.h to tools/

In reply to Andrey Ignatov

Sync bpf_get_socket_cookie() related bpf UAPI changes to tools/.

---
 tools/include/uapi/linux/bpf.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
tools/include/uapi/linux/bpf.h +14 -0
index 870113916cac..0ebaaf7f3568 100644
@@ -1371,6 +1371,20 @@ union bpf_attr {
  * 		A 8-byte long non-decreasing number on success, or 0 if the
  * 		socket field is missing inside *skb*.
  *
+ * u64 bpf_get_socket_cookie(struct bpf_sock_addr *ctx)
+ * 	Description
+ * 		Equivalent to bpf_get_socket_cookie() helper that accepts
+ * 		*skb*, but gets socket from **struct bpf_sock_addr** contex.
+ * 	Return
+ * 		A 8-byte long non-decreasing number.
+ *
+ * u64 bpf_get_socket_cookie(struct bpf_sock_ops *ctx)
+ * 	Description
+ * 		Equivalent to bpf_get_socket_cookie() helper that accepts
+ * 		*skb*, but gets socket from **struct bpf_sock_ops** contex.
+ * 	Return
+ * 		A 8-byte long non-decreasing number.
+ *
  * u32 bpf_get_socket_uid(struct sk_buff *skb)
  * 	Return
  * 		The owner UID of the socket associated to *skb*. If the socket
Signature · 1 line
2.17.1
#3 lore raw

PATCH v2 3/4 selftests/bpf: Add bpf_get_socket_cookie to bpf_helpers.h

In reply to Andrey Ignatov

Add missing helper to bpf_helpers.h that is used in tests and samples.

---
 tools/testing/selftests/bpf/bpf_helpers.h | 2 ++
 1 file changed, 2 insertions(+)
tools/testing/selftests/bpf/bpf_helpers.h +2 -0
index f2f28b6c8915..19a424483f6e 100644
@@ -65,6 +65,8 @@ static int (*bpf_xdp_adjust_head)(void *ctx, int offset) =
 	(void *) BPF_FUNC_xdp_adjust_head;
 static int (*bpf_xdp_adjust_meta)(void *ctx, int offset) =
 	(void *) BPF_FUNC_xdp_adjust_meta;
+static int (*bpf_get_socket_cookie)(void *ctx) =
+	(void *) BPF_FUNC_get_socket_cookie;
 static int (*bpf_setsockopt)(void *ctx, int level, int optname, void *optval,
 			     int optlen) =
 	(void *) BPF_FUNC_setsockopt;
Signature · 1 line
2.17.1
#4 lore raw

PATCH v2 4/4 selftests/bpf: Test for get_socket_cookie

In reply to Andrey Ignatov

Add test to use get_socket_cookie() from BPF programs of types BPF_PROG_TYPE_SOCK_OPS and BPF_PROG_TYPE_CGROUP_SOCK_ADDR.

The test attaches two programs to cgroup, runs TCP server and client in the cgroup and checks that two operations are done properly on client socket when user calls connect(2):

1. In BPF_CGROUP_INET6_CONNECT socket cookie is used as the key to write new value in a map for client socket.

2. In BPF_CGROUP_SOCK_OPS (BPF_SOCK_OPS_TCP_CONNECT_CB callback) the value written in "1." is found by socket cookie, since it's the same socket, and updated.

Finally the test verifies the value in the map.

---
 tools/testing/selftests/bpf/Makefile          |   6 +-
 .../selftests/bpf/socket_cookie_prog.c        |  60 +++++
 .../selftests/bpf/test_socket_cookie.c        | 225 ++++++++++++++++++
 3 files changed, 289 insertions(+), 2 deletions(-)
 create mode 100644 tools/testing/selftests/bpf/socket_cookie_prog.c
 create mode 100644 tools/testing/selftests/bpf/test_socket_cookie.c
tools/testing/selftests/bpf/Makefile +4 -2
index 478bf1bcbbf5..1b28277998e2 100644
@@ -22,7 +22,8 @@ $(TEST_CUSTOM_PROGS): $(OUTPUT)/%: %.c
 # Order correspond to 'make run_tests' order
 TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test_progs \
 	test_align test_verifier_log test_dev_cgroup test_tcpbpf_user \
-	test_sock test_btf test_sockmap test_lirc_mode2_user get_cgroup_id_user
+	test_sock test_btf test_sockmap test_lirc_mode2_user get_cgroup_id_user \
+	test_socket_cookie
 
 TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test_obj_id.o \
 	test_pkt_md_access.o test_xdp_redirect.o test_xdp_meta.o sockmap_parse_prog.o     \
@@ -33,7 +34,7 @@ TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test
 	test_btf_haskv.o test_btf_nokv.o test_sockmap_kern.o test_tunnel_kern.o \
 	test_get_stack_rawtp.o test_sockmap_kern.o test_sockhash_kern.o \
 	test_lwt_seg6local.o sendmsg4_prog.o sendmsg6_prog.o test_lirc_mode2_kern.o \
-	get_cgroup_id_kern.o
+	get_cgroup_id_kern.o socket_cookie_prog.o
 
 # Order correspond to 'make run_tests' order
 TEST_PROGS := test_kmod.sh \
@@ -60,6 +61,7 @@ $(TEST_GEN_PROGS_EXTENDED): $(OUTPUT)/libbpf.a
 $(OUTPUT)/test_dev_cgroup: cgroup_helpers.c
 $(OUTPUT)/test_sock: cgroup_helpers.c
 $(OUTPUT)/test_sock_addr: cgroup_helpers.c
+$(OUTPUT)/test_socket_cookie: cgroup_helpers.c
 $(OUTPUT)/test_sockmap: cgroup_helpers.c
 $(OUTPUT)/test_tcpbpf_user: cgroup_helpers.c
 $(OUTPUT)/test_progs: trace_helpers.c
tools/testing/selftests/bpf/socket_cookie_prog.c new file +60 -0

60 lines not on this page · raw message

tools/testing/selftests/bpf/test_socket_cookie.c new file +225 -0

225 lines not on this page · raw message

Signature · 1 line
2.17.1
Acked-by on v2 4/4
#5 lore raw

Re: [PATCH v2 bpf-next 4/4] selftests/bpf: Test for get_socket_cookie

Quoted 10 lines · Andrey Ignatov

Add test to use get_socket_cookie() from BPF programs of types BPF_PROG_TYPE_SOCK_OPS and BPF_PROG_TYPE_CGROUP_SOCK_ADDR.

The test attaches two programs to cgroup, runs TCP server and client in the cgroup and checks that two operations are done properly on client socket when user calls connect(2):

1. In BPF_CGROUP_INET6_CONNECT socket cookie is used as the key to write new value in a map for client socket.

Quoted 7 lines

2. In BPF_CGROUP_SOCK_OPS (BPF_SOCK_OPS_TCP_CONNECT_CB callback) the value written in "1." is found by socket cookie, since it's the same socket, and updated.

Finally the test verifies the value in the map.

maintainer Applied
#6 lore raw
In reply to Andrey Ignatov
Quoted 14 lines · Andrey Ignatov

v1->v2:
- simplify attach_type guessing logic in selftest.

This patch set adds support to call bpf_get_socket_cookie() helper from two more program types:
* BPF_PROG_TYPE_CGROUP_SOCK_ADDR;
* BPF_PROG_TYPE_SOCK_OPS.

Patch 1 adds kernel support and provides more details. Patch 2 syncs UAPI changes to tools/.
Patch 3 adds missing helper to bpf_helpers.h. Patch 4 adds selftest for new functionality.

Quoted 5 lines

Andrey Ignatov (4):
bpf: Support bpf_get_socket_cookie in more prog types
bpf: Sync bpf.h to tools/
selftests/bpf: Add bpf_get_socket_cookie to bpf_helpers.h selftests/bpf: Test for get_socket_cookie

Applied to bpf-next, thanks Andrey!