* [RFC mptcp-next v2 0/6] MP_FAIL echo and retrans
@ 2022-02-17 11:23 Geliang Tang
2022-02-17 11:23 ` [RFC mptcp-next v2 1/6] mptcp: add MP_FAIL echo support Geliang Tang
` (5 more replies)
0 siblings, 6 replies; 10+ messages in thread
From: Geliang Tang @ 2022-02-17 11:23 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
v2:
- Only send MP_FAIL response in the single subflow case
- Reuse icsk_retransmit_timer to trigger the retransmission.
- Patch 6 still doesn't work, needs Matt's help.
Geliang Tang (6):
mptcp: add MP_FAIL echo support
mptcp: add mibs for MP_FAIL echo
selftests: mptcp: add MP_FAIL echo mibs check
mptcp: add a new sysctl mp_fail_timeout
mptcp: add MP_FAIL retrans support
selftests: mptcp: MP_FAIL timeout testcases TODO
Documentation/networking/mptcp-sysctl.rst | 10 +++
net/mptcp/ctrl.c | 14 ++++
net/mptcp/mib.c | 2 +
net/mptcp/mib.h | 2 +
net/mptcp/pm.c | 13 +++-
net/mptcp/protocol.c | 44 +++++++++++-
net/mptcp/protocol.h | 4 ++
net/mptcp/subflow.c | 3 +
.../testing/selftests/net/mptcp/mptcp_join.sh | 72 +++++++++++++++++++
9 files changed, 161 insertions(+), 3 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [RFC mptcp-next v2 1/6] mptcp: add MP_FAIL echo support
2022-02-17 11:23 [RFC mptcp-next v2 0/6] MP_FAIL echo and retrans Geliang Tang
@ 2022-02-17 11:23 ` Geliang Tang
2022-02-24 1:42 ` Mat Martineau
2022-02-17 11:23 ` [RFC mptcp-next v2 2/6] mptcp: add mibs for MP_FAIL echo Geliang Tang
` (4 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Geliang Tang @ 2022-02-17 11:23 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
Add MP_FAIL echo support.
Signed-off-by: Geliang Tang <geliang.tang@suse.com>
---
net/mptcp/pm.c | 10 ++++++++--
net/mptcp/protocol.h | 1 +
net/mptcp/subflow.c | 2 ++
3 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index d0d31d5c198a..dc0dffc1b6b5 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -279,8 +279,14 @@ void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq)
pr_debug("fail_seq=%llu", fail_seq);
- if (!mptcp_has_another_subflow(sk) && READ_ONCE(msk->allow_infinite_fallback))
- subflow->send_infinite_map = 1;
+ if (!mptcp_has_another_subflow(sk) && READ_ONCE(msk->allow_infinite_fallback)) {
+ if (!subflow->mp_fail_response_expect) {
+ subflow->send_mp_fail = 1;
+ subflow->send_infinite_map = 1;
+ } else {
+ subflow->mp_fail_response_expect = 0;
+ }
+ }
}
/* path manager helpers */
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 18ca0248c084..3c74b04fba6c 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -448,6 +448,7 @@ struct mptcp_subflow_context {
backup : 1,
send_mp_prio : 1,
send_mp_fail : 1,
+ mp_fail_response_expect : 1,
send_fastclose : 1,
send_infinite_map : 1,
rx_eof : 1,
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index 8d086641bdc5..f06d93fce1bb 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -1172,6 +1172,8 @@ static bool subflow_check_data_avail(struct sock *ssk)
tcp_send_active_reset(ssk, GFP_ATOMIC);
while ((skb = skb_peek(&ssk->sk_receive_queue)))
sk_eat_skb(ssk, skb);
+ } else {
+ subflow->mp_fail_response_expect = 1;
}
WRITE_ONCE(subflow->data_avail, MPTCP_SUBFLOW_NODATA);
return true;
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [RFC mptcp-next v2 2/6] mptcp: add mibs for MP_FAIL echo
2022-02-17 11:23 [RFC mptcp-next v2 0/6] MP_FAIL echo and retrans Geliang Tang
2022-02-17 11:23 ` [RFC mptcp-next v2 1/6] mptcp: add MP_FAIL echo support Geliang Tang
@ 2022-02-17 11:23 ` Geliang Tang
2022-02-17 11:23 ` [RFC mptcp-next v2 3/6] selftests: mptcp: add MP_FAIL echo mibs check Geliang Tang
` (3 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Geliang Tang @ 2022-02-17 11:23 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
Add MP_FAIL echo support.
Signed-off-by: Geliang Tang <geliang.tang@suse.com>
---
net/mptcp/mib.c | 2 ++
net/mptcp/mib.h | 2 ++
net/mptcp/pm.c | 2 ++
3 files changed, 6 insertions(+)
diff --git a/net/mptcp/mib.c b/net/mptcp/mib.c
index d93a8c9996fd..f3070daa013b 100644
--- a/net/mptcp/mib.c
+++ b/net/mptcp/mib.c
@@ -49,6 +49,8 @@ static const struct snmp_mib mptcp_snmp_list[] = {
SNMP_MIB_ITEM("MPPrioRx", MPTCP_MIB_MPPRIORX),
SNMP_MIB_ITEM("MPFailTx", MPTCP_MIB_MPFAILTX),
SNMP_MIB_ITEM("MPFailRx", MPTCP_MIB_MPFAILRX),
+ SNMP_MIB_ITEM("MPFailEchoTx", MPTCP_MIB_MPFAILECHOTX),
+ SNMP_MIB_ITEM("MPFailEchoRx", MPTCP_MIB_MPFAILECHORX),
SNMP_MIB_ITEM("MPFastcloseTx", MPTCP_MIB_MPFASTCLOSETX),
SNMP_MIB_ITEM("MPFastcloseRx", MPTCP_MIB_MPFASTCLOSERX),
SNMP_MIB_ITEM("MPRstTx", MPTCP_MIB_MPRSTTX),
diff --git a/net/mptcp/mib.h b/net/mptcp/mib.h
index 529d07af9e14..83219721d337 100644
--- a/net/mptcp/mib.h
+++ b/net/mptcp/mib.h
@@ -42,6 +42,8 @@ enum linux_mptcp_mib_field {
MPTCP_MIB_MPPRIORX, /* Received a MP_PRIO */
MPTCP_MIB_MPFAILTX, /* Transmit a MP_FAIL */
MPTCP_MIB_MPFAILRX, /* Received a MP_FAIL */
+ MPTCP_MIB_MPFAILECHOTX, /* Transmit a MP_FAIL echo */
+ MPTCP_MIB_MPFAILECHORX, /* Received a MP_FAIL echo */
MPTCP_MIB_MPFASTCLOSETX, /* Transmit a MP_FASTCLOSE */
MPTCP_MIB_MPFASTCLOSERX, /* Received a MP_FASTCLOSE */
MPTCP_MIB_MPRSTTX, /* Transmit a MP_RST */
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index dc0dffc1b6b5..314e110588d7 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -283,8 +283,10 @@ void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq)
if (!subflow->mp_fail_response_expect) {
subflow->send_mp_fail = 1;
subflow->send_infinite_map = 1;
+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPFAILECHOTX);
} else {
subflow->mp_fail_response_expect = 0;
+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPFAILECHORX);
}
}
}
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [RFC mptcp-next v2 3/6] selftests: mptcp: add MP_FAIL echo mibs check
2022-02-17 11:23 [RFC mptcp-next v2 0/6] MP_FAIL echo and retrans Geliang Tang
2022-02-17 11:23 ` [RFC mptcp-next v2 1/6] mptcp: add MP_FAIL echo support Geliang Tang
2022-02-17 11:23 ` [RFC mptcp-next v2 2/6] mptcp: add mibs for MP_FAIL echo Geliang Tang
@ 2022-02-17 11:23 ` Geliang Tang
2022-02-17 11:23 ` [RFC mptcp-next v2 4/6] mptcp: add a new sysctl mp_fail_timeout Geliang Tang
` (2 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Geliang Tang @ 2022-02-17 11:23 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
This patch added the MP_FAIL echo mibs check.
Signed-off-by: Geliang Tang <geliang.tang@suse.com>
---
.../testing/selftests/net/mptcp/mptcp_join.sh | 24 +++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh
index 8708be740334..9a1d8a1d3447 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
@@ -947,6 +947,8 @@ chk_infi_nr()
{
local infi_tx=$1
local infi_rx=$2
+ local echo_tx=${3:-$infi_tx}
+ local echo_rx=${4:-$infi_rx}
local count
local dump_stats
@@ -972,6 +974,28 @@ chk_infi_nr()
echo "[ ok ]"
fi
+ printf "%-${nr_blank}s %s" " " "etx"
+ count=`ip netns exec $ns2 nstat -as | grep MPTcpExtMPFailEchoTx | awk '{print $2}'`
+ [ -z "$count" ] && count=0
+ if [ "$count" != "$echo_tx" ]; then
+ echo "[fail] got $count MP_FAIL echo[s] RX expected $echo_tx"
+ ret=1
+ dump_stats=1
+ else
+ echo -n "[ ok ]"
+ fi
+
+ echo -n " - echorx"
+ count=`ip netns exec $ns1 nstat -as | grep MPTcpExtMPFailEchoRx | awk '{print $2}'`
+ [ -z "$count" ] && count=0
+ if [ "$count" != "$echo_rx" ]; then
+ echo "[fail] got $count MP_FAIL echo[s] RX expected $echo_rx"
+ ret=1
+ dump_stats=1
+ else
+ echo "[ ok ]"
+ fi
+
[ "${dump_stats}" = 1 ] && dump_stats
}
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [RFC mptcp-next v2 4/6] mptcp: add a new sysctl mp_fail_timeout
2022-02-17 11:23 [RFC mptcp-next v2 0/6] MP_FAIL echo and retrans Geliang Tang
` (2 preceding siblings ...)
2022-02-17 11:23 ` [RFC mptcp-next v2 3/6] selftests: mptcp: add MP_FAIL echo mibs check Geliang Tang
@ 2022-02-17 11:23 ` Geliang Tang
2022-02-24 1:44 ` Mat Martineau
2022-02-17 11:23 ` [RFC mptcp-next v2 5/6] mptcp: add MP_FAIL retrans support Geliang Tang
2022-02-17 11:23 ` [RFC mptcp-next v2 6/6] selftests: mptcp: MP_FAIL timeout testcases TODO Geliang Tang
5 siblings, 1 reply; 10+ messages in thread
From: Geliang Tang @ 2022-02-17 11:23 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
This patch added a new sysctl, named mp_fail_timeout, to control the
timeout value (in seconds) of the MP_FAIL retransmission.
Signed-off-by: Geliang Tang <geliang.tang@suse.com>
---
Documentation/networking/mptcp-sysctl.rst | 10 ++++++++++
net/mptcp/ctrl.c | 14 ++++++++++++++
net/mptcp/protocol.h | 1 +
3 files changed, 25 insertions(+)
diff --git a/Documentation/networking/mptcp-sysctl.rst b/Documentation/networking/mptcp-sysctl.rst
index e263dfcc4b40..3ad19e04ecce 100644
--- a/Documentation/networking/mptcp-sysctl.rst
+++ b/Documentation/networking/mptcp-sysctl.rst
@@ -75,3 +75,13 @@ stale_loss_cnt - INTEGER
This is a per-namespace sysctl.
Default: 4
+
+mp_fail_timeout - INTEGER (seconds)
+ Set the timeout after which a MP_FAIL control message will be
+ resent to an MPTCP peer that has not acknowledged a previous
+ MP_FAIL message.
+
+ The default value matches TCP_RTO_MAX. This is a per-namespace
+ sysctl.
+
+ Default: 120
diff --git a/net/mptcp/ctrl.c b/net/mptcp/ctrl.c
index ae20b7d92e28..a211af9b19e8 100644
--- a/net/mptcp/ctrl.c
+++ b/net/mptcp/ctrl.c
@@ -32,6 +32,7 @@ struct mptcp_pernet {
u8 checksum_enabled;
u8 allow_join_initial_addr_port;
u8 pm_type;
+ unsigned int mp_fail_timeout;
};
static struct mptcp_pernet *mptcp_get_pernet(const struct net *net)
@@ -69,6 +70,11 @@ int mptcp_get_pm_type(const struct net *net)
return mptcp_get_pernet(net)->pm_type;
}
+unsigned int mptcp_get_mp_fail_timeout(const struct net *net)
+{
+ return mptcp_get_pernet(net)->mp_fail_timeout;
+}
+
static void mptcp_pernet_set_defaults(struct mptcp_pernet *pernet)
{
pernet->mptcp_enabled = 1;
@@ -77,6 +83,7 @@ static void mptcp_pernet_set_defaults(struct mptcp_pernet *pernet)
pernet->allow_join_initial_addr_port = 1;
pernet->stale_loss_cnt = 4;
pernet->pm_type = MPTCP_PM_TYPE_KERNEL;
+ pernet->mp_fail_timeout = TCP_RTO_MAX;
}
#ifdef CONFIG_SYSCTL
@@ -128,6 +135,12 @@ static struct ctl_table mptcp_sysctl_table[] = {
.extra1 = SYSCTL_ZERO,
.extra2 = &mptcp_pm_type_max
},
+ {
+ .procname = "mp_fail_timeout",
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec_jiffies,
+ },
{}
};
@@ -149,6 +162,7 @@ static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet)
table[3].data = &pernet->allow_join_initial_addr_port;
table[4].data = &pernet->stale_loss_cnt;
table[5].data = &pernet->pm_type;
+ table[6].data = &pernet->mp_fail_timeout;
hdr = register_net_sysctl(net, MPTCP_SYSCTL_PATH, table);
if (!hdr)
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 3c74b04fba6c..c28842ab0dcc 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -583,6 +583,7 @@ int mptcp_is_checksum_enabled(const struct net *net);
int mptcp_allow_join_id0(const struct net *net);
unsigned int mptcp_stale_loss_cnt(const struct net *net);
int mptcp_get_pm_type(const struct net *net);
+unsigned int mptcp_get_mp_fail_timeout(const struct net *net);
void mptcp_subflow_fully_established(struct mptcp_subflow_context *subflow,
struct mptcp_options_received *mp_opt);
bool __mptcp_retransmit_pending_data(struct sock *sk);
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [RFC mptcp-next v2 5/6] mptcp: add MP_FAIL retrans support
2022-02-17 11:23 [RFC mptcp-next v2 0/6] MP_FAIL echo and retrans Geliang Tang
` (3 preceding siblings ...)
2022-02-17 11:23 ` [RFC mptcp-next v2 4/6] mptcp: add a new sysctl mp_fail_timeout Geliang Tang
@ 2022-02-17 11:23 ` Geliang Tang
2022-02-24 1:54 ` Mat Martineau
2022-02-17 11:23 ` [RFC mptcp-next v2 6/6] selftests: mptcp: MP_FAIL timeout testcases TODO Geliang Tang
5 siblings, 1 reply; 10+ messages in thread
From: Geliang Tang @ 2022-02-17 11:23 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
Add MP_FAIL retrans support.
Signed-off-by: Geliang Tang <geliang.tang@suse.com>
---
net/mptcp/pm.c | 1 +
net/mptcp/protocol.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
net/mptcp/protocol.h | 2 ++
net/mptcp/subflow.c | 1 +
4 files changed, 47 insertions(+), 1 deletion(-)
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index 314e110588d7..ccb29b2d2075 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -285,6 +285,7 @@ void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq)
subflow->send_infinite_map = 1;
MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPFAILECHOTX);
} else {
+ sk_stop_timer((struct sock *)msk, &msk->sk.icsk_retransmit_timer);
subflow->mp_fail_response_expect = 0;
MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPFAILECHORX);
}
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 4599bde215b2..461fd30c6b9d 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -50,6 +50,8 @@ enum {
MPTCP_CMSG_INQ = BIT(1),
};
+#define MP_FAIL_RETRANS_MAX 3
+
static struct percpu_counter mptcp_sockets_allocated ____cacheline_aligned_in_smp;
static void __mptcp_destroy_sock(struct sock *sk);
@@ -860,6 +862,46 @@ static void mptcp_reset_timer(struct sock *sk)
sk_reset_timer(sk, &icsk->icsk_retransmit_timer, jiffies + tout);
}
+static void mptcp_mp_fail_timer(struct timer_list *t)
+{
+ struct inet_connection_sock *icsk = from_timer(icsk, t,
+ icsk_retransmit_timer);
+ struct sock *sk = &icsk->icsk_inet.sk;
+ struct mptcp_sock *msk = mptcp_sk(sk);
+ struct mptcp_subflow_context *subflow;
+
+ if (!msk)
+ return;
+ if (inet_sk_state_load(sk) == TCP_CLOSE)
+ return;
+
+ bh_lock_sock(sk);
+
+ subflow = mptcp_subflow_ctx(msk->first);
+ subflow->send_mp_fail = 1;
+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPFAILTX);
+ pr_debug("retransmit MP_FAIL %u", subflow->retrans_times++);
+
+ if (subflow->retrans_times < MP_FAIL_RETRANS_MAX) {
+ __mptcp_set_timeout(sk, mptcp_get_mp_fail_timeout(sock_net(sk)));
+ mptcp_reset_timer(sk);
+ }
+
+ bh_unlock_sock(sk);
+ sock_put(sk);
+}
+
+void mptcp_setup_mp_fail_timer(struct mptcp_sock *msk)
+{
+ struct sock *sk = (struct sock *)msk;
+
+ /* re-use the csk retrans timer for MP_FAIL retrans */
+ sk_stop_timer(sk, &msk->sk.icsk_retransmit_timer);
+ timer_setup(&msk->sk.icsk_retransmit_timer, mptcp_mp_fail_timer, 0);
+ __mptcp_set_timeout(sk, mptcp_get_mp_fail_timeout(sock_net(sk)));
+ mptcp_reset_timer(sk);
+}
+
bool mptcp_schedule_work(struct sock *sk)
{
if (inet_sk_state_load(sk) != TCP_CLOSE &&
@@ -1598,7 +1640,7 @@ void __mptcp_push_pending(struct sock *sk, unsigned int flags)
out:
/* ensure the rtx timer is running */
- if (!mptcp_timer_pending(sk))
+ if (!mptcp_timer_pending(sk) && !__mptcp_check_fallback(msk))
mptcp_reset_timer(sk);
if (copied)
__mptcp_check_send_data_fin(sk);
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index c28842ab0dcc..40954f2389e8 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -467,6 +467,7 @@ struct mptcp_subflow_context {
u8 reset_transient:1;
u8 reset_reason:4;
u8 stale_count;
+ u8 retrans_times;
long delegated_status;
@@ -669,6 +670,7 @@ void mptcp_rcv_space_init(struct mptcp_sock *msk, const struct sock *ssk);
void mptcp_data_ready(struct sock *sk, struct sock *ssk);
bool mptcp_finish_join(struct sock *sk);
bool mptcp_schedule_work(struct sock *sk);
+void mptcp_setup_mp_fail_timer(struct mptcp_sock *msk);
int mptcp_setsockopt(struct sock *sk, int level, int optname,
sockptr_t optval, unsigned int optlen);
int mptcp_getsockopt(struct sock *sk, int level, int optname,
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index f06d93fce1bb..a30867f926fd 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -1174,6 +1174,7 @@ static bool subflow_check_data_avail(struct sock *ssk)
sk_eat_skb(ssk, skb);
} else {
subflow->mp_fail_response_expect = 1;
+ mptcp_setup_mp_fail_timer(msk);
}
WRITE_ONCE(subflow->data_avail, MPTCP_SUBFLOW_NODATA);
return true;
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [RFC mptcp-next v2 6/6] selftests: mptcp: MP_FAIL timeout testcases TODO
2022-02-17 11:23 [RFC mptcp-next v2 0/6] MP_FAIL echo and retrans Geliang Tang
` (4 preceding siblings ...)
2022-02-17 11:23 ` [RFC mptcp-next v2 5/6] mptcp: add MP_FAIL retrans support Geliang Tang
@ 2022-02-17 11:23 ` Geliang Tang
5 siblings, 0 replies; 10+ messages in thread
From: Geliang Tang @ 2022-02-17 11:23 UTC (permalink / raw)
To: mptcp; +Cc: Geliang Tang
This patch added the MP_FAIL timeout testcases.
Doesn't work yet.
Signed-off-by: Geliang Tang <geliang.tang@suse.com>
---
.../testing/selftests/net/mptcp/mptcp_join.sh | 48 +++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh
index 9a1d8a1d3447..f28faf901a24 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
@@ -41,6 +41,24 @@ CBPF_MPTCP_SUBOPTION_ADD_ADDR="14,
6 0 0 65535,
6 0 0 0"
+# generated using "nfbpf_compile '(ip && (ip[54] & 0xf0) == 0x60) ||
+# (ip6 && (ip6[74] & 0xf0) == 0x60)'"
+CBPF_MPTCP_SUBOPTION_MP_FAIL="14,
+ 48 0 0 0,
+ 84 0 0 240,
+ 21 0 3 64,
+ 48 0 0 54,
+ 84 0 0 240,
+ 21 6 7 96,
+ 48 0 0 0,
+ 84 0 0 240,
+ 21 0 4 96,
+ 48 0 0 74,
+ 84 0 0 240,
+ 21 0 1 96,
+ 6 0 0 65535,
+ 6 0 0 0"
+
init_partial()
{
capout=$(mktemp)
@@ -261,6 +279,27 @@ reset_with_fail()
index 100 || exit 1
}
+reset_with_fail_timeout()
+{
+ local i="$1"
+ local ip="${2:-4}"
+ local tables
+
+ tables="iptables"
+ if [ $ip -eq 6 ]; then
+ tables="ip6tables"
+ fi
+
+ reset_with_fail $i $ip
+
+ ip netns exec $ns1 sysctl -q net.mptcp.mp_fail_timeout=1
+ ip netns exec $ns2 $tables -A OUTPUT -p tcp \
+ -m tcp --tcp-option 30 \
+ -m bpf --bytecode \
+ "$CBPF_MPTCP_SUBOPTION_MP_FAIL" \
+ -j DROP
+}
+
print_file_err()
{
ls -l "$1" 1>&2
@@ -2455,6 +2494,15 @@ fail_tests()
1 \
0 \
1
+
+ # single subflow
+ reset_with_fail_timeout 1
+ run_tests $ns1 $ns2 10.0.1.1 128
+ chk_join_nr "MP_FAIL timeout 1: $(pedit_action_pkts) corrupted pkts" 0 0 0 \
+ +1 +0 \
+ 1 \
+ 0 \
+ 1
}
all_tests()
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [RFC mptcp-next v2 1/6] mptcp: add MP_FAIL echo support
2022-02-17 11:23 ` [RFC mptcp-next v2 1/6] mptcp: add MP_FAIL echo support Geliang Tang
@ 2022-02-24 1:42 ` Mat Martineau
0 siblings, 0 replies; 10+ messages in thread
From: Mat Martineau @ 2022-02-24 1:42 UTC (permalink / raw)
To: Geliang Tang; +Cc: mptcp
On Thu, 17 Feb 2022, Geliang Tang wrote:
> Add MP_FAIL echo support.
>
> Signed-off-by: Geliang Tang <geliang.tang@suse.com>
> ---
> net/mptcp/pm.c | 10 ++++++++--
> net/mptcp/protocol.h | 1 +
> net/mptcp/subflow.c | 2 ++
> 3 files changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
> index d0d31d5c198a..dc0dffc1b6b5 100644
> --- a/net/mptcp/pm.c
> +++ b/net/mptcp/pm.c
> @@ -279,8 +279,14 @@ void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq)
>
> pr_debug("fail_seq=%llu", fail_seq);
>
> - if (!mptcp_has_another_subflow(sk) && READ_ONCE(msk->allow_infinite_fallback))
> - subflow->send_infinite_map = 1;
> + if (!mptcp_has_another_subflow(sk) && READ_ONCE(msk->allow_infinite_fallback)) {
> + if (!subflow->mp_fail_response_expect) {
> + subflow->send_mp_fail = 1;
> + subflow->send_infinite_map = 1;
> + } else {
> + subflow->mp_fail_response_expect = 0;
I'm not sure this should be cleared. If the peer retransmits MP_FAIL, we
could receive MP_FAIL multiple times and we don't want to echo an MP_FAIL
back.
-Mat
> + }
> + }
> }
>
> /* path manager helpers */
> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> index 18ca0248c084..3c74b04fba6c 100644
> --- a/net/mptcp/protocol.h
> +++ b/net/mptcp/protocol.h
> @@ -448,6 +448,7 @@ struct mptcp_subflow_context {
> backup : 1,
> send_mp_prio : 1,
> send_mp_fail : 1,
> + mp_fail_response_expect : 1,
> send_fastclose : 1,
> send_infinite_map : 1,
> rx_eof : 1,
> diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
> index 8d086641bdc5..f06d93fce1bb 100644
> --- a/net/mptcp/subflow.c
> +++ b/net/mptcp/subflow.c
> @@ -1172,6 +1172,8 @@ static bool subflow_check_data_avail(struct sock *ssk)
> tcp_send_active_reset(ssk, GFP_ATOMIC);
> while ((skb = skb_peek(&ssk->sk_receive_queue)))
> sk_eat_skb(ssk, skb);
> + } else {
> + subflow->mp_fail_response_expect = 1;
> }
> WRITE_ONCE(subflow->data_avail, MPTCP_SUBFLOW_NODATA);
> return true;
> --
> 2.34.1
>
>
>
--
Mat Martineau
Intel
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC mptcp-next v2 4/6] mptcp: add a new sysctl mp_fail_timeout
2022-02-17 11:23 ` [RFC mptcp-next v2 4/6] mptcp: add a new sysctl mp_fail_timeout Geliang Tang
@ 2022-02-24 1:44 ` Mat Martineau
0 siblings, 0 replies; 10+ messages in thread
From: Mat Martineau @ 2022-02-24 1:44 UTC (permalink / raw)
To: Geliang Tang; +Cc: mptcp
On Thu, 17 Feb 2022, Geliang Tang wrote:
> This patch added a new sysctl, named mp_fail_timeout, to control the
> timeout value (in seconds) of the MP_FAIL retransmission.
>
I'm reluctant to add a sysctl for this - is there a use case other than
making the selftest run faster? :)
-Mat
> Signed-off-by: Geliang Tang <geliang.tang@suse.com>
> ---
> Documentation/networking/mptcp-sysctl.rst | 10 ++++++++++
> net/mptcp/ctrl.c | 14 ++++++++++++++
> net/mptcp/protocol.h | 1 +
> 3 files changed, 25 insertions(+)
>
> diff --git a/Documentation/networking/mptcp-sysctl.rst b/Documentation/networking/mptcp-sysctl.rst
> index e263dfcc4b40..3ad19e04ecce 100644
> --- a/Documentation/networking/mptcp-sysctl.rst
> +++ b/Documentation/networking/mptcp-sysctl.rst
> @@ -75,3 +75,13 @@ stale_loss_cnt - INTEGER
> This is a per-namespace sysctl.
>
> Default: 4
> +
> +mp_fail_timeout - INTEGER (seconds)
> + Set the timeout after which a MP_FAIL control message will be
> + resent to an MPTCP peer that has not acknowledged a previous
> + MP_FAIL message.
> +
> + The default value matches TCP_RTO_MAX. This is a per-namespace
> + sysctl.
> +
> + Default: 120
> diff --git a/net/mptcp/ctrl.c b/net/mptcp/ctrl.c
> index ae20b7d92e28..a211af9b19e8 100644
> --- a/net/mptcp/ctrl.c
> +++ b/net/mptcp/ctrl.c
> @@ -32,6 +32,7 @@ struct mptcp_pernet {
> u8 checksum_enabled;
> u8 allow_join_initial_addr_port;
> u8 pm_type;
> + unsigned int mp_fail_timeout;
> };
>
> static struct mptcp_pernet *mptcp_get_pernet(const struct net *net)
> @@ -69,6 +70,11 @@ int mptcp_get_pm_type(const struct net *net)
> return mptcp_get_pernet(net)->pm_type;
> }
>
> +unsigned int mptcp_get_mp_fail_timeout(const struct net *net)
> +{
> + return mptcp_get_pernet(net)->mp_fail_timeout;
> +}
> +
> static void mptcp_pernet_set_defaults(struct mptcp_pernet *pernet)
> {
> pernet->mptcp_enabled = 1;
> @@ -77,6 +83,7 @@ static void mptcp_pernet_set_defaults(struct mptcp_pernet *pernet)
> pernet->allow_join_initial_addr_port = 1;
> pernet->stale_loss_cnt = 4;
> pernet->pm_type = MPTCP_PM_TYPE_KERNEL;
> + pernet->mp_fail_timeout = TCP_RTO_MAX;
> }
>
> #ifdef CONFIG_SYSCTL
> @@ -128,6 +135,12 @@ static struct ctl_table mptcp_sysctl_table[] = {
> .extra1 = SYSCTL_ZERO,
> .extra2 = &mptcp_pm_type_max
> },
> + {
> + .procname = "mp_fail_timeout",
> + .maxlen = sizeof(unsigned int),
> + .mode = 0644,
> + .proc_handler = proc_dointvec_jiffies,
> + },
> {}
> };
>
> @@ -149,6 +162,7 @@ static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet)
> table[3].data = &pernet->allow_join_initial_addr_port;
> table[4].data = &pernet->stale_loss_cnt;
> table[5].data = &pernet->pm_type;
> + table[6].data = &pernet->mp_fail_timeout;
>
> hdr = register_net_sysctl(net, MPTCP_SYSCTL_PATH, table);
> if (!hdr)
> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> index 3c74b04fba6c..c28842ab0dcc 100644
> --- a/net/mptcp/protocol.h
> +++ b/net/mptcp/protocol.h
> @@ -583,6 +583,7 @@ int mptcp_is_checksum_enabled(const struct net *net);
> int mptcp_allow_join_id0(const struct net *net);
> unsigned int mptcp_stale_loss_cnt(const struct net *net);
> int mptcp_get_pm_type(const struct net *net);
> +unsigned int mptcp_get_mp_fail_timeout(const struct net *net);
> void mptcp_subflow_fully_established(struct mptcp_subflow_context *subflow,
> struct mptcp_options_received *mp_opt);
> bool __mptcp_retransmit_pending_data(struct sock *sk);
> --
> 2.34.1
>
>
>
--
Mat Martineau
Intel
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC mptcp-next v2 5/6] mptcp: add MP_FAIL retrans support
2022-02-17 11:23 ` [RFC mptcp-next v2 5/6] mptcp: add MP_FAIL retrans support Geliang Tang
@ 2022-02-24 1:54 ` Mat Martineau
0 siblings, 0 replies; 10+ messages in thread
From: Mat Martineau @ 2022-02-24 1:54 UTC (permalink / raw)
To: Geliang Tang; +Cc: mptcp
On Thu, 17 Feb 2022, Geliang Tang wrote:
> Add MP_FAIL retrans support.
>
I'm still trying to figure out if retransmitting MP_FAIL is the action to
take if the MP_FAIL echo is not received. Could also just send RST, as in
the other checksum error cases. As Christoph said, this is a "best effort"
thing and I'm not sure the rare case justifies very much complexity. There
are other scenarios that arise: for example, the MP_FAIL echo from the
peer is lost, but the infinite mapping from the peer is delivered. That
implies that the peer did get the MP_FAIL, but the RFC doesn't have the
details on what to do.
What do you think about resetting the subflow if the fallback process
doesn't follow the expected steps?
- Mat
> Signed-off-by: Geliang Tang <geliang.tang@suse.com>
> ---
> net/mptcp/pm.c | 1 +
> net/mptcp/protocol.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
> net/mptcp/protocol.h | 2 ++
> net/mptcp/subflow.c | 1 +
> 4 files changed, 47 insertions(+), 1 deletion(-)
>
> diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
> index 314e110588d7..ccb29b2d2075 100644
> --- a/net/mptcp/pm.c
> +++ b/net/mptcp/pm.c
> @@ -285,6 +285,7 @@ void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq)
> subflow->send_infinite_map = 1;
> MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPFAILECHOTX);
> } else {
> + sk_stop_timer((struct sock *)msk, &msk->sk.icsk_retransmit_timer);
> subflow->mp_fail_response_expect = 0;
> MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPFAILECHORX);
> }
> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
> index 4599bde215b2..461fd30c6b9d 100644
> --- a/net/mptcp/protocol.c
> +++ b/net/mptcp/protocol.c
> @@ -50,6 +50,8 @@ enum {
> MPTCP_CMSG_INQ = BIT(1),
> };
>
> +#define MP_FAIL_RETRANS_MAX 3
> +
> static struct percpu_counter mptcp_sockets_allocated ____cacheline_aligned_in_smp;
>
> static void __mptcp_destroy_sock(struct sock *sk);
> @@ -860,6 +862,46 @@ static void mptcp_reset_timer(struct sock *sk)
> sk_reset_timer(sk, &icsk->icsk_retransmit_timer, jiffies + tout);
> }
>
> +static void mptcp_mp_fail_timer(struct timer_list *t)
> +{
> + struct inet_connection_sock *icsk = from_timer(icsk, t,
> + icsk_retransmit_timer);
> + struct sock *sk = &icsk->icsk_inet.sk;
> + struct mptcp_sock *msk = mptcp_sk(sk);
> + struct mptcp_subflow_context *subflow;
> +
> + if (!msk)
> + return;
> + if (inet_sk_state_load(sk) == TCP_CLOSE)
> + return;
> +
> + bh_lock_sock(sk);
> +
> + subflow = mptcp_subflow_ctx(msk->first);
> + subflow->send_mp_fail = 1;
> + MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPFAILTX);
> + pr_debug("retransmit MP_FAIL %u", subflow->retrans_times++);
> +
> + if (subflow->retrans_times < MP_FAIL_RETRANS_MAX) {
> + __mptcp_set_timeout(sk, mptcp_get_mp_fail_timeout(sock_net(sk)));
> + mptcp_reset_timer(sk);
> + }
> +
> + bh_unlock_sock(sk);
> + sock_put(sk);
> +}
> +
> +void mptcp_setup_mp_fail_timer(struct mptcp_sock *msk)
> +{
> + struct sock *sk = (struct sock *)msk;
> +
> + /* re-use the csk retrans timer for MP_FAIL retrans */
> + sk_stop_timer(sk, &msk->sk.icsk_retransmit_timer);
> + timer_setup(&msk->sk.icsk_retransmit_timer, mptcp_mp_fail_timer, 0);
> + __mptcp_set_timeout(sk, mptcp_get_mp_fail_timeout(sock_net(sk)));
> + mptcp_reset_timer(sk);
> +}
> +
> bool mptcp_schedule_work(struct sock *sk)
> {
> if (inet_sk_state_load(sk) != TCP_CLOSE &&
> @@ -1598,7 +1640,7 @@ void __mptcp_push_pending(struct sock *sk, unsigned int flags)
>
> out:
> /* ensure the rtx timer is running */
> - if (!mptcp_timer_pending(sk))
> + if (!mptcp_timer_pending(sk) && !__mptcp_check_fallback(msk))
> mptcp_reset_timer(sk);
> if (copied)
> __mptcp_check_send_data_fin(sk);
> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> index c28842ab0dcc..40954f2389e8 100644
> --- a/net/mptcp/protocol.h
> +++ b/net/mptcp/protocol.h
> @@ -467,6 +467,7 @@ struct mptcp_subflow_context {
> u8 reset_transient:1;
> u8 reset_reason:4;
> u8 stale_count;
> + u8 retrans_times;
>
> long delegated_status;
>
> @@ -669,6 +670,7 @@ void mptcp_rcv_space_init(struct mptcp_sock *msk, const struct sock *ssk);
> void mptcp_data_ready(struct sock *sk, struct sock *ssk);
> bool mptcp_finish_join(struct sock *sk);
> bool mptcp_schedule_work(struct sock *sk);
> +void mptcp_setup_mp_fail_timer(struct mptcp_sock *msk);
> int mptcp_setsockopt(struct sock *sk, int level, int optname,
> sockptr_t optval, unsigned int optlen);
> int mptcp_getsockopt(struct sock *sk, int level, int optname,
> diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
> index f06d93fce1bb..a30867f926fd 100644
> --- a/net/mptcp/subflow.c
> +++ b/net/mptcp/subflow.c
> @@ -1174,6 +1174,7 @@ static bool subflow_check_data_avail(struct sock *ssk)
> sk_eat_skb(ssk, skb);
> } else {
> subflow->mp_fail_response_expect = 1;
> + mptcp_setup_mp_fail_timer(msk);
> }
> WRITE_ONCE(subflow->data_avail, MPTCP_SUBFLOW_NODATA);
> return true;
> --
> 2.34.1
>
>
>
--
Mat Martineau
Intel
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2022-02-24 1:54 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-02-17 11:23 [RFC mptcp-next v2 0/6] MP_FAIL echo and retrans Geliang Tang
2022-02-17 11:23 ` [RFC mptcp-next v2 1/6] mptcp: add MP_FAIL echo support Geliang Tang
2022-02-24 1:42 ` Mat Martineau
2022-02-17 11:23 ` [RFC mptcp-next v2 2/6] mptcp: add mibs for MP_FAIL echo Geliang Tang
2022-02-17 11:23 ` [RFC mptcp-next v2 3/6] selftests: mptcp: add MP_FAIL echo mibs check Geliang Tang
2022-02-17 11:23 ` [RFC mptcp-next v2 4/6] mptcp: add a new sysctl mp_fail_timeout Geliang Tang
2022-02-24 1:44 ` Mat Martineau
2022-02-17 11:23 ` [RFC mptcp-next v2 5/6] mptcp: add MP_FAIL retrans support Geliang Tang
2022-02-24 1:54 ` Mat Martineau
2022-02-17 11:23 ` [RFC mptcp-next v2 6/6] selftests: mptcp: MP_FAIL timeout testcases TODO Geliang Tang
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.