tcp: Don't pass cookie to __cookie_v[46]_check().
authorKuniyuki Iwashima <kuniyu@amazon.com>
Wed, 29 Nov 2023 02:29:20 +0000 (18:29 -0800)
committerJakub Kicinski <kuba@kernel.org>
Thu, 30 Nov 2023 04:16:19 +0000 (20:16 -0800)
tcp_hdr(skb) and SYN Cookie are passed to __cookie_v[46]_check(), but
none of the callers passes cookie other than ntohl(th->ack_seq) - 1.

Let's fetch it in __cookie_v[46]_check() instead of passing the cookie
over and over.

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://lore.kernel.org/r/20231129022924.96156-5-kuniyu@amazon.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
include/linux/netfilter_ipv6.h
include/net/tcp.h
net/core/filter.c
net/ipv4/syncookies.c
net/ipv6/syncookies.c
net/netfilter/nf_synproxy_core.c

index 7834c0be2831ddd272ffa788a81f27c9a5a70b95..61aa48f46dd72f3e5eafc4e6fe1cc253a9ced58e 100644 (file)
@@ -51,7 +51,7 @@ struct nf_ipv6_ops {
        u32 (*cookie_init_sequence)(const struct ipv6hdr *iph,
                                    const struct tcphdr *th, u16 *mssp);
        int (*cookie_v6_check)(const struct ipv6hdr *iph,
-                              const struct tcphdr *th, __u32 cookie);
+                              const struct tcphdr *th);
 #endif
        void (*route_input)(struct sk_buff *skb);
        int (*fragment)(struct net *net, struct sock *sk, struct sk_buff *skb,
@@ -179,16 +179,16 @@ static inline u32 nf_ipv6_cookie_init_sequence(const struct ipv6hdr *iph,
 }
 
 static inline int nf_cookie_v6_check(const struct ipv6hdr *iph,
-                                    const struct tcphdr *th, __u32 cookie)
+                                    const struct tcphdr *th)
 {
 #if IS_ENABLED(CONFIG_SYN_COOKIES)
 #if IS_MODULE(CONFIG_IPV6)
        const struct nf_ipv6_ops *v6_ops = nf_get_ipv6_ops();
 
        if (v6_ops)
-               return v6_ops->cookie_v6_check(iph, th, cookie);
+               return v6_ops->cookie_v6_check(iph, th);
 #elif IS_BUILTIN(CONFIG_IPV6)
-       return __cookie_v6_check(iph, th, cookie);
+       return __cookie_v6_check(iph, th);
 #endif
 #endif
        return 0;
index d2f0736b76b8b299b41e59adb63055bc52dc1f34..2b2c79c7bbcd5831dec84318708e659faef26556 100644 (file)
@@ -491,8 +491,7 @@ void inet_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb);
 struct sock *tcp_get_cookie_sock(struct sock *sk, struct sk_buff *skb,
                                 struct request_sock *req,
                                 struct dst_entry *dst, u32 tsoff);
-int __cookie_v4_check(const struct iphdr *iph, const struct tcphdr *th,
-                     u32 cookie);
+int __cookie_v4_check(const struct iphdr *iph, const struct tcphdr *th);
 struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb);
 struct request_sock *cookie_tcp_reqsk_alloc(const struct request_sock_ops *ops,
                                            const struct tcp_request_sock_ops *af_ops,
@@ -586,8 +585,7 @@ bool cookie_ecn_ok(const struct tcp_options_received *opt,
                   const struct net *net, const struct dst_entry *dst);
 
 /* From net/ipv6/syncookies.c */
-int __cookie_v6_check(const struct ipv6hdr *iph, const struct tcphdr *th,
-                     u32 cookie);
+int __cookie_v6_check(const struct ipv6hdr *iph, const struct tcphdr *th);
 struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb);
 
 u32 __cookie_v6_init_sequence(const struct ipv6hdr *iph,
index 7e4d7c3bcc849a9211eca4246cda7fa76af13c36..0adaa4afa35f21f4ac6d5d3e4dde9ed7c76a2a04 100644 (file)
@@ -7238,7 +7238,6 @@ BPF_CALL_5(bpf_tcp_check_syncookie, struct sock *, sk, void *, iph, u32, iph_len
           struct tcphdr *, th, u32, th_len)
 {
 #ifdef CONFIG_SYN_COOKIES
-       u32 cookie;
        int ret;
 
        if (unlikely(!sk || th_len < sizeof(*th)))
@@ -7260,8 +7259,6 @@ BPF_CALL_5(bpf_tcp_check_syncookie, struct sock *, sk, void *, iph, u32, iph_len
        if (tcp_synq_no_recent_overflow(sk))
                return -ENOENT;
 
-       cookie = ntohl(th->ack_seq) - 1;
-
        /* Both struct iphdr and struct ipv6hdr have the version field at the
         * same offset so we can cast to the shorter header (struct iphdr).
         */
@@ -7270,7 +7267,7 @@ BPF_CALL_5(bpf_tcp_check_syncookie, struct sock *, sk, void *, iph, u32, iph_len
                if (sk->sk_family == AF_INET6 && ipv6_only_sock(sk))
                        return -EINVAL;
 
-               ret = __cookie_v4_check((struct iphdr *)iph, th, cookie);
+               ret = __cookie_v4_check((struct iphdr *)iph, th);
                break;
 
 #if IS_BUILTIN(CONFIG_IPV6)
@@ -7281,7 +7278,7 @@ BPF_CALL_5(bpf_tcp_check_syncookie, struct sock *, sk, void *, iph, u32, iph_len
                if (sk->sk_family != AF_INET6)
                        return -EINVAL;
 
-               ret = __cookie_v6_check((struct ipv6hdr *)iph, th, cookie);
+               ret = __cookie_v6_check((struct ipv6hdr *)iph, th);
                break;
 #endif /* CONFIG_IPV6 */
 
@@ -7734,9 +7731,7 @@ static const struct bpf_func_proto bpf_tcp_raw_gen_syncookie_ipv6_proto = {
 BPF_CALL_2(bpf_tcp_raw_check_syncookie_ipv4, struct iphdr *, iph,
           struct tcphdr *, th)
 {
-       u32 cookie = ntohl(th->ack_seq) - 1;
-
-       if (__cookie_v4_check(iph, th, cookie) > 0)
+       if (__cookie_v4_check(iph, th) > 0)
                return 0;
 
        return -EACCES;
@@ -7757,9 +7752,7 @@ BPF_CALL_2(bpf_tcp_raw_check_syncookie_ipv6, struct ipv6hdr *, iph,
           struct tcphdr *, th)
 {
 #if IS_BUILTIN(CONFIG_IPV6)
-       u32 cookie = ntohl(th->ack_seq) - 1;
-
-       if (__cookie_v6_check(iph, th, cookie) > 0)
+       if (__cookie_v6_check(iph, th) > 0)
                return 0;
 
        return -EACCES;
index 8b7d7d7788afa30fafd63629145b943648781d09..c08428d63d11dda95333f9aa1e9c46e0d210e3df 100644 (file)
@@ -189,12 +189,14 @@ __u32 cookie_v4_init_sequence(const struct sk_buff *skb, __u16 *mssp)
  * Check if a ack sequence number is a valid syncookie.
  * Return the decoded mss if it is, or 0 if not.
  */
-int __cookie_v4_check(const struct iphdr *iph, const struct tcphdr *th,
-                     u32 cookie)
+int __cookie_v4_check(const struct iphdr *iph, const struct tcphdr *th)
 {
+       __u32 cookie = ntohl(th->ack_seq) - 1;
        __u32 seq = ntohl(th->seq) - 1;
-       __u32 mssind = check_tcp_syn_cookie(cookie, iph->saddr, iph->daddr,
-                                           th->source, th->dest, seq);
+       __u32 mssind;
+
+       mssind = check_tcp_syn_cookie(cookie, iph->saddr, iph->daddr,
+                                     th->source, th->dest, seq);
 
        return mssind < ARRAY_SIZE(msstab) ? msstab[mssind] : 0;
 }
@@ -332,7 +334,6 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
 {
        struct ip_options *opt = &TCP_SKB_CB(skb)->header.h4.opt;
        const struct tcphdr *th = tcp_hdr(skb);
-       __u32 cookie = ntohl(th->ack_seq) - 1;
        struct tcp_options_received tcp_opt;
        struct tcp_sock *tp = tcp_sk(sk);
        struct inet_request_sock *ireq;
@@ -354,7 +355,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
        if (tcp_synq_no_recent_overflow(sk))
                goto out;
 
-       mss = __cookie_v4_check(ip_hdr(skb), th, cookie);
+       mss = __cookie_v4_check(ip_hdr(skb), th);
        if (mss == 0) {
                __NET_INC_STATS(net, LINUX_MIB_SYNCOOKIESFAILED);
                goto out;
@@ -384,7 +385,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
        ireq = inet_rsk(req);
        treq = tcp_rsk(req);
        treq->rcv_isn           = ntohl(th->seq) - 1;
-       treq->snt_isn           = cookie;
+       treq->snt_isn           = ntohl(th->ack_seq) - 1;
        treq->ts_off            = 0;
        treq->txhash            = net_tx_rndhash();
        req->mss                = mss;
index 106376cbc9de5fb01c1bb0ab893e8d857bb3a86e..4cd26c481168332f31be2ed409c24e7ad8ce46cc 100644 (file)
@@ -114,12 +114,14 @@ __u32 cookie_v6_init_sequence(const struct sk_buff *skb, __u16 *mssp)
        return __cookie_v6_init_sequence(iph, th, mssp);
 }
 
-int __cookie_v6_check(const struct ipv6hdr *iph, const struct tcphdr *th,
-                     __u32 cookie)
+int __cookie_v6_check(const struct ipv6hdr *iph, const struct tcphdr *th)
 {
+       __u32 cookie = ntohl(th->ack_seq) - 1;
        __u32 seq = ntohl(th->seq) - 1;
-       __u32 mssind = check_tcp_syn_cookie(cookie, &iph->saddr, &iph->daddr,
-                                           th->source, th->dest, seq);
+       __u32 mssind;
+
+       mssind = check_tcp_syn_cookie(cookie, &iph->saddr, &iph->daddr,
+                                     th->source, th->dest, seq);
 
        return mssind < ARRAY_SIZE(msstab) ? msstab[mssind] : 0;
 }
@@ -128,7 +130,6 @@ EXPORT_SYMBOL_GPL(__cookie_v6_check);
 struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
 {
        const struct tcphdr *th = tcp_hdr(skb);
-       __u32 cookie = ntohl(th->ack_seq) - 1;
        struct ipv6_pinfo *np = inet6_sk(sk);
        struct tcp_options_received tcp_opt;
        struct tcp_sock *tp = tcp_sk(sk);
@@ -150,7 +151,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
        if (tcp_synq_no_recent_overflow(sk))
                goto out;
 
-       mss = __cookie_v6_check(ipv6_hdr(skb), th, cookie);
+       mss = __cookie_v6_check(ipv6_hdr(skb), th);
        if (mss == 0) {
                __NET_INC_STATS(net, LINUX_MIB_SYNCOOKIESFAILED);
                goto out;
@@ -213,7 +214,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
        req->ts_recent          = tcp_opt.saw_tstamp ? tcp_opt.rcv_tsval : 0;
        treq->snt_synack        = 0;
        treq->rcv_isn = ntohl(th->seq) - 1;
-       treq->snt_isn = cookie;
+       treq->snt_isn = ntohl(th->ack_seq) - 1;
        treq->ts_off = 0;
        treq->txhash = net_tx_rndhash();
 
index 467671f2d42f742554d95b017738aaa4ea4c9121..fbbc4fd373495b69940e29e657fde2cdc67b55db 100644 (file)
@@ -617,7 +617,7 @@ synproxy_recv_client_ack(struct net *net,
        struct synproxy_net *snet = synproxy_pernet(net);
        int mss;
 
-       mss = __cookie_v4_check(ip_hdr(skb), th, ntohl(th->ack_seq) - 1);
+       mss = __cookie_v4_check(ip_hdr(skb), th);
        if (mss == 0) {
                this_cpu_inc(snet->stats->cookie_invalid);
                return false;
@@ -1034,7 +1034,7 @@ synproxy_recv_client_ack_ipv6(struct net *net,
        struct synproxy_net *snet = synproxy_pernet(net);
        int mss;
 
-       mss = nf_cookie_v6_check(ipv6_hdr(skb), th, ntohl(th->ack_seq) - 1);
+       mss = nf_cookie_v6_check(ipv6_hdr(skb), th);
        if (mss == 0) {
                this_cpu_inc(snet->stats->cookie_invalid);
                return false;