xref: /linux/net/smc/smc_inet.c (revision 1d227fcc72223cbdd34d0ce13541cbaab5e0d72f)
1  // SPDX-License-Identifier: GPL-2.0-only
2  /*
3   *  Shared Memory Communications over RDMA (SMC-R) and RoCE
4   *
5   *  Definitions for the IPPROTO_SMC (socket related)
6   *
7   *  Copyright IBM Corp. 2016, 2018
8   *  Copyright (c) 2024, Alibaba Inc.
9   *
10   *  Author: D. Wythe <alibuda@linux.alibaba.com>
11   */
12  
13  #include <net/protocol.h>
14  #include <net/sock.h>
15  
16  #include "smc_inet.h"
17  #include "smc.h"
18  
19  static int smc_inet_init_sock(struct sock *sk);
20  
21  static struct proto smc_inet_prot = {
22  	.name		= "INET_SMC",
23  	.owner		= THIS_MODULE,
24  	.init		= smc_inet_init_sock,
25  	.hash		= smc_hash_sk,
26  	.unhash		= smc_unhash_sk,
27  	.release_cb	= smc_release_cb,
28  	.obj_size	= sizeof(struct smc_sock),
29  	.h.smc_hash	= &smc_v4_hashinfo,
30  	.slab_flags	= SLAB_TYPESAFE_BY_RCU,
31  };
32  
33  static const struct proto_ops smc_inet_stream_ops = {
34  	.family		= PF_INET,
35  	.owner		= THIS_MODULE,
36  	.release	= smc_release,
37  	.bind		= smc_bind,
38  	.connect	= smc_connect,
39  	.socketpair	= sock_no_socketpair,
40  	.accept		= smc_accept,
41  	.getname	= smc_getname,
42  	.poll		= smc_poll,
43  	.ioctl		= smc_ioctl,
44  	.listen		= smc_listen,
45  	.shutdown	= smc_shutdown,
46  	.setsockopt	= smc_setsockopt,
47  	.getsockopt	= smc_getsockopt,
48  	.sendmsg	= smc_sendmsg,
49  	.recvmsg	= smc_recvmsg,
50  	.mmap		= sock_no_mmap,
51  	.splice_read	= smc_splice_read,
52  };
53  
54  static struct inet_protosw smc_inet_protosw = {
55  	.type		= SOCK_STREAM,
56  	.protocol	= IPPROTO_SMC,
57  	.prot		= &smc_inet_prot,
58  	.ops		= &smc_inet_stream_ops,
59  	.flags		= INET_PROTOSW_ICSK,
60  };
61  
62  #if IS_ENABLED(CONFIG_IPV6)
63  struct smc6_sock {
64  	struct smc_sock		smc;
65  	struct ipv6_pinfo	inet6;
66  };
67  
68  static struct proto smc_inet6_prot = {
69  	.name		= "INET6_SMC",
70  	.owner		= THIS_MODULE,
71  	.init		= smc_inet_init_sock,
72  	.hash		= smc_hash_sk,
73  	.unhash		= smc_unhash_sk,
74  	.release_cb	= smc_release_cb,
75  	.obj_size	= sizeof(struct smc6_sock),
76  	.h.smc_hash	= &smc_v6_hashinfo,
77  	.slab_flags	= SLAB_TYPESAFE_BY_RCU,
78  	.ipv6_pinfo_offset	= offsetof(struct smc6_sock, inet6),
79  };
80  
81  static const struct proto_ops smc_inet6_stream_ops = {
82  	.family		= PF_INET6,
83  	.owner		= THIS_MODULE,
84  	.release	= smc_release,
85  	.bind		= smc_bind,
86  	.connect	= smc_connect,
87  	.socketpair	= sock_no_socketpair,
88  	.accept		= smc_accept,
89  	.getname	= smc_getname,
90  	.poll		= smc_poll,
91  	.ioctl		= smc_ioctl,
92  	.listen		= smc_listen,
93  	.shutdown	= smc_shutdown,
94  	.setsockopt	= smc_setsockopt,
95  	.getsockopt	= smc_getsockopt,
96  	.sendmsg	= smc_sendmsg,
97  	.recvmsg	= smc_recvmsg,
98  	.mmap		= sock_no_mmap,
99  	.splice_read	= smc_splice_read,
100  };
101  
102  static struct inet_protosw smc_inet6_protosw = {
103  	.type		= SOCK_STREAM,
104  	.protocol	= IPPROTO_SMC,
105  	.prot		= &smc_inet6_prot,
106  	.ops		= &smc_inet6_stream_ops,
107  	.flags		= INET_PROTOSW_ICSK,
108  };
109  #endif /* CONFIG_IPV6 */
110  
smc_sync_mss(struct sock * sk,u32 pmtu)111  static unsigned int smc_sync_mss(struct sock *sk, u32 pmtu)
112  {
113  	/* No need pass it through to clcsock, mss can always be set by
114  	 * sock_create_kern or smc_setsockopt.
115  	 */
116  	return 0;
117  }
118  
smc_inet_init_sock(struct sock * sk)119  static int smc_inet_init_sock(struct sock *sk)
120  {
121  	struct net *net = sock_net(sk);
122  
123  	/* init common smc sock */
124  	smc_sk_init(net, sk, IPPROTO_SMC);
125  
126  	inet_csk(sk)->icsk_sync_mss = smc_sync_mss;
127  
128  	/* create clcsock */
129  	return smc_create_clcsk(net, sk, sk->sk_family);
130  }
131  
smc_inet_init(void)132  int __init smc_inet_init(void)
133  {
134  	int rc;
135  
136  	rc = proto_register(&smc_inet_prot, 1);
137  	if (rc) {
138  		pr_err("%s: proto_register smc_inet_prot fails with %d\n",
139  		       __func__, rc);
140  		return rc;
141  	}
142  	/* no return value */
143  	inet_register_protosw(&smc_inet_protosw);
144  
145  #if IS_ENABLED(CONFIG_IPV6)
146  	rc = proto_register(&smc_inet6_prot, 1);
147  	if (rc) {
148  		pr_err("%s: proto_register smc_inet6_prot fails with %d\n",
149  		       __func__, rc);
150  		goto out_inet6_prot;
151  	}
152  	rc = inet6_register_protosw(&smc_inet6_protosw);
153  	if (rc) {
154  		pr_err("%s: inet6_register_protosw smc_inet6_protosw fails with %d\n",
155  		       __func__, rc);
156  		goto out_inet6_protosw;
157  	}
158  	return rc;
159  out_inet6_protosw:
160  	proto_unregister(&smc_inet6_prot);
161  out_inet6_prot:
162  	inet_unregister_protosw(&smc_inet_protosw);
163  	proto_unregister(&smc_inet_prot);
164  #endif /* CONFIG_IPV6 */
165  	return rc;
166  }
167  
smc_inet_exit(void)168  void smc_inet_exit(void)
169  {
170  #if IS_ENABLED(CONFIG_IPV6)
171  	inet6_unregister_protosw(&smc_inet6_protosw);
172  	proto_unregister(&smc_inet6_prot);
173  #endif /* CONFIG_IPV6 */
174  	inet_unregister_protosw(&smc_inet_protosw);
175  	proto_unregister(&smc_inet_prot);
176  }
177