* [PATCH mptcp-next 1/9] mptcp: refactor passive socket initialization.
2023-01-13 18:20 [PATCH mptcp-next 0/9] mptcp: refactor first subflow init Paolo Abeni
@ 2023-01-13 18:20 ` Paolo Abeni
2023-01-13 18:20 ` [PATCH mptcp-next 2/9] mptcp: drop unneeded argument Paolo Abeni
` (7 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Paolo Abeni @ 2023-01-13 18:20 UTC (permalink / raw)
To: mptcp
After commit 30e51b923e43 ("mptcp: fix unreleased socket in
accept queue") unaccepted msk sockets go throu complete
shutdown, we don't need anymore to delay inserting the first
subflow into the subflow lists.
The reference counting deserve some extra care, as __mptcp_close()
is unaware of the request socket linkage to the first subflow.
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
Notes:
- this schema assumes that the TCP code will never drop
a request socket from the receive queue after the 3whs. I tried
to verify such assumption as strictily as I could, but more eyes
more then welcome!
- this will cause pktdrill failure for close_before_accept.pkt, because
the msk will become fully established before accept() - imho a
good thing - and send out add_addr earlier.
The pktdrill test change should be easier.
---
net/mptcp/protocol.c | 17 -----------------
net/mptcp/subflow.c | 31 ++++++++++++++++++++++++-------
2 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 003b44a79fce..d298d629b3b2 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -825,7 +825,6 @@ static bool __mptcp_finish_join(struct mptcp_sock *msk, struct sock *ssk)
if (sk->sk_socket && !ssk->sk_socket)
mptcp_sock_graft(ssk, sk->sk_socket);
- mptcp_propagate_sndbuf((struct sock *)msk, ssk);
mptcp_sockopt_sync_locked(msk, ssk);
return true;
}
@@ -3753,22 +3752,6 @@ static int mptcp_stream_accept(struct socket *sock, struct socket *newsock,
lock_sock(newsk);
- /* PM/worker can now acquire the first subflow socket
- * lock without racing with listener queue cleanup,
- * we can notify it, if needed.
- *
- * Even if remote has reset the initial subflow by now
- * the refcnt is still at least one.
- */
- subflow = mptcp_subflow_ctx(msk->first);
- list_add(&subflow->node, &msk->conn_list);
- sock_hold(msk->first);
- if (mptcp_is_fully_established(newsk))
- mptcp_pm_fully_established(msk, msk->first, GFP_KERNEL);
-
- mptcp_rcv_space_init(msk, msk->first);
- mptcp_propagate_sndbuf(newsk, msk->first);
-
/* set ssk->sk_socket of accept()ed flows to mptcp socket.
* This is needed so NOSPACE flag can be set from tcp stack.
*/
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index ec54413fb31f..0b7e7a6606f5 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -749,6 +749,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
struct mptcp_options_received mp_opt;
bool fallback, fallback_is_fatal;
struct sock *new_msk = NULL;
+ struct mptcp_sock *owner;
struct sock *child;
pr_debug("listener=%p, req=%p, conn=%p", listener, req, listener->conn);
@@ -823,6 +824,8 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
ctx->setsockopt_seq = listener->setsockopt_seq;
if (ctx->mp_capable) {
+ owner = mptcp_sk(new_msk);
+
/* this can't race with mptcp_close(), as the msk is
* not yet exposted to user-space
*/
@@ -831,14 +834,14 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
/* record the newly created socket as the first msk
* subflow, but don't link it yet into conn_list
*/
- WRITE_ONCE(mptcp_sk(new_msk)->first, child);
+ WRITE_ONCE(owner->first, child);
/* new mpc subflow takes ownership of the newly
* created mptcp socket
*/
mptcp_sk(new_msk)->setsockopt_seq = ctx->setsockopt_seq;
- mptcp_pm_new_connection(mptcp_sk(new_msk), child, 1);
- mptcp_token_accept(subflow_req, mptcp_sk(new_msk));
+ mptcp_pm_new_connection(owner, child, 1);
+ mptcp_token_accept(subflow_req, owner);
ctx->conn = new_msk;
new_msk = NULL;
@@ -846,15 +849,21 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
* uses the correct data
*/
mptcp_copy_inaddrs(ctx->conn, child);
+ mptcp_propagate_sndbuf(ctx->conn, child);
+
+ mptcp_rcv_space_init(owner, child);
+ list_add(&ctx->node, &owner->conn_list);
+ sock_hold(child);
/* with OoO packets we can reach here without ingress
* mpc option
*/
- if (mp_opt.suboptions & OPTION_MPTCP_MPC_ACK)
+ if (mp_opt.suboptions & OPTION_MPTCP_MPC_ACK) {
mptcp_subflow_fully_established(ctx, &mp_opt);
+ mptcp_pm_fully_established(owner, child, GFP_ATOMIC);
+ ctx->pm_notified = 1;
+ }
} else if (ctx->mp_join) {
- struct mptcp_sock *owner;
-
owner = subflow_req->msk;
if (!owner) {
subflow_add_reset_reason(skb, MPTCP_RST_EPROHIBIT);
@@ -1836,9 +1845,17 @@ void mptcp_subflow_queue_clean(struct sock *listener_sk, struct sock *listener_s
sock_hold(sk);
lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
next = msk->dl_next;
- msk->first = NULL;
msk->dl_next = NULL;
+ /* The upcoming mptcp_close is going to drop all the references
+ * to the first subflow, ignoring that one of such reference is
+ * owned by the request socket still in the accept queue and that
+ * later inet_csk_listen_stop will drop it.
+ * Acquire an extra reference here to avoid an UaF at that point.
+ */
+ if (msk->first)
+ sock_hold(msk->first);
+
do_cancel_work = __mptcp_close(sk, 0);
release_sock(sk);
if (do_cancel_work) {
--
2.38.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH mptcp-next 2/9] mptcp: drop unneeded argument
2023-01-13 18:20 [PATCH mptcp-next 0/9] mptcp: refactor first subflow init Paolo Abeni
2023-01-13 18:20 ` [PATCH mptcp-next 1/9] mptcp: refactor passive socket initialization Paolo Abeni
@ 2023-01-13 18:20 ` Paolo Abeni
2023-01-13 18:20 ` [PATCH mptcp-next 3/9] mptcp: drop legacy code Paolo Abeni
` (6 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Paolo Abeni @ 2023-01-13 18:20 UTC (permalink / raw)
To: mptcp
After the previous commit every mptcp_pm_fully_established() is
always invoked with a GFP_ATOMIC argument. We can drop it.
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
net/mptcp/options.c | 2 +-
net/mptcp/pm.c | 4 ++--
net/mptcp/protocol.h | 2 +-
net/mptcp/subflow.c | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/net/mptcp/options.c b/net/mptcp/options.c
index b30cea2fbf3f..99c4f9e9bb90 100644
--- a/net/mptcp/options.c
+++ b/net/mptcp/options.c
@@ -1001,7 +1001,7 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk,
clear_3rdack_retransmission(ssk);
mptcp_pm_subflow_established(msk);
} else {
- mptcp_pm_fully_established(msk, ssk, GFP_ATOMIC);
+ mptcp_pm_fully_established(msk, ssk);
}
return true;
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index 8e0cf6275e94..4ed4d29d9c11 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -126,7 +126,7 @@ static bool mptcp_pm_schedule_work(struct mptcp_sock *msk,
return true;
}
-void mptcp_pm_fully_established(struct mptcp_sock *msk, const struct sock *ssk, gfp_t gfp)
+void mptcp_pm_fully_established(struct mptcp_sock *msk, const struct sock *ssk)
{
struct mptcp_pm_data *pm = &msk->pm;
bool announce = false;
@@ -150,7 +150,7 @@ void mptcp_pm_fully_established(struct mptcp_sock *msk, const struct sock *ssk,
spin_unlock_bh(&pm->lock);
if (announce)
- mptcp_event(MPTCP_EVENT_ESTABLISHED, msk, ssk, gfp);
+ mptcp_event(MPTCP_EVENT_ESTABLISHED, msk, ssk, GFP_ATOMIC);
}
void mptcp_pm_connection_closed(struct mptcp_sock *msk)
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 871ec3e93314..5f1a30959b5c 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -799,7 +799,7 @@ bool mptcp_pm_addr_families_match(const struct sock *sk,
void mptcp_pm_subflow_chk_stale(const struct mptcp_sock *msk, struct sock *ssk);
void mptcp_pm_nl_subflow_chk_stale(const struct mptcp_sock *msk, struct sock *ssk);
void mptcp_pm_new_connection(struct mptcp_sock *msk, const struct sock *ssk, int server_side);
-void mptcp_pm_fully_established(struct mptcp_sock *msk, const struct sock *ssk, gfp_t gfp);
+void mptcp_pm_fully_established(struct mptcp_sock *msk, const struct sock *ssk);
bool mptcp_pm_allow_new_subflow(struct mptcp_sock *msk);
void mptcp_pm_connection_closed(struct mptcp_sock *msk);
void mptcp_pm_subflow_established(struct mptcp_sock *msk);
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index 0b7e7a6606f5..769ac8b7900d 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -860,7 +860,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
*/
if (mp_opt.suboptions & OPTION_MPTCP_MPC_ACK) {
mptcp_subflow_fully_established(ctx, &mp_opt);
- mptcp_pm_fully_established(owner, child, GFP_ATOMIC);
+ mptcp_pm_fully_established(owner, child);
ctx->pm_notified = 1;
}
} else if (ctx->mp_join) {
--
2.38.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH mptcp-next 3/9] mptcp: drop legacy code.
2023-01-13 18:20 [PATCH mptcp-next 0/9] mptcp: refactor first subflow init Paolo Abeni
2023-01-13 18:20 ` [PATCH mptcp-next 1/9] mptcp: refactor passive socket initialization Paolo Abeni
2023-01-13 18:20 ` [PATCH mptcp-next 2/9] mptcp: drop unneeded argument Paolo Abeni
@ 2023-01-13 18:20 ` Paolo Abeni
2023-01-13 18:20 ` [PATCH mptcp-next 4/9] mptcp: avoid unneeded __mptcp_nmpc_socket() usage Paolo Abeni
` (5 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Paolo Abeni @ 2023-01-13 18:20 UTC (permalink / raw)
To: mptcp
After the previous commits the PM worker can't race anymore
with the unaccepted subflow close and disposal, as the msk
keeps a reference to such subflow.
We can remove the now irrelevant and confusing checks explicitly
preventing the mentioned race.
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
net/mptcp/options.c | 7 +------
net/mptcp/subflow.c | 7 +++----
2 files changed, 4 insertions(+), 10 deletions(-)
diff --git a/net/mptcp/options.c b/net/mptcp/options.c
index 99c4f9e9bb90..91d5b59540e9 100644
--- a/net/mptcp/options.c
+++ b/net/mptcp/options.c
@@ -988,12 +988,7 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk,
mptcp_subflow_fully_established(subflow, mp_opt);
check_notify:
- /* if the subflow is not already linked into the conn_list, we can't
- * notify the PM: this subflow is still on the listener queue
- * and the PM possibly acquiring the subflow lock could race with
- * the listener close
- */
- if (likely(subflow->pm_notified) || list_empty(&subflow->node))
+ if (likely(subflow->pm_notified))
return true;
subflow->pm_notified = 1;
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index 769ac8b7900d..d3a17f924377 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -1933,11 +1933,10 @@ static void subflow_ulp_release(struct sock *ssk)
sk = ctx->conn;
if (sk) {
- /* if the msk has been orphaned, keep the ctx
- * alive, will be freed by __mptcp_close_ssk(),
- * when the subflow is still unaccepted
+ /* if the subflow has been closed by the TCP stack, keep
+ * the ctx alive, will be freed by __mptcp_close_ssk()
*/
- release = ctx->disposable || list_empty(&ctx->node);
+ release = ctx->disposable;
sock_put(sk);
}
--
2.38.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH mptcp-next 4/9] mptcp: avoid unneeded __mptcp_nmpc_socket() usage
2023-01-13 18:20 [PATCH mptcp-next 0/9] mptcp: refactor first subflow init Paolo Abeni
` (2 preceding siblings ...)
2023-01-13 18:20 ` [PATCH mptcp-next 3/9] mptcp: drop legacy code Paolo Abeni
@ 2023-01-13 18:20 ` Paolo Abeni
2023-01-13 18:20 ` [PATCH mptcp-next 5/9] mptcp: move fastopen subflow check inside mptcp_sendmsg_fastopen() Paolo Abeni
` (4 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Paolo Abeni @ 2023-01-13 18:20 UTC (permalink / raw)
To: mptcp
In a few spots the mptcp code invokes the __mptcp_nmpc_socket() helper
multiple times under the same socket lock scope. Additionally, in such
places, the socket status ensure that threre is not an MP capable
handshake running.
Under the above condition we can replace the later __mptcp_nmpc_socket()
helper invocation with direct access to the msk->subflow pointer and
better document such access is not supposed to fail with WARN().
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
net/mptcp/protocol.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index d298d629b3b2..fc13f1e45137 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -3172,7 +3172,7 @@ static struct sock *mptcp_accept(struct sock *sk, int flags, int *err,
struct socket *listener;
struct sock *newsk;
- listener = __mptcp_nmpc_socket(msk);
+ listener = msk->subflow;
if (WARN_ON_ONCE(!listener)) {
*err = -EINVAL;
return NULL;
@@ -3392,7 +3392,7 @@ static int mptcp_get_port(struct sock *sk, unsigned short snum)
struct mptcp_sock *msk = mptcp_sk(sk);
struct socket *ssock;
- ssock = __mptcp_nmpc_socket(msk);
+ ssock = msk->subflow;
pr_debug("msk=%p, subflow=%p", msk, ssock);
if (WARN_ON_ONCE(!ssock))
return -EINVAL;
@@ -3738,7 +3738,10 @@ static int mptcp_stream_accept(struct socket *sock, struct socket *newsock,
pr_debug("msk=%p", msk);
- ssock = __mptcp_nmpc_socket(msk);
+ /* buggy applications can call accept on socket states other then LISTEN
+ * but no need to allocate the first subflow just to error out.
+ */
+ ssock = msk->subflow;
if (!ssock)
return -EINVAL;
--
2.38.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH mptcp-next 5/9] mptcp: move fastopen subflow check inside mptcp_sendmsg_fastopen()
2023-01-13 18:20 [PATCH mptcp-next 0/9] mptcp: refactor first subflow init Paolo Abeni
` (3 preceding siblings ...)
2023-01-13 18:20 ` [PATCH mptcp-next 4/9] mptcp: avoid unneeded __mptcp_nmpc_socket() usage Paolo Abeni
@ 2023-01-13 18:20 ` Paolo Abeni
2023-01-13 18:20 ` [PATCH mptcp-next 6/9] mptcp: move first subflow allocation at mpc access time Paolo Abeni
` (3 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Paolo Abeni @ 2023-01-13 18:20 UTC (permalink / raw)
To: mptcp
So that we can avoid a bunch of check in fastpath. Additionally we
can specialize such check according to the specific fastopen method
- defer_connect vs MSG_FASTOPEN.
The latter bits will simplify the next patches.
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
net/mptcp/protocol.c | 24 ++++++++++++++++++------
1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index fc13f1e45137..9c4c729bf271 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -1694,13 +1694,27 @@ static void mptcp_set_nospace(struct sock *sk)
static int mptcp_disconnect(struct sock *sk, int flags);
-static int mptcp_sendmsg_fastopen(struct sock *sk, struct sock *ssk, struct msghdr *msg,
+static int mptcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
size_t len, int *copied_syn)
{
unsigned int saved_flags = msg->msg_flags;
struct mptcp_sock *msk = mptcp_sk(sk);
+ struct sock *ssk;
int ret;
+ /* on flags based fastopen the mptcp is supposed to create the
+ * first subflow right now. Otherwise we are in the defer_connect
+ * path, and the first subflow must be already present.
+ * Since the defer_connect flag is cleared after the first succsful
+ * fastopen attempt, no need to check for additional subflow status.
+ */
+ if (msg->msg_flags & MSG_FASTOPEN && !__mptcp_nmpc_socket(msk))
+ return -EINVAL;
+ if (!msk->first)
+ return -EINVAL;
+
+ ssk = msk->first;
+
lock_sock(ssk);
msg->msg_flags |= MSG_DONTWAIT;
msk->connect_flags = O_NONBLOCK;
@@ -1723,6 +1737,7 @@ static int mptcp_sendmsg_fastopen(struct sock *sk, struct sock *ssk, struct msgh
} else if (ret && ret != -EINPROGRESS) {
mptcp_disconnect(sk, 0);
}
+ inet_sk(sk)->defer_connect = 0;
return ret;
}
@@ -1731,7 +1746,6 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
{
struct mptcp_sock *msk = mptcp_sk(sk);
struct page_frag *pfrag;
- struct socket *ssock;
size_t copied = 0;
int ret = 0;
long timeo;
@@ -1741,12 +1755,10 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
lock_sock(sk);
- ssock = __mptcp_nmpc_socket(msk);
- if (unlikely(ssock && (inet_sk(ssock->sk)->defer_connect ||
- msg->msg_flags & MSG_FASTOPEN))) {
+ if (unlikely(inet_sk(sk)->defer_connect || msg->msg_flags & MSG_FASTOPEN)) {
int copied_syn = 0;
- ret = mptcp_sendmsg_fastopen(sk, ssock->sk, msg, len, &copied_syn);
+ ret = mptcp_sendmsg_fastopen(sk, msg, len, &copied_syn);
copied += copied_syn;
if (ret == -EINPROGRESS && copied_syn > 0)
goto out;
--
2.38.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH mptcp-next 6/9] mptcp: move first subflow allocation at mpc access time
2023-01-13 18:20 [PATCH mptcp-next 0/9] mptcp: refactor first subflow init Paolo Abeni
` (4 preceding siblings ...)
2023-01-13 18:20 ` [PATCH mptcp-next 5/9] mptcp: move fastopen subflow check inside mptcp_sendmsg_fastopen() Paolo Abeni
@ 2023-01-13 18:20 ` Paolo Abeni
2023-01-16 18:32 ` Paolo Abeni
2023-01-13 18:20 ` [PATCH mptcp-next 7/9] mptcp: do not keep around the first subflow after disconnect Paolo Abeni
` (2 subsequent siblings)
8 siblings, 1 reply; 12+ messages in thread
From: Paolo Abeni @ 2023-01-13 18:20 UTC (permalink / raw)
To: mptcp
In the long run this will simplify the mptcp code and will
allow for more consistent behavior. Move the first subflow
allocation out of the sock->init ops into the __mptcp_nmpc_socket()
helper.
Since the first subflow creation can now happen after the first
setsockopt() we additionally need to invoke mptcp_sockopt_sync()
on it.
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
net/mptcp/pm_netlink.c | 4 +--
net/mptcp/protocol.c | 57 +++++++++++++++++++++++++++---------------
net/mptcp/protocol.h | 2 +-
net/mptcp/sockopt.c | 18 ++++++-------
4 files changed, 49 insertions(+), 32 deletions(-)
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index e82a112b8779..290f88fffe5f 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -1014,8 +1014,8 @@ static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
return -EINVAL;
ssock = __mptcp_nmpc_socket(msk);
- if (!ssock)
- return -EINVAL;
+ if (IS_ERR(ssock))
+ return PTR_ERR(ssock);
mptcp_info2sockaddr(&entry->addr, &addr, entry->addr.family);
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 9c4c729bf271..1b93624db62d 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -49,18 +49,6 @@ static void __mptcp_check_send_data_fin(struct sock *sk);
DEFINE_PER_CPU(struct mptcp_delegated_action, mptcp_delegated_actions);
static struct net_device mptcp_napi_dev;
-/* If msk has an initial subflow socket, and the MP_CAPABLE handshake has not
- * completed yet or has failed, return the subflow socket.
- * Otherwise return NULL.
- */
-struct socket *__mptcp_nmpc_socket(const struct mptcp_sock *msk)
-{
- if (!msk->subflow || READ_ONCE(msk->can_ack))
- return NULL;
-
- return msk->subflow;
-}
-
/* Returns end sequence number of the receiver's advertised window */
static u64 mptcp_wnd_end(const struct mptcp_sock *msk)
{
@@ -116,6 +104,31 @@ static int __mptcp_socket_create(struct mptcp_sock *msk)
return 0;
}
+/* Returns the first subflow socket if available and the MPC
+ * handshake is not started yet.
+ */
+struct socket *__mptcp_nmpc_socket(struct mptcp_sock *msk)
+{
+ struct sock *sk = (struct sock *)msk;
+ int ret;
+
+ if (!((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)))
+ return ERR_PTR(-EINVAL);
+
+ if (!msk->subflow) {
+ if (msk->first)
+ return ERR_PTR(-EINVAL);
+
+ ret = __mptcp_socket_create(msk);
+ if (ret)
+ return ERR_PTR(ret);
+
+ mptcp_sockopt_sync(msk, msk->first);
+ }
+
+ return msk->subflow;
+}
+
static void mptcp_drop(struct sock *sk, struct sk_buff *skb)
{
sk_drops_add(sk, skb);
@@ -1699,6 +1712,7 @@ static int mptcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
{
unsigned int saved_flags = msg->msg_flags;
struct mptcp_sock *msk = mptcp_sk(sk);
+ struct socket *ssock;
struct sock *ssk;
int ret;
@@ -1708,8 +1722,11 @@ static int mptcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
* Since the defer_connect flag is cleared after the first succsful
* fastopen attempt, no need to check for additional subflow status.
*/
- if (msg->msg_flags & MSG_FASTOPEN && !__mptcp_nmpc_socket(msk))
- return -EINVAL;
+ if (msg->msg_flags & MSG_FASTOPEN) {
+ ssock = __mptcp_nmpc_socket(msk);
+ if (IS_ERR(ssock))
+ return PTR_ERR(ssock);
+ }
if (!msk->first)
return -EINVAL;
@@ -3592,8 +3609,8 @@ static int mptcp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
int err = -EINVAL;
ssock = __mptcp_nmpc_socket(msk);
- if (!ssock)
- return -EINVAL;
+ if (IS_ERR(ssock))
+ return PTR_ERR(ssock);
mptcp_token_destroy(msk);
inet_sk_state_store(sk, TCP_SYN_SENT);
@@ -3681,8 +3698,8 @@ static int mptcp_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
lock_sock(sock->sk);
ssock = __mptcp_nmpc_socket(msk);
- if (!ssock) {
- err = -EINVAL;
+ if (IS_ERR(ssock)) {
+ err = PTR_ERR(ssock);
goto unlock;
}
@@ -3718,8 +3735,8 @@ static int mptcp_listen(struct socket *sock, int backlog)
lock_sock(sk);
ssock = __mptcp_nmpc_socket(msk);
- if (!ssock) {
- err = -EINVAL;
+ if (IS_ERR(ssock)) {
+ err = PTR_ERR(ssock);
goto unlock;
}
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 5f1a30959b5c..3a055438c65e 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -632,7 +632,7 @@ void __mptcp_subflow_send_ack(struct sock *ssk);
void mptcp_subflow_reset(struct sock *ssk);
void mptcp_subflow_queue_clean(struct sock *sk, struct sock *ssk);
void mptcp_sock_graft(struct sock *sk, struct socket *parent);
-struct socket *__mptcp_nmpc_socket(const struct mptcp_sock *msk);
+struct socket *__mptcp_nmpc_socket(struct mptcp_sock *msk);
bool __mptcp_close(struct sock *sk, long timeout);
void mptcp_cancel_work(struct sock *sk);
void mptcp_set_owner_r(struct sk_buff *skb, struct sock *sk);
diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
index 9986681aaf40..022a6cad00c1 100644
--- a/net/mptcp/sockopt.c
+++ b/net/mptcp/sockopt.c
@@ -301,9 +301,9 @@ static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname,
case SO_BINDTOIFINDEX:
lock_sock(sk);
ssock = __mptcp_nmpc_socket(msk);
- if (!ssock) {
+ if (IS_ERR(ssock)) {
release_sock(sk);
- return -EINVAL;
+ return PTR_ERR(ssock);
}
ret = sock_setsockopt(ssock, SOL_SOCKET, optname, optval, optlen);
@@ -396,9 +396,9 @@ static int mptcp_setsockopt_v6(struct mptcp_sock *msk, int optname,
case IPV6_FREEBIND:
lock_sock(sk);
ssock = __mptcp_nmpc_socket(msk);
- if (!ssock) {
+ if (IS_ERR(ssock)) {
release_sock(sk);
- return -EINVAL;
+ return PTR_ERR(ssock);
}
ret = tcp_setsockopt(ssock->sk, SOL_IPV6, optname, optval, optlen);
@@ -693,9 +693,9 @@ static int mptcp_setsockopt_sol_ip_set_transparent(struct mptcp_sock *msk, int o
lock_sock(sk);
ssock = __mptcp_nmpc_socket(msk);
- if (!ssock) {
+ if (IS_ERR(ssock)) {
release_sock(sk);
- return -EINVAL;
+ return PTR_ERR(ssock);
}
issk = inet_sk(ssock->sk);
@@ -764,8 +764,8 @@ static int mptcp_setsockopt_first_sf_only(struct mptcp_sock *msk, int level, int
/* Limit to first subflow, before the connection establishment */
sock = __mptcp_nmpc_socket(msk);
- if (!sock)
- return -EINVAL;
+ if (IS_ERR(sock))
+ return PTR_ERR(sock);
return tcp_setsockopt(sock->sk, level, optname, optval, optlen);
}
@@ -865,7 +865,7 @@ static int mptcp_getsockopt_first_sf_only(struct mptcp_sock *msk, int level, int
}
ssock = __mptcp_nmpc_socket(msk);
- if (!ssock)
+ if (IS_ERR(ssock))
goto out;
ret = tcp_getsockopt(ssock->sk, level, optname, optval, optlen);
--
2.38.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PATCH mptcp-next 6/9] mptcp: move first subflow allocation at mpc access time
2023-01-13 18:20 ` [PATCH mptcp-next 6/9] mptcp: move first subflow allocation at mpc access time Paolo Abeni
@ 2023-01-16 18:32 ` Paolo Abeni
0 siblings, 0 replies; 12+ messages in thread
From: Paolo Abeni @ 2023-01-16 18:32 UTC (permalink / raw)
To: mptcp
On Fri, 2023-01-13 at 19:20 +0100, Paolo Abeni wrote:
> In the long run this will simplify the mptcp code and will
> allow for more consistent behavior. Move the first subflow
> allocation out of the sock->init ops into the __mptcp_nmpc_socket()
> helper.
>
> Since the first subflow creation can now happen after the first
> setsockopt() we additionally need to invoke mptcp_sockopt_sync()
> on it.
>
> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
> ---
> net/mptcp/pm_netlink.c | 4 +--
> net/mptcp/protocol.c | 57 +++++++++++++++++++++++++++---------------
> net/mptcp/protocol.h | 2 +-
> net/mptcp/sockopt.c | 18 ++++++-------
> 4 files changed, 49 insertions(+), 32 deletions(-)
>
> diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
> index e82a112b8779..290f88fffe5f 100644
> --- a/net/mptcp/pm_netlink.c
> +++ b/net/mptcp/pm_netlink.c
> @@ -1014,8 +1014,8 @@ static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
> return -EINVAL;
>
> ssock = __mptcp_nmpc_socket(msk);
> - if (!ssock)
> - return -EINVAL;
> + if (IS_ERR(ssock))
> + return PTR_ERR(ssock);
>
> mptcp_info2sockaddr(&entry->addr, &addr, entry->addr.family);
> #if IS_ENABLED(CONFIG_MPTCP_IPV6)
> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
> index 9c4c729bf271..1b93624db62d 100644
> --- a/net/mptcp/protocol.c
> +++ b/net/mptcp/protocol.c
> @@ -49,18 +49,6 @@ static void __mptcp_check_send_data_fin(struct sock *sk);
> DEFINE_PER_CPU(struct mptcp_delegated_action, mptcp_delegated_actions);
> static struct net_device mptcp_napi_dev;
>
> -/* If msk has an initial subflow socket, and the MP_CAPABLE handshake has not
> - * completed yet or has failed, return the subflow socket.
> - * Otherwise return NULL.
> - */
> -struct socket *__mptcp_nmpc_socket(const struct mptcp_sock *msk)
> -{
> - if (!msk->subflow || READ_ONCE(msk->can_ack))
> - return NULL;
> -
> - return msk->subflow;
> -}
> -
> /* Returns end sequence number of the receiver's advertised window */
> static u64 mptcp_wnd_end(const struct mptcp_sock *msk)
> {
> @@ -116,6 +104,31 @@ static int __mptcp_socket_create(struct mptcp_sock *msk)
> return 0;
> }
>
> +/* Returns the first subflow socket if available and the MPC
> + * handshake is not started yet.
> + */
> +struct socket *__mptcp_nmpc_socket(struct mptcp_sock *msk)
> +{
> + struct sock *sk = (struct sock *)msk;
> + int ret;
> +
> + if (!((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)))
> + return ERR_PTR(-EINVAL);
> +
> + if (!msk->subflow) {
> + if (msk->first)
> + return ERR_PTR(-EINVAL);
> +
> + ret = __mptcp_socket_create(msk);
> + if (ret)
> + return ERR_PTR(ret);
> +
> + mptcp_sockopt_sync(msk, msk->first);
> + }
> +
> + return msk->subflow;
> +}
> +
> static void mptcp_drop(struct sock *sk, struct sk_buff *skb)
> {
> sk_drops_add(sk, skb);
> @@ -1699,6 +1712,7 @@ static int mptcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
> {
> unsigned int saved_flags = msg->msg_flags;
> struct mptcp_sock *msk = mptcp_sk(sk);
> + struct socket *ssock;
> struct sock *ssk;
> int ret;
>
> @@ -1708,8 +1722,11 @@ static int mptcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
> * Since the defer_connect flag is cleared after the first succsful
> * fastopen attempt, no need to check for additional subflow status.
> */
> - if (msg->msg_flags & MSG_FASTOPEN && !__mptcp_nmpc_socket(msk))
> - return -EINVAL;
> + if (msg->msg_flags & MSG_FASTOPEN) {
> + ssock = __mptcp_nmpc_socket(msk);
> + if (IS_ERR(ssock))
> + return PTR_ERR(ssock);
> + }
> if (!msk->first)
> return -EINVAL;
>
> @@ -3592,8 +3609,8 @@ static int mptcp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
> int err = -EINVAL;
>
> ssock = __mptcp_nmpc_socket(msk);
> - if (!ssock)
> - return -EINVAL;
> + if (IS_ERR(ssock))
> + return PTR_ERR(ssock);
>
> mptcp_token_destroy(msk);
> inet_sk_state_store(sk, TCP_SYN_SENT);
> @@ -3681,8 +3698,8 @@ static int mptcp_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
>
> lock_sock(sock->sk);
> ssock = __mptcp_nmpc_socket(msk);
> - if (!ssock) {
> - err = -EINVAL;
> + if (IS_ERR(ssock)) {
> + err = PTR_ERR(ssock);
> goto unlock;
> }
>
> @@ -3718,8 +3735,8 @@ static int mptcp_listen(struct socket *sock, int backlog)
>
> lock_sock(sk);
> ssock = __mptcp_nmpc_socket(msk);
> - if (!ssock) {
> - err = -EINVAL;
> + if (IS_ERR(ssock)) {
> + err = PTR_ERR(ssock);
> goto unlock;
> }
>
> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> index 5f1a30959b5c..3a055438c65e 100644
> --- a/net/mptcp/protocol.h
> +++ b/net/mptcp/protocol.h
> @@ -632,7 +632,7 @@ void __mptcp_subflow_send_ack(struct sock *ssk);
> void mptcp_subflow_reset(struct sock *ssk);
> void mptcp_subflow_queue_clean(struct sock *sk, struct sock *ssk);
> void mptcp_sock_graft(struct sock *sk, struct socket *parent);
> -struct socket *__mptcp_nmpc_socket(const struct mptcp_sock *msk);
> +struct socket *__mptcp_nmpc_socket(struct mptcp_sock *msk);
> bool __mptcp_close(struct sock *sk, long timeout);
> void mptcp_cancel_work(struct sock *sk);
> void mptcp_set_owner_r(struct sk_buff *skb, struct sock *sk);
> diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
> index 9986681aaf40..022a6cad00c1 100644
> --- a/net/mptcp/sockopt.c
> +++ b/net/mptcp/sockopt.c
> @@ -301,9 +301,9 @@ static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname,
> case SO_BINDTOIFINDEX:
> lock_sock(sk);
> ssock = __mptcp_nmpc_socket(msk);
> - if (!ssock) {
> + if (IS_ERR(ssock)) {
> release_sock(sk);
> - return -EINVAL;
> + return PTR_ERR(ssock);
> }
>
> ret = sock_setsockopt(ssock, SOL_SOCKET, optname, optval, optlen);
> @@ -396,9 +396,9 @@ static int mptcp_setsockopt_v6(struct mptcp_sock *msk, int optname,
> case IPV6_FREEBIND:
> lock_sock(sk);
> ssock = __mptcp_nmpc_socket(msk);
> - if (!ssock) {
> + if (IS_ERR(ssock)) {
> release_sock(sk);
> - return -EINVAL;
> + return PTR_ERR(ssock);
> }
>
> ret = tcp_setsockopt(ssock->sk, SOL_IPV6, optname, optval, optlen);
> @@ -693,9 +693,9 @@ static int mptcp_setsockopt_sol_ip_set_transparent(struct mptcp_sock *msk, int o
> lock_sock(sk);
>
> ssock = __mptcp_nmpc_socket(msk);
> - if (!ssock) {
> + if (IS_ERR(ssock)) {
> release_sock(sk);
> - return -EINVAL;
> + return PTR_ERR(ssock);
> }
>
> issk = inet_sk(ssock->sk);
> @@ -764,8 +764,8 @@ static int mptcp_setsockopt_first_sf_only(struct mptcp_sock *msk, int level, int
>
> /* Limit to first subflow, before the connection establishment */
> sock = __mptcp_nmpc_socket(msk);
> - if (!sock)
> - return -EINVAL;
> + if (IS_ERR(sock))
> + return PTR_ERR(sock);
>
> return tcp_setsockopt(sock->sk, level, optname, optval, optlen);
> }
> @@ -865,7 +865,7 @@ static int mptcp_getsockopt_first_sf_only(struct mptcp_sock *msk, int level, int
> }
>
> ssock = __mptcp_nmpc_socket(msk);
> - if (!ssock)
> + if (IS_ERR(ssock))
> goto out;
>
> ret = tcp_getsockopt(ssock->sk, level, optname, optval, optlen);
Self-nack. While rebasing the LSM/selinux patches on top of this
series, I noticed I actually forgot (ahem ...) to remove the first
subflow initialization from mptcp_init_sock(). The relative low number
of issues found while testing should have warned me...
I'm updating the series and I'll post after some more testings.
Cheers,
Paolo
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH mptcp-next 7/9] mptcp: do not keep around the first subflow after disconnect.
2023-01-13 18:20 [PATCH mptcp-next 0/9] mptcp: refactor first subflow init Paolo Abeni
` (5 preceding siblings ...)
2023-01-13 18:20 ` [PATCH mptcp-next 6/9] mptcp: move first subflow allocation at mpc access time Paolo Abeni
@ 2023-01-13 18:20 ` Paolo Abeni
2023-01-13 18:20 ` [PATCH mptcp-next 8/9] mptcp: fastclose msk when cleaning unaccepted sockets Paolo Abeni
2023-01-13 18:20 ` [PATCH mptcp-next 9/9] mptcp: refactor mptcp_stream_accept() Paolo Abeni
8 siblings, 0 replies; 12+ messages in thread
From: Paolo Abeni @ 2023-01-13 18:20 UTC (permalink / raw)
To: mptcp
After the previous patch the first subflow is allocated as
needed at bind, connect, listen time. We don't need anymore
to keep alive the first subflow after a disconnect just to
be able to perform such syscall.
Overal this change makes the passive and active sockets consistent:
even passive sockets will be allowed to complete life cycle after
disconnect.
Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/290
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
net/mptcp/protocol.c | 24 +++++-------------------
1 file changed, 5 insertions(+), 19 deletions(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 1b93624db62d..9d440746704d 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -2371,11 +2371,9 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
unsigned int flags)
{
struct mptcp_sock *msk = mptcp_sk(sk);
- bool need_push, dispose_it;
+ bool need_push;
- dispose_it = !msk->subflow || ssk != msk->subflow->sk;
- if (dispose_it)
- list_del(&subflow->node);
+ list_del(&subflow->node);
lock_sock_nested(ssk, SINGLE_DEPTH_NESTING);
@@ -2389,15 +2387,6 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
}
need_push = (flags & MPTCP_CF_PUSH) && __mptcp_retransmit_pending_data(sk);
- if (!dispose_it) {
- tcp_disconnect(ssk, 0);
- msk->subflow->state = SS_UNCONNECTED;
- mptcp_subflow_ctx_reset(subflow);
- release_sock(ssk);
-
- goto out;
- }
-
sock_orphan(ssk);
subflow->disposable = 1;
@@ -2424,10 +2413,11 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
sock_put(ssk);
- if (ssk == msk->first)
+ if (ssk == msk->first) {
msk->first = NULL;
+ mptcp_dispose_initial_subflow(msk);
+ }
-out:
if (ssk == msk->last_snd)
msk->last_snd = NULL;
@@ -3274,10 +3264,6 @@ static void mptcp_destroy(struct sock *sk)
{
struct mptcp_sock *msk = mptcp_sk(sk);
- /* clears msk->subflow, allowing the following to close
- * even the initial subflow
- */
- mptcp_dispose_initial_subflow(msk);
mptcp_destroy_common(msk, 0);
sk_sockets_allocated_dec(sk);
}
--
2.38.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH mptcp-next 8/9] mptcp: fastclose msk when cleaning unaccepted sockets
2023-01-13 18:20 [PATCH mptcp-next 0/9] mptcp: refactor first subflow init Paolo Abeni
` (6 preceding siblings ...)
2023-01-13 18:20 ` [PATCH mptcp-next 7/9] mptcp: do not keep around the first subflow after disconnect Paolo Abeni
@ 2023-01-13 18:20 ` Paolo Abeni
2023-01-13 18:20 ` [PATCH mptcp-next 9/9] mptcp: refactor mptcp_stream_accept() Paolo Abeni
8 siblings, 0 replies; 12+ messages in thread
From: Paolo Abeni @ 2023-01-13 18:20 UTC (permalink / raw)
To: mptcp
When cleaning up unaccepted mptcp socket still laying inside
the listener queue at listener close time, such sockets will
go through a regular close, waiting for a timeout before
shutting down the subflows.
There is no need to keep the kernel resources in use for
such a possibly long time: short-circuit to fast-close.
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
net/mptcp/protocol.c | 7 +++++--
net/mptcp/subflow.c | 2 +-
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 9d440746704d..e5d1d2747e31 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -2981,10 +2981,13 @@ bool __mptcp_close(struct sock *sk, long timeout)
goto cleanup;
}
- if (mptcp_check_readable(msk)) {
- /* the msk has read data, do the MPTCP equivalent of TCP reset */
+ if (mptcp_check_readable(msk) || timeout < 0) {
+ /* If the msk has read data, or the caller explicitly ask it,
+ * do the MPTCP equivalent of TCP reset, aka MTCP fastclose
+ */
inet_sk_state_store(sk, TCP_CLOSE);
mptcp_do_fastclose(sk);
+ timeout = 0;
} else if (mptcp_close_state(sk)) {
__mptcp_wr_shutdown(sk);
}
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index d3a17f924377..b4d693089476 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -1856,7 +1856,7 @@ void mptcp_subflow_queue_clean(struct sock *listener_sk, struct sock *listener_s
if (msk->first)
sock_hold(msk->first);
- do_cancel_work = __mptcp_close(sk, 0);
+ do_cancel_work = __mptcp_close(sk, -1);
release_sock(sk);
if (do_cancel_work) {
/* lockdep will report a false positive ABBA deadlock
--
2.38.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH mptcp-next 9/9] mptcp: refactor mptcp_stream_accept()
2023-01-13 18:20 [PATCH mptcp-next 0/9] mptcp: refactor first subflow init Paolo Abeni
` (7 preceding siblings ...)
2023-01-13 18:20 ` [PATCH mptcp-next 8/9] mptcp: fastclose msk when cleaning unaccepted sockets Paolo Abeni
@ 2023-01-13 18:20 ` Paolo Abeni
2023-01-13 19:28 ` mptcp: refactor mptcp_stream_accept(): Tests Results MPTCP CI
8 siblings, 1 reply; 12+ messages in thread
From: Paolo Abeni @ 2023-01-13 18:20 UTC (permalink / raw)
To: mptcp
Rewrite the mptcp socket accept op, partially open-codying
inet_accept(), instead of indirectly calling it.
This way we can avoid acquiring the new socket lock twice
and we can avoid a couple of indirect calls.
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
net/mptcp/protocol.c | 27 +++++++++++++++++++--------
1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index e5d1d2747e31..cfc112f73d6e 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -3752,6 +3752,7 @@ static int mptcp_stream_accept(struct socket *sock, struct socket *newsock,
{
struct mptcp_sock *msk = mptcp_sk(sock->sk);
struct socket *ssock;
+ struct sock *newsk;
int err;
pr_debug("msk=%p", msk);
@@ -3763,16 +3764,26 @@ static int mptcp_stream_accept(struct socket *sock, struct socket *newsock,
if (!ssock)
return -EINVAL;
- err = ssock->ops->accept(sock, newsock, flags, kern);
- if (err == 0 && !mptcp_is_tcpsk(newsock->sk)) {
- struct mptcp_sock *msk = mptcp_sk(newsock->sk);
+ newsk = mptcp_accept(sock->sk, flags, &err, kern);
+ if (!newsk)
+ return err;
+
+ lock_sock(newsk);
+
+ sock_rps_record_flow(newsk);
+ WARN_ON(!((1 << newsk->sk_state) &
+ (TCPF_ESTABLISHED | TCPF_SYN_RECV |
+ TCPF_CLOSE_WAIT | TCPF_CLOSE)));
+
+ sock_graft(newsk, newsock);
+
+ newsock->state = SS_CONNECTED;
+ if (!mptcp_is_tcpsk(newsock->sk)) {
+ struct mptcp_sock *msk = mptcp_sk(newsk);
struct mptcp_subflow_context *subflow;
- struct sock *newsk = newsock->sk;
set_bit(SOCK_CUSTOM_SOCKOPT, &newsock->flags);
- lock_sock(newsk);
-
/* set ssk->sk_socket of accept()ed flows to mptcp socket.
* This is needed so NOSPACE flag can be set from tcp stack.
*/
@@ -3782,10 +3793,10 @@ static int mptcp_stream_accept(struct socket *sock, struct socket *newsock,
if (!ssk->sk_socket)
mptcp_sock_graft(ssk, newsock);
}
- release_sock(newsk);
}
+ release_sock(newsk);
- return err;
+ return 0;
}
static __poll_t mptcp_check_writeable(struct mptcp_sock *msk)
--
2.38.1
^ permalink raw reply related [flat|nested] 12+ messages in thread