This sysctl is going to be used in the next commits to drop TCP
timestamps option, to be able to send an ADD_ADDR with a v6 IP address
and a port number. It is enabled by default.

This knob is explicitly disabled in the MPTCP Join selftest, with the
"signal addr list progresses after tx drop" subtest, to continue
verifying the previous behaviour where the ADD_ADDR is not sent due to a
lack of space.

While at it, move syn_retrans_before_tcp_fallback down from struct
mptcp_pernet, to avoid creating another 3 bytes hole.

Reviewed-by: Mat Martineau <[email protected]>
Signed-off-by: Matthieu Baerts (NGI0) <[email protected]>
---
To: Jonathan Corbet <[email protected]>
To: Shuah Khan <[email protected]>
Cc: [email protected]
Cc: [email protected]
---
 Documentation/networking/mptcp-sysctl.rst       | 13 +++++++++++++
 net/mptcp/ctrl.c                                | 18 +++++++++++++++++-
 net/mptcp/protocol.h                            |  1 +
 tools/testing/selftests/net/mptcp/mptcp_join.sh |  1 +
 4 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/Documentation/networking/mptcp-sysctl.rst 
b/Documentation/networking/mptcp-sysctl.rst
index 1eb6af26b4a7..b9b5f58e0625 100644
--- a/Documentation/networking/mptcp-sysctl.rst
+++ b/Documentation/networking/mptcp-sysctl.rst
@@ -21,6 +21,19 @@ add_addr_timeout - INTEGER (seconds)
 
        Default: 120
 
+add_addr_v6_port_drop_ts - BOOLEAN
+       Control whether preparing an ADD_ADDR with an IPv6 address and a port
+       should drop the TCP timestamps option to have enough option space to
+       send the signal.
+
+       If there is not enough option space, and the TCP timestamps option
+       cannot be dropped, the signal cannot be sent. Note that dropping the TCP
+       timestamps option for one packet of the connection could disrupt some
+       middleboxes: even if it should be unlikely, they could drop the packet
+       or block the connection. This is a per-namespace sysctl.
+
+       Default: 1 (enabled)
+
 allow_join_initial_addr_port - BOOLEAN
        Allow peers to send join requests to the IP address and port number used
        by the initial subflow if the value is 1. This controls a flag that is
diff --git a/net/mptcp/ctrl.c b/net/mptcp/ctrl.c
index d96130e49942..c94a192f4118 100644
--- a/net/mptcp/ctrl.c
+++ b/net/mptcp/ctrl.c
@@ -32,12 +32,13 @@ struct mptcp_pernet {
        unsigned int close_timeout;
        unsigned int stale_loss_cnt;
        atomic_t active_disable_times;
-       u8 syn_retrans_before_tcp_fallback;
        unsigned long active_disable_stamp;
+       u8 syn_retrans_before_tcp_fallback;
        u8 mptcp_enabled;
        u8 checksum_enabled;
        u8 allow_join_initial_addr_port;
        u8 pm_type;
+       u8 add_addr_v6_port_drop_ts;
        char scheduler[MPTCP_SCHED_NAME_MAX];
        char path_manager[MPTCP_PM_NAME_MAX];
 };
@@ -94,6 +95,11 @@ const char *mptcp_get_scheduler(const struct net *net)
        return mptcp_get_pernet(net)->scheduler;
 }
 
+unsigned int mptcp_add_addr_v6_port_drop_ts(const struct net *net)
+{
+       return mptcp_get_pernet(net)->add_addr_v6_port_drop_ts;
+}
+
 static void mptcp_pernet_set_defaults(struct mptcp_pernet *pernet)
 {
        pernet->mptcp_enabled = 1;
@@ -108,6 +114,7 @@ static void mptcp_pernet_set_defaults(struct mptcp_pernet 
*pernet)
        pernet->pm_type = MPTCP_PM_TYPE_KERNEL;
        strscpy(pernet->scheduler, "default", sizeof(pernet->scheduler));
        strscpy(pernet->path_manager, "kernel", sizeof(pernet->path_manager));
+       pernet->add_addr_v6_port_drop_ts = 1;
 }
 
 #ifdef CONFIG_SYSCTL
@@ -362,6 +369,14 @@ static struct ctl_table mptcp_sysctl_table[] = {
                .mode = 0444,
                .proc_handler = proc_available_path_managers,
        },
+       {
+               .procname = "add_addr_v6_port_drop_ts",
+               .maxlen = sizeof(u8),
+               .mode = 0644,
+               .proc_handler = proc_dou8vec_minmax,
+               .extra1       = SYSCTL_ZERO,
+               .extra2       = SYSCTL_ONE
+       },
 };
 
 static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet)
@@ -389,6 +404,7 @@ static int mptcp_pernet_new_table(struct net *net, struct 
mptcp_pernet *pernet)
        table[10].data = &pernet->syn_retrans_before_tcp_fallback;
        table[11].data = &pernet->path_manager;
        /* table[12] is for available_path_managers which is read-only info */
+       table[13].data = &pernet->add_addr_v6_port_drop_ts;
 
        hdr = register_net_sysctl_sz(net, MPTCP_SYSCTL_PATH, table,
                                     ARRAY_SIZE(mptcp_sysctl_table));
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index e0ffebaa6795..f4276980d78a 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -798,6 +798,7 @@ unsigned int mptcp_close_timeout(const struct sock *sk);
 int mptcp_get_pm_type(const struct net *net);
 const char *mptcp_get_path_manager(const struct net *net);
 const char *mptcp_get_scheduler(const struct net *net);
+unsigned int mptcp_add_addr_v6_port_drop_ts(const struct net *net);
 
 void mptcp_active_disable(struct sock *sk);
 bool mptcp_active_should_disable(struct sock *ssk);
diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh 
b/tools/testing/selftests/net/mptcp/mptcp_join.sh
index 5d4d0f127f79..23b17957686a 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
@@ -3313,6 +3313,7 @@ add_addr_ports_tests()
        if reset "signal addr list progresses after tx drop"; then
                pm_nl_set_limits $ns1 0 2
                pm_nl_set_limits $ns2 1 0
+               ip netns exec $ns1 sysctl -q 
net.mptcp.add_addr_v6_port_drop_ts=0 2>/dev/null || true
                ip netns exec $ns1 sysctl -q net.ipv4.tcp_timestamps=1
                ip netns exec $ns2 sysctl -q net.ipv4.tcp_timestamps=1
 

-- 
2.53.0


Reply via email to