* [PATCH mptcp-next v6 1/9] mptcp: don't send RST for single subflow
2021-09-29 7:34 [PATCH mptcp-next v6 0/9] The infinite mapping support Geliang Tang
@ 2021-09-29 7:34 ` Geliang Tang
2021-09-29 7:35 ` [PATCH mptcp-next v6 2/9] mptcp: add the fallback check Geliang Tang
` (7 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Geliang Tang @ 2021-09-29 7:34 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
When a bad checksum is detected and a single subflow is in use, don't
send RST + MP_FAIL, send data_ack + MP_FAIL instead.
Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
net/mptcp/subflow.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index 6172f380dfb7..92b45a7c997e 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -1167,14 +1167,14 @@ static bool subflow_check_data_avail(struct sock *ssk)
/* RFC 8684 section 3.7. */
if (subflow->send_mp_fail) {
if (mptcp_has_another_subflow(ssk)) {
+ ssk->sk_err = EBADMSG;
+ tcp_set_state(ssk, TCP_CLOSE);
+ subflow->reset_transient = 0;
+ subflow->reset_reason = MPTCP_RST_EMIDDLEBOX;
+ tcp_send_active_reset(ssk, GFP_ATOMIC);
while ((skb = skb_peek(&ssk->sk_receive_queue)))
sk_eat_skb(ssk, skb);
}
- ssk->sk_err = EBADMSG;
- tcp_set_state(ssk, TCP_CLOSE);
- subflow->reset_transient = 0;
- subflow->reset_reason = MPTCP_RST_EMIDDLEBOX;
- tcp_send_active_reset(ssk, GFP_ATOMIC);
WRITE_ONCE(subflow->data_avail, 0);
return true;
}
--
2.31.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH mptcp-next v6 2/9] mptcp: add the fallback check
2021-09-29 7:34 [PATCH mptcp-next v6 0/9] The infinite mapping support Geliang Tang
2021-09-29 7:34 ` [PATCH mptcp-next v6 1/9] mptcp: don't send RST for single subflow Geliang Tang
@ 2021-09-29 7:35 ` Geliang Tang
2021-09-29 7:35 ` [PATCH mptcp-next v6 3/9] mptcp: track and update contiguous data status Geliang Tang
` (6 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Geliang Tang @ 2021-09-29 7:35 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang, Paolo Abeni
This patch added the fallback check in subflow_check_data_avail. Only do
the fallback when the msk isn't fallen back yet.
Suggested-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
net/mptcp/subflow.c | 45 ++++++++++++++++++++++++---------------------
1 file changed, 24 insertions(+), 21 deletions(-)
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index 92b45a7c997e..87a9ffebcc42 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -1164,35 +1164,38 @@ static bool subflow_check_data_avail(struct sock *ssk)
return false;
fallback:
- /* RFC 8684 section 3.7. */
- if (subflow->send_mp_fail) {
- if (mptcp_has_another_subflow(ssk)) {
+ if (!__mptcp_check_fallback(msk)) {
+ /* RFC 8684 section 3.7. */
+ if (subflow->send_mp_fail) {
+ if (mptcp_has_another_subflow(ssk)) {
+ ssk->sk_err = EBADMSG;
+ tcp_set_state(ssk, TCP_CLOSE);
+ subflow->reset_transient = 0;
+ subflow->reset_reason = MPTCP_RST_EMIDDLEBOX;
+ tcp_send_active_reset(ssk, GFP_ATOMIC);
+ while ((skb = skb_peek(&ssk->sk_receive_queue)))
+ sk_eat_skb(ssk, skb);
+ }
+ WRITE_ONCE(subflow->data_avail, 0);
+ return true;
+ }
+
+ if (subflow->mp_join || subflow->fully_established) {
+ /* fatal protocol error, close the socket.
+ * subflow_error_report() will introduce the appropriate barriers
+ */
ssk->sk_err = EBADMSG;
tcp_set_state(ssk, TCP_CLOSE);
subflow->reset_transient = 0;
- subflow->reset_reason = MPTCP_RST_EMIDDLEBOX;
+ subflow->reset_reason = MPTCP_RST_EMPTCP;
tcp_send_active_reset(ssk, GFP_ATOMIC);
- while ((skb = skb_peek(&ssk->sk_receive_queue)))
- sk_eat_skb(ssk, skb);
+ WRITE_ONCE(subflow->data_avail, 0);
+ return false;
}
- WRITE_ONCE(subflow->data_avail, 0);
- return true;
- }
- if (subflow->mp_join || subflow->fully_established) {
- /* fatal protocol error, close the socket.
- * subflow_error_report() will introduce the appropriate barriers
- */
- ssk->sk_err = EBADMSG;
- tcp_set_state(ssk, TCP_CLOSE);
- subflow->reset_transient = 0;
- subflow->reset_reason = MPTCP_RST_EMPTCP;
- tcp_send_active_reset(ssk, GFP_ATOMIC);
- WRITE_ONCE(subflow->data_avail, 0);
- return false;
+ __mptcp_do_fallback(msk);
}
- __mptcp_do_fallback(msk);
skb = skb_peek(&ssk->sk_receive_queue);
subflow->map_valid = 1;
subflow->map_seq = READ_ONCE(msk->ack_seq);
--
2.31.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH mptcp-next v6 3/9] mptcp: track and update contiguous data status
2021-09-29 7:34 [PATCH mptcp-next v6 0/9] The infinite mapping support Geliang Tang
2021-09-29 7:34 ` [PATCH mptcp-next v6 1/9] mptcp: don't send RST for single subflow Geliang Tang
2021-09-29 7:35 ` [PATCH mptcp-next v6 2/9] mptcp: add the fallback check Geliang Tang
@ 2021-09-29 7:35 ` Geliang Tang
2021-09-29 22:12 ` Mat Martineau
2021-09-29 7:35 ` [PATCH mptcp-next v6 4/9] mptcp: add last_ack_dss_start in the msk Geliang Tang
` (5 subsequent siblings)
8 siblings, 1 reply; 13+ messages in thread
From: Geliang Tang @ 2021-09-29 7:35 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang, Paolo Abeni
This patch added a new member allow_infinite_fallback in mptcp_sock,
which gets initialized to 'true' when the connection begins and is set
to 'false' on any retransmit or successful MP_JOIN.
Rename the helper function mptcp_is_data_contiguous() to
mptcp_allow_infinite_fallback(). In it, only do infinite mapping fallback
if there is a single subflow AND there have been no retransmissions AND
there have never been any MP_JOINs.
Suggested-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
net/mptcp/protocol.c | 2 ++
net/mptcp/protocol.h | 10 +++++++---
net/mptcp/subflow.c | 2 +-
3 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index f8ad049d6941..48979cb82126 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -2464,6 +2464,7 @@ static void __mptcp_retrans(struct sock *sk)
dfrag->already_sent = max(dfrag->already_sent, info.sent);
tcp_push(ssk, 0, info.mss_now, tcp_sk(ssk)->nonagle,
info.size_goal);
+ WRITE_ONCE(msk->allow_infinite_fallback, false);
}
release_sock(ssk);
@@ -2542,6 +2543,7 @@ static int __mptcp_init_sock(struct sock *sk)
msk->first = NULL;
inet_csk(sk)->icsk_sync_mss = mptcp_sync_mss;
WRITE_ONCE(msk->csum_enabled, mptcp_is_checksum_enabled(sock_net(sk)));
+ WRITE_ONCE(msk->allow_infinite_fallback, true);
msk->recovery = false;
mptcp_pm_data_init(msk);
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 7379ab580a7e..4807e486e762 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -249,6 +249,7 @@ struct mptcp_sock {
bool rcv_fastclose;
bool use_64bit_ack; /* Set when we received a 64-bit DSN */
bool csum_enabled;
+ bool allow_infinite_fallback;
spinlock_t join_list_lock;
struct work_struct work;
struct sk_buff *ooo_last_skb;
@@ -612,17 +613,20 @@ static inline void mptcp_subflow_tcp_fallback(struct sock *sk,
inet_csk(sk)->icsk_af_ops = ctx->icsk_af_ops;
}
-static inline bool mptcp_has_another_subflow(struct sock *ssk)
+static inline bool mptcp_allow_infinite_fallback(struct sock *ssk)
{
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk), *tmp;
struct mptcp_sock *msk = mptcp_sk(subflow->conn);
mptcp_for_each_subflow(msk, tmp) {
+ if (tmp->mp_join)
+ return false;
+
if (tmp != subflow)
- return true;
+ return false;
}
- return false;
+ return READ_ONCE(msk->allow_infinite_fallback);
}
void __init mptcp_proto_init(void);
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index 87a9ffebcc42..28ed7dc6e170 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -1167,7 +1167,7 @@ static bool subflow_check_data_avail(struct sock *ssk)
if (!__mptcp_check_fallback(msk)) {
/* RFC 8684 section 3.7. */
if (subflow->send_mp_fail) {
- if (mptcp_has_another_subflow(ssk)) {
+ if (!mptcp_allow_infinite_fallback(ssk)) {
ssk->sk_err = EBADMSG;
tcp_set_state(ssk, TCP_CLOSE);
subflow->reset_transient = 0;
--
2.31.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH mptcp-next v6 3/9] mptcp: track and update contiguous data status
2021-09-29 7:35 ` [PATCH mptcp-next v6 3/9] mptcp: track and update contiguous data status Geliang Tang
@ 2021-09-29 22:12 ` Mat Martineau
0 siblings, 0 replies; 13+ messages in thread
From: Mat Martineau @ 2021-09-29 22:12 UTC (permalink / raw)
To: Geliang Tang; +Cc: mptcp, Paolo Abeni
On Wed, 29 Sep 2021, Geliang Tang wrote:
> This patch added a new member allow_infinite_fallback in mptcp_sock,
> which gets initialized to 'true' when the connection begins and is set
> to 'false' on any retransmit or successful MP_JOIN.
>
> Rename the helper function mptcp_is_data_contiguous() to
> mptcp_allow_infinite_fallback(). In it, only do infinite mapping fallback
> if there is a single subflow AND there have been no retransmissions AND
> there have never been any MP_JOINs.
>
> Suggested-by: Paolo Abeni <pabeni@redhat.com>
> Signed-off-by: Geliang Tang <geliangtang@gmail.com>
> ---
> net/mptcp/protocol.c | 2 ++
> net/mptcp/protocol.h | 10 +++++++---
> net/mptcp/subflow.c | 2 +-
> 3 files changed, 10 insertions(+), 4 deletions(-)
>
> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
> index f8ad049d6941..48979cb82126 100644
> --- a/net/mptcp/protocol.c
> +++ b/net/mptcp/protocol.c
> @@ -2464,6 +2464,7 @@ static void __mptcp_retrans(struct sock *sk)
> dfrag->already_sent = max(dfrag->already_sent, info.sent);
> tcp_push(ssk, 0, info.mss_now, tcp_sk(ssk)->nonagle,
> info.size_goal);
> + WRITE_ONCE(msk->allow_infinite_fallback, false);
> }
>
> release_sock(ssk);
> @@ -2542,6 +2543,7 @@ static int __mptcp_init_sock(struct sock *sk)
> msk->first = NULL;
> inet_csk(sk)->icsk_sync_mss = mptcp_sync_mss;
> WRITE_ONCE(msk->csum_enabled, mptcp_is_checksum_enabled(sock_net(sk)));
> + WRITE_ONCE(msk->allow_infinite_fallback, true);
> msk->recovery = false;
>
> mptcp_pm_data_init(msk);
> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> index 7379ab580a7e..4807e486e762 100644
> --- a/net/mptcp/protocol.h
> +++ b/net/mptcp/protocol.h
> @@ -249,6 +249,7 @@ struct mptcp_sock {
> bool rcv_fastclose;
> bool use_64bit_ack; /* Set when we received a 64-bit DSN */
> bool csum_enabled;
> + bool allow_infinite_fallback;
> spinlock_t join_list_lock;
> struct work_struct work;
> struct sk_buff *ooo_last_skb;
> @@ -612,17 +613,20 @@ static inline void mptcp_subflow_tcp_fallback(struct sock *sk,
> inet_csk(sk)->icsk_af_ops = ctx->icsk_af_ops;
> }
>
> -static inline bool mptcp_has_another_subflow(struct sock *ssk)
> +static inline bool mptcp_allow_infinite_fallback(struct sock *ssk)
> {
> struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk), *tmp;
> struct mptcp_sock *msk = mptcp_sk(subflow->conn);
>
> mptcp_for_each_subflow(msk, tmp) {
> + if (tmp->mp_join)
> + return false;
> +
> if (tmp != subflow)
> - return true;
> + return false;
Sorry I missed your patch-1 v5 reply yesterday! I think it's better for
now to implement the simpler check discussed in the meeting last week and
in the v5 review, which is to set allow_infinite_fallback = false when a
join happens (in mptcp_finish_join() and __mptcp_subflow_connect()). Then
there's no need to iterate over the subflows here.
We don't have a good answer yet for how to guarantee a subflow and the
MPTCP-level stream are in a correct state to fallback *after*
retransmissions or joins, so I think it's important to get this
single-subflow infinite mapping working and tests implemented first. There
must be absolute certainty that fallback will not corrupt the application
data stream.
Mat
> }
>
> - return false;
> + return READ_ONCE(msk->allow_infinite_fallback);
> }
>
> void __init mptcp_proto_init(void);
> diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
> index 87a9ffebcc42..28ed7dc6e170 100644
> --- a/net/mptcp/subflow.c
> +++ b/net/mptcp/subflow.c
> @@ -1167,7 +1167,7 @@ static bool subflow_check_data_avail(struct sock *ssk)
> if (!__mptcp_check_fallback(msk)) {
> /* RFC 8684 section 3.7. */
> if (subflow->send_mp_fail) {
> - if (mptcp_has_another_subflow(ssk)) {
> + if (!mptcp_allow_infinite_fallback(ssk)) {
> ssk->sk_err = EBADMSG;
> tcp_set_state(ssk, TCP_CLOSE);
> subflow->reset_transient = 0;
> --
> 2.31.1
>
>
>
--
Mat Martineau
Intel
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH mptcp-next v6 4/9] mptcp: add last_ack_dss_start in the msk
2021-09-29 7:34 [PATCH mptcp-next v6 0/9] The infinite mapping support Geliang Tang
` (2 preceding siblings ...)
2021-09-29 7:35 ` [PATCH mptcp-next v6 3/9] mptcp: track and update contiguous data status Geliang Tang
@ 2021-09-29 7:35 ` Geliang Tang
2021-09-29 22:13 ` Mat Martineau
2021-09-29 7:35 ` [PATCH mptcp-next v6 5/9] mptcp: infinite mapping sending Geliang Tang
` (4 subsequent siblings)
8 siblings, 1 reply; 13+ messages in thread
From: Geliang Tang @ 2021-09-29 7:35 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang, Paolo Abeni
This patch added a new member named last_ack_dss_start to the msk to
keep track of the beginning of the last fully-acked data segment. This
would be updated in __mptcp_clean_una.
Suggested-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
net/mptcp/protocol.c | 3 +++
net/mptcp/protocol.h | 1 +
2 files changed, 4 insertions(+)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 48979cb82126..334bbce69fcb 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -1071,6 +1071,7 @@ static void __mptcp_clean_una(struct sock *sk)
WRITE_ONCE(msk->first_pending, mptcp_send_next(sk));
}
+ msk->last_ack_dss_start = dfrag->data_seq;
dfrag_clear(sk, dfrag);
cleaned = true;
}
@@ -2891,6 +2892,7 @@ struct sock *mptcp_sk_clone(const struct sock *sk,
msk->snd_una = msk->write_seq;
msk->wnd_end = msk->snd_nxt + req->rsk_rcv_wnd;
msk->setsockopt_seq = mptcp_sk(sk)->setsockopt_seq;
+ msk->last_ack_dss_start = subflow_req->idsn - 1;
if (mp_opt->suboptions & OPTIONS_MPTCP_MPC) {
msk->can_ack = true;
@@ -3147,6 +3149,7 @@ void mptcp_finish_connect(struct sock *ssk)
WRITE_ONCE(msk->rcv_wnd_sent, ack_seq);
WRITE_ONCE(msk->can_ack, 1);
WRITE_ONCE(msk->snd_una, msk->write_seq);
+ WRITE_ONCE(msk->last_ack_dss_start, subflow->idsn - 1);
mptcp_pm_new_connection(msk, ssk, 0);
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 4807e486e762..7927acf53f06 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -224,6 +224,7 @@ struct mptcp_sock {
u64 remote_key;
u64 write_seq;
u64 snd_nxt;
+ u64 last_ack_dss_start;
u64 ack_seq;
u64 rcv_wnd_sent;
u64 rcv_data_fin_seq;
--
2.31.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH mptcp-next v6 4/9] mptcp: add last_ack_dss_start in the msk
2021-09-29 7:35 ` [PATCH mptcp-next v6 4/9] mptcp: add last_ack_dss_start in the msk Geliang Tang
@ 2021-09-29 22:13 ` Mat Martineau
0 siblings, 0 replies; 13+ messages in thread
From: Mat Martineau @ 2021-09-29 22:13 UTC (permalink / raw)
To: Geliang Tang; +Cc: mptcp, Paolo Abeni
On Wed, 29 Sep 2021, Geliang Tang wrote:
> This patch added a new member named last_ack_dss_start to the msk to
> keep track of the beginning of the last fully-acked data segment. This
> would be updated in __mptcp_clean_una.
>
Can drop this patch, see patch 5 reply for more details.
Mat
> Suggested-by: Paolo Abeni <pabeni@redhat.com>
> Signed-off-by: Geliang Tang <geliangtang@gmail.com>
> ---
> net/mptcp/protocol.c | 3 +++
> net/mptcp/protocol.h | 1 +
> 2 files changed, 4 insertions(+)
>
> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
> index 48979cb82126..334bbce69fcb 100644
> --- a/net/mptcp/protocol.c
> +++ b/net/mptcp/protocol.c
> @@ -1071,6 +1071,7 @@ static void __mptcp_clean_una(struct sock *sk)
> WRITE_ONCE(msk->first_pending, mptcp_send_next(sk));
> }
>
> + msk->last_ack_dss_start = dfrag->data_seq;
> dfrag_clear(sk, dfrag);
> cleaned = true;
> }
> @@ -2891,6 +2892,7 @@ struct sock *mptcp_sk_clone(const struct sock *sk,
> msk->snd_una = msk->write_seq;
> msk->wnd_end = msk->snd_nxt + req->rsk_rcv_wnd;
> msk->setsockopt_seq = mptcp_sk(sk)->setsockopt_seq;
> + msk->last_ack_dss_start = subflow_req->idsn - 1;
>
> if (mp_opt->suboptions & OPTIONS_MPTCP_MPC) {
> msk->can_ack = true;
> @@ -3147,6 +3149,7 @@ void mptcp_finish_connect(struct sock *ssk)
> WRITE_ONCE(msk->rcv_wnd_sent, ack_seq);
> WRITE_ONCE(msk->can_ack, 1);
> WRITE_ONCE(msk->snd_una, msk->write_seq);
> + WRITE_ONCE(msk->last_ack_dss_start, subflow->idsn - 1);
>
> mptcp_pm_new_connection(msk, ssk, 0);
>
> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> index 4807e486e762..7927acf53f06 100644
> --- a/net/mptcp/protocol.h
> +++ b/net/mptcp/protocol.h
> @@ -224,6 +224,7 @@ struct mptcp_sock {
> u64 remote_key;
> u64 write_seq;
> u64 snd_nxt;
> + u64 last_ack_dss_start;
> u64 ack_seq;
> u64 rcv_wnd_sent;
> u64 rcv_data_fin_seq;
> --
> 2.31.1
>
>
>
--
Mat Martineau
Intel
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH mptcp-next v6 5/9] mptcp: infinite mapping sending
2021-09-29 7:34 [PATCH mptcp-next v6 0/9] The infinite mapping support Geliang Tang
` (3 preceding siblings ...)
2021-09-29 7:35 ` [PATCH mptcp-next v6 4/9] mptcp: add last_ack_dss_start in the msk Geliang Tang
@ 2021-09-29 7:35 ` Geliang Tang
2021-09-29 22:16 ` Mat Martineau
2021-09-29 7:35 ` [PATCH mptcp-next v6 6/9] mptcp: infinite mapping receiving Geliang Tang
` (3 subsequent siblings)
8 siblings, 1 reply; 13+ messages in thread
From: Geliang Tang @ 2021-09-29 7:35 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang, Paolo Abeni
This patch added the infinite mapping sending logic.
Added a new flag send_infinite_map in struct mptcp_subflow_context. Set
it true when a single contiguous subflow is in use in
mptcp_pm_mp_fail_received.
In mptcp_sendmsg_frag, if this flag is true, call the new function
mptcp_update_infinite_map to set the infinite mapping.
Suggested-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
include/net/mptcp.h | 3 ++-
net/mptcp/options.c | 2 +-
net/mptcp/pm.c | 5 +++++
net/mptcp/protocol.c | 19 +++++++++++++++++++
net/mptcp/protocol.h | 12 ++++++++++++
5 files changed, 39 insertions(+), 2 deletions(-)
diff --git a/include/net/mptcp.h b/include/net/mptcp.h
index f83fa48408b3..29e930540ea2 100644
--- a/include/net/mptcp.h
+++ b/include/net/mptcp.h
@@ -35,7 +35,8 @@ struct mptcp_ext {
frozen:1,
reset_transient:1;
u8 reset_reason:4,
- csum_reqd:1;
+ csum_reqd:1,
+ infinite_map:1;
};
#define MPTCP_RM_IDS_MAX 8
diff --git a/net/mptcp/options.c b/net/mptcp/options.c
index 422f4acfb3e6..f4591421ed22 100644
--- a/net/mptcp/options.c
+++ b/net/mptcp/options.c
@@ -816,7 +816,7 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
opts->suboptions = 0;
- if (unlikely(__mptcp_check_fallback(msk)))
+ if (unlikely(__mptcp_check_fallback(msk) && !mptcp_check_infinite_map(skb)))
return false;
if (unlikely(skb && TCP_SKB_CB(skb)->tcp_flags & TCPHDR_RST)) {
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index 6ab386ff3294..5b99c0c9c17e 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -251,7 +251,12 @@ void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup)
void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq)
{
+ struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
+
pr_debug("fail_seq=%llu", fail_seq);
+
+ if (mptcp_allow_infinite_fallback(sk))
+ subflow->send_infinite_map = 1;
}
/* path manager helpers */
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 334bbce69fcb..5b73493c75c5 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -1274,6 +1274,23 @@ static void mptcp_update_data_checksum(struct sk_buff *skb, int added)
mpext->csum = csum_fold(csum_block_add(csum, skb_checksum(skb, offset, added, 0), offset));
}
+static void mptcp_update_infinite_map(struct mptcp_sock *msk, struct sock *ssk,
+ struct mptcp_ext *mpext)
+{
+ if (!mpext)
+ return;
+
+ mpext->infinite_map = 1;
+ mpext->data_seq = READ_ONCE(msk->last_ack_dss_start);
+ mpext->subflow_seq = 0;
+ mpext->data_len = 0;
+ mpext->csum = 0;
+
+ mptcp_subflow_ctx(ssk)->send_infinite_map = 0;
+ pr_fallback(msk);
+ __mptcp_do_fallback(msk);
+}
+
static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
struct mptcp_data_frag *dfrag,
struct mptcp_sendmsg_info *info)
@@ -1406,6 +1423,8 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
out:
if (READ_ONCE(msk->csum_enabled))
mptcp_update_data_checksum(skb, copy);
+ if (mptcp_subflow_ctx(ssk)->send_infinite_map)
+ mptcp_update_infinite_map(msk, ssk, mpext);
mptcp_subflow_ctx(ssk)->rel_write_seq += copy;
return copy;
}
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 7927acf53f06..9da4dd3b2e2d 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -433,6 +433,7 @@ struct mptcp_subflow_context {
backup : 1,
send_mp_prio : 1,
send_mp_fail : 1,
+ send_infinite_map : 1,
rx_eof : 1,
can_ack : 1, /* only after processing the remote a key */
disposable : 1, /* ctx can be free at ulp release time */
@@ -872,6 +873,17 @@ static inline void mptcp_do_fallback(struct sock *sk)
#define pr_fallback(a) pr_debug("%s:fallback to TCP (msk=%p)", __func__, a)
+static inline bool mptcp_check_infinite_map(struct sk_buff *skb)
+{
+ struct mptcp_ext *mpext;
+
+ mpext = skb ? mptcp_get_ext(skb) : NULL;
+ if (mpext && mpext->infinite_map)
+ return true;
+
+ return false;
+}
+
static inline bool subflow_simultaneous_connect(struct sock *sk)
{
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
--
2.31.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH mptcp-next v6 5/9] mptcp: infinite mapping sending
2021-09-29 7:35 ` [PATCH mptcp-next v6 5/9] mptcp: infinite mapping sending Geliang Tang
@ 2021-09-29 22:16 ` Mat Martineau
0 siblings, 0 replies; 13+ messages in thread
From: Mat Martineau @ 2021-09-29 22:16 UTC (permalink / raw)
To: Geliang Tang; +Cc: mptcp, Paolo Abeni
On Wed, 29 Sep 2021, Geliang Tang wrote:
> This patch added the infinite mapping sending logic.
>
> Added a new flag send_infinite_map in struct mptcp_subflow_context. Set
> it true when a single contiguous subflow is in use in
> mptcp_pm_mp_fail_received.
>
> In mptcp_sendmsg_frag, if this flag is true, call the new function
> mptcp_update_infinite_map to set the infinite mapping.
>
> Suggested-by: Paolo Abeni <pabeni@redhat.com>
> Signed-off-by: Geliang Tang <geliangtang@gmail.com>
> ---
> include/net/mptcp.h | 3 ++-
> net/mptcp/options.c | 2 +-
> net/mptcp/pm.c | 5 +++++
> net/mptcp/protocol.c | 19 +++++++++++++++++++
> net/mptcp/protocol.h | 12 ++++++++++++
> 5 files changed, 39 insertions(+), 2 deletions(-)
>
> diff --git a/include/net/mptcp.h b/include/net/mptcp.h
> index f83fa48408b3..29e930540ea2 100644
> --- a/include/net/mptcp.h
> +++ b/include/net/mptcp.h
> @@ -35,7 +35,8 @@ struct mptcp_ext {
> frozen:1,
> reset_transient:1;
> u8 reset_reason:4,
> - csum_reqd:1;
> + csum_reqd:1,
> + infinite_map:1;
> };
>
> #define MPTCP_RM_IDS_MAX 8
> diff --git a/net/mptcp/options.c b/net/mptcp/options.c
> index 422f4acfb3e6..f4591421ed22 100644
> --- a/net/mptcp/options.c
> +++ b/net/mptcp/options.c
> @@ -816,7 +816,7 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
>
> opts->suboptions = 0;
>
> - if (unlikely(__mptcp_check_fallback(msk)))
> + if (unlikely(__mptcp_check_fallback(msk) && !mptcp_check_infinite_map(skb)))
> return false;
>
> if (unlikely(skb && TCP_SKB_CB(skb)->tcp_flags & TCPHDR_RST)) {
> diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
> index 6ab386ff3294..5b99c0c9c17e 100644
> --- a/net/mptcp/pm.c
> +++ b/net/mptcp/pm.c
> @@ -251,7 +251,12 @@ void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup)
>
> void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq)
> {
> + struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
> +
> pr_debug("fail_seq=%llu", fail_seq);
> +
> + if (mptcp_allow_infinite_fallback(sk))
> + subflow->send_infinite_map = 1;
> }
>
> /* path manager helpers */
> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
> index 334bbce69fcb..5b73493c75c5 100644
> --- a/net/mptcp/protocol.c
> +++ b/net/mptcp/protocol.c
> @@ -1274,6 +1274,23 @@ static void mptcp_update_data_checksum(struct sk_buff *skb, int added)
> mpext->csum = csum_fold(csum_block_add(csum, skb_checksum(skb, offset, added, 0), offset));
> }
>
> +static void mptcp_update_infinite_map(struct mptcp_sock *msk, struct sock *ssk,
> + struct mptcp_ext *mpext)
> +{
> + if (!mpext)
> + return;
> +
> + mpext->infinite_map = 1;
> + mpext->data_seq = READ_ONCE(msk->last_ack_dss_start);
> + mpext->subflow_seq = 0;
To match up with Christoph's reply from a couple of days ago (if I'm
reading it right), I think you just delete the above 2 lines so data_seq
and subflow_seq are unmodified from the values they were set to in
mptcp_sendmsg_frag().
Mat
> + mpext->data_len = 0;
> + mpext->csum = 0;
> +
> + mptcp_subflow_ctx(ssk)->send_infinite_map = 0;
> + pr_fallback(msk);
> + __mptcp_do_fallback(msk);
> +}
> +
> static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
> struct mptcp_data_frag *dfrag,
> struct mptcp_sendmsg_info *info)
> @@ -1406,6 +1423,8 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
> out:
> if (READ_ONCE(msk->csum_enabled))
> mptcp_update_data_checksum(skb, copy);
> + if (mptcp_subflow_ctx(ssk)->send_infinite_map)
> + mptcp_update_infinite_map(msk, ssk, mpext);
> mptcp_subflow_ctx(ssk)->rel_write_seq += copy;
> return copy;
> }
> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> index 7927acf53f06..9da4dd3b2e2d 100644
> --- a/net/mptcp/protocol.h
> +++ b/net/mptcp/protocol.h
> @@ -433,6 +433,7 @@ struct mptcp_subflow_context {
> backup : 1,
> send_mp_prio : 1,
> send_mp_fail : 1,
> + send_infinite_map : 1,
> rx_eof : 1,
> can_ack : 1, /* only after processing the remote a key */
> disposable : 1, /* ctx can be free at ulp release time */
> @@ -872,6 +873,17 @@ static inline void mptcp_do_fallback(struct sock *sk)
>
> #define pr_fallback(a) pr_debug("%s:fallback to TCP (msk=%p)", __func__, a)
>
> +static inline bool mptcp_check_infinite_map(struct sk_buff *skb)
> +{
> + struct mptcp_ext *mpext;
> +
> + mpext = skb ? mptcp_get_ext(skb) : NULL;
> + if (mpext && mpext->infinite_map)
> + return true;
> +
> + return false;
> +}
> +
> static inline bool subflow_simultaneous_connect(struct sock *sk)
> {
> struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
> --
> 2.31.1
>
>
>
--
Mat Martineau
Intel
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH mptcp-next v6 6/9] mptcp: infinite mapping receiving
2021-09-29 7:34 [PATCH mptcp-next v6 0/9] The infinite mapping support Geliang Tang
` (4 preceding siblings ...)
2021-09-29 7:35 ` [PATCH mptcp-next v6 5/9] mptcp: infinite mapping sending Geliang Tang
@ 2021-09-29 7:35 ` Geliang Tang
2021-09-29 7:35 ` [PATCH mptcp-next v6 7/9] mptcp: add mib for infinite map sending Geliang Tang
` (2 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Geliang Tang @ 2021-09-29 7:35 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang, Paolo Abeni
This patch added the infinite mapping receiving logic. When the infinite
mapping is received, set the map_data_len of the subflow to 0.
In subflow_check_data_avail, only reset the subflow when the map_data_len
of the subflow is non-zero.
Suggested-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
net/mptcp/subflow.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index 28ed7dc6e170..101bfa277a1c 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -968,6 +968,7 @@ static enum mapping_status get_mapping_status(struct sock *ssk,
data_len = mpext->data_len;
if (data_len == 0) {
MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_INFINITEMAPRX);
+ subflow->map_data_len = 0;
return MAPPING_INVALID;
}
@@ -1180,7 +1181,7 @@ static bool subflow_check_data_avail(struct sock *ssk)
return true;
}
- if (subflow->mp_join || subflow->fully_established) {
+ if ((subflow->mp_join || subflow->fully_established) && subflow->map_data_len) {
/* fatal protocol error, close the socket.
* subflow_error_report() will introduce the appropriate barriers
*/
--
2.31.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH mptcp-next v6 7/9] mptcp: add mib for infinite map sending
2021-09-29 7:34 [PATCH mptcp-next v6 0/9] The infinite mapping support Geliang Tang
` (5 preceding siblings ...)
2021-09-29 7:35 ` [PATCH mptcp-next v6 6/9] mptcp: infinite mapping receiving Geliang Tang
@ 2021-09-29 7:35 ` Geliang Tang
2021-09-29 7:35 ` [PATCH mptcp-next v6 8/9] selftests: mptcp: add infinite map mibs check Geliang Tang
2021-09-29 7:35 ` [PATCH mptcp-next v6 9/9] DO-NOT-MERGE: mptcp: mp_fail test Geliang Tang
8 siblings, 0 replies; 13+ messages in thread
From: Geliang Tang @ 2021-09-29 7:35 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
This patch added a new mib named MPTCP_MIB_INFINITEMAPTX, increase it
when a infinite mapping has been sent out.
Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
net/mptcp/mib.c | 1 +
net/mptcp/mib.h | 1 +
net/mptcp/protocol.c | 1 +
3 files changed, 3 insertions(+)
diff --git a/net/mptcp/mib.c b/net/mptcp/mib.c
index b21ff9be04c6..ab55afdcae22 100644
--- a/net/mptcp/mib.c
+++ b/net/mptcp/mib.c
@@ -24,6 +24,7 @@ static const struct snmp_mib mptcp_snmp_list[] = {
SNMP_MIB_ITEM("MPJoinAckRx", MPTCP_MIB_JOINACKRX),
SNMP_MIB_ITEM("MPJoinAckHMacFailure", MPTCP_MIB_JOINACKMAC),
SNMP_MIB_ITEM("DSSNotMatching", MPTCP_MIB_DSSNOMATCH),
+ SNMP_MIB_ITEM("InfiniteMapTx", MPTCP_MIB_INFINITEMAPTX),
SNMP_MIB_ITEM("InfiniteMapRx", MPTCP_MIB_INFINITEMAPRX),
SNMP_MIB_ITEM("DSSNoMatchTCP", MPTCP_MIB_DSSTCPMISMATCH),
SNMP_MIB_ITEM("DataCsumErr", MPTCP_MIB_DATACSUMERR),
diff --git a/net/mptcp/mib.h b/net/mptcp/mib.h
index ecd3d8b117e0..7901f1338d15 100644
--- a/net/mptcp/mib.h
+++ b/net/mptcp/mib.h
@@ -17,6 +17,7 @@ enum linux_mptcp_mib_field {
MPTCP_MIB_JOINACKRX, /* Received an ACK + MP_JOIN */
MPTCP_MIB_JOINACKMAC, /* HMAC was wrong on ACK + MP_JOIN */
MPTCP_MIB_DSSNOMATCH, /* Received a new mapping that did not match the previous one */
+ MPTCP_MIB_INFINITEMAPTX, /* Sent an infinite mapping */
MPTCP_MIB_INFINITEMAPRX, /* Received an infinite mapping */
MPTCP_MIB_DSSTCPMISMATCH, /* DSS-mapping did not map with TCP's sequence numbers */
MPTCP_MIB_DATACSUMERR, /* The data checksum fail */
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 5b73493c75c5..5122c4ea4350 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -1286,6 +1286,7 @@ static void mptcp_update_infinite_map(struct mptcp_sock *msk, struct sock *ssk,
mpext->data_len = 0;
mpext->csum = 0;
+ MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_INFINITEMAPTX);
mptcp_subflow_ctx(ssk)->send_infinite_map = 0;
pr_fallback(msk);
__mptcp_do_fallback(msk);
--
2.31.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH mptcp-next v6 8/9] selftests: mptcp: add infinite map mibs check
2021-09-29 7:34 [PATCH mptcp-next v6 0/9] The infinite mapping support Geliang Tang
` (6 preceding siblings ...)
2021-09-29 7:35 ` [PATCH mptcp-next v6 7/9] mptcp: add mib for infinite map sending Geliang Tang
@ 2021-09-29 7:35 ` Geliang Tang
2021-09-29 7:35 ` [PATCH mptcp-next v6 9/9] DO-NOT-MERGE: mptcp: mp_fail test Geliang Tang
8 siblings, 0 replies; 13+ messages in thread
From: Geliang Tang @ 2021-09-29 7:35 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
This patch added a function chk_infi_nr to check the mibs for the
infinite mapping.
Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
.../testing/selftests/net/mptcp/mptcp_join.sh | 38 +++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh
index 255793c5ac4f..fe0c8f3164a7 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
@@ -615,6 +615,43 @@ chk_fail_nr()
fi
}
+chk_infi_nr()
+{
+ local mp_infi_nr_tx=$1
+ local mp_infi_nr_rx=$2
+ local count
+ local dump_stats
+
+ printf "%-39s %s" " " "itx"
+ count=`ip netns exec $ns1 nstat -as | grep InfiniteMapTx | awk '{print $2}'`
+ [ -z "$count" ] && count=0
+ if [ "$count" != "$mp_infi_nr_tx" ]; then
+ echo "[fail] got $count infinite map[s] TX expected $mp_infi_nr_tx"
+ ret=1
+ dump_stats=1
+ else
+ echo -n "[ ok ]"
+ fi
+
+ echo -n " - irx "
+ count=`ip netns exec $ns2 nstat -as | grep InfiniteMapRx | awk '{print $2}'`
+ [ -z "$count" ] && count=0
+ if [ "$count" != "$mp_infi_nr_rx" ]; then
+ echo "[fail] got $count infinite map[s] RX expected $mp_infi_nr_rx"
+ ret=1
+ dump_stats=1
+ else
+ echo "[ ok ]"
+ fi
+
+ if [ "${dump_stats}" = 1 ]; then
+ echo Server ns stats
+ ip netns exec $ns1 nstat -as | grep MPTcp
+ echo Client ns stats
+ ip netns exec $ns2 nstat -as | grep MPTcp
+ fi
+}
+
chk_join_nr()
{
local msg="$1"
@@ -665,6 +702,7 @@ chk_join_nr()
if [ $checksum -eq 1 ]; then
chk_csum_nr
chk_fail_nr 0 0
+ chk_infi_nr 0 0
fi
}
--
2.31.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH mptcp-next v6 9/9] DO-NOT-MERGE: mptcp: mp_fail test
2021-09-29 7:34 [PATCH mptcp-next v6 0/9] The infinite mapping support Geliang Tang
` (7 preceding siblings ...)
2021-09-29 7:35 ` [PATCH mptcp-next v6 8/9] selftests: mptcp: add infinite map mibs check Geliang Tang
@ 2021-09-29 7:35 ` Geliang Tang
8 siblings, 0 replies; 13+ messages in thread
From: Geliang Tang @ 2021-09-29 7:35 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
./mptcp_join.sh -Cf
Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
net/mptcp/protocol.c | 9 +++++++++
.../testing/selftests/net/mptcp/mptcp_join.sh | 18 ++++++++++++++++++
2 files changed, 27 insertions(+)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 5122c4ea4350..d3b9f6894eb1 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -1292,6 +1292,8 @@ static void mptcp_update_infinite_map(struct mptcp_sock *msk, struct sock *ssk,
__mptcp_do_fallback(msk);
}
+static int j;
+
static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
struct mptcp_data_frag *dfrag,
struct mptcp_sendmsg_info *info)
@@ -1426,6 +1428,13 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
mptcp_update_data_checksum(skb, copy);
if (mptcp_subflow_ctx(ssk)->send_infinite_map)
mptcp_update_infinite_map(msk, ssk, mpext);
+
+ pr_debug("%s j=%d", __func__, j++);
+ if (j == 20)
+ skb->data_len = 1;
+ if (j > 40)
+ j = 0;
+
mptcp_subflow_ctx(ssk)->rel_write_seq += copy;
return copy;
}
diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh
index fe0c8f3164a7..38663f6373b8 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
@@ -977,6 +977,24 @@ chk_link_usage()
subflows_tests()
{
+ # 1 subflow
+ reset
+ ip netns exec $ns1 ./pm_nl_ctl limits 0 2
+ ip netns exec $ns2 ./pm_nl_ctl limits 0 2
+ run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow
+ chk_join_nr "1 subflow" 0 0 0
+
+ exit
+
+ # multiple subflows
+ reset
+ ip netns exec $ns1 ./pm_nl_ctl limits 0 2
+ ip netns exec $ns2 ./pm_nl_ctl limits 0 2
+ ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow
+ ip netns exec $ns2 ./pm_nl_ctl add 10.0.2.2 flags subflow
+ run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow
+ chk_join_nr "multiple subflows" 2 2 2
+
reset
run_tests $ns1 $ns2 10.0.1.1
chk_join_nr "no JOIN" "0" "0" "0"
--
2.31.1
^ permalink raw reply related [flat|nested] 13+ messages in thread