Blame view
net/ipv4/tcp_ipv4.c
63.1 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 |
/* * 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 Linux-2.6.12-rc2 |
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
* IPv4 specific functions * * * code split from: * linux/ipv4/tcp.c * linux/ipv4/tcp_input.c * linux/ipv4/tcp_output.c * * See tcp.c for author information * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ /* * 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 [NET] Rename open... |
37 |
* request_sock handling and moved |
1da177e4c Linux-2.6.12-rc2 |
38 39 |
* most of it into the af independent code. * Added tail drop and some other bugfixes. |
caa20d9ab [TCP]: spelling f... |
40 |
* Added new listen semantics. |
1da177e4c Linux-2.6.12-rc2 |
41 42 43 44 45 46 47 48 49 50 51 |
* 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 net: ipv4: Standa... |
52 |
#define pr_fmt(fmt) "TCP: " fmt |
1da177e4c Linux-2.6.12-rc2 |
53 |
|
eb4dea585 net: Fix percpu c... |
54 |
#include <linux/bottom_half.h> |
1da177e4c Linux-2.6.12-rc2 |
55 56 57 58 59 60 61 62 |
#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 include cleanup: ... |
63 |
#include <linux/slab.h> |
1da177e4c Linux-2.6.12-rc2 |
64 |
|
457c4cbc5 [NET]: Make /proc... |
65 |
#include <net/net_namespace.h> |
1da177e4c Linux-2.6.12-rc2 |
66 |
#include <net/icmp.h> |
304a16180 [INET]: Move the ... |
67 |
#include <net/inet_hashtables.h> |
1da177e4c Linux-2.6.12-rc2 |
68 |
#include <net/tcp.h> |
20380731b [NET]: Fix sparse... |
69 |
#include <net/transp_v6.h> |
1da177e4c Linux-2.6.12-rc2 |
70 71 |
#include <net/ipv6.h> #include <net/inet_common.h> |
6d6ee43e0 [TWSK]: Introduce... |
72 |
#include <net/timewait_sock.h> |
1da177e4c Linux-2.6.12-rc2 |
73 |
#include <net/xfrm.h> |
6e5714eaf net: Compute prot... |
74 |
#include <net/secure_seq.h> |
076bb0c82 net: rename inclu... |
75 |
#include <net/busy_poll.h> |
1da177e4c Linux-2.6.12-rc2 |
76 77 78 79 80 81 |
#include <linux/inet.h> #include <linux/ipv6.h> #include <linux/stddef.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> |
cf80e0e47 tcp: Use ahash |
82 |
#include <crypto/hash.h> |
cfb6eeb4c [TCP]: MD5 Signat... |
83 |
#include <linux/scatterlist.h> |
ab32ea5d8 [NET/IPV4/IPV6]: ... |
84 85 |
int sysctl_tcp_tw_reuse __read_mostly; int sysctl_tcp_low_latency __read_mostly; |
1da177e4c Linux-2.6.12-rc2 |
86 |
|
cfb6eeb4c [TCP]: MD5 Signat... |
87 |
#ifdef CONFIG_TCP_MD5SIG |
a915da9b6 tcp: md5: rcu con... |
88 |
static int tcp_v4_md5_hash_hdr(char *md5_hash, const struct tcp_md5sig_key *key, |
318cf7aaa tcp: md5: add mor... |
89 |
__be32 daddr, __be32 saddr, const struct tcphdr *th); |
cfb6eeb4c [TCP]: MD5 Signat... |
90 |
#endif |
5caea4ea7 net: listening_ha... |
91 |
struct inet_hashinfo tcp_hashinfo; |
4bc2f18ba net/ipv4: EXPORT_... |
92 |
EXPORT_SYMBOL(tcp_hashinfo); |
1da177e4c Linux-2.6.12-rc2 |
93 |
|
936b8bdb5 tcp: add init_seq... |
94 |
static __u32 tcp_v4_init_sequence(const struct sk_buff *skb) |
1da177e4c Linux-2.6.12-rc2 |
95 |
{ |
eddc9ec53 [SK_BUFF]: Introd... |
96 97 |
return secure_tcp_sequence_number(ip_hdr(skb)->daddr, ip_hdr(skb)->saddr, |
aa8223c7b [SK_BUFF]: Introd... |
98 99 |
tcp_hdr(skb)->dest, tcp_hdr(skb)->source); |
1da177e4c Linux-2.6.12-rc2 |
100 |
} |
6d6ee43e0 [TWSK]: Introduce... |
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp) { const struct tcp_timewait_sock *tcptw = tcp_twsk(sktw); struct tcp_sock *tp = tcp_sk(sk); /* 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 && |
51456b291 ipv4: coding styl... |
118 |
(!twp || (sysctl_tcp_tw_reuse && |
9d729f72d [NET]: Convert xt... |
119 |
get_seconds() - tcptw->tw_ts_recent_stamp > 1))) { |
6d6ee43e0 [TWSK]: Introduce... |
120 121 122 123 124 125 126 127 128 129 130 |
tp->write_seq = tcptw->tw_snd_nxt + 65535 + 2; if (tp->write_seq == 0) tp->write_seq = 1; tp->rx_opt.ts_recent = tcptw->tw_ts_recent; tp->rx_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp; sock_hold(sktw); return 1; } return 0; } |
6d6ee43e0 [TWSK]: Introduce... |
131 |
EXPORT_SYMBOL_GPL(tcp_twsk_unique); |
1da177e4c Linux-2.6.12-rc2 |
132 133 134 |
/* This will initiate an outgoing connection. */ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) { |
2d7192d6c ipv4: Sanitize an... |
135 |
struct sockaddr_in *usin = (struct sockaddr_in *)uaddr; |
1da177e4c Linux-2.6.12-rc2 |
136 137 |
struct inet_sock *inet = inet_sk(sk); struct tcp_sock *tp = tcp_sk(sk); |
dca8b089c ipv4: Rearrange h... |
138 |
__be16 orig_sport, orig_dport; |
bada8adc4 [IPV4]: ip_route_... |
139 |
__be32 daddr, nexthop; |
da905bd1d tcp: Use cork flo... |
140 |
struct flowi4 *fl4; |
2d7192d6c ipv4: Sanitize an... |
141 |
struct rtable *rt; |
1da177e4c Linux-2.6.12-rc2 |
142 |
int err; |
f6d8bd051 inet: add RCU pro... |
143 |
struct ip_options_rcu *inet_opt; |
1da177e4c Linux-2.6.12-rc2 |
144 145 146 147 148 149 150 151 |
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 inet: add RCU pro... |
152 |
inet_opt = rcu_dereference_protected(inet->inet_opt, |
1e1d04e67 net: introduce lo... |
153 |
lockdep_sock_is_held(sk)); |
f6d8bd051 inet: add RCU pro... |
154 |
if (inet_opt && inet_opt->opt.srr) { |
1da177e4c Linux-2.6.12-rc2 |
155 156 |
if (!daddr) return -EINVAL; |
f6d8bd051 inet: add RCU pro... |
157 |
nexthop = inet_opt->opt.faddr; |
1da177e4c Linux-2.6.12-rc2 |
158 |
} |
dca8b089c ipv4: Rearrange h... |
159 160 |
orig_sport = inet->inet_sport; orig_dport = usin->sin_port; |
da905bd1d tcp: Use cork flo... |
161 162 |
fl4 = &inet->cork.fl.u.ip4; rt = ip_route_connect(fl4, nexthop, inet->inet_saddr, |
b23dd4fe4 ipv4: Make output... |
163 164 |
RT_CONN_FLAGS(sk), sk->sk_bound_dev_if, IPPROTO_TCP, |
0e0d44ab4 net: Remove FLOWI... |
165 |
orig_sport, orig_dport, sk); |
b23dd4fe4 ipv4: Make output... |
166 167 168 |
if (IS_ERR(rt)) { err = PTR_ERR(rt); if (err == -ENETUNREACH) |
f1d8cba61 inet: fix possibl... |
169 |
IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); |
b23dd4fe4 ipv4: Make output... |
170 |
return err; |
584bdf8cb [IPV4]: Fix "ipOu... |
171 |
} |
1da177e4c Linux-2.6.12-rc2 |
172 173 174 175 176 |
if (rt->rt_flags & (RTCF_MULTICAST | RTCF_BROADCAST)) { ip_rt_put(rt); return -ENETUNREACH; } |
f6d8bd051 inet: add RCU pro... |
177 |
if (!inet_opt || !inet_opt->opt.srr) |
da905bd1d tcp: Use cork flo... |
178 |
daddr = fl4->daddr; |
1da177e4c Linux-2.6.12-rc2 |
179 |
|
c720c7e83 inet: rename some... |
180 |
if (!inet->inet_saddr) |
da905bd1d tcp: Use cork flo... |
181 |
inet->inet_saddr = fl4->saddr; |
d1e559d0b inet: add IPv6 su... |
182 |
sk_rcv_saddr_set(sk, inet->inet_saddr); |
1da177e4c Linux-2.6.12-rc2 |
183 |
|
c720c7e83 inet: rename some... |
184 |
if (tp->rx_opt.ts_recent_stamp && inet->inet_daddr != daddr) { |
1da177e4c Linux-2.6.12-rc2 |
185 186 187 |
/* Reset inherited state */ tp->rx_opt.ts_recent = 0; tp->rx_opt.ts_recent_stamp = 0; |
ee9952831 tcp: Initial repa... |
188 189 |
if (likely(!tp->repair)) tp->write_seq = 0; |
1da177e4c Linux-2.6.12-rc2 |
190 |
} |
295ff7edb [TIMEWAIT]: Intro... |
191 |
if (tcp_death_row.sysctl_tw_recycle && |
81166dd6f tcp: Move timesta... |
192 193 |
!tp->rx_opt.ts_recent_stamp && fl4->daddr == daddr) tcp_fetch_timewait_stamp(sk, &rt->dst); |
1da177e4c Linux-2.6.12-rc2 |
194 |
|
c720c7e83 inet: rename some... |
195 |
inet->inet_dport = usin->sin_port; |
d1e559d0b inet: add IPv6 su... |
196 |
sk_daddr_set(sk, daddr); |
1da177e4c Linux-2.6.12-rc2 |
197 |
|
d83d8461f [IP_SOCKGLUE]: Re... |
198 |
inet_csk(sk)->icsk_ext_hdr_len = 0; |
f6d8bd051 inet: add RCU pro... |
199 200 |
if (inet_opt) inet_csk(sk)->icsk_ext_hdr_len = inet_opt->opt.optlen; |
1da177e4c Linux-2.6.12-rc2 |
201 |
|
bee7ca9ec net: TCP_MSS_DEFA... |
202 |
tp->rx_opt.mss_clamp = TCP_MSS_DEFAULT; |
1da177e4c Linux-2.6.12-rc2 |
203 204 205 206 207 208 209 |
/* 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); |
a7f5e7f16 [INET]: Generalis... |
210 |
err = inet_hash_connect(&tcp_death_row, sk); |
1da177e4c Linux-2.6.12-rc2 |
211 212 |
if (err) goto failure; |
877d1f629 net: Set sk_txhas... |
213 |
sk_set_txhash(sk); |
9e7ceb060 net: fix saving T... |
214 |
|
da905bd1d tcp: Use cork flo... |
215 |
rt = ip_route_newports(fl4, rt, orig_sport, orig_dport, |
b23dd4fe4 ipv4: Make output... |
216 217 218 219 |
inet->inet_sport, inet->inet_dport, sk); if (IS_ERR(rt)) { err = PTR_ERR(rt); rt = NULL; |
1da177e4c Linux-2.6.12-rc2 |
220 |
goto failure; |
b23dd4fe4 ipv4: Make output... |
221 |
} |
1da177e4c Linux-2.6.12-rc2 |
222 |
/* OK, now commit destination to socket. */ |
bcd761111 [NET]: Generalise... |
223 |
sk->sk_gso_type = SKB_GSO_TCPV4; |
d8d1f30b9 net-next: remove ... |
224 |
sk_setup_caps(sk, &rt->dst); |
1da177e4c Linux-2.6.12-rc2 |
225 |
|
ee9952831 tcp: Initial repa... |
226 |
if (!tp->write_seq && likely(!tp->repair)) |
c720c7e83 inet: rename some... |
227 228 229 |
tp->write_seq = secure_tcp_sequence_number(inet->inet_saddr, inet->inet_daddr, inet->inet_sport, |
1da177e4c Linux-2.6.12-rc2 |
230 |
usin->sin_port); |
c720c7e83 inet: rename some... |
231 |
inet->inet_id = tp->write_seq ^ jiffies; |
1da177e4c Linux-2.6.12-rc2 |
232 |
|
2b9164771 ipv6: adapt conne... |
233 |
err = tcp_connect(sk); |
ee9952831 tcp: Initial repa... |
234 |
|
1da177e4c Linux-2.6.12-rc2 |
235 236 237 238 239 240 241 |
rt = NULL; if (err) goto failure; return 0; failure: |
7174259e6 [TCP_IPV4]: Codin... |
242 243 244 245 |
/* * This unhashes the socket and releases the local port, * if necessary. */ |
1da177e4c Linux-2.6.12-rc2 |
246 247 248 |
tcp_set_state(sk, TCP_CLOSE); ip_rt_put(rt); sk->sk_route_caps = 0; |
c720c7e83 inet: rename some... |
249 |
inet->inet_dport = 0; |
1da177e4c Linux-2.6.12-rc2 |
250 251 |
return err; } |
4bc2f18ba net/ipv4: EXPORT_... |
252 |
EXPORT_SYMBOL(tcp_v4_connect); |
1da177e4c Linux-2.6.12-rc2 |
253 |
|
1da177e4c Linux-2.6.12-rc2 |
254 |
/* |
563d34d05 tcp: dont drop MT... |
255 256 257 |
* 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 Linux-2.6.12-rc2 |
258 |
*/ |
4fab90719 tcp: fix tcp_rele... |
259 |
void tcp_v4_mtu_reduced(struct sock *sk) |
1da177e4c Linux-2.6.12-rc2 |
260 261 262 |
{ struct dst_entry *dst; struct inet_sock *inet = inet_sk(sk); |
563d34d05 tcp: dont drop MT... |
263 |
u32 mtu = tcp_sk(sk)->mtu_info; |
1da177e4c Linux-2.6.12-rc2 |
264 |
|
80d0a69fc ipv4: Add helper ... |
265 266 |
dst = inet_csk_update_pmtu(sk, mtu); if (!dst) |
1da177e4c Linux-2.6.12-rc2 |
267 |
return; |
1da177e4c Linux-2.6.12-rc2 |
268 269 270 271 272 273 274 275 276 |
/* 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 ipv4: introduce n... |
277 |
ip_sk_accept_pmtu(sk) && |
d83d8461f [IP_SOCKGLUE]: Re... |
278 |
inet_csk(sk)->icsk_pmtu_cookie > mtu) { |
1da177e4c Linux-2.6.12-rc2 |
279 280 281 282 283 284 285 286 287 288 |
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 tcp: fix tcp_rele... |
289 |
EXPORT_SYMBOL(tcp_v4_mtu_reduced); |
1da177e4c Linux-2.6.12-rc2 |
290 |
|
55be7a9c6 ipv4: Add redirec... |
291 292 293 |
static void do_redirect(struct sk_buff *skb, struct sock *sk) { struct dst_entry *dst = __sk_dst_check(sk, 0); |
1ed5c48f2 net: Remove check... |
294 |
if (dst) |
6700c2709 net: Pass optiona... |
295 |
dst->ops->redirect(dst, sk, skb); |
55be7a9c6 ipv4: Add redirec... |
296 |
} |
26e373609 ipv4: tcp: handle... |
297 298 |
/* handle ICMP messages on TCP_NEW_SYN_RECV request sockets */ |
9cf749036 tcp: do not drop ... |
299 |
void tcp_req_err(struct sock *sk, u32 seq, bool abort) |
26e373609 ipv4: tcp: handle... |
300 301 302 303 304 305 306 |
{ 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 ipv4: tcp: handle... |
307 |
if (seq != tcp_rsk(req)->snt_isn) { |
02a1d6e7a net: rename NET_{... |
308 |
__NET_INC_STATS(net, LINUX_MIB_OUTOFWINDOWICMPS); |
9cf749036 tcp: do not drop ... |
309 |
} else if (abort) { |
26e373609 ipv4: tcp: handle... |
310 311 312 313 314 315 |
/* * 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 inet: fix double ... |
316 |
inet_csk_reqsk_queue_drop(req->rsk_listener, req); |
9caad8641 tcp: increment sk... |
317 |
tcp_listendrop(req->rsk_listener); |
26e373609 ipv4: tcp: handle... |
318 |
} |
ef84d8ce5 Revert "inet: fix... |
319 |
reqsk_put(req); |
26e373609 ipv4: tcp: handle... |
320 321 |
} EXPORT_SYMBOL(tcp_req_err); |
1da177e4c Linux-2.6.12-rc2 |
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 |
/* * 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. * */ |
4d1a2d9ec Revert Backoff [v... |
337 |
void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) |
1da177e4c Linux-2.6.12-rc2 |
338 |
{ |
b71d1d426 inet: constify ip... |
339 |
const struct iphdr *iph = (const struct iphdr *)icmp_skb->data; |
4d1a2d9ec Revert Backoff [v... |
340 |
struct tcphdr *th = (struct tcphdr *)(icmp_skb->data + (iph->ihl << 2)); |
f1ecd5d9e Revert Backoff [v... |
341 |
struct inet_connection_sock *icsk; |
1da177e4c Linux-2.6.12-rc2 |
342 343 |
struct tcp_sock *tp; struct inet_sock *inet; |
4d1a2d9ec Revert Backoff [v... |
344 345 |
const int type = icmp_hdr(icmp_skb)->type; const int code = icmp_hdr(icmp_skb)->code; |
1da177e4c Linux-2.6.12-rc2 |
346 |
struct sock *sk; |
f1ecd5d9e Revert Backoff [v... |
347 |
struct sk_buff *skb; |
0a672f741 tcp: improve fast... |
348 349 |
struct request_sock *fastopen; __u32 seq, snd_una; |
f1ecd5d9e Revert Backoff [v... |
350 |
__u32 remaining; |
1da177e4c Linux-2.6.12-rc2 |
351 |
int err; |
4d1a2d9ec Revert Backoff [v... |
352 |
struct net *net = dev_net(icmp_skb->dev); |
1da177e4c Linux-2.6.12-rc2 |
353 |
|
26e373609 ipv4: tcp: handle... |
354 355 356 |
sk = __inet_lookup_established(net, &tcp_hashinfo, iph->daddr, th->dest, iph->saddr, ntohs(th->source), inet_iif(icmp_skb)); |
1da177e4c Linux-2.6.12-rc2 |
357 |
if (!sk) { |
5d3848bc3 net: rename ICMP_... |
358 |
__ICMP_INC_STATS(net, ICMP_MIB_INERRORS); |
1da177e4c Linux-2.6.12-rc2 |
359 360 361 |
return; } if (sk->sk_state == TCP_TIME_WAIT) { |
9469c7b4a [NET]: Use typesa... |
362 |
inet_twsk_put(inet_twsk(sk)); |
1da177e4c Linux-2.6.12-rc2 |
363 364 |
return; } |
26e373609 ipv4: tcp: handle... |
365 366 |
seq = ntohl(th->seq); if (sk->sk_state == TCP_NEW_SYN_RECV) |
9cf749036 tcp: do not drop ... |
367 368 369 370 371 372 |
return tcp_req_err(sk, seq, type == ICMP_PARAMETERPROB || type == ICMP_TIME_EXCEEDED || (type == ICMP_DEST_UNREACH && (code == ICMP_NET_UNREACH || code == ICMP_HOST_UNREACH))); |
1da177e4c Linux-2.6.12-rc2 |
373 374 375 376 |
bh_lock_sock(sk); /* If too many ICMPs get dropped on busy * servers this needs to be solved differently. |
563d34d05 tcp: dont drop MT... |
377 378 |
* We do take care of PMTU discovery (RFC1191) special case : * we can receive locally generated ICMP messages while socket is held. |
1da177e4c Linux-2.6.12-rc2 |
379 |
*/ |
b74aa930e tcp: fix incorrec... |
380 381 |
if (sock_owned_by_user(sk)) { if (!(type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED)) |
02a1d6e7a net: rename NET_{... |
382 |
__NET_INC_STATS(net, LINUX_MIB_LOCKDROPPEDICMPS); |
b74aa930e tcp: fix incorrec... |
383 |
} |
1da177e4c Linux-2.6.12-rc2 |
384 385 |
if (sk->sk_state == TCP_CLOSE) goto out; |
97e3ecd11 TCP: check min TT... |
386 |
if (unlikely(iph->ttl < inet_sk(sk)->min_ttl)) { |
02a1d6e7a net: rename NET_{... |
387 |
__NET_INC_STATS(net, LINUX_MIB_TCPMINTTLDROP); |
97e3ecd11 TCP: check min TT... |
388 389 |
goto out; } |
f1ecd5d9e Revert Backoff [v... |
390 |
icsk = inet_csk(sk); |
1da177e4c Linux-2.6.12-rc2 |
391 |
tp = tcp_sk(sk); |
0a672f741 tcp: improve fast... |
392 393 394 |
/* XXX (TFO) - tp->snd_una should be ISN (tcp_create_openreq_child() */ fastopen = tp->fastopen_rsk; snd_una = fastopen ? tcp_rsk(fastopen)->snt_isn : tp->snd_una; |
1da177e4c Linux-2.6.12-rc2 |
395 |
if (sk->sk_state != TCP_LISTEN && |
0a672f741 tcp: improve fast... |
396 |
!between(seq, snd_una, tp->snd_nxt)) { |
02a1d6e7a net: rename NET_{... |
397 |
__NET_INC_STATS(net, LINUX_MIB_OUTOFWINDOWICMPS); |
1da177e4c Linux-2.6.12-rc2 |
398 399 400 401 |
goto out; } switch (type) { |
55be7a9c6 ipv4: Add redirec... |
402 403 404 |
case ICMP_REDIRECT: do_redirect(icmp_skb, sk); goto out; |
1da177e4c Linux-2.6.12-rc2 |
405 406 407 408 409 410 411 412 413 414 415 |
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 tcp: dont handle ... |
416 417 418 419 420 421 |
/* 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 tcp: dont drop MT... |
422 |
tp->mtu_info = info; |
144d56e91 tcp: fix possible... |
423 |
if (!sock_owned_by_user(sk)) { |
563d34d05 tcp: dont drop MT... |
424 |
tcp_v4_mtu_reduced(sk); |
144d56e91 tcp: fix possible... |
425 426 427 428 |
} else { if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED, &tp->tsq_flags)) sock_hold(sk); } |
1da177e4c Linux-2.6.12-rc2 |
429 430 431 432 |
goto out; } err = icmp_err_convert[code].errno; |
f1ecd5d9e Revert Backoff [v... |
433 434 435 436 437 |
/* 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 tcp: improve fast... |
438 |
!icsk->icsk_backoff || fastopen) |
f1ecd5d9e Revert Backoff [v... |
439 |
break; |
8f49c2703 tcp: Don't change... |
440 441 |
if (sock_owned_by_user(sk)) break; |
f1ecd5d9e Revert Backoff [v... |
442 |
icsk->icsk_backoff--; |
fcdd1cf4d tcp: avoid possib... |
443 444 445 |
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 Revert Backoff [v... |
446 447 448 |
skb = tcp_write_queue_head(sk); BUG_ON(!skb); |
7faee5c0d tcp: remove TCP_S... |
449 450 451 |
remaining = icsk->icsk_rto - min(icsk->icsk_rto, tcp_time_stamp - tcp_skb_timestamp(skb)); |
f1ecd5d9e Revert Backoff [v... |
452 453 454 455 |
if (remaining) { inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, remaining, TCP_RTO_MAX); |
f1ecd5d9e Revert Backoff [v... |
456 457 458 459 460 |
} else { /* RTO revert clocked out retransmission. * Will retransmit now */ tcp_retransmit_timer(sk); } |
1da177e4c Linux-2.6.12-rc2 |
461 462 463 464 465 466 467 468 469 |
break; case ICMP_TIME_EXCEEDED: err = EHOSTUNREACH; break; default: goto out; } switch (sk->sk_state) { |
1da177e4c Linux-2.6.12-rc2 |
470 |
case TCP_SYN_SENT: |
0a672f741 tcp: improve fast... |
471 472 473 474 |
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 ipv4: coding styl... |
475 |
if (fastopen && !fastopen->sk) |
0a672f741 tcp: improve fast... |
476 |
break; |
1da177e4c Linux-2.6.12-rc2 |
477 |
if (!sock_owned_by_user(sk)) { |
1da177e4c Linux-2.6.12-rc2 |
478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 |
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); } |
28850dc7c net: tcp: move GR... |
517 |
void __tcp_v4_send_check(struct sk_buff *skb, __be32 saddr, __be32 daddr) |
1da177e4c Linux-2.6.12-rc2 |
518 |
{ |
aa8223c7b [SK_BUFF]: Introd... |
519 |
struct tcphdr *th = tcp_hdr(skb); |
1da177e4c Linux-2.6.12-rc2 |
520 |
|
84fa7933a [NET]: Replace CH... |
521 |
if (skb->ip_summed == CHECKSUM_PARTIAL) { |
419f9f896 tcp: Handle CHECK... |
522 |
th->check = ~tcp_v4_check(skb->len, saddr, daddr, 0); |
663ead3bb [NET]: Use csum_s... |
523 |
skb->csum_start = skb_transport_header(skb) - skb->head; |
ff1dcadb1 [NET]: Split skb-... |
524 |
skb->csum_offset = offsetof(struct tcphdr, check); |
1da177e4c Linux-2.6.12-rc2 |
525 |
} else { |
419f9f896 tcp: Handle CHECK... |
526 |
th->check = tcp_v4_check(skb->len, saddr, daddr, |
07f0757a6 include/net net/ ... |
527 |
csum_partial(th, |
1da177e4c Linux-2.6.12-rc2 |
528 529 530 531 |
th->doff << 2, skb->csum)); } } |
419f9f896 tcp: Handle CHECK... |
532 |
/* This routine computes an IPv4 TCP checksum. */ |
bb2962461 inet: Remove unus... |
533 |
void tcp_v4_send_check(struct sock *sk, struct sk_buff *skb) |
419f9f896 tcp: Handle CHECK... |
534 |
{ |
cf533ea53 tcp: add const qu... |
535 |
const struct inet_sock *inet = inet_sk(sk); |
419f9f896 tcp: Handle CHECK... |
536 537 538 |
__tcp_v4_send_check(skb, inet->inet_saddr, inet->inet_daddr); } |
4bc2f18ba net/ipv4: EXPORT_... |
539 |
EXPORT_SYMBOL(tcp_v4_send_check); |
419f9f896 tcp: Handle CHECK... |
540 |
|
1da177e4c Linux-2.6.12-rc2 |
541 542 543 544 545 546 547 548 549 550 551 552 |
/* * 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 tcp/dccp: constif... |
553 |
static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb) |
1da177e4c Linux-2.6.12-rc2 |
554 |
{ |
cf533ea53 tcp: add const qu... |
555 |
const struct tcphdr *th = tcp_hdr(skb); |
cfb6eeb4c [TCP]: MD5 Signat... |
556 557 558 |
struct { struct tcphdr th; #ifdef CONFIG_TCP_MD5SIG |
714e85be3 [IPV6]: Assorted ... |
559 |
__be32 opt[(TCPOLEN_MD5SIG_ALIGNED >> 2)]; |
cfb6eeb4c [TCP]: MD5 Signat... |
560 561 |
#endif } rep; |
1da177e4c Linux-2.6.12-rc2 |
562 |
struct ip_reply_arg arg; |
cfb6eeb4c [TCP]: MD5 Signat... |
563 |
#ifdef CONFIG_TCP_MD5SIG |
e46787f0d tcp: send_reset: ... |
564 |
struct tcp_md5sig_key *key = NULL; |
658ddaaf6 tcp: md5: RST: ge... |
565 566 567 568 |
const __u8 *hash_location = NULL; unsigned char newhash[16]; int genhash; struct sock *sk1 = NULL; |
cfb6eeb4c [TCP]: MD5 Signat... |
569 |
#endif |
a86b1e301 inet: prepare str... |
570 |
struct net *net; |
1da177e4c Linux-2.6.12-rc2 |
571 572 573 574 |
/* Never send a reset in response to a reset. */ if (th->rst) return; |
c3658e8d0 tcp: fix possible... |
575 576 577 578 |
/* 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 Linux-2.6.12-rc2 |
579 580 581 |
return; /* Swap the send and the receive. */ |
cfb6eeb4c [TCP]: MD5 Signat... |
582 583 584 585 586 |
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 Linux-2.6.12-rc2 |
587 588 |
if (th->ack) { |
cfb6eeb4c [TCP]: MD5 Signat... |
589 |
rep.th.seq = th->ack_seq; |
1da177e4c Linux-2.6.12-rc2 |
590 |
} else { |
cfb6eeb4c [TCP]: MD5 Signat... |
591 592 593 |
rep.th.ack = 1; rep.th.ack_seq = htonl(ntohl(th->seq) + th->syn + th->fin + skb->len - (th->doff << 2)); |
1da177e4c Linux-2.6.12-rc2 |
594 |
} |
7174259e6 [TCP_IPV4]: Codin... |
595 |
memset(&arg, 0, sizeof(arg)); |
cfb6eeb4c [TCP]: MD5 Signat... |
596 597 |
arg.iov[0].iov_base = (unsigned char *)&rep; arg.iov[0].iov_len = sizeof(rep.th); |
0f85feae6 tcp: fix more NUL... |
598 |
net = sk ? sock_net(sk) : dev_net(skb_dst(skb)->dev); |
cfb6eeb4c [TCP]: MD5 Signat... |
599 |
#ifdef CONFIG_TCP_MD5SIG |
3b24d854c tcp/dccp: do not ... |
600 |
rcu_read_lock(); |
658ddaaf6 tcp: md5: RST: ge... |
601 |
hash_location = tcp_parse_md5sig_option(th); |
271c3b9b7 tcp: honour SO_BI... |
602 |
if (sk && sk_fullsock(sk)) { |
e46787f0d tcp: send_reset: ... |
603 604 605 |
key = tcp_md5_do_lookup(sk, (union tcp_md5_addr *) &ip_hdr(skb)->saddr, AF_INET); } else if (hash_location) { |
658ddaaf6 tcp: md5: RST: ge... |
606 607 608 609 610 611 612 |
/* * 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 inet: refactor in... |
613 614 |
sk1 = __inet_lookup_listener(net, &tcp_hashinfo, NULL, 0, ip_hdr(skb)->saddr, |
da5e36308 soreuseport: TCP/... |
615 |
th->source, ip_hdr(skb)->daddr, |
658ddaaf6 tcp: md5: RST: ge... |
616 617 618 |
ntohs(th->source), inet_iif(skb)); /* don't send rst if it can't find key */ if (!sk1) |
3b24d854c tcp/dccp: do not ... |
619 |
goto out; |
658ddaaf6 tcp: md5: RST: ge... |
620 621 622 |
key = tcp_md5_do_lookup(sk1, (union tcp_md5_addr *) &ip_hdr(skb)->saddr, AF_INET); if (!key) |
3b24d854c tcp/dccp: do not ... |
623 |
goto out; |
658ddaaf6 tcp: md5: RST: ge... |
624 |
|
39f8e58e5 tcp: md5: remove ... |
625 |
genhash = tcp_v4_md5_hash_skb(newhash, key, NULL, skb); |
658ddaaf6 tcp: md5: RST: ge... |
626 |
if (genhash || memcmp(hash_location, newhash, 16) != 0) |
3b24d854c tcp/dccp: do not ... |
627 |
goto out; |
658ddaaf6 tcp: md5: RST: ge... |
628 |
} |
cfb6eeb4c [TCP]: MD5 Signat... |
629 630 631 632 633 634 635 636 |
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 tcp: Fix MD5 sign... |
637 |
tcp_v4_md5_hash_hdr((__u8 *) &rep.opt[1], |
78e645cb8 tcpv[46]: fix md5... |
638 639 |
key, ip_hdr(skb)->saddr, ip_hdr(skb)->daddr, &rep.th); |
cfb6eeb4c [TCP]: MD5 Signat... |
640 641 |
} #endif |
eddc9ec53 [SK_BUFF]: Introd... |
642 643 |
arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr, ip_hdr(skb)->saddr, /* XXX */ |
52cd5750e tcp: fix length u... |
644 |
arg.iov[0].iov_len, IPPROTO_TCP, 0); |
1da177e4c Linux-2.6.12-rc2 |
645 |
arg.csumoffset = offsetof(struct tcphdr, check) / 2; |
271c3b9b7 tcp: honour SO_BI... |
646 |
arg.flags = (sk && inet_sk_transparent(sk)) ? IP_REPLY_ARG_NOSRCCHECK : 0; |
e2446eaab tcp_v4_send_reset... |
647 |
/* When socket is gone, all binding information is lost. |
4c6752584 tcp: resets are m... |
648 649 |
* 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 tcp_v4_send_reset... |
650 |
*/ |
4c6752584 tcp: resets are m... |
651 652 |
if (sk) arg.bound_dev_if = sk->sk_bound_dev_if; |
1da177e4c Linux-2.6.12-rc2 |
653 |
|
271c3b9b7 tcp: honour SO_BI... |
654 655 |
BUILD_BUG_ON(offsetof(struct sock, sk_bound_dev_if) != offsetof(struct inet_timewait_sock, tw_bound_dev_if)); |
66b13d99d ipv4: tcp: fix TO... |
656 |
arg.tos = ip_hdr(skb)->tos; |
47dcc20a3 ipv4: tcp: ip_sen... |
657 |
local_bh_disable(); |
bdbbb8527 ipv4: tcp: get ri... |
658 659 |
ip_send_unicast_reply(*this_cpu_ptr(net->ipv4.tcp_sk), skb, &TCP_SKB_CB(skb)->header.h4.opt, |
24a2d43d8 ipv4: rename ip_o... |
660 661 |
ip_hdr(skb)->saddr, ip_hdr(skb)->daddr, &arg, arg.iov[0].iov_len); |
1da177e4c Linux-2.6.12-rc2 |
662 |
|
90bbcc608 net: tcp: rename ... |
663 664 |
__TCP_INC_STATS(net, TCP_MIB_OUTSEGS); __TCP_INC_STATS(net, TCP_MIB_OUTRSTS); |
47dcc20a3 ipv4: tcp: ip_sen... |
665 |
local_bh_enable(); |
658ddaaf6 tcp: md5: RST: ge... |
666 667 |
#ifdef CONFIG_TCP_MD5SIG |
3b24d854c tcp/dccp: do not ... |
668 669 |
out: rcu_read_unlock(); |
658ddaaf6 tcp: md5: RST: ge... |
670 |
#endif |
1da177e4c Linux-2.6.12-rc2 |
671 672 673 674 675 |
} /* The code following below sending ACKs in SYN-RECV and TIME-WAIT states outside socket context is ugly, certainly. What can I do? */ |
e62a123b8 tcp: fix NULL der... |
676 677 |
static void tcp_v4_send_ack(struct net *net, struct sk_buff *skb, u32 seq, u32 ack, |
ee684b6f2 tcp: send packets... |
678 |
u32 win, u32 tsval, u32 tsecr, int oif, |
88ef4a5a7 tcp: Handle TCP S... |
679 |
struct tcp_md5sig_key *key, |
66b13d99d ipv4: tcp: fix TO... |
680 |
int reply_flags, u8 tos) |
1da177e4c Linux-2.6.12-rc2 |
681 |
{ |
cf533ea53 tcp: add const qu... |
682 |
const struct tcphdr *th = tcp_hdr(skb); |
1da177e4c Linux-2.6.12-rc2 |
683 684 |
struct { struct tcphdr th; |
714e85be3 [IPV6]: Assorted ... |
685 |
__be32 opt[(TCPOLEN_TSTAMP_ALIGNED >> 2) |
cfb6eeb4c [TCP]: MD5 Signat... |
686 |
#ifdef CONFIG_TCP_MD5SIG |
714e85be3 [IPV6]: Assorted ... |
687 |
+ (TCPOLEN_MD5SIG_ALIGNED >> 2) |
cfb6eeb4c [TCP]: MD5 Signat... |
688 689 |
#endif ]; |
1da177e4c Linux-2.6.12-rc2 |
690 691 692 693 |
} rep; struct ip_reply_arg arg; memset(&rep.th, 0, sizeof(struct tcphdr)); |
7174259e6 [TCP_IPV4]: Codin... |
694 |
memset(&arg, 0, sizeof(arg)); |
1da177e4c Linux-2.6.12-rc2 |
695 696 697 |
arg.iov[0].iov_base = (unsigned char *)&rep; arg.iov[0].iov_len = sizeof(rep.th); |
ee684b6f2 tcp: send packets... |
698 |
if (tsecr) { |
cfb6eeb4c [TCP]: MD5 Signat... |
699 700 701 |
rep.opt[0] = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); |
ee684b6f2 tcp: send packets... |
702 703 |
rep.opt[1] = htonl(tsval); rep.opt[2] = htonl(tsecr); |
cb48cfe80 [TCP]: Fix iov_le... |
704 |
arg.iov[0].iov_len += TCPOLEN_TSTAMP_ALIGNED; |
1da177e4c Linux-2.6.12-rc2 |
705 706 707 708 709 710 711 712 713 714 |
} /* 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 [TCP]: MD5 Signat... |
715 |
#ifdef CONFIG_TCP_MD5SIG |
cfb6eeb4c [TCP]: MD5 Signat... |
716 |
if (key) { |
ee684b6f2 tcp: send packets... |
717 |
int offset = (tsecr) ? 3 : 0; |
cfb6eeb4c [TCP]: MD5 Signat... |
718 719 720 721 722 723 724 |
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 tcp: Fix MD5 sign... |
725 |
tcp_v4_md5_hash_hdr((__u8 *) &rep.opt[offset], |
90b7e1120 tcp: MD5: Fix MD5... |
726 727 |
key, ip_hdr(skb)->saddr, ip_hdr(skb)->daddr, &rep.th); |
cfb6eeb4c [TCP]: MD5 Signat... |
728 729 |
} #endif |
88ef4a5a7 tcp: Handle TCP S... |
730 |
arg.flags = reply_flags; |
eddc9ec53 [SK_BUFF]: Introd... |
731 732 |
arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr, ip_hdr(skb)->saddr, /* XXX */ |
1da177e4c Linux-2.6.12-rc2 |
733 734 |
arg.iov[0].iov_len, IPPROTO_TCP, 0); arg.csumoffset = offsetof(struct tcphdr, check) / 2; |
9501f9722 tcp md5sig: Let t... |
735 736 |
if (oif) arg.bound_dev_if = oif; |
66b13d99d ipv4: tcp: fix TO... |
737 |
arg.tos = tos; |
47dcc20a3 ipv4: tcp: ip_sen... |
738 |
local_bh_disable(); |
bdbbb8527 ipv4: tcp: get ri... |
739 740 |
ip_send_unicast_reply(*this_cpu_ptr(net->ipv4.tcp_sk), skb, &TCP_SKB_CB(skb)->header.h4.opt, |
24a2d43d8 ipv4: rename ip_o... |
741 742 |
ip_hdr(skb)->saddr, ip_hdr(skb)->daddr, &arg, arg.iov[0].iov_len); |
1da177e4c Linux-2.6.12-rc2 |
743 |
|
90bbcc608 net: tcp: rename ... |
744 |
__TCP_INC_STATS(net, TCP_MIB_OUTSEGS); |
47dcc20a3 ipv4: tcp: ip_sen... |
745 |
local_bh_enable(); |
1da177e4c Linux-2.6.12-rc2 |
746 747 748 749 |
} static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb) { |
8feaf0c0a [INET]: Generalis... |
750 |
struct inet_timewait_sock *tw = inet_twsk(sk); |
cfb6eeb4c [TCP]: MD5 Signat... |
751 |
struct tcp_timewait_sock *tcptw = tcp_twsk(sk); |
1da177e4c Linux-2.6.12-rc2 |
752 |
|
e62a123b8 tcp: fix NULL der... |
753 754 |
tcp_v4_send_ack(sock_net(sk), skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, |
7174259e6 [TCP_IPV4]: Codin... |
755 |
tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, |
ee684b6f2 tcp: send packets... |
756 |
tcp_time_stamp + tcptw->tw_ts_offset, |
9501f9722 tcp md5sig: Let t... |
757 758 |
tcptw->tw_ts_recent, tw->tw_bound_dev_if, |
88ef4a5a7 tcp: Handle TCP S... |
759 |
tcp_twsk_md5_key(tcptw), |
66b13d99d ipv4: tcp: fix TO... |
760 761 |
tw->tw_transparent ? IP_REPLY_ARG_NOSRCCHECK : 0, tw->tw_tos |
9501f9722 tcp md5sig: Let t... |
762 |
); |
1da177e4c Linux-2.6.12-rc2 |
763 |
|
8feaf0c0a [INET]: Generalis... |
764 |
inet_twsk_put(tw); |
1da177e4c Linux-2.6.12-rc2 |
765 |
} |
a00e74442 tcp/dccp: constif... |
766 |
static void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, |
7174259e6 [TCP_IPV4]: Codin... |
767 |
struct request_sock *req) |
1da177e4c Linux-2.6.12-rc2 |
768 |
{ |
168a8f580 tcp: TCP Fast Ope... |
769 770 771 |
/* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV * sk->sk_state == TCP_SYN_RECV -> for Fast Open. */ |
e62a123b8 tcp: fix NULL der... |
772 773 |
u32 seq = (sk->sk_state == TCP_LISTEN) ? tcp_rsk(req)->snt_isn + 1 : tcp_sk(sk)->snd_nxt; |
20a2b49fc tcp: properly sca... |
774 775 776 777 778 |
/* 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: */ |
e62a123b8 tcp: fix NULL der... |
779 |
tcp_v4_send_ack(sock_net(sk), skb, seq, |
20a2b49fc tcp: properly sca... |
780 781 |
tcp_rsk(req)->rcv_nxt, req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, |
ee684b6f2 tcp: send packets... |
782 |
tcp_time_stamp, |
9501f9722 tcp md5sig: Let t... |
783 784 |
req->ts_recent, 0, |
a915da9b6 tcp: md5: rcu con... |
785 786 |
tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&ip_hdr(skb)->daddr, AF_INET), |
66b13d99d ipv4: tcp: fix TO... |
787 788 |
inet_rsk(req)->no_srccheck ? IP_REPLY_ARG_NOSRCCHECK : 0, ip_hdr(skb)->tos); |
1da177e4c Linux-2.6.12-rc2 |
789 |
} |
1da177e4c Linux-2.6.12-rc2 |
790 |
/* |
9bf1d83e7 [TCP]: Fix tcp_v4... |
791 |
* Send a SYN-ACK after having received a SYN. |
60236fdd0 [NET] Rename open... |
792 |
* This still operates on a request_sock only, not on a big |
1da177e4c Linux-2.6.12-rc2 |
793 794 |
* socket. */ |
0f935dbed tcp: constify tcp... |
795 |
static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst, |
d6274bd8d tcp: add send_syn... |
796 |
struct flowi *fl, |
72659ecce tcp: account SYN-... |
797 |
struct request_sock *req, |
ca6fb0651 tcp: attach SYNAC... |
798 |
struct tcp_fastopen_cookie *foc, |
b3d051477 tcp: do not mess ... |
799 |
enum tcp_synack_type synack_type) |
1da177e4c Linux-2.6.12-rc2 |
800 |
{ |
2e6599cb8 [NET] Generalise ... |
801 |
const struct inet_request_sock *ireq = inet_rsk(req); |
6bd023f3d ipv4: Make caller... |
802 |
struct flowi4 fl4; |
1da177e4c Linux-2.6.12-rc2 |
803 |
int err = -1; |
d41db5af2 ipv4: fix checkpa... |
804 |
struct sk_buff *skb; |
1da177e4c Linux-2.6.12-rc2 |
805 806 |
/* First, grab a route. */ |
ba3f7f04e ipv4: Kill FLOWI_... |
807 |
if (!dst && (dst = inet_csk_route_req(sk, &fl4, req)) == NULL) |
fd80eb942 [INET]: Remove st... |
808 |
return -1; |
1da177e4c Linux-2.6.12-rc2 |
809 |
|
b3d051477 tcp: do not mess ... |
810 |
skb = tcp_make_synack(sk, dst, req, foc, synack_type); |
1da177e4c Linux-2.6.12-rc2 |
811 812 |
if (skb) { |
634fb979e inet: includes a ... |
813 |
__tcp_v4_send_check(skb, ireq->ir_loc_addr, ireq->ir_rmt_addr); |
1da177e4c Linux-2.6.12-rc2 |
814 |
|
634fb979e inet: includes a ... |
815 816 |
err = ip_build_and_send_pkt(skb, sk, ireq->ir_loc_addr, ireq->ir_rmt_addr, |
2e6599cb8 [NET] Generalise ... |
817 |
ireq->opt); |
b9df3cb8c [TCP/DCCP]: Intro... |
818 |
err = net_xmit_eval(err); |
1da177e4c Linux-2.6.12-rc2 |
819 |
} |
1da177e4c Linux-2.6.12-rc2 |
820 821 822 823 |
return err; } /* |
60236fdd0 [NET] Rename open... |
824 |
* IPv4 request_sock destructor. |
1da177e4c Linux-2.6.12-rc2 |
825 |
*/ |
60236fdd0 [NET] Rename open... |
826 |
static void tcp_v4_reqsk_destructor(struct request_sock *req) |
1da177e4c Linux-2.6.12-rc2 |
827 |
{ |
a51482bde [NET]: kfree cleanup |
828 |
kfree(inet_rsk(req)->opt); |
1da177e4c Linux-2.6.12-rc2 |
829 |
} |
cfb6eeb4c [TCP]: MD5 Signat... |
830 831 832 833 834 835 836 837 |
#ifdef CONFIG_TCP_MD5SIG /* * RFC2385 MD5 checksumming requires a mapping of * IP address->MD5 Key. * We need to maintain these in the sk structure. */ /* Find the Key structure for an address. */ |
b83e3deb9 tcp: md5: constif... |
838 |
struct tcp_md5sig_key *tcp_md5_do_lookup(const struct sock *sk, |
a915da9b6 tcp: md5: rcu con... |
839 840 |
const union tcp_md5_addr *addr, int family) |
cfb6eeb4c [TCP]: MD5 Signat... |
841 |
{ |
fd3a154a0 tcp: md5: get rid... |
842 |
const struct tcp_sock *tp = tcp_sk(sk); |
a915da9b6 tcp: md5: rcu con... |
843 |
struct tcp_md5sig_key *key; |
a915da9b6 tcp: md5: rcu con... |
844 |
unsigned int size = sizeof(struct in_addr); |
fd3a154a0 tcp: md5: get rid... |
845 |
const struct tcp_md5sig_info *md5sig; |
cfb6eeb4c [TCP]: MD5 Signat... |
846 |
|
a8afca032 tcp: md5: protect... |
847 848 |
/* caller either holds rcu_read_lock() or socket lock */ md5sig = rcu_dereference_check(tp->md5sig_info, |
1e1d04e67 net: introduce lo... |
849 |
lockdep_sock_is_held(sk)); |
a8afca032 tcp: md5: protect... |
850 |
if (!md5sig) |
cfb6eeb4c [TCP]: MD5 Signat... |
851 |
return NULL; |
a915da9b6 tcp: md5: rcu con... |
852 853 854 855 |
#if IS_ENABLED(CONFIG_IPV6) if (family == AF_INET6) size = sizeof(struct in6_addr); #endif |
b67bfe0d4 hlist: drop the n... |
856 |
hlist_for_each_entry_rcu(key, &md5sig->head, node) { |
a915da9b6 tcp: md5: rcu con... |
857 858 859 860 |
if (key->family != family) continue; if (!memcmp(&key->addr, addr, size)) return key; |
cfb6eeb4c [TCP]: MD5 Signat... |
861 862 863 |
} return NULL; } |
a915da9b6 tcp: md5: rcu con... |
864 |
EXPORT_SYMBOL(tcp_md5_do_lookup); |
cfb6eeb4c [TCP]: MD5 Signat... |
865 |
|
b83e3deb9 tcp: md5: constif... |
866 |
struct tcp_md5sig_key *tcp_v4_md5_lookup(const struct sock *sk, |
fd3a154a0 tcp: md5: get rid... |
867 |
const struct sock *addr_sk) |
cfb6eeb4c [TCP]: MD5 Signat... |
868 |
{ |
b52e69217 tcp: md5: fix a t... |
869 |
const union tcp_md5_addr *addr; |
a915da9b6 tcp: md5: rcu con... |
870 |
|
b52e69217 tcp: md5: fix a t... |
871 |
addr = (const union tcp_md5_addr *)&addr_sk->sk_daddr; |
a915da9b6 tcp: md5: rcu con... |
872 |
return tcp_md5_do_lookup(sk, addr, AF_INET); |
cfb6eeb4c [TCP]: MD5 Signat... |
873 |
} |
cfb6eeb4c [TCP]: MD5 Signat... |
874 |
EXPORT_SYMBOL(tcp_v4_md5_lookup); |
cfb6eeb4c [TCP]: MD5 Signat... |
875 |
/* This can be called on a newly created socket, from other files */ |
a915da9b6 tcp: md5: rcu con... |
876 877 |
int tcp_md5_do_add(struct sock *sk, const union tcp_md5_addr *addr, int family, const u8 *newkey, u8 newkeylen, gfp_t gfp) |
cfb6eeb4c [TCP]: MD5 Signat... |
878 879 |
{ /* Add Key to the list */ |
b0a713e9e [TCP] MD5: Remove... |
880 |
struct tcp_md5sig_key *key; |
cfb6eeb4c [TCP]: MD5 Signat... |
881 |
struct tcp_sock *tp = tcp_sk(sk); |
a915da9b6 tcp: md5: rcu con... |
882 |
struct tcp_md5sig_info *md5sig; |
cfb6eeb4c [TCP]: MD5 Signat... |
883 |
|
c0353c7b5 ipv4: Fixed MD5 k... |
884 |
key = tcp_md5_do_lookup(sk, addr, family); |
cfb6eeb4c [TCP]: MD5 Signat... |
885 886 |
if (key) { /* Pre-existing entry - just update that one. */ |
a915da9b6 tcp: md5: rcu con... |
887 |
memcpy(key->key, newkey, newkeylen); |
b0a713e9e [TCP] MD5: Remove... |
888 |
key->keylen = newkeylen; |
a915da9b6 tcp: md5: rcu con... |
889 890 |
return 0; } |
260fcbeb1 tcp: properly han... |
891 |
|
a8afca032 tcp: md5: protect... |
892 |
md5sig = rcu_dereference_protected(tp->md5sig_info, |
1e1d04e67 net: introduce lo... |
893 |
lockdep_sock_is_held(sk)); |
a915da9b6 tcp: md5: rcu con... |
894 895 896 |
if (!md5sig) { md5sig = kmalloc(sizeof(*md5sig), gfp); if (!md5sig) |
cfb6eeb4c [TCP]: MD5 Signat... |
897 |
return -ENOMEM; |
cfb6eeb4c [TCP]: MD5 Signat... |
898 |
|
a915da9b6 tcp: md5: rcu con... |
899 900 |
sk_nocaps_add(sk, NETIF_F_GSO_MASK); INIT_HLIST_HEAD(&md5sig->head); |
a8afca032 tcp: md5: protect... |
901 |
rcu_assign_pointer(tp->md5sig_info, md5sig); |
a915da9b6 tcp: md5: rcu con... |
902 |
} |
cfb6eeb4c [TCP]: MD5 Signat... |
903 |
|
5f3d9cb29 tcp: md5: use soc... |
904 |
key = sock_kmalloc(sk, sizeof(*key), gfp); |
a915da9b6 tcp: md5: rcu con... |
905 906 |
if (!key) return -ENOMEM; |
71cea17ed tcp: md5: remove ... |
907 |
if (!tcp_alloc_md5sig_pool()) { |
5f3d9cb29 tcp: md5: use soc... |
908 |
sock_kfree_s(sk, key, sizeof(*key)); |
a915da9b6 tcp: md5: rcu con... |
909 |
return -ENOMEM; |
cfb6eeb4c [TCP]: MD5 Signat... |
910 |
} |
a915da9b6 tcp: md5: rcu con... |
911 912 913 914 915 916 917 918 |
memcpy(key->key, newkey, newkeylen); key->keylen = newkeylen; key->family = family; memcpy(&key->addr, addr, (family == AF_INET6) ? sizeof(struct in6_addr) : sizeof(struct in_addr)); hlist_add_head_rcu(&key->node, &md5sig->head); |
cfb6eeb4c [TCP]: MD5 Signat... |
919 920 |
return 0; } |
a915da9b6 tcp: md5: rcu con... |
921 |
EXPORT_SYMBOL(tcp_md5_do_add); |
cfb6eeb4c [TCP]: MD5 Signat... |
922 |
|
a915da9b6 tcp: md5: rcu con... |
923 |
int tcp_md5_do_del(struct sock *sk, const union tcp_md5_addr *addr, int family) |
cfb6eeb4c [TCP]: MD5 Signat... |
924 |
{ |
a915da9b6 tcp: md5: rcu con... |
925 |
struct tcp_md5sig_key *key; |
c0353c7b5 ipv4: Fixed MD5 k... |
926 |
key = tcp_md5_do_lookup(sk, addr, family); |
a915da9b6 tcp: md5: rcu con... |
927 928 929 |
if (!key) return -ENOENT; hlist_del_rcu(&key->node); |
5f3d9cb29 tcp: md5: use soc... |
930 |
atomic_sub(sizeof(*key), &sk->sk_omem_alloc); |
a915da9b6 tcp: md5: rcu con... |
931 |
kfree_rcu(key, rcu); |
a915da9b6 tcp: md5: rcu con... |
932 |
return 0; |
cfb6eeb4c [TCP]: MD5 Signat... |
933 |
} |
a915da9b6 tcp: md5: rcu con... |
934 |
EXPORT_SYMBOL(tcp_md5_do_del); |
cfb6eeb4c [TCP]: MD5 Signat... |
935 |
|
e0683e707 tcp: make tcp_cle... |
936 |
static void tcp_clear_md5_list(struct sock *sk) |
cfb6eeb4c [TCP]: MD5 Signat... |
937 938 |
{ struct tcp_sock *tp = tcp_sk(sk); |
a915da9b6 tcp: md5: rcu con... |
939 |
struct tcp_md5sig_key *key; |
b67bfe0d4 hlist: drop the n... |
940 |
struct hlist_node *n; |
a8afca032 tcp: md5: protect... |
941 |
struct tcp_md5sig_info *md5sig; |
cfb6eeb4c [TCP]: MD5 Signat... |
942 |
|
a8afca032 tcp: md5: protect... |
943 |
md5sig = rcu_dereference_protected(tp->md5sig_info, 1); |
b67bfe0d4 hlist: drop the n... |
944 |
hlist_for_each_entry_safe(key, n, &md5sig->head, node) { |
a915da9b6 tcp: md5: rcu con... |
945 |
hlist_del_rcu(&key->node); |
5f3d9cb29 tcp: md5: use soc... |
946 |
atomic_sub(sizeof(*key), &sk->sk_omem_alloc); |
a915da9b6 tcp: md5: rcu con... |
947 |
kfree_rcu(key, rcu); |
cfb6eeb4c [TCP]: MD5 Signat... |
948 949 |
} } |
7174259e6 [TCP_IPV4]: Codin... |
950 951 |
static int tcp_v4_parse_md5_keys(struct sock *sk, char __user *optval, int optlen) |
cfb6eeb4c [TCP]: MD5 Signat... |
952 953 954 |
{ struct tcp_md5sig cmd; struct sockaddr_in *sin = (struct sockaddr_in *)&cmd.tcpm_addr; |
cfb6eeb4c [TCP]: MD5 Signat... |
955 956 957 |
if (optlen < sizeof(cmd)) return -EINVAL; |
7174259e6 [TCP_IPV4]: Codin... |
958 |
if (copy_from_user(&cmd, optval, sizeof(cmd))) |
cfb6eeb4c [TCP]: MD5 Signat... |
959 960 961 962 |
return -EFAULT; if (sin->sin_family != AF_INET) return -EINVAL; |
64a124edc tcp: md5: remove ... |
963 |
if (!cmd.tcpm_keylen) |
a915da9b6 tcp: md5: rcu con... |
964 965 |
return tcp_md5_do_del(sk, (union tcp_md5_addr *)&sin->sin_addr.s_addr, AF_INET); |
cfb6eeb4c [TCP]: MD5 Signat... |
966 967 968 |
if (cmd.tcpm_keylen > TCP_MD5SIG_MAXKEYLEN) return -EINVAL; |
a915da9b6 tcp: md5: rcu con... |
969 970 971 |
return tcp_md5_do_add(sk, (union tcp_md5_addr *)&sin->sin_addr.s_addr, AF_INET, cmd.tcpm_key, cmd.tcpm_keylen, GFP_KERNEL); |
cfb6eeb4c [TCP]: MD5 Signat... |
972 |
} |
19689e38e tcp: md5: use kma... |
973 974 975 |
static int tcp_v4_md5_hash_headers(struct tcp_md5sig_pool *hp, __be32 daddr, __be32 saddr, const struct tcphdr *th, int nbytes) |
cfb6eeb4c [TCP]: MD5 Signat... |
976 |
{ |
cfb6eeb4c [TCP]: MD5 Signat... |
977 |
struct tcp4_pseudohdr *bp; |
49a72dfb8 tcp: Fix MD5 sign... |
978 |
struct scatterlist sg; |
19689e38e tcp: md5: use kma... |
979 |
struct tcphdr *_th; |
cfb6eeb4c [TCP]: MD5 Signat... |
980 |
|
19689e38e tcp: md5: use kma... |
981 |
bp = hp->scratch; |
cfb6eeb4c [TCP]: MD5 Signat... |
982 983 984 |
bp->saddr = saddr; bp->daddr = daddr; bp->pad = 0; |
076fb7223 tcp md5sig: Remov... |
985 |
bp->protocol = IPPROTO_TCP; |
49a72dfb8 tcp: Fix MD5 sign... |
986 |
bp->len = cpu_to_be16(nbytes); |
c7da57a18 [TCP]: Fix scatte... |
987 |
|
19689e38e tcp: md5: use kma... |
988 989 990 991 992 993 994 |
_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 tcp: Use ahash |
995 |
return crypto_ahash_update(hp->md5_req); |
49a72dfb8 tcp: Fix MD5 sign... |
996 |
} |
a915da9b6 tcp: md5: rcu con... |
997 |
static int tcp_v4_md5_hash_hdr(char *md5_hash, const struct tcp_md5sig_key *key, |
318cf7aaa tcp: md5: add mor... |
998 |
__be32 daddr, __be32 saddr, const struct tcphdr *th) |
49a72dfb8 tcp: Fix MD5 sign... |
999 1000 |
{ struct tcp_md5sig_pool *hp; |
cf80e0e47 tcp: Use ahash |
1001 |
struct ahash_request *req; |
49a72dfb8 tcp: Fix MD5 sign... |
1002 1003 1004 1005 |
hp = tcp_get_md5sig_pool(); if (!hp) goto clear_hash_noput; |
cf80e0e47 tcp: Use ahash |
1006 |
req = hp->md5_req; |
49a72dfb8 tcp: Fix MD5 sign... |
1007 |
|
cf80e0e47 tcp: Use ahash |
1008 |
if (crypto_ahash_init(req)) |
49a72dfb8 tcp: Fix MD5 sign... |
1009 |
goto clear_hash; |
19689e38e tcp: md5: use kma... |
1010 |
if (tcp_v4_md5_hash_headers(hp, daddr, saddr, th, th->doff << 2)) |
49a72dfb8 tcp: Fix MD5 sign... |
1011 1012 1013 |
goto clear_hash; if (tcp_md5_hash_key(hp, key)) goto clear_hash; |
cf80e0e47 tcp: Use ahash |
1014 1015 |
ahash_request_set_crypt(req, NULL, md5_hash, 0); if (crypto_ahash_final(req)) |
cfb6eeb4c [TCP]: MD5 Signat... |
1016 |
goto clear_hash; |
cfb6eeb4c [TCP]: MD5 Signat... |
1017 |
tcp_put_md5sig_pool(); |
cfb6eeb4c [TCP]: MD5 Signat... |
1018 |
return 0; |
49a72dfb8 tcp: Fix MD5 sign... |
1019 |
|
cfb6eeb4c [TCP]: MD5 Signat... |
1020 1021 1022 1023 |
clear_hash: tcp_put_md5sig_pool(); clear_hash_noput: memset(md5_hash, 0, 16); |
49a72dfb8 tcp: Fix MD5 sign... |
1024 |
return 1; |
cfb6eeb4c [TCP]: MD5 Signat... |
1025 |
} |
39f8e58e5 tcp: md5: remove ... |
1026 1027 |
int tcp_v4_md5_hash_skb(char *md5_hash, const struct tcp_md5sig_key *key, const struct sock *sk, |
318cf7aaa tcp: md5: add mor... |
1028 |
const struct sk_buff *skb) |
cfb6eeb4c [TCP]: MD5 Signat... |
1029 |
{ |
49a72dfb8 tcp: Fix MD5 sign... |
1030 |
struct tcp_md5sig_pool *hp; |
cf80e0e47 tcp: Use ahash |
1031 |
struct ahash_request *req; |
318cf7aaa tcp: md5: add mor... |
1032 |
const struct tcphdr *th = tcp_hdr(skb); |
cfb6eeb4c [TCP]: MD5 Signat... |
1033 |
__be32 saddr, daddr; |
39f8e58e5 tcp: md5: remove ... |
1034 1035 1036 |
if (sk) { /* valid for establish/request sockets */ saddr = sk->sk_rcv_saddr; daddr = sk->sk_daddr; |
cfb6eeb4c [TCP]: MD5 Signat... |
1037 |
} else { |
49a72dfb8 tcp: Fix MD5 sign... |
1038 1039 1040 |
const struct iphdr *iph = ip_hdr(skb); saddr = iph->saddr; daddr = iph->daddr; |
cfb6eeb4c [TCP]: MD5 Signat... |
1041 |
} |
49a72dfb8 tcp: Fix MD5 sign... |
1042 1043 1044 1045 |
hp = tcp_get_md5sig_pool(); if (!hp) goto clear_hash_noput; |
cf80e0e47 tcp: Use ahash |
1046 |
req = hp->md5_req; |
49a72dfb8 tcp: Fix MD5 sign... |
1047 |
|
cf80e0e47 tcp: Use ahash |
1048 |
if (crypto_ahash_init(req)) |
49a72dfb8 tcp: Fix MD5 sign... |
1049 |
goto clear_hash; |
19689e38e tcp: md5: use kma... |
1050 |
if (tcp_v4_md5_hash_headers(hp, daddr, saddr, th, skb->len)) |
49a72dfb8 tcp: Fix MD5 sign... |
1051 1052 1053 1054 1055 |
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 tcp: Use ahash |
1056 1057 |
ahash_request_set_crypt(req, NULL, md5_hash, 0); if (crypto_ahash_final(req)) |
49a72dfb8 tcp: Fix MD5 sign... |
1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 |
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 [TCP]: MD5 Signat... |
1068 |
} |
49a72dfb8 tcp: Fix MD5 sign... |
1069 |
EXPORT_SYMBOL(tcp_v4_md5_hash_skb); |
cfb6eeb4c [TCP]: MD5 Signat... |
1070 |
|
ba8e275a4 tcp: cleanup tcp_... |
1071 |
#endif |
ff74e23f7 tcp: md5: input p... |
1072 |
/* Called with rcu_read_lock() */ |
ba8e275a4 tcp: cleanup tcp_... |
1073 |
static bool tcp_v4_inbound_md5_hash(const struct sock *sk, |
ff74e23f7 tcp: md5: input p... |
1074 |
const struct sk_buff *skb) |
cfb6eeb4c [TCP]: MD5 Signat... |
1075 |
{ |
ba8e275a4 tcp: cleanup tcp_... |
1076 |
#ifdef CONFIG_TCP_MD5SIG |
cfb6eeb4c [TCP]: MD5 Signat... |
1077 1078 1079 1080 1081 1082 1083 1084 |
/* * 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 tcp: add const qu... |
1085 |
const __u8 *hash_location = NULL; |
cfb6eeb4c [TCP]: MD5 Signat... |
1086 |
struct tcp_md5sig_key *hash_expected; |
eddc9ec53 [SK_BUFF]: Introd... |
1087 |
const struct iphdr *iph = ip_hdr(skb); |
cf533ea53 tcp: add const qu... |
1088 |
const struct tcphdr *th = tcp_hdr(skb); |
cfb6eeb4c [TCP]: MD5 Signat... |
1089 |
int genhash; |
cfb6eeb4c [TCP]: MD5 Signat... |
1090 |
unsigned char newhash[16]; |
a915da9b6 tcp: md5: rcu con... |
1091 1092 |
hash_expected = tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&iph->saddr, AF_INET); |
7d5d5525b tcp md5sig: Share... |
1093 |
hash_location = tcp_parse_md5sig_option(th); |
cfb6eeb4c [TCP]: MD5 Signat... |
1094 |
|
cfb6eeb4c [TCP]: MD5 Signat... |
1095 1096 |
/* We've parsed the options - do we have a hash? */ if (!hash_expected && !hash_location) |
a2a385d62 tcp: bool convers... |
1097 |
return false; |
cfb6eeb4c [TCP]: MD5 Signat... |
1098 1099 |
if (hash_expected && !hash_location) { |
c10d9310e tcp: do not assum... |
1100 |
NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPMD5NOTFOUND); |
a2a385d62 tcp: bool convers... |
1101 |
return true; |
cfb6eeb4c [TCP]: MD5 Signat... |
1102 1103 1104 |
} if (!hash_expected && hash_location) { |
c10d9310e tcp: do not assum... |
1105 |
NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPMD5UNEXPECTED); |
a2a385d62 tcp: bool convers... |
1106 |
return true; |
cfb6eeb4c [TCP]: MD5 Signat... |
1107 1108 1109 1110 1111 |
} /* Okay, so this is hash_expected and hash_location - * so we need to calculate the checksum. */ |
49a72dfb8 tcp: Fix MD5 sign... |
1112 1113 |
genhash = tcp_v4_md5_hash_skb(newhash, hash_expected, |
39f8e58e5 tcp: md5: remove ... |
1114 |
NULL, skb); |
cfb6eeb4c [TCP]: MD5 Signat... |
1115 1116 |
if (genhash || memcmp(hash_location, newhash, 16) != 0) { |
72145a68e tcp: md5: add LIN... |
1117 |
NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPMD5FAILURE); |
e87cc4728 net: Convert net_... |
1118 1119 1120 1121 1122 1123 |
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 tcp: bool convers... |
1124 |
return true; |
cfb6eeb4c [TCP]: MD5 Signat... |
1125 |
} |
a2a385d62 tcp: bool convers... |
1126 |
return false; |
cfb6eeb4c [TCP]: MD5 Signat... |
1127 |
#endif |
ba8e275a4 tcp: cleanup tcp_... |
1128 1129 |
return false; } |
cfb6eeb4c [TCP]: MD5 Signat... |
1130 |
|
b40cf18ef tcp: constify lis... |
1131 1132 |
static void tcp_v4_init_req(struct request_sock *req, const struct sock *sk_listener, |
16bea70aa tcp: add init_req... |
1133 1134 1135 |
struct sk_buff *skb) { struct inet_request_sock *ireq = inet_rsk(req); |
08d2cc3b2 inet: request soc... |
1136 1137 |
sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr); sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr); |
16bea70aa tcp: add init_req... |
1138 1139 |
ireq->opt = tcp_v4_save_options(skb); } |
f964629e3 tcp: constify tcp... |
1140 1141 |
static struct dst_entry *tcp_v4_route_req(const struct sock *sk, struct flowi *fl, |
d94e0417a tcp: add route_re... |
1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 |
const struct request_sock *req, bool *strict) { struct dst_entry *dst = inet_csk_route_req(sk, &fl->u.ip4, req); if (strict) { if (fl->u.ip4.daddr == inet_rsk(req)->ir_rmt_addr) *strict = true; else *strict = false; } return dst; } |
72a3effaf [NET]: Size liste... |
1156 |
struct request_sock_ops tcp_request_sock_ops __read_mostly = { |
1da177e4c Linux-2.6.12-rc2 |
1157 |
.family = PF_INET, |
2e6599cb8 [NET] Generalise ... |
1158 |
.obj_size = sizeof(struct tcp_request_sock), |
5db92c994 tcp: unify tcp_v4... |
1159 |
.rtx_syn_ack = tcp_rtx_synack, |
60236fdd0 [NET] Rename open... |
1160 1161 |
.send_ack = tcp_v4_reqsk_send_ack, .destructor = tcp_v4_reqsk_destructor, |
1da177e4c Linux-2.6.12-rc2 |
1162 |
.send_reset = tcp_v4_send_reset, |
688d1945b tcp: whitespace f... |
1163 |
.syn_ack_timeout = tcp_syn_ack_timeout, |
1da177e4c Linux-2.6.12-rc2 |
1164 |
}; |
b2e4b3deb tcp: MD5 operatio... |
1165 |
static const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = { |
2aec4a297 tcp: add mss_clam... |
1166 |
.mss_clamp = TCP_MSS_DEFAULT, |
16bea70aa tcp: add init_req... |
1167 |
#ifdef CONFIG_TCP_MD5SIG |
fd3a154a0 tcp: md5: get rid... |
1168 |
.req_md5_lookup = tcp_v4_md5_lookup, |
e3afe7b75 tcp: Fix MD5 sign... |
1169 |
.calc_md5_hash = tcp_v4_md5_hash_skb, |
b6332e6cf [TCP]: Fix warnin... |
1170 |
#endif |
16bea70aa tcp: add init_req... |
1171 |
.init_req = tcp_v4_init_req, |
fb7b37a7f tcp: add init_coo... |
1172 1173 1174 |
#ifdef CONFIG_SYN_COOKIES .cookie_init_seq = cookie_v4_init_sequence, #endif |
d94e0417a tcp: add route_re... |
1175 |
.route_req = tcp_v4_route_req, |
936b8bdb5 tcp: add init_seq... |
1176 |
.init_seq = tcp_v4_init_sequence, |
d6274bd8d tcp: add send_syn... |
1177 |
.send_synack = tcp_v4_send_synack, |
16bea70aa tcp: add init_req... |
1178 |
}; |
cfb6eeb4c [TCP]: MD5 Signat... |
1179 |
|
1da177e4c Linux-2.6.12-rc2 |
1180 1181 |
int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) { |
1da177e4c Linux-2.6.12-rc2 |
1182 |
/* Never answer to SYNs send to broadcast or multicast */ |
511c3f92a net: skb->rtable ... |
1183 |
if (skb_rtable(skb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) |
1da177e4c Linux-2.6.12-rc2 |
1184 |
goto drop; |
1fb6f159f tcp: add tcp_conn... |
1185 1186 |
return tcp_conn_request(&tcp_request_sock_ops, &tcp_request_sock_ipv4_ops, sk, skb); |
1da177e4c Linux-2.6.12-rc2 |
1187 |
|
1da177e4c Linux-2.6.12-rc2 |
1188 |
drop: |
9caad8641 tcp: increment sk... |
1189 |
tcp_listendrop(sk); |
1da177e4c Linux-2.6.12-rc2 |
1190 1191 |
return 0; } |
4bc2f18ba net/ipv4: EXPORT_... |
1192 |
EXPORT_SYMBOL(tcp_v4_conn_request); |
1da177e4c Linux-2.6.12-rc2 |
1193 1194 1195 1196 1197 1198 |
/* * The three way handshake has completed - we got a valid synack - * now create the new socket. */ |
0c27171e6 tcp/dccp: constif... |
1199 |
struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, |
60236fdd0 [NET] Rename open... |
1200 |
struct request_sock *req, |
5e0724d02 tcp/dccp: fix has... |
1201 1202 1203 |
struct dst_entry *dst, struct request_sock *req_unhash, bool *own_req) |
1da177e4c Linux-2.6.12-rc2 |
1204 |
{ |
2e6599cb8 [NET] Generalise ... |
1205 |
struct inet_request_sock *ireq; |
1da177e4c Linux-2.6.12-rc2 |
1206 1207 1208 |
struct inet_sock *newinet; struct tcp_sock *newtp; struct sock *newsk; |
cfb6eeb4c [TCP]: MD5 Signat... |
1209 1210 1211 |
#ifdef CONFIG_TCP_MD5SIG struct tcp_md5sig_key *key; #endif |
f6d8bd051 inet: add RCU pro... |
1212 |
struct ip_options_rcu *inet_opt; |
1da177e4c Linux-2.6.12-rc2 |
1213 1214 1215 |
if (sk_acceptq_is_full(sk)) goto exit_overflow; |
1da177e4c Linux-2.6.12-rc2 |
1216 1217 |
newsk = tcp_create_openreq_child(sk, req, skb); if (!newsk) |
093d28232 tproxy: fix hash ... |
1218 |
goto exit_nonewsk; |
1da177e4c Linux-2.6.12-rc2 |
1219 |
|
bcd761111 [NET]: Generalise... |
1220 |
newsk->sk_gso_type = SKB_GSO_TCPV4; |
fae6ef87f net: tcp: move sk... |
1221 |
inet_sk_rx_dst_set(newsk, skb); |
1da177e4c Linux-2.6.12-rc2 |
1222 1223 1224 |
newtp = tcp_sk(newsk); newinet = inet_sk(newsk); |
2e6599cb8 [NET] Generalise ... |
1225 |
ireq = inet_rsk(req); |
d1e559d0b inet: add IPv6 su... |
1226 1227 |
sk_daddr_set(newsk, ireq->ir_rmt_addr); sk_rcv_saddr_set(newsk, ireq->ir_loc_addr); |
6dd9a14e9 net: Allow accept... |
1228 |
newsk->sk_bound_dev_if = ireq->ir_iif; |
634fb979e inet: includes a ... |
1229 |
newinet->inet_saddr = ireq->ir_loc_addr; |
f6d8bd051 inet: add RCU pro... |
1230 1231 |
inet_opt = ireq->opt; rcu_assign_pointer(newinet->inet_opt, inet_opt); |
2e6599cb8 [NET] Generalise ... |
1232 |
ireq->opt = NULL; |
463c84b97 [NET]: Introduce ... |
1233 |
newinet->mc_index = inet_iif(skb); |
eddc9ec53 [SK_BUFF]: Introd... |
1234 |
newinet->mc_ttl = ip_hdr(skb)->ttl; |
4c507d289 net: implement IP... |
1235 |
newinet->rcv_tos = ip_hdr(skb)->tos; |
d83d8461f [IP_SOCKGLUE]: Re... |
1236 |
inet_csk(newsk)->icsk_ext_hdr_len = 0; |
f6d8bd051 inet: add RCU pro... |
1237 1238 |
if (inet_opt) inet_csk(newsk)->icsk_ext_hdr_len = inet_opt->opt.optlen; |
c720c7e83 inet: rename some... |
1239 |
newinet->inet_id = newtp->write_seq ^ jiffies; |
1da177e4c Linux-2.6.12-rc2 |
1240 |
|
dfd25ffff tcp: fix syncooki... |
1241 1242 1243 1244 1245 1246 1247 |
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 ipv4: Use inet_cs... |
1248 |
sk_setup_caps(newsk, dst); |
81164413a net: tcp: add per... |
1249 |
tcp_ca_openreq_child(newsk, dst); |
1da177e4c Linux-2.6.12-rc2 |
1250 |
tcp_sync_mss(newsk, dst_mtu(dst)); |
0dbaee3b3 net: Abstract def... |
1251 |
newtp->advmss = dst_metric_advmss(dst); |
f5fff5dc8 tcp: advertise MS... |
1252 1253 1254 |
if (tcp_sk(sk)->rx_opt.user_mss && tcp_sk(sk)->rx_opt.user_mss < newtp->advmss) newtp->advmss = tcp_sk(sk)->rx_opt.user_mss; |
1da177e4c Linux-2.6.12-rc2 |
1255 |
tcp_initialize_rcv_mss(newsk); |
cfb6eeb4c [TCP]: MD5 Signat... |
1256 1257 |
#ifdef CONFIG_TCP_MD5SIG /* Copy over the MD5 key from the original socket */ |
a915da9b6 tcp: md5: rcu con... |
1258 1259 |
key = tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&newinet->inet_daddr, AF_INET); |
00db41243 ipv4: coding styl... |
1260 |
if (key) { |
cfb6eeb4c [TCP]: MD5 Signat... |
1261 1262 1263 1264 1265 1266 |
/* * 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 tcp: md5: rcu con... |
1267 1268 |
tcp_md5_do_add(newsk, (union tcp_md5_addr *)&newinet->inet_daddr, AF_INET, key->key, key->keylen, GFP_ATOMIC); |
a465419b1 net: Introduce sk... |
1269 |
sk_nocaps_add(newsk, NETIF_F_GSO_MASK); |
cfb6eeb4c [TCP]: MD5 Signat... |
1270 1271 |
} #endif |
0e7344199 ipv4: Use inet_cs... |
1272 1273 |
if (__inet_inherit_port(sk, newsk) < 0) goto put_and_exit; |
5e0724d02 tcp/dccp: fix has... |
1274 |
*own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash)); |
805c4bc05 tcp: fix req->sav... |
1275 |
if (*own_req) |
49a496c97 tcp: use correct ... |
1276 |
tcp_move_syn(newtp, req); |
1da177e4c Linux-2.6.12-rc2 |
1277 1278 1279 1280 |
return newsk; exit_overflow: |
c10d9310e tcp: do not assum... |
1281 |
NET_INC_STATS(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS); |
093d28232 tproxy: fix hash ... |
1282 1283 |
exit_nonewsk: dst_release(dst); |
1da177e4c Linux-2.6.12-rc2 |
1284 |
exit: |
9caad8641 tcp: increment sk... |
1285 |
tcp_listendrop(sk); |
1da177e4c Linux-2.6.12-rc2 |
1286 |
return NULL; |
0e7344199 ipv4: Use inet_cs... |
1287 |
put_and_exit: |
e337e24d6 inet: Fix kmemlea... |
1288 1289 |
inet_csk_prepare_forced_close(newsk); tcp_done(newsk); |
0e7344199 ipv4: Use inet_cs... |
1290 |
goto exit; |
1da177e4c Linux-2.6.12-rc2 |
1291 |
} |
4bc2f18ba net/ipv4: EXPORT_... |
1292 |
EXPORT_SYMBOL(tcp_v4_syn_recv_sock); |
1da177e4c Linux-2.6.12-rc2 |
1293 |
|
079096f10 tcp/dccp: install... |
1294 |
static struct sock *tcp_v4_cookie_check(struct sock *sk, struct sk_buff *skb) |
1da177e4c Linux-2.6.12-rc2 |
1295 |
{ |
079096f10 tcp/dccp: install... |
1296 |
#ifdef CONFIG_SYN_COOKIES |
52452c542 inet: drop prev p... |
1297 |
const struct tcphdr *th = tcp_hdr(skb); |
1da177e4c Linux-2.6.12-rc2 |
1298 |
|
af9b47385 syncookies: avoid... |
1299 |
if (!th->syn) |
461b74c39 ipv4: clean up co... |
1300 |
sk = cookie_v4_check(sk, skb); |
1da177e4c Linux-2.6.12-rc2 |
1301 1302 1303 |
#endif return sk; } |
1da177e4c Linux-2.6.12-rc2 |
1304 |
/* The socket must have it's spinlock held when we get |
e994b2f0f tcp: do not lock ... |
1305 |
* here, unless it is a TCP_LISTEN socket. |
1da177e4c Linux-2.6.12-rc2 |
1306 1307 1308 1309 1310 1311 1312 1313 |
* * 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 [TCP]: MD5 Signat... |
1314 |
struct sock *rsk; |
cfb6eeb4c [TCP]: MD5 Signat... |
1315 |
|
1da177e4c Linux-2.6.12-rc2 |
1316 |
if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */ |
404e0a8b6 net: ipv4: fix RC... |
1317 |
struct dst_entry *dst = sk->sk_rx_dst; |
bdeab9919 rps: Add flag to ... |
1318 |
sock_rps_save_rxhash(sk, skb); |
3d97379a6 tcp: move sk_mark... |
1319 |
sk_mark_napi_id(sk, skb); |
404e0a8b6 net: ipv4: fix RC... |
1320 |
if (dst) { |
505fbcf03 ipv4: fix TCP ear... |
1321 |
if (inet_sk(sk)->rx_dst_ifindex != skb->skb_iif || |
51456b291 ipv4: coding styl... |
1322 |
!dst->ops->check(dst, 0)) { |
92101b3b2 ipv4: Prepare for... |
1323 1324 1325 1326 |
dst_release(dst); sk->sk_rx_dst = NULL; } } |
c995ae225 tcp: Change retur... |
1327 |
tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len); |
1da177e4c Linux-2.6.12-rc2 |
1328 1329 |
return 0; } |
12e25e104 tcp: remove redun... |
1330 |
if (tcp_checksum_complete(skb)) |
1da177e4c Linux-2.6.12-rc2 |
1331 1332 1333 |
goto csum_err; if (sk->sk_state == TCP_LISTEN) { |
079096f10 tcp/dccp: install... |
1334 |
struct sock *nsk = tcp_v4_cookie_check(sk, skb); |
1da177e4c Linux-2.6.12-rc2 |
1335 1336 |
if (!nsk) goto discard; |
1da177e4c Linux-2.6.12-rc2 |
1337 |
if (nsk != sk) { |
bdeab9919 rps: Add flag to ... |
1338 |
sock_rps_save_rxhash(nsk, skb); |
38cb52455 tcp: call sk_mark... |
1339 |
sk_mark_napi_id(nsk, skb); |
cfb6eeb4c [TCP]: MD5 Signat... |
1340 1341 |
if (tcp_child_process(sk, nsk, skb)) { rsk = nsk; |
1da177e4c Linux-2.6.12-rc2 |
1342 |
goto reset; |
cfb6eeb4c [TCP]: MD5 Signat... |
1343 |
} |
1da177e4c Linux-2.6.12-rc2 |
1344 1345 |
return 0; } |
ca55158c6 rps: tcp: fix rps... |
1346 |
} else |
bdeab9919 rps: Add flag to ... |
1347 |
sock_rps_save_rxhash(sk, skb); |
ca55158c6 rps: tcp: fix rps... |
1348 |
|
72ab4a86f tcp: remove tcp_r... |
1349 |
if (tcp_rcv_state_process(sk, skb)) { |
cfb6eeb4c [TCP]: MD5 Signat... |
1350 |
rsk = sk; |
1da177e4c Linux-2.6.12-rc2 |
1351 |
goto reset; |
cfb6eeb4c [TCP]: MD5 Signat... |
1352 |
} |
1da177e4c Linux-2.6.12-rc2 |
1353 1354 1355 |
return 0; reset: |
cfb6eeb4c [TCP]: MD5 Signat... |
1356 |
tcp_v4_send_reset(rsk, skb); |
1da177e4c Linux-2.6.12-rc2 |
1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 |
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 tcp: do not assum... |
1367 1368 |
TCP_INC_STATS(sock_net(sk), TCP_MIB_CSUMERRORS); TCP_INC_STATS(sock_net(sk), TCP_MIB_INERRS); |
1da177e4c Linux-2.6.12-rc2 |
1369 1370 |
goto discard; } |
4bc2f18ba net/ipv4: EXPORT_... |
1371 |
EXPORT_SYMBOL(tcp_v4_do_rcv); |
1da177e4c Linux-2.6.12-rc2 |
1372 |
|
160eb5a6b ipv4: Kill early ... |
1373 |
void tcp_v4_early_demux(struct sk_buff *skb) |
41063e9dd ipv4: Early TCP s... |
1374 |
{ |
41063e9dd ipv4: Early TCP s... |
1375 1376 1377 |
const struct iphdr *iph; const struct tcphdr *th; struct sock *sk; |
41063e9dd ipv4: Early TCP s... |
1378 |
|
41063e9dd ipv4: Early TCP s... |
1379 |
if (skb->pkt_type != PACKET_HOST) |
160eb5a6b ipv4: Kill early ... |
1380 |
return; |
41063e9dd ipv4: Early TCP s... |
1381 |
|
45f00f99d ipv4: tcp: clean ... |
1382 |
if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct tcphdr))) |
160eb5a6b ipv4: Kill early ... |
1383 |
return; |
41063e9dd ipv4: Early TCP s... |
1384 1385 |
iph = ip_hdr(skb); |
45f00f99d ipv4: tcp: clean ... |
1386 |
th = tcp_hdr(skb); |
41063e9dd ipv4: Early TCP s... |
1387 1388 |
if (th->doff < sizeof(struct tcphdr) / 4) |
160eb5a6b ipv4: Kill early ... |
1389 |
return; |
41063e9dd ipv4: Early TCP s... |
1390 |
|
45f00f99d ipv4: tcp: clean ... |
1391 |
sk = __inet_lookup_established(dev_net(skb->dev), &tcp_hashinfo, |
41063e9dd ipv4: Early TCP s... |
1392 |
iph->saddr, th->source, |
7011d0851 tcp: Fix bug in t... |
1393 |
iph->daddr, ntohs(th->dest), |
9cb429d69 tcp: early_demux ... |
1394 |
skb->skb_iif); |
41063e9dd ipv4: Early TCP s... |
1395 1396 1397 |
if (sk) { skb->sk = sk; skb->destructor = sock_edemux; |
f7e4eb03f inet: ip early de... |
1398 |
if (sk_fullsock(sk)) { |
d0c294c53 tcp: prevent fetc... |
1399 |
struct dst_entry *dst = READ_ONCE(sk->sk_rx_dst); |
505fbcf03 ipv4: fix TCP ear... |
1400 |
|
41063e9dd ipv4: Early TCP s... |
1401 1402 |
if (dst) dst = dst_check(dst, 0); |
92101b3b2 ipv4: Prepare for... |
1403 |
if (dst && |
505fbcf03 ipv4: fix TCP ear... |
1404 |
inet_sk(sk)->rx_dst_ifindex == skb->skb_iif) |
92101b3b2 ipv4: Prepare for... |
1405 |
skb_dst_set_noref(skb, dst); |
41063e9dd ipv4: Early TCP s... |
1406 1407 |
} } |
41063e9dd ipv4: Early TCP s... |
1408 |
} |
b2fb4f54e tcp: uninline tcp... |
1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 |
/* Packet is added to VJ-style prequeue for processing in process * context, if a reader task is waiting. Apparently, this exciting * idea (VJ's mail "Re: query about TCP header on tcp-ip" of 07 Sep 93) * failed somewhere. Latency? Burstiness? Well, at least now we will * see, why it failed. 8)8) --ANK * */ bool tcp_prequeue(struct sock *sk, struct sk_buff *skb) { struct tcp_sock *tp = tcp_sk(sk); if (sysctl_tcp_low_latency || !tp->ucopy.task) return false; if (skb->len <= tcp_hdrlen(skb) && skb_queue_len(&tp->ucopy.prequeue) == 0) return false; |
ca777eff5 tcp: remove dst r... |
1426 1427 1428 1429 1430 1431 1432 1433 1434 |
/* Before escaping RCU protected region, we need to take care of skb * dst. Prequeue is only enabled for established sockets. * For such sockets, we might need the skb dst only to set sk->sk_rx_dst * Instead of doing full sk_rx_dst validity here, let's perform * an optimistic check. */ if (likely(sk->sk_rx_dst)) skb_dst_drop(skb); else |
5037e9ef9 net: fix IP early... |
1435 |
skb_dst_force_safe(skb); |
ca777eff5 tcp: remove dst r... |
1436 |
|
b2fb4f54e tcp: uninline tcp... |
1437 1438 |
__skb_queue_tail(&tp->ucopy.prequeue, skb); tp->ucopy.memory += skb->truesize; |
0cef6a4c3 tcp: give prequeu... |
1439 1440 |
if (skb_queue_len(&tp->ucopy.prequeue) >= 32 || tp->ucopy.memory + atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf) { |
b2fb4f54e tcp: uninline tcp... |
1441 1442 1443 |
struct sk_buff *skb1; BUG_ON(sock_owned_by_user(sk)); |
0cef6a4c3 tcp: give prequeu... |
1444 1445 |
__NET_ADD_STATS(sock_net(sk), LINUX_MIB_TCPPREQUEUEDROPPED, skb_queue_len(&tp->ucopy.prequeue)); |
b2fb4f54e tcp: uninline tcp... |
1446 |
|
0cef6a4c3 tcp: give prequeu... |
1447 |
while ((skb1 = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) |
b2fb4f54e tcp: uninline tcp... |
1448 |
sk_backlog_rcv(sk, skb1); |
b2fb4f54e tcp: uninline tcp... |
1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 |
tp->ucopy.memory = 0; } else if (skb_queue_len(&tp->ucopy.prequeue) == 1) { wake_up_interruptible_sync_poll(sk_sleep(sk), POLLIN | POLLRDNORM | POLLRDBAND); if (!inet_csk_ack_scheduled(sk)) inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK, (3 * tcp_rto_min(sk)) / 4, TCP_RTO_MAX); } return true; } EXPORT_SYMBOL(tcp_prequeue); |
c9c332125 tcp: add tcp_add_... |
1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 |
bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb) { u32 limit = sk->sk_rcvbuf + sk->sk_sndbuf; /* 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; /* 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). */ if (!skb->data_len) skb->truesize = SKB_TRUESIZE(skb_end_offset(skb)); 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 tcp: take care of... |
1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 |
int tcp_filter(struct sock *sk, struct sk_buff *skb) { struct tcphdr *th = (struct tcphdr *)skb->data; unsigned int eaten = skb->len; int err; err = sk_filter_trim_cap(sk, skb, th->doff * 4); if (!err) { eaten -= skb->len; TCP_SKB_CB(skb)->end_seq -= eaten; } return err; } EXPORT_SYMBOL(tcp_filter); |
1da177e4c Linux-2.6.12-rc2 |
1503 1504 1505 1506 1507 1508 |
/* * From tcp_input.c */ int tcp_v4_rcv(struct sk_buff *skb) { |
3b24d854c tcp/dccp: do not ... |
1509 |
struct net *net = dev_net(skb->dev); |
eddc9ec53 [SK_BUFF]: Introd... |
1510 |
const struct iphdr *iph; |
cf533ea53 tcp: add const qu... |
1511 |
const struct tcphdr *th; |
3b24d854c tcp/dccp: do not ... |
1512 |
bool refcounted; |
1da177e4c Linux-2.6.12-rc2 |
1513 1514 1515 1516 1517 1518 1519 |
struct sock *sk; int ret; if (skb->pkt_type != PACKET_HOST) goto discard_it; /* Count it even if it's bad */ |
90bbcc608 net: tcp: rename ... |
1520 |
__TCP_INC_STATS(net, TCP_MIB_INSEGS); |
1da177e4c Linux-2.6.12-rc2 |
1521 1522 1523 |
if (!pskb_may_pull(skb, sizeof(struct tcphdr))) goto discard_it; |
ea1627c20 tcp: minor optimi... |
1524 |
th = (const struct tcphdr *)skb->data; |
1da177e4c Linux-2.6.12-rc2 |
1525 |
|
ea1627c20 tcp: minor optimi... |
1526 |
if (unlikely(th->doff < sizeof(struct tcphdr) / 4)) |
1da177e4c Linux-2.6.12-rc2 |
1527 1528 1529 1530 1531 1532 |
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 [TCP]: spelling f... |
1533 |
* provided case of th->doff==0 is eliminated. |
1da177e4c Linux-2.6.12-rc2 |
1534 |
* So, we defer the checks. */ |
ed70fcfce net: Call skb_che... |
1535 1536 |
if (skb_checksum_init(skb, IPPROTO_TCP, inet_compute_pseudo)) |
6a5dc9e59 net: Add MIB coun... |
1537 |
goto csum_error; |
1da177e4c Linux-2.6.12-rc2 |
1538 |
|
ea1627c20 tcp: minor optimi... |
1539 |
th = (const struct tcphdr *)skb->data; |
eddc9ec53 [SK_BUFF]: Introd... |
1540 |
iph = ip_hdr(skb); |
971f10eca tcp: better TCP_S... |
1541 1542 1543 1544 1545 1546 |
/* 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(); |
1da177e4c Linux-2.6.12-rc2 |
1547 1548 1549 1550 |
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); |
e11ecddf5 tcp: use TCP_SKB_... |
1551 |
TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th); |
04317dafd tcp: introduce TC... |
1552 |
TCP_SKB_CB(skb)->tcp_tw_isn = 0; |
b82d1bb4f tcp: unalias tcp_... |
1553 |
TCP_SKB_CB(skb)->ip_dsfield = ipv4_get_dsfield(iph); |
1da177e4c Linux-2.6.12-rc2 |
1554 |
TCP_SKB_CB(skb)->sacked = 0; |
4bdc3d661 tcp/dccp: fix beh... |
1555 |
lookup: |
a583636a8 inet: refactor in... |
1556 |
sk = __inet_lookup_skb(&tcp_hashinfo, skb, __tcp_hdrlen(th), th->source, |
3b24d854c tcp/dccp: do not ... |
1557 |
th->dest, &refcounted); |
1da177e4c Linux-2.6.12-rc2 |
1558 1559 |
if (!sk) goto no_tcp_socket; |
bb134d5d9 tcp: Fix tcp_v4_r... |
1560 1561 1562 |
process: if (sk->sk_state == TCP_TIME_WAIT) goto do_time_wait; |
079096f10 tcp/dccp: install... |
1563 1564 |
if (sk->sk_state == TCP_NEW_SYN_RECV) { struct request_sock *req = inet_reqsk(sk); |
7716682cc tcp/dccp: fix ano... |
1565 |
struct sock *nsk; |
079096f10 tcp/dccp: install... |
1566 1567 |
sk = req->rsk_listener; |
729235554 tcp: md5: release... |
1568 |
if (unlikely(tcp_v4_inbound_md5_hash(sk, skb))) { |
e65c332de tcp: md5: increme... |
1569 |
sk_drops_add(sk, skb); |
729235554 tcp: md5: release... |
1570 1571 1572 |
reqsk_put(req); goto discard_it; } |
7716682cc tcp/dccp: fix ano... |
1573 |
if (unlikely(sk->sk_state != TCP_LISTEN)) { |
f03f2e154 tcp/dccp: add ine... |
1574 |
inet_csk_reqsk_queue_drop_and_put(sk, req); |
4bdc3d661 tcp/dccp: fix beh... |
1575 1576 |
goto lookup; } |
3b24d854c tcp/dccp: do not ... |
1577 1578 1579 |
/* We own a reference on the listener, increase it again * as we might lose it too soon. */ |
7716682cc tcp/dccp: fix ano... |
1580 |
sock_hold(sk); |
3b24d854c tcp/dccp: do not ... |
1581 |
refcounted = true; |
7716682cc tcp/dccp: fix ano... |
1582 |
nsk = tcp_check_req(sk, skb, req, false); |
079096f10 tcp/dccp: install... |
1583 1584 |
if (!nsk) { reqsk_put(req); |
7716682cc tcp/dccp: fix ano... |
1585 |
goto discard_and_relse; |
079096f10 tcp/dccp: install... |
1586 1587 |
} if (nsk == sk) { |
079096f10 tcp/dccp: install... |
1588 1589 1590 |
reqsk_put(req); } else if (tcp_child_process(sk, nsk, skb)) { tcp_v4_send_reset(nsk, skb); |
7716682cc tcp/dccp: fix ano... |
1591 |
goto discard_and_relse; |
079096f10 tcp/dccp: install... |
1592 |
} else { |
7716682cc tcp/dccp: fix ano... |
1593 |
sock_put(sk); |
079096f10 tcp/dccp: install... |
1594 1595 1596 |
return 0; } } |
6cce09f87 tcp: Add SNMP cou... |
1597 |
if (unlikely(iph->ttl < inet_sk(sk)->min_ttl)) { |
02a1d6e7a net: rename NET_{... |
1598 |
__NET_INC_STATS(net, LINUX_MIB_TCPMINTTLDROP); |
d218d1113 tcp: Generalized ... |
1599 |
goto discard_and_relse; |
6cce09f87 tcp: Add SNMP cou... |
1600 |
} |
d218d1113 tcp: Generalized ... |
1601 |
|
1da177e4c Linux-2.6.12-rc2 |
1602 1603 |
if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) goto discard_and_relse; |
9ea88a153 tcp: md5: check m... |
1604 |
|
9ea88a153 tcp: md5: check m... |
1605 1606 |
if (tcp_v4_inbound_md5_hash(sk, skb)) goto discard_and_relse; |
9ea88a153 tcp: md5: check m... |
1607 |
|
b59c27010 [NETFILTER]: Keep... |
1608 |
nf_reset(skb); |
1da177e4c Linux-2.6.12-rc2 |
1609 |
|
ac6e78007 tcp: take care of... |
1610 |
if (tcp_filter(sk, skb)) |
1da177e4c Linux-2.6.12-rc2 |
1611 |
goto discard_and_relse; |
ac6e78007 tcp: take care of... |
1612 1613 |
th = (const struct tcphdr *)skb->data; iph = ip_hdr(skb); |
1da177e4c Linux-2.6.12-rc2 |
1614 1615 |
skb->dev = NULL; |
e994b2f0f tcp: do not lock ... |
1616 1617 1618 1619 1620 1621 |
if (sk->sk_state == TCP_LISTEN) { ret = tcp_v4_do_rcv(sk, skb); goto put_and_return; } sk_incoming_cpu_update(sk); |
c63661848 [PATCH] lockdep: ... |
1622 |
bh_lock_sock_nested(sk); |
a44d6eacd tcp: Add RFC4898 ... |
1623 |
tcp_segs_in(tcp_sk(sk), skb); |
1da177e4c Linux-2.6.12-rc2 |
1624 1625 |
ret = 0; if (!sock_owned_by_user(sk)) { |
7bced3975 net_dma: simple r... |
1626 |
if (!tcp_prequeue(sk, skb)) |
1da177e4c Linux-2.6.12-rc2 |
1627 |
ret = tcp_v4_do_rcv(sk, skb); |
c9c332125 tcp: add tcp_add_... |
1628 |
} else if (tcp_add_backlog(sk, skb)) { |
6b03a53a5 tcp: use limited ... |
1629 1630 |
goto discard_and_relse; } |
1da177e4c Linux-2.6.12-rc2 |
1631 |
bh_unlock_sock(sk); |
e994b2f0f tcp: do not lock ... |
1632 |
put_and_return: |
3b24d854c tcp/dccp: do not ... |
1633 1634 |
if (refcounted) sock_put(sk); |
1da177e4c Linux-2.6.12-rc2 |
1635 1636 1637 1638 1639 1640 |
return ret; no_tcp_socket: if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) goto discard_it; |
12e25e104 tcp: remove redun... |
1641 |
if (tcp_checksum_complete(skb)) { |
6a5dc9e59 net: Add MIB coun... |
1642 |
csum_error: |
90bbcc608 net: tcp: rename ... |
1643 |
__TCP_INC_STATS(net, TCP_MIB_CSUMERRORS); |
1da177e4c Linux-2.6.12-rc2 |
1644 |
bad_packet: |
90bbcc608 net: tcp: rename ... |
1645 |
__TCP_INC_STATS(net, TCP_MIB_INERRS); |
1da177e4c Linux-2.6.12-rc2 |
1646 |
} else { |
cfb6eeb4c [TCP]: MD5 Signat... |
1647 |
tcp_v4_send_reset(NULL, skb); |
1da177e4c Linux-2.6.12-rc2 |
1648 1649 1650 1651 1652 |
} discard_it: /* Discard frame. */ kfree_skb(skb); |
e905a9eda [NET] IPV4: Fix w... |
1653 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
1654 1655 |
discard_and_relse: |
532182cd6 tcp: increment sk... |
1656 |
sk_drops_add(sk, skb); |
3b24d854c tcp/dccp: do not ... |
1657 1658 |
if (refcounted) sock_put(sk); |
1da177e4c Linux-2.6.12-rc2 |
1659 1660 1661 1662 |
goto discard_it; do_time_wait: if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { |
9469c7b4a [NET]: Use typesa... |
1663 |
inet_twsk_put(inet_twsk(sk)); |
1da177e4c Linux-2.6.12-rc2 |
1664 1665 |
goto discard_it; } |
6a5dc9e59 net: Add MIB coun... |
1666 1667 1668 |
if (tcp_checksum_complete(skb)) { inet_twsk_put(inet_twsk(sk)); goto csum_error; |
1da177e4c Linux-2.6.12-rc2 |
1669 |
} |
9469c7b4a [NET]: Use typesa... |
1670 |
switch (tcp_timewait_state_process(inet_twsk(sk), skb, th)) { |
1da177e4c Linux-2.6.12-rc2 |
1671 |
case TCP_TW_SYN: { |
c346dca10 [NET] NETNS: Omit... |
1672 |
struct sock *sk2 = inet_lookup_listener(dev_net(skb->dev), |
a583636a8 inet: refactor in... |
1673 1674 |
&tcp_hashinfo, skb, __tcp_hdrlen(th), |
da5e36308 soreuseport: TCP/... |
1675 |
iph->saddr, th->source, |
eddc9ec53 [SK_BUFF]: Introd... |
1676 |
iph->daddr, th->dest, |
463c84b97 [NET]: Introduce ... |
1677 |
inet_iif(skb)); |
1da177e4c Linux-2.6.12-rc2 |
1678 |
if (sk2) { |
dbe7faa40 inet: inet_twsk_d... |
1679 |
inet_twsk_deschedule_put(inet_twsk(sk)); |
1da177e4c Linux-2.6.12-rc2 |
1680 |
sk = sk2; |
3b24d854c tcp/dccp: do not ... |
1681 |
refcounted = false; |
1da177e4c Linux-2.6.12-rc2 |
1682 1683 1684 1685 1686 1687 1688 1689 |
goto process; } /* Fall through to ACK */ } case TCP_TW_ACK: tcp_v4_timewait_ack(sk, skb); break; case TCP_TW_RST: |
271c3b9b7 tcp: honour SO_BI... |
1690 1691 1692 |
tcp_v4_send_reset(sk, skb); inet_twsk_deschedule_put(inet_twsk(sk)); goto discard_it; |
1da177e4c Linux-2.6.12-rc2 |
1693 1694 1695 1696 |
case TCP_TW_SUCCESS:; } goto discard_it; } |
ccb7c410d timewait_sock: Cr... |
1697 1698 1699 1700 |
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 timewait_sock: Cr... |
1701 |
}; |
1da177e4c Linux-2.6.12-rc2 |
1702 |
|
63d02d157 net: tcp: ipv6_ma... |
1703 |
void inet_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb) |
5d299f3d3 net: ipv6: fix TC... |
1704 1705 |
{ struct dst_entry *dst = skb_dst(skb); |
5037e9ef9 net: fix IP early... |
1706 |
if (dst && dst_hold_safe(dst)) { |
ca777eff5 tcp: remove dst r... |
1707 1708 1709 |
sk->sk_rx_dst = dst; inet_sk(sk)->rx_dst_ifindex = skb->skb_iif; } |
5d299f3d3 net: ipv6: fix TC... |
1710 |
} |
63d02d157 net: tcp: ipv6_ma... |
1711 |
EXPORT_SYMBOL(inet_sk_rx_dst_set); |
5d299f3d3 net: ipv6: fix TC... |
1712 |
|
3b401a81c inet: inet_connec... |
1713 |
const struct inet_connection_sock_af_ops ipv4_specific = { |
543d9cfee [NET]: Identation... |
1714 1715 1716 |
.queue_xmit = ip_queue_xmit, .send_check = tcp_v4_send_check, .rebuild_header = inet_sk_rebuild_header, |
5d299f3d3 net: ipv6: fix TC... |
1717 |
.sk_rx_dst_set = inet_sk_rx_dst_set, |
543d9cfee [NET]: Identation... |
1718 1719 |
.conn_request = tcp_v4_conn_request, .syn_recv_sock = tcp_v4_syn_recv_sock, |
543d9cfee [NET]: Identation... |
1720 1721 1722 1723 1724 |
.net_header_len = sizeof(struct iphdr), .setsockopt = ip_setsockopt, .getsockopt = ip_getsockopt, .addr2sockaddr = inet_csk_addr2sockaddr, .sockaddr_len = sizeof(struct sockaddr_in), |
ab1e0a13d [SOCK] proto: Add... |
1725 |
.bind_conflict = inet_csk_bind_conflict, |
3fdadf7d2 [NET]: {get|set}s... |
1726 |
#ifdef CONFIG_COMPAT |
543d9cfee [NET]: Identation... |
1727 1728 |
.compat_setsockopt = compat_ip_setsockopt, .compat_getsockopt = compat_ip_getsockopt, |
3fdadf7d2 [NET]: {get|set}s... |
1729 |
#endif |
4fab90719 tcp: fix tcp_rele... |
1730 |
.mtu_reduced = tcp_v4_mtu_reduced, |
1da177e4c Linux-2.6.12-rc2 |
1731 |
}; |
4bc2f18ba net/ipv4: EXPORT_... |
1732 |
EXPORT_SYMBOL(ipv4_specific); |
1da177e4c Linux-2.6.12-rc2 |
1733 |
|
cfb6eeb4c [TCP]: MD5 Signat... |
1734 |
#ifdef CONFIG_TCP_MD5SIG |
b2e4b3deb tcp: MD5 operatio... |
1735 |
static const struct tcp_sock_af_ops tcp_sock_ipv4_specific = { |
cfb6eeb4c [TCP]: MD5 Signat... |
1736 |
.md5_lookup = tcp_v4_md5_lookup, |
49a72dfb8 tcp: Fix MD5 sign... |
1737 |
.calc_md5_hash = tcp_v4_md5_hash_skb, |
cfb6eeb4c [TCP]: MD5 Signat... |
1738 |
.md5_parse = tcp_v4_parse_md5_keys, |
cfb6eeb4c [TCP]: MD5 Signat... |
1739 |
}; |
b6332e6cf [TCP]: Fix warnin... |
1740 |
#endif |
cfb6eeb4c [TCP]: MD5 Signat... |
1741 |
|
1da177e4c Linux-2.6.12-rc2 |
1742 1743 1744 1745 1746 |
/* 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 [ICSK]: Move TCP ... |
1747 |
struct inet_connection_sock *icsk = inet_csk(sk); |
1da177e4c Linux-2.6.12-rc2 |
1748 |
|
900f65d36 tcp: move duplica... |
1749 |
tcp_init_sock(sk); |
1da177e4c Linux-2.6.12-rc2 |
1750 |
|
8292a17a3 [ICSK]: Rename st... |
1751 |
icsk->icsk_af_ops = &ipv4_specific; |
900f65d36 tcp: move duplica... |
1752 |
|
cfb6eeb4c [TCP]: MD5 Signat... |
1753 |
#ifdef CONFIG_TCP_MD5SIG |
ac807fa8e tcp: Fix build wa... |
1754 |
tcp_sk(sk)->af_specific = &tcp_sock_ipv4_specific; |
cfb6eeb4c [TCP]: MD5 Signat... |
1755 |
#endif |
1da177e4c Linux-2.6.12-rc2 |
1756 |
|
1da177e4c Linux-2.6.12-rc2 |
1757 1758 |
return 0; } |
7d06b2e05 net: change proto... |
1759 |
void tcp_v4_destroy_sock(struct sock *sk) |
1da177e4c Linux-2.6.12-rc2 |
1760 1761 1762 1763 |
{ struct tcp_sock *tp = tcp_sk(sk); tcp_clear_xmit_timers(sk); |
6687e988d [ICSK]: Move TCP ... |
1764 |
tcp_cleanup_congestion_control(sk); |
317a76f9a [TCP]: Add plugga... |
1765 |
|
1da177e4c Linux-2.6.12-rc2 |
1766 |
/* Cleanup up the write buffer. */ |
fe067e8ab [TCP]: Abstract o... |
1767 |
tcp_write_queue_purge(sk); |
1da177e4c Linux-2.6.12-rc2 |
1768 1769 |
/* Cleans up our, hopefully empty, out_of_order_queue. */ |
9f5afeae5 tcp: use an RB tr... |
1770 |
skb_rbtree_purge(&tp->out_of_order_queue); |
1da177e4c Linux-2.6.12-rc2 |
1771 |
|
cfb6eeb4c [TCP]: MD5 Signat... |
1772 1773 1774 |
#ifdef CONFIG_TCP_MD5SIG /* Clean up the MD5 key list, if any */ if (tp->md5sig_info) { |
a915da9b6 tcp: md5: rcu con... |
1775 |
tcp_clear_md5_list(sk); |
a8afca032 tcp: md5: protect... |
1776 |
kfree_rcu(tp->md5sig_info, rcu); |
cfb6eeb4c [TCP]: MD5 Signat... |
1777 1778 1779 |
tp->md5sig_info = NULL; } #endif |
1a2449a87 [I/OAT]: TCP recv... |
1780 |
|
1da177e4c Linux-2.6.12-rc2 |
1781 1782 1783 1784 |
/* Clean prequeue, it must be empty really */ __skb_queue_purge(&tp->ucopy.prequeue); /* Clean up a referenced TCP bind bucket. */ |
463c84b97 [NET]: Introduce ... |
1785 |
if (inet_csk(sk)->icsk_bind_hash) |
ab1e0a13d [SOCK] proto: Add... |
1786 |
inet_put_port(sk); |
1da177e4c Linux-2.6.12-rc2 |
1787 |
|
00db41243 ipv4: coding styl... |
1788 |
BUG_ON(tp->fastopen_rsk); |
435cf559f TCPCT part 1d: de... |
1789 |
|
cf60af03c net-tcp: Fast Ope... |
1790 1791 |
/* If socket is aborted during connect operation */ tcp_free_fastopen_req(tp); |
cd8ae8529 tcp: provide SYN ... |
1792 |
tcp_saved_syn_free(tp); |
cf60af03c net-tcp: Fast Ope... |
1793 |
|
777c6ae57 tcp: two more mis... |
1794 |
local_bh_disable(); |
180d8cd94 foundations of pe... |
1795 |
sk_sockets_allocated_dec(sk); |
777c6ae57 tcp: two more mis... |
1796 |
local_bh_enable(); |
1da177e4c Linux-2.6.12-rc2 |
1797 |
} |
1da177e4c Linux-2.6.12-rc2 |
1798 1799 1800 1801 |
EXPORT_SYMBOL(tcp_v4_destroy_sock); #ifdef CONFIG_PROC_FS /* Proc filesystem TCP sock list dumping. */ |
a8b690f98 tcp: Fix slowness... |
1802 1803 1804 1805 1806 |
/* * 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 Linux-2.6.12-rc2 |
1807 1808 |
static void *listening_get_next(struct seq_file *seq, void *cur) { |
5799de0b1 net: clean up net... |
1809 |
struct tcp_iter_state *st = seq->private; |
a4146b1b2 [TCP]: Replace st... |
1810 |
struct net *net = seq_file_net(seq); |
3b24d854c tcp/dccp: do not ... |
1811 |
struct inet_listen_hashbucket *ilb; |
3b24d854c tcp/dccp: do not ... |
1812 |
struct sock *sk = cur; |
1da177e4c Linux-2.6.12-rc2 |
1813 1814 |
if (!sk) { |
3b24d854c tcp/dccp: do not ... |
1815 |
get_head: |
a8b690f98 tcp: Fix slowness... |
1816 |
ilb = &tcp_hashinfo.listening_hash[st->bucket]; |
5caea4ea7 net: listening_ha... |
1817 |
spin_lock_bh(&ilb->lock); |
3b24d854c tcp/dccp: do not ... |
1818 |
sk = sk_head(&ilb->head); |
a8b690f98 tcp: Fix slowness... |
1819 |
st->offset = 0; |
1da177e4c Linux-2.6.12-rc2 |
1820 1821 |
goto get_sk; } |
5caea4ea7 net: listening_ha... |
1822 |
ilb = &tcp_hashinfo.listening_hash[st->bucket]; |
1da177e4c Linux-2.6.12-rc2 |
1823 |
++st->num; |
a8b690f98 tcp: Fix slowness... |
1824 |
++st->offset; |
1da177e4c Linux-2.6.12-rc2 |
1825 |
|
3b24d854c tcp/dccp: do not ... |
1826 |
sk = sk_next(sk); |
1da177e4c Linux-2.6.12-rc2 |
1827 |
get_sk: |
3b24d854c tcp/dccp: do not ... |
1828 |
sk_for_each_from(sk) { |
8475ef9fd netns: Don't leak... |
1829 1830 |
if (!net_eq(sock_net(sk), net)) continue; |
3b24d854c tcp/dccp: do not ... |
1831 1832 |
if (sk->sk_family == st->family) return sk; |
1da177e4c Linux-2.6.12-rc2 |
1833 |
} |
5caea4ea7 net: listening_ha... |
1834 |
spin_unlock_bh(&ilb->lock); |
a8b690f98 tcp: Fix slowness... |
1835 |
st->offset = 0; |
3b24d854c tcp/dccp: do not ... |
1836 1837 1838 |
if (++st->bucket < INET_LHTABLE_SIZE) goto get_head; return NULL; |
1da177e4c Linux-2.6.12-rc2 |
1839 1840 1841 1842 |
} static void *listening_get_idx(struct seq_file *seq, loff_t *pos) { |
a8b690f98 tcp: Fix slowness... |
1843 1844 1845 1846 1847 1848 |
struct tcp_iter_state *st = seq->private; void *rc; st->bucket = 0; st->offset = 0; rc = listening_get_next(seq, NULL); |
1da177e4c Linux-2.6.12-rc2 |
1849 1850 1851 1852 1853 1854 1855 |
while (rc && *pos) { rc = listening_get_next(seq, rc); --*pos; } return rc; } |
05dbc7b59 tcp/dccp: remove ... |
1856 |
static inline bool empty_bucket(const struct tcp_iter_state *st) |
6eac56040 tcp: Skip empty h... |
1857 |
{ |
05dbc7b59 tcp/dccp: remove ... |
1858 |
return hlist_nulls_empty(&tcp_hashinfo.ehash[st->bucket].chain); |
6eac56040 tcp: Skip empty h... |
1859 |
} |
a8b690f98 tcp: Fix slowness... |
1860 1861 1862 1863 |
/* * 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 Linux-2.6.12-rc2 |
1864 1865 |
static void *established_get_first(struct seq_file *seq) { |
5799de0b1 net: clean up net... |
1866 |
struct tcp_iter_state *st = seq->private; |
a4146b1b2 [TCP]: Replace st... |
1867 |
struct net *net = seq_file_net(seq); |
1da177e4c Linux-2.6.12-rc2 |
1868 |
void *rc = NULL; |
a8b690f98 tcp: Fix slowness... |
1869 1870 |
st->offset = 0; for (; st->bucket <= tcp_hashinfo.ehash_mask; ++st->bucket) { |
1da177e4c Linux-2.6.12-rc2 |
1871 |
struct sock *sk; |
3ab5aee7f net: Convert TCP ... |
1872 |
struct hlist_nulls_node *node; |
9db66bdcc net: convert TCP/... |
1873 |
spinlock_t *lock = inet_ehash_lockp(&tcp_hashinfo, st->bucket); |
1da177e4c Linux-2.6.12-rc2 |
1874 |
|
6eac56040 tcp: Skip empty h... |
1875 1876 1877 |
/* Lockless fast path for the common case of empty buckets */ if (empty_bucket(st)) continue; |
9db66bdcc net: convert TCP/... |
1878 |
spin_lock_bh(lock); |
3ab5aee7f net: Convert TCP ... |
1879 |
sk_nulls_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) { |
f40c8174d [NETNS][IPV4] tcp... |
1880 |
if (sk->sk_family != st->family || |
878628fbf [NET] NETNS: Omit... |
1881 |
!net_eq(sock_net(sk), net)) { |
1da177e4c Linux-2.6.12-rc2 |
1882 1883 1884 1885 1886 |
continue; } rc = sk; goto out; } |
9db66bdcc net: convert TCP/... |
1887 |
spin_unlock_bh(lock); |
1da177e4c Linux-2.6.12-rc2 |
1888 1889 1890 1891 1892 1893 1894 1895 |
} out: return rc; } static void *established_get_next(struct seq_file *seq, void *cur) { struct sock *sk = cur; |
3ab5aee7f net: Convert TCP ... |
1896 |
struct hlist_nulls_node *node; |
5799de0b1 net: clean up net... |
1897 |
struct tcp_iter_state *st = seq->private; |
a4146b1b2 [TCP]: Replace st... |
1898 |
struct net *net = seq_file_net(seq); |
1da177e4c Linux-2.6.12-rc2 |
1899 1900 |
++st->num; |
a8b690f98 tcp: Fix slowness... |
1901 |
++st->offset; |
1da177e4c Linux-2.6.12-rc2 |
1902 |
|
05dbc7b59 tcp/dccp: remove ... |
1903 |
sk = sk_nulls_next(sk); |
1da177e4c Linux-2.6.12-rc2 |
1904 |
|
3ab5aee7f net: Convert TCP ... |
1905 |
sk_nulls_for_each_from(sk, node) { |
878628fbf [NET] NETNS: Omit... |
1906 |
if (sk->sk_family == st->family && net_eq(sock_net(sk), net)) |
05dbc7b59 tcp/dccp: remove ... |
1907 |
return sk; |
1da177e4c Linux-2.6.12-rc2 |
1908 |
} |
05dbc7b59 tcp/dccp: remove ... |
1909 1910 1911 |
spin_unlock_bh(inet_ehash_lockp(&tcp_hashinfo, st->bucket)); ++st->bucket; return established_get_first(seq); |
1da177e4c Linux-2.6.12-rc2 |
1912 1913 1914 1915 |
} static void *established_get_idx(struct seq_file *seq, loff_t pos) { |
a8b690f98 tcp: Fix slowness... |
1916 1917 1918 1919 1920 |
struct tcp_iter_state *st = seq->private; void *rc; st->bucket = 0; rc = established_get_first(seq); |
1da177e4c Linux-2.6.12-rc2 |
1921 1922 1923 1924 |
while (rc && pos) { rc = established_get_next(seq, rc); --pos; |
7174259e6 [TCP_IPV4]: Codin... |
1925 |
} |
1da177e4c Linux-2.6.12-rc2 |
1926 1927 1928 1929 1930 1931 |
return rc; } static void *tcp_get_idx(struct seq_file *seq, loff_t pos) { void *rc; |
5799de0b1 net: clean up net... |
1932 |
struct tcp_iter_state *st = seq->private; |
1da177e4c Linux-2.6.12-rc2 |
1933 |
|
1da177e4c Linux-2.6.12-rc2 |
1934 1935 1936 1937 |
st->state = TCP_SEQ_STATE_LISTENING; rc = listening_get_idx(seq, &pos); if (!rc) { |
1da177e4c Linux-2.6.12-rc2 |
1938 1939 1940 1941 1942 1943 |
st->state = TCP_SEQ_STATE_ESTABLISHED; rc = established_get_idx(seq, pos); } return rc; } |
a8b690f98 tcp: Fix slowness... |
1944 1945 1946 1947 1948 1949 1950 1951 |
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 tcp: Fix slowness... |
1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 |
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 tcp/dccp: remove ... |
1962 |
st->state = TCP_SEQ_STATE_ESTABLISHED; |
a8b690f98 tcp: Fix slowness... |
1963 1964 |
/* Fallthrough */ case TCP_SEQ_STATE_ESTABLISHED: |
a8b690f98 tcp: Fix slowness... |
1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 |
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; } |
1da177e4c Linux-2.6.12-rc2 |
1976 1977 |
static void *tcp_seq_start(struct seq_file *seq, loff_t *pos) { |
5799de0b1 net: clean up net... |
1978 |
struct tcp_iter_state *st = seq->private; |
a8b690f98 tcp: Fix slowness... |
1979 1980 1981 1982 1983 1984 1985 |
void *rc; if (*pos && *pos == st->last_pos) { rc = tcp_seek_last_pos(seq); if (rc) goto out; } |
1da177e4c Linux-2.6.12-rc2 |
1986 1987 |
st->state = TCP_SEQ_STATE_LISTENING; st->num = 0; |
a8b690f98 tcp: Fix slowness... |
1988 1989 1990 1991 1992 1993 1994 |
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 Linux-2.6.12-rc2 |
1995 1996 1997 1998 |
} static void *tcp_seq_next(struct seq_file *seq, void *v, loff_t *pos) { |
a8b690f98 tcp: Fix slowness... |
1999 |
struct tcp_iter_state *st = seq->private; |
1da177e4c Linux-2.6.12-rc2 |
2000 |
void *rc = NULL; |
1da177e4c Linux-2.6.12-rc2 |
2001 2002 2003 2004 2005 |
if (v == SEQ_START_TOKEN) { rc = tcp_get_idx(seq, 0); goto out; } |
1da177e4c Linux-2.6.12-rc2 |
2006 2007 |
switch (st->state) { |
1da177e4c Linux-2.6.12-rc2 |
2008 2009 2010 |
case TCP_SEQ_STATE_LISTENING: rc = listening_get_next(seq, v); if (!rc) { |
1da177e4c Linux-2.6.12-rc2 |
2011 |
st->state = TCP_SEQ_STATE_ESTABLISHED; |
a8b690f98 tcp: Fix slowness... |
2012 2013 |
st->bucket = 0; st->offset = 0; |
1da177e4c Linux-2.6.12-rc2 |
2014 2015 2016 2017 |
rc = established_get_first(seq); } break; case TCP_SEQ_STATE_ESTABLISHED: |
1da177e4c Linux-2.6.12-rc2 |
2018 2019 2020 2021 2022 |
rc = established_get_next(seq, v); break; } out: ++*pos; |
a8b690f98 tcp: Fix slowness... |
2023 |
st->last_pos = *pos; |
1da177e4c Linux-2.6.12-rc2 |
2024 2025 2026 2027 2028 |
return rc; } static void tcp_seq_stop(struct seq_file *seq, void *v) { |
5799de0b1 net: clean up net... |
2029 |
struct tcp_iter_state *st = seq->private; |
1da177e4c Linux-2.6.12-rc2 |
2030 2031 |
switch (st->state) { |
1da177e4c Linux-2.6.12-rc2 |
2032 2033 |
case TCP_SEQ_STATE_LISTENING: if (v != SEQ_START_TOKEN) |
5caea4ea7 net: listening_ha... |
2034 |
spin_unlock_bh(&tcp_hashinfo.listening_hash[st->bucket].lock); |
1da177e4c Linux-2.6.12-rc2 |
2035 |
break; |
1da177e4c Linux-2.6.12-rc2 |
2036 2037 |
case TCP_SEQ_STATE_ESTABLISHED: if (v) |
9db66bdcc net: convert TCP/... |
2038 |
spin_unlock_bh(inet_ehash_lockp(&tcp_hashinfo, st->bucket)); |
1da177e4c Linux-2.6.12-rc2 |
2039 2040 2041 |
break; } } |
73cb88ecb net: make the tcp... |
2042 |
int tcp_seq_open(struct inode *inode, struct file *file) |
1da177e4c Linux-2.6.12-rc2 |
2043 |
{ |
d9dda78ba procfs: new helpe... |
2044 |
struct tcp_seq_afinfo *afinfo = PDE_DATA(inode); |
1da177e4c Linux-2.6.12-rc2 |
2045 |
struct tcp_iter_state *s; |
52d6f3f11 [TCP]: Cleanup /p... |
2046 |
int err; |
1da177e4c Linux-2.6.12-rc2 |
2047 |
|
52d6f3f11 [TCP]: Cleanup /p... |
2048 2049 2050 2051 |
err = seq_open_net(inode, file, &afinfo->seq_ops, sizeof(struct tcp_iter_state)); if (err < 0) return err; |
f40c8174d [NETNS][IPV4] tcp... |
2052 |
|
52d6f3f11 [TCP]: Cleanup /p... |
2053 |
s = ((struct seq_file *)file->private_data)->private; |
1da177e4c Linux-2.6.12-rc2 |
2054 |
s->family = afinfo->family; |
688d1945b tcp: whitespace f... |
2055 |
s->last_pos = 0; |
f40c8174d [NETNS][IPV4] tcp... |
2056 2057 |
return 0; } |
73cb88ecb net: make the tcp... |
2058 |
EXPORT_SYMBOL(tcp_seq_open); |
f40c8174d [NETNS][IPV4] tcp... |
2059 |
|
6f8b13bcb [NETNS][IPV6] tcp... |
2060 |
int tcp_proc_register(struct net *net, struct tcp_seq_afinfo *afinfo) |
1da177e4c Linux-2.6.12-rc2 |
2061 2062 2063 |
{ int rc = 0; struct proc_dir_entry *p; |
9427c4b36 [TCP]: Move seq_o... |
2064 2065 2066 |
afinfo->seq_ops.start = tcp_seq_start; afinfo->seq_ops.next = tcp_seq_next; afinfo->seq_ops.stop = tcp_seq_stop; |
84841c3c6 ipv4: assign PDE-... |
2067 |
p = proc_create_data(afinfo->name, S_IRUGO, net->proc_net, |
73cb88ecb net: make the tcp... |
2068 |
afinfo->seq_fops, afinfo); |
84841c3c6 ipv4: assign PDE-... |
2069 |
if (!p) |
1da177e4c Linux-2.6.12-rc2 |
2070 2071 2072 |
rc = -ENOMEM; return rc; } |
4bc2f18ba net/ipv4: EXPORT_... |
2073 |
EXPORT_SYMBOL(tcp_proc_register); |
1da177e4c Linux-2.6.12-rc2 |
2074 |
|
6f8b13bcb [NETNS][IPV6] tcp... |
2075 |
void tcp_proc_unregister(struct net *net, struct tcp_seq_afinfo *afinfo) |
1da177e4c Linux-2.6.12-rc2 |
2076 |
{ |
ece31ffd5 net: proc: change... |
2077 |
remove_proc_entry(afinfo->name, net->proc_net); |
1da177e4c Linux-2.6.12-rc2 |
2078 |
} |
4bc2f18ba net/ipv4: EXPORT_... |
2079 |
EXPORT_SYMBOL(tcp_proc_unregister); |
1da177e4c Linux-2.6.12-rc2 |
2080 |
|
d4f06873b inet: get_openreq... |
2081 |
static void get_openreq4(const struct request_sock *req, |
aa3a0c8ce tcp: get_openreq[... |
2082 |
struct seq_file *f, int i) |
1da177e4c Linux-2.6.12-rc2 |
2083 |
{ |
2e6599cb8 [NET] Generalise ... |
2084 |
const struct inet_request_sock *ireq = inet_rsk(req); |
fa76ce732 inet: get rid of ... |
2085 |
long delta = req->rsk_timer.expires - jiffies; |
1da177e4c Linux-2.6.12-rc2 |
2086 |
|
5e659e4cb [NET]: Fix heavy ... |
2087 |
seq_printf(f, "%4d: %08X:%04X %08X:%04X" |
652586df9 seq_file: remove ... |
2088 |
" %02X %08X:%08X %02X:%08lX %08X %5u %8d %u %d %pK", |
1da177e4c Linux-2.6.12-rc2 |
2089 |
i, |
634fb979e inet: includes a ... |
2090 |
ireq->ir_loc_addr, |
d4f06873b inet: get_openreq... |
2091 |
ireq->ir_num, |
634fb979e inet: includes a ... |
2092 2093 |
ireq->ir_rmt_addr, ntohs(ireq->ir_rmt_port), |
1da177e4c Linux-2.6.12-rc2 |
2094 2095 2096 |
TCP_SYN_RECV, 0, 0, /* could print option size, but that is af dependent. */ 1, /* timers active (only the expire timer) */ |
a399a8053 time: jiffies_del... |
2097 |
jiffies_delta_to_clock_t(delta), |
e6c022a4f tcp: better retra... |
2098 |
req->num_timeout, |
aa3a0c8ce tcp: get_openreq[... |
2099 2100 |
from_kuid_munged(seq_user_ns(f), sock_i_uid(req->rsk_listener)), |
1da177e4c Linux-2.6.12-rc2 |
2101 2102 |
0, /* non standard timer */ 0, /* open_requests have no inode */ |
d4f06873b inet: get_openreq... |
2103 |
0, |
652586df9 seq_file: remove ... |
2104 |
req); |
1da177e4c Linux-2.6.12-rc2 |
2105 |
} |
652586df9 seq_file: remove ... |
2106 |
static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i) |
1da177e4c Linux-2.6.12-rc2 |
2107 2108 2109 |
{ int timer_active; unsigned long timer_expires; |
cf533ea53 tcp: add const qu... |
2110 |
const struct tcp_sock *tp = tcp_sk(sk); |
cf4c6bf83 [TCP]: struct *so... |
2111 |
const struct inet_connection_sock *icsk = inet_csk(sk); |
cf533ea53 tcp: add const qu... |
2112 |
const struct inet_sock *inet = inet_sk(sk); |
0536fcc03 tcp: prepare fast... |
2113 |
const struct fastopen_queue *fastopenq = &icsk->icsk_accept_queue.fastopenq; |
c720c7e83 inet: rename some... |
2114 2115 2116 2117 |
__be32 dest = inet->inet_daddr; __be32 src = inet->inet_rcv_saddr; __u16 destp = ntohs(inet->inet_dport); __u16 srcp = ntohs(inet->inet_sport); |
49d090078 tcp: diag: Dont r... |
2118 |
int rx_queue; |
00fd38d93 tcp: ensure prope... |
2119 |
int state; |
1da177e4c Linux-2.6.12-rc2 |
2120 |
|
6ba8a3b19 tcp: Tail loss pr... |
2121 2122 2123 |
if (icsk->icsk_pending == ICSK_TIME_RETRANS || icsk->icsk_pending == ICSK_TIME_EARLY_RETRANS || icsk->icsk_pending == ICSK_TIME_LOSS_PROBE) { |
1da177e4c Linux-2.6.12-rc2 |
2124 |
timer_active = 1; |
463c84b97 [NET]: Introduce ... |
2125 2126 |
timer_expires = icsk->icsk_timeout; } else if (icsk->icsk_pending == ICSK_TIME_PROBE0) { |
1da177e4c Linux-2.6.12-rc2 |
2127 |
timer_active = 4; |
463c84b97 [NET]: Introduce ... |
2128 |
timer_expires = icsk->icsk_timeout; |
cf4c6bf83 [TCP]: struct *so... |
2129 |
} else if (timer_pending(&sk->sk_timer)) { |
1da177e4c Linux-2.6.12-rc2 |
2130 |
timer_active = 2; |
cf4c6bf83 [TCP]: struct *so... |
2131 |
timer_expires = sk->sk_timer.expires; |
1da177e4c Linux-2.6.12-rc2 |
2132 2133 2134 2135 |
} else { timer_active = 0; timer_expires = jiffies; } |
00fd38d93 tcp: ensure prope... |
2136 2137 |
state = sk_state_load(sk); if (state == TCP_LISTEN) |
49d090078 tcp: diag: Dont r... |
2138 2139 |
rx_queue = sk->sk_ack_backlog; else |
00fd38d93 tcp: ensure prope... |
2140 2141 |
/* Because we don't lock the socket, * we might find a transient negative value. |
49d090078 tcp: diag: Dont r... |
2142 2143 |
*/ rx_queue = max_t(int, tp->rcv_nxt - tp->copied_seq, 0); |
5e659e4cb [NET]: Fix heavy ... |
2144 |
seq_printf(f, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX " |
652586df9 seq_file: remove ... |
2145 |
"%08X %5u %8d %lu %d %pK %lu %lu %u %u %d", |
00fd38d93 tcp: ensure prope... |
2146 |
i, src, srcp, dest, destp, state, |
47da8ee68 [TCP]: Export acc... |
2147 |
tp->write_seq - tp->snd_una, |
49d090078 tcp: diag: Dont r... |
2148 |
rx_queue, |
1da177e4c Linux-2.6.12-rc2 |
2149 |
timer_active, |
a399a8053 time: jiffies_del... |
2150 |
jiffies_delta_to_clock_t(timer_expires - jiffies), |
463c84b97 [NET]: Introduce ... |
2151 |
icsk->icsk_retransmits, |
a7cb5a49b userns: Print out... |
2152 |
from_kuid_munged(seq_user_ns(f), sock_i_uid(sk)), |
6687e988d [ICSK]: Move TCP ... |
2153 |
icsk->icsk_probes_out, |
cf4c6bf83 [TCP]: struct *so... |
2154 2155 |
sock_i_ino(sk), atomic_read(&sk->sk_refcnt), sk, |
7be87351a tcp: /proc/net/tc... |
2156 2157 |
jiffies_to_clock_t(icsk->icsk_rto), jiffies_to_clock_t(icsk->icsk_ack.ato), |
463c84b97 [NET]: Introduce ... |
2158 |
(icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong, |
1da177e4c Linux-2.6.12-rc2 |
2159 |
tp->snd_cwnd, |
00fd38d93 tcp: ensure prope... |
2160 2161 |
state == TCP_LISTEN ? fastopenq->max_qlen : |
652586df9 seq_file: remove ... |
2162 |
(tcp_in_initial_slowstart(tp) ? -1 : tp->snd_ssthresh)); |
1da177e4c Linux-2.6.12-rc2 |
2163 |
} |
cf533ea53 tcp: add const qu... |
2164 |
static void get_timewait4_sock(const struct inet_timewait_sock *tw, |
652586df9 seq_file: remove ... |
2165 |
struct seq_file *f, int i) |
1da177e4c Linux-2.6.12-rc2 |
2166 |
{ |
789f558cf tcp/dccp: get rid... |
2167 |
long delta = tw->tw_timer.expires - jiffies; |
23f33c2d4 [IPV4]: struct in... |
2168 |
__be32 dest, src; |
1da177e4c Linux-2.6.12-rc2 |
2169 |
__u16 destp, srcp; |
1da177e4c Linux-2.6.12-rc2 |
2170 2171 2172 2173 2174 |
dest = tw->tw_daddr; src = tw->tw_rcv_saddr; destp = ntohs(tw->tw_dport); srcp = ntohs(tw->tw_sport); |
5e659e4cb [NET]: Fix heavy ... |
2175 |
seq_printf(f, "%4d: %08X:%04X %08X:%04X" |
652586df9 seq_file: remove ... |
2176 |
" %02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %pK", |
1da177e4c Linux-2.6.12-rc2 |
2177 |
i, src, srcp, dest, destp, tw->tw_substate, 0, 0, |
a399a8053 time: jiffies_del... |
2178 |
3, jiffies_delta_to_clock_t(delta), 0, 0, 0, 0, |
652586df9 seq_file: remove ... |
2179 |
atomic_read(&tw->tw_refcnt), tw); |
1da177e4c Linux-2.6.12-rc2 |
2180 2181 2182 2183 2184 2185 |
} #define TMPSZ 150 static int tcp4_seq_show(struct seq_file *seq, void *v) { |
5799de0b1 net: clean up net... |
2186 |
struct tcp_iter_state *st; |
05dbc7b59 tcp/dccp: remove ... |
2187 |
struct sock *sk = v; |
1da177e4c Linux-2.6.12-rc2 |
2188 |
|
652586df9 seq_file: remove ... |
2189 |
seq_setwidth(seq, TMPSZ - 1); |
1da177e4c Linux-2.6.12-rc2 |
2190 |
if (v == SEQ_START_TOKEN) { |
652586df9 seq_file: remove ... |
2191 |
seq_puts(seq, " sl local_address rem_address st tx_queue " |
1da177e4c Linux-2.6.12-rc2 |
2192 2193 2194 2195 2196 |
"rx_queue tr tm->when retrnsmt uid timeout " "inode"); goto out; } st = seq->private; |
079096f10 tcp/dccp: install... |
2197 2198 2199 |
if (sk->sk_state == TCP_TIME_WAIT) get_timewait4_sock(v, seq, st->num); else if (sk->sk_state == TCP_NEW_SYN_RECV) |
aa3a0c8ce tcp: get_openreq[... |
2200 |
get_openreq4(v, seq, st->num); |
079096f10 tcp/dccp: install... |
2201 2202 |
else get_tcp4_sock(v, seq, st->num); |
1da177e4c Linux-2.6.12-rc2 |
2203 |
out: |
652586df9 seq_file: remove ... |
2204 2205 |
seq_pad(seq, ' '); |
1da177e4c Linux-2.6.12-rc2 |
2206 2207 |
return 0; } |
73cb88ecb net: make the tcp... |
2208 2209 2210 2211 2212 2213 2214 |
static const struct file_operations tcp_afinfo_seq_fops = { .owner = THIS_MODULE, .open = tcp_seq_open, .read = seq_read, .llseek = seq_lseek, .release = seq_release_net }; |
1da177e4c Linux-2.6.12-rc2 |
2215 |
static struct tcp_seq_afinfo tcp4_seq_afinfo = { |
1da177e4c Linux-2.6.12-rc2 |
2216 2217 |
.name = "tcp", .family = AF_INET, |
73cb88ecb net: make the tcp... |
2218 |
.seq_fops = &tcp_afinfo_seq_fops, |
9427c4b36 [TCP]: Move seq_o... |
2219 2220 2221 |
.seq_ops = { .show = tcp4_seq_show, }, |
1da177e4c Linux-2.6.12-rc2 |
2222 |
}; |
2c8c1e729 net: spread __net... |
2223 |
static int __net_init tcp4_proc_init_net(struct net *net) |
757764f61 [NETNS][TCP]: Reg... |
2224 2225 2226 |
{ return tcp_proc_register(net, &tcp4_seq_afinfo); } |
2c8c1e729 net: spread __net... |
2227 |
static void __net_exit tcp4_proc_exit_net(struct net *net) |
757764f61 [NETNS][TCP]: Reg... |
2228 2229 2230 2231 2232 2233 2234 2235 |
{ tcp_proc_unregister(net, &tcp4_seq_afinfo); } static struct pernet_operations tcp4_net_ops = { .init = tcp4_proc_init_net, .exit = tcp4_proc_exit_net, }; |
1da177e4c Linux-2.6.12-rc2 |
2236 2237 |
int __init tcp4_proc_init(void) { |
757764f61 [NETNS][TCP]: Reg... |
2238 |
return register_pernet_subsys(&tcp4_net_ops); |
1da177e4c Linux-2.6.12-rc2 |
2239 2240 2241 2242 |
} void tcp4_proc_exit(void) { |
757764f61 [NETNS][TCP]: Reg... |
2243 |
unregister_pernet_subsys(&tcp4_net_ops); |
1da177e4c Linux-2.6.12-rc2 |
2244 2245 2246 2247 2248 2249 2250 2251 2252 |
} #endif /* CONFIG_PROC_FS */ struct proto tcp_prot = { .name = "TCP", .owner = THIS_MODULE, .close = tcp_close, .connect = tcp_v4_connect, .disconnect = tcp_disconnect, |
463c84b97 [NET]: Introduce ... |
2253 |
.accept = inet_csk_accept, |
1da177e4c Linux-2.6.12-rc2 |
2254 2255 2256 2257 2258 2259 |
.ioctl = tcp_ioctl, .init = tcp_v4_init_sock, .destroy = tcp_v4_destroy_sock, .shutdown = tcp_shutdown, .setsockopt = tcp_setsockopt, .getsockopt = tcp_getsockopt, |
1da177e4c Linux-2.6.12-rc2 |
2260 |
.recvmsg = tcp_recvmsg, |
7ba429100 inet, inet6: make... |
2261 2262 |
.sendmsg = tcp_sendmsg, .sendpage = tcp_sendpage, |
1da177e4c Linux-2.6.12-rc2 |
2263 |
.backlog_rcv = tcp_v4_do_rcv, |
46d3ceabd tcp: TCP Small Qu... |
2264 |
.release_cb = tcp_release_cb, |
ab1e0a13d [SOCK] proto: Add... |
2265 2266 2267 |
.hash = inet_hash, .unhash = inet_unhash, .get_port = inet_csk_get_port, |
1da177e4c Linux-2.6.12-rc2 |
2268 |
.enter_memory_pressure = tcp_enter_memory_pressure, |
c9bee3b7f tcp: TCP_NOTSENT_... |
2269 |
.stream_memory_free = tcp_stream_memory_free, |
1da177e4c Linux-2.6.12-rc2 |
2270 |
.sockets_allocated = &tcp_sockets_allocated, |
0a5578cf8 [ICSK]: Generalis... |
2271 |
.orphan_count = &tcp_orphan_count, |
1da177e4c Linux-2.6.12-rc2 |
2272 2273 |
.memory_allocated = &tcp_memory_allocated, .memory_pressure = &tcp_memory_pressure, |
a4fe34bf9 tcp_memcontrol: R... |
2274 |
.sysctl_mem = sysctl_tcp_mem, |
1da177e4c Linux-2.6.12-rc2 |
2275 2276 2277 2278 |
.sysctl_wmem = sysctl_tcp_wmem, .sysctl_rmem = sysctl_tcp_rmem, .max_header = MAX_TCP_HEADER, .obj_size = sizeof(struct tcp_sock), |
3ab5aee7f net: Convert TCP ... |
2279 |
.slab_flags = SLAB_DESTROY_BY_RCU, |
6d6ee43e0 [TWSK]: Introduce... |
2280 |
.twsk_prot = &tcp_timewait_sock_ops, |
60236fdd0 [NET] Rename open... |
2281 |
.rsk_prot = &tcp_request_sock_ops, |
39d8cda76 [SOCK]: Add udp_h... |
2282 |
.h.hashinfo = &tcp_hashinfo, |
7ba429100 inet, inet6: make... |
2283 |
.no_autobind = true, |
543d9cfee [NET]: Identation... |
2284 2285 2286 2287 |
#ifdef CONFIG_COMPAT .compat_setsockopt = compat_tcp_setsockopt, .compat_getsockopt = compat_tcp_getsockopt, #endif |
c1e64e298 net: diag: Suppor... |
2288 |
.diag_destroy = tcp_abort, |
1da177e4c Linux-2.6.12-rc2 |
2289 |
}; |
4bc2f18ba net/ipv4: EXPORT_... |
2290 |
EXPORT_SYMBOL(tcp_prot); |
1da177e4c Linux-2.6.12-rc2 |
2291 |
|
bdbbb8527 ipv4: tcp: get ri... |
2292 2293 2294 2295 2296 2297 2298 2299 |
static void __net_exit tcp_sk_exit(struct net *net) { int cpu; for_each_possible_cpu(cpu) inet_ctl_sock_destroy(*per_cpu_ptr(net->ipv4.tcp_sk, cpu)); free_percpu(net->ipv4.tcp_sk); } |
046ee9023 [NETNS]: Create t... |
2300 2301 |
static int __net_init tcp_sk_init(struct net *net) { |
bdbbb8527 ipv4: tcp: get ri... |
2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 |
int res, cpu; 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 ipv4: tcp: set SO... |
2315 |
sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); |
bdbbb8527 ipv4: tcp: get ri... |
2316 2317 |
*per_cpu_ptr(net->ipv4.tcp_sk, cpu) = sk; } |
492135557 tcp: add rfc3168,... |
2318 |
|
5d134f1c1 tcp: make sysctl_... |
2319 |
net->ipv4.sysctl_tcp_ecn = 2; |
492135557 tcp: add rfc3168,... |
2320 |
net->ipv4.sysctl_tcp_ecn_fallback = 1; |
b0f9ca53c ipv4: Namespecify... |
2321 |
net->ipv4.sysctl_tcp_base_mss = TCP_BASE_MSS; |
6b58e0a5f ipv4: Use binary ... |
2322 |
net->ipv4.sysctl_tcp_probe_threshold = TCP_PROBE_THRESHOLD; |
05cbc0db0 ipv4: Create prob... |
2323 |
net->ipv4.sysctl_tcp_probe_interval = TCP_PROBE_INTERVAL; |
046ee9023 [NETNS]: Create t... |
2324 |
|
13b287e8d ipv4: Namespaceif... |
2325 |
net->ipv4.sysctl_tcp_keepalive_time = TCP_KEEPALIVE_TIME; |
9bd6861bd ipv4: Namespecify... |
2326 |
net->ipv4.sysctl_tcp_keepalive_probes = TCP_KEEPALIVE_PROBES; |
b840d15d3 ipv4: Namespecify... |
2327 |
net->ipv4.sysctl_tcp_keepalive_intvl = TCP_KEEPALIVE_INTVL; |
13b287e8d ipv4: Namespaceif... |
2328 |
|
6fa251663 ipv4: Namespaceif... |
2329 |
net->ipv4.sysctl_tcp_syn_retries = TCP_SYN_RETRIES; |
7c083ecb3 ipv4: Namespaceif... |
2330 |
net->ipv4.sysctl_tcp_synack_retries = TCP_SYNACK_RETRIES; |
0aca737d4 tcp: Fix syncooki... |
2331 |
net->ipv4.sysctl_tcp_syncookies = 1; |
1043e25ff ipv4: Namespaceif... |
2332 |
net->ipv4.sysctl_tcp_reordering = TCP_FASTRETRANS_THRESH; |
ae5c3f406 ipv4: Namespaceif... |
2333 |
net->ipv4.sysctl_tcp_retries1 = TCP_RETR1; |
c6214a97c ipv4: Namespaceif... |
2334 |
net->ipv4.sysctl_tcp_retries2 = TCP_RETR2; |
c402d9bef ipv4: Namespaceif... |
2335 |
net->ipv4.sysctl_tcp_orphan_retries = 0; |
1e579caa1 ipv4: Namespaceif... |
2336 |
net->ipv4.sysctl_tcp_fin_timeout = TCP_FIN_TIMEOUT; |
4979f2d9f ipv4: Namespaceif... |
2337 |
net->ipv4.sysctl_tcp_notsent_lowat = UINT_MAX; |
12ed8244e ipv4: Namespaceif... |
2338 |
|
492135557 tcp: add rfc3168,... |
2339 |
return 0; |
bdbbb8527 ipv4: tcp: get ri... |
2340 2341 2342 2343 |
fail: tcp_sk_exit(net); return res; |
b099ce260 net: Batch inet_t... |
2344 2345 2346 2347 2348 |
} static void __net_exit tcp_sk_exit_batch(struct list_head *net_exit_list) { inet_twsk_purge(&tcp_hashinfo, &tcp_death_row, AF_INET); |
046ee9023 [NETNS]: Create t... |
2349 2350 2351 |
} static struct pernet_operations __net_initdata tcp_sk_ops = { |
b099ce260 net: Batch inet_t... |
2352 2353 2354 |
.init = tcp_sk_init, .exit = tcp_sk_exit, .exit_batch = tcp_sk_exit_batch, |
046ee9023 [NETNS]: Create t... |
2355 |
}; |
9b0f976f2 [INET]: Remove st... |
2356 |
void __init tcp_v4_init(void) |
1da177e4c Linux-2.6.12-rc2 |
2357 |
{ |
5caea4ea7 net: listening_ha... |
2358 |
inet_hashinfo_init(&tcp_hashinfo); |
6a1b3054d tcp: Like icmp us... |
2359 |
if (register_pernet_subsys(&tcp_sk_ops)) |
1da177e4c Linux-2.6.12-rc2 |
2360 2361 |
panic("Failed to create the TCP control socket. "); |
1da177e4c Linux-2.6.12-rc2 |
2362 |
} |