Blame view

net/ipv4/syncookies.c 10.2 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
  /*
   *  Syncookies implementation for the Linux kernel
   *
   *  Copyright (C) 1997 Andi Kleen
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
5
   *  Based on ideas by D.J.Bernstein and Eric Schenk.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6
7
8
9
10
   *
   *	This program is free software; you can redistribute it and/or
   *      modify it under the terms of the GNU General Public License
   *      as published by the Free Software Foundation; either version
   *      2 of the License, or (at your option) any later version.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
11
12
13
14
15
16
17
18
   */
  
  #include <linux/tcp.h>
  #include <linux/slab.h>
  #include <linux/random.h>
  #include <linux/cryptohash.h>
  #include <linux/kernel.h>
  #include <net/tcp.h>
86b08d867   KOVACS Krisztian   ipv4: Make Netfil...
19
  #include <net/route.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
20

734f614bc   Florian Westphal   syncookies: do no...
21
  /* Timestamps: lowest bits store TCP options */
172d69e63   Florian Westphal   syncookies: add s...
22
  #define TSBITS 6
4dfc28170   Florian Westphal   [Syncookies]: Add...
23
  #define TSMASK (((__u32)1 << TSBITS) - 1)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
24
  extern int sysctl_tcp_syncookies;
2051f11fb   Florian Westphal   [TCP]: Shrink syn...
25
  __u32 syncookie_secret[2][16-4+SHA_DIGEST_WORDS];
c6aefafb7   Glenn Griffin   [TCP]: Add IPv6 s...
26
  EXPORT_SYMBOL(syncookie_secret);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
28
29
30
31
32
  
  static __init int init_syncookies(void)
  {
  	get_random_bytes(syncookie_secret, sizeof(syncookie_secret));
  	return 0;
  }
c6aefafb7   Glenn Griffin   [TCP]: Add IPv6 s...
33
  __initcall(init_syncookies);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34
35
36
  
  #define COOKIEBITS 24	/* Upper bits store count */
  #define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1)
245b2e70e   Tejun Heo   percpu: clean up ...
37
38
  static DEFINE_PER_CPU(__u32 [16 + 5 + SHA_WORKSPACE_WORDS],
  		      ipv4_cookie_scratch);
11baab7ac   Eric Dumazet   [TCP]: lower stac...
39

714e85be3   Al Viro   [IPV6]: Assorted ...
40
  static u32 cookie_hash(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41
42
  		       u32 count, int c)
  {
245b2e70e   Tejun Heo   percpu: clean up ...
43
  	__u32 *tmp = __get_cpu_var(ipv4_cookie_scratch);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
44

2051f11fb   Florian Westphal   [TCP]: Shrink syn...
45
  	memcpy(tmp + 4, syncookie_secret[c], sizeof(syncookie_secret[c]));
714e85be3   Al Viro   [IPV6]: Assorted ...
46
47
48
  	tmp[0] = (__force u32)saddr;
  	tmp[1] = (__force u32)daddr;
  	tmp[2] = ((__force u32)sport << 16) + (__force u32)dport;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
49
50
51
52
53
  	tmp[3] = count;
  	sha_transform(tmp + 16, (__u8 *)tmp, tmp + 16 + 5);
  
  	return tmp[17];
  }
4dfc28170   Florian Westphal   [Syncookies]: Add...
54
55
56
  
  /*
   * when syncookies are in effect and tcp timestamps are enabled we encode
734f614bc   Florian Westphal   syncookies: do no...
57
   * tcp options in the lower bits of the timestamp value that will be
4dfc28170   Florian Westphal   [Syncookies]: Add...
58
59
60
61
62
63
64
65
66
67
68
   * sent in the syn-ack.
   * Since subsequent timestamps use the normal tcp_time_stamp value, we
   * must make sure that the resulting initial timestamp is <= tcp_time_stamp.
   */
  __u32 cookie_init_timestamp(struct request_sock *req)
  {
  	struct inet_request_sock *ireq;
  	u32 ts, ts_now = tcp_time_stamp;
  	u32 options = 0;
  
  	ireq = inet_rsk(req);
734f614bc   Florian Westphal   syncookies: do no...
69
70
71
  
  	options = ireq->wscale_ok ? ireq->snd_wscale : 0xf;
  	options |= ireq->sack_ok << 4;
172d69e63   Florian Westphal   syncookies: add s...
72
  	options |= ireq->ecn_ok << 5;
4dfc28170   Florian Westphal   [Syncookies]: Add...
73
74
75
76
77
78
79
80
81
82
83
  
  	ts = ts_now & ~TSMASK;
  	ts |= options;
  	if (ts > ts_now) {
  		ts >>= TSBITS;
  		ts--;
  		ts <<= TSBITS;
  		ts |= options;
  	}
  	return ts;
  }
714e85be3   Al Viro   [IPV6]: Assorted ...
84
85
  static __u32 secure_tcp_syn_cookie(__be32 saddr, __be32 daddr, __be16 sport,
  				   __be16 dport, __u32 sseq, __u32 count,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86
87
88
89
90
  				   __u32 data)
  {
  	/*
  	 * Compute the secure sequence number.
  	 * The output should be:
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
91
  	 *   HASH(sec1,saddr,sport,daddr,dport,sec1) + sseq + (count * 2^24)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
  	 *      + (HASH(sec2,saddr,sport,daddr,dport,count,sec2) % 2^24).
  	 * Where sseq is their sequence number and count increases every
  	 * minute by 1.
  	 * As an extra hack, we add a small "data" value that encodes the
  	 * MSS into the second hash value.
  	 */
  
  	return (cookie_hash(saddr, daddr, sport, dport, 0, 0) +
  		sseq + (count << COOKIEBITS) +
  		((cookie_hash(saddr, daddr, sport, dport, count, 1) + data)
  		 & COOKIEMASK));
  }
  
  /*
   * This retrieves the small "data" value from the syncookie.
   * If the syncookie is bad, the data returned will be out of
   * range.  This must be checked by the caller.
   *
   * The count value used to generate the cookie must be within
   * "maxdiff" if the current (passed-in) "count".  The return value
   * is (__u32)-1 if this test fails.
   */
714e85be3   Al Viro   [IPV6]: Assorted ...
114
115
  static __u32 check_tcp_syn_cookie(__u32 cookie, __be32 saddr, __be32 daddr,
  				  __be16 sport, __be16 dport, __u32 sseq,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
  				  __u32 count, __u32 maxdiff)
  {
  	__u32 diff;
  
  	/* Strip away the layers from the cookie */
  	cookie -= cookie_hash(saddr, daddr, sport, dport, 0, 0) + sseq;
  
  	/* Cookie is now reduced to (count * 2^24) ^ (hash % 2^24) */
  	diff = (count - (cookie >> COOKIEBITS)) & ((__u32) - 1 >> COOKIEBITS);
  	if (diff >= maxdiff)
  		return (__u32)-1;
  
  	return (cookie -
  		cookie_hash(saddr, daddr, sport, dport, count - diff, 1))
  		& COOKIEMASK;	/* Leaving the data behind */
  }
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
132
  /*
5918e2fb9   Florian Westphal   syncookies: updat...
133
134
135
136
137
138
   * MSS Values are taken from the 2009 paper
   * 'Measuring TCP Maximum Segment Size' by S. Alcock and R. Nelson:
   *  - values 1440 to 1460 accounted for 80% of observed mss values
   *  - values outside the 536-1460 range are rare (<0.2%).
   *
   * Table must be sorted.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
139
140
   */
  static __u16 const msstab[] = {
5918e2fb9   Florian Westphal   syncookies: updat...
141
142
143
144
145
146
147
148
  	64,
  	512,
  	536,
  	1024,
  	1440,
  	1460,
  	4312,
  	8960,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
149
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
150
151
152
153
154
155
156
  
  /*
   * Generate a syncookie.  mssp points to the mss, which is returned
   * rounded down to the value encoded in the cookie.
   */
  __u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb, __u16 *mssp)
  {
aa8223c7b   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
157
158
  	const struct iphdr *iph = ip_hdr(skb);
  	const struct tcphdr *th = tcp_hdr(skb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
159
160
  	int mssind;
  	const __u16 mss = *mssp;
a0f82f64e   Florian Westphal   syncookies: remov...
161
  	tcp_synq_overflow(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
162

5918e2fb9   Florian Westphal   syncookies: updat...
163
164
165
166
  	for (mssind = ARRAY_SIZE(msstab) - 1; mssind ; mssind--)
  		if (mss >= msstab[mssind])
  			break;
  	*mssp = msstab[mssind];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
167

de0744af1   Pavel Emelyanov   mib: add net to N...
168
  	NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESSENT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
169

aa8223c7b   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
170
171
  	return secure_tcp_syn_cookie(iph->saddr, iph->daddr,
  				     th->source, th->dest, ntohl(th->seq),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
172
173
  				     jiffies / (HZ * 60), mssind);
  }
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
174
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
175
176
177
178
179
180
   * This (misnamed) value is the age of syncookie which is permitted.
   * Its ideal value should be dependent on TCP_TIMEOUT_INIT and
   * sysctl_tcp_retries1. It's a rather complicated formula (exponential
   * backoff) to compute at runtime so it's currently hardcoded here.
   */
  #define COUNTER_TRIES 4
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
181
182
  /*
   * Check if a ack sequence number is a valid syncookie.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
183
184
185
186
   * Return the decoded mss if it is, or 0 if not.
   */
  static inline int cookie_check(struct sk_buff *skb, __u32 cookie)
  {
aa8223c7b   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
187
188
189
190
191
192
193
  	const struct iphdr *iph = ip_hdr(skb);
  	const struct tcphdr *th = tcp_hdr(skb);
  	__u32 seq = ntohl(th->seq) - 1;
  	__u32 mssind = check_tcp_syn_cookie(cookie, iph->saddr, iph->daddr,
  					    th->source, th->dest, seq,
  					    jiffies / (HZ * 60),
  					    COUNTER_TRIES);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
194

5918e2fb9   Florian Westphal   syncookies: updat...
195
  	return mssind < ARRAY_SIZE(msstab) ? msstab[mssind] : 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
196
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
197
  static inline struct sock *get_cookie_sock(struct sock *sk, struct sk_buff *skb,
60236fdd0   Arnaldo Carvalho de Melo   [NET] Rename open...
198
  					   struct request_sock *req,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
199
200
  					   struct dst_entry *dst)
  {
8292a17a3   Arnaldo Carvalho de Melo   [ICSK]: Rename st...
201
  	struct inet_connection_sock *icsk = inet_csk(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
202
  	struct sock *child;
8292a17a3   Arnaldo Carvalho de Melo   [ICSK]: Rename st...
203
  	child = icsk->icsk_af_ops->syn_recv_sock(sk, skb, req, dst);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
204
  	if (child)
463c84b97   Arnaldo Carvalho de Melo   [NET]: Introduce ...
205
  		inet_csk_reqsk_queue_add(sk, req, child);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
206
  	else
60236fdd0   Arnaldo Carvalho de Melo   [NET] Rename open...
207
  		reqsk_free(req);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
208
209
210
  
  	return child;
  }
4dfc28170   Florian Westphal   [Syncookies]: Add...
211
212
213
214
215
216
  
  /*
   * when syncookies are in effect and tcp timestamps are enabled we stored
   * additional tcp options in the timestamp.
   * This extracts these options from the timestamp echo.
   *
734f614bc   Florian Westphal   syncookies: do no...
217
   * The lowest 4 bits store snd_wscale.
172d69e63   Florian Westphal   syncookies: add s...
218
   * next 2 bits indicate SACK and ECN support.
8c7636817   Florian Westphal   syncookies: check...
219
220
   *
   * return false if we decode an option that should not be.
4dfc28170   Florian Westphal   [Syncookies]: Add...
221
   */
172d69e63   Florian Westphal   syncookies: add s...
222
  bool cookie_check_timestamp(struct tcp_options_received *tcp_opt, bool *ecn_ok)
4dfc28170   Florian Westphal   [Syncookies]: Add...
223
  {
734f614bc   Florian Westphal   syncookies: do no...
224
  	/* echoed timestamp, lowest bits contain options */
4dfc28170   Florian Westphal   [Syncookies]: Add...
225
  	u32 options = tcp_opt->rcv_tsecr & TSMASK;
8c7636817   Florian Westphal   syncookies: check...
226
227
228
229
230
231
232
  	if (!tcp_opt->saw_tstamp)  {
  		tcp_clear_options(tcp_opt);
  		return true;
  	}
  
  	if (!sysctl_tcp_timestamps)
  		return false;
4dfc28170   Florian Westphal   [Syncookies]: Add...
233
  	tcp_opt->sack_ok = (options >> 4) & 0x1;
172d69e63   Florian Westphal   syncookies: add s...
234
235
236
  	*ecn_ok = (options >> 5) & 1;
  	if (*ecn_ok && !sysctl_tcp_ecn)
  		return false;
4dfc28170   Florian Westphal   [Syncookies]: Add...
237

8c7636817   Florian Westphal   syncookies: check...
238
239
  	if (tcp_opt->sack_ok && !sysctl_tcp_sack)
  		return false;
4dfc28170   Florian Westphal   [Syncookies]: Add...
240

734f614bc   Florian Westphal   syncookies: do no...
241
242
243
244
245
246
  	if ((options & 0xf) == 0xf)
  		return true; /* no window scaling */
  
  	tcp_opt->wscale_ok = 1;
  	tcp_opt->snd_wscale = options & 0xf;
  	return sysctl_tcp_window_scaling != 0;
4dfc28170   Florian Westphal   [Syncookies]: Add...
247
248
  }
  EXPORT_SYMBOL(cookie_check_timestamp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
249
250
251
  struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
  			     struct ip_options *opt)
  {
4957faade   William Allen Simpson   TCPCT part 1g: Re...
252
253
  	struct tcp_options_received tcp_opt;
  	u8 *hash_location;
2e6599cb8   Arnaldo Carvalho de Melo   [NET] Generalise ...
254
255
  	struct inet_request_sock *ireq;
  	struct tcp_request_sock *treq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
256
  	struct tcp_sock *tp = tcp_sk(sk);
aa8223c7b   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
257
258
  	const struct tcphdr *th = tcp_hdr(skb);
  	__u32 cookie = ntohl(th->ack_seq) - 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
259
  	struct sock *ret = sk;
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
260
261
262
  	struct request_sock *req;
  	int mss;
  	struct rtable *rt;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
263
  	__u8 rcv_wscale;
172d69e63   Florian Westphal   syncookies: add s...
264
  	bool ecn_ok;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265

af9b47385   Florian Westphal   syncookies: avoid...
266
  	if (!sysctl_tcp_syncookies || !th->ack || th->rst)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
267
  		goto out;
a0f82f64e   Florian Westphal   syncookies: remov...
268
  	if (tcp_synq_no_recent_overflow(sk) ||
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
269
  	    (mss = cookie_check(skb, cookie)) == 0) {
de0744af1   Pavel Emelyanov   mib: add net to N...
270
  		NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESFAILED);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
271
272
  		goto out;
  	}
de0744af1   Pavel Emelyanov   mib: add net to N...
273
  	NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESRECV);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
274

bb5b7c112   David S. Miller   tcp: Revert per-r...
275
276
277
  	/* check for timestamp cookie support */
  	memset(&tcp_opt, 0, sizeof(tcp_opt));
  	tcp_parse_options(skb, &tcp_opt, &hash_location, 0);
172d69e63   Florian Westphal   syncookies: add s...
278
  	if (!cookie_check_timestamp(&tcp_opt, &ecn_ok))
8c7636817   Florian Westphal   syncookies: check...
279
  		goto out;
bb5b7c112   David S. Miller   tcp: Revert per-r...
280

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
281
  	ret = NULL;
ce4a7d0d4   Arnaldo Carvalho de Melo   inet{6}_request_s...
282
  	req = inet_reqsk_alloc(&tcp_request_sock_ops); /* for safety */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
283
284
  	if (!req)
  		goto out;
2e6599cb8   Arnaldo Carvalho de Melo   [NET] Generalise ...
285
286
  	ireq = inet_rsk(req);
  	treq = tcp_rsk(req);
aa8223c7b   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
287
  	treq->rcv_isn		= ntohl(th->seq) - 1;
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
288
  	treq->snt_isn		= cookie;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
289
  	req->mss		= mss;
a3116ac5c   KOVACS Krisztian   tcp: Port redirec...
290
  	ireq->loc_port		= th->dest;
aa8223c7b   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
291
  	ireq->rmt_port		= th->source;
eddc9ec53   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
292
293
  	ireq->loc_addr		= ip_hdr(skb)->daddr;
  	ireq->rmt_addr		= ip_hdr(skb)->saddr;
172d69e63   Florian Westphal   syncookies: add s...
294
  	ireq->ecn_ok		= ecn_ok;
bb5b7c112   David S. Miller   tcp: Revert per-r...
295
  	ireq->snd_wscale	= tcp_opt.snd_wscale;
bb5b7c112   David S. Miller   tcp: Revert per-r...
296
297
298
299
  	ireq->sack_ok		= tcp_opt.sack_ok;
  	ireq->wscale_ok		= tcp_opt.wscale_ok;
  	ireq->tstamp_ok		= tcp_opt.saw_tstamp;
  	req->ts_recent		= tcp_opt.saw_tstamp ? tcp_opt.rcv_tsval : 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
300
301
302
303
304
305
  
  	/* We throwed the options of the initial SYN away, so we hope
  	 * the ACK carries the same options again (see RFC1122 4.2.3.8)
  	 */
  	if (opt && opt->optlen) {
  		int opt_size = sizeof(struct ip_options) + opt->optlen;
2e6599cb8   Arnaldo Carvalho de Melo   [NET] Generalise ...
306
307
308
309
  		ireq->opt = kmalloc(opt_size, GFP_ATOMIC);
  		if (ireq->opt != NULL && ip_options_echo(ireq->opt, skb)) {
  			kfree(ireq->opt);
  			ireq->opt = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
310
311
  		}
  	}
284904aa7   Paul Moore   lsm: Relocate the...
312
313
314
315
  	if (security_inet_conn_request(sk, skb, req)) {
  		reqsk_free(req);
  		goto out;
  	}
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
316
317
  	req->expires	= 0UL;
  	req->retrans	= 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
318
319
320
321
  	/*
  	 * We need to lookup the route here to get at the correct
  	 * window size. We should better make sure that the window size
  	 * hasn't changed since we received the original syn, but I see
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
322
  	 * no easy way to do this.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
323
324
  	 */
  	{
ffce90824   Atis Elsts   net: Add sk_mark ...
325
  		struct flowi fl = { .mark = sk->sk_mark,
5811662b1   Changli Gao   net: use the macr...
326
327
328
329
  				    .fl4_dst = ((opt && opt->srr) ?
  						opt->faddr : ireq->rmt_addr),
  				    .fl4_src = ireq->loc_addr,
  				    .fl4_tos = RT_CONN_FLAGS(sk),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
330
  				    .proto = IPPROTO_TCP,
86b08d867   KOVACS Krisztian   ipv4: Make Netfil...
331
  				    .flags = inet_sk_flowi_flags(sk),
5811662b1   Changli Gao   net: use the macr...
332
333
  				    .fl_ip_sport = th->dest,
  				    .fl_ip_dport = th->source };
4237c75c0   Venkat Yekkirala   [MLSXFRM]: Auto-l...
334
  		security_req_classify_flow(req, &fl);
c44649216   Eric Dumazet   tcp: use correct ...
335
  		if (ip_route_output_key(sock_net(sk), &rt, &fl)) {
60236fdd0   Arnaldo Carvalho de Melo   [NET] Rename open...
336
  			reqsk_free(req);
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
337
  			goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
338
339
340
341
  		}
  	}
  
  	/* Try to redo what tcp_v4_send_synack did. */
d8d1f30b9   Changli Gao   net-next: remove ...
342
  	req->window_clamp = tp->window_clamp ? :dst_metric(&rt->dst, RTAX_WINDOW);
4dfc28170   Florian Westphal   [Syncookies]: Add...
343

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
344
  	tcp_select_initial_window(tcp_full_space(sk), req->mss,
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
345
  				  &req->rcv_wnd, &req->window_clamp,
31d12926e   laurent chavey   net: Add rtnetlin...
346
  				  ireq->wscale_ok, &rcv_wscale,
d8d1f30b9   Changli Gao   net-next: remove ...
347
  				  dst_metric(&rt->dst, RTAX_INITRWND));
4dfc28170   Florian Westphal   [Syncookies]: Add...
348

e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
349
  	ireq->rcv_wscale  = rcv_wscale;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
350

d8d1f30b9   Changli Gao   net-next: remove ...
351
  	ret = get_cookie_sock(sk, skb, req, &rt->dst);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
352
353
  out:	return ret;
  }