From: Eric Dumazet Date: Tue, 3 Mar 2026 19:12:43 +0000 (+0000) Subject: tcp: move tcp_do_parse_auth_options() to net/ipv4/tcp.c X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1d88db16156e02989087eb6287662827c10ada13;p=thirdparty%2Fkernel%2Flinux.git tcp: move tcp_do_parse_auth_options() to net/ipv4/tcp.c tcp_do_parse_auth_options() fast path user is tcp_inbound_hash(). Move tcp_do_parse_auth_options() right before tcp_inbound_hash() so that it can be (auto)inlined by the compiler. As a bonus, stack canary is removed from tcp_inbound_hash(). Also use EXPORT_IPV6_MOD(tcp_do_parse_auth_options). $ scripts/bloat-o-meter -t vmlinux.0 vmlinux add/remove: 0/0 grow/shrink: 1/0 up/down: 131/0 (131) Function old new delta tcp_inbound_hash 565 696 +131 Total: Before=25223788, After=25223919, chg +0.00% Signed-off-by: Eric Dumazet Reviewed-by: Kuniyuki Iwashima Link: https://patch.msgid.link/20260303191243.557245-1-edumazet@google.com Signed-off-by: Jakub Kicinski --- diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 1790d2fa75ade..5997e0fb7a45f 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -4987,6 +4987,60 @@ tcp_inbound_md5_hash(const struct sock *sk, const struct sk_buff *skb, #endif +#if defined(CONFIG_TCP_MD5SIG) || defined(CONFIG_TCP_AO) +/* + * Parse Signature options + */ +int tcp_do_parse_auth_options(const struct tcphdr *th, + const u8 **md5_hash, const u8 **ao_hash) +{ + int length = (th->doff << 2) - sizeof(*th); + const u8 *ptr = (const u8 *)(th + 1); + unsigned int minlen = TCPOLEN_MD5SIG; + + if (IS_ENABLED(CONFIG_TCP_AO)) + minlen = sizeof(struct tcp_ao_hdr) + 1; + + *md5_hash = NULL; + *ao_hash = NULL; + + /* If not enough data remaining, we can short cut */ + while (length >= minlen) { + int opcode = *ptr++; + int opsize; + + switch (opcode) { + case TCPOPT_EOL: + return 0; + case TCPOPT_NOP: + length--; + continue; + default: + opsize = *ptr++; + if (opsize < 2 || opsize > length) + return -EINVAL; + if (opcode == TCPOPT_MD5SIG) { + if (opsize != TCPOLEN_MD5SIG) + return -EINVAL; + if (unlikely(*md5_hash || *ao_hash)) + return -EEXIST; + *md5_hash = ptr; + } else if (opcode == TCPOPT_AO) { + if (opsize <= sizeof(struct tcp_ao_hdr)) + return -EINVAL; + if (unlikely(*md5_hash || *ao_hash)) + return -EEXIST; + *ao_hash = ptr; + } + } + ptr += opsize - 2; + length -= opsize; + } + return 0; +} +EXPORT_IPV6_MOD(tcp_do_parse_auth_options); +#endif + /* Called with rcu_read_lock() */ enum skb_drop_reason tcp_inbound_hash(struct sock *sk, const struct request_sock *req, diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 9079bc963f818..c27d11c3470bc 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -4714,60 +4714,6 @@ static bool tcp_fast_parse_options(const struct net *net, return true; } -#if defined(CONFIG_TCP_MD5SIG) || defined(CONFIG_TCP_AO) -/* - * Parse Signature options - */ -int tcp_do_parse_auth_options(const struct tcphdr *th, - const u8 **md5_hash, const u8 **ao_hash) -{ - int length = (th->doff << 2) - sizeof(*th); - const u8 *ptr = (const u8 *)(th + 1); - unsigned int minlen = TCPOLEN_MD5SIG; - - if (IS_ENABLED(CONFIG_TCP_AO)) - minlen = sizeof(struct tcp_ao_hdr) + 1; - - *md5_hash = NULL; - *ao_hash = NULL; - - /* If not enough data remaining, we can short cut */ - while (length >= minlen) { - int opcode = *ptr++; - int opsize; - - switch (opcode) { - case TCPOPT_EOL: - return 0; - case TCPOPT_NOP: - length--; - continue; - default: - opsize = *ptr++; - if (opsize < 2 || opsize > length) - return -EINVAL; - if (opcode == TCPOPT_MD5SIG) { - if (opsize != TCPOLEN_MD5SIG) - return -EINVAL; - if (unlikely(*md5_hash || *ao_hash)) - return -EEXIST; - *md5_hash = ptr; - } else if (opcode == TCPOPT_AO) { - if (opsize <= sizeof(struct tcp_ao_hdr)) - return -EINVAL; - if (unlikely(*md5_hash || *ao_hash)) - return -EEXIST; - *ao_hash = ptr; - } - } - ptr += opsize - 2; - length -= opsize; - } - return 0; -} -EXPORT_SYMBOL(tcp_do_parse_auth_options); -#endif - /* Sorry, PAWS as specified is broken wrt. pure-ACKs -DaveM * * It is not fatal. If this ACK does _not_ change critical state (seqs, window)