* [PATCH mptcp-next v4 1/7] bpf: Add new prog type sockinit
2023-07-05 6:56 [PATCH mptcp-next v4 0/7] BPF 'force to MPTCP' Geliang Tang
@ 2023-07-05 6:56 ` Geliang Tang
2023-07-05 6:56 ` [PATCH mptcp-next v4 2/7] bpf: Run a sockinit program Geliang Tang
` (6 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Geliang Tang @ 2023-07-05 6:56 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
The patch introduces new program type BPF_PROG_TYPE_CGROUP_SOCKINIT
and attach type BPF_CGROUP_SOCKINIT on cgroup basis.
Define this program by BPF_PROG_TYPE(), and implement two operations:
cg_sockinit_prog_ops and cg_sockinit_verifier_ops.
Signed-off-by: Geliang Tang <geliang.tang@suse.com>
---
include/linux/bpf_types.h | 2 ++
include/uapi/linux/bpf.h | 8 +++++
kernel/bpf/cgroup.c | 66 +++++++++++++++++++++++++++++++++++++++
kernel/bpf/syscall.c | 7 +++++
kernel/bpf/verifier.c | 1 +
5 files changed, 84 insertions(+)
diff --git a/include/linux/bpf_types.h b/include/linux/bpf_types.h
index fc0d6f32c687..44afed8e5444 100644
--- a/include/linux/bpf_types.h
+++ b/include/linux/bpf_types.h
@@ -52,6 +52,8 @@ BPF_PROG_TYPE(BPF_PROG_TYPE_TRACING, tracing,
#ifdef CONFIG_CGROUP_BPF
BPF_PROG_TYPE(BPF_PROG_TYPE_CGROUP_DEVICE, cg_dev,
struct bpf_cgroup_dev_ctx, struct bpf_cgroup_dev_ctx)
+BPF_PROG_TYPE(BPF_PROG_TYPE_CGROUP_SOCKINIT, cg_sockinit,
+ struct bpf_sockinit_ctx, struct bpf_sockinit_ctx)
BPF_PROG_TYPE(BPF_PROG_TYPE_CGROUP_SYSCTL, cg_sysctl,
struct bpf_sysctl, struct bpf_sysctl_kern)
BPF_PROG_TYPE(BPF_PROG_TYPE_CGROUP_SOCKOPT, cg_sockopt,
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 60a9d59beeab..cb882ab8065d 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -980,6 +980,7 @@ enum bpf_prog_type {
BPF_PROG_TYPE_CGROUP_SYSCTL,
BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE,
BPF_PROG_TYPE_CGROUP_SOCKOPT,
+ BPF_PROG_TYPE_CGROUP_SOCKINIT,
BPF_PROG_TYPE_TRACING,
BPF_PROG_TYPE_STRUCT_OPS,
BPF_PROG_TYPE_EXT,
@@ -1013,6 +1014,7 @@ enum bpf_attach_type {
BPF_CGROUP_UDP6_RECVMSG,
BPF_CGROUP_GETSOCKOPT,
BPF_CGROUP_SETSOCKOPT,
+ BPF_CGROUP_SOCKINIT,
BPF_TRACE_RAW_TP,
BPF_TRACE_FENTRY,
BPF_TRACE_FEXIT,
@@ -6829,6 +6831,12 @@ struct bpf_raw_tracepoint_args {
__u64 args[0];
};
+struct bpf_sockinit_ctx {
+ __u32 family;
+ __u32 type;
+ __u32 protocol;
+};
+
/* DIRECT: Skip the FIB rules and go to FIB table associated with device
* OUTPUT: Do lookup from egress perspective; default is ingress
*/
diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
index 5b2741aa0d9b..93b9f404a007 100644
--- a/kernel/bpf/cgroup.c
+++ b/kernel/bpf/cgroup.c
@@ -2505,6 +2505,72 @@ const struct bpf_verifier_ops cg_sockopt_verifier_ops = {
const struct bpf_prog_ops cg_sockopt_prog_ops = {
};
+static const struct bpf_func_proto *
+cgroup_sockinit_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
+{
+ const struct bpf_func_proto *func_proto;
+
+ func_proto = cgroup_common_func_proto(func_id, prog);
+ if (func_proto)
+ return func_proto;
+
+ func_proto = cgroup_current_func_proto(func_id, prog);
+ if (func_proto)
+ return func_proto;
+
+ switch (func_id) {
+ default:
+ return bpf_base_func_proto(func_id);
+ }
+}
+
+static bool cgroup_sockinit_is_valid_access(int off, int size,
+ enum bpf_access_type type,
+ const struct bpf_prog *prog,
+ struct bpf_insn_access_aux *info)
+{
+ const int size_default = sizeof(__u32);
+
+ if (off < 0 || off + size > sizeof(struct bpf_sockinit_ctx))
+ return false;
+
+ if (off % size != 0)
+ return false;
+
+ switch (off) {
+ case bpf_ctx_range(struct bpf_sockinit_ctx, family):
+ bpf_ctx_record_field_size(info, size_default);
+ if (!bpf_ctx_narrow_access_ok(off, size, size_default))
+ return false;
+ break;
+ case bpf_ctx_range(struct bpf_sockinit_ctx, type):
+ bpf_ctx_record_field_size(info, size_default);
+ if (!bpf_ctx_narrow_access_ok(off, size, size_default))
+ return false;
+ break;
+ case bpf_ctx_range(struct bpf_sockinit_ctx, protocol):
+ if (type == BPF_READ) {
+ bpf_ctx_record_field_size(info, size_default);
+ return bpf_ctx_narrow_access_ok(off, size, size_default);
+ } else {
+ return size == size_default;
+ }
+ default:
+ if (size != size_default)
+ return false;
+ }
+
+ return true;
+}
+
+const struct bpf_verifier_ops cg_sockinit_verifier_ops = {
+ .get_func_proto = cgroup_sockinit_func_proto,
+ .is_valid_access = cgroup_sockinit_is_valid_access,
+};
+
+const struct bpf_prog_ops cg_sockinit_prog_ops = {
+};
+
/* Common helpers for cgroup hooks. */
const struct bpf_func_proto *
cgroup_common_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index a2aef900519c..2952dd88c614 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -2513,6 +2513,7 @@ static bool is_net_admin_prog_type(enum bpf_prog_type prog_type)
case BPF_PROG_TYPE_CGROUP_SOCK_ADDR:
case BPF_PROG_TYPE_CGROUP_SOCKOPT:
case BPF_PROG_TYPE_CGROUP_SYSCTL:
+ case BPF_PROG_TYPE_CGROUP_SOCKINIT:
case BPF_PROG_TYPE_SOCK_OPS:
case BPF_PROG_TYPE_EXT: /* extends any prog */
case BPF_PROG_TYPE_NETFILTER:
@@ -3574,6 +3575,8 @@ attach_type_to_prog_type(enum bpf_attach_type attach_type)
case BPF_CGROUP_GETSOCKOPT:
case BPF_CGROUP_SETSOCKOPT:
return BPF_PROG_TYPE_CGROUP_SOCKOPT;
+ case BPF_CGROUP_SOCKINIT:
+ return BPF_PROG_TYPE_CGROUP_SOCKINIT;
case BPF_TRACE_ITER:
case BPF_TRACE_RAW_TP:
case BPF_TRACE_FENTRY:
@@ -3640,6 +3643,7 @@ static int bpf_prog_attach(const union bpf_attr *attr)
case BPF_PROG_TYPE_CGROUP_SOCK_ADDR:
case BPF_PROG_TYPE_CGROUP_SOCKOPT:
case BPF_PROG_TYPE_CGROUP_SYSCTL:
+ case BPF_PROG_TYPE_CGROUP_SOCKINIT:
case BPF_PROG_TYPE_SOCK_OPS:
case BPF_PROG_TYPE_LSM:
if (ptype == BPF_PROG_TYPE_LSM &&
@@ -3682,6 +3686,7 @@ static int bpf_prog_detach(const union bpf_attr *attr)
case BPF_PROG_TYPE_CGROUP_SOCK_ADDR:
case BPF_PROG_TYPE_CGROUP_SOCKOPT:
case BPF_PROG_TYPE_CGROUP_SYSCTL:
+ case BPF_PROG_TYPE_CGROUP_SOCKINIT:
case BPF_PROG_TYPE_SOCK_OPS:
case BPF_PROG_TYPE_LSM:
return cgroup_bpf_prog_detach(attr, ptype);
@@ -3726,6 +3731,7 @@ static int bpf_prog_query(const union bpf_attr *attr,
case BPF_CGROUP_SYSCTL:
case BPF_CGROUP_GETSOCKOPT:
case BPF_CGROUP_SETSOCKOPT:
+ case BPF_CGROUP_SOCKINIT:
case BPF_LSM_CGROUP:
return cgroup_bpf_prog_query(attr, uattr);
case BPF_LIRC_MODE2:
@@ -4717,6 +4723,7 @@ static int link_create(union bpf_attr *attr, bpfptr_t uattr)
case BPF_PROG_TYPE_CGROUP_DEVICE:
case BPF_PROG_TYPE_CGROUP_SYSCTL:
case BPF_PROG_TYPE_CGROUP_SOCKOPT:
+ case BPF_PROG_TYPE_CGROUP_SOCKINIT:
ret = cgroup_bpf_link_attach(attr, prog);
break;
case BPF_PROG_TYPE_EXT:
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 11e54dd8b6dd..d0ade7759123 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -14316,6 +14316,7 @@ static int check_return_code(struct bpf_verifier_env *env)
case BPF_PROG_TYPE_CGROUP_DEVICE:
case BPF_PROG_TYPE_CGROUP_SYSCTL:
case BPF_PROG_TYPE_CGROUP_SOCKOPT:
+ case BPF_PROG_TYPE_CGROUP_SOCKINIT:
break;
case BPF_PROG_TYPE_RAW_TRACEPOINT:
if (!env->prog->aux->attach_btf_id)
--
2.35.3
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH mptcp-next v4 2/7] bpf: Run a sockinit program
2023-07-05 6:56 [PATCH mptcp-next v4 0/7] BPF 'force to MPTCP' Geliang Tang
2023-07-05 6:56 ` [PATCH mptcp-next v4 1/7] bpf: Add new prog type sockinit Geliang Tang
@ 2023-07-05 6:56 ` Geliang Tang
2023-07-05 6:56 ` [PATCH mptcp-next v4 3/7] net: socket: run sockinit hooks Geliang Tang
` (5 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Geliang Tang @ 2023-07-05 6:56 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
This patch defines BPF_CGROUP_RUN_PROG_SOCKINIT() helper, and implements
__cgroup_bpf_run_sockinit() helper to run a sockinit program.
Signed-off-by: Geliang Tang <geliang.tang@suse.com>
---
include/linux/bpf-cgroup-defs.h | 1 +
include/linux/bpf-cgroup.h | 14 ++++++++++++++
kernel/bpf/cgroup.c | 24 ++++++++++++++++++++++++
3 files changed, 39 insertions(+)
diff --git a/include/linux/bpf-cgroup-defs.h b/include/linux/bpf-cgroup-defs.h
index 7b121bd780eb..aa9ee82f5d20 100644
--- a/include/linux/bpf-cgroup-defs.h
+++ b/include/linux/bpf-cgroup-defs.h
@@ -37,6 +37,7 @@ enum cgroup_bpf_attach_type {
CGROUP_UDP6_RECVMSG,
CGROUP_GETSOCKOPT,
CGROUP_SETSOCKOPT,
+ CGROUP_SOCKINIT,
CGROUP_INET4_GETPEERNAME,
CGROUP_INET6_GETPEERNAME,
CGROUP_INET4_GETSOCKNAME,
diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h
index 57e9e109257e..a2f58f0d2260 100644
--- a/include/linux/bpf-cgroup.h
+++ b/include/linux/bpf-cgroup.h
@@ -57,6 +57,7 @@ to_cgroup_bpf_attach_type(enum bpf_attach_type attach_type)
CGROUP_ATYPE(CGROUP_UDP6_RECVMSG);
CGROUP_ATYPE(CGROUP_GETSOCKOPT);
CGROUP_ATYPE(CGROUP_SETSOCKOPT);
+ CGROUP_ATYPE(CGROUP_SOCKINIT);
CGROUP_ATYPE(CGROUP_INET4_GETPEERNAME);
CGROUP_ATYPE(CGROUP_INET6_GETPEERNAME);
CGROUP_ATYPE(CGROUP_INET4_GETSOCKNAME);
@@ -148,6 +149,9 @@ int __cgroup_bpf_run_filter_getsockopt_kern(struct sock *sk, int level,
int optname, void *optval,
int *optlen, int retval);
+int __cgroup_bpf_run_sockinit(int *family, int *type, int *protocol,
+ enum cgroup_bpf_attach_type atype);
+
static inline enum bpf_cgroup_storage_type cgroup_storage_type(
struct bpf_map *map)
{
@@ -407,6 +411,15 @@ static inline bool cgroup_bpf_sock_enabled(struct sock *sk,
__ret; \
})
+#define BPF_CGROUP_RUN_PROG_SOCKINIT(family, type, protocol) \
+({ \
+ int __ret = 0; \
+ if (cgroup_bpf_enabled(CGROUP_SOCKINIT)) \
+ __ret = __cgroup_bpf_run_sockinit(family, type, protocol, \
+ CGROUP_SOCKINIT); \
+ __ret; \
+})
+
int cgroup_bpf_prog_attach(const union bpf_attr *attr,
enum bpf_prog_type ptype, struct bpf_prog *prog);
int cgroup_bpf_prog_detach(const union bpf_attr *attr,
@@ -505,6 +518,7 @@ static inline int bpf_percpu_cgroup_storage_update(struct bpf_map *map,
optlen, retval) ({ retval; })
#define BPF_CGROUP_RUN_PROG_SETSOCKOPT(sock, level, optname, optval, optlen, \
kernel_optval) ({ 0; })
+#define BPF_CGROUP_RUN_PROG_SOCKINIT(family, type, protocol) ({ 0; })
#define for_each_cgroup_storage_type(stype) for (; false; )
diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
index 93b9f404a007..fe294e4d618c 100644
--- a/kernel/bpf/cgroup.c
+++ b/kernel/bpf/cgroup.c
@@ -1996,6 +1996,30 @@ int __cgroup_bpf_run_filter_getsockopt_kern(struct sock *sk, int level,
return ret;
}
+
+int __cgroup_bpf_run_sockinit(int *family, int *type, int *protocol,
+ enum cgroup_bpf_attach_type atype)
+{
+ struct bpf_sockinit_ctx ctx = {
+ .family = *family,
+ .type = *type,
+ .protocol = *protocol,
+ };
+ struct cgroup *cgrp;
+ int ret;
+
+ rcu_read_lock();
+ cgrp = task_dfl_cgroup(current);
+ ret = bpf_prog_run_array_cg(&cgrp->bpf, atype, &ctx, bpf_prog_run, 0,
+ NULL);
+ rcu_read_unlock();
+
+ *family = ctx.family;
+ *type = ctx.type;
+ *protocol = ctx.protocol;
+
+ return ret;
+}
#endif
static ssize_t sysctl_cpy_dir(const struct ctl_dir *dir, char **bufp,
--
2.35.3
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH mptcp-next v4 3/7] net: socket: run sockinit hooks
2023-07-05 6:56 [PATCH mptcp-next v4 0/7] BPF 'force to MPTCP' Geliang Tang
2023-07-05 6:56 ` [PATCH mptcp-next v4 1/7] bpf: Add new prog type sockinit Geliang Tang
2023-07-05 6:56 ` [PATCH mptcp-next v4 2/7] bpf: Run a sockinit program Geliang Tang
@ 2023-07-05 6:56 ` Geliang Tang
2023-07-05 6:56 ` [PATCH mptcp-next v4 4/7] libbpf: Support sockinit hook Geliang Tang
` (4 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Geliang Tang @ 2023-07-05 6:56 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
The arguments of socket() need to be changed sometimes like the MPTCP
case in the next commits.
It's too late to add the BPF hooks in BPF_CGROUP_RUN_PROG_INET_SOCK()
in inet_create(). So this patch invokes BPF_CGROUP_RUN_PROG_SOCKINIT()
in __socket_create() to change the arguments.
Signed-off-by: Geliang Tang <geliang.tang@suse.com>
---
net/socket.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/socket.c b/net/socket.c
index 2b0e54b2405c..27b423e1800f 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1469,6 +1469,12 @@ int __sock_create(struct net *net, int family, int type, int protocol,
struct socket *sock;
const struct net_proto_family *pf;
+ if (!kern) {
+ err = BPF_CGROUP_RUN_PROG_SOCKINIT(&family, &type, &protocol);
+ if (err)
+ return err;
+ }
+
/*
* Check protocol is in range
*/
--
2.35.3
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH mptcp-next v4 4/7] libbpf: Support sockinit hook
2023-07-05 6:56 [PATCH mptcp-next v4 0/7] BPF 'force to MPTCP' Geliang Tang
` (2 preceding siblings ...)
2023-07-05 6:56 ` [PATCH mptcp-next v4 3/7] net: socket: run sockinit hooks Geliang Tang
@ 2023-07-05 6:56 ` Geliang Tang
2023-07-05 6:56 ` [PATCH mptcp-next v4 5/7] selftests/bpf: Add mptcpify program Geliang Tang
` (3 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Geliang Tang @ 2023-07-05 6:56 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
Sync BPF_PROG_TYPE_CGROUP_SOCKINIT related bpf UAPI changes to tools/.
Support BPF_PROG_TYPE_CGROUP_SOCKINIT program in libbpf: identifying
program and attach types by section name, probe.
Signed-off-by: Geliang Tang <geliang.tang@suse.com>
---
tools/include/uapi/linux/bpf.h | 8 ++++++++
tools/lib/bpf/libbpf.c | 3 +++
tools/lib/bpf/libbpf_probes.c | 1 +
3 files changed, 12 insertions(+)
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 60a9d59beeab..cb882ab8065d 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -980,6 +980,7 @@ enum bpf_prog_type {
BPF_PROG_TYPE_CGROUP_SYSCTL,
BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE,
BPF_PROG_TYPE_CGROUP_SOCKOPT,
+ BPF_PROG_TYPE_CGROUP_SOCKINIT,
BPF_PROG_TYPE_TRACING,
BPF_PROG_TYPE_STRUCT_OPS,
BPF_PROG_TYPE_EXT,
@@ -1013,6 +1014,7 @@ enum bpf_attach_type {
BPF_CGROUP_UDP6_RECVMSG,
BPF_CGROUP_GETSOCKOPT,
BPF_CGROUP_SETSOCKOPT,
+ BPF_CGROUP_SOCKINIT,
BPF_TRACE_RAW_TP,
BPF_TRACE_FENTRY,
BPF_TRACE_FEXIT,
@@ -6829,6 +6831,12 @@ struct bpf_raw_tracepoint_args {
__u64 args[0];
};
+struct bpf_sockinit_ctx {
+ __u32 family;
+ __u32 type;
+ __u32 protocol;
+};
+
/* DIRECT: Skip the FIB rules and go to FIB table associated with device
* OUTPUT: Do lookup from egress perspective; default is ingress
*/
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 214f828ece6b..03f62d163030 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -95,6 +95,7 @@ static const char * const attach_type_name[] = {
[BPF_CGROUP_UDP6_RECVMSG] = "cgroup_udp6_recvmsg",
[BPF_CGROUP_GETSOCKOPT] = "cgroup_getsockopt",
[BPF_CGROUP_SETSOCKOPT] = "cgroup_setsockopt",
+ [BPF_CGROUP_SOCKINIT] = "cgroup_sockinit",
[BPF_SK_SKB_STREAM_PARSER] = "sk_skb_stream_parser",
[BPF_SK_SKB_STREAM_VERDICT] = "sk_skb_stream_verdict",
[BPF_SK_SKB_VERDICT] = "sk_skb_verdict",
@@ -197,6 +198,7 @@ static const char * const prog_type_name[] = {
[BPF_PROG_TYPE_CGROUP_SYSCTL] = "cgroup_sysctl",
[BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE] = "raw_tracepoint_writable",
[BPF_PROG_TYPE_CGROUP_SOCKOPT] = "cgroup_sockopt",
+ [BPF_PROG_TYPE_CGROUP_SOCKINIT] = "cgroup_sockinit",
[BPF_PROG_TYPE_TRACING] = "tracing",
[BPF_PROG_TYPE_STRUCT_OPS] = "struct_ops",
[BPF_PROG_TYPE_EXT] = "ext",
@@ -8734,6 +8736,7 @@ static const struct bpf_sec_def section_defs[] = {
SEC_DEF("cgroup/getsockopt", CGROUP_SOCKOPT, BPF_CGROUP_GETSOCKOPT, SEC_ATTACHABLE),
SEC_DEF("cgroup/setsockopt", CGROUP_SOCKOPT, BPF_CGROUP_SETSOCKOPT, SEC_ATTACHABLE),
SEC_DEF("cgroup/dev", CGROUP_DEVICE, BPF_CGROUP_DEVICE, SEC_ATTACHABLE_OPT),
+ SEC_DEF("cgroup/sockinit", CGROUP_SOCKINIT, BPF_CGROUP_SOCKINIT, SEC_ATTACHABLE),
SEC_DEF("struct_ops+", STRUCT_OPS, 0, SEC_NONE),
SEC_DEF("struct_ops.s+", STRUCT_OPS, 0, SEC_SLEEPABLE),
SEC_DEF("sk_lookup", SK_LOOKUP, BPF_SK_LOOKUP, SEC_ATTACHABLE),
diff --git a/tools/lib/bpf/libbpf_probes.c b/tools/lib/bpf/libbpf_probes.c
index 9c4db90b92b6..3734fee60d2f 100644
--- a/tools/lib/bpf/libbpf_probes.c
+++ b/tools/lib/bpf/libbpf_probes.c
@@ -180,6 +180,7 @@ static int probe_prog_load(enum bpf_prog_type prog_type,
case BPF_PROG_TYPE_SK_REUSEPORT:
case BPF_PROG_TYPE_FLOW_DISSECTOR:
case BPF_PROG_TYPE_CGROUP_SYSCTL:
+ case BPF_PROG_TYPE_CGROUP_SOCKINIT:
break;
case BPF_PROG_TYPE_NETFILTER:
opts.expected_attach_type = BPF_NETFILTER;
--
2.35.3
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH mptcp-next v4 5/7] selftests/bpf: Add mptcpify program
2023-07-05 6:56 [PATCH mptcp-next v4 0/7] BPF 'force to MPTCP' Geliang Tang
` (3 preceding siblings ...)
2023-07-05 6:56 ` [PATCH mptcp-next v4 4/7] libbpf: Support sockinit hook Geliang Tang
@ 2023-07-05 6:56 ` Geliang Tang
2023-07-05 6:56 ` [PATCH mptcp-next v4 6/7] Squash to "selftests/bpf: add two mptcp netns helpers" Geliang Tang
` (2 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Geliang Tang @ 2023-07-05 6:56 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
This patch implements a new test program mptcpify: if the family is
AF_INET or AF_INET6, the type is SOCK_STREAM, and the protocol ID is
0 or IPPROTO_TCP, set it to IPPROTO_MPTCP.
This is defined in a newly added 'sockinit' SEC, so it will be hooked
in BPF_CGROUP_RUN_PROG_SOCKINIT() in __socket_create().
Signed-off-by: Geliang Tang <geliang.tang@suse.com>
---
.../bpf/cgroup_getset_retval_hooks.h | 1 +
.../selftests/bpf/prog_tests/section_names.c | 5 ++++
tools/testing/selftests/bpf/progs/mptcpify.c | 26 +++++++++++++++++++
3 files changed, 32 insertions(+)
create mode 100644 tools/testing/selftests/bpf/progs/mptcpify.c
diff --git a/tools/testing/selftests/bpf/cgroup_getset_retval_hooks.h b/tools/testing/selftests/bpf/cgroup_getset_retval_hooks.h
index a525d3544fd7..0ba09e135df3 100644
--- a/tools/testing/selftests/bpf/cgroup_getset_retval_hooks.h
+++ b/tools/testing/selftests/bpf/cgroup_getset_retval_hooks.h
@@ -14,6 +14,7 @@ BPF_RETVAL_HOOK(post_bind6, "cgroup/post_bind6", bpf_sock_addr, 0)
BPF_RETVAL_HOOK(sendmsg4, "cgroup/sendmsg4", bpf_sock_addr, 0)
BPF_RETVAL_HOOK(sendmsg6, "cgroup/sendmsg6", bpf_sock_addr, 0)
BPF_RETVAL_HOOK(sysctl, "cgroup/sysctl", bpf_sysctl, 0)
+BPF_RETVAL_HOOK(sockinit, "cgroup/sockinit", bpf_sockinit_ctx, 0)
BPF_RETVAL_HOOK(recvmsg4, "cgroup/recvmsg4", bpf_sock_addr, -EINVAL)
BPF_RETVAL_HOOK(recvmsg6, "cgroup/recvmsg6", bpf_sock_addr, -EINVAL)
BPF_RETVAL_HOOK(getsockopt, "cgroup/getsockopt", bpf_sockopt, 0)
diff --git a/tools/testing/selftests/bpf/prog_tests/section_names.c b/tools/testing/selftests/bpf/prog_tests/section_names.c
index 8b571890c57e..52319c45de57 100644
--- a/tools/testing/selftests/bpf/prog_tests/section_names.c
+++ b/tools/testing/selftests/bpf/prog_tests/section_names.c
@@ -158,6 +158,11 @@ static struct sec_name_test tests[] = {
{0, BPF_PROG_TYPE_CGROUP_SOCKOPT, BPF_CGROUP_SETSOCKOPT},
{0, BPF_CGROUP_SETSOCKOPT},
},
+ {
+ "cgroup/sockinit",
+ {0, BPF_PROG_TYPE_CGROUP_SOCKINIT, BPF_CGROUP_SOCKINIT},
+ {0, BPF_CGROUP_SOCKINIT},
+ },
};
static void test_prog_type_by_name(const struct sec_name_test *test)
diff --git a/tools/testing/selftests/bpf/progs/mptcpify.c b/tools/testing/selftests/bpf/progs/mptcpify.c
new file mode 100644
index 000000000000..f751e6f65eca
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/mptcpify.c
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2023, SUSE. */
+
+#include <linux/bpf.h>
+#include <bpf/bpf_helpers.h>
+#include "bpf_tcp_helpers.h"
+
+char _license[] SEC("license") = "GPL";
+
+#define AF_INET 2
+#define AF_INET6 10
+#define SOCK_STREAM 1
+#define IPPROTO_TCP 6
+#define IPPROTO_MPTCP 262
+
+SEC("cgroup/sockinit")
+int mptcpify(struct bpf_sockinit_ctx *ctx)
+{
+ if ((ctx->family == AF_INET || ctx->family == AF_INET6) &&
+ ctx->type == SOCK_STREAM &&
+ (!ctx->protocol || ctx->protocol == IPPROTO_TCP)) {
+ ctx->protocol = IPPROTO_MPTCP;
+ }
+
+ return 1;
+}
--
2.35.3
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH mptcp-next v4 6/7] Squash to "selftests/bpf: add two mptcp netns helpers"
2023-07-05 6:56 [PATCH mptcp-next v4 0/7] BPF 'force to MPTCP' Geliang Tang
` (4 preceding siblings ...)
2023-07-05 6:56 ` [PATCH mptcp-next v4 5/7] selftests/bpf: Add mptcpify program Geliang Tang
@ 2023-07-05 6:56 ` Geliang Tang
2023-07-05 8:04 ` Matthieu Baerts
2023-07-05 6:56 ` [PATCH mptcp-next v4 7/7] selftests/bpf: Add mptcpify selftest Geliang Tang
2023-07-05 8:02 ` [PATCH mptcp-next v4 0/7] BPF 'force to MPTCP' Matthieu Baerts
7 siblings, 1 reply; 11+ messages in thread
From: Geliang Tang @ 2023-07-05 6:56 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
Move the helpers to the beginning.
Signed-off-by: Geliang Tang <geliang.tang@suse.com>
---
.../testing/selftests/bpf/prog_tests/mptcp.c | 40 +++++++++----------
1 file changed, 20 insertions(+), 20 deletions(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/mptcp.c b/tools/testing/selftests/bpf/prog_tests/mptcp.c
index a968641cc94a..e430bebebcf0 100644
--- a/tools/testing/selftests/bpf/prog_tests/mptcp.c
+++ b/tools/testing/selftests/bpf/prog_tests/mptcp.c
@@ -26,6 +26,26 @@ struct mptcp_storage {
char ca_name[TCP_CA_NAME_MAX];
};
+static struct nstoken *create_netns(void)
+{
+ srand(time(NULL));
+ snprintf(NS_TEST, sizeof(NS_TEST), "mptcp_ns_%d", rand());
+ SYS(fail, "ip netns add %s", NS_TEST);
+ SYS(fail, "ip -net %s link set dev lo up", NS_TEST);
+
+ return open_netns(NS_TEST);
+fail:
+ return NULL;
+}
+
+static void cleanup_netns(struct nstoken *nstoken)
+{
+ if (nstoken)
+ close_netns(nstoken);
+
+ SYS_NOFAIL("ip netns del %s &> /dev/null", NS_TEST);
+}
+
static int verify_tsk(int map_fd, int client_fd)
{
int err, cfd = client_fd;
@@ -142,26 +162,6 @@ static int run_test(int cgroup_fd, int server_fd, bool is_mptcp)
return err;
}
-static struct nstoken *create_netns(void)
-{
- srand(time(NULL));
- snprintf(NS_TEST, sizeof(NS_TEST), "mptcp_ns_%d", rand());
- SYS(fail, "ip netns add %s", NS_TEST);
- SYS(fail, "ip -net %s link set dev lo up", NS_TEST);
-
- return open_netns(NS_TEST);
-fail:
- return NULL;
-}
-
-static void cleanup_netns(struct nstoken *nstoken)
-{
- if (nstoken)
- close_netns(nstoken);
-
- SYS_NOFAIL("ip netns del %s &> /dev/null", NS_TEST);
-}
-
static void test_base(void)
{
struct nstoken *nstoken = NULL;
--
2.35.3
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH mptcp-next v4 7/7] selftests/bpf: Add mptcpify selftest
2023-07-05 6:56 [PATCH mptcp-next v4 0/7] BPF 'force to MPTCP' Geliang Tang
` (5 preceding siblings ...)
2023-07-05 6:56 ` [PATCH mptcp-next v4 6/7] Squash to "selftests/bpf: add two mptcp netns helpers" Geliang Tang
@ 2023-07-05 6:56 ` Geliang Tang
2023-07-05 8:15 ` selftests/bpf: Add mptcpify selftest: Tests Results MPTCP CI
2023-07-05 8:02 ` [PATCH mptcp-next v4 0/7] BPF 'force to MPTCP' Matthieu Baerts
7 siblings, 1 reply; 11+ messages in thread
From: Geliang Tang @ 2023-07-05 6:56 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
This patch extends the MPTCP test base, add a selftest test_mptcpify()
for the mptcpify case.
Open and load the mptcpify test prog to mptcpify the TCP sockets
dynamically, then use start_server() and connect_to_fd() to create a
TCP socket, but actually what's created is an MPTCP socket, which can
be verified through the output of 'ss' command.
Signed-off-by: Geliang Tang <geliang.tang@suse.com>
---
.../testing/selftests/bpf/prog_tests/mptcp.c | 84 +++++++++++++++++++
1 file changed, 84 insertions(+)
diff --git a/tools/testing/selftests/bpf/prog_tests/mptcp.c b/tools/testing/selftests/bpf/prog_tests/mptcp.c
index e430bebebcf0..69c102a02ae3 100644
--- a/tools/testing/selftests/bpf/prog_tests/mptcp.c
+++ b/tools/testing/selftests/bpf/prog_tests/mptcp.c
@@ -6,6 +6,7 @@
#include "cgroup_helpers.h"
#include "network_helpers.h"
#include "mptcp_sock.skel.h"
+#include "mptcpify.skel.h"
#include "mptcp_bpf_first.skel.h"
#include "mptcp_bpf_bkup.skel.h"
#include "mptcp_bpf_rr.skel.h"
@@ -200,6 +201,87 @@ static void test_base(void)
close(cgroup_fd);
}
+static void send_byte(int fd)
+{
+ char b = 0x55;
+
+ ASSERT_EQ(write(fd, &b, sizeof(b)), 1, "send single byte");
+}
+
+static int verify_mptcpify(void)
+{
+ char cmd[128];
+ int err = 0;
+
+ snprintf(cmd, sizeof(cmd),
+ "ip netns exec %s ss -tOni | grep -q tcp-ulp-mptcp",
+ NS_TEST);
+ if (!ASSERT_OK(system(cmd), "No tcp-ulp-mptcp found!"))
+ err++;
+
+ return err;
+}
+
+static int run_mptcpify(int cgroup_fd)
+{
+ int server_fd, client_fd, err = 0;
+ struct mptcpify *mptcpify_skel;
+
+ mptcpify_skel = mptcpify__open_and_load();
+ if (!ASSERT_OK_PTR(mptcpify_skel, "mptcpify__open_and_load"))
+ return -EIO;
+
+ mptcpify_skel->links.mptcpify =
+ bpf_program__attach_cgroup(mptcpify_skel->progs.mptcpify, cgroup_fd);
+ if (!ASSERT_OK_PTR(mptcpify_skel->links.mptcpify, "bpf_program__attach_cgroup")) {
+ err = -EIO;
+ goto out;
+ }
+
+ /* without MPTCP */
+ server_fd = start_server(AF_INET, SOCK_STREAM, NULL, 0, 0);
+ if (!ASSERT_GE(server_fd, 0, "start_server")) {
+ err = -EIO;
+ goto out;
+ }
+
+ client_fd = connect_to_fd(server_fd, 0);
+ if (!ASSERT_GE(client_fd, 0, "connect to fd")) {
+ err = -EIO;
+ goto close_server;
+ }
+
+ send_byte(client_fd);
+ err += verify_mptcpify();
+
+ close(client_fd);
+close_server:
+ close(server_fd);
+out:
+ mptcpify__destroy(mptcpify_skel);
+ return err;
+}
+
+static void test_mptcpify(void)
+{
+ struct nstoken *nstoken = NULL;
+ int cgroup_fd;
+
+ cgroup_fd = test__join_cgroup("/mptcpify");
+ if (!ASSERT_GE(cgroup_fd, 0, "test__join_cgroup"))
+ return;
+
+ nstoken = create_netns();
+ if (!ASSERT_OK_PTR(nstoken, "create_netns"))
+ goto fail;
+
+ ASSERT_OK(run_mptcpify(cgroup_fd), "run_mptcpify");
+
+fail:
+ cleanup_netns(nstoken);
+ close(cgroup_fd);
+}
+
static const unsigned int total_bytes = 10 * 1024 * 1024;
static int stop, duration;
@@ -459,6 +541,8 @@ void test_mptcp(void)
{
if (test__start_subtest("base"))
test_base();
+ if (test__start_subtest("mptcpify"))
+ test_mptcpify();
if (test__start_subtest("first"))
test_first();
if (test__start_subtest("bkup"))
--
2.35.3
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH mptcp-next v4 0/7] BPF 'force to MPTCP'
2023-07-05 6:56 [PATCH mptcp-next v4 0/7] BPF 'force to MPTCP' Geliang Tang
` (6 preceding siblings ...)
2023-07-05 6:56 ` [PATCH mptcp-next v4 7/7] selftests/bpf: Add mptcpify selftest Geliang Tang
@ 2023-07-05 8:02 ` Matthieu Baerts
7 siblings, 0 replies; 11+ messages in thread
From: Matthieu Baerts @ 2023-07-05 8:02 UTC (permalink / raw)
To: Geliang Tang, mptcp
Hi Geliang,
On 05/07/2023 08:56, Geliang Tang wrote:
> v4:
> - add hooks in __sock_create().
Thank you for this new version!
I had a very quick look: it seems nice!
Personally, I don't know the BPF environment well enough to give a good
review and judge if the direction you took is the good one. Then, I
wonder if it would not be better to rebase this series on top of
bpf-next and send a first (RFC?) version to BPF maintainers to get some
feedbacks (with MPTCP list in CC of course). WDYT?
In this case, it will be important to mention in the cover-letter what
is the goal (e.g. create a different socket and the main use-case is
MPTCP) and why it is interesting to do that with BPF (see my previous
email [1] -- I also updated the ticket [2]). Don't hesitate to add a
link to the v3 explaining what was the limitations.
I can help reviewing the new cover-letter if needed.
[1]
https://lore.kernel.org/mptcp/7d4ccbc9-17b6-28cf-9046-c7f81401ee60@tessares.net/
[2] https://github.com/multipath-tcp/mptcp_net-next/issues/79
Cheers,
Matt
--
Tessares | Belgium | Hybrid Access Solutions
www.tessares.net
^ permalink raw reply [flat|nested] 11+ messages in thread