forked from mirrors/linux
		
	net/smc: Introduce IPPROTO_SMC
This patch allows to create smc socket via AF_INET, similar to the following code, /* create v4 smc sock */ v4 = socket(AF_INET, SOCK_STREAM, IPPROTO_SMC); /* create v6 smc sock */ v6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_SMC); There are several reasons why we believe it is appropriate here: 1. For smc sockets, it actually use IPv4 (AF-INET) or IPv6 (AF-INET6) address. There is no AF_SMC address at all. 2. Create smc socket in the AF_INET(6) path, which allows us to reuse the infrastructure of AF_INET(6) path, such as common ebpf hooks. Otherwise, smc have to implement it again in AF_SMC path. Signed-off-by: D. Wythe <alibuda@linux.alibaba.com> Reviewed-by: Wenjia Zhang <wenjia@linux.ibm.com> Reviewed-by: Dust Li <dust.li@linux.alibaba.com> Tested-by: Niklas Schnelle <schnelle@linux.ibm.com> Tested-by: Wenjia Zhang <wenjia@linux.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									13543d02c9
								
							
						
					
					
						commit
						d25a92ccae
					
				
					 5 changed files with 198 additions and 3 deletions
				
			
		|  | @ -81,6 +81,8 @@ enum { | ||||||
| #define IPPROTO_ETHERNET	IPPROTO_ETHERNET | #define IPPROTO_ETHERNET	IPPROTO_ETHERNET | ||||||
|   IPPROTO_RAW = 255,		/* Raw IP packets			*/ |   IPPROTO_RAW = 255,		/* Raw IP packets			*/ | ||||||
| #define IPPROTO_RAW		IPPROTO_RAW | #define IPPROTO_RAW		IPPROTO_RAW | ||||||
|  |   IPPROTO_SMC = 256,		/* Shared Memory Communications		*/ | ||||||
|  | #define IPPROTO_SMC		IPPROTO_SMC | ||||||
|   IPPROTO_MPTCP = 262,		/* Multipath TCP connection		*/ |   IPPROTO_MPTCP = 262,		/* Multipath TCP connection		*/ | ||||||
| #define IPPROTO_MPTCP		IPPROTO_MPTCP | #define IPPROTO_MPTCP		IPPROTO_MPTCP | ||||||
|   IPPROTO_MAX |   IPPROTO_MAX | ||||||
|  |  | ||||||
|  | @ -4,6 +4,6 @@ obj-$(CONFIG_SMC)	+= smc.o | ||||||
| obj-$(CONFIG_SMC_DIAG)	+= smc_diag.o | obj-$(CONFIG_SMC_DIAG)	+= smc_diag.o | ||||||
| smc-y := af_smc.o smc_pnet.o smc_ib.o smc_clc.o smc_core.o smc_wr.o smc_llc.o | smc-y := af_smc.o smc_pnet.o smc_ib.o smc_clc.o smc_core.o smc_wr.o smc_llc.o | ||||||
| smc-y += smc_cdc.o smc_tx.o smc_rx.o smc_close.o smc_ism.o smc_netlink.o smc_stats.o | smc-y += smc_cdc.o smc_tx.o smc_rx.o smc_close.o smc_ism.o smc_netlink.o smc_stats.o | ||||||
| smc-y += smc_tracepoint.o | smc-y += smc_tracepoint.o smc_inet.o | ||||||
| smc-$(CONFIG_SYSCTL) += smc_sysctl.o | smc-$(CONFIG_SYSCTL) += smc_sysctl.o | ||||||
| smc-$(CONFIG_SMC_LO) += smc_loopback.o | smc-$(CONFIG_SMC_LO) += smc_loopback.o | ||||||
|  |  | ||||||
|  | @ -54,6 +54,7 @@ | ||||||
| #include "smc_tracepoint.h" | #include "smc_tracepoint.h" | ||||||
| #include "smc_sysctl.h" | #include "smc_sysctl.h" | ||||||
| #include "smc_loopback.h" | #include "smc_loopback.h" | ||||||
|  | #include "smc_inet.h" | ||||||
| 
 | 
 | ||||||
| static DEFINE_MUTEX(smc_server_lgr_pending);	/* serialize link group
 | static DEFINE_MUTEX(smc_server_lgr_pending);	/* serialize link group
 | ||||||
| 						 * creation on server | 						 * creation on server | ||||||
|  | @ -3575,10 +3576,15 @@ static int __init smc_init(void) | ||||||
| 		pr_err("%s: tcp_ulp_register fails with %d\n", __func__, rc); | 		pr_err("%s: tcp_ulp_register fails with %d\n", __func__, rc); | ||||||
| 		goto out_lo; | 		goto out_lo; | ||||||
| 	} | 	} | ||||||
| 
 | 	rc = smc_inet_init(); | ||||||
|  | 	if (rc) { | ||||||
|  | 		pr_err("%s: smc_inet_init fails with %d\n", __func__, rc); | ||||||
|  | 		goto out_ulp; | ||||||
|  | 	} | ||||||
| 	static_branch_enable(&tcp_have_smc); | 	static_branch_enable(&tcp_have_smc); | ||||||
| 	return 0; | 	return 0; | ||||||
| 
 | out_ulp: | ||||||
|  | 	tcp_unregister_ulp(&smc_ulp_ops); | ||||||
| out_lo: | out_lo: | ||||||
| 	smc_loopback_exit(); | 	smc_loopback_exit(); | ||||||
| out_ib: | out_ib: | ||||||
|  | @ -3615,6 +3621,7 @@ static int __init smc_init(void) | ||||||
| static void __exit smc_exit(void) | static void __exit smc_exit(void) | ||||||
| { | { | ||||||
| 	static_branch_disable(&tcp_have_smc); | 	static_branch_disable(&tcp_have_smc); | ||||||
|  | 	smc_inet_exit(); | ||||||
| 	tcp_unregister_ulp(&smc_ulp_ops); | 	tcp_unregister_ulp(&smc_ulp_ops); | ||||||
| 	sock_unregister(PF_SMC); | 	sock_unregister(PF_SMC); | ||||||
| 	smc_core_exit(); | 	smc_core_exit(); | ||||||
|  | @ -3642,4 +3649,9 @@ MODULE_DESCRIPTION("smc socket address family"); | ||||||
| MODULE_LICENSE("GPL"); | MODULE_LICENSE("GPL"); | ||||||
| MODULE_ALIAS_NETPROTO(PF_SMC); | MODULE_ALIAS_NETPROTO(PF_SMC); | ||||||
| MODULE_ALIAS_TCP_ULP("smc"); | MODULE_ALIAS_TCP_ULP("smc"); | ||||||
|  | /* 256 for IPPROTO_SMC and 1 for SOCK_STREAM */ | ||||||
|  | MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 256, 1); | ||||||
|  | #if IS_ENABLED(CONFIG_IPV6) | ||||||
|  | MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET6, 256, 1); | ||||||
|  | #endif /* CONFIG_IPV6 */ | ||||||
| MODULE_ALIAS_GENL_FAMILY(SMC_GENL_FAMILY_NAME); | MODULE_ALIAS_GENL_FAMILY(SMC_GENL_FAMILY_NAME); | ||||||
|  |  | ||||||
							
								
								
									
										159
									
								
								net/smc/smc_inet.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								net/smc/smc_inet.c
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,159 @@ | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-only
 | ||||||
|  | /*
 | ||||||
|  |  *  Shared Memory Communications over RDMA (SMC-R) and RoCE | ||||||
|  |  * | ||||||
|  |  *  Definitions for the IPPROTO_SMC (socket related) | ||||||
|  |  * | ||||||
|  |  *  Copyright IBM Corp. 2016, 2018 | ||||||
|  |  *  Copyright (c) 2024, Alibaba Inc. | ||||||
|  |  * | ||||||
|  |  *  Author: D. Wythe <alibuda@linux.alibaba.com> | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include <net/protocol.h> | ||||||
|  | #include <net/sock.h> | ||||||
|  | 
 | ||||||
|  | #include "smc_inet.h" | ||||||
|  | #include "smc.h" | ||||||
|  | 
 | ||||||
|  | static int smc_inet_init_sock(struct sock *sk); | ||||||
|  | 
 | ||||||
|  | static struct proto smc_inet_prot = { | ||||||
|  | 	.name		= "INET_SMC", | ||||||
|  | 	.owner		= THIS_MODULE, | ||||||
|  | 	.init		= smc_inet_init_sock, | ||||||
|  | 	.hash		= smc_hash_sk, | ||||||
|  | 	.unhash		= smc_unhash_sk, | ||||||
|  | 	.release_cb	= smc_release_cb, | ||||||
|  | 	.obj_size	= sizeof(struct smc_sock), | ||||||
|  | 	.h.smc_hash	= &smc_v4_hashinfo, | ||||||
|  | 	.slab_flags	= SLAB_TYPESAFE_BY_RCU, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static const struct proto_ops smc_inet_stream_ops = { | ||||||
|  | 	.family		= PF_INET, | ||||||
|  | 	.owner		= THIS_MODULE, | ||||||
|  | 	.release	= smc_release, | ||||||
|  | 	.bind		= smc_bind, | ||||||
|  | 	.connect	= smc_connect, | ||||||
|  | 	.socketpair	= sock_no_socketpair, | ||||||
|  | 	.accept		= smc_accept, | ||||||
|  | 	.getname	= smc_getname, | ||||||
|  | 	.poll		= smc_poll, | ||||||
|  | 	.ioctl		= smc_ioctl, | ||||||
|  | 	.listen		= smc_listen, | ||||||
|  | 	.shutdown	= smc_shutdown, | ||||||
|  | 	.setsockopt	= smc_setsockopt, | ||||||
|  | 	.getsockopt	= smc_getsockopt, | ||||||
|  | 	.sendmsg	= smc_sendmsg, | ||||||
|  | 	.recvmsg	= smc_recvmsg, | ||||||
|  | 	.mmap		= sock_no_mmap, | ||||||
|  | 	.splice_read	= smc_splice_read, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static struct inet_protosw smc_inet_protosw = { | ||||||
|  | 	.type		= SOCK_STREAM, | ||||||
|  | 	.protocol	= IPPROTO_SMC, | ||||||
|  | 	.prot		= &smc_inet_prot, | ||||||
|  | 	.ops		= &smc_inet_stream_ops, | ||||||
|  | 	.flags		= INET_PROTOSW_ICSK, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #if IS_ENABLED(CONFIG_IPV6) | ||||||
|  | static struct proto smc_inet6_prot = { | ||||||
|  | 	.name		= "INET6_SMC", | ||||||
|  | 	.owner		= THIS_MODULE, | ||||||
|  | 	.init		= smc_inet_init_sock, | ||||||
|  | 	.hash		= smc_hash_sk, | ||||||
|  | 	.unhash		= smc_unhash_sk, | ||||||
|  | 	.release_cb	= smc_release_cb, | ||||||
|  | 	.obj_size	= sizeof(struct smc_sock), | ||||||
|  | 	.h.smc_hash	= &smc_v6_hashinfo, | ||||||
|  | 	.slab_flags	= SLAB_TYPESAFE_BY_RCU, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static const struct proto_ops smc_inet6_stream_ops = { | ||||||
|  | 	.family		= PF_INET6, | ||||||
|  | 	.owner		= THIS_MODULE, | ||||||
|  | 	.release	= smc_release, | ||||||
|  | 	.bind		= smc_bind, | ||||||
|  | 	.connect	= smc_connect, | ||||||
|  | 	.socketpair	= sock_no_socketpair, | ||||||
|  | 	.accept		= smc_accept, | ||||||
|  | 	.getname	= smc_getname, | ||||||
|  | 	.poll		= smc_poll, | ||||||
|  | 	.ioctl		= smc_ioctl, | ||||||
|  | 	.listen		= smc_listen, | ||||||
|  | 	.shutdown	= smc_shutdown, | ||||||
|  | 	.setsockopt	= smc_setsockopt, | ||||||
|  | 	.getsockopt	= smc_getsockopt, | ||||||
|  | 	.sendmsg	= smc_sendmsg, | ||||||
|  | 	.recvmsg	= smc_recvmsg, | ||||||
|  | 	.mmap		= sock_no_mmap, | ||||||
|  | 	.splice_read	= smc_splice_read, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static struct inet_protosw smc_inet6_protosw = { | ||||||
|  | 	.type		= SOCK_STREAM, | ||||||
|  | 	.protocol	= IPPROTO_SMC, | ||||||
|  | 	.prot		= &smc_inet6_prot, | ||||||
|  | 	.ops		= &smc_inet6_stream_ops, | ||||||
|  | 	.flags		= INET_PROTOSW_ICSK, | ||||||
|  | }; | ||||||
|  | #endif /* CONFIG_IPV6 */ | ||||||
|  | 
 | ||||||
|  | static int smc_inet_init_sock(struct sock *sk) | ||||||
|  | { | ||||||
|  | 	struct net *net = sock_net(sk); | ||||||
|  | 
 | ||||||
|  | 	/* init common smc sock */ | ||||||
|  | 	smc_sk_init(net, sk, IPPROTO_SMC); | ||||||
|  | 	/* create clcsock */ | ||||||
|  | 	return smc_create_clcsk(net, sk, sk->sk_family); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int __init smc_inet_init(void) | ||||||
|  | { | ||||||
|  | 	int rc; | ||||||
|  | 
 | ||||||
|  | 	rc = proto_register(&smc_inet_prot, 1); | ||||||
|  | 	if (rc) { | ||||||
|  | 		pr_err("%s: proto_register smc_inet_prot fails with %d\n", | ||||||
|  | 		       __func__, rc); | ||||||
|  | 		return rc; | ||||||
|  | 	} | ||||||
|  | 	/* no return value */ | ||||||
|  | 	inet_register_protosw(&smc_inet_protosw); | ||||||
|  | 
 | ||||||
|  | #if IS_ENABLED(CONFIG_IPV6) | ||||||
|  | 	rc = proto_register(&smc_inet6_prot, 1); | ||||||
|  | 	if (rc) { | ||||||
|  | 		pr_err("%s: proto_register smc_inet6_prot fails with %d\n", | ||||||
|  | 		       __func__, rc); | ||||||
|  | 		goto out_inet6_prot; | ||||||
|  | 	} | ||||||
|  | 	rc = inet6_register_protosw(&smc_inet6_protosw); | ||||||
|  | 	if (rc) { | ||||||
|  | 		pr_err("%s: inet6_register_protosw smc_inet6_protosw fails with %d\n", | ||||||
|  | 		       __func__, rc); | ||||||
|  | 		goto out_inet6_protosw; | ||||||
|  | 	} | ||||||
|  | 	return rc; | ||||||
|  | out_inet6_protosw: | ||||||
|  | 	proto_unregister(&smc_inet6_prot); | ||||||
|  | out_inet6_prot: | ||||||
|  | 	inet_unregister_protosw(&smc_inet_protosw); | ||||||
|  | 	proto_unregister(&smc_inet_prot); | ||||||
|  | #endif /* CONFIG_IPV6 */ | ||||||
|  | 	return rc; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void smc_inet_exit(void) | ||||||
|  | { | ||||||
|  | #if IS_ENABLED(CONFIG_IPV6) | ||||||
|  | 	inet6_unregister_protosw(&smc_inet6_protosw); | ||||||
|  | 	proto_unregister(&smc_inet6_prot); | ||||||
|  | #endif /* CONFIG_IPV6 */ | ||||||
|  | 	inet_unregister_protosw(&smc_inet_protosw); | ||||||
|  | 	proto_unregister(&smc_inet_prot); | ||||||
|  | } | ||||||
							
								
								
									
										22
									
								
								net/smc/smc_inet.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								net/smc/smc_inet.h
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,22 @@ | ||||||
|  | /* SPDX-License-Identifier: GPL-2.0 */ | ||||||
|  | /*
 | ||||||
|  |  *  Shared Memory Communications over RDMA (SMC-R) and RoCE | ||||||
|  |  * | ||||||
|  |  *  Definitions for the IPPROTO_SMC (socket related) | ||||||
|  | 
 | ||||||
|  |  *  Copyright IBM Corp. 2016 | ||||||
|  |  *  Copyright (c) 2024, Alibaba Inc. | ||||||
|  |  * | ||||||
|  |  *  Author: D. Wythe <alibuda@linux.alibaba.com> | ||||||
|  |  */ | ||||||
|  | #ifndef __INET_SMC | ||||||
|  | #define __INET_SMC | ||||||
|  | 
 | ||||||
|  | /* Initialize protocol registration on IPPROTO_SMC,
 | ||||||
|  |  * @return 0 on success | ||||||
|  |  */ | ||||||
|  | int smc_inet_init(void); | ||||||
|  | 
 | ||||||
|  | void smc_inet_exit(void); | ||||||
|  | 
 | ||||||
|  | #endif /* __INET_SMC */ | ||||||
		Loading…
	
		Reference in a new issue
	
	 D. Wythe
						D. Wythe