| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- // SPDX-License-Identifier: GPL-2.0-only
- /*
- * Shared Memory Communications over RDMA (SMC-R) and RoCE
- *
- * Definitions for the IPPROTO_SMC (socket related)
- *
- * Copyright IBM Corp. 2016, 2018
- * Copyright (c) 2024, Alibaba Inc.
- *
- * Author: D. Wythe <alibuda@linux.alibaba.com>
- */
- #include <net/protocol.h>
- #include <net/sock.h>
- #include "smc_inet.h"
- #include "smc.h"
- static int smc_inet_init_sock(struct sock *sk);
- static struct proto smc_inet_prot = {
- .name = "INET_SMC",
- .owner = THIS_MODULE,
- .init = smc_inet_init_sock,
- .hash = smc_hash_sk,
- .unhash = smc_unhash_sk,
- .release_cb = smc_release_cb,
- .obj_size = sizeof(struct smc_sock),
- .h.smc_hash = &smc_v4_hashinfo,
- .slab_flags = SLAB_TYPESAFE_BY_RCU,
- };
- static const struct proto_ops smc_inet_stream_ops = {
- .family = PF_INET,
- .owner = THIS_MODULE,
- .release = smc_release,
- .bind = smc_bind,
- .connect = smc_connect,
- .socketpair = sock_no_socketpair,
- .accept = smc_accept,
- .getname = smc_getname,
- .poll = smc_poll,
- .ioctl = smc_ioctl,
- .listen = smc_listen,
- .shutdown = smc_shutdown,
- .setsockopt = smc_setsockopt,
- .getsockopt = smc_getsockopt,
- .sendmsg = smc_sendmsg,
- .recvmsg = smc_recvmsg,
- .mmap = sock_no_mmap,
- .splice_read = smc_splice_read,
- };
- static struct inet_protosw smc_inet_protosw = {
- .type = SOCK_STREAM,
- .protocol = IPPROTO_SMC,
- .prot = &smc_inet_prot,
- .ops = &smc_inet_stream_ops,
- .flags = INET_PROTOSW_ICSK,
- };
- #if IS_ENABLED(CONFIG_IPV6)
- struct smc6_sock {
- struct smc_sock smc;
- struct ipv6_pinfo inet6;
- };
- static struct proto smc_inet6_prot = {
- .name = "INET6_SMC",
- .owner = THIS_MODULE,
- .init = smc_inet_init_sock,
- .hash = smc_hash_sk,
- .unhash = smc_unhash_sk,
- .release_cb = smc_release_cb,
- .obj_size = sizeof(struct smc6_sock),
- .h.smc_hash = &smc_v6_hashinfo,
- .slab_flags = SLAB_TYPESAFE_BY_RCU,
- .ipv6_pinfo_offset = offsetof(struct smc6_sock, inet6),
- };
- static const struct proto_ops smc_inet6_stream_ops = {
- .family = PF_INET6,
- .owner = THIS_MODULE,
- .release = smc_release,
- .bind = smc_bind,
- .connect = smc_connect,
- .socketpair = sock_no_socketpair,
- .accept = smc_accept,
- .getname = smc_getname,
- .poll = smc_poll,
- .ioctl = smc_ioctl,
- .listen = smc_listen,
- .shutdown = smc_shutdown,
- .setsockopt = smc_setsockopt,
- .getsockopt = smc_getsockopt,
- .sendmsg = smc_sendmsg,
- .recvmsg = smc_recvmsg,
- .mmap = sock_no_mmap,
- .splice_read = smc_splice_read,
- };
- static struct inet_protosw smc_inet6_protosw = {
- .type = SOCK_STREAM,
- .protocol = IPPROTO_SMC,
- .prot = &smc_inet6_prot,
- .ops = &smc_inet6_stream_ops,
- .flags = INET_PROTOSW_ICSK,
- };
- #endif /* CONFIG_IPV6 */
- static unsigned int smc_sync_mss(struct sock *sk, u32 pmtu)
- {
- /* No need pass it through to clcsock, mss can always be set by
- * sock_create_kern or smc_setsockopt.
- */
- return 0;
- }
- static int smc_inet_init_sock(struct sock *sk)
- {
- struct net *net = sock_net(sk);
- /* init common smc sock */
- smc_sk_init(net, sk, IPPROTO_SMC);
- inet_csk(sk)->icsk_sync_mss = smc_sync_mss;
- /* create clcsock */
- return smc_create_clcsk(net, sk, sk->sk_family);
- }
- int __init smc_inet_init(void)
- {
- int rc;
- rc = proto_register(&smc_inet_prot, 1);
- if (rc) {
- pr_err("%s: proto_register smc_inet_prot fails with %d\n",
- __func__, rc);
- return rc;
- }
- /* no return value */
- inet_register_protosw(&smc_inet_protosw);
- #if IS_ENABLED(CONFIG_IPV6)
- rc = proto_register(&smc_inet6_prot, 1);
- if (rc) {
- pr_err("%s: proto_register smc_inet6_prot fails with %d\n",
- __func__, rc);
- goto out_inet6_prot;
- }
- rc = inet6_register_protosw(&smc_inet6_protosw);
- if (rc) {
- pr_err("%s: inet6_register_protosw smc_inet6_protosw fails with %d\n",
- __func__, rc);
- goto out_inet6_protosw;
- }
- return rc;
- out_inet6_protosw:
- proto_unregister(&smc_inet6_prot);
- out_inet6_prot:
- inet_unregister_protosw(&smc_inet_protosw);
- proto_unregister(&smc_inet_prot);
- #endif /* CONFIG_IPV6 */
- return rc;
- }
- void smc_inet_exit(void)
- {
- #if IS_ENABLED(CONFIG_IPV6)
- inet6_unregister_protosw(&smc_inet6_protosw);
- proto_unregister(&smc_inet6_prot);
- #endif /* CONFIG_IPV6 */
- inet_unregister_protosw(&smc_inet_protosw);
- proto_unregister(&smc_inet_prot);
- }
|