syncookies.c (f94f3cb37a1c4d44dd2070cc4a6165689bda9c92) | syncookies.c (b71d1d426d263b0b6cb5760322efebbfc89d4463) |
---|---|
1/* 2 * IPv6 Syncookies implementation for the Linux kernel 3 * 4 * Authors: 5 * Glenn Griffin <ggriffin.kernel@gmail.com> 6 * 7 * Based on IPv4 implementation by Andi Kleen 8 * linux/net/ipv4/syncookies.c --- 52 unchanged lines hidden (view full) --- 61 reqsk_free(req); 62 63 return child; 64} 65 66static DEFINE_PER_CPU(__u32 [16 + 5 + SHA_WORKSPACE_WORDS], 67 ipv6_cookie_scratch); 68 | 1/* 2 * IPv6 Syncookies implementation for the Linux kernel 3 * 4 * Authors: 5 * Glenn Griffin <ggriffin.kernel@gmail.com> 6 * 7 * Based on IPv4 implementation by Andi Kleen 8 * linux/net/ipv4/syncookies.c --- 52 unchanged lines hidden (view full) --- 61 reqsk_free(req); 62 63 return child; 64} 65 66static DEFINE_PER_CPU(__u32 [16 + 5 + SHA_WORKSPACE_WORDS], 67 ipv6_cookie_scratch); 68 |
69static u32 cookie_hash(struct in6_addr *saddr, struct in6_addr *daddr, | 69static u32 cookie_hash(const struct in6_addr *saddr, const struct in6_addr *daddr, |
70 __be16 sport, __be16 dport, u32 count, int c) 71{ 72 __u32 *tmp = __get_cpu_var(ipv6_cookie_scratch); 73 74 /* 75 * we have 320 bits of information to hash, copy in the remaining 76 * 192 bits required for sha_transform, from the syncookie_secret 77 * and overwrite the digest with the secret 78 */ 79 memcpy(tmp + 10, syncookie_secret[c], 44); 80 memcpy(tmp, saddr, 16); 81 memcpy(tmp + 4, daddr, 16); 82 tmp[8] = ((__force u32)sport << 16) + (__force u32)dport; 83 tmp[9] = count; 84 sha_transform(tmp + 16, (__u8 *)tmp, tmp + 16 + 5); 85 86 return tmp[17]; 87} 88 | 70 __be16 sport, __be16 dport, u32 count, int c) 71{ 72 __u32 *tmp = __get_cpu_var(ipv6_cookie_scratch); 73 74 /* 75 * we have 320 bits of information to hash, copy in the remaining 76 * 192 bits required for sha_transform, from the syncookie_secret 77 * and overwrite the digest with the secret 78 */ 79 memcpy(tmp + 10, syncookie_secret[c], 44); 80 memcpy(tmp, saddr, 16); 81 memcpy(tmp + 4, daddr, 16); 82 tmp[8] = ((__force u32)sport << 16) + (__force u32)dport; 83 tmp[9] = count; 84 sha_transform(tmp + 16, (__u8 *)tmp, tmp + 16 + 5); 85 86 return tmp[17]; 87} 88 |
89static __u32 secure_tcp_syn_cookie(struct in6_addr *saddr, struct in6_addr *daddr, | 89static __u32 secure_tcp_syn_cookie(const struct in6_addr *saddr, 90 const struct in6_addr *daddr, |
90 __be16 sport, __be16 dport, __u32 sseq, 91 __u32 count, __u32 data) 92{ 93 return (cookie_hash(saddr, daddr, sport, dport, 0, 0) + 94 sseq + (count << COOKIEBITS) + 95 ((cookie_hash(saddr, daddr, sport, dport, count, 1) + data) 96 & COOKIEMASK)); 97} 98 | 91 __be16 sport, __be16 dport, __u32 sseq, 92 __u32 count, __u32 data) 93{ 94 return (cookie_hash(saddr, daddr, sport, dport, 0, 0) + 95 sseq + (count << COOKIEBITS) + 96 ((cookie_hash(saddr, daddr, sport, dport, count, 1) + data) 97 & COOKIEMASK)); 98} 99 |
99static __u32 check_tcp_syn_cookie(__u32 cookie, struct in6_addr *saddr, 100 struct in6_addr *daddr, __be16 sport, | 100static __u32 check_tcp_syn_cookie(__u32 cookie, const struct in6_addr *saddr, 101 const struct in6_addr *daddr, __be16 sport, |
101 __be16 dport, __u32 sseq, __u32 count, 102 __u32 maxdiff) 103{ 104 __u32 diff; 105 106 cookie -= cookie_hash(saddr, daddr, sport, dport, 0, 0) + sseq; 107 108 diff = (count - (cookie >> COOKIEBITS)) & ((__u32) -1 >> COOKIEBITS); 109 if (diff >= maxdiff) 110 return (__u32)-1; 111 112 return (cookie - 113 cookie_hash(saddr, daddr, sport, dport, count - diff, 1)) 114 & COOKIEMASK; 115} 116 117__u32 cookie_v6_init_sequence(struct sock *sk, struct sk_buff *skb, __u16 *mssp) 118{ | 102 __be16 dport, __u32 sseq, __u32 count, 103 __u32 maxdiff) 104{ 105 __u32 diff; 106 107 cookie -= cookie_hash(saddr, daddr, sport, dport, 0, 0) + sseq; 108 109 diff = (count - (cookie >> COOKIEBITS)) & ((__u32) -1 >> COOKIEBITS); 110 if (diff >= maxdiff) 111 return (__u32)-1; 112 113 return (cookie - 114 cookie_hash(saddr, daddr, sport, dport, count - diff, 1)) 115 & COOKIEMASK; 116} 117 118__u32 cookie_v6_init_sequence(struct sock *sk, struct sk_buff *skb, __u16 *mssp) 119{ |
119 struct ipv6hdr *iph = ipv6_hdr(skb); | 120 const struct ipv6hdr *iph = ipv6_hdr(skb); |
120 const struct tcphdr *th = tcp_hdr(skb); 121 int mssind; 122 const __u16 mss = *mssp; 123 124 tcp_synq_overflow(sk); 125 126 for (mssind = ARRAY_SIZE(msstab) - 1; mssind ; mssind--) 127 if (mss >= msstab[mssind]) --- 5 unchanged lines hidden (view full) --- 133 134 return secure_tcp_syn_cookie(&iph->saddr, &iph->daddr, th->source, 135 th->dest, ntohl(th->seq), 136 jiffies / (HZ * 60), mssind); 137} 138 139static inline int cookie_check(struct sk_buff *skb, __u32 cookie) 140{ | 121 const struct tcphdr *th = tcp_hdr(skb); 122 int mssind; 123 const __u16 mss = *mssp; 124 125 tcp_synq_overflow(sk); 126 127 for (mssind = ARRAY_SIZE(msstab) - 1; mssind ; mssind--) 128 if (mss >= msstab[mssind]) --- 5 unchanged lines hidden (view full) --- 134 135 return secure_tcp_syn_cookie(&iph->saddr, &iph->daddr, th->source, 136 th->dest, ntohl(th->seq), 137 jiffies / (HZ * 60), mssind); 138} 139 140static inline int cookie_check(struct sk_buff *skb, __u32 cookie) 141{ |
141 struct ipv6hdr *iph = ipv6_hdr(skb); | 142 const struct ipv6hdr *iph = ipv6_hdr(skb); |
142 const struct tcphdr *th = tcp_hdr(skb); 143 __u32 seq = ntohl(th->seq) - 1; 144 __u32 mssind = check_tcp_syn_cookie(cookie, &iph->saddr, &iph->daddr, 145 th->source, th->dest, seq, 146 jiffies / (HZ * 60), COUNTER_TRIES); 147 148 return mssind < ARRAY_SIZE(msstab) ? msstab[mssind] : 0; 149} --- 118 unchanged lines hidden --- | 143 const struct tcphdr *th = tcp_hdr(skb); 144 __u32 seq = ntohl(th->seq) - 1; 145 __u32 mssind = check_tcp_syn_cookie(cookie, &iph->saddr, &iph->daddr, 146 th->source, th->dest, seq, 147 jiffies / (HZ * 60), COUNTER_TRIES); 148 149 return mssind < ARRAY_SIZE(msstab) ? msstab[mssind] : 0; 150} --- 118 unchanged lines hidden --- |