[MPTCP][PATCH mptcp-next] Squash to "mptcp: use adding up size to get ADD_ADDR length"
by Geliang Tang
Drop the duplicate macro TCPOLEN_MPTCP_ADD_ADDR_HMAC, use MPTCPOPT_THMAC_LEN
instead.
Signed-off-by: Geliang Tang <geliangtang(a)gmail.com>
---
This patch will conflict with "mptcp: add the outgoing ADD_ADDR port
support", please fix the conflict like this:
static inline unsigned int mptcp_add_addr_len(int family, bool echo, bool port)
{
u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE;
if (family == AF_INET6)
len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
if (!echo)
<<<<<<< HEAD
len += MPTCPOPT_THMAC_LEN;
=======
len += TCPOLEN_MPTCP_ADD_ADDR_HMAC;
if (port)
len += TCPOLEN_MPTCP_PORT_LEN;
>>>>>>> 95a78f5e7ac1... mptcp: add the outgoing ADD_ADDR port support
return len;
}
->
static inline unsigned int mptcp_add_addr_len(int family, bool echo, bool port)
{
u8 len = TCPOLEN_MPTCP_ADD_ADDR_BASE;
if (family == AF_INET6)
len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
if (!echo)
len += MPTCPOPT_THMAC_LEN;
if (port)
len += TCPOLEN_MPTCP_PORT_LEN;
return len;
}
---
net/mptcp/protocol.h | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 0ca633c0475a..9315f6a8343a 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -57,7 +57,6 @@
#define TCPOLEN_MPTCP_ADD_ADDR6_BASE 20
#define TCPOLEN_MPTCP_ADD_ADDR6_BASE_PORT 24
#define TCPOLEN_MPTCP_PORT_LEN 4
-#define TCPOLEN_MPTCP_ADD_ADDR_HMAC 8
#define TCPOLEN_MPTCP_RM_ADDR_BASE 4
/* MPTCP MP_JOIN flags */
@@ -583,7 +582,7 @@ static inline unsigned int mptcp_add_addr_len(int family, bool echo)
if (family == AF_INET6)
len = TCPOLEN_MPTCP_ADD_ADDR6_BASE;
if (!echo)
- len += TCPOLEN_MPTCP_ADD_ADDR_HMAC;
+ len += MPTCPOPT_THMAC_LEN;
return len;
}
--
2.26.2
3 months
[PATCH mptcp-next] mptcp: address potential infinite loop on receive
by Paolo Abeni
Eric noted the MPTCP recvmsg() loop can iterate multiple
times when the argument lenght is 0 and some subflow is
feeding new data.
Be sure to quite the loop soon moving the exit condition
earlier. Additionally move a related comment into the
right place.
Reported-by: Eric Dumazet <eric.dumazet(a)gmail.com>
Fixes: ea4ca586b16f ("mptcp: refine MPTCP-level ack scheduling")
Signed-off-by: Paolo Abeni <pabeni(a)redhat.com>
---
Note: looking again at the current code, I think that at worst we
can do a single additional, unneeded iteration - after the first
'continue' statement __mptcp_move_skbs() will have moved some data
into the receive_queue, and we are not going to receive them. On
next iteration the receive_queue will be not empty.
Unless the peer is crafting some malicious DSS/packets combo I'm
unable to foreseen.
---
net/mptcp/protocol.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 221f7cdd416b..5a3f4bc38ee3 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -1933,21 +1933,21 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
copied += bytes_read;
- if (skb_queue_empty(&msk->receive_queue) &&
- __mptcp_move_skbs(msk, len - copied))
- continue;
-
/* be sure to advertise window change */
old_space = READ_ONCE(msk->old_wspace);
if ((tcp_space(sk) - old_space) >= old_space)
mptcp_cleanup_rbuf(msk);
- /* only the master socket status is relevant here. The exit
- * conditions mirror closely tcp_recvmsg()
- */
if (copied >= target)
break;
+ if (skb_queue_empty(&msk->receive_queue) &&
+ __mptcp_move_skbs(msk, len - copied))
+ continue;
+
+ /* only the master socket status is relevant here. The exit
+ * conditions mirror closely tcp_recvmsg()
+ */
if (copied) {
if (sk->sk_err ||
sk->sk_state == TCP_CLOSE ||
--
2.26.2
3 months
[PATCH net-next v2] mptcp: be careful on MPTCP-level ack.
by Paolo Abeni
We can enter the main mptcp_recvmsg() loop even when
no subflows are connected. As note by Eric, that would
result in a divide by zero oops on ack generation.
Address the issue by checking the subflow status before
sending the ack.
Additionally protect mptcp_recvmsg() against invocation
with weird socket states.
v1 -> v2:
- removed unneeded inline keyword - Jakub
Reported-and-suggested-by: Eric Dumazet <eric.dumazet(a)gmail.com>
Fixes: ea4ca586b16f ("mptcp: refine MPTCP-level ack scheduling")
Signed-off-by: Paolo Abeni <pabeni(a)redhat.com>
---
net/mptcp/protocol.c | 67 ++++++++++++++++++++++++++++++++------------
1 file changed, 49 insertions(+), 18 deletions(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 4b7794835fea..371a5e691a9a 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -419,31 +419,57 @@ static bool mptcp_subflow_active(struct mptcp_subflow_context *subflow)
return ((1 << ssk->sk_state) & (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT));
}
-static void mptcp_send_ack(struct mptcp_sock *msk, bool force)
+static bool tcp_can_send_ack(const struct sock *ssk)
+{
+ return !((1 << inet_sk_state_load(ssk)) &
+ (TCPF_SYN_SENT | TCPF_SYN_RECV | TCPF_TIME_WAIT | TCPF_CLOSE));
+}
+
+static void mptcp_send_ack(struct mptcp_sock *msk)
{
struct mptcp_subflow_context *subflow;
- struct sock *pick = NULL;
mptcp_for_each_subflow(msk, subflow) {
struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
- if (force) {
- lock_sock(ssk);
+ lock_sock(ssk);
+ if (tcp_can_send_ack(ssk))
tcp_send_ack(ssk);
- release_sock(ssk);
- continue;
- }
-
- /* if the hintes ssk is still active, use it */
- pick = ssk;
- if (ssk == msk->ack_hint)
- break;
+ release_sock(ssk);
}
- if (!force && pick) {
- lock_sock(pick);
- tcp_cleanup_rbuf(pick, 1);
- release_sock(pick);
+}
+
+static bool mptcp_subflow_cleanup_rbuf(struct sock *ssk)
+{
+ int ret;
+
+ lock_sock(ssk);
+ ret = tcp_can_send_ack(ssk);
+ if (ret)
+ tcp_cleanup_rbuf(ssk, 1);
+ release_sock(ssk);
+ return ret;
+}
+
+static void mptcp_cleanup_rbuf(struct mptcp_sock *msk)
+{
+ struct mptcp_subflow_context *subflow;
+
+ /* if the hinted ssk is still active, try to use it */
+ if (likely(msk->ack_hint)) {
+ mptcp_for_each_subflow(msk, subflow) {
+ struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
+
+ if (msk->ack_hint == ssk &&
+ mptcp_subflow_cleanup_rbuf(ssk))
+ return;
+ }
}
+
+ /* otherwise pick the first active subflow */
+ mptcp_for_each_subflow(msk, subflow)
+ if (mptcp_subflow_cleanup_rbuf(mptcp_subflow_tcp_sock(subflow)))
+ return;
}
static bool mptcp_check_data_fin(struct sock *sk)
@@ -494,7 +520,7 @@ static bool mptcp_check_data_fin(struct sock *sk)
ret = true;
mptcp_set_timeout(sk, NULL);
- mptcp_send_ack(msk, true);
+ mptcp_send_ack(msk);
mptcp_close_wake_up(sk);
}
return ret;
@@ -1579,6 +1605,11 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
return -EOPNOTSUPP;
lock_sock(sk);
+ if (unlikely(sk->sk_state == TCP_LISTEN)) {
+ copied = -ENOTCONN;
+ goto out_err;
+ }
+
timeo = sock_rcvtimeo(sk, nonblock);
len = min_t(size_t, len, INT_MAX);
@@ -1604,7 +1635,7 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
/* be sure to advertise window change */
old_space = READ_ONCE(msk->old_wspace);
if ((tcp_space(sk) - old_space) >= old_space)
- mptcp_send_ack(msk, false);
+ mptcp_cleanup_rbuf(msk);
/* only the master socket status is relevant here. The exit
* conditions mirror closely tcp_recvmsg()
--
2.26.2
3 months
[PATCH net-next 0/6] mptcp: avoid workqueue usage for data
by Paolo Abeni
The current locking schema used to protect the MPTCP data-path
requires the usage of the MPTCP workqueue to process the incoming
data, depending on trylock result.
The above poses scalability limits and introduces random delays
in MPTCP-level acks.
With this series we use a single spinlock to protect the MPTCP
data-path, removing the need for workqueue and delayed ack usage.
This additionally reduces the number of atomic operations required
per packet and cleans-up considerably the poll/wake-up code.
Paolo Abeni (6):
mptcp: open code mptcp variant for lock_sock
mptcp: implement wmem reservation
mptcp: protect the rx path with the msk socket spinlock
mptcp: allocate TX skbs in msk context
mptcp: avoid a few atomic ops in the rx path
mptcp: use mptcp release_cb for delayed tasks
include/net/sock.h | 1 +
net/core/sock.c | 2 +-
net/mptcp/mptcp_diag.c | 2 +-
net/mptcp/options.c | 47 +--
net/mptcp/protocol.c | 733 ++++++++++++++++++++++++++++++-----------
net/mptcp/protocol.h | 34 +-
net/mptcp/subflow.c | 14 +-
7 files changed, 598 insertions(+), 235 deletions(-)
--
2.26.2
3 months