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 ---