History

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.

D. Wythe committed 2 years ago

Commit d25a92c1 parent 13543d05 files · +198 −3Browse files

Unified · Split

5 files
  1. include/uapi/linux/in.h +2 −0
  2. net/smc/Makefile +1 −1
  3. net/smc/af_smc.c +14 −2
  4. net/smc/smc_inet.c +159 −0
  5. net/smc/smc_inet.h +22 −0
include/uapi/linux/in.h+2−0
@@ -81,6 +81,8 @@ enum { · 80 unmodified lines
8181 #define IPPROTO_ETHERNET IPPROTO_ETHERNET
8282 IPPROTO_RAW = 255, /* Raw IP packets */
8383 #define IPPROTO_RAW IPPROTO_RAW
84+ IPPROTO_SMC = 256, /* Shared Memory Communications */
85+#define IPPROTO_SMC IPPROTO_SMC
8486 IPPROTO_MPTCP = 262, /* Multipath TCP connection */
8587 #define IPPROTO_MPTCP IPPROTO_MPTCP
8688 IPPROTO_MAX
net/smc/Makefile+1−1
@@ -4,6 +4,6 @@ obj-$(CONFIG_SMC) += smc.o · 3 unmodified lines
44 obj-$(CONFIG_SMC_DIAG) += smc_diag.o
55 smc-y := af_smc.o smc_pnet.o smc_ib.o smc_clc.o smc_core.o smc_wr.o smc_llc.o
66 smc-y += smc_cdc.o smc_tx.o smc_rx.o smc_close.o smc_ism.o smc_netlink.o smc_stats.o
7−smc-y += smc_tracepoint.o
7+smc-y += smc_tracepoint.o smc_inet.o
88 smc-$(CONFIG_SYSCTL) += smc_sysctl.o
99 smc-$(CONFIG_SMC_LO) += smc_loopback.o
net/smc/af_smc.c+14−2
@@ -54,6 +54,7 @@ · 53 unmodified lines
5454 #include "smc_tracepoint.h"
5555 #include "smc_sysctl.h"
5656 #include "smc_loopback.h"
57+#include "smc_inet.h"
5758
5859 static DEFINE_MUTEX(smc_server_lgr_pending); /* serialize link group
5960 * creation on server
@@ -3575,10 +3576,15 @@ static int __init smc_init(void) · 3515 unmodified lines
35753576 pr_err("%s: tcp_ulp_register fails with %d\n", __func__, rc);
35763577 goto out_lo;
35773578 }
3578−
3579+ rc = smc_inet_init();
3580+ if (rc) {
3581+ pr_err("%s: smc_inet_init fails with %d\n", __func__, rc);
3582+ goto out_ulp;
3583+ }
35793584 static_branch_enable(&tcp_have_smc);
35803585 return 0;
3581−
3586+out_ulp:
3587+ tcp_unregister_ulp(&smc_ulp_ops);
35823588 out_lo:
35833589 smc_loopback_exit();
35843590 out_ib:
@@ -3615,6 +3621,7 @@ out_pernet_subsys: · 30 unmodified lines
36153621 static void __exit smc_exit(void)
36163622 {
36173623 static_branch_disable(&tcp_have_smc);
3624+ smc_inet_exit();
36183625 tcp_unregister_ulp(&smc_ulp_ops);
36193626 sock_unregister(PF_SMC);
36203627 smc_core_exit();
@@ -3642,4 +3649,9 @@ MODULE_DESCRIPTION("smc socket address family"); · 21 unmodified lines
36423649 MODULE_LICENSE("GPL");
36433650 MODULE_ALIAS_NETPROTO(PF_SMC);
36443651 MODULE_ALIAS_TCP_ULP("smc");
3652+/* 256 for IPPROTO_SMC and 1 for SOCK_STREAM */
3653+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 256, 1);
3654+#if IS_ENABLED(CONFIG_IPV6)
3655+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET6, 256, 1);
3656+#endif /* CONFIG_IPV6 */
36453657 MODULE_ALIAS_GENL_FAMILY(SMC_GENL_FAMILY_NAME);
net/smc/smc_inet.c+159−0
@@ -0,0 +1,159 @@
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+static struct proto smc_inet6_prot = {
64+ .name = "INET6_SMC",
65+ .owner = THIS_MODULE,
66+ .init = smc_inet_init_sock,
67+ .hash = smc_hash_sk,
68+ .unhash = smc_unhash_sk,
69+ .release_cb = smc_release_cb,
70+ .obj_size = sizeof(struct smc_sock),
71+ .h.smc_hash = &smc_v6_hashinfo,
72+ .slab_flags = SLAB_TYPESAFE_BY_RCU,
73+};
74+
75+static const struct proto_ops smc_inet6_stream_ops = {
76+ .family = PF_INET6,
77+ .owner = THIS_MODULE,
78+ .release = smc_release,
79+ .bind = smc_bind,
80+ .connect = smc_connect,
81+ .socketpair = sock_no_socketpair,
82+ .accept = smc_accept,
83+ .getname = smc_getname,
84+ .poll = smc_poll,
85+ .ioctl = smc_ioctl,
86+ .listen = smc_listen,
87+ .shutdown = smc_shutdown,
88+ .setsockopt = smc_setsockopt,
89+ .getsockopt = smc_getsockopt,
90+ .sendmsg = smc_sendmsg,
91+ .recvmsg = smc_recvmsg,
92+ .mmap = sock_no_mmap,
93+ .splice_read = smc_splice_read,
94+};
95+
96+static struct inet_protosw smc_inet6_protosw = {
97+ .type = SOCK_STREAM,
98+ .protocol = IPPROTO_SMC,
99+ .prot = &smc_inet6_prot,
100+ .ops = &smc_inet6_stream_ops,
101+ .flags = INET_PROTOSW_ICSK,
102+};
103+#endif /* CONFIG_IPV6 */
104+
105+static int smc_inet_init_sock(struct sock *sk)
106+{
107+ struct net *net = sock_net(sk);
108+
109+ /* init common smc sock */
110+ smc_sk_init(net, sk, IPPROTO_SMC);
111+ /* create clcsock */
112+ return smc_create_clcsk(net, sk, sk->sk_family);
113+}
114+
115+int __init smc_inet_init(void)
116+{
117+ int rc;
118+
119+ rc = proto_register(&smc_inet_prot, 1);
120+ if (rc) {
121+ pr_err("%s: proto_register smc_inet_prot fails with %d\n",
122+ __func__, rc);
123+ return rc;
124+ }
125+ /* no return value */
126+ inet_register_protosw(&smc_inet_protosw);
127+
128+#if IS_ENABLED(CONFIG_IPV6)
129+ rc = proto_register(&smc_inet6_prot, 1);
130+ if (rc) {
131+ pr_err("%s: proto_register smc_inet6_prot fails with %d\n",
132+ __func__, rc);
133+ goto out_inet6_prot;
134+ }
135+ rc = inet6_register_protosw(&smc_inet6_protosw);
136+ if (rc) {
137+ pr_err("%s: inet6_register_protosw smc_inet6_protosw fails with %d\n",
138+ __func__, rc);
139+ goto out_inet6_protosw;
140+ }
141+ return rc;
142+out_inet6_protosw:
143+ proto_unregister(&smc_inet6_prot);
144+out_inet6_prot:
145+ inet_unregister_protosw(&smc_inet_protosw);
146+ proto_unregister(&smc_inet_prot);
147+#endif /* CONFIG_IPV6 */
148+ return rc;
149+}
150+
151+void smc_inet_exit(void)
152+{
153+#if IS_ENABLED(CONFIG_IPV6)
154+ inet6_unregister_protosw(&smc_inet6_protosw);
155+ proto_unregister(&smc_inet6_prot);
156+#endif /* CONFIG_IPV6 */
157+ inet_unregister_protosw(&smc_inet_protosw);
158+ proto_unregister(&smc_inet_prot);
159+}
net/smc/smc_inet.h+22−0
@@ -0,0 +1,22 @@
1+/* SPDX-License-Identifier: GPL-2.0 */
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
8+ * Copyright (c) 2024, Alibaba Inc.
9+ *
10+ * Author: D. Wythe <alibuda@linux.alibaba.com>
11+ */
12+#ifndef __INET_SMC
13+#define __INET_SMC
14+
15+/* Initialize protocol registration on IPPROTO_SMC,
16+ * @return 0 on success
17+ */
18+int smc_inet_init(void);
19+
20+void smc_inet_exit(void);
21+
22+#endif /* __INET_SMC */