diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig index 98bf88a2e7f7bf615c5bb5b81003d0220a5f15ba..db7446f0991bd5b94d471508235d6dc23a8be72f 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig @@ -1300,6 +1300,7 @@ CONFIG_NET_KEY_MIGRATE=y CONFIG_SMC=m CONFIG_SMC_DIAG=m CONFIG_SMC_LO=y +CONFIG_UB_UMS=m CONFIG_XDP_SOCKETS=y CONFIG_XDP_SOCKETS_DIAG=y CONFIG_NET_HANDSHAKE=y diff --git a/arch/x86/configs/openeuler_defconfig b/arch/x86/configs/openeuler_defconfig index 4050098c07757c8d479f13d67deb38276c36b1a0..7822b87d332ee924d40e7ecbe460129f16e65dae 100644 --- a/arch/x86/configs/openeuler_defconfig +++ b/arch/x86/configs/openeuler_defconfig @@ -1264,6 +1264,7 @@ CONFIG_NET_KEY_MIGRATE=y CONFIG_SMC=m CONFIG_SMC_DIAG=m CONFIG_SMC_LO=y +CONFIG_UB_UMS=m CONFIG_XDP_SOCKETS=y CONFIG_XDP_SOCKETS_DIAG=y # CONFIG_OENETCLS is not set diff --git a/include/linux/socket.h b/include/linux/socket.h index cfcb7e2c3813f2dbd3fd5ca9d123a6883713d672..9d4533ade4bfe6405ce85d6dafc576f061246842 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -239,8 +239,9 @@ struct ucred { #define AF_MCTP 45 /* Management component * transport protocol */ +#define AF_UB 46 /* UMS sockets */ -#define AF_MAX 46 /* For now.. */ +#define AF_MAX 47 /* For now.. */ /* Protocol families, same as address families. */ #define PF_UNSPEC AF_UNSPEC @@ -291,6 +292,7 @@ struct ucred { #define PF_SMC AF_SMC #define PF_XDP AF_XDP #define PF_MCTP AF_MCTP +#define PF_UB AF_UB #define PF_MAX AF_MAX /* Maximum queue length specifiable by listen. */ diff --git a/include/linux/tcp.h b/include/linux/tcp.h index a564202b5b3d6b5cba019a28f57e8fba775c2ec2..507b5c177544a85c846304f0b5aa0f6ce67b7f3e 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -126,7 +126,8 @@ struct tcp_options_received { #if IS_ENABLED(CONFIG_TCP_COMP) comp_ok:1, /* COMP seen on SYN packet */ #endif - unused:6; + ums_ok:1, /* UMS seen on SYN packet */ + unused:5; u8 num_sacks; /* Number of SACK blocks */ u16 user_mss; /* mss requested by user in ioctl */ u16 mss_clamp; /* Maximal mss, negotiated at connection setup */ @@ -142,6 +143,9 @@ static inline void tcp_clear_options(struct tcp_options_received *rx_opt) #if IS_ENABLED(CONFIG_TCP_COMP) rx_opt->comp_ok = 0; #endif +#if IS_ENABLED(CONFIG_UB_UMS) + rx_opt->ums_ok = 0; +#endif } /* This is the max number of SACKS that we'll generate and process. It's safe @@ -450,6 +454,9 @@ struct tcp_sock { bool (*smc_hs_congested)(const struct sock *sk); bool syn_smc; /* SYN includes SMC */ #endif +#if IS_ENABLED(CONFIG_UB_UMS) + bool syn_ums; /* SYN includes UMS */ +#endif #ifdef CONFIG_TCP_MD5SIG /* TCP AF-Specific parts; only used by MD5 Signature support so far */ diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h index c26a55521c0f8b814d99b1aafc79ebdd51375315..335bb507078f95faff0b2728abd09299b4c1a427 100644 --- a/include/net/inet_sock.h +++ b/include/net/inet_sock.h @@ -91,6 +91,8 @@ struct inet_request_sock { comp_ok : 1, #endif smc_ok : 1; + u16 ums_ok : 1, + unused : 15; u32 ir_mark; union { struct ip_options_rcu __rcu *ireq_opt; diff --git a/include/net/tcp.h b/include/net/tcp.h index ec4ed462f181e942db0c918613a5ae2ca69b9122..b82f3394d8ed233d062f91d6a616303fe90cd3bf 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -201,6 +201,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo); #define TCPOPT_FASTOPEN_MAGIC 0xF989 #define TCPOPT_SMC_MAGIC 0xE2D4C3D9 #define TCPOPT_COMP_MAGIC 0x7954 +#define TCPOPT_UMS_MAGIC 0xE4D4E2 /* * TCP option lengths @@ -215,6 +216,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo); #define TCPOLEN_EXP_FASTOPEN_BASE 4 #define TCPOLEN_EXP_SMC_BASE 6 #define TCPOLEN_EXP_COMP_BASE 4 +#define TCPOLEN_EXP_UMS_BASE 6 /* But this is what stacks really send out. */ #define TCPOLEN_TSTAMP_ALIGNED 12 @@ -226,6 +228,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo); #define TCPOLEN_MD5SIG_ALIGNED 20 #define TCPOLEN_MSS_ALIGNED 4 #define TCPOLEN_EXP_SMC_BASE_ALIGNED 8 +#define TCPOLEN_EXP_UMS_BASE_ALIGNED 8 /* Flags in tp->nonagle */ #define TCP_NAGLE_OFF 1 /* Nagle's algo is disabled */ @@ -2555,6 +2558,10 @@ static inline void tcp_bpf_rtt(struct sock *sk) extern struct static_key_false tcp_have_smc; #endif +#if IS_ENABLED(CONFIG_UB_UMS) +extern struct static_key_false tcp_have_ums; +#endif + #if IS_ENABLED(CONFIG_TLS_DEVICE) void clean_acked_data_enable(struct inet_connection_sock *icsk, void (*cad)(struct sock *sk, u32 ack_seq)); diff --git a/net/Kconfig b/net/Kconfig index 45dd1a93ed8530a7f417817e238b757d911eb913..8e6e80ce5b90924156ce39ba2194d93980b8400d 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -74,6 +74,14 @@ source "net/smc/Kconfig" source "net/xdp/Kconfig" source "net/oenetcls/Kconfig" +config UB_UMS + tristate "Enable UB Memory based Socket(UMS)" + default m + help + UB Memort based Socket(UMS) is compatiable with the standard socket API and + based on the UB network for data transmission, transparently accelerating + TCP communication + config NET_HANDSHAKE bool depends on SUNRPC || NVME_TARGET_TCP || NVME_TCP diff --git a/net/core/sock.c b/net/core/sock.c index 1e27275bb24f297b40bb48dd68ce8c597a4780ed..84e3a4be73cd14cdcc354360b89362c09e98985e 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -234,7 +234,7 @@ static struct lock_class_key af_family_kern_slock_keys[AF_MAX]; x "AF_IEEE802154", x "AF_CAIF" , x "AF_ALG" , \ x "AF_NFC" , x "AF_VSOCK" , x "AF_KCM" , \ x "AF_QIPCRTR", x "AF_SMC" , x "AF_XDP" , \ - x "AF_MCTP" , \ + x "AF_MCTP", x "AF_UB", \ x "AF_MAX" static const char *const af_family_key_strings[AF_MAX+1] = { diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index 7da9fcf90de21d3d83651e05726902d1493e8909..cc77c9d22d58dc1e64830a41eb62cdb47a565bd2 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c @@ -395,6 +395,9 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb) ireq->comp_ok = 0; #endif + if (IS_ENABLED(CONFIG_UB_UMS)) + ireq->ums_ok = 0; + ireq->ir_iif = inet_request_bound_dev_if(sk, skb); /* We throwed the options of the initial SYN away, so we hope diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 41c02ed1c26e858a11774bdd324c5742d8fcd01b..7c66c46c125fddb476eeef6d8814a28927375907 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -310,6 +310,11 @@ EXPORT_SYMBOL(tcp_have_smc); DEFINE_STATIC_KEY_FALSE(tcp_have_comp); #endif +#if IS_ENABLED(CONFIG_UB_UMS) +DEFINE_STATIC_KEY_FALSE(tcp_have_ums); +EXPORT_SYMBOL(tcp_have_ums); +#endif + /* * Current number of TCP sockets. */ diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 5483861522d6c12f0fe15de81261069c0760e2f7..6e0efdc3f32bfa11e2c8625bd4f843dbbd0e4d5a 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -4115,6 +4115,24 @@ static bool tcp_parse_comp_option(const struct tcphdr *th, return false; } +static bool tcp_parse_ums_option(const struct tcphdr *th, + struct tcp_options_received *opt_rx, + const unsigned char *ptr, + int opsize) +{ +#if IS_ENABLED(CONFIG_UB_UMS) + if (static_branch_unlikely(&tcp_have_ums)) { + if (th->syn && !(opsize & 1) && + opsize >= TCPOLEN_EXP_UMS_BASE && + get_unaligned_be32(ptr) == TCPOPT_UMS_MAGIC) { + opt_rx->ums_ok = 1; + return true; + } + } +#endif + return false; +} + /* Try to parse the MSS option from the TCP header. Return 0 on failure, clamped * value on success. */ @@ -4278,6 +4296,10 @@ void tcp_parse_options(const struct net *net, opsize)) break; + if (tcp_parse_ums_option(th, opt_rx, ptr, + opsize)) + break; + opt_rx->saw_unknown = 1; break; @@ -6328,6 +6350,16 @@ static void smc_check_reset_syn(struct tcp_sock *tp) #endif } +static void ums_check_reset_syn(struct tcp_sock *tp) +{ +#if IS_ENABLED(CONFIG_UB_UMS) + if (static_branch_unlikely(&tcp_have_ums)) { + if (tp->syn_ums && !tp->rx_opt.ums_ok) + tp->syn_ums = 0; + } +#endif +} + static void tcp_try_undo_spurious_syn(struct sock *sk) { struct tcp_sock *tp = tcp_sk(sk); @@ -6460,6 +6492,8 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, smc_check_reset_syn(tp); + ums_check_reset_syn(tp); + smp_mb(); tcp_finish_connect(sk, skb); @@ -6975,6 +7009,9 @@ static void tcp_openreq_init(struct request_sock *req, #if IS_ENABLED(CONFIG_TCP_COMP) ireq->comp_ok = rx_opt->comp_ok; #endif +#if IS_ENABLED(CONFIG_UB_UMS) + ireq->ums_ok = rx_opt->ums_ok; +#endif } struct request_sock *inet_reqsk_alloc(const struct request_sock_ops *ops, @@ -7157,6 +7194,9 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops, if (IS_ENABLED(CONFIG_SMC) && want_cookie) tmp_opt.smc_ok = 0; + if (IS_ENABLED(CONFIG_UB_UMS) && want_cookie) + tmp_opt.ums_ok = 0; + tmp_opt.tstamp_ok = tmp_opt.saw_tstamp; tcp_openreq_init(req, &tmp_opt, skb, sk); inet_rsk(req)->no_srccheck = inet_test_bit(TRANSPARENT, sk); diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index b9dcda3a106f89932db019a1b81f94eed581896c..770b1ffb2e224097569ca89a3de9739e5646f570 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -473,6 +473,21 @@ static void smc_check_reset_syn_req(const struct tcp_sock *oldtp, #endif } +static void ums_check_reset_syn_req(const struct tcp_sock *oldtp, + struct request_sock *req, + struct tcp_sock *newtp) +{ +#if IS_ENABLED(CONFIG_UB_UMS) + struct inet_request_sock *ireq; + + if (static_branch_unlikely(&tcp_have_ums)) { + ireq = inet_rsk(req); + if (oldtp->syn_ums && !ireq->ums_ok) + newtp->syn_ums = 0; + } +#endif +} + /* This is not only more efficient than what we used to do, it eliminates * a lot of code duplication between IPv4/IPv6 SYN recv processing. -DaveM * @@ -500,6 +515,8 @@ struct sock *tcp_create_openreq_child(const struct sock *sk, smc_check_reset_syn_req(oldtp, req, newtp); + ums_check_reset_syn_req(oldtp, req, newtp); + /* Now setup tcp_sock */ newtp->pred_flags = 0; diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index fdc501aaec9be5ba352a35effed9dbcde7434fdc..a7670162865f551d311ff08c47693765600b6638 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -429,6 +429,7 @@ static inline bool tcp_urg_mode(const struct tcp_sock *tp) #define OPTION_SMC BIT(9) #define OPTION_MPTCP BIT(10) #define OPTION_COMP BIT(11) +#define OPTION_UMS BIT(12) static void smc_options_write(__be32 *ptr, u16 *options) { @@ -458,6 +459,21 @@ static void comp_options_write(__be32 *ptr, u16 *options) #endif } +static void ums_options_write(__be32 *ptr, u16 *options) +{ +#if IS_ENABLED(CONFIG_UB_UMS) + if (static_branch_unlikely(&tcp_have_ums)) { + if (unlikely(OPTION_UMS & *options)) { + *ptr++ = htonl((TCPOPT_NOP << 24) | + (TCPOPT_NOP << 16) | + (TCPOPT_EXP << 8) | + (TCPOLEN_EXP_UMS_BASE)); + *ptr++ = htonl(TCPOPT_UMS_MAGIC); + } + } +#endif +} + struct tcp_out_options { u16 options; /* bit field of OPTION_* */ u16 mss; /* 0 to disable */ @@ -733,6 +749,8 @@ static void tcp_options_write(struct tcphdr *th, struct tcp_sock *tp, mptcp_options_write(th, ptr, tp, opts); comp_options_write(ptr, &options); + + ums_options_write(ptr, &options); } static void smc_set_option(const struct tcp_sock *tp, @@ -767,6 +785,22 @@ static void comp_set_option(struct sock *sk, #endif } +static void ums_set_option(const struct tcp_sock *tp, + struct tcp_out_options *opts, + unsigned int *remaining) +{ +#if IS_ENABLED(CONFIG_UB_UMS) + if (static_branch_unlikely(&tcp_have_ums)) { + if (tp->syn_ums) { + if (*remaining >= TCPOLEN_EXP_UMS_BASE_ALIGNED) { + opts->options |= OPTION_UMS; + *remaining -= TCPOLEN_EXP_UMS_BASE_ALIGNED; + } + } + } +#endif +} + static void comp_set_option_cond(struct sock *sk, const struct inet_request_sock *ireq, struct tcp_out_options *opts, @@ -801,6 +835,23 @@ static void smc_set_option_cond(const struct tcp_sock *tp, #endif } +static void ums_set_option_cond(const struct tcp_sock *tp, + const struct inet_request_sock *ireq, + struct tcp_out_options *opts, + unsigned int *remaining) +{ +#if IS_ENABLED(CONFIG_UB_UMS) + if (static_branch_unlikely(&tcp_have_ums)) { + if (tp->syn_ums && ireq->ums_ok) { + if (*remaining >= TCPOLEN_EXP_UMS_BASE_ALIGNED) { + opts->options |= OPTION_UMS; + *remaining -= TCPOLEN_EXP_UMS_BASE_ALIGNED; + } + } + } +#endif +} + static void mptcp_set_option_cond(const struct request_sock *req, struct tcp_out_options *opts, unsigned int *remaining) @@ -886,6 +937,7 @@ static unsigned int tcp_syn_options(struct sock *sk, struct sk_buff *skb, smc_set_option(tp, opts, &remaining); comp_set_option(sk, opts, &remaining); + ums_set_option(tp, opts, &remaining); if (sk_is_mptcp(sk)) { unsigned int size; @@ -970,6 +1022,8 @@ static unsigned int tcp_synack_options(const struct sock *sk, comp_set_option_cond((struct sock *)sk, ireq, opts, &remaining); + ums_set_option_cond(tcp_sk(sk), ireq, opts, &remaining); + bpf_skops_hdr_opt_len((struct sock *)sk, skb, req, syn_skb, synack_type, opts, &remaining); diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index 1d93fd9ec260b786e58235f8f6c06ac3d15d62ea..d7491d251c0aba2fdd62dcdb7d2eedd82b967f28 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c @@ -222,6 +222,9 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) ireq->comp_ok = 0; #endif + if (IS_ENABLED(CONFIG_UB_UMS)) + ireq->ums_ok = 0; + /* * We need to lookup the dst_entry to get the correct window size. * This is taken from tcp_v6_syn_recv_sock. Somebody please enlighten diff --git a/net/socket.c b/net/socket.c index 01088da25a09b93718811c47f29f12145c367942..23c08b0d2899bc3740c02562f6eede44efa57112 100644 --- a/net/socket.c +++ b/net/socket.c @@ -218,6 +218,7 @@ static const char * const pf_family_names[] = { [PF_SMC] = "PF_SMC", [PF_XDP] = "PF_XDP", [PF_MCTP] = "PF_MCTP", + [PF_UB] = "PF_UB", }; /* diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index d4a99d98ec774558a6c36b4d4ff71d1fe61e88d4..e8bc30e32c0960d05be23e9439f2735bab032119 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -1295,7 +1295,9 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc return SECCLASS_XDP_SOCKET; case PF_MCTP: return SECCLASS_MCTP_SOCKET; -#if PF_MAX > 46 + case PF_UB: + return SECCLASS_UMS_SOCKET; +#if PF_MAX > 47 #error New address family defined, please update this function. #endif } diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index a3c380775d410c513e256450a08a6c22ccc3749a..8cf72c738339fce1fcd845111ded829113ba8635 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h @@ -237,6 +237,8 @@ const struct security_class_mapping secclass_map[] = { { COMMON_SOCK_PERMS, NULL } }, { "smc_socket", { COMMON_SOCK_PERMS, NULL } }, + { "ums_socket", + { COMMON_SOCK_PERMS, NULL } }, { "infiniband_pkey", { "access", NULL } }, { "infiniband_endport", @@ -259,6 +261,6 @@ const struct security_class_mapping secclass_map[] = { { NULL } }; -#if PF_MAX > 46 +#if PF_MAX > 47 #error New address family defined, please update secclass_map. #endif diff --git a/tools/perf/trace/beauty/include/linux/socket.h b/tools/perf/trace/beauty/include/linux/socket.h index 39b74d83c7c4a7e8f1434a8b2005f0d7d8d4904f..5423b5f0edc01e854ecbf70574b8f93d6b005e33 100644 --- a/tools/perf/trace/beauty/include/linux/socket.h +++ b/tools/perf/trace/beauty/include/linux/socket.h @@ -239,8 +239,9 @@ struct ucred { #define AF_MCTP 45 /* Management component * transport protocol */ +#define AF_UB 46 /* UMS sockets */ -#define AF_MAX 46 /* For now.. */ +#define AF_MAX 47 /* For now.. */ /* Protocol families, same as address families. */ #define PF_UNSPEC AF_UNSPEC @@ -291,6 +292,7 @@ struct ucred { #define PF_SMC AF_SMC #define PF_XDP AF_XDP #define PF_MCTP AF_MCTP +#define PF_UB AF_UB #define PF_MAX AF_MAX /* Maximum queue length specifiable by listen. */