smc_inet.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  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. .flags = INET_PROTOSW_ICSK,
  54. };
  55. #if IS_ENABLED(CONFIG_IPV6)
  56. struct smc6_sock {
  57. struct smc_sock smc;
  58. struct ipv6_pinfo inet6;
  59. };
  60. static struct proto smc_inet6_prot = {
  61. .name = "INET6_SMC",
  62. .owner = THIS_MODULE,
  63. .init = smc_inet_init_sock,
  64. .hash = smc_hash_sk,
  65. .unhash = smc_unhash_sk,
  66. .release_cb = smc_release_cb,
  67. .obj_size = sizeof(struct smc6_sock),
  68. .h.smc_hash = &smc_v6_hashinfo,
  69. .slab_flags = SLAB_TYPESAFE_BY_RCU,
  70. .ipv6_pinfo_offset = offsetof(struct smc6_sock, inet6),
  71. };
  72. static const struct proto_ops smc_inet6_stream_ops = {
  73. .family = PF_INET6,
  74. .owner = THIS_MODULE,
  75. .release = smc_release,
  76. .bind = smc_bind,
  77. .connect = smc_connect,
  78. .socketpair = sock_no_socketpair,
  79. .accept = smc_accept,
  80. .getname = smc_getname,
  81. .poll = smc_poll,
  82. .ioctl = smc_ioctl,
  83. .listen = smc_listen,
  84. .shutdown = smc_shutdown,
  85. .setsockopt = smc_setsockopt,
  86. .getsockopt = smc_getsockopt,
  87. .sendmsg = smc_sendmsg,
  88. .recvmsg = smc_recvmsg,
  89. .mmap = sock_no_mmap,
  90. .splice_read = smc_splice_read,
  91. };
  92. static struct inet_protosw smc_inet6_protosw = {
  93. .type = SOCK_STREAM,
  94. .protocol = IPPROTO_SMC,
  95. .prot = &smc_inet6_prot,
  96. .ops = &smc_inet6_stream_ops,
  97. .flags = INET_PROTOSW_ICSK,
  98. };
  99. #endif /* CONFIG_IPV6 */
  100. static unsigned int smc_sync_mss(struct sock *sk, u32 pmtu)
  101. {
  102. /* No need pass it through to clcsock, mss can always be set by
  103. * sock_create_kern or smc_setsockopt.
  104. */
  105. return 0;
  106. }
  107. static int smc_inet_init_sock(struct sock *sk)
  108. {
  109. struct net *net = sock_net(sk);
  110. /* init common smc sock */
  111. smc_sk_init(net, sk, IPPROTO_SMC);
  112. inet_csk(sk)->icsk_sync_mss = smc_sync_mss;
  113. /* create clcsock */
  114. return smc_create_clcsk(net, sk, sk->sk_family);
  115. }
  116. int __init smc_inet_init(void)
  117. {
  118. int rc;
  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. #if IS_ENABLED(CONFIG_IPV6)
  128. rc = proto_register(&smc_inet6_prot, 1);
  129. if (rc) {
  130. pr_err("%s: proto_register smc_inet6_prot fails with %d\n",
  131. __func__, rc);
  132. goto out_inet6_prot;
  133. }
  134. rc = inet6_register_protosw(&smc_inet6_protosw);
  135. if (rc) {
  136. pr_err("%s: inet6_register_protosw smc_inet6_protosw fails with %d\n",
  137. __func__, rc);
  138. goto out_inet6_protosw;
  139. }
  140. return rc;
  141. out_inet6_protosw:
  142. proto_unregister(&smc_inet6_prot);
  143. out_inet6_prot:
  144. inet_unregister_protosw(&smc_inet_protosw);
  145. proto_unregister(&smc_inet_prot);
  146. #endif /* CONFIG_IPV6 */
  147. return rc;
  148. }
  149. void smc_inet_exit(void)
  150. {
  151. #if IS_ENABLED(CONFIG_IPV6)
  152. inet6_unregister_protosw(&smc_inet6_protosw);
  153. proto_unregister(&smc_inet6_prot);
  154. #endif /* CONFIG_IPV6 */
  155. inet_unregister_protosw(&smc_inet_protosw);
  156. proto_unregister(&smc_inet_prot);
  157. }