提交 95d68651 编写于 作者: P Paolo Abeni 提交者: Jakub Kicinski

mptcp: fix subflow accounting on close

If the PM closes a fully established MPJ subflow or the subflow
creation errors out in it's early stage the subflows counter is
not bumped accordingly.

This change adds the missing accounting, additionally taking care
of updating accordingly the 'accept_subflow' flag.

Fixes: a88c9e49 ("mptcp: do not block subflows creation on errors")
Signed-off-by: NPaolo Abeni <pabeni@redhat.com>
Signed-off-by: NMat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: NJakub Kicinski <kuba@kernel.org>
上级 04c494e6
...@@ -178,14 +178,13 @@ void mptcp_pm_subflow_check_next(struct mptcp_sock *msk, const struct sock *ssk, ...@@ -178,14 +178,13 @@ void mptcp_pm_subflow_check_next(struct mptcp_sock *msk, const struct sock *ssk,
struct mptcp_pm_data *pm = &msk->pm; struct mptcp_pm_data *pm = &msk->pm;
bool update_subflows; bool update_subflows;
update_subflows = (ssk->sk_state == TCP_CLOSE) && update_subflows = subflow->request_join || subflow->mp_join;
(subflow->request_join || subflow->mp_join);
if (!READ_ONCE(pm->work_pending) && !update_subflows) if (!READ_ONCE(pm->work_pending) && !update_subflows)
return; return;
spin_lock_bh(&pm->lock); spin_lock_bh(&pm->lock);
if (update_subflows) if (update_subflows)
pm->subflows--; __mptcp_pm_close_subflow(msk);
/* Even if this subflow is not really established, tell the PM to try /* Even if this subflow is not really established, tell the PM to try
* to pick the next ones, if possible. * to pick the next ones, if possible.
......
...@@ -833,6 +833,20 @@ unsigned int mptcp_pm_get_add_addr_accept_max(const struct mptcp_sock *msk); ...@@ -833,6 +833,20 @@ unsigned int mptcp_pm_get_add_addr_accept_max(const struct mptcp_sock *msk);
unsigned int mptcp_pm_get_subflows_max(const struct mptcp_sock *msk); unsigned int mptcp_pm_get_subflows_max(const struct mptcp_sock *msk);
unsigned int mptcp_pm_get_local_addr_max(const struct mptcp_sock *msk); unsigned int mptcp_pm_get_local_addr_max(const struct mptcp_sock *msk);
/* called under PM lock */
static inline void __mptcp_pm_close_subflow(struct mptcp_sock *msk)
{
if (--msk->pm.subflows < mptcp_pm_get_subflows_max(msk))
WRITE_ONCE(msk->pm.accept_subflow, true);
}
static inline void mptcp_pm_close_subflow(struct mptcp_sock *msk)
{
spin_lock_bh(&msk->pm.lock);
__mptcp_pm_close_subflow(msk);
spin_unlock_bh(&msk->pm.lock);
}
void mptcp_sockopt_sync(struct mptcp_sock *msk, struct sock *ssk); void mptcp_sockopt_sync(struct mptcp_sock *msk, struct sock *ssk);
void mptcp_sockopt_sync_locked(struct mptcp_sock *msk, struct sock *ssk); void mptcp_sockopt_sync_locked(struct mptcp_sock *msk, struct sock *ssk);
......
...@@ -1422,20 +1422,20 @@ int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc, ...@@ -1422,20 +1422,20 @@ int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
struct sockaddr_storage addr; struct sockaddr_storage addr;
int remote_id = remote->id; int remote_id = remote->id;
int local_id = loc->id; int local_id = loc->id;
int err = -ENOTCONN;
struct socket *sf; struct socket *sf;
struct sock *ssk; struct sock *ssk;
u32 remote_token; u32 remote_token;
int addrlen; int addrlen;
int ifindex; int ifindex;
u8 flags; u8 flags;
int err;
if (!mptcp_is_fully_established(sk)) if (!mptcp_is_fully_established(sk))
return -ENOTCONN; goto err_out;
err = mptcp_subflow_create_socket(sk, &sf); err = mptcp_subflow_create_socket(sk, &sf);
if (err) if (err)
return err; goto err_out;
ssk = sf->sk; ssk = sf->sk;
subflow = mptcp_subflow_ctx(ssk); subflow = mptcp_subflow_ctx(ssk);
...@@ -1492,6 +1492,12 @@ int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc, ...@@ -1492,6 +1492,12 @@ int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
failed: failed:
subflow->disposable = 1; subflow->disposable = 1;
sock_release(sf); sock_release(sf);
err_out:
/* we account subflows before the creation, and this failures will not
* be caught by sk_state_change()
*/
mptcp_pm_close_subflow(msk);
return err; return err;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册