Blame view

net/ipv4/tcp_ipv4.c 72.1 KB
2874c5fd2   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
6
7
8
  /*
   * INET		An implementation of the TCP/IP protocol suite for the LINUX
   *		operating system.  INET is implemented using the  BSD Socket
   *		interface as the means of communication with the user level.
   *
   *		Implementation of the Transmission Control Protocol(TCP).
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
9
10
   *		IPv4 specific functions
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
11
12
13
14
15
16
   *		code split from:
   *		linux/ipv4/tcp.c
   *		linux/ipv4/tcp_input.c
   *		linux/ipv4/tcp_output.c
   *
   *		See tcp.c for author information
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
   */
  
  /*
   * Changes:
   *		David S. Miller	:	New socket lookup architecture.
   *					This code is dedicated to John Dyson.
   *		David S. Miller :	Change semantics of established hash,
   *					half is devoted to TIME_WAIT sockets
   *					and the rest go in the other half.
   *		Andi Kleen :		Add support for syncookies and fixed
   *					some bugs: ip options weren't passed to
   *					the TCP layer, missed a check for an
   *					ACK bit.
   *		Andi Kleen :		Implemented fast path mtu discovery.
   *	     				Fixed many serious bugs in the
60236fdd0   Arnaldo Carvalho de Melo   [NET] Rename open...
32
   *					request_sock handling and moved
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
33
34
   *					most of it into the af independent code.
   *					Added tail drop and some other bugfixes.
caa20d9ab   Stephen Hemminger   [TCP]: spelling f...
35
   *					Added new listen semantics.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36
37
38
39
40
41
42
43
44
45
46
   *		Mike McLagan	:	Routing by source
   *	Juan Jose Ciarlante:		ip_dynaddr bits
   *		Andi Kleen:		various fixes.
   *	Vitaly E. Lavrov	:	Transparent proxy revived after year
   *					coma.
   *	Andi Kleen		:	Fix new listen.
   *	Andi Kleen		:	Fix accept error reporting.
   *	YOSHIFUJI Hideaki @USAGI and:	Support IPV6_V6ONLY socket option, which
   *	Alexey Kuznetsov		allow both IPv4 and IPv6 sockets to bind
   *					a single port at the same time.
   */
afd465030   Joe Perches   net: ipv4: Standa...
47
  #define pr_fmt(fmt) "TCP: " fmt
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
48

eb4dea585   Herbert Xu   net: Fix percpu c...
49
  #include <linux/bottom_half.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50
51
52
53
54
55
56
57
  #include <linux/types.h>
  #include <linux/fcntl.h>
  #include <linux/module.h>
  #include <linux/random.h>
  #include <linux/cache.h>
  #include <linux/jhash.h>
  #include <linux/init.h>
  #include <linux/times.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
58
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59

457c4cbc5   Eric W. Biederman   [NET]: Make /proc...
60
  #include <net/net_namespace.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
  #include <net/icmp.h>
304a16180   Arnaldo Carvalho de Melo   [INET]: Move the ...
62
  #include <net/inet_hashtables.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
63
  #include <net/tcp.h>
20380731b   Arnaldo Carvalho de Melo   [NET]: Fix sparse...
64
  #include <net/transp_v6.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
65
66
  #include <net/ipv6.h>
  #include <net/inet_common.h>
6d6ee43e0   Arnaldo Carvalho de Melo   [TWSK]: Introduce...
67
  #include <net/timewait_sock.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
68
  #include <net/xfrm.h>
6e5714eaf   David S. Miller   net: Compute prot...
69
  #include <net/secure_seq.h>
076bb0c82   Eliezer Tamir   net: rename inclu...
70
  #include <net/busy_poll.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71
72
73
74
75
76
  
  #include <linux/inet.h>
  #include <linux/ipv6.h>
  #include <linux/stddef.h>
  #include <linux/proc_fs.h>
  #include <linux/seq_file.h>
6797318e6   Ivan Delalande   tcp: md5: add an ...
77
  #include <linux/inetdevice.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
78

cf80e0e47   Herbert Xu   tcp: Use ahash
79
  #include <crypto/hash.h>
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
80
  #include <linux/scatterlist.h>
c24b14c46   Song Liu   tcp: add tracepoi...
81
  #include <trace/events/tcp.h>
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
82
  #ifdef CONFIG_TCP_MD5SIG
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
83
  static int tcp_v4_md5_hash_hdr(char *md5_hash, const struct tcp_md5sig_key *key,
318cf7aaa   Eric Dumazet   tcp: md5: add mor...
84
  			       __be32 daddr, __be32 saddr, const struct tcphdr *th);
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
85
  #endif
5caea4ea7   Eric Dumazet   net: listening_ha...
86
  struct inet_hashinfo tcp_hashinfo;
4bc2f18ba   Eric Dumazet   net/ipv4: EXPORT_...
87
  EXPORT_SYMBOL(tcp_hashinfo);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
88

84b114b98   Eric Dumazet   tcp: randomize ti...
89
  static u32 tcp_v4_init_seq(const struct sk_buff *skb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
90
  {
84b114b98   Eric Dumazet   tcp: randomize ti...
91
92
93
94
95
  	return secure_tcp_seq(ip_hdr(skb)->daddr,
  			      ip_hdr(skb)->saddr,
  			      tcp_hdr(skb)->dest,
  			      tcp_hdr(skb)->source);
  }
5d2ed0521   Eric Dumazet   tcp: Namespaceify...
96
  static u32 tcp_v4_init_ts_off(const struct net *net, const struct sk_buff *skb)
84b114b98   Eric Dumazet   tcp: randomize ti...
97
  {
5d2ed0521   Eric Dumazet   tcp: Namespaceify...
98
  	return secure_tcp_ts_off(net, ip_hdr(skb)->daddr, ip_hdr(skb)->saddr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
99
  }
6d6ee43e0   Arnaldo Carvalho de Melo   [TWSK]: Introduce...
100
101
  int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp)
  {
79e9fed46   Maciej Żenczykowski   net-tcp: extend t...
102
  	const struct inet_timewait_sock *tw = inet_twsk(sktw);
6d6ee43e0   Arnaldo Carvalho de Melo   [TWSK]: Introduce...
103
104
  	const struct tcp_timewait_sock *tcptw = tcp_twsk(sktw);
  	struct tcp_sock *tp = tcp_sk(sk);
79e9fed46   Maciej Żenczykowski   net-tcp: extend t...
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
  	int reuse = sock_net(sk)->ipv4.sysctl_tcp_tw_reuse;
  
  	if (reuse == 2) {
  		/* Still does not detect *everything* that goes through
  		 * lo, since we require a loopback src or dst address
  		 * or direct binding to 'lo' interface.
  		 */
  		bool loopback = false;
  		if (tw->tw_bound_dev_if == LOOPBACK_IFINDEX)
  			loopback = true;
  #if IS_ENABLED(CONFIG_IPV6)
  		if (tw->tw_family == AF_INET6) {
  			if (ipv6_addr_loopback(&tw->tw_v6_daddr) ||
  			    (ipv6_addr_v4mapped(&tw->tw_v6_daddr) &&
  			     (tw->tw_v6_daddr.s6_addr[12] == 127)) ||
  			    ipv6_addr_loopback(&tw->tw_v6_rcv_saddr) ||
  			    (ipv6_addr_v4mapped(&tw->tw_v6_rcv_saddr) &&
  			     (tw->tw_v6_rcv_saddr.s6_addr[12] == 127)))
  				loopback = true;
  		} else
  #endif
  		{
  			if (ipv4_is_loopback(tw->tw_daddr) ||
  			    ipv4_is_loopback(tw->tw_rcv_saddr))
  				loopback = true;
  		}
  		if (!loopback)
  			reuse = 0;
  	}
6d6ee43e0   Arnaldo Carvalho de Melo   [TWSK]: Introduce...
134
135
136
137
138
139
140
141
142
143
144
145
146
  
  	/* With PAWS, it is safe from the viewpoint
  	   of data integrity. Even without PAWS it is safe provided sequence
  	   spaces do not overlap i.e. at data rates <= 80Mbit/sec.
  
  	   Actually, the idea is close to VJ's one, only timestamp cache is
  	   held not per host, but per port pair and TW bucket is used as state
  	   holder.
  
  	   If TW bucket has been already destroyed we fall back to VJ's scheme
  	   and use initial timestamp retrieved from peer table.
  	 */
  	if (tcptw->tw_ts_recent_stamp &&
cca9bab1b   Arnd Bergmann   tcp: use monotoni...
147
148
  	    (!twp || (reuse && time_after32(ktime_get_seconds(),
  					    tcptw->tw_ts_recent_stamp)))) {
21684dc46   Stefan Baranoff   tcp: fix sequence...
149
150
151
152
153
154
155
156
157
158
159
160
  		/* In case of repair and re-using TIME-WAIT sockets we still
  		 * want to be sure that it is safe as above but honor the
  		 * sequence numbers and time stamps set as part of the repair
  		 * process.
  		 *
  		 * Without this check re-using a TIME-WAIT socket with TCP
  		 * repair would accumulate a -1 on the repair assigned
  		 * sequence number. The first time it is reused the sequence
  		 * is -1, the second time -2, etc. This fixes that issue
  		 * without appearing to create any others.
  		 */
  		if (likely(!tp->repair)) {
0f3174645   Eric Dumazet   tcp: annotate tp-...
161
162
163
164
165
  			u32 seq = tcptw->tw_snd_nxt + 65535 + 2;
  
  			if (!seq)
  				seq = 1;
  			WRITE_ONCE(tp->write_seq, seq);
21684dc46   Stefan Baranoff   tcp: fix sequence...
166
167
168
  			tp->rx_opt.ts_recent	   = tcptw->tw_ts_recent;
  			tp->rx_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp;
  		}
6d6ee43e0   Arnaldo Carvalho de Melo   [TWSK]: Introduce...
169
170
171
172
173
174
  		sock_hold(sktw);
  		return 1;
  	}
  
  	return 0;
  }
6d6ee43e0   Arnaldo Carvalho de Melo   [TWSK]: Introduce...
175
  EXPORT_SYMBOL_GPL(tcp_twsk_unique);
d74bad4e7   Andrey Ignatov   bpf: Hooks for sy...
176
177
178
179
180
181
182
183
184
185
186
187
188
189
  static int tcp_v4_pre_connect(struct sock *sk, struct sockaddr *uaddr,
  			      int addr_len)
  {
  	/* This check is replicated from tcp_v4_connect() and intended to
  	 * prevent BPF program called below from accessing bytes that are out
  	 * of the bound specified by user in addr_len.
  	 */
  	if (addr_len < sizeof(struct sockaddr_in))
  		return -EINVAL;
  
  	sock_owned_by_me(sk);
  
  	return BPF_CGROUP_RUN_PROG_INET4_CONNECT(sk, uaddr);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
190
191
192
  /* This will initiate an outgoing connection. */
  int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
  {
2d7192d6c   David S. Miller   ipv4: Sanitize an...
193
  	struct sockaddr_in *usin = (struct sockaddr_in *)uaddr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
194
195
  	struct inet_sock *inet = inet_sk(sk);
  	struct tcp_sock *tp = tcp_sk(sk);
dca8b089c   David S. Miller   ipv4: Rearrange h...
196
  	__be16 orig_sport, orig_dport;
bada8adc4   Al Viro   [IPV4]: ip_route_...
197
  	__be32 daddr, nexthop;
da905bd1d   David S. Miller   tcp: Use cork flo...
198
  	struct flowi4 *fl4;
2d7192d6c   David S. Miller   ipv4: Sanitize an...
199
  	struct rtable *rt;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
200
  	int err;
f6d8bd051   Eric Dumazet   inet: add RCU pro...
201
  	struct ip_options_rcu *inet_opt;
1946e672c   Haishuang Yan   ipv4: Namespaceif...
202
  	struct inet_timewait_death_row *tcp_death_row = &sock_net(sk)->ipv4.tcp_death_row;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
203
204
205
206
207
208
209
210
  
  	if (addr_len < sizeof(struct sockaddr_in))
  		return -EINVAL;
  
  	if (usin->sin_family != AF_INET)
  		return -EAFNOSUPPORT;
  
  	nexthop = daddr = usin->sin_addr.s_addr;
f6d8bd051   Eric Dumazet   inet: add RCU pro...
211
  	inet_opt = rcu_dereference_protected(inet->inet_opt,
1e1d04e67   Hannes Frederic Sowa   net: introduce lo...
212
  					     lockdep_sock_is_held(sk));
f6d8bd051   Eric Dumazet   inet: add RCU pro...
213
  	if (inet_opt && inet_opt->opt.srr) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
214
215
  		if (!daddr)
  			return -EINVAL;
f6d8bd051   Eric Dumazet   inet: add RCU pro...
216
  		nexthop = inet_opt->opt.faddr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
217
  	}
dca8b089c   David S. Miller   ipv4: Rearrange h...
218
219
  	orig_sport = inet->inet_sport;
  	orig_dport = usin->sin_port;
da905bd1d   David S. Miller   tcp: Use cork flo...
220
221
  	fl4 = &inet->cork.fl.u.ip4;
  	rt = ip_route_connect(fl4, nexthop, inet->inet_saddr,
b23dd4fe4   David S. Miller   ipv4: Make output...
222
223
  			      RT_CONN_FLAGS(sk), sk->sk_bound_dev_if,
  			      IPPROTO_TCP,
0e0d44ab4   Steffen Klassert   net: Remove FLOWI...
224
  			      orig_sport, orig_dport, sk);
b23dd4fe4   David S. Miller   ipv4: Make output...
225
226
227
  	if (IS_ERR(rt)) {
  		err = PTR_ERR(rt);
  		if (err == -ENETUNREACH)
f1d8cba61   Eric Dumazet   inet: fix possibl...
228
  			IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
b23dd4fe4   David S. Miller   ipv4: Make output...
229
  		return err;
584bdf8cb   Wei Dong   [IPV4]: Fix "ipOu...
230
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
231
232
233
234
235
  
  	if (rt->rt_flags & (RTCF_MULTICAST | RTCF_BROADCAST)) {
  		ip_rt_put(rt);
  		return -ENETUNREACH;
  	}
f6d8bd051   Eric Dumazet   inet: add RCU pro...
236
  	if (!inet_opt || !inet_opt->opt.srr)
da905bd1d   David S. Miller   tcp: Use cork flo...
237
  		daddr = fl4->daddr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
238

c720c7e83   Eric Dumazet   inet: rename some...
239
  	if (!inet->inet_saddr)
da905bd1d   David S. Miller   tcp: Use cork flo...
240
  		inet->inet_saddr = fl4->saddr;
d1e559d0b   Eric Dumazet   inet: add IPv6 su...
241
  	sk_rcv_saddr_set(sk, inet->inet_saddr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
242

c720c7e83   Eric Dumazet   inet: rename some...
243
  	if (tp->rx_opt.ts_recent_stamp && inet->inet_daddr != daddr) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
244
245
246
  		/* Reset inherited state */
  		tp->rx_opt.ts_recent	   = 0;
  		tp->rx_opt.ts_recent_stamp = 0;
ee9952831   Pavel Emelyanov   tcp: Initial repa...
247
  		if (likely(!tp->repair))
0f3174645   Eric Dumazet   tcp: annotate tp-...
248
  			WRITE_ONCE(tp->write_seq, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
249
  	}
c720c7e83   Eric Dumazet   inet: rename some...
250
  	inet->inet_dport = usin->sin_port;
d1e559d0b   Eric Dumazet   inet: add IPv6 su...
251
  	sk_daddr_set(sk, daddr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
252

d83d8461f   Arnaldo Carvalho de Melo   [IP_SOCKGLUE]: Re...
253
  	inet_csk(sk)->icsk_ext_hdr_len = 0;
f6d8bd051   Eric Dumazet   inet: add RCU pro...
254
255
  	if (inet_opt)
  		inet_csk(sk)->icsk_ext_hdr_len = inet_opt->opt.optlen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
256

bee7ca9ec   William Allen Simpson   net: TCP_MSS_DEFA...
257
  	tp->rx_opt.mss_clamp = TCP_MSS_DEFAULT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
258
259
260
261
262
263
264
  
  	/* Socket identity is still unknown (sport may be zero).
  	 * However we set state to SYN-SENT and not releasing socket
  	 * lock select source port, enter ourselves into the hash tables and
  	 * complete initialization after this.
  	 */
  	tcp_set_state(sk, TCP_SYN_SENT);
1946e672c   Haishuang Yan   ipv4: Namespaceif...
265
  	err = inet_hash_connect(tcp_death_row, sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
266
267
  	if (err)
  		goto failure;
877d1f629   Tom Herbert   net: Set sk_txhas...
268
  	sk_set_txhash(sk);
9e7ceb060   Sathya Perla   net: fix saving T...
269

da905bd1d   David S. Miller   tcp: Use cork flo...
270
  	rt = ip_route_newports(fl4, rt, orig_sport, orig_dport,
b23dd4fe4   David S. Miller   ipv4: Make output...
271
272
273
274
  			       inet->inet_sport, inet->inet_dport, sk);
  	if (IS_ERR(rt)) {
  		err = PTR_ERR(rt);
  		rt = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
275
  		goto failure;
b23dd4fe4   David S. Miller   ipv4: Make output...
276
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
277
  	/* OK, now commit destination to socket.  */
bcd761111   Herbert Xu   [NET]: Generalise...
278
  	sk->sk_gso_type = SKB_GSO_TCPV4;
d8d1f30b9   Changli Gao   net-next: remove ...
279
  	sk_setup_caps(sk, &rt->dst);
19f6d3f3c   Wei Wang   net/tcp-fastopen:...
280
  	rt = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
281

00355fa5b   Alexey Kodanev   tcp: setup timest...
282
  	if (likely(!tp->repair)) {
00355fa5b   Alexey Kodanev   tcp: setup timest...
283
  		if (!tp->write_seq)
0f3174645   Eric Dumazet   tcp: annotate tp-...
284
285
286
287
288
  			WRITE_ONCE(tp->write_seq,
  				   secure_tcp_seq(inet->inet_saddr,
  						  inet->inet_daddr,
  						  inet->inet_sport,
  						  usin->sin_port));
5d2ed0521   Eric Dumazet   tcp: Namespaceify...
289
290
  		tp->tsoffset = secure_tcp_ts_off(sock_net(sk),
  						 inet->inet_saddr,
84b114b98   Eric Dumazet   tcp: randomize ti...
291
  						 inet->inet_daddr);
00355fa5b   Alexey Kodanev   tcp: setup timest...
292
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
293

a904a0693   Eric Dumazet   inet: stop leakin...
294
  	inet->inet_id = prandom_u32();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
295

19f6d3f3c   Wei Wang   net/tcp-fastopen:...
296
297
298
299
  	if (tcp_fastopen_defer_connect(sk, &err))
  		return err;
  	if (err)
  		goto failure;
2b9164771   Andrey Vagin   ipv6: adapt conne...
300
  	err = tcp_connect(sk);
ee9952831   Pavel Emelyanov   tcp: Initial repa...
301

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
302
303
304
305
306
307
  	if (err)
  		goto failure;
  
  	return 0;
  
  failure:
7174259e6   Arnaldo Carvalho de Melo   [TCP_IPV4]: Codin...
308
309
310
311
  	/*
  	 * This unhashes the socket and releases the local port,
  	 * if necessary.
  	 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
312
313
314
  	tcp_set_state(sk, TCP_CLOSE);
  	ip_rt_put(rt);
  	sk->sk_route_caps = 0;
c720c7e83   Eric Dumazet   inet: rename some...
315
  	inet->inet_dport = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
316
317
  	return err;
  }
4bc2f18ba   Eric Dumazet   net/ipv4: EXPORT_...
318
  EXPORT_SYMBOL(tcp_v4_connect);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
319

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
320
  /*
563d34d05   Eric Dumazet   tcp: dont drop MT...
321
322
323
   * This routine reacts to ICMP_FRAG_NEEDED mtu indications as defined in RFC1191.
   * It can be called through tcp_release_cb() if socket was owned by user
   * at the time tcp_v4_err() was called to handle ICMP message.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
324
   */
4fab90719   Neal Cardwell   tcp: fix tcp_rele...
325
  void tcp_v4_mtu_reduced(struct sock *sk)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
326
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
327
  	struct inet_sock *inet = inet_sk(sk);
02b2faaf0   Eric Dumazet   tcp: fix various ...
328
329
  	struct dst_entry *dst;
  	u32 mtu;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
330

02b2faaf0   Eric Dumazet   tcp: fix various ...
331
332
333
  	if ((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE))
  		return;
  	mtu = tcp_sk(sk)->mtu_info;
80d0a69fc   David S. Miller   ipv4: Add helper ...
334
335
  	dst = inet_csk_update_pmtu(sk, mtu);
  	if (!dst)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
336
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
337
338
339
340
341
342
343
344
345
  	/* Something is about to be wrong... Remember soft error
  	 * for the case, if this connection will not able to recover.
  	 */
  	if (mtu < dst_mtu(dst) && ip_dont_fragment(sk, dst))
  		sk->sk_err_soft = EMSGSIZE;
  
  	mtu = dst_mtu(dst);
  
  	if (inet->pmtudisc != IP_PMTUDISC_DONT &&
482fc6094   Hannes Frederic Sowa   ipv4: introduce n...
346
  	    ip_sk_accept_pmtu(sk) &&
d83d8461f   Arnaldo Carvalho de Melo   [IP_SOCKGLUE]: Re...
347
  	    inet_csk(sk)->icsk_pmtu_cookie > mtu) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
348
349
350
351
352
353
354
355
356
357
  		tcp_sync_mss(sk, mtu);
  
  		/* Resend the TCP packet because it's
  		 * clear that the old packet has been
  		 * dropped. This is the new "fast" path mtu
  		 * discovery.
  		 */
  		tcp_simple_retransmit(sk);
  	} /* else let the usual retransmit timer handle it */
  }
4fab90719   Neal Cardwell   tcp: fix tcp_rele...
358
  EXPORT_SYMBOL(tcp_v4_mtu_reduced);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
359

55be7a9c6   David S. Miller   ipv4: Add redirec...
360
361
362
  static void do_redirect(struct sk_buff *skb, struct sock *sk)
  {
  	struct dst_entry *dst = __sk_dst_check(sk, 0);
1ed5c48f2   David S. Miller   net: Remove check...
363
  	if (dst)
6700c2709   David S. Miller   net: Pass optiona...
364
  		dst->ops->redirect(dst, sk, skb);
55be7a9c6   David S. Miller   ipv4: Add redirec...
365
  }
26e373609   Eric Dumazet   ipv4: tcp: handle...
366
367
  
  /* handle ICMP messages on TCP_NEW_SYN_RECV request sockets */
9cf749036   Eric Dumazet   tcp: do not drop ...
368
  void tcp_req_err(struct sock *sk, u32 seq, bool abort)
26e373609   Eric Dumazet   ipv4: tcp: handle...
369
370
371
372
373
374
375
  {
  	struct request_sock *req = inet_reqsk(sk);
  	struct net *net = sock_net(sk);
  
  	/* ICMPs are not backlogged, hence we cannot get
  	 * an established socket here.
  	 */
26e373609   Eric Dumazet   ipv4: tcp: handle...
376
  	if (seq != tcp_rsk(req)->snt_isn) {
02a1d6e7a   Eric Dumazet   net: rename NET_{...
377
  		__NET_INC_STATS(net, LINUX_MIB_OUTOFWINDOWICMPS);
9cf749036   Eric Dumazet   tcp: do not drop ...
378
  	} else if (abort) {
26e373609   Eric Dumazet   ipv4: tcp: handle...
379
380
381
382
383
384
  		/*
  		 * Still in SYN_RECV, just remove it silently.
  		 * There is no good way to pass the error to the newly
  		 * created socket, and POSIX does not want network
  		 * errors returned from accept().
  		 */
c69736696   Fan Du   inet: fix double ...
385
  		inet_csk_reqsk_queue_drop(req->rsk_listener, req);
9caad8641   Eric Dumazet   tcp: increment sk...
386
  		tcp_listendrop(req->rsk_listener);
26e373609   Eric Dumazet   ipv4: tcp: handle...
387
  	}
ef84d8ce5   Eric Dumazet   Revert "inet: fix...
388
  	reqsk_put(req);
26e373609   Eric Dumazet   ipv4: tcp: handle...
389
390
  }
  EXPORT_SYMBOL(tcp_req_err);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
  /*
   * This routine is called by the ICMP module when it gets some
   * sort of error condition.  If err < 0 then the socket should
   * be closed and the error returned to the user.  If err > 0
   * it's just the icmp type << 8 | icmp code.  After adjustment
   * header points to the first 8 bytes of the tcp header.  We need
   * to find the appropriate port.
   *
   * The locking strategy used here is very "optimistic". When
   * someone else accesses the socket the ICMP is just dropped
   * and for some paths there is no check at all.
   * A more general error queue to queue errors for later handling
   * is probably better.
   *
   */
32bbd8793   Stefano Brivio   net: Convert prot...
406
  int tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
407
  {
b71d1d426   Eric Dumazet   inet: constify ip...
408
  	const struct iphdr *iph = (const struct iphdr *)icmp_skb->data;
4d1a2d9ec   Damian Lukowski   Revert Backoff [v...
409
  	struct tcphdr *th = (struct tcphdr *)(icmp_skb->data + (iph->ihl << 2));
f1ecd5d9e   Damian Lukowski   Revert Backoff [v...
410
  	struct inet_connection_sock *icsk;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
411
412
  	struct tcp_sock *tp;
  	struct inet_sock *inet;
4d1a2d9ec   Damian Lukowski   Revert Backoff [v...
413
414
  	const int type = icmp_hdr(icmp_skb)->type;
  	const int code = icmp_hdr(icmp_skb)->code;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
415
  	struct sock *sk;
f1ecd5d9e   Damian Lukowski   Revert Backoff [v...
416
  	struct sk_buff *skb;
0a672f741   Yuchung Cheng   tcp: improve fast...
417
  	struct request_sock *fastopen;
9a568de48   Eric Dumazet   tcp: switch TCP T...
418
419
420
  	u32 seq, snd_una;
  	s32 remaining;
  	u32 delta_us;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
421
  	int err;
4d1a2d9ec   Damian Lukowski   Revert Backoff [v...
422
  	struct net *net = dev_net(icmp_skb->dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
423

26e373609   Eric Dumazet   ipv4: tcp: handle...
424
425
  	sk = __inet_lookup_established(net, &tcp_hashinfo, iph->daddr,
  				       th->dest, iph->saddr, ntohs(th->source),
3fa6f616a   David Ahern   net: ipv4: add se...
426
  				       inet_iif(icmp_skb), 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
427
  	if (!sk) {
5d3848bc3   Eric Dumazet   net: rename ICMP_...
428
  		__ICMP_INC_STATS(net, ICMP_MIB_INERRORS);
32bbd8793   Stefano Brivio   net: Convert prot...
429
  		return -ENOENT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
430
431
  	}
  	if (sk->sk_state == TCP_TIME_WAIT) {
9469c7b4a   YOSHIFUJI Hideaki   [NET]: Use typesa...
432
  		inet_twsk_put(inet_twsk(sk));
32bbd8793   Stefano Brivio   net: Convert prot...
433
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
434
  	}
26e373609   Eric Dumazet   ipv4: tcp: handle...
435
  	seq = ntohl(th->seq);
32bbd8793   Stefano Brivio   net: Convert prot...
436
437
438
439
440
441
442
443
  	if (sk->sk_state == TCP_NEW_SYN_RECV) {
  		tcp_req_err(sk, seq, type == ICMP_PARAMETERPROB ||
  				     type == ICMP_TIME_EXCEEDED ||
  				     (type == ICMP_DEST_UNREACH &&
  				      (code == ICMP_NET_UNREACH ||
  				       code == ICMP_HOST_UNREACH)));
  		return 0;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
444
445
446
447
  
  	bh_lock_sock(sk);
  	/* If too many ICMPs get dropped on busy
  	 * servers this needs to be solved differently.
563d34d05   Eric Dumazet   tcp: dont drop MT...
448
449
  	 * We do take care of PMTU discovery (RFC1191) special case :
  	 * we can receive locally generated ICMP messages while socket is held.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
450
  	 */
b74aa930e   Eric Dumazet   tcp: fix incorrec...
451
452
  	if (sock_owned_by_user(sk)) {
  		if (!(type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED))
02a1d6e7a   Eric Dumazet   net: rename NET_{...
453
  			__NET_INC_STATS(net, LINUX_MIB_LOCKDROPPEDICMPS);
b74aa930e   Eric Dumazet   tcp: fix incorrec...
454
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
455
456
  	if (sk->sk_state == TCP_CLOSE)
  		goto out;
97e3ecd11   stephen hemminger   TCP: check min TT...
457
  	if (unlikely(iph->ttl < inet_sk(sk)->min_ttl)) {
02a1d6e7a   Eric Dumazet   net: rename NET_{...
458
  		__NET_INC_STATS(net, LINUX_MIB_TCPMINTTLDROP);
97e3ecd11   stephen hemminger   TCP: check min TT...
459
460
  		goto out;
  	}
f1ecd5d9e   Damian Lukowski   Revert Backoff [v...
461
  	icsk = inet_csk(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
462
  	tp = tcp_sk(sk);
0a672f741   Yuchung Cheng   tcp: improve fast...
463
  	/* XXX (TFO) - tp->snd_una should be ISN (tcp_create_openreq_child() */
d983ea6f1   Eric Dumazet   tcp: add rcu prot...
464
  	fastopen = rcu_dereference(tp->fastopen_rsk);
0a672f741   Yuchung Cheng   tcp: improve fast...
465
  	snd_una = fastopen ? tcp_rsk(fastopen)->snt_isn : tp->snd_una;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
466
  	if (sk->sk_state != TCP_LISTEN &&
0a672f741   Yuchung Cheng   tcp: improve fast...
467
  	    !between(seq, snd_una, tp->snd_nxt)) {
02a1d6e7a   Eric Dumazet   net: rename NET_{...
468
  		__NET_INC_STATS(net, LINUX_MIB_OUTOFWINDOWICMPS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
469
470
471
472
  		goto out;
  	}
  
  	switch (type) {
55be7a9c6   David S. Miller   ipv4: Add redirec...
473
  	case ICMP_REDIRECT:
45caeaa5a   Jon Maxwell   dccp/tcp: fix rou...
474
475
  		if (!sock_owned_by_user(sk))
  			do_redirect(icmp_skb, sk);
55be7a9c6   David S. Miller   ipv4: Add redirec...
476
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
477
478
479
480
481
482
483
484
485
486
487
  	case ICMP_SOURCE_QUENCH:
  		/* Just silently ignore these. */
  		goto out;
  	case ICMP_PARAMETERPROB:
  		err = EPROTO;
  		break;
  	case ICMP_DEST_UNREACH:
  		if (code > NR_ICMP_UNREACH)
  			goto out;
  
  		if (code == ICMP_FRAG_NEEDED) { /* PMTU discovery (RFC1191) */
0d4f06086   Eric Dumazet   tcp: dont handle ...
488
489
490
491
492
493
  			/* We are not interested in TCP_LISTEN and open_requests
  			 * (SYN-ACKs send out by Linux are always <576bytes so
  			 * they should go through unfragmented).
  			 */
  			if (sk->sk_state == TCP_LISTEN)
  				goto out;
563d34d05   Eric Dumazet   tcp: dont drop MT...
494
  			tp->mtu_info = info;
144d56e91   Eric Dumazet   tcp: fix possible...
495
  			if (!sock_owned_by_user(sk)) {
563d34d05   Eric Dumazet   tcp: dont drop MT...
496
  				tcp_v4_mtu_reduced(sk);
144d56e91   Eric Dumazet   tcp: fix possible...
497
  			} else {
7aa5470c2   Eric Dumazet   tcp: tsq: move ts...
498
  				if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED, &sk->sk_tsq_flags))
144d56e91   Eric Dumazet   tcp: fix possible...
499
500
  					sock_hold(sk);
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
501
502
503
504
  			goto out;
  		}
  
  		err = icmp_err_convert[code].errno;
f1ecd5d9e   Damian Lukowski   Revert Backoff [v...
505
506
507
508
509
  		/* check if icmp_skb allows revert of backoff
  		 * (see draft-zimmermann-tcp-lcd) */
  		if (code != ICMP_NET_UNREACH && code != ICMP_HOST_UNREACH)
  			break;
  		if (seq != tp->snd_una  || !icsk->icsk_retransmits ||
0a672f741   Yuchung Cheng   tcp: improve fast...
510
  		    !icsk->icsk_backoff || fastopen)
f1ecd5d9e   Damian Lukowski   Revert Backoff [v...
511
  			break;
8f49c2703   David S. Miller   tcp: Don't change...
512
513
  		if (sock_owned_by_user(sk))
  			break;
2c4cc9712   Eric Dumazet   tcp: tcp_v4_err()...
514
515
516
  		skb = tcp_rtx_queue_head(sk);
  		if (WARN_ON_ONCE(!skb))
  			break;
f1ecd5d9e   Damian Lukowski   Revert Backoff [v...
517
  		icsk->icsk_backoff--;
fcdd1cf4d   Eric Dumazet   tcp: avoid possib...
518
519
520
  		icsk->icsk_rto = tp->srtt_us ? __tcp_set_rto(tp) :
  					       TCP_TIMEOUT_INIT;
  		icsk->icsk_rto = inet_csk_rto_backoff(icsk, TCP_RTO_MAX);
f1ecd5d9e   Damian Lukowski   Revert Backoff [v...
521

f1ecd5d9e   Damian Lukowski   Revert Backoff [v...
522

9a568de48   Eric Dumazet   tcp: switch TCP T...
523
  		tcp_mstamp_refresh(tp);
2fd66ffba   Eric Dumazet   tcp: introduce tc...
524
  		delta_us = (u32)(tp->tcp_mstamp - tcp_skb_timestamp_us(skb));
7faee5c0d   Eric Dumazet   tcp: remove TCP_S...
525
  		remaining = icsk->icsk_rto -
9a568de48   Eric Dumazet   tcp: switch TCP T...
526
  			    usecs_to_jiffies(delta_us);
f1ecd5d9e   Damian Lukowski   Revert Backoff [v...
527

9a568de48   Eric Dumazet   tcp: switch TCP T...
528
  		if (remaining > 0) {
f1ecd5d9e   Damian Lukowski   Revert Backoff [v...
529
530
  			inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
  						  remaining, TCP_RTO_MAX);
f1ecd5d9e   Damian Lukowski   Revert Backoff [v...
531
532
533
534
535
  		} else {
  			/* RTO revert clocked out retransmission.
  			 * Will retransmit now */
  			tcp_retransmit_timer(sk);
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
536
537
538
539
540
541
542
543
544
  		break;
  	case ICMP_TIME_EXCEEDED:
  		err = EHOSTUNREACH;
  		break;
  	default:
  		goto out;
  	}
  
  	switch (sk->sk_state) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
545
  	case TCP_SYN_SENT:
0a672f741   Yuchung Cheng   tcp: improve fast...
546
547
548
549
  	case TCP_SYN_RECV:
  		/* Only in fast or simultaneous open. If a fast open socket is
  		 * is already accepted it is treated as a connected one below.
  		 */
51456b291   Ian Morris   ipv4: coding styl...
550
  		if (fastopen && !fastopen->sk)
0a672f741   Yuchung Cheng   tcp: improve fast...
551
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
552
  		if (!sock_owned_by_user(sk)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
  			sk->sk_err = err;
  
  			sk->sk_error_report(sk);
  
  			tcp_done(sk);
  		} else {
  			sk->sk_err_soft = err;
  		}
  		goto out;
  	}
  
  	/* If we've already connected we will keep trying
  	 * until we time out, or the user gives up.
  	 *
  	 * rfc1122 4.2.3.9 allows to consider as hard errors
  	 * only PROTO_UNREACH and PORT_UNREACH (well, FRAG_FAILED too,
  	 * but it is obsoleted by pmtu discovery).
  	 *
  	 * Note, that in modern internet, where routing is unreliable
  	 * and in each dark corner broken firewalls sit, sending random
  	 * errors ordered by their masters even this two messages finally lose
  	 * their original sense (even Linux sends invalid PORT_UNREACHs)
  	 *
  	 * Now we are in compliance with RFCs.
  	 *							--ANK (980905)
  	 */
  
  	inet = inet_sk(sk);
  	if (!sock_owned_by_user(sk) && inet->recverr) {
  		sk->sk_err = err;
  		sk->sk_error_report(sk);
  	} else	{ /* Only an error on timeout */
  		sk->sk_err_soft = err;
  	}
  
  out:
  	bh_unlock_sock(sk);
  	sock_put(sk);
32bbd8793   Stefano Brivio   net: Convert prot...
591
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
592
  }
28850dc7c   Daniel Borkmann   net: tcp: move GR...
593
  void __tcp_v4_send_check(struct sk_buff *skb, __be32 saddr, __be32 daddr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
594
  {
aa8223c7b   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
595
  	struct tcphdr *th = tcp_hdr(skb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
596

98be9b120   Eric Dumazet   tcp: remove dead ...
597
598
599
  	th->check = ~tcp_v4_check(skb->len, saddr, daddr, 0);
  	skb->csum_start = skb_transport_header(skb) - skb->head;
  	skb->csum_offset = offsetof(struct tcphdr, check);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
600
  }
419f9f896   Herbert Xu   tcp: Handle CHECK...
601
  /* This routine computes an IPv4 TCP checksum. */
bb2962461   Herbert Xu   inet: Remove unus...
602
  void tcp_v4_send_check(struct sock *sk, struct sk_buff *skb)
419f9f896   Herbert Xu   tcp: Handle CHECK...
603
  {
cf533ea53   Eric Dumazet   tcp: add const qu...
604
  	const struct inet_sock *inet = inet_sk(sk);
419f9f896   Herbert Xu   tcp: Handle CHECK...
605
606
607
  
  	__tcp_v4_send_check(skb, inet->inet_saddr, inet->inet_daddr);
  }
4bc2f18ba   Eric Dumazet   net/ipv4: EXPORT_...
608
  EXPORT_SYMBOL(tcp_v4_send_check);
419f9f896   Herbert Xu   tcp: Handle CHECK...
609

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
610
611
612
613
614
615
616
617
618
619
620
621
  /*
   *	This routine will send an RST to the other tcp.
   *
   *	Someone asks: why I NEVER use socket parameters (TOS, TTL etc.)
   *		      for reset.
   *	Answer: if a packet caused RST, it is not for a socket
   *		existing in our system, if it is matched to a socket,
   *		it is just duplicate segment or bug in other side's TCP.
   *		So that we build reply only basing on parameters
   *		arrived with segment.
   *	Exception: precedence violation. We do not implement it in any case.
   */
a00e74442   Eric Dumazet   tcp/dccp: constif...
622
  static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
623
  {
cf533ea53   Eric Dumazet   tcp: add const qu...
624
  	const struct tcphdr *th = tcp_hdr(skb);
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
625
626
627
  	struct {
  		struct tcphdr th;
  #ifdef CONFIG_TCP_MD5SIG
714e85be3   Al Viro   [IPV6]: Assorted ...
628
  		__be32 opt[(TCPOLEN_MD5SIG_ALIGNED >> 2)];
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
629
630
  #endif
  	} rep;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
631
  	struct ip_reply_arg arg;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
632
  #ifdef CONFIG_TCP_MD5SIG
e46787f0d   Florian Westphal   tcp: send_reset: ...
633
  	struct tcp_md5sig_key *key = NULL;
658ddaaf6   Shawn Lu   tcp: md5: RST: ge...
634
635
636
637
  	const __u8 *hash_location = NULL;
  	unsigned char newhash[16];
  	int genhash;
  	struct sock *sk1 = NULL;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
638
  #endif
d6fb396cf   Eric Dumazet   ipv4: tcp: fix AC...
639
  	u64 transmit_time = 0;
004836905   Jon Maxwell   tcp: Add mark for...
640
  	struct sock *ctl_sk;
d6fb396cf   Eric Dumazet   ipv4: tcp: fix AC...
641
  	struct net *net;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
642
643
644
645
  
  	/* Never send a reset in response to a reset. */
  	if (th->rst)
  		return;
c3658e8d0   Eric Dumazet   tcp: fix possible...
646
647
648
649
  	/* If sk not NULL, it means we did a successful lookup and incoming
  	 * route had to be correct. prequeue might have dropped our dst.
  	 */
  	if (!sk && skb_rtable(skb)->rt_type != RTN_LOCAL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
650
651
652
  		return;
  
  	/* Swap the send and the receive. */
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
653
654
655
656
657
  	memset(&rep, 0, sizeof(rep));
  	rep.th.dest   = th->source;
  	rep.th.source = th->dest;
  	rep.th.doff   = sizeof(struct tcphdr) / 4;
  	rep.th.rst    = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
658
659
  
  	if (th->ack) {
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
660
  		rep.th.seq = th->ack_seq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
661
  	} else {
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
662
663
664
  		rep.th.ack = 1;
  		rep.th.ack_seq = htonl(ntohl(th->seq) + th->syn + th->fin +
  				       skb->len - (th->doff << 2));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
665
  	}
7174259e6   Arnaldo Carvalho de Melo   [TCP_IPV4]: Codin...
666
  	memset(&arg, 0, sizeof(arg));
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
667
668
  	arg.iov[0].iov_base = (unsigned char *)&rep;
  	arg.iov[0].iov_len  = sizeof(rep.th);
0f85feae6   Eric Dumazet   tcp: fix more NUL...
669
  	net = sk ? sock_net(sk) : dev_net(skb_dst(skb)->dev);
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
670
  #ifdef CONFIG_TCP_MD5SIG
3b24d854c   Eric Dumazet   tcp/dccp: do not ...
671
  	rcu_read_lock();
658ddaaf6   Shawn Lu   tcp: md5: RST: ge...
672
  	hash_location = tcp_parse_md5sig_option(th);
271c3b9b7   Florian Westphal   tcp: honour SO_BI...
673
  	if (sk && sk_fullsock(sk)) {
e46787f0d   Florian Westphal   tcp: send_reset: ...
674
675
676
  		key = tcp_md5_do_lookup(sk, (union tcp_md5_addr *)
  					&ip_hdr(skb)->saddr, AF_INET);
  	} else if (hash_location) {
658ddaaf6   Shawn Lu   tcp: md5: RST: ge...
677
678
679
680
681
682
683
  		/*
  		 * active side is lost. Try to find listening socket through
  		 * source port, and then find md5 key through listening socket.
  		 * we are not loose security here:
  		 * Incoming packet is checked with md5 hash with finding key,
  		 * no RST generated if md5 hash doesn't match.
  		 */
a583636a8   Craig Gallek   inet: refactor in...
684
685
  		sk1 = __inet_lookup_listener(net, &tcp_hashinfo, NULL, 0,
  					     ip_hdr(skb)->saddr,
da5e36308   Tom Herbert   soreuseport: TCP/...
686
  					     th->source, ip_hdr(skb)->daddr,
3fa6f616a   David Ahern   net: ipv4: add se...
687
688
  					     ntohs(th->source), inet_iif(skb),
  					     tcp_v4_sdif(skb));
658ddaaf6   Shawn Lu   tcp: md5: RST: ge...
689
690
  		/* don't send rst if it can't find key */
  		if (!sk1)
3b24d854c   Eric Dumazet   tcp/dccp: do not ...
691
  			goto out;
658ddaaf6   Shawn Lu   tcp: md5: RST: ge...
692
693
694
  		key = tcp_md5_do_lookup(sk1, (union tcp_md5_addr *)
  					&ip_hdr(skb)->saddr, AF_INET);
  		if (!key)
3b24d854c   Eric Dumazet   tcp/dccp: do not ...
695
  			goto out;
658ddaaf6   Shawn Lu   tcp: md5: RST: ge...
696

39f8e58e5   Eric Dumazet   tcp: md5: remove ...
697
  		genhash = tcp_v4_md5_hash_skb(newhash, key, NULL, skb);
658ddaaf6   Shawn Lu   tcp: md5: RST: ge...
698
  		if (genhash || memcmp(hash_location, newhash, 16) != 0)
3b24d854c   Eric Dumazet   tcp/dccp: do not ...
699
  			goto out;
658ddaaf6   Shawn Lu   tcp: md5: RST: ge...
700
  	}
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
701
702
703
704
705
706
707
708
  	if (key) {
  		rep.opt[0] = htonl((TCPOPT_NOP << 24) |
  				   (TCPOPT_NOP << 16) |
  				   (TCPOPT_MD5SIG << 8) |
  				   TCPOLEN_MD5SIG);
  		/* Update length and the length the header thinks exists */
  		arg.iov[0].iov_len += TCPOLEN_MD5SIG_ALIGNED;
  		rep.th.doff = arg.iov[0].iov_len / 4;
49a72dfb8   Adam Langley   tcp: Fix MD5 sign...
709
  		tcp_v4_md5_hash_hdr((__u8 *) &rep.opt[1],
78e645cb8   Ilpo Järvinen   tcpv[46]: fix md5...
710
711
  				     key, ip_hdr(skb)->saddr,
  				     ip_hdr(skb)->daddr, &rep.th);
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
712
713
  	}
  #endif
eddc9ec53   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
714
715
  	arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr,
  				      ip_hdr(skb)->saddr, /* XXX */
52cd5750e   Ilpo Järvinen   tcp: fix length u...
716
  				      arg.iov[0].iov_len, IPPROTO_TCP, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
717
  	arg.csumoffset = offsetof(struct tcphdr, check) / 2;
271c3b9b7   Florian Westphal   tcp: honour SO_BI...
718
  	arg.flags = (sk && inet_sk_transparent(sk)) ? IP_REPLY_ARG_NOSRCCHECK : 0;
e2446eaab   Shawn Lu   tcp_v4_send_reset...
719
  	/* When socket is gone, all binding information is lost.
4c6752584   Alexey Kuznetsov   tcp: resets are m...
720
721
  	 * routing might fail in this case. No choice here, if we choose to force
  	 * input interface, we will misroute in case of asymmetric route.
e2446eaab   Shawn Lu   tcp_v4_send_reset...
722
  	 */
c24b14c46   Song Liu   tcp: add tracepoi...
723
  	if (sk) {
4c6752584   Alexey Kuznetsov   tcp: resets are m...
724
  		arg.bound_dev_if = sk->sk_bound_dev_if;
5c487bb9a   Song Liu   tcp: tracepoint: ...
725
726
  		if (sk_fullsock(sk))
  			trace_tcp_send_reset(sk, skb);
c24b14c46   Song Liu   tcp: add tracepoi...
727
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
728

271c3b9b7   Florian Westphal   tcp: honour SO_BI...
729
730
  	BUILD_BUG_ON(offsetof(struct sock, sk_bound_dev_if) !=
  		     offsetof(struct inet_timewait_sock, tw_bound_dev_if));
66b13d99d   Eric Dumazet   ipv4: tcp: fix TO...
731
  	arg.tos = ip_hdr(skb)->tos;
e2d118a1c   Lorenzo Colitti   net: inet: Suppor...
732
  	arg.uid = sock_net_uid(net, sk && sk_fullsock(sk) ? sk : NULL);
47dcc20a3   Eric Dumazet   ipv4: tcp: ip_sen...
733
  	local_bh_disable();
5472c3c6a   Eric Dumazet   tcp: use this_cpu...
734
  	ctl_sk = this_cpu_read(*net->ipv4.tcp_sk);
a842fe142   Eric Dumazet   tcp: add optional...
735
  	if (sk) {
004836905   Jon Maxwell   tcp: Add mark for...
736
737
  		ctl_sk->sk_mark = (sk->sk_state == TCP_TIME_WAIT) ?
  				   inet_twsk(sk)->tw_mark : sk->sk_mark;
f6c0f5d20   Eric Dumazet   tcp: honor SO_PRI...
738
739
  		ctl_sk->sk_priority = (sk->sk_state == TCP_TIME_WAIT) ?
  				   inet_twsk(sk)->tw_priority : sk->sk_priority;
d6fb396cf   Eric Dumazet   ipv4: tcp: fix AC...
740
  		transmit_time = tcp_transmit_time(sk);
a842fe142   Eric Dumazet   tcp: add optional...
741
  	}
004836905   Jon Maxwell   tcp: Add mark for...
742
  	ip_send_unicast_reply(ctl_sk,
bdbbb8527   Eric Dumazet   ipv4: tcp: get ri...
743
  			      skb, &TCP_SKB_CB(skb)->header.h4.opt,
24a2d43d8   Eric Dumazet   ipv4: rename ip_o...
744
  			      ip_hdr(skb)->saddr, ip_hdr(skb)->daddr,
d6fb396cf   Eric Dumazet   ipv4: tcp: fix AC...
745
746
  			      &arg, arg.iov[0].iov_len,
  			      transmit_time);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
747

004836905   Jon Maxwell   tcp: Add mark for...
748
  	ctl_sk->sk_mark = 0;
90bbcc608   Eric Dumazet   net: tcp: rename ...
749
750
  	__TCP_INC_STATS(net, TCP_MIB_OUTSEGS);
  	__TCP_INC_STATS(net, TCP_MIB_OUTRSTS);
47dcc20a3   Eric Dumazet   ipv4: tcp: ip_sen...
751
  	local_bh_enable();
658ddaaf6   Shawn Lu   tcp: md5: RST: ge...
752
753
  
  #ifdef CONFIG_TCP_MD5SIG
3b24d854c   Eric Dumazet   tcp/dccp: do not ...
754
755
  out:
  	rcu_read_unlock();
658ddaaf6   Shawn Lu   tcp: md5: RST: ge...
756
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
757
758
759
760
761
  }
  
  /* The code following below sending ACKs in SYN-RECV and TIME-WAIT states
     outside socket context is ugly, certainly. What can I do?
   */
e2d118a1c   Lorenzo Colitti   net: inet: Suppor...
762
  static void tcp_v4_send_ack(const struct sock *sk,
e62a123b8   Eric Dumazet   tcp: fix NULL der...
763
  			    struct sk_buff *skb, u32 seq, u32 ack,
ee684b6f2   Andrey Vagin   tcp: send packets...
764
  			    u32 win, u32 tsval, u32 tsecr, int oif,
88ef4a5a7   KOVACS Krisztian   tcp: Handle TCP S...
765
  			    struct tcp_md5sig_key *key,
66b13d99d   Eric Dumazet   ipv4: tcp: fix TO...
766
  			    int reply_flags, u8 tos)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
767
  {
cf533ea53   Eric Dumazet   tcp: add const qu...
768
  	const struct tcphdr *th = tcp_hdr(skb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
769
770
  	struct {
  		struct tcphdr th;
714e85be3   Al Viro   [IPV6]: Assorted ...
771
  		__be32 opt[(TCPOLEN_TSTAMP_ALIGNED >> 2)
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
772
  #ifdef CONFIG_TCP_MD5SIG
714e85be3   Al Viro   [IPV6]: Assorted ...
773
  			   + (TCPOLEN_MD5SIG_ALIGNED >> 2)
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
774
775
  #endif
  			];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
776
  	} rep;
e2d118a1c   Lorenzo Colitti   net: inet: Suppor...
777
  	struct net *net = sock_net(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
778
  	struct ip_reply_arg arg;
004836905   Jon Maxwell   tcp: Add mark for...
779
  	struct sock *ctl_sk;
d6fb396cf   Eric Dumazet   ipv4: tcp: fix AC...
780
  	u64 transmit_time;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
781
782
  
  	memset(&rep.th, 0, sizeof(struct tcphdr));
7174259e6   Arnaldo Carvalho de Melo   [TCP_IPV4]: Codin...
783
  	memset(&arg, 0, sizeof(arg));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
784
785
786
  
  	arg.iov[0].iov_base = (unsigned char *)&rep;
  	arg.iov[0].iov_len  = sizeof(rep.th);
ee684b6f2   Andrey Vagin   tcp: send packets...
787
  	if (tsecr) {
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
788
789
790
  		rep.opt[0] = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
  				   (TCPOPT_TIMESTAMP << 8) |
  				   TCPOLEN_TIMESTAMP);
ee684b6f2   Andrey Vagin   tcp: send packets...
791
792
  		rep.opt[1] = htonl(tsval);
  		rep.opt[2] = htonl(tsecr);
cb48cfe80   Craig Schlenter   [TCP]: Fix iov_le...
793
  		arg.iov[0].iov_len += TCPOLEN_TSTAMP_ALIGNED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
794
795
796
797
798
799
800
801
802
803
  	}
  
  	/* Swap the send and the receive. */
  	rep.th.dest    = th->source;
  	rep.th.source  = th->dest;
  	rep.th.doff    = arg.iov[0].iov_len / 4;
  	rep.th.seq     = htonl(seq);
  	rep.th.ack_seq = htonl(ack);
  	rep.th.ack     = 1;
  	rep.th.window  = htons(win);
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
804
  #ifdef CONFIG_TCP_MD5SIG
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
805
  	if (key) {
ee684b6f2   Andrey Vagin   tcp: send packets...
806
  		int offset = (tsecr) ? 3 : 0;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
807
808
809
810
811
812
813
  
  		rep.opt[offset++] = htonl((TCPOPT_NOP << 24) |
  					  (TCPOPT_NOP << 16) |
  					  (TCPOPT_MD5SIG << 8) |
  					  TCPOLEN_MD5SIG);
  		arg.iov[0].iov_len += TCPOLEN_MD5SIG_ALIGNED;
  		rep.th.doff = arg.iov[0].iov_len/4;
49a72dfb8   Adam Langley   tcp: Fix MD5 sign...
814
  		tcp_v4_md5_hash_hdr((__u8 *) &rep.opt[offset],
90b7e1120   Adam Langley   tcp: MD5: Fix MD5...
815
816
  				    key, ip_hdr(skb)->saddr,
  				    ip_hdr(skb)->daddr, &rep.th);
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
817
818
  	}
  #endif
88ef4a5a7   KOVACS Krisztian   tcp: Handle TCP S...
819
  	arg.flags = reply_flags;
eddc9ec53   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
820
821
  	arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr,
  				      ip_hdr(skb)->saddr, /* XXX */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
822
823
  				      arg.iov[0].iov_len, IPPROTO_TCP, 0);
  	arg.csumoffset = offsetof(struct tcphdr, check) / 2;
9501f9722   YOSHIFUJI Hideaki   tcp md5sig: Let t...
824
825
  	if (oif)
  		arg.bound_dev_if = oif;
66b13d99d   Eric Dumazet   ipv4: tcp: fix TO...
826
  	arg.tos = tos;
e2d118a1c   Lorenzo Colitti   net: inet: Suppor...
827
  	arg.uid = sock_net_uid(net, sk_fullsock(sk) ? sk : NULL);
47dcc20a3   Eric Dumazet   ipv4: tcp: ip_sen...
828
  	local_bh_disable();
5472c3c6a   Eric Dumazet   tcp: use this_cpu...
829
  	ctl_sk = this_cpu_read(*net->ipv4.tcp_sk);
a842fe142   Eric Dumazet   tcp: add optional...
830
831
  	ctl_sk->sk_mark = (sk->sk_state == TCP_TIME_WAIT) ?
  			   inet_twsk(sk)->tw_mark : sk->sk_mark;
f6c0f5d20   Eric Dumazet   tcp: honor SO_PRI...
832
833
  	ctl_sk->sk_priority = (sk->sk_state == TCP_TIME_WAIT) ?
  			   inet_twsk(sk)->tw_priority : sk->sk_priority;
d6fb396cf   Eric Dumazet   ipv4: tcp: fix AC...
834
  	transmit_time = tcp_transmit_time(sk);
004836905   Jon Maxwell   tcp: Add mark for...
835
  	ip_send_unicast_reply(ctl_sk,
bdbbb8527   Eric Dumazet   ipv4: tcp: get ri...
836
  			      skb, &TCP_SKB_CB(skb)->header.h4.opt,
24a2d43d8   Eric Dumazet   ipv4: rename ip_o...
837
  			      ip_hdr(skb)->saddr, ip_hdr(skb)->daddr,
d6fb396cf   Eric Dumazet   ipv4: tcp: fix AC...
838
839
  			      &arg, arg.iov[0].iov_len,
  			      transmit_time);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
840

004836905   Jon Maxwell   tcp: Add mark for...
841
  	ctl_sk->sk_mark = 0;
90bbcc608   Eric Dumazet   net: tcp: rename ...
842
  	__TCP_INC_STATS(net, TCP_MIB_OUTSEGS);
47dcc20a3   Eric Dumazet   ipv4: tcp: ip_sen...
843
  	local_bh_enable();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
844
845
846
847
  }
  
  static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb)
  {
8feaf0c0a   Arnaldo Carvalho de Melo   [INET]: Generalis...
848
  	struct inet_timewait_sock *tw = inet_twsk(sk);
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
849
  	struct tcp_timewait_sock *tcptw = tcp_twsk(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
850

e2d118a1c   Lorenzo Colitti   net: inet: Suppor...
851
  	tcp_v4_send_ack(sk, skb,
e62a123b8   Eric Dumazet   tcp: fix NULL der...
852
  			tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
7174259e6   Arnaldo Carvalho de Melo   [TCP_IPV4]: Codin...
853
  			tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
9a568de48   Eric Dumazet   tcp: switch TCP T...
854
  			tcp_time_stamp_raw() + tcptw->tw_ts_offset,
9501f9722   YOSHIFUJI Hideaki   tcp md5sig: Let t...
855
856
  			tcptw->tw_ts_recent,
  			tw->tw_bound_dev_if,
88ef4a5a7   KOVACS Krisztian   tcp: Handle TCP S...
857
  			tcp_twsk_md5_key(tcptw),
66b13d99d   Eric Dumazet   ipv4: tcp: fix TO...
858
859
  			tw->tw_transparent ? IP_REPLY_ARG_NOSRCCHECK : 0,
  			tw->tw_tos
9501f9722   YOSHIFUJI Hideaki   tcp md5sig: Let t...
860
  			);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
861

8feaf0c0a   Arnaldo Carvalho de Melo   [INET]: Generalis...
862
  	inet_twsk_put(tw);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
863
  }
a00e74442   Eric Dumazet   tcp/dccp: constif...
864
  static void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb,
7174259e6   Arnaldo Carvalho de Melo   [TCP_IPV4]: Codin...
865
  				  struct request_sock *req)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
866
  {
168a8f580   Jerry Chu   tcp: TCP Fast Ope...
867
868
869
  	/* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV
  	 * sk->sk_state == TCP_SYN_RECV -> for Fast Open.
  	 */
e62a123b8   Eric Dumazet   tcp: fix NULL der...
870
871
  	u32 seq = (sk->sk_state == TCP_LISTEN) ? tcp_rsk(req)->snt_isn + 1 :
  					     tcp_sk(sk)->snd_nxt;
20a2b49fc   Eric Dumazet   tcp: properly sca...
872
873
874
875
876
  	/* RFC 7323 2.3
  	 * The window field (SEG.WND) of every outgoing segment, with the
  	 * exception of <SYN> segments, MUST be right-shifted by
  	 * Rcv.Wind.Shift bits:
  	 */
e2d118a1c   Lorenzo Colitti   net: inet: Suppor...
877
  	tcp_v4_send_ack(sk, skb, seq,
20a2b49fc   Eric Dumazet   tcp: properly sca...
878
879
  			tcp_rsk(req)->rcv_nxt,
  			req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale,
9a568de48   Eric Dumazet   tcp: switch TCP T...
880
  			tcp_time_stamp_raw() + tcp_rsk(req)->ts_off,
9501f9722   YOSHIFUJI Hideaki   tcp md5sig: Let t...
881
882
  			req->ts_recent,
  			0,
30791ac41   Christoph Paasch   tcp md5sig: Use s...
883
  			tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&ip_hdr(skb)->saddr,
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
884
  					  AF_INET),
66b13d99d   Eric Dumazet   ipv4: tcp: fix TO...
885
886
  			inet_rsk(req)->no_srccheck ? IP_REPLY_ARG_NOSRCCHECK : 0,
  			ip_hdr(skb)->tos);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
887
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
888
  /*
9bf1d83e7   Kris Katterjohn   [TCP]: Fix tcp_v4...
889
   *	Send a SYN-ACK after having received a SYN.
60236fdd0   Arnaldo Carvalho de Melo   [NET] Rename open...
890
   *	This still operates on a request_sock only, not on a big
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
891
892
   *	socket.
   */
0f935dbed   Eric Dumazet   tcp: constify tcp...
893
  static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst,
d6274bd8d   Octavian Purdila   tcp: add send_syn...
894
  			      struct flowi *fl,
72659ecce   Octavian Purdila   tcp: account SYN-...
895
  			      struct request_sock *req,
ca6fb0651   Eric Dumazet   tcp: attach SYNAC...
896
  			      struct tcp_fastopen_cookie *foc,
b3d051477   Eric Dumazet   tcp: do not mess ...
897
  			      enum tcp_synack_type synack_type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
898
  {
2e6599cb8   Arnaldo Carvalho de Melo   [NET] Generalise ...
899
  	const struct inet_request_sock *ireq = inet_rsk(req);
6bd023f3d   David S. Miller   ipv4: Make caller...
900
  	struct flowi4 fl4;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
901
  	int err = -1;
d41db5af2   Weilong Chen   ipv4: fix checkpa...
902
  	struct sk_buff *skb;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
903
904
  
  	/* First, grab a route. */
ba3f7f04e   David S. Miller   ipv4: Kill FLOWI_...
905
  	if (!dst && (dst = inet_csk_route_req(sk, &fl4, req)) == NULL)
fd80eb942   Denis V. Lunev   [INET]: Remove st...
906
  		return -1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
907

b3d051477   Eric Dumazet   tcp: do not mess ...
908
  	skb = tcp_make_synack(sk, dst, req, foc, synack_type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
909
910
  
  	if (skb) {
634fb979e   Eric Dumazet   inet: includes a ...
911
  		__tcp_v4_send_check(skb, ireq->ir_loc_addr, ireq->ir_rmt_addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
912

2ab2ddd30   Eric Dumazet   inet: make sure t...
913
  		rcu_read_lock();
634fb979e   Eric Dumazet   inet: includes a ...
914
915
  		err = ip_build_and_send_pkt(skb, sk, ireq->ir_loc_addr,
  					    ireq->ir_rmt_addr,
2ab2ddd30   Eric Dumazet   inet: make sure t...
916
917
  					    rcu_dereference(ireq->ireq_opt));
  		rcu_read_unlock();
b9df3cb8c   Gerrit Renker   [TCP/DCCP]: Intro...
918
  		err = net_xmit_eval(err);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
919
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
920
921
922
923
  	return err;
  }
  
  /*
60236fdd0   Arnaldo Carvalho de Melo   [NET] Rename open...
924
   *	IPv4 request_sock destructor.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
925
   */
60236fdd0   Arnaldo Carvalho de Melo   [NET] Rename open...
926
  static void tcp_v4_reqsk_destructor(struct request_sock *req)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
927
  {
c92e8c02f   Eric Dumazet   tcp/dccp: fix ire...
928
  	kfree(rcu_dereference_protected(inet_rsk(req)->ireq_opt, 1));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
929
  }
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
930
931
932
933
934
935
  #ifdef CONFIG_TCP_MD5SIG
  /*
   * RFC2385 MD5 checksumming requires a mapping of
   * IP address->MD5 Key.
   * We need to maintain these in the sk structure.
   */
921f9a0f2   Eric Dumazet   tcp: convert tcp_...
936
  DEFINE_STATIC_KEY_FALSE(tcp_md5_needed);
6015c71e6   Eric Dumazet   tcp: md5: add tcp...
937
  EXPORT_SYMBOL(tcp_md5_needed);
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
938
  /* Find the Key structure for an address.  */
6015c71e6   Eric Dumazet   tcp: md5: add tcp...
939
940
941
  struct tcp_md5sig_key *__tcp_md5_do_lookup(const struct sock *sk,
  					   const union tcp_md5_addr *addr,
  					   int family)
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
942
  {
fd3a154a0   Eric Dumazet   tcp: md5: get rid...
943
  	const struct tcp_sock *tp = tcp_sk(sk);
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
944
  	struct tcp_md5sig_key *key;
fd3a154a0   Eric Dumazet   tcp: md5: get rid...
945
  	const struct tcp_md5sig_info *md5sig;
6797318e6   Ivan Delalande   tcp: md5: add an ...
946
947
948
  	__be32 mask;
  	struct tcp_md5sig_key *best_match = NULL;
  	bool match;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
949

a8afca032   Eric Dumazet   tcp: md5: protect...
950
951
  	/* caller either holds rcu_read_lock() or socket lock */
  	md5sig = rcu_dereference_check(tp->md5sig_info,
1e1d04e67   Hannes Frederic Sowa   net: introduce lo...
952
  				       lockdep_sock_is_held(sk));
a8afca032   Eric Dumazet   tcp: md5: protect...
953
  	if (!md5sig)
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
954
  		return NULL;
083a0326a   Arnd Bergmann   tcp: md5: hide un...
955

b67bfe0d4   Sasha Levin   hlist: drop the n...
956
  	hlist_for_each_entry_rcu(key, &md5sig->head, node) {
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
957
958
  		if (key->family != family)
  			continue;
6797318e6   Ivan Delalande   tcp: md5: add an ...
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
  
  		if (family == AF_INET) {
  			mask = inet_make_mask(key->prefixlen);
  			match = (key->addr.a4.s_addr & mask) ==
  				(addr->a4.s_addr & mask);
  #if IS_ENABLED(CONFIG_IPV6)
  		} else if (family == AF_INET6) {
  			match = ipv6_prefix_equal(&key->addr.a6, &addr->a6,
  						  key->prefixlen);
  #endif
  		} else {
  			match = false;
  		}
  
  		if (match && (!best_match ||
  			      key->prefixlen > best_match->prefixlen))
  			best_match = key;
  	}
  	return best_match;
  }
6015c71e6   Eric Dumazet   tcp: md5: add tcp...
979
  EXPORT_SYMBOL(__tcp_md5_do_lookup);
6797318e6   Ivan Delalande   tcp: md5: add an ...
980

e8f37d57d   Wu Fengguang   tcp: md5: tcp_md5...
981
982
983
  static struct tcp_md5sig_key *tcp_md5_do_lookup_exact(const struct sock *sk,
  						      const union tcp_md5_addr *addr,
  						      int family, u8 prefixlen)
6797318e6   Ivan Delalande   tcp: md5: add an ...
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
  {
  	const struct tcp_sock *tp = tcp_sk(sk);
  	struct tcp_md5sig_key *key;
  	unsigned int size = sizeof(struct in_addr);
  	const struct tcp_md5sig_info *md5sig;
  
  	/* caller either holds rcu_read_lock() or socket lock */
  	md5sig = rcu_dereference_check(tp->md5sig_info,
  				       lockdep_sock_is_held(sk));
  	if (!md5sig)
  		return NULL;
  #if IS_ENABLED(CONFIG_IPV6)
  	if (family == AF_INET6)
  		size = sizeof(struct in6_addr);
  #endif
  	hlist_for_each_entry_rcu(key, &md5sig->head, node) {
  		if (key->family != family)
  			continue;
  		if (!memcmp(&key->addr, addr, size) &&
  		    key->prefixlen == prefixlen)
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1004
  			return key;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1005
1006
1007
  	}
  	return NULL;
  }
b83e3deb9   Eric Dumazet   tcp: md5: constif...
1008
  struct tcp_md5sig_key *tcp_v4_md5_lookup(const struct sock *sk,
fd3a154a0   Eric Dumazet   tcp: md5: get rid...
1009
  					 const struct sock *addr_sk)
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1010
  {
b52e69217   Eric Dumazet   tcp: md5: fix a t...
1011
  	const union tcp_md5_addr *addr;
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1012

b52e69217   Eric Dumazet   tcp: md5: fix a t...
1013
  	addr = (const union tcp_md5_addr *)&addr_sk->sk_daddr;
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1014
  	return tcp_md5_do_lookup(sk, addr, AF_INET);
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1015
  }
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1016
  EXPORT_SYMBOL(tcp_v4_md5_lookup);
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1017
  /* This can be called on a newly created socket, from other files */
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1018
  int tcp_md5_do_add(struct sock *sk, const union tcp_md5_addr *addr,
6797318e6   Ivan Delalande   tcp: md5: add an ...
1019
1020
  		   int family, u8 prefixlen, const u8 *newkey, u8 newkeylen,
  		   gfp_t gfp)
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1021
1022
  {
  	/* Add Key to the list */
b0a713e9e   Matthias M. Dellweg   [TCP] MD5: Remove...
1023
  	struct tcp_md5sig_key *key;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1024
  	struct tcp_sock *tp = tcp_sk(sk);
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1025
  	struct tcp_md5sig_info *md5sig;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1026

6797318e6   Ivan Delalande   tcp: md5: add an ...
1027
  	key = tcp_md5_do_lookup_exact(sk, addr, family, prefixlen);
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1028
1029
  	if (key) {
  		/* Pre-existing entry - just update that one. */
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1030
  		memcpy(key->key, newkey, newkeylen);
b0a713e9e   Matthias M. Dellweg   [TCP] MD5: Remove...
1031
  		key->keylen = newkeylen;
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1032
1033
  		return 0;
  	}
260fcbeb1   Yan, Zheng   tcp: properly han...
1034

a8afca032   Eric Dumazet   tcp: md5: protect...
1035
  	md5sig = rcu_dereference_protected(tp->md5sig_info,
1e1d04e67   Hannes Frederic Sowa   net: introduce lo...
1036
  					   lockdep_sock_is_held(sk));
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1037
1038
1039
  	if (!md5sig) {
  		md5sig = kmalloc(sizeof(*md5sig), gfp);
  		if (!md5sig)
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1040
  			return -ENOMEM;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1041

a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1042
1043
  		sk_nocaps_add(sk, NETIF_F_GSO_MASK);
  		INIT_HLIST_HEAD(&md5sig->head);
a8afca032   Eric Dumazet   tcp: md5: protect...
1044
  		rcu_assign_pointer(tp->md5sig_info, md5sig);
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1045
  	}
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1046

5f3d9cb29   Eric Dumazet   tcp: md5: use soc...
1047
  	key = sock_kmalloc(sk, sizeof(*key), gfp);
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1048
1049
  	if (!key)
  		return -ENOMEM;
71cea17ed   Eric Dumazet   tcp: md5: remove ...
1050
  	if (!tcp_alloc_md5sig_pool()) {
5f3d9cb29   Eric Dumazet   tcp: md5: use soc...
1051
  		sock_kfree_s(sk, key, sizeof(*key));
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1052
  		return -ENOMEM;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1053
  	}
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1054
1055
1056
1057
  
  	memcpy(key->key, newkey, newkeylen);
  	key->keylen = newkeylen;
  	key->family = family;
6797318e6   Ivan Delalande   tcp: md5: add an ...
1058
  	key->prefixlen = prefixlen;
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1059
1060
1061
1062
  	memcpy(&key->addr, addr,
  	       (family == AF_INET6) ? sizeof(struct in6_addr) :
  				      sizeof(struct in_addr));
  	hlist_add_head_rcu(&key->node, &md5sig->head);
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1063
1064
  	return 0;
  }
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1065
  EXPORT_SYMBOL(tcp_md5_do_add);
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1066

6797318e6   Ivan Delalande   tcp: md5: add an ...
1067
1068
  int tcp_md5_do_del(struct sock *sk, const union tcp_md5_addr *addr, int family,
  		   u8 prefixlen)
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1069
  {
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1070
  	struct tcp_md5sig_key *key;
6797318e6   Ivan Delalande   tcp: md5: add an ...
1071
  	key = tcp_md5_do_lookup_exact(sk, addr, family, prefixlen);
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1072
1073
1074
  	if (!key)
  		return -ENOENT;
  	hlist_del_rcu(&key->node);
5f3d9cb29   Eric Dumazet   tcp: md5: use soc...
1075
  	atomic_sub(sizeof(*key), &sk->sk_omem_alloc);
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1076
  	kfree_rcu(key, rcu);
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1077
  	return 0;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1078
  }
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1079
  EXPORT_SYMBOL(tcp_md5_do_del);
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1080

e0683e707   stephen hemminger   tcp: make tcp_cle...
1081
  static void tcp_clear_md5_list(struct sock *sk)
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1082
1083
  {
  	struct tcp_sock *tp = tcp_sk(sk);
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1084
  	struct tcp_md5sig_key *key;
b67bfe0d4   Sasha Levin   hlist: drop the n...
1085
  	struct hlist_node *n;
a8afca032   Eric Dumazet   tcp: md5: protect...
1086
  	struct tcp_md5sig_info *md5sig;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1087

a8afca032   Eric Dumazet   tcp: md5: protect...
1088
  	md5sig = rcu_dereference_protected(tp->md5sig_info, 1);
b67bfe0d4   Sasha Levin   hlist: drop the n...
1089
  	hlist_for_each_entry_safe(key, n, &md5sig->head, node) {
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1090
  		hlist_del_rcu(&key->node);
5f3d9cb29   Eric Dumazet   tcp: md5: use soc...
1091
  		atomic_sub(sizeof(*key), &sk->sk_omem_alloc);
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1092
  		kfree_rcu(key, rcu);
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1093
1094
  	}
  }
8917a777b   Ivan Delalande   tcp: md5: add TCP...
1095
1096
  static int tcp_v4_parse_md5_keys(struct sock *sk, int optname,
  				 char __user *optval, int optlen)
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1097
1098
1099
  {
  	struct tcp_md5sig cmd;
  	struct sockaddr_in *sin = (struct sockaddr_in *)&cmd.tcpm_addr;
8917a777b   Ivan Delalande   tcp: md5: add TCP...
1100
  	u8 prefixlen = 32;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1101
1102
1103
  
  	if (optlen < sizeof(cmd))
  		return -EINVAL;
7174259e6   Arnaldo Carvalho de Melo   [TCP_IPV4]: Codin...
1104
  	if (copy_from_user(&cmd, optval, sizeof(cmd)))
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1105
1106
1107
1108
  		return -EFAULT;
  
  	if (sin->sin_family != AF_INET)
  		return -EINVAL;
8917a777b   Ivan Delalande   tcp: md5: add TCP...
1109
1110
1111
1112
1113
1114
  	if (optname == TCP_MD5SIG_EXT &&
  	    cmd.tcpm_flags & TCP_MD5SIG_FLAG_PREFIX) {
  		prefixlen = cmd.tcpm_prefixlen;
  		if (prefixlen > 32)
  			return -EINVAL;
  	}
64a124edc   Dmitry Popov   tcp: md5: remove ...
1115
  	if (!cmd.tcpm_keylen)
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1116
  		return tcp_md5_do_del(sk, (union tcp_md5_addr *)&sin->sin_addr.s_addr,
8917a777b   Ivan Delalande   tcp: md5: add TCP...
1117
  				      AF_INET, prefixlen);
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1118
1119
1120
  
  	if (cmd.tcpm_keylen > TCP_MD5SIG_MAXKEYLEN)
  		return -EINVAL;
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1121
  	return tcp_md5_do_add(sk, (union tcp_md5_addr *)&sin->sin_addr.s_addr,
8917a777b   Ivan Delalande   tcp: md5: add TCP...
1122
  			      AF_INET, prefixlen, cmd.tcpm_key, cmd.tcpm_keylen,
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1123
  			      GFP_KERNEL);
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1124
  }
19689e38e   Eric Dumazet   tcp: md5: use kma...
1125
1126
1127
  static int tcp_v4_md5_hash_headers(struct tcp_md5sig_pool *hp,
  				   __be32 daddr, __be32 saddr,
  				   const struct tcphdr *th, int nbytes)
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1128
  {
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1129
  	struct tcp4_pseudohdr *bp;
49a72dfb8   Adam Langley   tcp: Fix MD5 sign...
1130
  	struct scatterlist sg;
19689e38e   Eric Dumazet   tcp: md5: use kma...
1131
  	struct tcphdr *_th;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1132

19689e38e   Eric Dumazet   tcp: md5: use kma...
1133
  	bp = hp->scratch;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1134
1135
1136
  	bp->saddr = saddr;
  	bp->daddr = daddr;
  	bp->pad = 0;
076fb7223   YOSHIFUJI Hideaki   tcp md5sig: Remov...
1137
  	bp->protocol = IPPROTO_TCP;
49a72dfb8   Adam Langley   tcp: Fix MD5 sign...
1138
  	bp->len = cpu_to_be16(nbytes);
c7da57a18   David S. Miller   [TCP]: Fix scatte...
1139

19689e38e   Eric Dumazet   tcp: md5: use kma...
1140
1141
1142
1143
1144
1145
1146
  	_th = (struct tcphdr *)(bp + 1);
  	memcpy(_th, th, sizeof(*th));
  	_th->check = 0;
  
  	sg_init_one(&sg, bp, sizeof(*bp) + sizeof(*th));
  	ahash_request_set_crypt(hp->md5_req, &sg, NULL,
  				sizeof(*bp) + sizeof(*th));
cf80e0e47   Herbert Xu   tcp: Use ahash
1147
  	return crypto_ahash_update(hp->md5_req);
49a72dfb8   Adam Langley   tcp: Fix MD5 sign...
1148
  }
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1149
  static int tcp_v4_md5_hash_hdr(char *md5_hash, const struct tcp_md5sig_key *key,
318cf7aaa   Eric Dumazet   tcp: md5: add mor...
1150
  			       __be32 daddr, __be32 saddr, const struct tcphdr *th)
49a72dfb8   Adam Langley   tcp: Fix MD5 sign...
1151
1152
  {
  	struct tcp_md5sig_pool *hp;
cf80e0e47   Herbert Xu   tcp: Use ahash
1153
  	struct ahash_request *req;
49a72dfb8   Adam Langley   tcp: Fix MD5 sign...
1154
1155
1156
1157
  
  	hp = tcp_get_md5sig_pool();
  	if (!hp)
  		goto clear_hash_noput;
cf80e0e47   Herbert Xu   tcp: Use ahash
1158
  	req = hp->md5_req;
49a72dfb8   Adam Langley   tcp: Fix MD5 sign...
1159

cf80e0e47   Herbert Xu   tcp: Use ahash
1160
  	if (crypto_ahash_init(req))
49a72dfb8   Adam Langley   tcp: Fix MD5 sign...
1161
  		goto clear_hash;
19689e38e   Eric Dumazet   tcp: md5: use kma...
1162
  	if (tcp_v4_md5_hash_headers(hp, daddr, saddr, th, th->doff << 2))
49a72dfb8   Adam Langley   tcp: Fix MD5 sign...
1163
1164
1165
  		goto clear_hash;
  	if (tcp_md5_hash_key(hp, key))
  		goto clear_hash;
cf80e0e47   Herbert Xu   tcp: Use ahash
1166
1167
  	ahash_request_set_crypt(req, NULL, md5_hash, 0);
  	if (crypto_ahash_final(req))
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1168
  		goto clear_hash;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1169
  	tcp_put_md5sig_pool();
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1170
  	return 0;
49a72dfb8   Adam Langley   tcp: Fix MD5 sign...
1171

cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1172
1173
1174
1175
  clear_hash:
  	tcp_put_md5sig_pool();
  clear_hash_noput:
  	memset(md5_hash, 0, 16);
49a72dfb8   Adam Langley   tcp: Fix MD5 sign...
1176
  	return 1;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1177
  }
39f8e58e5   Eric Dumazet   tcp: md5: remove ...
1178
1179
  int tcp_v4_md5_hash_skb(char *md5_hash, const struct tcp_md5sig_key *key,
  			const struct sock *sk,
318cf7aaa   Eric Dumazet   tcp: md5: add mor...
1180
  			const struct sk_buff *skb)
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1181
  {
49a72dfb8   Adam Langley   tcp: Fix MD5 sign...
1182
  	struct tcp_md5sig_pool *hp;
cf80e0e47   Herbert Xu   tcp: Use ahash
1183
  	struct ahash_request *req;
318cf7aaa   Eric Dumazet   tcp: md5: add mor...
1184
  	const struct tcphdr *th = tcp_hdr(skb);
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1185
  	__be32 saddr, daddr;
39f8e58e5   Eric Dumazet   tcp: md5: remove ...
1186
1187
1188
  	if (sk) { /* valid for establish/request sockets */
  		saddr = sk->sk_rcv_saddr;
  		daddr = sk->sk_daddr;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1189
  	} else {
49a72dfb8   Adam Langley   tcp: Fix MD5 sign...
1190
1191
1192
  		const struct iphdr *iph = ip_hdr(skb);
  		saddr = iph->saddr;
  		daddr = iph->daddr;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1193
  	}
49a72dfb8   Adam Langley   tcp: Fix MD5 sign...
1194
1195
1196
1197
  
  	hp = tcp_get_md5sig_pool();
  	if (!hp)
  		goto clear_hash_noput;
cf80e0e47   Herbert Xu   tcp: Use ahash
1198
  	req = hp->md5_req;
49a72dfb8   Adam Langley   tcp: Fix MD5 sign...
1199

cf80e0e47   Herbert Xu   tcp: Use ahash
1200
  	if (crypto_ahash_init(req))
49a72dfb8   Adam Langley   tcp: Fix MD5 sign...
1201
  		goto clear_hash;
19689e38e   Eric Dumazet   tcp: md5: use kma...
1202
  	if (tcp_v4_md5_hash_headers(hp, daddr, saddr, th, skb->len))
49a72dfb8   Adam Langley   tcp: Fix MD5 sign...
1203
1204
1205
1206
1207
  		goto clear_hash;
  	if (tcp_md5_hash_skb_data(hp, skb, th->doff << 2))
  		goto clear_hash;
  	if (tcp_md5_hash_key(hp, key))
  		goto clear_hash;
cf80e0e47   Herbert Xu   tcp: Use ahash
1208
1209
  	ahash_request_set_crypt(req, NULL, md5_hash, 0);
  	if (crypto_ahash_final(req))
49a72dfb8   Adam Langley   tcp: Fix MD5 sign...
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
  		goto clear_hash;
  
  	tcp_put_md5sig_pool();
  	return 0;
  
  clear_hash:
  	tcp_put_md5sig_pool();
  clear_hash_noput:
  	memset(md5_hash, 0, 16);
  	return 1;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1220
  }
49a72dfb8   Adam Langley   tcp: Fix MD5 sign...
1221
  EXPORT_SYMBOL(tcp_v4_md5_hash_skb);
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1222

ba8e275a4   Eric Dumazet   tcp: cleanup tcp_...
1223
  #endif
ff74e23f7   Eric Dumazet   tcp: md5: input p...
1224
  /* Called with rcu_read_lock() */
ba8e275a4   Eric Dumazet   tcp: cleanup tcp_...
1225
  static bool tcp_v4_inbound_md5_hash(const struct sock *sk,
ff74e23f7   Eric Dumazet   tcp: md5: input p...
1226
  				    const struct sk_buff *skb)
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1227
  {
ba8e275a4   Eric Dumazet   tcp: cleanup tcp_...
1228
  #ifdef CONFIG_TCP_MD5SIG
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1229
1230
1231
1232
1233
1234
1235
1236
  	/*
  	 * This gets called for each TCP segment that arrives
  	 * so we want to be efficient.
  	 * We have 3 drop cases:
  	 * o No MD5 hash and one expected.
  	 * o MD5 hash and we're not expecting one.
  	 * o MD5 hash and its wrong.
  	 */
cf533ea53   Eric Dumazet   tcp: add const qu...
1237
  	const __u8 *hash_location = NULL;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1238
  	struct tcp_md5sig_key *hash_expected;
eddc9ec53   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
1239
  	const struct iphdr *iph = ip_hdr(skb);
cf533ea53   Eric Dumazet   tcp: add const qu...
1240
  	const struct tcphdr *th = tcp_hdr(skb);
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1241
  	int genhash;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1242
  	unsigned char newhash[16];
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1243
1244
  	hash_expected = tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&iph->saddr,
  					  AF_INET);
7d5d5525b   YOSHIFUJI Hideaki   tcp md5sig: Share...
1245
  	hash_location = tcp_parse_md5sig_option(th);
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1246

cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1247
1248
  	/* We've parsed the options - do we have a hash? */
  	if (!hash_expected && !hash_location)
a2a385d62   Eric Dumazet   tcp: bool convers...
1249
  		return false;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1250
1251
  
  	if (hash_expected && !hash_location) {
c10d9310e   Eric Dumazet   tcp: do not assum...
1252
  		NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPMD5NOTFOUND);
a2a385d62   Eric Dumazet   tcp: bool convers...
1253
  		return true;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1254
1255
1256
  	}
  
  	if (!hash_expected && hash_location) {
c10d9310e   Eric Dumazet   tcp: do not assum...
1257
  		NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPMD5UNEXPECTED);
a2a385d62   Eric Dumazet   tcp: bool convers...
1258
  		return true;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1259
1260
1261
1262
1263
  	}
  
  	/* Okay, so this is hash_expected and hash_location -
  	 * so we need to calculate the checksum.
  	 */
49a72dfb8   Adam Langley   tcp: Fix MD5 sign...
1264
1265
  	genhash = tcp_v4_md5_hash_skb(newhash,
  				      hash_expected,
39f8e58e5   Eric Dumazet   tcp: md5: remove ...
1266
  				      NULL, skb);
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1267
1268
  
  	if (genhash || memcmp(hash_location, newhash, 16) != 0) {
72145a68e   Eric Dumazet   tcp: md5: add LIN...
1269
  		NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPMD5FAILURE);
e87cc4728   Joe Perches   net: Convert net_...
1270
1271
1272
1273
1274
1275
  		net_info_ratelimited("MD5 Hash failed for (%pI4, %d)->(%pI4, %d)%s
  ",
  				     &iph->saddr, ntohs(th->source),
  				     &iph->daddr, ntohs(th->dest),
  				     genhash ? " tcp_v4_calc_md5_hash failed"
  				     : "");
a2a385d62   Eric Dumazet   tcp: bool convers...
1276
  		return true;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1277
  	}
a2a385d62   Eric Dumazet   tcp: bool convers...
1278
  	return false;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1279
  #endif
ba8e275a4   Eric Dumazet   tcp: cleanup tcp_...
1280
1281
  	return false;
  }
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1282

b40cf18ef   Eric Dumazet   tcp: constify lis...
1283
1284
  static void tcp_v4_init_req(struct request_sock *req,
  			    const struct sock *sk_listener,
16bea70aa   Octavian Purdila   tcp: add init_req...
1285
1286
1287
  			    struct sk_buff *skb)
  {
  	struct inet_request_sock *ireq = inet_rsk(req);
c92e8c02f   Eric Dumazet   tcp/dccp: fix ire...
1288
  	struct net *net = sock_net(sk_listener);
16bea70aa   Octavian Purdila   tcp: add init_req...
1289

08d2cc3b2   Eric Dumazet   inet: request soc...
1290
1291
  	sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr);
  	sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr);
c92e8c02f   Eric Dumazet   tcp/dccp: fix ire...
1292
  	RCU_INIT_POINTER(ireq->ireq_opt, tcp_v4_save_options(net, skb));
16bea70aa   Octavian Purdila   tcp: add init_req...
1293
  }
f964629e3   Eric Dumazet   tcp: constify tcp...
1294
1295
  static struct dst_entry *tcp_v4_route_req(const struct sock *sk,
  					  struct flowi *fl,
4396e4618   Soheil Hassas Yeganeh   tcp: remove tcp_t...
1296
  					  const struct request_sock *req)
d94e0417a   Octavian Purdila   tcp: add route_re...
1297
  {
4396e4618   Soheil Hassas Yeganeh   tcp: remove tcp_t...
1298
  	return inet_csk_route_req(sk, &fl->u.ip4, req);
d94e0417a   Octavian Purdila   tcp: add route_re...
1299
  }
72a3effaf   Eric Dumazet   [NET]: Size liste...
1300
  struct request_sock_ops tcp_request_sock_ops __read_mostly = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1301
  	.family		=	PF_INET,
2e6599cb8   Arnaldo Carvalho de Melo   [NET] Generalise ...
1302
  	.obj_size	=	sizeof(struct tcp_request_sock),
5db92c994   Octavian Purdila   tcp: unify tcp_v4...
1303
  	.rtx_syn_ack	=	tcp_rtx_synack,
60236fdd0   Arnaldo Carvalho de Melo   [NET] Rename open...
1304
1305
  	.send_ack	=	tcp_v4_reqsk_send_ack,
  	.destructor	=	tcp_v4_reqsk_destructor,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1306
  	.send_reset	=	tcp_v4_send_reset,
688d1945b   stephen hemminger   tcp: whitespace f...
1307
  	.syn_ack_timeout =	tcp_syn_ack_timeout,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1308
  };
b2e4b3deb   Stephen Hemminger   tcp: MD5 operatio...
1309
  static const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = {
2aec4a297   Octavian Purdila   tcp: add mss_clam...
1310
  	.mss_clamp	=	TCP_MSS_DEFAULT,
16bea70aa   Octavian Purdila   tcp: add init_req...
1311
  #ifdef CONFIG_TCP_MD5SIG
fd3a154a0   Eric Dumazet   tcp: md5: get rid...
1312
  	.req_md5_lookup	=	tcp_v4_md5_lookup,
e3afe7b75   John Dykstra   tcp: Fix MD5 sign...
1313
  	.calc_md5_hash	=	tcp_v4_md5_hash_skb,
b6332e6cf   Andrew Morton   [TCP]: Fix warnin...
1314
  #endif
16bea70aa   Octavian Purdila   tcp: add init_req...
1315
  	.init_req	=	tcp_v4_init_req,
fb7b37a7f   Octavian Purdila   tcp: add init_coo...
1316
1317
1318
  #ifdef CONFIG_SYN_COOKIES
  	.cookie_init_seq =	cookie_v4_init_sequence,
  #endif
d94e0417a   Octavian Purdila   tcp: add route_re...
1319
  	.route_req	=	tcp_v4_route_req,
84b114b98   Eric Dumazet   tcp: randomize ti...
1320
1321
  	.init_seq	=	tcp_v4_init_seq,
  	.init_ts_off	=	tcp_v4_init_ts_off,
d6274bd8d   Octavian Purdila   tcp: add send_syn...
1322
  	.send_synack	=	tcp_v4_send_synack,
16bea70aa   Octavian Purdila   tcp: add init_req...
1323
  };
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1324

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1325
1326
  int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1327
  	/* Never answer to SYNs send to broadcast or multicast */
511c3f92a   Eric Dumazet   net: skb->rtable ...
1328
  	if (skb_rtable(skb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1329
  		goto drop;
1fb6f159f   Octavian Purdila   tcp: add tcp_conn...
1330
1331
  	return tcp_conn_request(&tcp_request_sock_ops,
  				&tcp_request_sock_ipv4_ops, sk, skb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1332

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1333
  drop:
9caad8641   Eric Dumazet   tcp: increment sk...
1334
  	tcp_listendrop(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1335
1336
  	return 0;
  }
4bc2f18ba   Eric Dumazet   net/ipv4: EXPORT_...
1337
  EXPORT_SYMBOL(tcp_v4_conn_request);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1338
1339
1340
1341
1342
1343
  
  
  /*
   * The three way handshake has completed - we got a valid synack -
   * now create the new socket.
   */
0c27171e6   Eric Dumazet   tcp/dccp: constif...
1344
  struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
60236fdd0   Arnaldo Carvalho de Melo   [NET] Rename open...
1345
  				  struct request_sock *req,
5e0724d02   Eric Dumazet   tcp/dccp: fix has...
1346
1347
1348
  				  struct dst_entry *dst,
  				  struct request_sock *req_unhash,
  				  bool *own_req)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1349
  {
2e6599cb8   Arnaldo Carvalho de Melo   [NET] Generalise ...
1350
  	struct inet_request_sock *ireq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1351
1352
1353
  	struct inet_sock *newinet;
  	struct tcp_sock *newtp;
  	struct sock *newsk;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1354
1355
1356
  #ifdef CONFIG_TCP_MD5SIG
  	struct tcp_md5sig_key *key;
  #endif
f6d8bd051   Eric Dumazet   inet: add RCU pro...
1357
  	struct ip_options_rcu *inet_opt;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1358
1359
1360
  
  	if (sk_acceptq_is_full(sk))
  		goto exit_overflow;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1361
1362
  	newsk = tcp_create_openreq_child(sk, req, skb);
  	if (!newsk)
093d28232   Balazs Scheidler   tproxy: fix hash ...
1363
  		goto exit_nonewsk;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1364

bcd761111   Herbert Xu   [NET]: Generalise...
1365
  	newsk->sk_gso_type = SKB_GSO_TCPV4;
fae6ef87f   Neal Cardwell   net: tcp: move sk...
1366
  	inet_sk_rx_dst_set(newsk, skb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1367
1368
1369
  
  	newtp		      = tcp_sk(newsk);
  	newinet		      = inet_sk(newsk);
2e6599cb8   Arnaldo Carvalho de Melo   [NET] Generalise ...
1370
  	ireq		      = inet_rsk(req);
d1e559d0b   Eric Dumazet   inet: add IPv6 su...
1371
1372
  	sk_daddr_set(newsk, ireq->ir_rmt_addr);
  	sk_rcv_saddr_set(newsk, ireq->ir_loc_addr);
6dd9a14e9   David Ahern   net: Allow accept...
1373
  	newsk->sk_bound_dev_if = ireq->ir_iif;
c92e8c02f   Eric Dumazet   tcp/dccp: fix ire...
1374
1375
1376
  	newinet->inet_saddr   = ireq->ir_loc_addr;
  	inet_opt	      = rcu_dereference(ireq->ireq_opt);
  	RCU_INIT_POINTER(newinet->inet_opt, inet_opt);
463c84b97   Arnaldo Carvalho de Melo   [NET]: Introduce ...
1377
  	newinet->mc_index     = inet_iif(skb);
eddc9ec53   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
1378
  	newinet->mc_ttl	      = ip_hdr(skb)->ttl;
4c507d289   Jiri Benc   net: implement IP...
1379
  	newinet->rcv_tos      = ip_hdr(skb)->tos;
d83d8461f   Arnaldo Carvalho de Melo   [IP_SOCKGLUE]: Re...
1380
  	inet_csk(newsk)->icsk_ext_hdr_len = 0;
f6d8bd051   Eric Dumazet   inet: add RCU pro...
1381
1382
  	if (inet_opt)
  		inet_csk(newsk)->icsk_ext_hdr_len = inet_opt->opt.optlen;
a904a0693   Eric Dumazet   inet: stop leakin...
1383
  	newinet->inet_id = prandom_u32();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1384

dfd25ffff   Eric Dumazet   tcp: fix syncooki...
1385
1386
1387
1388
1389
1390
1391
  	if (!dst) {
  		dst = inet_csk_route_child_sock(sk, newsk, req);
  		if (!dst)
  			goto put_and_exit;
  	} else {
  		/* syncookie case : see end of cookie_v4_check() */
  	}
0e7344199   David S. Miller   ipv4: Use inet_cs...
1392
  	sk_setup_caps(newsk, dst);
81164413a   Daniel Borkmann   net: tcp: add per...
1393
  	tcp_ca_openreq_child(newsk, dst);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1394
  	tcp_sync_mss(newsk, dst_mtu(dst));
3541f9e8b   Eric Dumazet   tcp: add tcp_mss_...
1395
  	newtp->advmss = tcp_mss_clamp(tcp_sk(sk), dst_metric_advmss(dst));
f5fff5dc8   Tom Quetchenbach   tcp: advertise MS...
1396

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1397
  	tcp_initialize_rcv_mss(newsk);
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1398
1399
  #ifdef CONFIG_TCP_MD5SIG
  	/* Copy over the MD5 key from the original socket */
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1400
1401
  	key = tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&newinet->inet_daddr,
  				AF_INET);
00db41243   Ian Morris   ipv4: coding styl...
1402
  	if (key) {
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1403
1404
1405
1406
1407
1408
  		/*
  		 * We're using one, so create a matching key
  		 * on the newsk structure. If we fail to get
  		 * memory, then we end up not copying the key
  		 * across. Shucks.
  		 */
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
1409
  		tcp_md5_do_add(newsk, (union tcp_md5_addr *)&newinet->inet_daddr,
6797318e6   Ivan Delalande   tcp: md5: add an ...
1410
  			       AF_INET, 32, key->key, key->keylen, GFP_ATOMIC);
a465419b1   Eric Dumazet   net: Introduce sk...
1411
  		sk_nocaps_add(newsk, NETIF_F_GSO_MASK);
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1412
1413
  	}
  #endif
0e7344199   David S. Miller   ipv4: Use inet_cs...
1414
1415
  	if (__inet_inherit_port(sk, newsk) < 0)
  		goto put_and_exit;
5e0724d02   Eric Dumazet   tcp/dccp: fix has...
1416
  	*own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash));
c92e8c02f   Eric Dumazet   tcp/dccp: fix ire...
1417
  	if (likely(*own_req)) {
49a496c97   Eric Dumazet   tcp: use correct ...
1418
  		tcp_move_syn(newtp, req);
c92e8c02f   Eric Dumazet   tcp/dccp: fix ire...
1419
1420
1421
1422
  		ireq->ireq_opt = NULL;
  	} else {
  		newinet->inet_opt = NULL;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1423
1424
1425
  	return newsk;
  
  exit_overflow:
c10d9310e   Eric Dumazet   tcp: do not assum...
1426
  	NET_INC_STATS(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS);
093d28232   Balazs Scheidler   tproxy: fix hash ...
1427
1428
  exit_nonewsk:
  	dst_release(dst);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1429
  exit:
9caad8641   Eric Dumazet   tcp: increment sk...
1430
  	tcp_listendrop(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1431
  	return NULL;
0e7344199   David S. Miller   ipv4: Use inet_cs...
1432
  put_and_exit:
c92e8c02f   Eric Dumazet   tcp/dccp: fix ire...
1433
  	newinet->inet_opt = NULL;
e337e24d6   Christoph Paasch   inet: Fix kmemlea...
1434
1435
  	inet_csk_prepare_forced_close(newsk);
  	tcp_done(newsk);
0e7344199   David S. Miller   ipv4: Use inet_cs...
1436
  	goto exit;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1437
  }
4bc2f18ba   Eric Dumazet   net/ipv4: EXPORT_...
1438
  EXPORT_SYMBOL(tcp_v4_syn_recv_sock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1439

079096f10   Eric Dumazet   tcp/dccp: install...
1440
  static struct sock *tcp_v4_cookie_check(struct sock *sk, struct sk_buff *skb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1441
  {
079096f10   Eric Dumazet   tcp/dccp: install...
1442
  #ifdef CONFIG_SYN_COOKIES
52452c542   Eric Dumazet   inet: drop prev p...
1443
  	const struct tcphdr *th = tcp_hdr(skb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1444

af9b47385   Florian Westphal   syncookies: avoid...
1445
  	if (!th->syn)
461b74c39   Cong Wang   ipv4: clean up co...
1446
  		sk = cookie_v4_check(sk, skb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1447
1448
1449
  #endif
  	return sk;
  }
9349d600f   Petar Penkov   tcp: add skb-less...
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
  u16 tcp_v4_get_syncookie(struct sock *sk, struct iphdr *iph,
  			 struct tcphdr *th, u32 *cookie)
  {
  	u16 mss = 0;
  #ifdef CONFIG_SYN_COOKIES
  	mss = tcp_get_syncookie_mss(&tcp_request_sock_ops,
  				    &tcp_request_sock_ipv4_ops, sk, th);
  	if (mss) {
  		*cookie = __cookie_v4_init_sequence(iph, th, &mss);
  		tcp_synq_overflow(sk);
  	}
  #endif
  	return mss;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1464
  /* The socket must have it's spinlock held when we get
e994b2f0f   Eric Dumazet   tcp: do not lock ...
1465
   * here, unless it is a TCP_LISTEN socket.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1466
1467
1468
1469
1470
1471
1472
1473
   *
   * We have a potential double-lock case here, so even when
   * doing backlog processing we use the BH locking scheme.
   * This is because we cannot sleep with the original spinlock
   * held.
   */
  int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
  {
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1474
  	struct sock *rsk;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1475

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1476
  	if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
404e0a8b6   Eric Dumazet   net: ipv4: fix RC...
1477
  		struct dst_entry *dst = sk->sk_rx_dst;
bdeab9919   Tom Herbert   rps: Add flag to ...
1478
  		sock_rps_save_rxhash(sk, skb);
3d97379a6   Eric Dumazet   tcp: move sk_mark...
1479
  		sk_mark_napi_id(sk, skb);
404e0a8b6   Eric Dumazet   net: ipv4: fix RC...
1480
  		if (dst) {
505fbcf03   Eric Dumazet   ipv4: fix TCP ear...
1481
  			if (inet_sk(sk)->rx_dst_ifindex != skb->skb_iif ||
51456b291   Ian Morris   ipv4: coding styl...
1482
  			    !dst->ops->check(dst, 0)) {
92101b3b2   David S. Miller   ipv4: Prepare for...
1483
1484
1485
1486
  				dst_release(dst);
  				sk->sk_rx_dst = NULL;
  			}
  		}
3d97d88e8   Yafang Shao   tcp: minor optimi...
1487
  		tcp_rcv_established(sk, skb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1488
1489
  		return 0;
  	}
12e25e104   Eric Dumazet   tcp: remove redun...
1490
  	if (tcp_checksum_complete(skb))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1491
1492
1493
  		goto csum_err;
  
  	if (sk->sk_state == TCP_LISTEN) {
079096f10   Eric Dumazet   tcp/dccp: install...
1494
  		struct sock *nsk = tcp_v4_cookie_check(sk, skb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1495
1496
  		if (!nsk)
  			goto discard;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1497
  		if (nsk != sk) {
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1498
1499
  			if (tcp_child_process(sk, nsk, skb)) {
  				rsk = nsk;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1500
  				goto reset;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1501
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1502
1503
  			return 0;
  		}
ca55158c6   Eric Dumazet   rps: tcp: fix rps...
1504
  	} else
bdeab9919   Tom Herbert   rps: Add flag to ...
1505
  		sock_rps_save_rxhash(sk, skb);
ca55158c6   Eric Dumazet   rps: tcp: fix rps...
1506

72ab4a86f   Eric Dumazet   tcp: remove tcp_r...
1507
  	if (tcp_rcv_state_process(sk, skb)) {
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1508
  		rsk = sk;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1509
  		goto reset;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1510
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1511
1512
1513
  	return 0;
  
  reset:
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1514
  	tcp_v4_send_reset(rsk, skb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
  discard:
  	kfree_skb(skb);
  	/* Be careful here. If this function gets more complicated and
  	 * gcc suffers from register pressure on the x86, sk (in %ebx)
  	 * might be destroyed here. This current version compiles correctly,
  	 * but you have been warned.
  	 */
  	return 0;
  
  csum_err:
c10d9310e   Eric Dumazet   tcp: do not assum...
1525
1526
  	TCP_INC_STATS(sock_net(sk), TCP_MIB_CSUMERRORS);
  	TCP_INC_STATS(sock_net(sk), TCP_MIB_INERRS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1527
1528
  	goto discard;
  }
4bc2f18ba   Eric Dumazet   net/ipv4: EXPORT_...
1529
  EXPORT_SYMBOL(tcp_v4_do_rcv);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1530

7487449c8   Paolo Abeni   IPv4: early demux...
1531
  int tcp_v4_early_demux(struct sk_buff *skb)
41063e9dd   David S. Miller   ipv4: Early TCP s...
1532
  {
41063e9dd   David S. Miller   ipv4: Early TCP s...
1533
1534
1535
  	const struct iphdr *iph;
  	const struct tcphdr *th;
  	struct sock *sk;
41063e9dd   David S. Miller   ipv4: Early TCP s...
1536

41063e9dd   David S. Miller   ipv4: Early TCP s...
1537
  	if (skb->pkt_type != PACKET_HOST)
7487449c8   Paolo Abeni   IPv4: early demux...
1538
  		return 0;
41063e9dd   David S. Miller   ipv4: Early TCP s...
1539

45f00f99d   Eric Dumazet   ipv4: tcp: clean ...
1540
  	if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct tcphdr)))
7487449c8   Paolo Abeni   IPv4: early demux...
1541
  		return 0;
41063e9dd   David S. Miller   ipv4: Early TCP s...
1542
1543
  
  	iph = ip_hdr(skb);
45f00f99d   Eric Dumazet   ipv4: tcp: clean ...
1544
  	th = tcp_hdr(skb);
41063e9dd   David S. Miller   ipv4: Early TCP s...
1545
1546
  
  	if (th->doff < sizeof(struct tcphdr) / 4)
7487449c8   Paolo Abeni   IPv4: early demux...
1547
  		return 0;
41063e9dd   David S. Miller   ipv4: Early TCP s...
1548

45f00f99d   Eric Dumazet   ipv4: tcp: clean ...
1549
  	sk = __inet_lookup_established(dev_net(skb->dev), &tcp_hashinfo,
41063e9dd   David S. Miller   ipv4: Early TCP s...
1550
  				       iph->saddr, th->source,
7011d0851   Vijay Subramanian   tcp: Fix bug in t...
1551
  				       iph->daddr, ntohs(th->dest),
3fa6f616a   David Ahern   net: ipv4: add se...
1552
  				       skb->skb_iif, inet_sdif(skb));
41063e9dd   David S. Miller   ipv4: Early TCP s...
1553
1554
1555
  	if (sk) {
  		skb->sk = sk;
  		skb->destructor = sock_edemux;
f7e4eb03f   Eric Dumazet   inet: ip early de...
1556
  		if (sk_fullsock(sk)) {
d0c294c53   Michal Kubeček   tcp: prevent fetc...
1557
  			struct dst_entry *dst = READ_ONCE(sk->sk_rx_dst);
505fbcf03   Eric Dumazet   ipv4: fix TCP ear...
1558

41063e9dd   David S. Miller   ipv4: Early TCP s...
1559
1560
  			if (dst)
  				dst = dst_check(dst, 0);
92101b3b2   David S. Miller   ipv4: Prepare for...
1561
  			if (dst &&
505fbcf03   Eric Dumazet   ipv4: fix TCP ear...
1562
  			    inet_sk(sk)->rx_dst_ifindex == skb->skb_iif)
92101b3b2   David S. Miller   ipv4: Prepare for...
1563
  				skb_dst_set_noref(skb, dst);
41063e9dd   David S. Miller   ipv4: Early TCP s...
1564
1565
  		}
  	}
7487449c8   Paolo Abeni   IPv4: early demux...
1566
  	return 0;
41063e9dd   David S. Miller   ipv4: Early TCP s...
1567
  }
c9c332125   Eric Dumazet   tcp: add tcp_add_...
1568
1569
  bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb)
  {
8265792bf   Eric Dumazet   net: silence KCSA...
1570
  	u32 limit = READ_ONCE(sk->sk_rcvbuf) + READ_ONCE(sk->sk_sndbuf);
4f693b55c   Eric Dumazet   tcp: implement co...
1571
1572
1573
1574
1575
1576
1577
1578
  	struct skb_shared_info *shinfo;
  	const struct tcphdr *th;
  	struct tcphdr *thtail;
  	struct sk_buff *tail;
  	unsigned int hdrlen;
  	bool fragstolen;
  	u32 gso_segs;
  	int delta;
c9c332125   Eric Dumazet   tcp: add tcp_add_...
1579
1580
1581
1582
1583
1584
1585
  
  	/* In case all data was pulled from skb frags (in __pskb_pull_tail()),
  	 * we can fix skb->truesize to its real value to avoid future drops.
  	 * This is valid because skb is not yet charged to the socket.
  	 * It has been noticed pure SACK packets were sometimes dropped
  	 * (if cooked by drivers without copybreak feature).
  	 */
60b1af330   Eric Dumazet   tcp: reduce skb o...
1586
  	skb_condense(skb);
c9c332125   Eric Dumazet   tcp: add tcp_add_...
1587

ade9628ed   Eric Dumazet   tcp: drop dst in ...
1588
  	skb_dst_drop(skb);
4f693b55c   Eric Dumazet   tcp: implement co...
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
  	if (unlikely(tcp_checksum_complete(skb))) {
  		bh_unlock_sock(sk);
  		__TCP_INC_STATS(sock_net(sk), TCP_MIB_CSUMERRORS);
  		__TCP_INC_STATS(sock_net(sk), TCP_MIB_INERRS);
  		return true;
  	}
  
  	/* Attempt coalescing to last skb in backlog, even if we are
  	 * above the limits.
  	 * This is okay because skb capacity is limited to MAX_SKB_FRAGS.
  	 */
  	th = (const struct tcphdr *)skb->data;
  	hdrlen = th->doff * 4;
  	shinfo = skb_shinfo(skb);
  
  	if (!shinfo->gso_size)
  		shinfo->gso_size = skb->len - hdrlen;
  
  	if (!shinfo->gso_segs)
  		shinfo->gso_segs = 1;
  
  	tail = sk->sk_backlog.tail;
  	if (!tail)
  		goto no_coalesce;
  	thtail = (struct tcphdr *)tail->data;
  
  	if (TCP_SKB_CB(tail)->end_seq != TCP_SKB_CB(skb)->seq ||
  	    TCP_SKB_CB(tail)->ip_dsfield != TCP_SKB_CB(skb)->ip_dsfield ||
  	    ((TCP_SKB_CB(tail)->tcp_flags |
ca2fe2956   Eric Dumazet   tcp: add sanity t...
1618
1619
1620
  	      TCP_SKB_CB(skb)->tcp_flags) & (TCPHDR_SYN | TCPHDR_RST | TCPHDR_URG)) ||
  	    !((TCP_SKB_CB(tail)->tcp_flags &
  	      TCP_SKB_CB(skb)->tcp_flags) & TCPHDR_ACK) ||
4f693b55c   Eric Dumazet   tcp: implement co...
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
  	    ((TCP_SKB_CB(tail)->tcp_flags ^
  	      TCP_SKB_CB(skb)->tcp_flags) & (TCPHDR_ECE | TCPHDR_CWR)) ||
  #ifdef CONFIG_TLS_DEVICE
  	    tail->decrypted != skb->decrypted ||
  #endif
  	    thtail->doff != th->doff ||
  	    memcmp(thtail + 1, th + 1, hdrlen - sizeof(*th)))
  		goto no_coalesce;
  
  	__skb_pull(skb, hdrlen);
  	if (skb_try_coalesce(tail, skb, &fragstolen, &delta)) {
  		thtail->window = th->window;
  
  		TCP_SKB_CB(tail)->end_seq = TCP_SKB_CB(skb)->end_seq;
  
  		if (after(TCP_SKB_CB(skb)->ack_seq, TCP_SKB_CB(tail)->ack_seq))
  			TCP_SKB_CB(tail)->ack_seq = TCP_SKB_CB(skb)->ack_seq;
ca2fe2956   Eric Dumazet   tcp: add sanity t...
1638
1639
1640
1641
1642
1643
1644
1645
1646
  		/* We have to update both TCP_SKB_CB(tail)->tcp_flags and
  		 * thtail->fin, so that the fast path in tcp_rcv_established()
  		 * is not entered if we append a packet with a FIN.
  		 * SYN, RST, URG are not present.
  		 * ACK is set on both packets.
  		 * PSH : we do not really care in TCP stack,
  		 *       at least for 'GRO' packets.
  		 */
  		thtail->fin |= th->fin;
4f693b55c   Eric Dumazet   tcp: implement co...
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
  		TCP_SKB_CB(tail)->tcp_flags |= TCP_SKB_CB(skb)->tcp_flags;
  
  		if (TCP_SKB_CB(skb)->has_rxtstamp) {
  			TCP_SKB_CB(tail)->has_rxtstamp = true;
  			tail->tstamp = skb->tstamp;
  			skb_hwtstamps(tail)->hwtstamp = skb_hwtstamps(skb)->hwtstamp;
  		}
  
  		/* Not as strict as GRO. We only need to carry mss max value */
  		skb_shinfo(tail)->gso_size = max(shinfo->gso_size,
  						 skb_shinfo(tail)->gso_size);
  
  		gso_segs = skb_shinfo(tail)->gso_segs + shinfo->gso_segs;
  		skb_shinfo(tail)->gso_segs = min_t(u32, gso_segs, 0xFFFF);
  
  		sk->sk_backlog.len += delta;
  		__NET_INC_STATS(sock_net(sk),
  				LINUX_MIB_TCPBACKLOGCOALESCE);
  		kfree_skb_partial(skb, fragstolen);
  		return false;
  	}
  	__skb_push(skb, hdrlen);
  
  no_coalesce:
  	/* Only socket owner can try to collapse/prune rx queues
  	 * to reduce memory overhead, so add a little headroom here.
  	 * Few sockets backlog are possibly concurrently non empty.
  	 */
  	limit += 64*1024;
c9c332125   Eric Dumazet   tcp: add tcp_add_...
1676
1677
1678
1679
1680
1681
1682
1683
  	if (unlikely(sk_add_backlog(sk, skb, limit))) {
  		bh_unlock_sock(sk);
  		__NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPBACKLOGDROP);
  		return true;
  	}
  	return false;
  }
  EXPORT_SYMBOL(tcp_add_backlog);
ac6e78007   Eric Dumazet   tcp: take care of...
1684
1685
1686
  int tcp_filter(struct sock *sk, struct sk_buff *skb)
  {
  	struct tcphdr *th = (struct tcphdr *)skb->data;
ac6e78007   Eric Dumazet   tcp: take care of...
1687

f2feaefda   Christoph Paasch   tcp: Don't access...
1688
  	return sk_filter_trim_cap(sk, skb, th->doff * 4);
ac6e78007   Eric Dumazet   tcp: take care of...
1689
1690
  }
  EXPORT_SYMBOL(tcp_filter);
eeea10b83   Eric Dumazet   tcp: add tcp_v4_f...
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
  static void tcp_v4_restore_cb(struct sk_buff *skb)
  {
  	memmove(IPCB(skb), &TCP_SKB_CB(skb)->header.h4,
  		sizeof(struct inet_skb_parm));
  }
  
  static void tcp_v4_fill_cb(struct sk_buff *skb, const struct iphdr *iph,
  			   const struct tcphdr *th)
  {
  	/* This is tricky : We move IPCB at its correct location into TCP_SKB_CB()
  	 * barrier() makes sure compiler wont play fool^Waliasing games.
  	 */
  	memmove(&TCP_SKB_CB(skb)->header.h4, IPCB(skb),
  		sizeof(struct inet_skb_parm));
  	barrier();
  
  	TCP_SKB_CB(skb)->seq = ntohl(th->seq);
  	TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
  				    skb->len - th->doff * 4);
  	TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);
  	TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th);
  	TCP_SKB_CB(skb)->tcp_tw_isn = 0;
  	TCP_SKB_CB(skb)->ip_dsfield = ipv4_get_dsfield(iph);
  	TCP_SKB_CB(skb)->sacked	 = 0;
  	TCP_SKB_CB(skb)->has_rxtstamp =
  			skb->tstamp || skb_hwtstamps(skb)->hwtstamp;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1718
1719
1720
1721
1722
1723
  /*
   *	From tcp_input.c
   */
  
  int tcp_v4_rcv(struct sk_buff *skb)
  {
3b24d854c   Eric Dumazet   tcp/dccp: do not ...
1724
  	struct net *net = dev_net(skb->dev);
8b27dae5a   Eric Dumazet   tcp: add one skb ...
1725
  	struct sk_buff *skb_to_free;
3fa6f616a   David Ahern   net: ipv4: add se...
1726
  	int sdif = inet_sdif(skb);
eddc9ec53   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
1727
  	const struct iphdr *iph;
cf533ea53   Eric Dumazet   tcp: add const qu...
1728
  	const struct tcphdr *th;
3b24d854c   Eric Dumazet   tcp/dccp: do not ...
1729
  	bool refcounted;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1730
1731
1732
1733
1734
1735
1736
  	struct sock *sk;
  	int ret;
  
  	if (skb->pkt_type != PACKET_HOST)
  		goto discard_it;
  
  	/* Count it even if it's bad */
90bbcc608   Eric Dumazet   net: tcp: rename ...
1737
  	__TCP_INC_STATS(net, TCP_MIB_INSEGS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1738
1739
1740
  
  	if (!pskb_may_pull(skb, sizeof(struct tcphdr)))
  		goto discard_it;
ea1627c20   Eric Dumazet   tcp: minor optimi...
1741
  	th = (const struct tcphdr *)skb->data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1742

ea1627c20   Eric Dumazet   tcp: minor optimi...
1743
  	if (unlikely(th->doff < sizeof(struct tcphdr) / 4))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1744
1745
1746
1747
1748
1749
  		goto bad_packet;
  	if (!pskb_may_pull(skb, th->doff * 4))
  		goto discard_it;
  
  	/* An explanation is required here, I think.
  	 * Packet length and doff are validated by header prediction,
caa20d9ab   Stephen Hemminger   [TCP]: spelling f...
1750
  	 * provided case of th->doff==0 is eliminated.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1751
  	 * So, we defer the checks. */
ed70fcfce   Tom Herbert   net: Call skb_che...
1752
1753
  
  	if (skb_checksum_init(skb, IPPROTO_TCP, inet_compute_pseudo))
6a5dc9e59   Eric Dumazet   net: Add MIB coun...
1754
  		goto csum_error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1755

ea1627c20   Eric Dumazet   tcp: minor optimi...
1756
  	th = (const struct tcphdr *)skb->data;
eddc9ec53   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
1757
  	iph = ip_hdr(skb);
4bdc3d661   Eric Dumazet   tcp/dccp: fix beh...
1758
  lookup:
a583636a8   Craig Gallek   inet: refactor in...
1759
  	sk = __inet_lookup_skb(&tcp_hashinfo, skb, __tcp_hdrlen(th), th->source,
3fa6f616a   David Ahern   net: ipv4: add se...
1760
  			       th->dest, sdif, &refcounted);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1761
1762
  	if (!sk)
  		goto no_tcp_socket;
bb134d5d9   Eric Dumazet   tcp: Fix tcp_v4_r...
1763
1764
1765
  process:
  	if (sk->sk_state == TCP_TIME_WAIT)
  		goto do_time_wait;
079096f10   Eric Dumazet   tcp/dccp: install...
1766
1767
  	if (sk->sk_state == TCP_NEW_SYN_RECV) {
  		struct request_sock *req = inet_reqsk(sk);
e0f9759f5   Eric Dumazet   tcp: try to keep ...
1768
  		bool req_stolen = false;
7716682cc   Eric Dumazet   tcp/dccp: fix ano...
1769
  		struct sock *nsk;
079096f10   Eric Dumazet   tcp/dccp: install...
1770
1771
  
  		sk = req->rsk_listener;
729235554   Eric Dumazet   tcp: md5: release...
1772
  		if (unlikely(tcp_v4_inbound_md5_hash(sk, skb))) {
e65c332de   Eric Dumazet   tcp: md5: increme...
1773
  			sk_drops_add(sk, skb);
729235554   Eric Dumazet   tcp: md5: release...
1774
1775
1776
  			reqsk_put(req);
  			goto discard_it;
  		}
4fd44a98f   Frank van der Linden   tcp: verify the c...
1777
1778
1779
1780
  		if (tcp_checksum_complete(skb)) {
  			reqsk_put(req);
  			goto csum_error;
  		}
7716682cc   Eric Dumazet   tcp/dccp: fix ano...
1781
  		if (unlikely(sk->sk_state != TCP_LISTEN)) {
f03f2e154   Eric Dumazet   tcp/dccp: add ine...
1782
  			inet_csk_reqsk_queue_drop_and_put(sk, req);
4bdc3d661   Eric Dumazet   tcp/dccp: fix beh...
1783
1784
  			goto lookup;
  		}
3b24d854c   Eric Dumazet   tcp/dccp: do not ...
1785
1786
1787
  		/* We own a reference on the listener, increase it again
  		 * as we might lose it too soon.
  		 */
7716682cc   Eric Dumazet   tcp/dccp: fix ano...
1788
  		sock_hold(sk);
3b24d854c   Eric Dumazet   tcp/dccp: do not ...
1789
  		refcounted = true;
1f3b359f1   Eric Dumazet   tcp: fix a reques...
1790
  		nsk = NULL;
eeea10b83   Eric Dumazet   tcp: add tcp_v4_f...
1791
1792
1793
1794
  		if (!tcp_filter(sk, skb)) {
  			th = (const struct tcphdr *)skb->data;
  			iph = ip_hdr(skb);
  			tcp_v4_fill_cb(skb, iph, th);
e0f9759f5   Eric Dumazet   tcp: try to keep ...
1795
  			nsk = tcp_check_req(sk, skb, req, false, &req_stolen);
eeea10b83   Eric Dumazet   tcp: add tcp_v4_f...
1796
  		}
079096f10   Eric Dumazet   tcp/dccp: install...
1797
1798
  		if (!nsk) {
  			reqsk_put(req);
e0f9759f5   Eric Dumazet   tcp: try to keep ...
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
  			if (req_stolen) {
  				/* Another cpu got exclusive access to req
  				 * and created a full blown socket.
  				 * Try to feed this packet to this socket
  				 * instead of discarding it.
  				 */
  				tcp_v4_restore_cb(skb);
  				sock_put(sk);
  				goto lookup;
  			}
7716682cc   Eric Dumazet   tcp/dccp: fix ano...
1809
  			goto discard_and_relse;
079096f10   Eric Dumazet   tcp/dccp: install...
1810
1811
  		}
  		if (nsk == sk) {
079096f10   Eric Dumazet   tcp/dccp: install...
1812
  			reqsk_put(req);
eeea10b83   Eric Dumazet   tcp: add tcp_v4_f...
1813
  			tcp_v4_restore_cb(skb);
079096f10   Eric Dumazet   tcp/dccp: install...
1814
1815
  		} else if (tcp_child_process(sk, nsk, skb)) {
  			tcp_v4_send_reset(nsk, skb);
7716682cc   Eric Dumazet   tcp/dccp: fix ano...
1816
  			goto discard_and_relse;
079096f10   Eric Dumazet   tcp/dccp: install...
1817
  		} else {
7716682cc   Eric Dumazet   tcp/dccp: fix ano...
1818
  			sock_put(sk);
079096f10   Eric Dumazet   tcp/dccp: install...
1819
1820
1821
  			return 0;
  		}
  	}
6cce09f87   Eric Dumazet   tcp: Add SNMP cou...
1822
  	if (unlikely(iph->ttl < inet_sk(sk)->min_ttl)) {
02a1d6e7a   Eric Dumazet   net: rename NET_{...
1823
  		__NET_INC_STATS(net, LINUX_MIB_TCPMINTTLDROP);
d218d1113   Stephen Hemminger   tcp: Generalized ...
1824
  		goto discard_and_relse;
6cce09f87   Eric Dumazet   tcp: Add SNMP cou...
1825
  	}
d218d1113   Stephen Hemminger   tcp: Generalized ...
1826

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1827
1828
  	if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
  		goto discard_and_relse;
9ea88a153   Dmitry Popov   tcp: md5: check m...
1829

9ea88a153   Dmitry Popov   tcp: md5: check m...
1830
1831
  	if (tcp_v4_inbound_md5_hash(sk, skb))
  		goto discard_and_relse;
9ea88a153   Dmitry Popov   tcp: md5: check m...
1832

895b5c9f2   Florian Westphal   netfilter: drop b...
1833
  	nf_reset_ct(skb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1834

ac6e78007   Eric Dumazet   tcp: take care of...
1835
  	if (tcp_filter(sk, skb))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1836
  		goto discard_and_relse;
ac6e78007   Eric Dumazet   tcp: take care of...
1837
1838
  	th = (const struct tcphdr *)skb->data;
  	iph = ip_hdr(skb);
eeea10b83   Eric Dumazet   tcp: add tcp_v4_f...
1839
  	tcp_v4_fill_cb(skb, iph, th);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1840
1841
  
  	skb->dev = NULL;
e994b2f0f   Eric Dumazet   tcp: do not lock ...
1842
1843
1844
1845
1846
1847
  	if (sk->sk_state == TCP_LISTEN) {
  		ret = tcp_v4_do_rcv(sk, skb);
  		goto put_and_return;
  	}
  
  	sk_incoming_cpu_update(sk);
c63661848   Ingo Molnar   [PATCH] lockdep: ...
1848
  	bh_lock_sock_nested(sk);
a44d6eacd   Martin KaFai Lau   tcp: Add RFC4898 ...
1849
  	tcp_segs_in(tcp_sk(sk), skb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1850
1851
  	ret = 0;
  	if (!sock_owned_by_user(sk)) {
8b27dae5a   Eric Dumazet   tcp: add one skb ...
1852
1853
  		skb_to_free = sk->sk_rx_skb_cache;
  		sk->sk_rx_skb_cache = NULL;
e7942d063   Florian Westphal   tcp: remove prequ...
1854
  		ret = tcp_v4_do_rcv(sk, skb);
8b27dae5a   Eric Dumazet   tcp: add one skb ...
1855
1856
1857
1858
  	} else {
  		if (tcp_add_backlog(sk, skb))
  			goto discard_and_relse;
  		skb_to_free = NULL;
6b03a53a5   Zhu Yi   tcp: use limited ...
1859
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1860
  	bh_unlock_sock(sk);
8b27dae5a   Eric Dumazet   tcp: add one skb ...
1861
1862
  	if (skb_to_free)
  		__kfree_skb(skb_to_free);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1863

e994b2f0f   Eric Dumazet   tcp: do not lock ...
1864
  put_and_return:
3b24d854c   Eric Dumazet   tcp/dccp: do not ...
1865
1866
  	if (refcounted)
  		sock_put(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1867
1868
1869
1870
1871
1872
  
  	return ret;
  
  no_tcp_socket:
  	if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
  		goto discard_it;
eeea10b83   Eric Dumazet   tcp: add tcp_v4_f...
1873
  	tcp_v4_fill_cb(skb, iph, th);
12e25e104   Eric Dumazet   tcp: remove redun...
1874
  	if (tcp_checksum_complete(skb)) {
6a5dc9e59   Eric Dumazet   net: Add MIB coun...
1875
  csum_error:
90bbcc608   Eric Dumazet   net: tcp: rename ...
1876
  		__TCP_INC_STATS(net, TCP_MIB_CSUMERRORS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1877
  bad_packet:
90bbcc608   Eric Dumazet   net: tcp: rename ...
1878
  		__TCP_INC_STATS(net, TCP_MIB_INERRS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1879
  	} else {
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1880
  		tcp_v4_send_reset(NULL, skb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1881
1882
1883
1884
1885
  	}
  
  discard_it:
  	/* Discard frame. */
  	kfree_skb(skb);
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
1886
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1887
1888
  
  discard_and_relse:
532182cd6   Eric Dumazet   tcp: increment sk...
1889
  	sk_drops_add(sk, skb);
3b24d854c   Eric Dumazet   tcp/dccp: do not ...
1890
1891
  	if (refcounted)
  		sock_put(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1892
1893
1894
1895
  	goto discard_it;
  
  do_time_wait:
  	if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
9469c7b4a   YOSHIFUJI Hideaki   [NET]: Use typesa...
1896
  		inet_twsk_put(inet_twsk(sk));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1897
1898
  		goto discard_it;
  	}
eeea10b83   Eric Dumazet   tcp: add tcp_v4_f...
1899
  	tcp_v4_fill_cb(skb, iph, th);
6a5dc9e59   Eric Dumazet   net: Add MIB coun...
1900
1901
1902
  	if (tcp_checksum_complete(skb)) {
  		inet_twsk_put(inet_twsk(sk));
  		goto csum_error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1903
  	}
9469c7b4a   YOSHIFUJI Hideaki   [NET]: Use typesa...
1904
  	switch (tcp_timewait_state_process(inet_twsk(sk), skb, th)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1905
  	case TCP_TW_SYN: {
c346dca10   YOSHIFUJI Hideaki   [NET] NETNS: Omit...
1906
  		struct sock *sk2 = inet_lookup_listener(dev_net(skb->dev),
a583636a8   Craig Gallek   inet: refactor in...
1907
1908
  							&tcp_hashinfo, skb,
  							__tcp_hdrlen(th),
da5e36308   Tom Herbert   soreuseport: TCP/...
1909
  							iph->saddr, th->source,
eddc9ec53   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
1910
  							iph->daddr, th->dest,
3fa6f616a   David Ahern   net: ipv4: add se...
1911
1912
  							inet_iif(skb),
  							sdif);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1913
  		if (sk2) {
dbe7faa40   Eric Dumazet   inet: inet_twsk_d...
1914
  			inet_twsk_deschedule_put(inet_twsk(sk));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1915
  			sk = sk2;
eeea10b83   Eric Dumazet   tcp: add tcp_v4_f...
1916
  			tcp_v4_restore_cb(skb);
3b24d854c   Eric Dumazet   tcp/dccp: do not ...
1917
  			refcounted = false;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1918
1919
  			goto process;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1920
  	}
fcfd6dfab   Gustavo A. R. Silva   ipv4: mark expect...
1921
1922
  		/* to ACK */
  		/* fall through */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1923
1924
1925
1926
  	case TCP_TW_ACK:
  		tcp_v4_timewait_ack(sk, skb);
  		break;
  	case TCP_TW_RST:
271c3b9b7   Florian Westphal   tcp: honour SO_BI...
1927
1928
1929
  		tcp_v4_send_reset(sk, skb);
  		inet_twsk_deschedule_put(inet_twsk(sk));
  		goto discard_it;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1930
1931
1932
1933
  	case TCP_TW_SUCCESS:;
  	}
  	goto discard_it;
  }
ccb7c410d   David S. Miller   timewait_sock: Cr...
1934
1935
1936
1937
  static struct timewait_sock_ops tcp_timewait_sock_ops = {
  	.twsk_obj_size	= sizeof(struct tcp_timewait_sock),
  	.twsk_unique	= tcp_twsk_unique,
  	.twsk_destructor= tcp_twsk_destructor,
ccb7c410d   David S. Miller   timewait_sock: Cr...
1938
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1939

63d02d157   Eric Dumazet   net: tcp: ipv6_ma...
1940
  void inet_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb)
5d299f3d3   Eric Dumazet   net: ipv6: fix TC...
1941
1942
  {
  	struct dst_entry *dst = skb_dst(skb);
5037e9ef9   Eric Dumazet   net: fix IP early...
1943
  	if (dst && dst_hold_safe(dst)) {
ca777eff5   Eric Dumazet   tcp: remove dst r...
1944
1945
1946
  		sk->sk_rx_dst = dst;
  		inet_sk(sk)->rx_dst_ifindex = skb->skb_iif;
  	}
5d299f3d3   Eric Dumazet   net: ipv6: fix TC...
1947
  }
63d02d157   Eric Dumazet   net: tcp: ipv6_ma...
1948
  EXPORT_SYMBOL(inet_sk_rx_dst_set);
5d299f3d3   Eric Dumazet   net: ipv6: fix TC...
1949

3b401a81c   Stephen Hemminger   inet: inet_connec...
1950
  const struct inet_connection_sock_af_ops ipv4_specific = {
543d9cfee   Arnaldo Carvalho de Melo   [NET]: Identation...
1951
1952
1953
  	.queue_xmit	   = ip_queue_xmit,
  	.send_check	   = tcp_v4_send_check,
  	.rebuild_header	   = inet_sk_rebuild_header,
5d299f3d3   Eric Dumazet   net: ipv6: fix TC...
1954
  	.sk_rx_dst_set	   = inet_sk_rx_dst_set,
543d9cfee   Arnaldo Carvalho de Melo   [NET]: Identation...
1955
1956
  	.conn_request	   = tcp_v4_conn_request,
  	.syn_recv_sock	   = tcp_v4_syn_recv_sock,
543d9cfee   Arnaldo Carvalho de Melo   [NET]: Identation...
1957
1958
1959
1960
1961
  	.net_header_len	   = sizeof(struct iphdr),
  	.setsockopt	   = ip_setsockopt,
  	.getsockopt	   = ip_getsockopt,
  	.addr2sockaddr	   = inet_csk_addr2sockaddr,
  	.sockaddr_len	   = sizeof(struct sockaddr_in),
3fdadf7d2   Dmitry Mishin   [NET]: {get|set}s...
1962
  #ifdef CONFIG_COMPAT
543d9cfee   Arnaldo Carvalho de Melo   [NET]: Identation...
1963
1964
  	.compat_setsockopt = compat_ip_setsockopt,
  	.compat_getsockopt = compat_ip_getsockopt,
3fdadf7d2   Dmitry Mishin   [NET]: {get|set}s...
1965
  #endif
4fab90719   Neal Cardwell   tcp: fix tcp_rele...
1966
  	.mtu_reduced	   = tcp_v4_mtu_reduced,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1967
  };
4bc2f18ba   Eric Dumazet   net/ipv4: EXPORT_...
1968
  EXPORT_SYMBOL(ipv4_specific);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1969

cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1970
  #ifdef CONFIG_TCP_MD5SIG
b2e4b3deb   Stephen Hemminger   tcp: MD5 operatio...
1971
  static const struct tcp_sock_af_ops tcp_sock_ipv4_specific = {
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1972
  	.md5_lookup		= tcp_v4_md5_lookup,
49a72dfb8   Adam Langley   tcp: Fix MD5 sign...
1973
  	.calc_md5_hash		= tcp_v4_md5_hash_skb,
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1974
  	.md5_parse		= tcp_v4_parse_md5_keys,
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1975
  };
b6332e6cf   Andrew Morton   [TCP]: Fix warnin...
1976
  #endif
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1977

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1978
1979
1980
1981
1982
  /* NOTE: A lot of things set to zero explicitly by call to
   *       sk_alloc() so need not be done here.
   */
  static int tcp_v4_init_sock(struct sock *sk)
  {
6687e988d   Arnaldo Carvalho de Melo   [ICSK]: Move TCP ...
1983
  	struct inet_connection_sock *icsk = inet_csk(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1984

900f65d36   Neal Cardwell   tcp: move duplica...
1985
  	tcp_init_sock(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1986

8292a17a3   Arnaldo Carvalho de Melo   [ICSK]: Rename st...
1987
  	icsk->icsk_af_ops = &ipv4_specific;
900f65d36   Neal Cardwell   tcp: move duplica...
1988

cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1989
  #ifdef CONFIG_TCP_MD5SIG
ac807fa8e   David S. Miller   tcp: Fix build wa...
1990
  	tcp_sk(sk)->af_specific = &tcp_sock_ipv4_specific;
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
1991
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1992

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1993
1994
  	return 0;
  }
7d06b2e05   Brian Haley   net: change proto...
1995
  void tcp_v4_destroy_sock(struct sock *sk)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1996
1997
  {
  	struct tcp_sock *tp = tcp_sk(sk);
e1a4aa50f   Song Liu   tcp: add tracepoi...
1998
  	trace_tcp_destroy_sock(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1999
  	tcp_clear_xmit_timers(sk);
6687e988d   Arnaldo Carvalho de Melo   [ICSK]: Move TCP ...
2000
  	tcp_cleanup_congestion_control(sk);
317a76f9a   Stephen Hemminger   [TCP]: Add plugga...
2001

734942cc4   Dave Watson   tcp: ULP infrastr...
2002
  	tcp_cleanup_ulp(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2003
  	/* Cleanup up the write buffer. */
fe067e8ab   David S. Miller   [TCP]: Abstract o...
2004
  	tcp_write_queue_purge(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2005

cf1ef3f07   Wei Wang   net/tcp_fastopen:...
2006
2007
  	/* Check if we want to disable active TFO */
  	tcp_fastopen_active_disable_ofo_check(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2008
  	/* Cleans up our, hopefully empty, out_of_order_queue. */
9f5afeae5   Yaogong Wang   tcp: use an RB tr...
2009
  	skb_rbtree_purge(&tp->out_of_order_queue);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2010

cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
2011
2012
2013
  #ifdef CONFIG_TCP_MD5SIG
  	/* Clean up the MD5 key list, if any */
  	if (tp->md5sig_info) {
a915da9b6   Eric Dumazet   tcp: md5: rcu con...
2014
  		tcp_clear_md5_list(sk);
fb7df5e40   Mat Martineau   tcp: md5: Handle ...
2015
  		kfree_rcu(rcu_dereference_protected(tp->md5sig_info, 1), rcu);
cfb6eeb4c   YOSHIFUJI Hideaki   [TCP]: MD5 Signat...
2016
2017
2018
  		tp->md5sig_info = NULL;
  	}
  #endif
1a2449a87   Chris Leech   [I/OAT]: TCP recv...
2019

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2020
  	/* Clean up a referenced TCP bind bucket. */
463c84b97   Arnaldo Carvalho de Melo   [NET]: Introduce ...
2021
  	if (inet_csk(sk)->icsk_bind_hash)
ab1e0a13d   Arnaldo Carvalho de Melo   [SOCK] proto: Add...
2022
  		inet_put_port(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2023

d983ea6f1   Eric Dumazet   tcp: add rcu prot...
2024
  	BUG_ON(rcu_access_pointer(tp->fastopen_rsk));
435cf559f   William Allen Simpson   TCPCT part 1d: de...
2025

cf60af03c   Yuchung Cheng   net-tcp: Fast Ope...
2026
2027
  	/* If socket is aborted during connect operation */
  	tcp_free_fastopen_req(tp);
1fba70e5b   Yuchung Cheng   tcp: socket optio...
2028
  	tcp_fastopen_destroy_cipher(sk);
cd8ae8529   Eric Dumazet   tcp: provide SYN ...
2029
  	tcp_saved_syn_free(tp);
cf60af03c   Yuchung Cheng   net-tcp: Fast Ope...
2030

180d8cd94   Glauber Costa   foundations of pe...
2031
  	sk_sockets_allocated_dec(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2032
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2033
2034
2035
2036
  EXPORT_SYMBOL(tcp_v4_destroy_sock);
  
  #ifdef CONFIG_PROC_FS
  /* Proc filesystem TCP sock list dumping. */
a8b690f98   Tom Herbert   tcp: Fix slowness...
2037
2038
2039
2040
2041
  /*
   * Get next listener socket follow cur.  If cur is NULL, get first socket
   * starting from bucket given in st->bucket; when st->bucket is zero the
   * very first socket in the hash table is returned.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2042
2043
  static void *listening_get_next(struct seq_file *seq, void *cur)
  {
37d849bb4   Christoph Hellwig   ipv{4,6}/tcp: sim...
2044
  	struct tcp_seq_afinfo *afinfo = PDE_DATA(file_inode(seq->file));
5799de0b1   Jianjun Kong   net: clean up net...
2045
  	struct tcp_iter_state *st = seq->private;
a4146b1b2   Denis V. Lunev   [TCP]: Replace st...
2046
  	struct net *net = seq_file_net(seq);
3b24d854c   Eric Dumazet   tcp/dccp: do not ...
2047
  	struct inet_listen_hashbucket *ilb;
0a0ee9f2d   Eric Dumazet   tcp/dccp: fix pos...
2048
  	struct hlist_nulls_node *node;
3b24d854c   Eric Dumazet   tcp/dccp: do not ...
2049
  	struct sock *sk = cur;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2050
2051
  
  	if (!sk) {
3b24d854c   Eric Dumazet   tcp/dccp: do not ...
2052
  get_head:
a8b690f98   Tom Herbert   tcp: Fix slowness...
2053
  		ilb = &tcp_hashinfo.listening_hash[st->bucket];
9652dc2eb   Eric Dumazet   tcp: relax listen...
2054
  		spin_lock(&ilb->lock);
0a0ee9f2d   Eric Dumazet   tcp/dccp: fix pos...
2055
  		sk = sk_nulls_head(&ilb->nulls_head);
a8b690f98   Tom Herbert   tcp: Fix slowness...
2056
  		st->offset = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2057
2058
  		goto get_sk;
  	}
5caea4ea7   Eric Dumazet   net: listening_ha...
2059
  	ilb = &tcp_hashinfo.listening_hash[st->bucket];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2060
  	++st->num;
a8b690f98   Tom Herbert   tcp: Fix slowness...
2061
  	++st->offset;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2062

0a0ee9f2d   Eric Dumazet   tcp/dccp: fix pos...
2063
  	sk = sk_nulls_next(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2064
  get_sk:
0a0ee9f2d   Eric Dumazet   tcp/dccp: fix pos...
2065
  	sk_nulls_for_each_from(sk, node) {
8475ef9fd   Pavel Emelyanov   netns: Don't leak...
2066
2067
  		if (!net_eq(sock_net(sk), net))
  			continue;
37d849bb4   Christoph Hellwig   ipv{4,6}/tcp: sim...
2068
  		if (sk->sk_family == afinfo->family)
3b24d854c   Eric Dumazet   tcp/dccp: do not ...
2069
  			return sk;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2070
  	}
9652dc2eb   Eric Dumazet   tcp: relax listen...
2071
  	spin_unlock(&ilb->lock);
a8b690f98   Tom Herbert   tcp: Fix slowness...
2072
  	st->offset = 0;
3b24d854c   Eric Dumazet   tcp/dccp: do not ...
2073
2074
2075
  	if (++st->bucket < INET_LHTABLE_SIZE)
  		goto get_head;
  	return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2076
2077
2078
2079
  }
  
  static void *listening_get_idx(struct seq_file *seq, loff_t *pos)
  {
a8b690f98   Tom Herbert   tcp: Fix slowness...
2080
2081
2082
2083
2084
2085
  	struct tcp_iter_state *st = seq->private;
  	void *rc;
  
  	st->bucket = 0;
  	st->offset = 0;
  	rc = listening_get_next(seq, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2086
2087
2088
2089
2090
2091
2092
  
  	while (rc && *pos) {
  		rc = listening_get_next(seq, rc);
  		--*pos;
  	}
  	return rc;
  }
05dbc7b59   Eric Dumazet   tcp/dccp: remove ...
2093
  static inline bool empty_bucket(const struct tcp_iter_state *st)
6eac56040   Andi Kleen   tcp: Skip empty h...
2094
  {
05dbc7b59   Eric Dumazet   tcp/dccp: remove ...
2095
  	return hlist_nulls_empty(&tcp_hashinfo.ehash[st->bucket].chain);
6eac56040   Andi Kleen   tcp: Skip empty h...
2096
  }
a8b690f98   Tom Herbert   tcp: Fix slowness...
2097
2098
2099
2100
  /*
   * Get first established socket starting from bucket given in st->bucket.
   * If st->bucket is zero, the very first socket in the hash is returned.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2101
2102
  static void *established_get_first(struct seq_file *seq)
  {
37d849bb4   Christoph Hellwig   ipv{4,6}/tcp: sim...
2103
  	struct tcp_seq_afinfo *afinfo = PDE_DATA(file_inode(seq->file));
5799de0b1   Jianjun Kong   net: clean up net...
2104
  	struct tcp_iter_state *st = seq->private;
a4146b1b2   Denis V. Lunev   [TCP]: Replace st...
2105
  	struct net *net = seq_file_net(seq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2106
  	void *rc = NULL;
a8b690f98   Tom Herbert   tcp: Fix slowness...
2107
2108
  	st->offset = 0;
  	for (; st->bucket <= tcp_hashinfo.ehash_mask; ++st->bucket) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2109
  		struct sock *sk;
3ab5aee7f   Eric Dumazet   net: Convert TCP ...
2110
  		struct hlist_nulls_node *node;
9db66bdcc   Eric Dumazet   net: convert TCP/...
2111
  		spinlock_t *lock = inet_ehash_lockp(&tcp_hashinfo, st->bucket);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2112

6eac56040   Andi Kleen   tcp: Skip empty h...
2113
2114
2115
  		/* Lockless fast path for the common case of empty buckets */
  		if (empty_bucket(st))
  			continue;
9db66bdcc   Eric Dumazet   net: convert TCP/...
2116
  		spin_lock_bh(lock);
3ab5aee7f   Eric Dumazet   net: Convert TCP ...
2117
  		sk_nulls_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
37d849bb4   Christoph Hellwig   ipv{4,6}/tcp: sim...
2118
  			if (sk->sk_family != afinfo->family ||
878628fbf   YOSHIFUJI Hideaki   [NET] NETNS: Omit...
2119
  			    !net_eq(sock_net(sk), net)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2120
2121
2122
2123
2124
  				continue;
  			}
  			rc = sk;
  			goto out;
  		}
9db66bdcc   Eric Dumazet   net: convert TCP/...
2125
  		spin_unlock_bh(lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2126
2127
2128
2129
2130
2131
2132
  	}
  out:
  	return rc;
  }
  
  static void *established_get_next(struct seq_file *seq, void *cur)
  {
37d849bb4   Christoph Hellwig   ipv{4,6}/tcp: sim...
2133
  	struct tcp_seq_afinfo *afinfo = PDE_DATA(file_inode(seq->file));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2134
  	struct sock *sk = cur;
3ab5aee7f   Eric Dumazet   net: Convert TCP ...
2135
  	struct hlist_nulls_node *node;
5799de0b1   Jianjun Kong   net: clean up net...
2136
  	struct tcp_iter_state *st = seq->private;
a4146b1b2   Denis V. Lunev   [TCP]: Replace st...
2137
  	struct net *net = seq_file_net(seq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2138
2139
  
  	++st->num;
a8b690f98   Tom Herbert   tcp: Fix slowness...
2140
  	++st->offset;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2141

05dbc7b59   Eric Dumazet   tcp/dccp: remove ...
2142
  	sk = sk_nulls_next(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2143

3ab5aee7f   Eric Dumazet   net: Convert TCP ...
2144
  	sk_nulls_for_each_from(sk, node) {
37d849bb4   Christoph Hellwig   ipv{4,6}/tcp: sim...
2145
2146
  		if (sk->sk_family == afinfo->family &&
  		    net_eq(sock_net(sk), net))
05dbc7b59   Eric Dumazet   tcp/dccp: remove ...
2147
  			return sk;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2148
  	}
05dbc7b59   Eric Dumazet   tcp/dccp: remove ...
2149
2150
2151
  	spin_unlock_bh(inet_ehash_lockp(&tcp_hashinfo, st->bucket));
  	++st->bucket;
  	return established_get_first(seq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2152
2153
2154
2155
  }
  
  static void *established_get_idx(struct seq_file *seq, loff_t pos)
  {
a8b690f98   Tom Herbert   tcp: Fix slowness...
2156
2157
2158
2159
2160
  	struct tcp_iter_state *st = seq->private;
  	void *rc;
  
  	st->bucket = 0;
  	rc = established_get_first(seq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2161
2162
2163
2164
  
  	while (rc && pos) {
  		rc = established_get_next(seq, rc);
  		--pos;
7174259e6   Arnaldo Carvalho de Melo   [TCP_IPV4]: Codin...
2165
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2166
2167
2168
2169
2170
2171
  	return rc;
  }
  
  static void *tcp_get_idx(struct seq_file *seq, loff_t pos)
  {
  	void *rc;
5799de0b1   Jianjun Kong   net: clean up net...
2172
  	struct tcp_iter_state *st = seq->private;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2173

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2174
2175
2176
2177
  	st->state = TCP_SEQ_STATE_LISTENING;
  	rc	  = listening_get_idx(seq, &pos);
  
  	if (!rc) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2178
2179
2180
2181
2182
2183
  		st->state = TCP_SEQ_STATE_ESTABLISHED;
  		rc	  = established_get_idx(seq, pos);
  	}
  
  	return rc;
  }
a8b690f98   Tom Herbert   tcp: Fix slowness...
2184
2185
2186
2187
2188
2189
2190
2191
  static void *tcp_seek_last_pos(struct seq_file *seq)
  {
  	struct tcp_iter_state *st = seq->private;
  	int offset = st->offset;
  	int orig_num = st->num;
  	void *rc = NULL;
  
  	switch (st->state) {
a8b690f98   Tom Herbert   tcp: Fix slowness...
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
  	case TCP_SEQ_STATE_LISTENING:
  		if (st->bucket >= INET_LHTABLE_SIZE)
  			break;
  		st->state = TCP_SEQ_STATE_LISTENING;
  		rc = listening_get_next(seq, NULL);
  		while (offset-- && rc)
  			rc = listening_get_next(seq, rc);
  		if (rc)
  			break;
  		st->bucket = 0;
05dbc7b59   Eric Dumazet   tcp/dccp: remove ...
2202
  		st->state = TCP_SEQ_STATE_ESTABLISHED;
a8b690f98   Tom Herbert   tcp: Fix slowness...
2203
2204
  		/* Fallthrough */
  	case TCP_SEQ_STATE_ESTABLISHED:
a8b690f98   Tom Herbert   tcp: Fix slowness...
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
  		if (st->bucket > tcp_hashinfo.ehash_mask)
  			break;
  		rc = established_get_first(seq);
  		while (offset-- && rc)
  			rc = established_get_next(seq, rc);
  	}
  
  	st->num = orig_num;
  
  	return rc;
  }
37d849bb4   Christoph Hellwig   ipv{4,6}/tcp: sim...
2216
  void *tcp_seq_start(struct seq_file *seq, loff_t *pos)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2217
  {
5799de0b1   Jianjun Kong   net: clean up net...
2218
  	struct tcp_iter_state *st = seq->private;
a8b690f98   Tom Herbert   tcp: Fix slowness...
2219
2220
2221
2222
2223
2224
2225
  	void *rc;
  
  	if (*pos && *pos == st->last_pos) {
  		rc = tcp_seek_last_pos(seq);
  		if (rc)
  			goto out;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2226
2227
  	st->state = TCP_SEQ_STATE_LISTENING;
  	st->num = 0;
a8b690f98   Tom Herbert   tcp: Fix slowness...
2228
2229
2230
2231
2232
2233
2234
  	st->bucket = 0;
  	st->offset = 0;
  	rc = *pos ? tcp_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
  
  out:
  	st->last_pos = *pos;
  	return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2235
  }
37d849bb4   Christoph Hellwig   ipv{4,6}/tcp: sim...
2236
  EXPORT_SYMBOL(tcp_seq_start);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2237

37d849bb4   Christoph Hellwig   ipv{4,6}/tcp: sim...
2238
  void *tcp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2239
  {
a8b690f98   Tom Herbert   tcp: Fix slowness...
2240
  	struct tcp_iter_state *st = seq->private;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2241
  	void *rc = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2242
2243
2244
2245
2246
  
  	if (v == SEQ_START_TOKEN) {
  		rc = tcp_get_idx(seq, 0);
  		goto out;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2247
2248
  
  	switch (st->state) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2249
2250
2251
  	case TCP_SEQ_STATE_LISTENING:
  		rc = listening_get_next(seq, v);
  		if (!rc) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2252
  			st->state = TCP_SEQ_STATE_ESTABLISHED;
a8b690f98   Tom Herbert   tcp: Fix slowness...
2253
2254
  			st->bucket = 0;
  			st->offset = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2255
2256
2257
2258
  			rc	  = established_get_first(seq);
  		}
  		break;
  	case TCP_SEQ_STATE_ESTABLISHED:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2259
2260
2261
2262
2263
  		rc = established_get_next(seq, v);
  		break;
  	}
  out:
  	++*pos;
a8b690f98   Tom Herbert   tcp: Fix slowness...
2264
  	st->last_pos = *pos;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2265
2266
  	return rc;
  }
37d849bb4   Christoph Hellwig   ipv{4,6}/tcp: sim...
2267
  EXPORT_SYMBOL(tcp_seq_next);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2268

37d849bb4   Christoph Hellwig   ipv{4,6}/tcp: sim...
2269
  void tcp_seq_stop(struct seq_file *seq, void *v)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2270
  {
5799de0b1   Jianjun Kong   net: clean up net...
2271
  	struct tcp_iter_state *st = seq->private;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2272
2273
  
  	switch (st->state) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2274
2275
  	case TCP_SEQ_STATE_LISTENING:
  		if (v != SEQ_START_TOKEN)
9652dc2eb   Eric Dumazet   tcp: relax listen...
2276
  			spin_unlock(&tcp_hashinfo.listening_hash[st->bucket].lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2277
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2278
2279
  	case TCP_SEQ_STATE_ESTABLISHED:
  		if (v)
9db66bdcc   Eric Dumazet   net: convert TCP/...
2280
  			spin_unlock_bh(inet_ehash_lockp(&tcp_hashinfo, st->bucket));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2281
2282
2283
  		break;
  	}
  }
37d849bb4   Christoph Hellwig   ipv{4,6}/tcp: sim...
2284
  EXPORT_SYMBOL(tcp_seq_stop);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2285

d4f06873b   Eric Dumazet   inet: get_openreq...
2286
  static void get_openreq4(const struct request_sock *req,
aa3a0c8ce   Eric Dumazet   tcp: get_openreq[...
2287
  			 struct seq_file *f, int i)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2288
  {
2e6599cb8   Arnaldo Carvalho de Melo   [NET] Generalise ...
2289
  	const struct inet_request_sock *ireq = inet_rsk(req);
fa76ce732   Eric Dumazet   inet: get rid of ...
2290
  	long delta = req->rsk_timer.expires - jiffies;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2291

5e659e4cb   Pavel Emelyanov   [NET]: Fix heavy ...
2292
  	seq_printf(f, "%4d: %08X:%04X %08X:%04X"
652586df9   Tetsuo Handa   seq_file: remove ...
2293
  		" %02X %08X:%08X %02X:%08lX %08X %5u %8d %u %d %pK",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2294
  		i,
634fb979e   Eric Dumazet   inet: includes a ...
2295
  		ireq->ir_loc_addr,
d4f06873b   Eric Dumazet   inet: get_openreq...
2296
  		ireq->ir_num,
634fb979e   Eric Dumazet   inet: includes a ...
2297
2298
  		ireq->ir_rmt_addr,
  		ntohs(ireq->ir_rmt_port),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2299
2300
2301
  		TCP_SYN_RECV,
  		0, 0, /* could print option size, but that is af dependent. */
  		1,    /* timers active (only the expire timer) */
a399a8053   Eric Dumazet   time: jiffies_del...
2302
  		jiffies_delta_to_clock_t(delta),
e6c022a4f   Eric Dumazet   tcp: better retra...
2303
  		req->num_timeout,
aa3a0c8ce   Eric Dumazet   tcp: get_openreq[...
2304
2305
  		from_kuid_munged(seq_user_ns(f),
  				 sock_i_uid(req->rsk_listener)),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2306
2307
  		0,  /* non standard timer */
  		0, /* open_requests have no inode */
d4f06873b   Eric Dumazet   inet: get_openreq...
2308
  		0,
652586df9   Tetsuo Handa   seq_file: remove ...
2309
  		req);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2310
  }
652586df9   Tetsuo Handa   seq_file: remove ...
2311
  static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2312
2313
2314
  {
  	int timer_active;
  	unsigned long timer_expires;
cf533ea53   Eric Dumazet   tcp: add const qu...
2315
  	const struct tcp_sock *tp = tcp_sk(sk);
cf4c6bf83   Ilpo Järvinen   [TCP]: struct *so...
2316
  	const struct inet_connection_sock *icsk = inet_csk(sk);
cf533ea53   Eric Dumazet   tcp: add const qu...
2317
  	const struct inet_sock *inet = inet_sk(sk);
0536fcc03   Eric Dumazet   tcp: prepare fast...
2318
  	const struct fastopen_queue *fastopenq = &icsk->icsk_accept_queue.fastopenq;
c720c7e83   Eric Dumazet   inet: rename some...
2319
2320
2321
2322
  	__be32 dest = inet->inet_daddr;
  	__be32 src = inet->inet_rcv_saddr;
  	__u16 destp = ntohs(inet->inet_dport);
  	__u16 srcp = ntohs(inet->inet_sport);
49d090078   Eric Dumazet   tcp: diag: Dont r...
2323
  	int rx_queue;
00fd38d93   Eric Dumazet   tcp: ensure prope...
2324
  	int state;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2325

6ba8a3b19   Nandita Dukkipati   tcp: Tail loss pr...
2326
  	if (icsk->icsk_pending == ICSK_TIME_RETRANS ||
57dde7f70   Yuchung Cheng   tcp: add reorderi...
2327
  	    icsk->icsk_pending == ICSK_TIME_REO_TIMEOUT ||
6ba8a3b19   Nandita Dukkipati   tcp: Tail loss pr...
2328
  	    icsk->icsk_pending == ICSK_TIME_LOSS_PROBE) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2329
  		timer_active	= 1;
463c84b97   Arnaldo Carvalho de Melo   [NET]: Introduce ...
2330
2331
  		timer_expires	= icsk->icsk_timeout;
  	} else if (icsk->icsk_pending == ICSK_TIME_PROBE0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2332
  		timer_active	= 4;
463c84b97   Arnaldo Carvalho de Melo   [NET]: Introduce ...
2333
  		timer_expires	= icsk->icsk_timeout;
cf4c6bf83   Ilpo Järvinen   [TCP]: struct *so...
2334
  	} else if (timer_pending(&sk->sk_timer)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2335
  		timer_active	= 2;
cf4c6bf83   Ilpo Järvinen   [TCP]: struct *so...
2336
  		timer_expires	= sk->sk_timer.expires;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2337
2338
2339
2340
  	} else {
  		timer_active	= 0;
  		timer_expires = jiffies;
  	}
986ffdfd0   Yafang Shao   net: sock: replac...
2341
  	state = inet_sk_state_load(sk);
00fd38d93   Eric Dumazet   tcp: ensure prope...
2342
  	if (state == TCP_LISTEN)
49d090078   Eric Dumazet   tcp: diag: Dont r...
2343
2344
  		rx_queue = sk->sk_ack_backlog;
  	else
00fd38d93   Eric Dumazet   tcp: ensure prope...
2345
2346
  		/* Because we don't lock the socket,
  		 * we might find a transient negative value.
49d090078   Eric Dumazet   tcp: diag: Dont r...
2347
  		 */
dba7d9b8c   Eric Dumazet   tcp: annotate tp-...
2348
  		rx_queue = max_t(int, READ_ONCE(tp->rcv_nxt) -
7db48e983   Eric Dumazet   tcp: annotate tp-...
2349
  				      READ_ONCE(tp->copied_seq), 0);
49d090078   Eric Dumazet   tcp: diag: Dont r...
2350

5e659e4cb   Pavel Emelyanov   [NET]: Fix heavy ...
2351
  	seq_printf(f, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX "
652586df9   Tetsuo Handa   seq_file: remove ...
2352
  			"%08X %5u %8d %lu %d %pK %lu %lu %u %u %d",
00fd38d93   Eric Dumazet   tcp: ensure prope...
2353
  		i, src, srcp, dest, destp, state,
0f3174645   Eric Dumazet   tcp: annotate tp-...
2354
  		READ_ONCE(tp->write_seq) - tp->snd_una,
49d090078   Eric Dumazet   tcp: diag: Dont r...
2355
  		rx_queue,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2356
  		timer_active,
a399a8053   Eric Dumazet   time: jiffies_del...
2357
  		jiffies_delta_to_clock_t(timer_expires - jiffies),
463c84b97   Arnaldo Carvalho de Melo   [NET]: Introduce ...
2358
  		icsk->icsk_retransmits,
a7cb5a49b   Eric W. Biederman   userns: Print out...
2359
  		from_kuid_munged(seq_user_ns(f), sock_i_uid(sk)),
6687e988d   Arnaldo Carvalho de Melo   [ICSK]: Move TCP ...
2360
  		icsk->icsk_probes_out,
cf4c6bf83   Ilpo Järvinen   [TCP]: struct *so...
2361
  		sock_i_ino(sk),
41c6d650f   Reshetova, Elena   net: convert sock...
2362
  		refcount_read(&sk->sk_refcnt), sk,
7be87351a   Stephen Hemminger   tcp: /proc/net/tc...
2363
2364
  		jiffies_to_clock_t(icsk->icsk_rto),
  		jiffies_to_clock_t(icsk->icsk_ack.ato),
31954cd8b   Wei Wang   tcp: Refactor pin...
2365
  		(icsk->icsk_ack.quick << 1) | inet_csk_in_pingpong_mode(sk),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2366
  		tp->snd_cwnd,
00fd38d93   Eric Dumazet   tcp: ensure prope...
2367
2368
  		state == TCP_LISTEN ?
  		    fastopenq->max_qlen :
652586df9   Tetsuo Handa   seq_file: remove ...
2369
  		    (tcp_in_initial_slowstart(tp) ? -1 : tp->snd_ssthresh));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2370
  }
cf533ea53   Eric Dumazet   tcp: add const qu...
2371
  static void get_timewait4_sock(const struct inet_timewait_sock *tw,
652586df9   Tetsuo Handa   seq_file: remove ...
2372
  			       struct seq_file *f, int i)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2373
  {
789f558cf   Eric Dumazet   tcp/dccp: get rid...
2374
  	long delta = tw->tw_timer.expires - jiffies;
23f33c2d4   Al Viro   [IPV4]: struct in...
2375
  	__be32 dest, src;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2376
  	__u16 destp, srcp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2377
2378
2379
2380
2381
  
  	dest  = tw->tw_daddr;
  	src   = tw->tw_rcv_saddr;
  	destp = ntohs(tw->tw_dport);
  	srcp  = ntohs(tw->tw_sport);
5e659e4cb   Pavel Emelyanov   [NET]: Fix heavy ...
2382
  	seq_printf(f, "%4d: %08X:%04X %08X:%04X"
652586df9   Tetsuo Handa   seq_file: remove ...
2383
  		" %02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %pK",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2384
  		i, src, srcp, dest, destp, tw->tw_substate, 0, 0,
a399a8053   Eric Dumazet   time: jiffies_del...
2385
  		3, jiffies_delta_to_clock_t(delta), 0, 0, 0, 0,
41c6d650f   Reshetova, Elena   net: convert sock...
2386
  		refcount_read(&tw->tw_refcnt), tw);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2387
2388
2389
2390
2391
2392
  }
  
  #define TMPSZ 150
  
  static int tcp4_seq_show(struct seq_file *seq, void *v)
  {
5799de0b1   Jianjun Kong   net: clean up net...
2393
  	struct tcp_iter_state *st;
05dbc7b59   Eric Dumazet   tcp/dccp: remove ...
2394
  	struct sock *sk = v;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2395

652586df9   Tetsuo Handa   seq_file: remove ...
2396
  	seq_setwidth(seq, TMPSZ - 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2397
  	if (v == SEQ_START_TOKEN) {
652586df9   Tetsuo Handa   seq_file: remove ...
2398
  		seq_puts(seq, "  sl  local_address rem_address   st tx_queue "
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2399
2400
2401
2402
2403
  			   "rx_queue tr tm->when retrnsmt   uid  timeout "
  			   "inode");
  		goto out;
  	}
  	st = seq->private;
079096f10   Eric Dumazet   tcp/dccp: install...
2404
2405
2406
  	if (sk->sk_state == TCP_TIME_WAIT)
  		get_timewait4_sock(v, seq, st->num);
  	else if (sk->sk_state == TCP_NEW_SYN_RECV)
aa3a0c8ce   Eric Dumazet   tcp: get_openreq[...
2407
  		get_openreq4(v, seq, st->num);
079096f10   Eric Dumazet   tcp/dccp: install...
2408
2409
  	else
  		get_tcp4_sock(v, seq, st->num);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2410
  out:
652586df9   Tetsuo Handa   seq_file: remove ...
2411
2412
  	seq_pad(seq, '
  ');
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2413
2414
  	return 0;
  }
37d849bb4   Christoph Hellwig   ipv{4,6}/tcp: sim...
2415
2416
2417
2418
2419
2420
  static const struct seq_operations tcp4_seq_ops = {
  	.show		= tcp4_seq_show,
  	.start		= tcp_seq_start,
  	.next		= tcp_seq_next,
  	.stop		= tcp_seq_stop,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2421
  static struct tcp_seq_afinfo tcp4_seq_afinfo = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2422
  	.family		= AF_INET,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2423
  };
2c8c1e729   Alexey Dobriyan   net: spread __net...
2424
  static int __net_init tcp4_proc_init_net(struct net *net)
757764f61   Pavel Emelyanov   [NETNS][TCP]: Reg...
2425
  {
c35063722   Christoph Hellwig   proc: introduce p...
2426
2427
  	if (!proc_create_net_data("tcp", 0444, net->proc_net, &tcp4_seq_ops,
  			sizeof(struct tcp_iter_state), &tcp4_seq_afinfo))
37d849bb4   Christoph Hellwig   ipv{4,6}/tcp: sim...
2428
2429
  		return -ENOMEM;
  	return 0;
757764f61   Pavel Emelyanov   [NETNS][TCP]: Reg...
2430
  }
2c8c1e729   Alexey Dobriyan   net: spread __net...
2431
  static void __net_exit tcp4_proc_exit_net(struct net *net)
757764f61   Pavel Emelyanov   [NETNS][TCP]: Reg...
2432
  {
37d849bb4   Christoph Hellwig   ipv{4,6}/tcp: sim...
2433
  	remove_proc_entry("tcp", net->proc_net);
757764f61   Pavel Emelyanov   [NETNS][TCP]: Reg...
2434
2435
2436
2437
2438
2439
  }
  
  static struct pernet_operations tcp4_net_ops = {
  	.init = tcp4_proc_init_net,
  	.exit = tcp4_proc_exit_net,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2440
2441
  int __init tcp4_proc_init(void)
  {
757764f61   Pavel Emelyanov   [NETNS][TCP]: Reg...
2442
  	return register_pernet_subsys(&tcp4_net_ops);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2443
2444
2445
2446
  }
  
  void tcp4_proc_exit(void)
  {
757764f61   Pavel Emelyanov   [NETNS][TCP]: Reg...
2447
  	unregister_pernet_subsys(&tcp4_net_ops);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2448
2449
2450
2451
2452
2453
2454
  }
  #endif /* CONFIG_PROC_FS */
  
  struct proto tcp_prot = {
  	.name			= "TCP",
  	.owner			= THIS_MODULE,
  	.close			= tcp_close,
d74bad4e7   Andrey Ignatov   bpf: Hooks for sy...
2455
  	.pre_connect		= tcp_v4_pre_connect,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2456
2457
  	.connect		= tcp_v4_connect,
  	.disconnect		= tcp_disconnect,
463c84b97   Arnaldo Carvalho de Melo   [NET]: Introduce ...
2458
  	.accept			= inet_csk_accept,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2459
2460
2461
2462
2463
2464
  	.ioctl			= tcp_ioctl,
  	.init			= tcp_v4_init_sock,
  	.destroy		= tcp_v4_destroy_sock,
  	.shutdown		= tcp_shutdown,
  	.setsockopt		= tcp_setsockopt,
  	.getsockopt		= tcp_getsockopt,
4b9d07a44   Ursula Braun   net: introduce ke...
2465
  	.keepalive		= tcp_set_keepalive,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2466
  	.recvmsg		= tcp_recvmsg,
7ba429100   Changli Gao   inet, inet6: make...
2467
2468
  	.sendmsg		= tcp_sendmsg,
  	.sendpage		= tcp_sendpage,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2469
  	.backlog_rcv		= tcp_v4_do_rcv,
46d3ceabd   Eric Dumazet   tcp: TCP Small Qu...
2470
  	.release_cb		= tcp_release_cb,
ab1e0a13d   Arnaldo Carvalho de Melo   [SOCK] proto: Add...
2471
2472
2473
  	.hash			= inet_hash,
  	.unhash			= inet_unhash,
  	.get_port		= inet_csk_get_port,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2474
  	.enter_memory_pressure	= tcp_enter_memory_pressure,
060447511   Eric Dumazet   tcp: add TCPMemor...
2475
  	.leave_memory_pressure	= tcp_leave_memory_pressure,
c9bee3b7f   Eric Dumazet   tcp: TCP_NOTSENT_...
2476
  	.stream_memory_free	= tcp_stream_memory_free,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2477
  	.sockets_allocated	= &tcp_sockets_allocated,
0a5578cf8   Arnaldo Carvalho de Melo   [ICSK]: Generalis...
2478
  	.orphan_count		= &tcp_orphan_count,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2479
2480
  	.memory_allocated	= &tcp_memory_allocated,
  	.memory_pressure	= &tcp_memory_pressure,
a4fe34bf9   Eric W. Biederman   tcp_memcontrol: R...
2481
  	.sysctl_mem		= sysctl_tcp_mem,
356d1833b   Eric Dumazet   tcp: Namespace-if...
2482
2483
  	.sysctl_wmem_offset	= offsetof(struct net, ipv4.sysctl_tcp_wmem),
  	.sysctl_rmem_offset	= offsetof(struct net, ipv4.sysctl_tcp_rmem),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2484
2485
  	.max_header		= MAX_TCP_HEADER,
  	.obj_size		= sizeof(struct tcp_sock),
5f0d5a3ae   Paul E. McKenney   mm: Rename SLAB_D...
2486
  	.slab_flags		= SLAB_TYPESAFE_BY_RCU,
6d6ee43e0   Arnaldo Carvalho de Melo   [TWSK]: Introduce...
2487
  	.twsk_prot		= &tcp_timewait_sock_ops,
60236fdd0   Arnaldo Carvalho de Melo   [NET] Rename open...
2488
  	.rsk_prot		= &tcp_request_sock_ops,
39d8cda76   Pavel Emelyanov   [SOCK]: Add udp_h...
2489
  	.h.hashinfo		= &tcp_hashinfo,
7ba429100   Changli Gao   inet, inet6: make...
2490
  	.no_autobind		= true,
543d9cfee   Arnaldo Carvalho de Melo   [NET]: Identation...
2491
2492
2493
2494
  #ifdef CONFIG_COMPAT
  	.compat_setsockopt	= compat_tcp_setsockopt,
  	.compat_getsockopt	= compat_tcp_getsockopt,
  #endif
c1e64e298   Lorenzo Colitti   net: diag: Suppor...
2495
  	.diag_destroy		= tcp_abort,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2496
  };
4bc2f18ba   Eric Dumazet   net/ipv4: EXPORT_...
2497
  EXPORT_SYMBOL(tcp_prot);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2498

bdbbb8527   Eric Dumazet   ipv4: tcp: get ri...
2499
2500
2501
  static void __net_exit tcp_sk_exit(struct net *net)
  {
  	int cpu;
b506bc975   Dust Li   tcp: fix a potent...
2502
2503
  	if (net->ipv4.tcp_congestion_control)
  		module_put(net->ipv4.tcp_congestion_control->owner);
6670e1524   Stephen Hemminger   tcp: Namespace-if...
2504

bdbbb8527   Eric Dumazet   ipv4: tcp: get ri...
2505
2506
2507
2508
  	for_each_possible_cpu(cpu)
  		inet_ctl_sock_destroy(*per_cpu_ptr(net->ipv4.tcp_sk, cpu));
  	free_percpu(net->ipv4.tcp_sk);
  }
046ee9023   Denis V. Lunev   [NETNS]: Create t...
2509
2510
  static int __net_init tcp_sk_init(struct net *net)
  {
fee83d097   Haishuang Yan   ipv4: Namespaceif...
2511
  	int res, cpu, cnt;
bdbbb8527   Eric Dumazet   ipv4: tcp: get ri...
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
  
  	net->ipv4.tcp_sk = alloc_percpu(struct sock *);
  	if (!net->ipv4.tcp_sk)
  		return -ENOMEM;
  
  	for_each_possible_cpu(cpu) {
  		struct sock *sk;
  
  		res = inet_ctl_sock_create(&sk, PF_INET, SOCK_RAW,
  					   IPPROTO_TCP, net);
  		if (res)
  			goto fail;
a9d6532b5   Eric Dumazet   ipv4: tcp: set SO...
2524
  		sock_set_flag(sk, SOCK_USE_WRITE_QUEUE);
431280eeb   Eric Dumazet   ipv4: tcp: send z...
2525
2526
2527
2528
2529
  
  		/* Please enforce IP_DF and IPID==0 for RST and
  		 * ACK sent in SYN-RECV and TIME-WAIT state.
  		 */
  		inet_sk(sk)->pmtudisc = IP_PMTUDISC_DO;
bdbbb8527   Eric Dumazet   ipv4: tcp: get ri...
2530
2531
  		*per_cpu_ptr(net->ipv4.tcp_sk, cpu) = sk;
  	}
492135557   Daniel Borkmann   tcp: add rfc3168,...
2532

5d134f1c1   Hannes Frederic Sowa   tcp: make sysctl_...
2533
  	net->ipv4.sysctl_tcp_ecn = 2;
492135557   Daniel Borkmann   tcp: add rfc3168,...
2534
  	net->ipv4.sysctl_tcp_ecn_fallback = 1;
b0f9ca53c   Fan Du   ipv4: Namespecify...
2535
  	net->ipv4.sysctl_tcp_base_mss = TCP_BASE_MSS;
5f3e2bf00   Eric Dumazet   tcp: add tcp_min_...
2536
  	net->ipv4.sysctl_tcp_min_snd_mss = TCP_MIN_SND_MSS;
6b58e0a5f   Fan Du   ipv4: Use binary ...
2537
  	net->ipv4.sysctl_tcp_probe_threshold = TCP_PROBE_THRESHOLD;
05cbc0db0   Fan Du   ipv4: Create prob...
2538
  	net->ipv4.sysctl_tcp_probe_interval = TCP_PROBE_INTERVAL;
c04b79b6c   Josh Hunt   tcp: add new tcp_...
2539
  	net->ipv4.sysctl_tcp_mtu_probe_floor = TCP_MIN_SND_MSS;
046ee9023   Denis V. Lunev   [NETNS]: Create t...
2540

13b287e8d   Nikolay Borisov   ipv4: Namespaceif...
2541
  	net->ipv4.sysctl_tcp_keepalive_time = TCP_KEEPALIVE_TIME;
9bd6861bd   Nikolay Borisov   ipv4: Namespecify...
2542
  	net->ipv4.sysctl_tcp_keepalive_probes = TCP_KEEPALIVE_PROBES;
b840d15d3   Nikolay Borisov   ipv4: Namespecify...
2543
  	net->ipv4.sysctl_tcp_keepalive_intvl = TCP_KEEPALIVE_INTVL;
13b287e8d   Nikolay Borisov   ipv4: Namespaceif...
2544

6fa251663   Nikolay Borisov   ipv4: Namespaceif...
2545
  	net->ipv4.sysctl_tcp_syn_retries = TCP_SYN_RETRIES;
7c083ecb3   Nikolay Borisov   ipv4: Namespaceif...
2546
  	net->ipv4.sysctl_tcp_synack_retries = TCP_SYNACK_RETRIES;
0aca737d4   David S. Miller   tcp: Fix syncooki...
2547
  	net->ipv4.sysctl_tcp_syncookies = 1;
1043e25ff   Nikolay Borisov   ipv4: Namespaceif...
2548
  	net->ipv4.sysctl_tcp_reordering = TCP_FASTRETRANS_THRESH;
ae5c3f406   Nikolay Borisov   ipv4: Namespaceif...
2549
  	net->ipv4.sysctl_tcp_retries1 = TCP_RETR1;
c6214a97c   Nikolay Borisov   ipv4: Namespaceif...
2550
  	net->ipv4.sysctl_tcp_retries2 = TCP_RETR2;
c402d9bef   Nikolay Borisov   ipv4: Namespaceif...
2551
  	net->ipv4.sysctl_tcp_orphan_retries = 0;
1e579caa1   Nikolay Borisov   ipv4: Namespaceif...
2552
  	net->ipv4.sysctl_tcp_fin_timeout = TCP_FIN_TIMEOUT;
4979f2d9f   Nikolay Borisov   ipv4: Namespaceif...
2553
  	net->ipv4.sysctl_tcp_notsent_lowat = UINT_MAX;
79e9fed46   Maciej Żenczykowski   net-tcp: extend t...
2554
  	net->ipv4.sysctl_tcp_tw_reuse = 2;
12ed8244e   Nikolay Borisov   ipv4: Namespaceif...
2555

fee83d097   Haishuang Yan   ipv4: Namespaceif...
2556
  	cnt = tcp_hashinfo.ehash_mask + 1;
743e48158   Yafang Shao   tcp: remove usele...
2557
  	net->ipv4.tcp_death_row.sysctl_max_tw_buckets = cnt / 2;
1946e672c   Haishuang Yan   ipv4: Namespaceif...
2558
  	net->ipv4.tcp_death_row.hashinfo = &tcp_hashinfo;
623d0c2db   Eric Dumazet   tcp: increase tcp...
2559
  	net->ipv4.sysctl_max_syn_backlog = max(128, cnt / 128);
f93010342   Eric Dumazet   tcp: Namespaceify...
2560
  	net->ipv4.sysctl_tcp_sack = 1;
9bb37ef00   Eric Dumazet   tcp: Namespaceify...
2561
  	net->ipv4.sysctl_tcp_window_scaling = 1;
5d2ed0521   Eric Dumazet   tcp: Namespaceify...
2562
  	net->ipv4.sysctl_tcp_timestamps = 1;
2ae21cf52   Eric Dumazet   tcp: Namespace-if...
2563
  	net->ipv4.sysctl_tcp_early_retrans = 3;
e20223f19   Eric Dumazet   tcp: Namespace-if...
2564
  	net->ipv4.sysctl_tcp_recovery = TCP_RACK_LOSS_DETECTION;
b510f0d23   Eric Dumazet   tcp: Namespace-if...
2565
  	net->ipv4.sysctl_tcp_slow_start_after_idle = 1; /* By default, RFC2861 behavior.  */
e0a1e5b51   Eric Dumazet   tcp: Namespace-if...
2566
  	net->ipv4.sysctl_tcp_retrans_collapse = 1;
c6e218035   Eric Dumazet   tcp: Namespace-if...
2567
  	net->ipv4.sysctl_tcp_max_reordering = 300;
6496f6bde   Eric Dumazet   tcp: Namespace-if...
2568
  	net->ipv4.sysctl_tcp_dsack = 1;
0c12654ac   Eric Dumazet   tcp: Namespace-if...
2569
  	net->ipv4.sysctl_tcp_app_win = 31;
94f0893e0   Eric Dumazet   tcp: Namespace-if...
2570
  	net->ipv4.sysctl_tcp_adv_win_scale = 1;
af9b69a7a   Eric Dumazet   tcp: Namespace-if...
2571
  	net->ipv4.sysctl_tcp_frto = 2;
4540c0cf9   Eric Dumazet   tcp: Namespace-if...
2572
  	net->ipv4.sysctl_tcp_moderate_rcvbuf = 1;
d06a99045   Eric Dumazet   tcp: Namespace-if...
2573
2574
2575
2576
2577
  	/* This limits the percentage of the congestion window which we
  	 * will allow a single TSO frame to consume.  Building TSO frames
  	 * which are too large can cause TCP streams to be bursty.
  	 */
  	net->ipv4.sysctl_tcp_tso_win_divisor = 3;
c73e5807e   Eric Dumazet   tcp: tsq: no long...
2578
2579
  	/* Default TSQ limit of 16 TSO segments */
  	net->ipv4.sysctl_tcp_limit_output_bytes = 16 * 65536;
b530b6814   Eric Dumazet   tcp: Namespace-if...
2580
2581
  	/* rfc5961 challenge ack rate limiting */
  	net->ipv4.sysctl_tcp_challenge_ack_limit = 1000;
26e9596e5   Eric Dumazet   tcp: Namespace-if...
2582
  	net->ipv4.sysctl_tcp_min_tso_segs = 2;
bd2397042   Eric Dumazet   tcp: Namespace-if...
2583
  	net->ipv4.sysctl_tcp_min_rtt_wlen = 300;
790f00e19   Eric Dumazet   tcp: Namespace-if...
2584
  	net->ipv4.sysctl_tcp_autocorking = 1;
4170ba6b5   Eric Dumazet   tcp: Namespace-if...
2585
  	net->ipv4.sysctl_tcp_invalid_ratelimit = HZ/2;
23a7102a2   Eric Dumazet   tcp: Namespace-if...
2586
  	net->ipv4.sysctl_tcp_pacing_ss_ratio = 200;
c26e91f8b   Eric Dumazet   tcp: Namespace-if...
2587
  	net->ipv4.sysctl_tcp_pacing_ca_ratio = 120;
356d1833b   Eric Dumazet   tcp: Namespace-if...
2588
2589
2590
2591
2592
2593
2594
2595
  	if (net != &init_net) {
  		memcpy(net->ipv4.sysctl_tcp_rmem,
  		       init_net.ipv4.sysctl_tcp_rmem,
  		       sizeof(init_net.ipv4.sysctl_tcp_rmem));
  		memcpy(net->ipv4.sysctl_tcp_wmem,
  		       init_net.ipv4.sysctl_tcp_wmem,
  		       sizeof(init_net.ipv4.sysctl_tcp_wmem));
  	}
6d82aa242   Eric Dumazet   tcp: add tcp_comp...
2596
  	net->ipv4.sysctl_tcp_comp_sack_delay_ns = NSEC_PER_MSEC;
9c21d2fc4   Eric Dumazet   tcp: add tcp_comp...
2597
  	net->ipv4.sysctl_tcp_comp_sack_nr = 44;
e1cfcbe82   Haishuang Yan   ipv4: Namespaceif...
2598
  	net->ipv4.sysctl_tcp_fastopen = TFO_CLIENT_ENABLE;
437138485   Haishuang Yan   ipv4: Namespaceif...
2599
  	spin_lock_init(&net->ipv4.tcp_fastopen_ctx_lock);
3733be14a   Haishuang Yan   ipv4: Namespaceif...
2600
2601
  	net->ipv4.sysctl_tcp_fastopen_blackhole_timeout = 60 * 60;
  	atomic_set(&net->ipv4.tfo_active_disable_times, 0);
e1cfcbe82   Haishuang Yan   ipv4: Namespaceif...
2602

6670e1524   Stephen Hemminger   tcp: Namespace-if...
2603
2604
2605
2606
2607
2608
  	/* Reno is always built in */
  	if (!net_eq(net, &init_net) &&
  	    try_module_get(init_net.ipv4.tcp_congestion_control->owner))
  		net->ipv4.tcp_congestion_control = init_net.ipv4.tcp_congestion_control;
  	else
  		net->ipv4.tcp_congestion_control = &tcp_reno;
492135557   Daniel Borkmann   tcp: add rfc3168,...
2609
  	return 0;
bdbbb8527   Eric Dumazet   ipv4: tcp: get ri...
2610
2611
2612
2613
  fail:
  	tcp_sk_exit(net);
  
  	return res;
b099ce260   Eric W. Biederman   net: Batch inet_t...
2614
2615
2616
2617
  }
  
  static void __net_exit tcp_sk_exit_batch(struct list_head *net_exit_list)
  {
437138485   Haishuang Yan   ipv4: Namespaceif...
2618
  	struct net *net;
1946e672c   Haishuang Yan   ipv4: Namespaceif...
2619
  	inet_twsk_purge(&tcp_hashinfo, AF_INET);
437138485   Haishuang Yan   ipv4: Namespaceif...
2620
2621
2622
  
  	list_for_each_entry(net, net_exit_list, exit_list)
  		tcp_fastopen_ctx_destroy(net);
046ee9023   Denis V. Lunev   [NETNS]: Create t...
2623
2624
2625
  }
  
  static struct pernet_operations __net_initdata tcp_sk_ops = {
b099ce260   Eric W. Biederman   net: Batch inet_t...
2626
2627
2628
         .init	   = tcp_sk_init,
         .exit	   = tcp_sk_exit,
         .exit_batch = tcp_sk_exit_batch,
046ee9023   Denis V. Lunev   [NETNS]: Create t...
2629
  };
9b0f976f2   Denis V. Lunev   [INET]: Remove st...
2630
  void __init tcp_v4_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2631
  {
6a1b3054d   Eric W. Biederman   tcp: Like icmp us...
2632
  	if (register_pernet_subsys(&tcp_sk_ops))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2633
2634
  		panic("Failed to create the TCP control socket.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2635
  }