Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  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
 19static int smc_inet_init_sock(struct sock *sk);
 20
 21static 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
 33static 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
 54static 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)
 63struct smc6_sock {
 64	struct smc_sock		smc;
 65	struct ipv6_pinfo	inet6;
 66};
 67
 68static 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
 81static 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
102static 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
111static 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
119static 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
132int __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;
159out_inet6_protosw:
160	proto_unregister(&smc_inet6_prot);
161out_inet6_prot:
162	inet_unregister_protosw(&smc_inet_protosw);
163	proto_unregister(&smc_inet_prot);
164#endif /* CONFIG_IPV6 */
165	return rc;
166}
167
168void 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}