1 // SPDX-License-Identifier: GPL-2.0
4 * Copyright (c) 2017 - 2019, Intel Corporation.
7 #define pr_fmt(fmt) "MPTCP: " fmt
9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include <linux/netdevice.h>
13 #include <net/inet_common.h>
14 #include <net/inet_hashtables.h>
15 #include <net/protocol.h>
17 #include <net/mptcp.h>
20 static int mptcp_sendmsg(struct sock
*sk
, struct msghdr
*msg
, size_t len
)
22 struct mptcp_sock
*msk
= mptcp_sk(sk
);
23 struct socket
*subflow
= msk
->subflow
;
25 if (msg
->msg_flags
& ~(MSG_MORE
| MSG_DONTWAIT
| MSG_NOSIGNAL
))
28 return sock_sendmsg(subflow
, msg
);
31 static int mptcp_recvmsg(struct sock
*sk
, struct msghdr
*msg
, size_t len
,
32 int nonblock
, int flags
, int *addr_len
)
34 struct mptcp_sock
*msk
= mptcp_sk(sk
);
35 struct socket
*subflow
= msk
->subflow
;
37 if (msg
->msg_flags
& ~(MSG_WAITALL
| MSG_DONTWAIT
))
40 return sock_recvmsg(subflow
, msg
, flags
);
43 static int mptcp_init_sock(struct sock
*sk
)
48 static void mptcp_close(struct sock
*sk
, long timeout
)
50 struct mptcp_sock
*msk
= mptcp_sk(sk
);
52 inet_sk_state_store(sk
, TCP_CLOSE
);
55 pr_debug("subflow=%p", msk
->subflow
->sk
);
56 sock_release(msk
->subflow
);
63 static int mptcp_connect(struct sock
*sk
, struct sockaddr
*saddr
, int len
)
65 struct mptcp_sock
*msk
= mptcp_sk(sk
);
68 saddr
->sa_family
= AF_INET
;
70 pr_debug("msk=%p, subflow=%p", msk
, msk
->subflow
->sk
);
72 err
= kernel_connect(msk
->subflow
, saddr
, len
, 0);
74 sk
->sk_state
= TCP_ESTABLISHED
;
79 static struct proto mptcp_prot
= {
82 .init
= mptcp_init_sock
,
84 .accept
= inet_csk_accept
,
85 .connect
= mptcp_connect
,
86 .shutdown
= tcp_shutdown
,
87 .sendmsg
= mptcp_sendmsg
,
88 .recvmsg
= mptcp_recvmsg
,
90 .unhash
= inet_unhash
,
91 .get_port
= inet_csk_get_port
,
92 .obj_size
= sizeof(struct mptcp_sock
),
96 static struct inet_protosw mptcp_protosw
= {
98 .protocol
= IPPROTO_MPTCP
,
100 .ops
= &inet_stream_ops
,
103 void __init
mptcp_init(void)
105 if (proto_register(&mptcp_prot
, 1) != 0)
106 panic("Failed to register MPTCP proto.\n");
108 inet_register_protosw(&mptcp_protosw
);
111 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
112 static struct proto mptcp_v6_prot
;
114 static struct inet_protosw mptcp_v6_protosw
= {
116 .protocol
= IPPROTO_MPTCP
,
117 .prot
= &mptcp_v6_prot
,
118 .ops
= &inet6_stream_ops
,
119 .flags
= INET_PROTOSW_ICSK
,
122 int mptcpv6_init(void)
126 mptcp_v6_prot
= mptcp_prot
;
127 strcpy(mptcp_v6_prot
.name
, "MPTCPv6");
128 mptcp_v6_prot
.slab
= NULL
;
129 mptcp_v6_prot
.obj_size
= sizeof(struct mptcp_sock
) +
130 sizeof(struct ipv6_pinfo
);
132 err
= proto_register(&mptcp_v6_prot
, 1);
136 err
= inet6_register_protosw(&mptcp_v6_protosw
);
138 proto_unregister(&mptcp_v6_prot
);