Skip to content

Commit 8571da3

Browse files
Paolo Abenijenkins-tessares
Paolo Abeni
authored andcommitted
mptcp: move first subflow allocation at mpc access time
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 <[email protected]> Reviewed-by: Matthieu Baerts <[email protected]>
1 parent 8e4bc2d commit 8571da3

File tree

4 files changed

+54
-37
lines changed

4 files changed

+54
-37
lines changed

net/mptcp/pm_netlink.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,8 +1035,8 @@ static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
10351035
lock_sock(newsk);
10361036
ssock = __mptcp_nmpc_socket(mptcp_sk(newsk));
10371037
release_sock(newsk);
1038-
if (!ssock)
1039-
return -EINVAL;
1038+
if (IS_ERR(ssock))
1039+
return PTR_ERR(ssock);
10401040

10411041
mptcp_info2sockaddr(&entry->addr, &addr, entry->addr.family);
10421042
#if IS_ENABLED(CONFIG_MPTCP_IPV6)

net/mptcp/protocol.c

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,6 @@ static void __mptcp_check_send_data_fin(struct sock *sk);
4949
DEFINE_PER_CPU(struct mptcp_delegated_action, mptcp_delegated_actions);
5050
static struct net_device mptcp_napi_dev;
5151

52-
/* If msk has an initial subflow socket, and the MP_CAPABLE handshake has not
53-
* completed yet or has failed, return the subflow socket.
54-
* Otherwise return NULL.
55-
*/
56-
struct socket *__mptcp_nmpc_socket(const struct mptcp_sock *msk)
57-
{
58-
if (!msk->subflow || READ_ONCE(msk->can_ack))
59-
return NULL;
60-
61-
return msk->subflow;
62-
}
63-
6452
/* Returns end sequence number of the receiver's advertised window */
6553
static u64 mptcp_wnd_end(const struct mptcp_sock *msk)
6654
{
@@ -116,6 +104,31 @@ static int __mptcp_socket_create(struct mptcp_sock *msk)
116104
return 0;
117105
}
118106

107+
/* If the MPC handshake is not started, returns the first subflow,
108+
* eventually allocating it.
109+
*/
110+
struct socket *__mptcp_nmpc_socket(struct mptcp_sock *msk)
111+
{
112+
struct sock *sk = (struct sock *)msk;
113+
int ret;
114+
115+
if (!((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)))
116+
return ERR_PTR(-EINVAL);
117+
118+
if (!msk->subflow) {
119+
if (msk->first)
120+
return ERR_PTR(-EINVAL);
121+
122+
ret = __mptcp_socket_create(msk);
123+
if (ret)
124+
return ERR_PTR(ret);
125+
126+
mptcp_sockopt_sync(msk, msk->first);
127+
}
128+
129+
return msk->subflow;
130+
}
131+
119132
static void mptcp_drop(struct sock *sk, struct sk_buff *skb)
120133
{
121134
sk_drops_add(sk, skb);
@@ -1667,6 +1680,7 @@ static int mptcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
16671680
{
16681681
unsigned int saved_flags = msg->msg_flags;
16691682
struct mptcp_sock *msk = mptcp_sk(sk);
1683+
struct socket *ssock;
16701684
struct sock *ssk;
16711685
int ret;
16721686

@@ -1676,8 +1690,11 @@ static int mptcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
16761690
* Since the defer_connect flag is cleared after the first succsful
16771691
* fastopen attempt, no need to check for additional subflow status.
16781692
*/
1679-
if (msg->msg_flags & MSG_FASTOPEN && !__mptcp_nmpc_socket(msk))
1680-
return -EINVAL;
1693+
if (msg->msg_flags & MSG_FASTOPEN) {
1694+
ssock = __mptcp_nmpc_socket(msk);
1695+
if (IS_ERR(ssock))
1696+
return PTR_ERR(ssock);
1697+
}
16811698
if (!msk->first)
16821699
return -EINVAL;
16831700

@@ -2740,10 +2757,6 @@ static int mptcp_init_sock(struct sock *sk)
27402757
if (unlikely(!net->mib.mptcp_statistics) && !mptcp_mib_alloc(net))
27412758
return -ENOMEM;
27422759

2743-
ret = __mptcp_socket_create(mptcp_sk(sk));
2744-
if (ret)
2745-
return ret;
2746-
27472760
set_bit(SOCK_CUSTOM_SOCKOPT, &sk->sk_socket->flags);
27482761

27492762
/* fetch the ca name; do it outside __mptcp_init_sock(), so that clone will
@@ -3563,8 +3576,8 @@ static int mptcp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
35633576
int err = -EINVAL;
35643577

35653578
ssock = __mptcp_nmpc_socket(msk);
3566-
if (!ssock)
3567-
return -EINVAL;
3579+
if (IS_ERR(ssock))
3580+
return PTR_ERR(ssock);
35683581

35693582
mptcp_token_destroy(msk);
35703583
inet_sk_state_store(sk, TCP_SYN_SENT);
@@ -3652,8 +3665,8 @@ static int mptcp_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
36523665

36533666
lock_sock(sock->sk);
36543667
ssock = __mptcp_nmpc_socket(msk);
3655-
if (!ssock) {
3656-
err = -EINVAL;
3668+
if (IS_ERR(ssock)) {
3669+
err = PTR_ERR(ssock);
36573670
goto unlock;
36583671
}
36593672

@@ -3689,8 +3702,8 @@ static int mptcp_listen(struct socket *sock, int backlog)
36893702

36903703
lock_sock(sk);
36913704
ssock = __mptcp_nmpc_socket(msk);
3692-
if (!ssock) {
3693-
err = -EINVAL;
3705+
if (IS_ERR(ssock)) {
3706+
err = PTR_ERR(ssock);
36943707
goto unlock;
36953708
}
36963709

net/mptcp/protocol.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -630,7 +630,7 @@ void mptcp_close_ssk(struct sock *sk, struct sock *ssk,
630630
void __mptcp_subflow_send_ack(struct sock *ssk);
631631
void mptcp_subflow_reset(struct sock *ssk);
632632
void mptcp_sock_graft(struct sock *sk, struct socket *parent);
633-
struct socket *__mptcp_nmpc_socket(const struct mptcp_sock *msk);
633+
struct socket *__mptcp_nmpc_socket(struct mptcp_sock *msk);
634634
bool __mptcp_close(struct sock *sk, long timeout);
635635
void mptcp_cancel_work(struct sock *sk);
636636
void mptcp_set_owner_r(struct sk_buff *skb, struct sock *sk);

net/mptcp/sockopt.c

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -301,9 +301,9 @@ static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname,
301301
case SO_BINDTOIFINDEX:
302302
lock_sock(sk);
303303
ssock = __mptcp_nmpc_socket(msk);
304-
if (!ssock) {
304+
if (IS_ERR(ssock)) {
305305
release_sock(sk);
306-
return -EINVAL;
306+
return PTR_ERR(ssock);
307307
}
308308

309309
ret = sock_setsockopt(ssock, SOL_SOCKET, optname, optval, optlen);
@@ -396,9 +396,9 @@ static int mptcp_setsockopt_v6(struct mptcp_sock *msk, int optname,
396396
case IPV6_FREEBIND:
397397
lock_sock(sk);
398398
ssock = __mptcp_nmpc_socket(msk);
399-
if (!ssock) {
399+
if (IS_ERR(ssock)) {
400400
release_sock(sk);
401-
return -EINVAL;
401+
return PTR_ERR(ssock);
402402
}
403403

404404
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
693693
lock_sock(sk);
694694

695695
ssock = __mptcp_nmpc_socket(msk);
696-
if (!ssock) {
696+
if (IS_ERR(ssock)) {
697697
release_sock(sk);
698-
return -EINVAL;
698+
return PTR_ERR(ssock);
699699
}
700700

701701
issk = inet_sk(ssock->sk);
@@ -762,13 +762,15 @@ static int mptcp_setsockopt_first_sf_only(struct mptcp_sock *msk, int level, int
762762
{
763763
struct sock *sk = (struct sock *)msk;
764764
struct socket *sock;
765-
int ret = -EINVAL;
765+
int ret;
766766

767767
/* Limit to first subflow, before the connection establishment */
768768
lock_sock(sk);
769769
sock = __mptcp_nmpc_socket(msk);
770-
if (!sock)
770+
if (IS_ERR(sock)) {
771+
ret = PTR_ERR(sock);
771772
goto unlock;
773+
}
772774

773775
ret = tcp_setsockopt(sock->sk, level, optname, optval, optlen);
774776

@@ -861,7 +863,7 @@ static int mptcp_getsockopt_first_sf_only(struct mptcp_sock *msk, int level, int
861863
{
862864
struct sock *sk = (struct sock *)msk;
863865
struct socket *ssock;
864-
int ret = -EINVAL;
866+
int ret;
865867
struct sock *ssk;
866868

867869
lock_sock(sk);
@@ -872,8 +874,10 @@ static int mptcp_getsockopt_first_sf_only(struct mptcp_sock *msk, int level, int
872874
}
873875

874876
ssock = __mptcp_nmpc_socket(msk);
875-
if (!ssock)
877+
if (IS_ERR(ssock)) {
878+
ret = PTR_ERR(ssock);
876879
goto out;
880+
}
877881

878882
ret = tcp_getsockopt(ssock->sk, level, optname, optval, optlen);
879883

0 commit comments

Comments
 (0)