]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
mptcp: change mptcp_established_options() to return opt_size
authorEric Dumazet <edumazet@google.com>
Tue, 2 Jun 2026 12:51:38 +0000 (12:51 +0000)
committerJakub Kicinski <kuba@kernel.org>
Thu, 4 Jun 2026 02:04:40 +0000 (19:04 -0700)
Instead of passing opt_size address to mptcp_established_options(),
change this function to return it by value.

This removes the need for an expensive stack canary in
tcp_established_options() when CONFIG_STACKPROTECTOR_STRONG=y.

$ scripts/bloat-o-meter -t vmlinux.old vmlinux.new
add/remove: 0/0 grow/shrink: 0/3 up/down: 0/-92 (-92)
Function                                     old     new   delta
tcp_options_write.isra                      1423    1407     -16
mptcp_established_options                   2746    2720     -26
tcp_established_options                      553     503     -50
Total: Before=22110750, After=22110658, chg -0.00%

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260602125138.2317015-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
include/net/mptcp.h
net/ipv4/tcp_output.c
net/mptcp/options.c

index f7263fe2a2e40b507257c3720cc2d78d37357d6d..27225c68a388f1e4cfd1e77e464d5dc4307f87c9 100644 (file)
@@ -149,9 +149,9 @@ bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb,
                       unsigned int *size, struct mptcp_out_options *opts);
 bool mptcp_synack_options(const struct request_sock *req, unsigned int *size,
                          struct mptcp_out_options *opts);
-bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
-                              unsigned int *size, unsigned int remaining,
-                              struct mptcp_out_options *opts);
+int mptcp_established_options(struct sock *sk, struct sk_buff *skb,
+                             unsigned int remaining,
+                             struct mptcp_out_options *opts);
 bool mptcp_incoming_options(struct sock *sk, struct sk_buff *skb);
 
 void mptcp_write_options(struct tcphdr *th, __be32 *ptr, struct tcp_sock *tp,
@@ -266,13 +266,12 @@ static inline bool mptcp_synack_options(const struct request_sock *req,
        return false;
 }
 
-static inline bool mptcp_established_options(struct sock *sk,
-                                            struct sk_buff *skb,
-                                            unsigned int *size,
-                                            unsigned int remaining,
-                                            struct mptcp_out_options *opts)
+static inline int mptcp_established_options(struct sock *sk,
+                                           struct sk_buff *skb,
+                                           unsigned int remaining,
+                                           struct mptcp_out_options *opts)
 {
-       return false;
+       return -1;
 }
 
 static inline bool mptcp_incoming_options(struct sock *sk,
index 1b0a066bb6a31cc0d1847459bce081f183134361..d3b8e61d3c5e7fb2723950b4d29aca535378df40 100644 (file)
@@ -1183,10 +1183,11 @@ static unsigned int tcp_established_options(struct sock *sk, struct sk_buff *skb
         */
        if (sk_is_mptcp(sk)) {
                unsigned int remaining = MAX_TCP_OPTION_SPACE - size;
-               unsigned int opt_size = 0;
+               int opt_size;
 
-               if (mptcp_established_options(sk, skb, &opt_size, remaining,
-                                             &opts->mptcp)) {
+               opt_size = mptcp_established_options(sk, skb, remaining,
+                                                    &opts->mptcp);
+               if (opt_size >= 0) {
                        opts->options |= OPTION_MPTCP;
                        size += opt_size;
                }
index 8a1c5698983cff3082d68290626dd8f1e044527f..53528301394d70072dde6614feca6128ea949436 100644 (file)
@@ -836,13 +836,14 @@ static bool mptcp_established_options_mp_fail(struct sock *sk,
        return true;
 }
 
-bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
-                              unsigned int *size, unsigned int remaining,
-                              struct mptcp_out_options *opts)
+int mptcp_established_options(struct sock *sk, struct sk_buff *skb,
+                             unsigned int remaining,
+                             struct mptcp_out_options *opts)
 {
        struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
        struct mptcp_sock *msk = mptcp_sk(subflow->conn);
        unsigned int opt_size = 0;
+       int total_size = 0;
        bool snd_data_fin;
        bool ret = false;
 
@@ -852,20 +853,20 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
         * option space.
         */
        if (unlikely(__mptcp_check_fallback(msk) && !mptcp_check_infinite_map(skb)))
-               return true;
+               return 0;
 
        if (unlikely(skb && TCP_SKB_CB(skb)->tcp_flags & TCPHDR_RST)) {
                if (mptcp_established_options_fastclose(sk, &opt_size, remaining, opts) ||
                    mptcp_established_options_mp_fail(sk, &opt_size, remaining, opts)) {
-                       *size += opt_size;
+                       total_size += opt_size;
                        remaining -= opt_size;
                }
                /* MP_RST can be used with MP_FASTCLOSE and MP_FAIL if there is room */
                if (mptcp_established_options_rst(sk, skb, &opt_size, remaining, opts)) {
-                       *size += opt_size;
+                       total_size += opt_size;
                        remaining -= opt_size;
                }
-               return true;
+               return total_size;
        }
 
        snd_data_fin = mptcp_data_fin_enabled(msk);
@@ -877,9 +878,9 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
                ret = true;
                if (mptcp_established_options_mp_fail(sk, &mp_fail_size,
                                                      remaining - opt_size, opts)) {
-                       *size += opt_size + mp_fail_size;
+                       total_size += opt_size + mp_fail_size;
                        remaining -= opt_size - mp_fail_size;
-                       return true;
+                       return total_size;
                }
        }
 
@@ -887,27 +888,27 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
         * TCP option space would be fatal
         */
        if (WARN_ON_ONCE(opt_size > remaining))
-               return false;
+               return -1;
 
-       *size += opt_size;
+       total_size += opt_size;
        remaining -= opt_size;
        if (mptcp_established_options_add_addr(sk, skb, &opt_size, remaining, opts)) {
-               *size += opt_size;
+               total_size += opt_size;
                remaining -= opt_size;
                ret = true;
        } else if (mptcp_established_options_rm_addr(sk, &opt_size, remaining, opts)) {
-               *size += opt_size;
+               total_size += opt_size;
                remaining -= opt_size;
                ret = true;
        }
 
        if (mptcp_established_options_mp_prio(sk, &opt_size, remaining, opts)) {
-               *size += opt_size;
+               total_size += opt_size;
                remaining -= opt_size;
                ret = true;
        }
 
-       return ret;
+       return ret ? total_size : -1;
 }
 
 bool mptcp_synack_options(const struct request_sock *req, unsigned int *size,