1*f870fa0bSMat Martineau // SPDX-License-Identifier: GPL-2.0 2*f870fa0bSMat Martineau /* Multipath TCP 3*f870fa0bSMat Martineau * 4*f870fa0bSMat Martineau * Copyright (c) 2017 - 2019, Intel Corporation. 5*f870fa0bSMat Martineau */ 6*f870fa0bSMat Martineau 7*f870fa0bSMat Martineau #define pr_fmt(fmt) "MPTCP: " fmt 8*f870fa0bSMat Martineau 9*f870fa0bSMat Martineau #include <linux/kernel.h> 10*f870fa0bSMat Martineau #include <linux/module.h> 11*f870fa0bSMat Martineau #include <linux/netdevice.h> 12*f870fa0bSMat Martineau #include <net/sock.h> 13*f870fa0bSMat Martineau #include <net/inet_common.h> 14*f870fa0bSMat Martineau #include <net/inet_hashtables.h> 15*f870fa0bSMat Martineau #include <net/protocol.h> 16*f870fa0bSMat Martineau #include <net/tcp.h> 17*f870fa0bSMat Martineau #include <net/mptcp.h> 18*f870fa0bSMat Martineau #include "protocol.h" 19*f870fa0bSMat Martineau 20*f870fa0bSMat Martineau static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) 21*f870fa0bSMat Martineau { 22*f870fa0bSMat Martineau struct mptcp_sock *msk = mptcp_sk(sk); 23*f870fa0bSMat Martineau struct socket *subflow = msk->subflow; 24*f870fa0bSMat Martineau 25*f870fa0bSMat Martineau if (msg->msg_flags & ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL)) 26*f870fa0bSMat Martineau return -EOPNOTSUPP; 27*f870fa0bSMat Martineau 28*f870fa0bSMat Martineau return sock_sendmsg(subflow, msg); 29*f870fa0bSMat Martineau } 30*f870fa0bSMat Martineau 31*f870fa0bSMat Martineau static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, 32*f870fa0bSMat Martineau int nonblock, int flags, int *addr_len) 33*f870fa0bSMat Martineau { 34*f870fa0bSMat Martineau struct mptcp_sock *msk = mptcp_sk(sk); 35*f870fa0bSMat Martineau struct socket *subflow = msk->subflow; 36*f870fa0bSMat Martineau 37*f870fa0bSMat Martineau if (msg->msg_flags & ~(MSG_WAITALL | MSG_DONTWAIT)) 38*f870fa0bSMat Martineau return -EOPNOTSUPP; 39*f870fa0bSMat Martineau 40*f870fa0bSMat Martineau return sock_recvmsg(subflow, msg, flags); 41*f870fa0bSMat Martineau } 42*f870fa0bSMat Martineau 43*f870fa0bSMat Martineau static int mptcp_init_sock(struct sock *sk) 44*f870fa0bSMat Martineau { 45*f870fa0bSMat Martineau return 0; 46*f870fa0bSMat Martineau } 47*f870fa0bSMat Martineau 48*f870fa0bSMat Martineau static void mptcp_close(struct sock *sk, long timeout) 49*f870fa0bSMat Martineau { 50*f870fa0bSMat Martineau struct mptcp_sock *msk = mptcp_sk(sk); 51*f870fa0bSMat Martineau 52*f870fa0bSMat Martineau inet_sk_state_store(sk, TCP_CLOSE); 53*f870fa0bSMat Martineau 54*f870fa0bSMat Martineau if (msk->subflow) { 55*f870fa0bSMat Martineau pr_debug("subflow=%p", msk->subflow->sk); 56*f870fa0bSMat Martineau sock_release(msk->subflow); 57*f870fa0bSMat Martineau } 58*f870fa0bSMat Martineau 59*f870fa0bSMat Martineau sock_orphan(sk); 60*f870fa0bSMat Martineau sock_put(sk); 61*f870fa0bSMat Martineau } 62*f870fa0bSMat Martineau 63*f870fa0bSMat Martineau static int mptcp_connect(struct sock *sk, struct sockaddr *saddr, int len) 64*f870fa0bSMat Martineau { 65*f870fa0bSMat Martineau struct mptcp_sock *msk = mptcp_sk(sk); 66*f870fa0bSMat Martineau int err; 67*f870fa0bSMat Martineau 68*f870fa0bSMat Martineau saddr->sa_family = AF_INET; 69*f870fa0bSMat Martineau 70*f870fa0bSMat Martineau pr_debug("msk=%p, subflow=%p", msk, msk->subflow->sk); 71*f870fa0bSMat Martineau 72*f870fa0bSMat Martineau err = kernel_connect(msk->subflow, saddr, len, 0); 73*f870fa0bSMat Martineau 74*f870fa0bSMat Martineau sk->sk_state = TCP_ESTABLISHED; 75*f870fa0bSMat Martineau 76*f870fa0bSMat Martineau return err; 77*f870fa0bSMat Martineau } 78*f870fa0bSMat Martineau 79*f870fa0bSMat Martineau static struct proto mptcp_prot = { 80*f870fa0bSMat Martineau .name = "MPTCP", 81*f870fa0bSMat Martineau .owner = THIS_MODULE, 82*f870fa0bSMat Martineau .init = mptcp_init_sock, 83*f870fa0bSMat Martineau .close = mptcp_close, 84*f870fa0bSMat Martineau .accept = inet_csk_accept, 85*f870fa0bSMat Martineau .connect = mptcp_connect, 86*f870fa0bSMat Martineau .shutdown = tcp_shutdown, 87*f870fa0bSMat Martineau .sendmsg = mptcp_sendmsg, 88*f870fa0bSMat Martineau .recvmsg = mptcp_recvmsg, 89*f870fa0bSMat Martineau .hash = inet_hash, 90*f870fa0bSMat Martineau .unhash = inet_unhash, 91*f870fa0bSMat Martineau .get_port = inet_csk_get_port, 92*f870fa0bSMat Martineau .obj_size = sizeof(struct mptcp_sock), 93*f870fa0bSMat Martineau .no_autobind = true, 94*f870fa0bSMat Martineau }; 95*f870fa0bSMat Martineau 96*f870fa0bSMat Martineau static struct inet_protosw mptcp_protosw = { 97*f870fa0bSMat Martineau .type = SOCK_STREAM, 98*f870fa0bSMat Martineau .protocol = IPPROTO_MPTCP, 99*f870fa0bSMat Martineau .prot = &mptcp_prot, 100*f870fa0bSMat Martineau .ops = &inet_stream_ops, 101*f870fa0bSMat Martineau }; 102*f870fa0bSMat Martineau 103*f870fa0bSMat Martineau void __init mptcp_init(void) 104*f870fa0bSMat Martineau { 105*f870fa0bSMat Martineau if (proto_register(&mptcp_prot, 1) != 0) 106*f870fa0bSMat Martineau panic("Failed to register MPTCP proto.\n"); 107*f870fa0bSMat Martineau 108*f870fa0bSMat Martineau inet_register_protosw(&mptcp_protosw); 109*f870fa0bSMat Martineau } 110*f870fa0bSMat Martineau 111*f870fa0bSMat Martineau #if IS_ENABLED(CONFIG_MPTCP_IPV6) 112*f870fa0bSMat Martineau static struct proto mptcp_v6_prot; 113*f870fa0bSMat Martineau 114*f870fa0bSMat Martineau static struct inet_protosw mptcp_v6_protosw = { 115*f870fa0bSMat Martineau .type = SOCK_STREAM, 116*f870fa0bSMat Martineau .protocol = IPPROTO_MPTCP, 117*f870fa0bSMat Martineau .prot = &mptcp_v6_prot, 118*f870fa0bSMat Martineau .ops = &inet6_stream_ops, 119*f870fa0bSMat Martineau .flags = INET_PROTOSW_ICSK, 120*f870fa0bSMat Martineau }; 121*f870fa0bSMat Martineau 122*f870fa0bSMat Martineau int mptcpv6_init(void) 123*f870fa0bSMat Martineau { 124*f870fa0bSMat Martineau int err; 125*f870fa0bSMat Martineau 126*f870fa0bSMat Martineau mptcp_v6_prot = mptcp_prot; 127*f870fa0bSMat Martineau strcpy(mptcp_v6_prot.name, "MPTCPv6"); 128*f870fa0bSMat Martineau mptcp_v6_prot.slab = NULL; 129*f870fa0bSMat Martineau mptcp_v6_prot.obj_size = sizeof(struct mptcp_sock) + 130*f870fa0bSMat Martineau sizeof(struct ipv6_pinfo); 131*f870fa0bSMat Martineau 132*f870fa0bSMat Martineau err = proto_register(&mptcp_v6_prot, 1); 133*f870fa0bSMat Martineau if (err) 134*f870fa0bSMat Martineau return err; 135*f870fa0bSMat Martineau 136*f870fa0bSMat Martineau err = inet6_register_protosw(&mptcp_v6_protosw); 137*f870fa0bSMat Martineau if (err) 138*f870fa0bSMat Martineau proto_unregister(&mptcp_v6_prot); 139*f870fa0bSMat Martineau 140*f870fa0bSMat Martineau return err; 141*f870fa0bSMat Martineau } 142*f870fa0bSMat Martineau #endif 143