smc_inet.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  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. #include <net/protocol.h>
  13. #include <net/sock.h>
  14. #include "smc_inet.h"
  15. #include "smc.h"
  16. static int smc_inet_init_sock(struct sock *sk);
  17. static struct proto smc_inet_prot = {
  18. .name = "INET_SMC",
  19. .owner = THIS_MODULE,
  20. .init = smc_inet_init_sock,
  21. .hash = smc_hash_sk,
  22. .unhash = smc_unhash_sk,
  23. .release_cb = smc_release_cb,
  24. .obj_size = sizeof(struct smc_sock),
  25. .h.smc_hash = &smc_v4_hashinfo,
  26. .slab_flags = SLAB_TYPESAFE_BY_RCU,
  27. };
  28. static const struct proto_ops smc_inet_stream_ops = {
  29. .family = PF_INET,
  30. .owner = THIS_MODULE,
  31. .release = smc_release,
  32. .bind = smc_bind,
  33. .connect = smc_connect,
  34. .socketpair = sock_no_socketpair,
  35. .accept = smc_accept,
  36. .getname = smc_getname,
  37. .poll = smc_poll,
  38. .ioctl = smc_ioctl,
  39. .listen = smc_listen,
  40. .shutdown = smc_shutdown,
  41. .setsockopt = smc_setsockopt,
  42. .getsockopt = smc_getsockopt,
  43. .sendmsg = smc_sendmsg,
  44. .recvmsg = smc_recvmsg,
  45. .mmap = sock_no_mmap,
  46. .splice_read = smc_splice_read,
  47. };
  48. static struct inet_protosw smc_inet_protosw = {
  49. .type = SOCK_STREAM,
  50. .protocol = IPPROTO_SMC,
  51. .prot = &smc_inet_prot,
  52. .ops = &smc_inet_stream_ops,
  53. };
  54. #if IS_ENABLED(CONFIG_IPV6)
  55. struct smc6_sock {
  56. struct smc_sock smc;
  57. struct ipv6_pinfo inet6;
  58. };
  59. static struct proto smc_inet6_prot = {
  60. .name = "INET6_SMC",
  61. .owner = THIS_MODULE,
  62. .init = smc_inet_init_sock,
  63. .hash = smc_hash_sk,
  64. .unhash = smc_unhash_sk,
  65. .release_cb = smc_release_cb,
  66. .obj_size = sizeof(struct smc6_sock),
  67. .h.smc_hash = &smc_v6_hashinfo,
  68. .slab_flags = SLAB_TYPESAFE_BY_RCU,
  69. .ipv6_pinfo_offset = offsetof(struct smc6_sock, inet6),
  70. };
  71. static const struct proto_ops smc_inet6_stream_ops = {
  72. .family = PF_INET6,
  73. .owner = THIS_MODULE,
  74. .release = smc_release,
  75. .bind = smc_bind,
  76. .connect = smc_connect,
  77. .socketpair = sock_no_socketpair,
  78. .accept = smc_accept,
  79. .getname = smc_getname,
  80. .poll = smc_poll,
  81. .ioctl = smc_ioctl,
  82. .listen = smc_listen,
  83. .shutdown = smc_shutdown,
  84. .setsockopt = smc_setsockopt,
  85. .getsockopt = smc_getsockopt,
  86. .sendmsg = smc_sendmsg,
  87. .recvmsg = smc_recvmsg,
  88. .mmap = sock_no_mmap,
  89. .splice_read = smc_splice_read,
  90. };
  91. static struct inet_protosw smc_inet6_protosw = {
  92. .type = SOCK_STREAM,
  93. .protocol = IPPROTO_SMC,
  94. .prot = &smc_inet6_prot,
  95. .ops = &smc_inet6_stream_ops,
  96. };
  97. #endif /* CONFIG_IPV6 */
  98. static int smc_inet_init_sock(struct sock *sk)
  99. {
  100. struct net *net = sock_net(sk);
  101. /* init common smc sock */
  102. smc_sk_init(net, sk, IPPROTO_SMC);
  103. /* create clcsock */
  104. return smc_create_clcsk(net, sk, sk->sk_family);
  105. }
  106. int __init smc_inet_init(void)
  107. {
  108. int rc;
  109. rc = proto_register(&smc_inet_prot, 1);
  110. if (rc) {
  111. pr_err("%s: proto_register smc_inet_prot fails with %d\n",
  112. __func__, rc);
  113. return rc;
  114. }
  115. /* no return value */
  116. inet_register_protosw(&smc_inet_protosw);
  117. #if IS_ENABLED(CONFIG_IPV6)
  118. rc = proto_register(&smc_inet6_prot, 1);
  119. if (rc) {
  120. pr_err("%s: proto_register smc_inet6_prot fails with %d\n",
  121. __func__, rc);
  122. goto out_inet6_prot;
  123. }
  124. rc = inet6_register_protosw(&smc_inet6_protosw);
  125. if (rc) {
  126. pr_err("%s: inet6_register_protosw smc_inet6_protosw fails with %d\n",
  127. __func__, rc);
  128. goto out_inet6_protosw;
  129. }
  130. return rc;
  131. out_inet6_protosw:
  132. proto_unregister(&smc_inet6_prot);
  133. out_inet6_prot:
  134. inet_unregister_protosw(&smc_inet_protosw);
  135. proto_unregister(&smc_inet_prot);
  136. #endif /* CONFIG_IPV6 */
  137. return rc;
  138. }
  139. void smc_inet_exit(void)
  140. {
  141. #if IS_ENABLED(CONFIG_IPV6)
  142. inet6_unregister_protosw(&smc_inet6_protosw);
  143. proto_unregister(&smc_inet6_prot);
  144. #endif /* CONFIG_IPV6 */
  145. inet_unregister_protosw(&smc_inet_protosw);
  146. proto_unregister(&smc_inet_prot);
  147. }