Blame view
net/ipv6/tcp_ipv6.c
58.2 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 |
/* * TCP over IPv6 |
1ab1457c4 [NET] IPV6: Fix w... |
3 |
* Linux INET6 implementation |
1da177e4c Linux-2.6.12-rc2 |
4 5 |
* * Authors: |
1ab1457c4 [NET] IPV6: Fix w... |
6 |
* Pedro Roque <roque@di.fc.ul.pt> |
1da177e4c Linux-2.6.12-rc2 |
7 |
* |
1ab1457c4 [NET] IPV6: Fix w... |
8 |
* Based on: |
1da177e4c Linux-2.6.12-rc2 |
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
* linux/net/ipv4/tcp.c * linux/net/ipv4/tcp_input.c * linux/net/ipv4/tcp_output.c * * Fixes: * Hideaki YOSHIFUJI : sin6_scope_id support * 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. * YOSHIFUJI Hideaki @USAGI: convert /proc/net/tcp6 to seq_file. * * 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. */ |
eb4dea585 net: Fix percpu c... |
25 |
#include <linux/bottom_half.h> |
1da177e4c Linux-2.6.12-rc2 |
26 |
#include <linux/module.h> |
1da177e4c Linux-2.6.12-rc2 |
27 28 29 30 31 32 33 34 35 36 37 38 39 |
#include <linux/errno.h> #include <linux/types.h> #include <linux/socket.h> #include <linux/sockios.h> #include <linux/net.h> #include <linux/jiffies.h> #include <linux/in.h> #include <linux/in6.h> #include <linux/netdevice.h> #include <linux/init.h> #include <linux/jhash.h> #include <linux/ipsec.h> #include <linux/times.h> |
5a0e3ad6a include cleanup: ... |
40 |
#include <linux/slab.h> |
1da177e4c Linux-2.6.12-rc2 |
41 42 43 44 45 46 47 |
#include <linux/ipv6.h> #include <linux/icmpv6.h> #include <linux/random.h> #include <net/tcp.h> #include <net/ndisc.h> |
5324a040c [INET6_HASHTABLES... |
48 |
#include <net/inet6_hashtables.h> |
8129765ac [IPV6]: Generalis... |
49 |
#include <net/inet6_connection_sock.h> |
1da177e4c Linux-2.6.12-rc2 |
50 51 52 53 54 55 56 57 |
#include <net/ipv6.h> #include <net/transp_v6.h> #include <net/addrconf.h> #include <net/ip6_route.h> #include <net/ip6_checksum.h> #include <net/inet_ecn.h> #include <net/protocol.h> #include <net/xfrm.h> |
1da177e4c Linux-2.6.12-rc2 |
58 59 |
#include <net/snmp.h> #include <net/dsfield.h> |
6d6ee43e0 [TWSK]: Introduce... |
60 |
#include <net/timewait_sock.h> |
18134bed0 [TCP] IPV6: fix s... |
61 |
#include <net/netdma.h> |
3d58b5fa8 [INET]: Rename in... |
62 |
#include <net/inet_common.h> |
6e5714eaf net: Compute prot... |
63 |
#include <net/secure_seq.h> |
d1a4c0b37 tcp memory pressu... |
64 |
#include <net/tcp_memcontrol.h> |
1da177e4c Linux-2.6.12-rc2 |
65 66 67 68 69 |
#include <asm/uaccess.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> |
cfb6eeb4c [TCP]: MD5 Signat... |
70 71 |
#include <linux/crypto.h> #include <linux/scatterlist.h> |
cfb6eeb4c [TCP]: MD5 Signat... |
72 |
static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb); |
6edafaaf6 tcp: Fix kernel p... |
73 74 |
static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb, struct request_sock *req); |
1da177e4c Linux-2.6.12-rc2 |
75 76 |
static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); |
8ad50d96d tcp: Handle CHECK... |
77 |
static void __tcp_v6_send_check(struct sk_buff *skb, |
b71d1d426 inet: constify ip... |
78 79 |
const struct in6_addr *saddr, const struct in6_addr *daddr); |
1da177e4c Linux-2.6.12-rc2 |
80 |
|
3b401a81c inet: inet_connec... |
81 82 |
static const struct inet_connection_sock_af_ops ipv6_mapped; static const struct inet_connection_sock_af_ops ipv6_specific; |
a928630a2 [TCP]: Fix some w... |
83 |
#ifdef CONFIG_TCP_MD5SIG |
b2e4b3deb tcp: MD5 operatio... |
84 85 |
static const struct tcp_sock_af_ops tcp_sock_ipv6_specific; static const struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific; |
9501f9722 tcp md5sig: Let t... |
86 87 |
#else static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(struct sock *sk, |
b71d1d426 inet: constify ip... |
88 |
const struct in6_addr *addr) |
9501f9722 tcp md5sig: Let t... |
89 90 91 |
{ return NULL; } |
a928630a2 [TCP]: Fix some w... |
92 |
#endif |
1da177e4c Linux-2.6.12-rc2 |
93 |
|
1da177e4c Linux-2.6.12-rc2 |
94 95 96 |
static void tcp_v6_hash(struct sock *sk) { if (sk->sk_state != TCP_CLOSE) { |
8292a17a3 [ICSK]: Rename st... |
97 |
if (inet_csk(sk)->icsk_af_ops == &ipv6_mapped) { |
1da177e4c Linux-2.6.12-rc2 |
98 99 100 101 |
tcp_prot.hash(sk); return; } local_bh_disable(); |
9327f7053 tcp: Fix a connec... |
102 |
__inet6_hash(sk, NULL); |
1da177e4c Linux-2.6.12-rc2 |
103 104 105 |
local_bh_enable(); } } |
684f21760 tcp6: Add GRO sup... |
106 |
static __inline__ __sum16 tcp_v6_check(int len, |
b71d1d426 inet: constify ip... |
107 108 |
const struct in6_addr *saddr, const struct in6_addr *daddr, |
868c86bcb [NET]: annotate c... |
109 |
__wsum base) |
1da177e4c Linux-2.6.12-rc2 |
110 111 112 |
{ return csum_ipv6_magic(saddr, daddr, len, IPPROTO_TCP, base); } |
cf533ea53 tcp: add const qu... |
113 |
static __u32 tcp_v6_init_sequence(const struct sk_buff *skb) |
1da177e4c Linux-2.6.12-rc2 |
114 |
{ |
0660e03f6 [SK_BUFF]: Introd... |
115 116 |
return secure_tcpv6_sequence_number(ipv6_hdr(skb)->daddr.s6_addr32, ipv6_hdr(skb)->saddr.s6_addr32, |
aa8223c7b [SK_BUFF]: Introd... |
117 118 |
tcp_hdr(skb)->dest, tcp_hdr(skb)->source); |
1da177e4c Linux-2.6.12-rc2 |
119 |
} |
1ab1457c4 [NET] IPV6: Fix w... |
120 |
static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, |
1da177e4c Linux-2.6.12-rc2 |
121 122 123 |
int addr_len) { struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; |
1ab1457c4 [NET] IPV6: Fix w... |
124 |
struct inet_sock *inet = inet_sk(sk); |
d83d8461f [IP_SOCKGLUE]: Re... |
125 |
struct inet_connection_sock *icsk = inet_csk(sk); |
1da177e4c Linux-2.6.12-rc2 |
126 127 |
struct ipv6_pinfo *np = inet6_sk(sk); struct tcp_sock *tp = tcp_sk(sk); |
20c59de2e ipv6: Refactor up... |
128 |
struct in6_addr *saddr = NULL, *final_p, final; |
493f377d6 tcp: Add timewait... |
129 |
struct rt6_info *rt; |
4c9483b2f ipv6: Convert to ... |
130 |
struct flowi6 fl6; |
1da177e4c Linux-2.6.12-rc2 |
131 132 133 |
struct dst_entry *dst; int addr_type; int err; |
1ab1457c4 [NET] IPV6: Fix w... |
134 |
if (addr_len < SIN6_LEN_RFC2133) |
1da177e4c Linux-2.6.12-rc2 |
135 |
return -EINVAL; |
1ab1457c4 [NET] IPV6: Fix w... |
136 |
if (usin->sin6_family != AF_INET6) |
a02cec215 net: return opera... |
137 |
return -EAFNOSUPPORT; |
1da177e4c Linux-2.6.12-rc2 |
138 |
|
4c9483b2f ipv6: Convert to ... |
139 |
memset(&fl6, 0, sizeof(fl6)); |
1da177e4c Linux-2.6.12-rc2 |
140 141 |
if (np->sndflow) { |
4c9483b2f ipv6: Convert to ... |
142 143 144 |
fl6.flowlabel = usin->sin6_flowinfo&IPV6_FLOWINFO_MASK; IP6_ECN_flow_init(fl6.flowlabel); if (fl6.flowlabel&IPV6_FLOWLABEL_MASK) { |
1da177e4c Linux-2.6.12-rc2 |
145 |
struct ip6_flowlabel *flowlabel; |
4c9483b2f ipv6: Convert to ... |
146 |
flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
1da177e4c Linux-2.6.12-rc2 |
147 148 |
if (flowlabel == NULL) return -EINVAL; |
4e3fd7a06 net: remove ipv6_... |
149 |
usin->sin6_addr = flowlabel->dst; |
1da177e4c Linux-2.6.12-rc2 |
150 151 152 153 154 |
fl6_sock_release(flowlabel); } } /* |
1ab1457c4 [NET] IPV6: Fix w... |
155 156 157 158 159 |
* connect() to INADDR_ANY means loopback (BSD'ism). */ if(ipv6_addr_any(&usin->sin6_addr)) usin->sin6_addr.s6_addr[15] = 0x1; |
1da177e4c Linux-2.6.12-rc2 |
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
addr_type = ipv6_addr_type(&usin->sin6_addr); if(addr_type & IPV6_ADDR_MULTICAST) return -ENETUNREACH; if (addr_type&IPV6_ADDR_LINKLOCAL) { if (addr_len >= sizeof(struct sockaddr_in6) && usin->sin6_scope_id) { /* If interface is set while binding, indices * must coincide. */ if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != usin->sin6_scope_id) return -EINVAL; sk->sk_bound_dev_if = usin->sin6_scope_id; } /* Connect to link-local address requires an interface */ if (!sk->sk_bound_dev_if) return -EINVAL; } if (tp->rx_opt.ts_recent_stamp && !ipv6_addr_equal(&np->daddr, &usin->sin6_addr)) { tp->rx_opt.ts_recent = 0; tp->rx_opt.ts_recent_stamp = 0; tp->write_seq = 0; } |
4e3fd7a06 net: remove ipv6_... |
190 |
np->daddr = usin->sin6_addr; |
4c9483b2f ipv6: Convert to ... |
191 |
np->flow_label = fl6.flowlabel; |
1da177e4c Linux-2.6.12-rc2 |
192 193 194 195 196 197 |
/* * TCP over IPv4 */ if (addr_type == IPV6_ADDR_MAPPED) { |
d83d8461f [IP_SOCKGLUE]: Re... |
198 |
u32 exthdrlen = icsk->icsk_ext_hdr_len; |
1da177e4c Linux-2.6.12-rc2 |
199 200 201 202 203 204 205 206 207 208 209 |
struct sockaddr_in sin; SOCK_DEBUG(sk, "connect: ipv4 mapped "); if (__ipv6_only_sock(sk)) return -ENETUNREACH; sin.sin_family = AF_INET; sin.sin_port = usin->sin6_port; sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3]; |
d83d8461f [IP_SOCKGLUE]: Re... |
210 |
icsk->icsk_af_ops = &ipv6_mapped; |
1da177e4c Linux-2.6.12-rc2 |
211 |
sk->sk_backlog_rcv = tcp_v4_do_rcv; |
cfb6eeb4c [TCP]: MD5 Signat... |
212 213 214 |
#ifdef CONFIG_TCP_MD5SIG tp->af_specific = &tcp_sock_ipv6_mapped_specific; #endif |
1da177e4c Linux-2.6.12-rc2 |
215 216 217 218 |
err = tcp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin)); if (err) { |
d83d8461f [IP_SOCKGLUE]: Re... |
219 220 |
icsk->icsk_ext_hdr_len = exthdrlen; icsk->icsk_af_ops = &ipv6_specific; |
1da177e4c Linux-2.6.12-rc2 |
221 |
sk->sk_backlog_rcv = tcp_v6_do_rcv; |
cfb6eeb4c [TCP]: MD5 Signat... |
222 223 224 |
#ifdef CONFIG_TCP_MD5SIG tp->af_specific = &tcp_sock_ipv6_specific; #endif |
1da177e4c Linux-2.6.12-rc2 |
225 226 |
goto failure; } else { |
c720c7e83 inet: rename some... |
227 228 229 |
ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr); ipv6_addr_set_v4mapped(inet->inet_rcv_saddr, &np->rcv_saddr); |
1da177e4c Linux-2.6.12-rc2 |
230 231 232 233 234 235 236 |
} return err; } if (!ipv6_addr_any(&np->rcv_saddr)) saddr = &np->rcv_saddr; |
4c9483b2f ipv6: Convert to ... |
237 |
fl6.flowi6_proto = IPPROTO_TCP; |
4e3fd7a06 net: remove ipv6_... |
238 239 |
fl6.daddr = np->daddr; fl6.saddr = saddr ? *saddr : np->saddr; |
4c9483b2f ipv6: Convert to ... |
240 241 |
fl6.flowi6_oif = sk->sk_bound_dev_if; fl6.flowi6_mark = sk->sk_mark; |
1958b856c net: Put fl6_* ma... |
242 243 |
fl6.fl6_dport = usin->sin6_port; fl6.fl6_sport = inet->inet_sport; |
1da177e4c Linux-2.6.12-rc2 |
244 |
|
4c9483b2f ipv6: Convert to ... |
245 |
final_p = fl6_update_dst(&fl6, np->opt, &final); |
1da177e4c Linux-2.6.12-rc2 |
246 |
|
4c9483b2f ipv6: Convert to ... |
247 |
security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); |
beb8d13be [MLSXFRM]: Add fl... |
248 |
|
4c9483b2f ipv6: Convert to ... |
249 |
dst = ip6_dst_lookup_flow(sk, &fl6, final_p, true); |
68d0c6d34 ipv6: Consolidate... |
250 251 |
if (IS_ERR(dst)) { err = PTR_ERR(dst); |
1da177e4c Linux-2.6.12-rc2 |
252 |
goto failure; |
14e50e57a [XFRM]: Allow pac... |
253 |
} |
1da177e4c Linux-2.6.12-rc2 |
254 255 |
if (saddr == NULL) { |
4c9483b2f ipv6: Convert to ... |
256 |
saddr = &fl6.saddr; |
4e3fd7a06 net: remove ipv6_... |
257 |
np->rcv_saddr = *saddr; |
1da177e4c Linux-2.6.12-rc2 |
258 259 260 |
} /* set the source address */ |
4e3fd7a06 net: remove ipv6_... |
261 |
np->saddr = *saddr; |
c720c7e83 inet: rename some... |
262 |
inet->inet_rcv_saddr = LOOPBACK4_IPV6; |
1da177e4c Linux-2.6.12-rc2 |
263 |
|
f83ef8c0b [IPV6]: Added GSO... |
264 |
sk->sk_gso_type = SKB_GSO_TCPV6; |
8e1ef0a95 [IPV6]: Cache sou... |
265 |
__ip6_dst_store(sk, dst, NULL, NULL); |
1da177e4c Linux-2.6.12-rc2 |
266 |
|
493f377d6 tcp: Add timewait... |
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 |
rt = (struct rt6_info *) dst; if (tcp_death_row.sysctl_tw_recycle && !tp->rx_opt.ts_recent_stamp && ipv6_addr_equal(&rt->rt6i_dst.addr, &np->daddr)) { struct inet_peer *peer = rt6_get_peer(rt); /* * VJ's idea. We save last timestamp seen from * the destination in peer table, when entering state * TIME-WAIT * and initialize rx_opt.ts_recent from it, * when trying new connection. */ if (peer) { inet_peer_refcheck(peer); if ((u32)get_seconds() - peer->tcp_ts_stamp <= TCP_PAWS_MSL) { tp->rx_opt.ts_recent_stamp = peer->tcp_ts_stamp; tp->rx_opt.ts_recent = peer->tcp_ts; } } } |
d83d8461f [IP_SOCKGLUE]: Re... |
286 |
icsk->icsk_ext_hdr_len = 0; |
1da177e4c Linux-2.6.12-rc2 |
287 |
if (np->opt) |
d83d8461f [IP_SOCKGLUE]: Re... |
288 289 |
icsk->icsk_ext_hdr_len = (np->opt->opt_flen + np->opt->opt_nflen); |
1da177e4c Linux-2.6.12-rc2 |
290 291 |
tp->rx_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); |
c720c7e83 inet: rename some... |
292 |
inet->inet_dport = usin->sin6_port; |
1da177e4c Linux-2.6.12-rc2 |
293 294 |
tcp_set_state(sk, TCP_SYN_SENT); |
d8313f5ca [INET6]: Generali... |
295 |
err = inet6_hash_connect(&tcp_death_row, sk); |
1da177e4c Linux-2.6.12-rc2 |
296 297 298 299 300 301 |
if (err) goto late_failure; if (!tp->write_seq) tp->write_seq = secure_tcpv6_sequence_number(np->saddr.s6_addr32, np->daddr.s6_addr32, |
c720c7e83 inet: rename some... |
302 303 |
inet->inet_sport, inet->inet_dport); |
1da177e4c Linux-2.6.12-rc2 |
304 305 306 307 308 309 310 311 312 313 314 |
err = tcp_connect(sk); if (err) goto late_failure; return 0; late_failure: tcp_set_state(sk, TCP_CLOSE); __sk_dst_reset(sk); failure: |
c720c7e83 inet: rename some... |
315 |
inet->inet_dport = 0; |
1da177e4c Linux-2.6.12-rc2 |
316 317 318 319 320 |
sk->sk_route_caps = 0; return err; } static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, |
d5fdd6bab ipv6: Use correct... |
321 |
u8 type, u8 code, int offset, __be32 info) |
1da177e4c Linux-2.6.12-rc2 |
322 |
{ |
b71d1d426 inet: constify ip... |
323 |
const struct ipv6hdr *hdr = (const struct ipv6hdr*)skb->data; |
505cbfc57 [IPV6]: Generalis... |
324 |
const struct tcphdr *th = (struct tcphdr *)(skb->data+offset); |
1da177e4c Linux-2.6.12-rc2 |
325 326 327 |
struct ipv6_pinfo *np; struct sock *sk; int err; |
1ab1457c4 [NET] IPV6: Fix w... |
328 |
struct tcp_sock *tp; |
1da177e4c Linux-2.6.12-rc2 |
329 |
__u32 seq; |
ca12a1a44 inet: prepare net... |
330 |
struct net *net = dev_net(skb->dev); |
1da177e4c Linux-2.6.12-rc2 |
331 |
|
ca12a1a44 inet: prepare net... |
332 |
sk = inet6_lookup(net, &tcp_hashinfo, &hdr->daddr, |
d86e0dac2 [NETNS]: Tcp-v6 s... |
333 |
th->dest, &hdr->saddr, th->source, skb->dev->ifindex); |
1da177e4c Linux-2.6.12-rc2 |
334 335 |
if (sk == NULL) { |
e41b5368e ipv6: added net a... |
336 337 |
ICMP6_INC_STATS_BH(net, __in6_dev_get(skb->dev), ICMP6_MIB_INERRORS); |
1da177e4c Linux-2.6.12-rc2 |
338 339 340 341 |
return; } if (sk->sk_state == TCP_TIME_WAIT) { |
9469c7b4a [NET]: Use typesa... |
342 |
inet_twsk_put(inet_twsk(sk)); |
1da177e4c Linux-2.6.12-rc2 |
343 344 345 346 347 |
return; } bh_lock_sock(sk); if (sock_owned_by_user(sk)) |
de0744af1 mib: add net to N... |
348 |
NET_INC_STATS_BH(net, LINUX_MIB_LOCKDROPPEDICMPS); |
1da177e4c Linux-2.6.12-rc2 |
349 350 351 |
if (sk->sk_state == TCP_CLOSE) goto out; |
e802af9ca IPv6: Generic TTL... |
352 353 354 355 |
if (ipv6_hdr(skb)->hop_limit < inet6_sk(sk)->min_hopcount) { NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP); goto out; } |
1da177e4c Linux-2.6.12-rc2 |
356 |
tp = tcp_sk(sk); |
1ab1457c4 [NET] IPV6: Fix w... |
357 |
seq = ntohl(th->seq); |
1da177e4c Linux-2.6.12-rc2 |
358 359 |
if (sk->sk_state != TCP_LISTEN && !between(seq, tp->snd_una, tp->snd_nxt)) { |
de0744af1 mib: add net to N... |
360 |
NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS); |
1da177e4c Linux-2.6.12-rc2 |
361 362 363 364 365 366 |
goto out; } np = inet6_sk(sk); if (type == ICMPV6_PKT_TOOBIG) { |
68d0c6d34 ipv6: Consolidate... |
367 |
struct dst_entry *dst; |
1da177e4c Linux-2.6.12-rc2 |
368 369 370 371 372 373 374 375 376 377 378 |
if (sock_owned_by_user(sk)) goto out; if ((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)) goto out; /* icmp should have updated the destination cache entry */ dst = __sk_dst_check(sk, np->dst_cookie); if (dst == NULL) { struct inet_sock *inet = inet_sk(sk); |
4c9483b2f ipv6: Convert to ... |
379 |
struct flowi6 fl6; |
1da177e4c Linux-2.6.12-rc2 |
380 381 382 383 384 |
/* BUGGG_FUTURE: Again, it is not clear how to handle rthdr case. Ignore this complexity for now. */ |
4c9483b2f ipv6: Convert to ... |
385 386 |
memset(&fl6, 0, sizeof(fl6)); fl6.flowi6_proto = IPPROTO_TCP; |
4e3fd7a06 net: remove ipv6_... |
387 388 |
fl6.daddr = np->daddr; fl6.saddr = np->saddr; |
4c9483b2f ipv6: Convert to ... |
389 390 |
fl6.flowi6_oif = sk->sk_bound_dev_if; fl6.flowi6_mark = sk->sk_mark; |
1958b856c net: Put fl6_* ma... |
391 392 |
fl6.fl6_dport = inet->inet_dport; fl6.fl6_sport = inet->inet_sport; |
4c9483b2f ipv6: Convert to ... |
393 394 395 |
security_skb_classify_flow(skb, flowi6_to_flowi(&fl6)); dst = ip6_dst_lookup_flow(sk, &fl6, NULL, false); |
68d0c6d34 ipv6: Consolidate... |
396 397 |
if (IS_ERR(dst)) { sk->sk_err_soft = -PTR_ERR(dst); |
1da177e4c Linux-2.6.12-rc2 |
398 399 400 401 402 |
goto out; } } else dst_hold(dst); |
d83d8461f [IP_SOCKGLUE]: Re... |
403 |
if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst)) { |
1da177e4c Linux-2.6.12-rc2 |
404 405 406 407 408 409 410 411 |
tcp_sync_mss(sk, dst_mtu(dst)); tcp_simple_retransmit(sk); } /* else let the usual retransmit timer handle it */ dst_release(dst); goto out; } icmpv6_err_convert(type, code, &err); |
60236fdd0 [NET] Rename open... |
412 |
/* Might be for an request_sock */ |
1da177e4c Linux-2.6.12-rc2 |
413 |
switch (sk->sk_state) { |
60236fdd0 [NET] Rename open... |
414 |
struct request_sock *req, **prev; |
1da177e4c Linux-2.6.12-rc2 |
415 416 417 |
case TCP_LISTEN: if (sock_owned_by_user(sk)) goto out; |
8129765ac [IPV6]: Generalis... |
418 419 |
req = inet6_csk_search_req(sk, &prev, th->dest, &hdr->daddr, &hdr->saddr, inet6_iif(skb)); |
1da177e4c Linux-2.6.12-rc2 |
420 421 422 423 424 425 |
if (!req) goto out; /* ICMPs are not backlogged, hence we cannot get * an established socket here. */ |
547b792ca net: convert BUG_... |
426 |
WARN_ON(req->sk != NULL); |
1da177e4c Linux-2.6.12-rc2 |
427 |
|
2e6599cb8 [NET] Generalise ... |
428 |
if (seq != tcp_rsk(req)->snt_isn) { |
de0744af1 mib: add net to N... |
429 |
NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS); |
1da177e4c Linux-2.6.12-rc2 |
430 431 |
goto out; } |
463c84b97 [NET]: Introduce ... |
432 |
inet_csk_reqsk_queue_drop(sk, req, prev); |
1da177e4c Linux-2.6.12-rc2 |
433 434 435 436 |
goto out; case TCP_SYN_SENT: case TCP_SYN_RECV: /* Cannot happen. |
1ab1457c4 [NET] IPV6: Fix w... |
437 |
It can, it SYNs are crossed. --ANK */ |
1da177e4c Linux-2.6.12-rc2 |
438 |
if (!sock_owned_by_user(sk)) { |
1da177e4c Linux-2.6.12-rc2 |
439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 |
sk->sk_err = err; sk->sk_error_report(sk); /* Wake people up to see the error (see connect in sock.c) */ tcp_done(sk); } else sk->sk_err_soft = err; goto out; } if (!sock_owned_by_user(sk) && np->recverr) { sk->sk_err = err; sk->sk_error_report(sk); } else sk->sk_err_soft = err; out: bh_unlock_sock(sk); sock_put(sk); } |
e6b4d1136 TCPCT part 1a: ad... |
458 459 |
static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, struct request_values *rvp) |
1da177e4c Linux-2.6.12-rc2 |
460 |
{ |
ca304b610 [IPV6]: Introduce... |
461 |
struct inet6_request_sock *treq = inet6_rsk(req); |
1da177e4c Linux-2.6.12-rc2 |
462 463 464 |
struct ipv6_pinfo *np = inet6_sk(sk); struct sk_buff * skb; struct ipv6_txoptions *opt = NULL; |
20c59de2e ipv6: Refactor up... |
465 |
struct in6_addr * final_p, final; |
4c9483b2f ipv6: Convert to ... |
466 |
struct flowi6 fl6; |
fd80eb942 [INET]: Remove st... |
467 |
struct dst_entry *dst; |
68d0c6d34 ipv6: Consolidate... |
468 |
int err; |
1da177e4c Linux-2.6.12-rc2 |
469 |
|
4c9483b2f ipv6: Convert to ... |
470 471 |
memset(&fl6, 0, sizeof(fl6)); fl6.flowi6_proto = IPPROTO_TCP; |
4e3fd7a06 net: remove ipv6_... |
472 473 |
fl6.daddr = treq->rmt_addr; fl6.saddr = treq->loc_addr; |
4c9483b2f ipv6: Convert to ... |
474 475 476 |
fl6.flowlabel = 0; fl6.flowi6_oif = treq->iif; fl6.flowi6_mark = sk->sk_mark; |
1958b856c net: Put fl6_* ma... |
477 478 |
fl6.fl6_dport = inet_rsk(req)->rmt_port; fl6.fl6_sport = inet_rsk(req)->loc_port; |
4c9483b2f ipv6: Convert to ... |
479 |
security_req_classify_flow(req, flowi6_to_flowi(&fl6)); |
1da177e4c Linux-2.6.12-rc2 |
480 |
|
fd80eb942 [INET]: Remove st... |
481 |
opt = np->opt; |
4c9483b2f ipv6: Convert to ... |
482 |
final_p = fl6_update_dst(&fl6, opt, &final); |
1da177e4c Linux-2.6.12-rc2 |
483 |
|
4c9483b2f ipv6: Convert to ... |
484 |
dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); |
68d0c6d34 ipv6: Consolidate... |
485 486 |
if (IS_ERR(dst)) { err = PTR_ERR(dst); |
738faca34 ipv6: Don't pass ... |
487 |
dst = NULL; |
fd80eb942 [INET]: Remove st... |
488 |
goto done; |
68d0c6d34 ipv6: Consolidate... |
489 |
} |
e6b4d1136 TCPCT part 1a: ad... |
490 |
skb = tcp_make_synack(sk, dst, req, rvp); |
68d0c6d34 ipv6: Consolidate... |
491 |
err = -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
492 |
if (skb) { |
8ad50d96d tcp: Handle CHECK... |
493 |
__tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr); |
1da177e4c Linux-2.6.12-rc2 |
494 |
|
4e3fd7a06 net: remove ipv6_... |
495 |
fl6.daddr = treq->rmt_addr; |
b903d324b ipv6: tcp: fix TC... |
496 |
err = ip6_xmit(sk, skb, &fl6, opt, np->tclass); |
b9df3cb8c [TCP/DCCP]: Intro... |
497 |
err = net_xmit_eval(err); |
1da177e4c Linux-2.6.12-rc2 |
498 499 500 |
} done: |
1ab1457c4 [NET] IPV6: Fix w... |
501 |
if (opt && opt != np->opt) |
1da177e4c Linux-2.6.12-rc2 |
502 |
sock_kfree_s(sk, opt, opt->tot_len); |
78b910429 [IPV6] tcp_v6_sen... |
503 |
dst_release(dst); |
1da177e4c Linux-2.6.12-rc2 |
504 505 |
return err; } |
72659ecce tcp: account SYN-... |
506 507 508 509 510 511 |
static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req, struct request_values *rvp) { TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS); return tcp_v6_send_synack(sk, req, rvp); } |
60236fdd0 [NET] Rename open... |
512 |
static void tcp_v6_reqsk_destructor(struct request_sock *req) |
1da177e4c Linux-2.6.12-rc2 |
513 |
{ |
800d55f14 ipv6: Remove some... |
514 |
kfree_skb(inet6_rsk(req)->pktopts); |
1da177e4c Linux-2.6.12-rc2 |
515 |
} |
cfb6eeb4c [TCP]: MD5 Signat... |
516 517 |
#ifdef CONFIG_TCP_MD5SIG static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(struct sock *sk, |
b71d1d426 inet: constify ip... |
518 |
const struct in6_addr *addr) |
cfb6eeb4c [TCP]: MD5 Signat... |
519 520 521 522 523 524 525 526 527 528 |
{ struct tcp_sock *tp = tcp_sk(sk); int i; BUG_ON(tp == NULL); if (!tp->md5sig_info || !tp->md5sig_info->entries6) return NULL; for (i = 0; i < tp->md5sig_info->entries6; i++) { |
caad295fe [IPV6]: Use ipv6_... |
529 |
if (ipv6_addr_equal(&tp->md5sig_info->keys6[i].addr, addr)) |
f8ab18d2d [TCP]: Fix MD5 si... |
530 |
return &tp->md5sig_info->keys6[i].base; |
cfb6eeb4c [TCP]: MD5 Signat... |
531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 |
} return NULL; } static struct tcp_md5sig_key *tcp_v6_md5_lookup(struct sock *sk, struct sock *addr_sk) { return tcp_v6_md5_do_lookup(sk, &inet6_sk(addr_sk)->daddr); } static struct tcp_md5sig_key *tcp_v6_reqsk_md5_lookup(struct sock *sk, struct request_sock *req) { return tcp_v6_md5_do_lookup(sk, &inet6_rsk(req)->rmt_addr); } |
b71d1d426 inet: constify ip... |
546 |
static int tcp_v6_md5_do_add(struct sock *sk, const struct in6_addr *peer, |
cfb6eeb4c [TCP]: MD5 Signat... |
547 548 549 |
char *newkey, u8 newkeylen) { /* Add key to the list */ |
b0a713e9e [TCP] MD5: Remove... |
550 |
struct tcp_md5sig_key *key; |
cfb6eeb4c [TCP]: MD5 Signat... |
551 552 |
struct tcp_sock *tp = tcp_sk(sk); struct tcp6_md5sig_key *keys; |
b0a713e9e [TCP] MD5: Remove... |
553 |
key = tcp_v6_md5_do_lookup(sk, peer); |
cfb6eeb4c [TCP]: MD5 Signat... |
554 555 |
if (key) { /* modify existing entry - just update that one */ |
b0a713e9e [TCP] MD5: Remove... |
556 557 558 |
kfree(key->key); key->key = newkey; key->keylen = newkeylen; |
cfb6eeb4c [TCP]: MD5 Signat... |
559 560 561 562 563 564 565 566 |
} else { /* reallocate new list if current one is full. */ if (!tp->md5sig_info) { tp->md5sig_info = kzalloc(sizeof(*tp->md5sig_info), GFP_ATOMIC); if (!tp->md5sig_info) { kfree(newkey); return -ENOMEM; } |
a465419b1 net: Introduce sk... |
567 |
sk_nocaps_add(sk, NETIF_F_GSO_MASK); |
cfb6eeb4c [TCP]: MD5 Signat... |
568 |
} |
260fcbeb1 tcp: properly han... |
569 570 |
if (tp->md5sig_info->entries6 == 0 && tcp_alloc_md5sig_pool(sk) == NULL) { |
aacbe8c88 [IPV6] TCPMD5: Ch... |
571 572 573 |
kfree(newkey); return -ENOMEM; } |
cfb6eeb4c [TCP]: MD5 Signat... |
574 575 576 577 578 |
if (tp->md5sig_info->alloced6 == tp->md5sig_info->entries6) { keys = kmalloc((sizeof (tp->md5sig_info->keys6[0]) * (tp->md5sig_info->entries6 + 1)), GFP_ATOMIC); if (!keys) { |
cfb6eeb4c [TCP]: MD5 Signat... |
579 |
kfree(newkey); |
260fcbeb1 tcp: properly han... |
580 581 |
if (tp->md5sig_info->entries6 == 0) tcp_free_md5sig_pool(); |
cfb6eeb4c [TCP]: MD5 Signat... |
582 583 584 585 586 587 588 589 590 591 592 593 |
return -ENOMEM; } if (tp->md5sig_info->entries6) memmove(keys, tp->md5sig_info->keys6, (sizeof (tp->md5sig_info->keys6[0]) * tp->md5sig_info->entries6)); kfree(tp->md5sig_info->keys6); tp->md5sig_info->keys6 = keys; tp->md5sig_info->alloced6++; } |
4e3fd7a06 net: remove ipv6_... |
594 |
tp->md5sig_info->keys6[tp->md5sig_info->entries6].addr = *peer; |
f8ab18d2d [TCP]: Fix MD5 si... |
595 596 |
tp->md5sig_info->keys6[tp->md5sig_info->entries6].base.key = newkey; tp->md5sig_info->keys6[tp->md5sig_info->entries6].base.keylen = newkeylen; |
cfb6eeb4c [TCP]: MD5 Signat... |
597 598 599 600 601 602 603 604 605 606 607 608 |
tp->md5sig_info->entries6++; } return 0; } static int tcp_v6_md5_add_func(struct sock *sk, struct sock *addr_sk, u8 *newkey, __u8 newkeylen) { return tcp_v6_md5_do_add(sk, &inet6_sk(addr_sk)->daddr, newkey, newkeylen); } |
b71d1d426 inet: constify ip... |
609 |
static int tcp_v6_md5_do_del(struct sock *sk, const struct in6_addr *peer) |
cfb6eeb4c [TCP]: MD5 Signat... |
610 611 612 613 614 |
{ struct tcp_sock *tp = tcp_sk(sk); int i; for (i = 0; i < tp->md5sig_info->entries6; i++) { |
caad295fe [IPV6]: Use ipv6_... |
615 |
if (ipv6_addr_equal(&tp->md5sig_info->keys6[i].addr, peer)) { |
cfb6eeb4c [TCP]: MD5 Signat... |
616 |
/* Free the key */ |
f8ab18d2d [TCP]: Fix MD5 si... |
617 |
kfree(tp->md5sig_info->keys6[i].base.key); |
cfb6eeb4c [TCP]: MD5 Signat... |
618 619 620 621 622 |
tp->md5sig_info->entries6--; if (tp->md5sig_info->entries6 == 0) { kfree(tp->md5sig_info->keys6); tp->md5sig_info->keys6 = NULL; |
ca983cefd [TCPv6] MD5SIG: E... |
623 |
tp->md5sig_info->alloced6 = 0; |
260fcbeb1 tcp: properly han... |
624 |
tcp_free_md5sig_pool(); |
cfb6eeb4c [TCP]: MD5 Signat... |
625 626 627 628 629 630 631 632 |
} else { /* shrink the database */ if (tp->md5sig_info->entries6 != i) memmove(&tp->md5sig_info->keys6[i], &tp->md5sig_info->keys6[i+1], (tp->md5sig_info->entries6 - i) * sizeof (tp->md5sig_info->keys6[0])); } |
77adefdc9 [IPV6] TCPMD5: Fi... |
633 |
return 0; |
cfb6eeb4c [TCP]: MD5 Signat... |
634 635 636 637 638 639 640 641 642 643 644 645 |
} } return -ENOENT; } static void tcp_v6_clear_md5_list (struct sock *sk) { struct tcp_sock *tp = tcp_sk(sk); int i; if (tp->md5sig_info->entries6) { for (i = 0; i < tp->md5sig_info->entries6; i++) |
f8ab18d2d [TCP]: Fix MD5 si... |
646 |
kfree(tp->md5sig_info->keys6[i].base.key); |
cfb6eeb4c [TCP]: MD5 Signat... |
647 648 649 650 651 652 653 654 655 656 |
tp->md5sig_info->entries6 = 0; tcp_free_md5sig_pool(); } kfree(tp->md5sig_info->keys6); tp->md5sig_info->keys6 = NULL; tp->md5sig_info->alloced6 = 0; if (tp->md5sig_info->entries4) { for (i = 0; i < tp->md5sig_info->entries4; i++) |
f8ab18d2d [TCP]: Fix MD5 si... |
657 |
kfree(tp->md5sig_info->keys4[i].base.key); |
cfb6eeb4c [TCP]: MD5 Signat... |
658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 |
tp->md5sig_info->entries4 = 0; tcp_free_md5sig_pool(); } kfree(tp->md5sig_info->keys4); tp->md5sig_info->keys4 = NULL; tp->md5sig_info->alloced4 = 0; } static int tcp_v6_parse_md5_keys (struct sock *sk, char __user *optval, int optlen) { struct tcp_md5sig cmd; struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&cmd.tcpm_addr; u8 *newkey; if (optlen < sizeof(cmd)) return -EINVAL; if (copy_from_user(&cmd, optval, sizeof(cmd))) return -EFAULT; if (sin6->sin6_family != AF_INET6) return -EINVAL; if (!cmd.tcpm_keylen) { if (!tcp_sk(sk)->md5sig_info) return -ENOENT; |
e773e4faa [IPV6]: Add v4map... |
686 |
if (ipv6_addr_v4mapped(&sin6->sin6_addr)) |
cfb6eeb4c [TCP]: MD5 Signat... |
687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 |
return tcp_v4_md5_do_del(sk, sin6->sin6_addr.s6_addr32[3]); return tcp_v6_md5_do_del(sk, &sin6->sin6_addr); } if (cmd.tcpm_keylen > TCP_MD5SIG_MAXKEYLEN) return -EINVAL; if (!tcp_sk(sk)->md5sig_info) { struct tcp_sock *tp = tcp_sk(sk); struct tcp_md5sig_info *p; p = kzalloc(sizeof(struct tcp_md5sig_info), GFP_KERNEL); if (!p) return -ENOMEM; tp->md5sig_info = p; |
a465419b1 net: Introduce sk... |
703 |
sk_nocaps_add(sk, NETIF_F_GSO_MASK); |
cfb6eeb4c [TCP]: MD5 Signat... |
704 |
} |
af879cc70 [IPV6]: Use kmemdup |
705 |
newkey = kmemdup(cmd.tcpm_key, cmd.tcpm_keylen, GFP_KERNEL); |
cfb6eeb4c [TCP]: MD5 Signat... |
706 707 |
if (!newkey) return -ENOMEM; |
e773e4faa [IPV6]: Add v4map... |
708 |
if (ipv6_addr_v4mapped(&sin6->sin6_addr)) { |
cfb6eeb4c [TCP]: MD5 Signat... |
709 710 711 712 713 |
return tcp_v4_md5_do_add(sk, sin6->sin6_addr.s6_addr32[3], newkey, cmd.tcpm_keylen); } return tcp_v6_md5_do_add(sk, &sin6->sin6_addr, newkey, cmd.tcpm_keylen); } |
49a72dfb8 tcp: Fix MD5 sign... |
714 |
static int tcp_v6_md5_hash_pseudoheader(struct tcp_md5sig_pool *hp, |
b71d1d426 inet: constify ip... |
715 716 |
const struct in6_addr *daddr, const struct in6_addr *saddr, int nbytes) |
cfb6eeb4c [TCP]: MD5 Signat... |
717 |
{ |
cfb6eeb4c [TCP]: MD5 Signat... |
718 |
struct tcp6_pseudohdr *bp; |
49a72dfb8 tcp: Fix MD5 sign... |
719 |
struct scatterlist sg; |
8d26d76dd tcp md5sig: Share... |
720 |
|
cfb6eeb4c [TCP]: MD5 Signat... |
721 |
bp = &hp->md5_blk.ip6; |
cfb6eeb4c [TCP]: MD5 Signat... |
722 |
/* 1. TCP pseudo-header (RFC2460) */ |
4e3fd7a06 net: remove ipv6_... |
723 724 |
bp->saddr = *saddr; bp->daddr = *daddr; |
49a72dfb8 tcp: Fix MD5 sign... |
725 |
bp->protocol = cpu_to_be32(IPPROTO_TCP); |
00b1304c4 tcp: MD5: Fix IPv... |
726 |
bp->len = cpu_to_be32(nbytes); |
cfb6eeb4c [TCP]: MD5 Signat... |
727 |
|
49a72dfb8 tcp: Fix MD5 sign... |
728 729 730 |
sg_init_one(&sg, bp, sizeof(*bp)); return crypto_hash_update(&hp->md5_desc, &sg, sizeof(*bp)); } |
c7da57a18 [TCP]: Fix scatte... |
731 |
|
49a72dfb8 tcp: Fix MD5 sign... |
732 |
static int tcp_v6_md5_hash_hdr(char *md5_hash, struct tcp_md5sig_key *key, |
b71d1d426 inet: constify ip... |
733 |
const struct in6_addr *daddr, struct in6_addr *saddr, |
318cf7aaa tcp: md5: add mor... |
734 |
const struct tcphdr *th) |
49a72dfb8 tcp: Fix MD5 sign... |
735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 |
{ struct tcp_md5sig_pool *hp; struct hash_desc *desc; hp = tcp_get_md5sig_pool(); if (!hp) goto clear_hash_noput; desc = &hp->md5_desc; if (crypto_hash_init(desc)) goto clear_hash; if (tcp_v6_md5_hash_pseudoheader(hp, daddr, saddr, th->doff << 2)) goto clear_hash; if (tcp_md5_hash_header(hp, th)) goto clear_hash; if (tcp_md5_hash_key(hp, key)) goto clear_hash; if (crypto_hash_final(desc, md5_hash)) |
cfb6eeb4c [TCP]: MD5 Signat... |
753 |
goto clear_hash; |
cfb6eeb4c [TCP]: MD5 Signat... |
754 |
|
cfb6eeb4c [TCP]: MD5 Signat... |
755 |
tcp_put_md5sig_pool(); |
cfb6eeb4c [TCP]: MD5 Signat... |
756 |
return 0; |
49a72dfb8 tcp: Fix MD5 sign... |
757 |
|
cfb6eeb4c [TCP]: MD5 Signat... |
758 759 760 761 |
clear_hash: tcp_put_md5sig_pool(); clear_hash_noput: memset(md5_hash, 0, 16); |
49a72dfb8 tcp: Fix MD5 sign... |
762 |
return 1; |
cfb6eeb4c [TCP]: MD5 Signat... |
763 |
} |
49a72dfb8 tcp: Fix MD5 sign... |
764 |
static int tcp_v6_md5_hash_skb(char *md5_hash, struct tcp_md5sig_key *key, |
318cf7aaa tcp: md5: add mor... |
765 766 767 |
const struct sock *sk, const struct request_sock *req, const struct sk_buff *skb) |
cfb6eeb4c [TCP]: MD5 Signat... |
768 |
{ |
b71d1d426 inet: constify ip... |
769 |
const struct in6_addr *saddr, *daddr; |
49a72dfb8 tcp: Fix MD5 sign... |
770 771 |
struct tcp_md5sig_pool *hp; struct hash_desc *desc; |
318cf7aaa tcp: md5: add mor... |
772 |
const struct tcphdr *th = tcp_hdr(skb); |
cfb6eeb4c [TCP]: MD5 Signat... |
773 774 775 776 |
if (sk) { saddr = &inet6_sk(sk)->saddr; daddr = &inet6_sk(sk)->daddr; |
49a72dfb8 tcp: Fix MD5 sign... |
777 |
} else if (req) { |
cfb6eeb4c [TCP]: MD5 Signat... |
778 779 |
saddr = &inet6_rsk(req)->loc_addr; daddr = &inet6_rsk(req)->rmt_addr; |
49a72dfb8 tcp: Fix MD5 sign... |
780 |
} else { |
b71d1d426 inet: constify ip... |
781 |
const struct ipv6hdr *ip6h = ipv6_hdr(skb); |
49a72dfb8 tcp: Fix MD5 sign... |
782 783 |
saddr = &ip6h->saddr; daddr = &ip6h->daddr; |
cfb6eeb4c [TCP]: MD5 Signat... |
784 |
} |
49a72dfb8 tcp: Fix MD5 sign... |
785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 |
hp = tcp_get_md5sig_pool(); if (!hp) goto clear_hash_noput; desc = &hp->md5_desc; if (crypto_hash_init(desc)) goto clear_hash; if (tcp_v6_md5_hash_pseudoheader(hp, daddr, saddr, skb->len)) goto clear_hash; if (tcp_md5_hash_header(hp, th)) 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; if (crypto_hash_final(desc, md5_hash)) 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... |
813 |
} |
318cf7aaa tcp: md5: add mor... |
814 |
static int tcp_v6_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb) |
cfb6eeb4c [TCP]: MD5 Signat... |
815 |
{ |
cf533ea53 tcp: add const qu... |
816 |
const __u8 *hash_location = NULL; |
cfb6eeb4c [TCP]: MD5 Signat... |
817 |
struct tcp_md5sig_key *hash_expected; |
b71d1d426 inet: constify ip... |
818 |
const struct ipv6hdr *ip6h = ipv6_hdr(skb); |
318cf7aaa tcp: md5: add mor... |
819 |
const struct tcphdr *th = tcp_hdr(skb); |
cfb6eeb4c [TCP]: MD5 Signat... |
820 |
int genhash; |
cfb6eeb4c [TCP]: MD5 Signat... |
821 822 823 |
u8 newhash[16]; hash_expected = tcp_v6_md5_do_lookup(sk, &ip6h->saddr); |
7d5d5525b tcp md5sig: Share... |
824 |
hash_location = tcp_parse_md5sig_option(th); |
cfb6eeb4c [TCP]: MD5 Signat... |
825 |
|
785957d3e tcp: MD5: Use MIB... |
826 827 828 829 830 831 |
/* We've parsed the options - do we have a hash? */ if (!hash_expected && !hash_location) return 0; if (hash_expected && !hash_location) { NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPMD5NOTFOUND); |
cfb6eeb4c [TCP]: MD5 Signat... |
832 833 |
return 1; } |
785957d3e tcp: MD5: Use MIB... |
834 835 |
if (!hash_expected && hash_location) { NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPMD5UNEXPECTED); |
cfb6eeb4c [TCP]: MD5 Signat... |
836 837 838 839 |
return 1; } /* check the signature */ |
49a72dfb8 tcp: Fix MD5 sign... |
840 841 842 |
genhash = tcp_v6_md5_hash_skb(newhash, hash_expected, NULL, NULL, skb); |
cfb6eeb4c [TCP]: MD5 Signat... |
843 844 |
if (genhash || memcmp(hash_location, newhash, 16) != 0) { if (net_ratelimit()) { |
5856b606e net/ipv6/tcp_ipv6... |
845 846 |
printk(KERN_INFO "MD5 Hash %s for [%pI6c]:%u->[%pI6c]:%u ", |
cfb6eeb4c [TCP]: MD5 Signat... |
847 |
genhash ? "failed" : "mismatch", |
0c6ce78ab net: replace uses... |
848 849 |
&ip6h->saddr, ntohs(th->source), &ip6h->daddr, ntohs(th->dest)); |
cfb6eeb4c [TCP]: MD5 Signat... |
850 851 852 853 854 855 |
} return 1; } return 0; } #endif |
c6aefafb7 [TCP]: Add IPv6 s... |
856 |
struct request_sock_ops tcp6_request_sock_ops __read_mostly = { |
1da177e4c Linux-2.6.12-rc2 |
857 |
.family = AF_INET6, |
2e6599cb8 [NET] Generalise ... |
858 |
.obj_size = sizeof(struct tcp6_request_sock), |
72659ecce tcp: account SYN-... |
859 |
.rtx_syn_ack = tcp_v6_rtx_synack, |
60236fdd0 [NET] Rename open... |
860 861 |
.send_ack = tcp_v6_reqsk_send_ack, .destructor = tcp_v6_reqsk_destructor, |
72659ecce tcp: account SYN-... |
862 863 |
.send_reset = tcp_v6_send_reset, .syn_ack_timeout = tcp_syn_ack_timeout, |
1da177e4c Linux-2.6.12-rc2 |
864 |
}; |
cfb6eeb4c [TCP]: MD5 Signat... |
865 |
#ifdef CONFIG_TCP_MD5SIG |
b2e4b3deb tcp: MD5 operatio... |
866 |
static const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = { |
cfb6eeb4c [TCP]: MD5 Signat... |
867 |
.md5_lookup = tcp_v6_reqsk_md5_lookup, |
e3afe7b75 tcp: Fix MD5 sign... |
868 |
.calc_md5_hash = tcp_v6_md5_hash_skb, |
cfb6eeb4c [TCP]: MD5 Signat... |
869 |
}; |
b6332e6cf [TCP]: Fix warnin... |
870 |
#endif |
cfb6eeb4c [TCP]: MD5 Signat... |
871 |
|
8ad50d96d tcp: Handle CHECK... |
872 |
static void __tcp_v6_send_check(struct sk_buff *skb, |
b71d1d426 inet: constify ip... |
873 |
const struct in6_addr *saddr, const struct in6_addr *daddr) |
1da177e4c Linux-2.6.12-rc2 |
874 |
{ |
aa8223c7b [SK_BUFF]: Introd... |
875 |
struct tcphdr *th = tcp_hdr(skb); |
1da177e4c Linux-2.6.12-rc2 |
876 |
|
84fa7933a [NET]: Replace CH... |
877 |
if (skb->ip_summed == CHECKSUM_PARTIAL) { |
8ad50d96d tcp: Handle CHECK... |
878 |
th->check = ~tcp_v6_check(skb->len, saddr, daddr, 0); |
663ead3bb [NET]: Use csum_s... |
879 |
skb->csum_start = skb_transport_header(skb) - skb->head; |
ff1dcadb1 [NET]: Split skb-... |
880 |
skb->csum_offset = offsetof(struct tcphdr, check); |
1da177e4c Linux-2.6.12-rc2 |
881 |
} else { |
8ad50d96d tcp: Handle CHECK... |
882 883 884 |
th->check = tcp_v6_check(skb->len, saddr, daddr, csum_partial(th, th->doff << 2, skb->csum)); |
1da177e4c Linux-2.6.12-rc2 |
885 886 |
} } |
bb2962461 inet: Remove unus... |
887 |
static void tcp_v6_send_check(struct sock *sk, struct sk_buff *skb) |
8ad50d96d tcp: Handle CHECK... |
888 889 890 891 892 |
{ struct ipv6_pinfo *np = inet6_sk(sk); __tcp_v6_send_check(skb, &np->saddr, &np->daddr); } |
a430a43d0 [NET] gso: Fix up... |
893 894 |
static int tcp_v6_gso_send_check(struct sk_buff *skb) { |
b71d1d426 inet: constify ip... |
895 |
const struct ipv6hdr *ipv6h; |
a430a43d0 [NET] gso: Fix up... |
896 897 898 899 |
struct tcphdr *th; if (!pskb_may_pull(skb, sizeof(*th))) return -EINVAL; |
0660e03f6 [SK_BUFF]: Introd... |
900 |
ipv6h = ipv6_hdr(skb); |
aa8223c7b [SK_BUFF]: Introd... |
901 |
th = tcp_hdr(skb); |
a430a43d0 [NET] gso: Fix up... |
902 903 |
th->check = 0; |
84fa7933a [NET]: Replace CH... |
904 |
skb->ip_summed = CHECKSUM_PARTIAL; |
8ad50d96d tcp: Handle CHECK... |
905 |
__tcp_v6_send_check(skb, &ipv6h->saddr, &ipv6h->daddr); |
a430a43d0 [NET] gso: Fix up... |
906 907 |
return 0; } |
1da177e4c Linux-2.6.12-rc2 |
908 |
|
369906738 tcp: Unexport TCP... |
909 910 |
static struct sk_buff **tcp6_gro_receive(struct sk_buff **head, struct sk_buff *skb) |
684f21760 tcp6: Add GRO sup... |
911 |
{ |
b71d1d426 inet: constify ip... |
912 |
const struct ipv6hdr *iph = skb_gro_network_header(skb); |
684f21760 tcp6: Add GRO sup... |
913 914 915 |
switch (skb->ip_summed) { case CHECKSUM_COMPLETE: |
86911732d gro: Avoid copyin... |
916 |
if (!tcp_v6_check(skb_gro_len(skb), &iph->saddr, &iph->daddr, |
684f21760 tcp6: Add GRO sup... |
917 918 919 920 921 922 923 924 925 926 927 928 929 |
skb->csum)) { skb->ip_summed = CHECKSUM_UNNECESSARY; break; } /* fall through */ case CHECKSUM_NONE: NAPI_GRO_CB(skb)->flush = 1; return NULL; } return tcp_gro_receive(head, skb); } |
684f21760 tcp6: Add GRO sup... |
930 |
|
369906738 tcp: Unexport TCP... |
931 |
static int tcp6_gro_complete(struct sk_buff *skb) |
684f21760 tcp6: Add GRO sup... |
932 |
{ |
b71d1d426 inet: constify ip... |
933 |
const struct ipv6hdr *iph = ipv6_hdr(skb); |
684f21760 tcp6: Add GRO sup... |
934 935 936 937 938 939 940 941 |
struct tcphdr *th = tcp_hdr(skb); th->check = ~tcp_v6_check(skb->len - skb_transport_offset(skb), &iph->saddr, &iph->daddr, 0); skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; return tcp_gro_complete(skb); } |
684f21760 tcp6: Add GRO sup... |
942 |
|
626e264dd tcpv6: combine tc... |
943 |
static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, |
b903d324b ipv6: tcp: fix TC... |
944 |
u32 ts, struct tcp_md5sig_key *key, int rst, u8 tclass) |
1da177e4c Linux-2.6.12-rc2 |
945 |
{ |
cf533ea53 tcp: add const qu... |
946 947 |
const struct tcphdr *th = tcp_hdr(skb); struct tcphdr *t1; |
1da177e4c Linux-2.6.12-rc2 |
948 |
struct sk_buff *buff; |
4c9483b2f ipv6: Convert to ... |
949 |
struct flowi6 fl6; |
adf30907d net: skb->dst acc... |
950 |
struct net *net = dev_net(skb_dst(skb)->dev); |
e50479927 [NETNS][IPV6] tcp... |
951 |
struct sock *ctl_sk = net->ipv6.tcp_sk; |
77c676da1 tcpv6: trivial fo... |
952 |
unsigned int tot_len = sizeof(struct tcphdr); |
adf30907d net: skb->dst acc... |
953 |
struct dst_entry *dst; |
81ada62d7 tcpv6: convert op... |
954 |
__be32 *topt; |
1da177e4c Linux-2.6.12-rc2 |
955 |
|
626e264dd tcpv6: combine tc... |
956 957 |
if (ts) tot_len += TCPOLEN_TSTAMP_ALIGNED; |
cfb6eeb4c [TCP]: MD5 Signat... |
958 |
#ifdef CONFIG_TCP_MD5SIG |
cfb6eeb4c [TCP]: MD5 Signat... |
959 960 961 |
if (key) tot_len += TCPOLEN_MD5SIG_ALIGNED; #endif |
cfb6eeb4c [TCP]: MD5 Signat... |
962 |
buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + tot_len, |
1da177e4c Linux-2.6.12-rc2 |
963 |
GFP_ATOMIC); |
1ab1457c4 [NET] IPV6: Fix w... |
964 965 |
if (buff == NULL) return; |
1da177e4c Linux-2.6.12-rc2 |
966 |
|
cfb6eeb4c [TCP]: MD5 Signat... |
967 |
skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len); |
1da177e4c Linux-2.6.12-rc2 |
968 |
|
cfb6eeb4c [TCP]: MD5 Signat... |
969 |
t1 = (struct tcphdr *) skb_push(buff, tot_len); |
6651ffc8e ipv6: Fix tcp_v6_... |
970 |
skb_reset_transport_header(buff); |
1da177e4c Linux-2.6.12-rc2 |
971 972 973 974 975 |
/* Swap the send and the receive. */ memset(t1, 0, sizeof(*t1)); t1->dest = th->source; t1->source = th->dest; |
cfb6eeb4c [TCP]: MD5 Signat... |
976 |
t1->doff = tot_len / 4; |
626e264dd tcpv6: combine tc... |
977 978 979 980 981 |
t1->seq = htonl(seq); t1->ack_seq = htonl(ack); t1->ack = !rst || !th->ack; t1->rst = rst; t1->window = htons(win); |
1da177e4c Linux-2.6.12-rc2 |
982 |
|
81ada62d7 tcpv6: convert op... |
983 |
topt = (__be32 *)(t1 + 1); |
626e264dd tcpv6: combine tc... |
984 985 986 987 988 989 |
if (ts) { *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); *topt++ = htonl(tcp_time_stamp); *topt++ = htonl(ts); } |
cfb6eeb4c [TCP]: MD5 Signat... |
990 991 |
#ifdef CONFIG_TCP_MD5SIG if (key) { |
81ada62d7 tcpv6: convert op... |
992 993 994 |
*topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | (TCPOPT_MD5SIG << 8) | TCPOLEN_MD5SIG); tcp_v6_md5_hash_hdr((__u8 *)topt, key, |
78e645cb8 tcpv[46]: fix md5... |
995 996 |
&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, t1); |
cfb6eeb4c [TCP]: MD5 Signat... |
997 998 |
} #endif |
4c9483b2f ipv6: Convert to ... |
999 |
memset(&fl6, 0, sizeof(fl6)); |
4e3fd7a06 net: remove ipv6_... |
1000 1001 |
fl6.daddr = ipv6_hdr(skb)->saddr; fl6.saddr = ipv6_hdr(skb)->daddr; |
1da177e4c Linux-2.6.12-rc2 |
1002 |
|
e5700aff1 tcp: Mark v6 resp... |
1003 1004 |
buff->ip_summed = CHECKSUM_PARTIAL; buff->csum = 0; |
4c9483b2f ipv6: Convert to ... |
1005 |
__tcp_v6_send_check(buff, &fl6.saddr, &fl6.daddr); |
1da177e4c Linux-2.6.12-rc2 |
1006 |
|
4c9483b2f ipv6: Convert to ... |
1007 1008 |
fl6.flowi6_proto = IPPROTO_TCP; fl6.flowi6_oif = inet6_iif(skb); |
1958b856c net: Put fl6_* ma... |
1009 1010 |
fl6.fl6_dport = t1->dest; fl6.fl6_sport = t1->source; |
4c9483b2f ipv6: Convert to ... |
1011 |
security_skb_classify_flow(skb, flowi6_to_flowi(&fl6)); |
1da177e4c Linux-2.6.12-rc2 |
1012 |
|
c20121ae8 [NETNS][IPV6] rou... |
1013 1014 1015 1016 |
/* Pass a socket to ip6_dst_lookup either it is for RST * Underlying function will use this to retrieve the network * namespace */ |
4c9483b2f ipv6: Convert to ... |
1017 |
dst = ip6_dst_lookup_flow(ctl_sk, &fl6, NULL, false); |
68d0c6d34 ipv6: Consolidate... |
1018 1019 |
if (!IS_ERR(dst)) { skb_dst_set(buff, dst); |
b903d324b ipv6: tcp: fix TC... |
1020 |
ip6_xmit(ctl_sk, buff, &fl6, NULL, tclass); |
68d0c6d34 ipv6: Consolidate... |
1021 1022 1023 1024 |
TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS); if (rst) TCP_INC_STATS_BH(net, TCP_MIB_OUTRSTS); return; |
1da177e4c Linux-2.6.12-rc2 |
1025 1026 1027 1028 |
} kfree_skb(buff); } |
626e264dd tcpv6: combine tc... |
1029 |
static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb) |
1da177e4c Linux-2.6.12-rc2 |
1030 |
{ |
cf533ea53 tcp: add const qu... |
1031 |
const struct tcphdr *th = tcp_hdr(skb); |
626e264dd tcpv6: combine tc... |
1032 |
u32 seq = 0, ack_seq = 0; |
fa3e5b4eb tcpv6: fix error ... |
1033 |
struct tcp_md5sig_key *key = NULL; |
1da177e4c Linux-2.6.12-rc2 |
1034 |
|
626e264dd tcpv6: combine tc... |
1035 |
if (th->rst) |
1da177e4c Linux-2.6.12-rc2 |
1036 |
return; |
626e264dd tcpv6: combine tc... |
1037 1038 |
if (!ipv6_unicast_destination(skb)) return; |
1da177e4c Linux-2.6.12-rc2 |
1039 |
|
cfb6eeb4c [TCP]: MD5 Signat... |
1040 |
#ifdef CONFIG_TCP_MD5SIG |
626e264dd tcpv6: combine tc... |
1041 1042 |
if (sk) key = tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr); |
cfb6eeb4c [TCP]: MD5 Signat... |
1043 |
#endif |
626e264dd tcpv6: combine tc... |
1044 1045 1046 1047 1048 |
if (th->ack) seq = ntohl(th->ack_seq); else ack_seq = ntohl(th->seq) + th->syn + th->fin + skb->len - (th->doff << 2); |
1da177e4c Linux-2.6.12-rc2 |
1049 |
|
b903d324b ipv6: tcp: fix TC... |
1050 |
tcp_v6_send_response(skb, seq, ack_seq, 0, 0, key, 1, 0); |
626e264dd tcpv6: combine tc... |
1051 |
} |
1da177e4c Linux-2.6.12-rc2 |
1052 |
|
626e264dd tcpv6: combine tc... |
1053 |
static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts, |
b903d324b ipv6: tcp: fix TC... |
1054 |
struct tcp_md5sig_key *key, u8 tclass) |
626e264dd tcpv6: combine tc... |
1055 |
{ |
b903d324b ipv6: tcp: fix TC... |
1056 |
tcp_v6_send_response(skb, seq, ack, win, ts, key, 0, tclass); |
1da177e4c Linux-2.6.12-rc2 |
1057 1058 1059 1060 |
} static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) { |
8feaf0c0a [INET]: Generalis... |
1061 |
struct inet_timewait_sock *tw = inet_twsk(sk); |
cfb6eeb4c [TCP]: MD5 Signat... |
1062 |
struct tcp_timewait_sock *tcptw = tcp_twsk(sk); |
1da177e4c Linux-2.6.12-rc2 |
1063 |
|
9501f9722 tcp md5sig: Let t... |
1064 |
tcp_v6_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, |
8feaf0c0a [INET]: Generalis... |
1065 |
tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, |
b903d324b ipv6: tcp: fix TC... |
1066 1067 |
tcptw->tw_ts_recent, tcp_twsk_md5_key(tcptw), tw->tw_tclass); |
1da177e4c Linux-2.6.12-rc2 |
1068 |
|
8feaf0c0a [INET]: Generalis... |
1069 |
inet_twsk_put(tw); |
1da177e4c Linux-2.6.12-rc2 |
1070 |
} |
6edafaaf6 tcp: Fix kernel p... |
1071 1072 |
static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb, struct request_sock *req) |
1da177e4c Linux-2.6.12-rc2 |
1073 |
{ |
9501f9722 tcp md5sig: Let t... |
1074 |
tcp_v6_send_ack(skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent, |
b903d324b ipv6: tcp: fix TC... |
1075 |
tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr), 0); |
1da177e4c Linux-2.6.12-rc2 |
1076 1077 1078 1079 1080 |
} static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb) { |
60236fdd0 [NET] Rename open... |
1081 |
struct request_sock *req, **prev; |
aa8223c7b [SK_BUFF]: Introd... |
1082 |
const struct tcphdr *th = tcp_hdr(skb); |
1da177e4c Linux-2.6.12-rc2 |
1083 1084 1085 |
struct sock *nsk; /* Find possible connection requests. */ |
8129765ac [IPV6]: Generalis... |
1086 |
req = inet6_csk_search_req(sk, &prev, th->source, |
0660e03f6 [SK_BUFF]: Introd... |
1087 1088 |
&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, inet6_iif(skb)); |
1da177e4c Linux-2.6.12-rc2 |
1089 1090 |
if (req) return tcp_check_req(sk, skb, req, prev); |
3b1e0a655 [NET] NETNS: Omit... |
1091 |
nsk = __inet6_lookup_established(sock_net(sk), &tcp_hashinfo, |
d86e0dac2 [NETNS]: Tcp-v6 s... |
1092 1093 |
&ipv6_hdr(skb)->saddr, th->source, &ipv6_hdr(skb)->daddr, ntohs(th->dest), inet6_iif(skb)); |
1da177e4c Linux-2.6.12-rc2 |
1094 1095 1096 1097 1098 1099 |
if (nsk) { if (nsk->sk_state != TCP_TIME_WAIT) { bh_lock_sock(nsk); return nsk; } |
9469c7b4a [NET]: Use typesa... |
1100 |
inet_twsk_put(inet_twsk(nsk)); |
1da177e4c Linux-2.6.12-rc2 |
1101 1102 |
return NULL; } |
c6aefafb7 [TCP]: Add IPv6 s... |
1103 |
#ifdef CONFIG_SYN_COOKIES |
af9b47385 syncookies: avoid... |
1104 |
if (!th->syn) |
c6aefafb7 [TCP]: Add IPv6 s... |
1105 |
sk = cookie_v6_check(sk, skb); |
1da177e4c Linux-2.6.12-rc2 |
1106 1107 1108 |
#endif return sk; } |
1da177e4c Linux-2.6.12-rc2 |
1109 1110 1111 1112 1113 |
/* FIXME: this is substantially similar to the ipv4 code. * Can some kind of merge be done? -- erics */ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) { |
4957faade TCPCT part 1g: Re... |
1114 |
struct tcp_extend_values tmp_ext; |
e6b4d1136 TCPCT part 1a: ad... |
1115 |
struct tcp_options_received tmp_opt; |
cf533ea53 tcp: add const qu... |
1116 |
const u8 *hash_location; |
e6b4d1136 TCPCT part 1a: ad... |
1117 |
struct request_sock *req; |
ca304b610 [IPV6]: Introduce... |
1118 |
struct inet6_request_sock *treq; |
1da177e4c Linux-2.6.12-rc2 |
1119 |
struct ipv6_pinfo *np = inet6_sk(sk); |
1da177e4c Linux-2.6.12-rc2 |
1120 |
struct tcp_sock *tp = tcp_sk(sk); |
e6b4d1136 TCPCT part 1a: ad... |
1121 |
__u32 isn = TCP_SKB_CB(skb)->when; |
493f377d6 tcp: Add timewait... |
1122 |
struct dst_entry *dst = NULL; |
c6aefafb7 [TCP]: Add IPv6 s... |
1123 |
int want_cookie = 0; |
1da177e4c Linux-2.6.12-rc2 |
1124 1125 1126 1127 1128 |
if (skb->protocol == htons(ETH_P_IP)) return tcp_v4_conn_request(sk, skb); if (!ipv6_unicast_destination(skb)) |
1ab1457c4 [NET] IPV6: Fix w... |
1129 |
goto drop; |
1da177e4c Linux-2.6.12-rc2 |
1130 |
|
463c84b97 [NET]: Introduce ... |
1131 |
if (inet_csk_reqsk_queue_is_full(sk) && !isn) { |
946cedccb tcp: Change possi... |
1132 1133 1134 |
want_cookie = tcp_syn_flood_action(sk, skb, "TCPv6"); if (!want_cookie) goto drop; |
1da177e4c Linux-2.6.12-rc2 |
1135 |
} |
463c84b97 [NET]: Introduce ... |
1136 |
if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) |
1da177e4c Linux-2.6.12-rc2 |
1137 |
goto drop; |
ca304b610 [IPV6]: Introduce... |
1138 |
req = inet6_reqsk_alloc(&tcp6_request_sock_ops); |
1da177e4c Linux-2.6.12-rc2 |
1139 1140 |
if (req == NULL) goto drop; |
cfb6eeb4c [TCP]: MD5 Signat... |
1141 1142 1143 |
#ifdef CONFIG_TCP_MD5SIG tcp_rsk(req)->af_specific = &tcp_request_sock_ipv6_ops; #endif |
1da177e4c Linux-2.6.12-rc2 |
1144 1145 1146 |
tcp_clear_options(&tmp_opt); tmp_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); tmp_opt.user_mss = tp->rx_opt.user_mss; |
bb5b7c112 tcp: Revert per-r... |
1147 |
tcp_parse_options(skb, &tmp_opt, &hash_location, 0); |
4957faade TCPCT part 1g: Re... |
1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 |
if (tmp_opt.cookie_plus > 0 && tmp_opt.saw_tstamp && !tp->rx_opt.cookie_out_never && (sysctl_tcp_cookie_size > 0 || (tp->cookie_values != NULL && tp->cookie_values->cookie_desired > 0))) { u8 *c; u32 *d; u32 *mess = &tmp_ext.cookie_bakery[COOKIE_DIGEST_WORDS]; int l = tmp_opt.cookie_plus - TCPOLEN_COOKIE_BASE; if (tcp_cookie_generator(&tmp_ext.cookie_bakery[0]) != 0) goto drop_and_free; /* Secret recipe starts with IP addresses */ |
0eae88f31 net: Fix various ... |
1164 |
d = (__force u32 *)&ipv6_hdr(skb)->daddr.s6_addr32[0]; |
4957faade TCPCT part 1g: Re... |
1165 1166 1167 1168 |
*mess++ ^= *d++; *mess++ ^= *d++; *mess++ ^= *d++; *mess++ ^= *d++; |
0eae88f31 net: Fix various ... |
1169 |
d = (__force u32 *)&ipv6_hdr(skb)->saddr.s6_addr32[0]; |
4957faade TCPCT part 1g: Re... |
1170 1171 1172 1173 1174 1175 1176 1177 1178 |
*mess++ ^= *d++; *mess++ ^= *d++; *mess++ ^= *d++; *mess++ ^= *d++; /* plus variable length Initiator Cookie */ c = (u8 *)mess; while (l-- > 0) *c++ ^= *hash_location++; |
1da177e4c Linux-2.6.12-rc2 |
1179 |
|
4957faade TCPCT part 1g: Re... |
1180 |
want_cookie = 0; /* not our kind of cookie */ |
4957faade TCPCT part 1g: Re... |
1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 |
tmp_ext.cookie_out_never = 0; /* false */ tmp_ext.cookie_plus = tmp_opt.cookie_plus; } else if (!tp->rx_opt.cookie_in_always) { /* redundant indications, but ensure initialization. */ tmp_ext.cookie_out_never = 1; /* true */ tmp_ext.cookie_plus = 0; } else { goto drop_and_free; } tmp_ext.cookie_in_always = tp->rx_opt.cookie_in_always; |
1da177e4c Linux-2.6.12-rc2 |
1191 |
|
4dfc28170 [Syncookies]: Add... |
1192 |
if (want_cookie && !tmp_opt.saw_tstamp) |
c6aefafb7 [TCP]: Add IPv6 s... |
1193 |
tcp_clear_options(&tmp_opt); |
c6aefafb7 [TCP]: Add IPv6 s... |
1194 |
|
1da177e4c Linux-2.6.12-rc2 |
1195 1196 |
tmp_opt.tstamp_ok = tmp_opt.saw_tstamp; tcp_openreq_init(req, &tmp_opt, skb); |
ca304b610 [IPV6]: Introduce... |
1197 |
treq = inet6_rsk(req); |
4e3fd7a06 net: remove ipv6_... |
1198 1199 |
treq->rmt_addr = ipv6_hdr(skb)->saddr; treq->loc_addr = ipv6_hdr(skb)->daddr; |
172d69e63 syncookies: add s... |
1200 |
if (!want_cookie || tmp_opt.tstamp_ok) |
c6aefafb7 [TCP]: Add IPv6 s... |
1201 |
TCP_ECN_create_request(req, tcp_hdr(skb)); |
4d0fe50c7 ipv6: tcp: fix tc... |
1202 1203 1204 1205 1206 1207 |
treq->iif = sk->sk_bound_dev_if; /* So that link locals have meaning */ if (!sk->sk_bound_dev_if && ipv6_addr_type(&treq->rmt_addr) & IPV6_ADDR_LINKLOCAL) treq->iif = inet6_iif(skb); |
2bbdf389a ipv6: syncookies:... |
1208 |
if (!isn) { |
493f377d6 tcp: Add timewait... |
1209 |
struct inet_peer *peer = NULL; |
c6aefafb7 [TCP]: Add IPv6 s... |
1210 1211 1212 1213 1214 1215 |
if (ipv6_opt_accepted(sk, skb) || np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo || np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) { atomic_inc(&skb->users); treq->pktopts = skb; } |
493f377d6 tcp: Add timewait... |
1216 1217 |
if (want_cookie) { |
2bbdf389a ipv6: syncookies:... |
1218 1219 |
isn = cookie_v6_init_sequence(sk, skb, &req->mss); req->cookie_ts = tmp_opt.tstamp_ok; |
493f377d6 tcp: Add timewait... |
1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 |
goto have_isn; } /* VJ's idea. We save last timestamp seen * from the destination in peer table, when entering * state TIME-WAIT, and check against it before * accepting new connection request. * * If "isn" is not zero, this request hit alive * timewait bucket, so that all the necessary checks * are made in the function processing timewait state. */ if (tmp_opt.saw_tstamp && tcp_death_row.sysctl_tw_recycle && (dst = inet6_csk_route_req(sk, req)) != NULL && (peer = rt6_get_peer((struct rt6_info *)dst)) != NULL && |
7a71ed899 inetpeer: Abstrac... |
1236 |
ipv6_addr_equal((struct in6_addr *)peer->daddr.addr.a6, |
493f377d6 tcp: Add timewait... |
1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 |
&treq->rmt_addr)) { inet_peer_refcheck(peer); if ((u32)get_seconds() - peer->tcp_ts_stamp < TCP_PAWS_MSL && (s32)(peer->tcp_ts - req->ts_recent) > TCP_PAWS_WINDOW) { NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSPASSIVEREJECTED); goto drop_and_release; } } /* Kill the following clause, if you dislike this way. */ else if (!sysctl_tcp_syncookies && (sysctl_max_syn_backlog - inet_csk_reqsk_queue_len(sk) < (sysctl_max_syn_backlog >> 2)) && (!peer || !peer->tcp_ts_stamp) && (!dst || !dst_metric(dst, RTAX_RTT))) { /* Without syncookies last quarter of * backlog is filled with destinations, * proven to be alive. * It means that we continue to communicate * to destinations, already remembered * to the moment of synflood. */ LIMIT_NETDEBUG(KERN_DEBUG "TCP: drop open request from %pI6/%u ", &treq->rmt_addr, ntohs(tcp_hdr(skb)->source)); goto drop_and_release; |
2bbdf389a ipv6: syncookies:... |
1263 |
} |
493f377d6 tcp: Add timewait... |
1264 1265 |
isn = tcp_v6_init_sequence(skb); |
c6aefafb7 [TCP]: Add IPv6 s... |
1266 |
} |
493f377d6 tcp: Add timewait... |
1267 |
have_isn: |
2e6599cb8 [NET] Generalise ... |
1268 |
tcp_rsk(req)->snt_isn = isn; |
9ad7c049f tcp: RFC2988bis +... |
1269 |
tcp_rsk(req)->snt_synack = tcp_time_stamp; |
1da177e4c Linux-2.6.12-rc2 |
1270 |
|
4237c75c0 [MLSXFRM]: Auto-l... |
1271 |
security_inet_conn_request(sk, skb, req); |
4957faade TCPCT part 1g: Re... |
1272 1273 1274 |
if (tcp_v6_send_synack(sk, req, (struct request_values *)&tmp_ext) || want_cookie) |
e6b4d1136 TCPCT part 1a: ad... |
1275 |
goto drop_and_free; |
1da177e4c Linux-2.6.12-rc2 |
1276 |
|
e6b4d1136 TCPCT part 1a: ad... |
1277 1278 |
inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT); return 0; |
1da177e4c Linux-2.6.12-rc2 |
1279 |
|
493f377d6 tcp: Add timewait... |
1280 1281 |
drop_and_release: dst_release(dst); |
e6b4d1136 TCPCT part 1a: ad... |
1282 1283 |
drop_and_free: reqsk_free(req); |
1da177e4c Linux-2.6.12-rc2 |
1284 |
drop: |
1da177e4c Linux-2.6.12-rc2 |
1285 1286 1287 1288 |
return 0; /* don't send reset */ } static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, |
60236fdd0 [NET] Rename open... |
1289 |
struct request_sock *req, |
1da177e4c Linux-2.6.12-rc2 |
1290 1291 |
struct dst_entry *dst) { |
78d15e827 tcp_ipv6: fix use... |
1292 |
struct inet6_request_sock *treq; |
1da177e4c Linux-2.6.12-rc2 |
1293 1294 1295 1296 1297 1298 |
struct ipv6_pinfo *newnp, *np = inet6_sk(sk); struct tcp6_sock *newtcp6sk; struct inet_sock *newinet; struct tcp_sock *newtp; struct sock *newsk; struct ipv6_txoptions *opt; |
cfb6eeb4c [TCP]: MD5 Signat... |
1299 1300 1301 |
#ifdef CONFIG_TCP_MD5SIG struct tcp_md5sig_key *key; #endif |
1da177e4c Linux-2.6.12-rc2 |
1302 1303 1304 1305 1306 1307 1308 |
if (skb->protocol == htons(ETH_P_IP)) { /* * v6 mapped */ newsk = tcp_v4_syn_recv_sock(sk, skb, req, dst); |
1ab1457c4 [NET] IPV6: Fix w... |
1309 |
if (newsk == NULL) |
1da177e4c Linux-2.6.12-rc2 |
1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 |
return NULL; newtcp6sk = (struct tcp6_sock *)newsk; inet_sk(newsk)->pinet6 = &newtcp6sk->inet6; newinet = inet_sk(newsk); newnp = inet6_sk(newsk); newtp = tcp_sk(newsk); memcpy(newnp, np, sizeof(struct ipv6_pinfo)); |
c720c7e83 inet: rename some... |
1320 |
ipv6_addr_set_v4mapped(newinet->inet_daddr, &newnp->daddr); |
1da177e4c Linux-2.6.12-rc2 |
1321 |
|
c720c7e83 inet: rename some... |
1322 |
ipv6_addr_set_v4mapped(newinet->inet_saddr, &newnp->saddr); |
1da177e4c Linux-2.6.12-rc2 |
1323 |
|
4e3fd7a06 net: remove ipv6_... |
1324 |
newnp->rcv_saddr = newnp->saddr; |
1da177e4c Linux-2.6.12-rc2 |
1325 |
|
8292a17a3 [ICSK]: Rename st... |
1326 |
inet_csk(newsk)->icsk_af_ops = &ipv6_mapped; |
1da177e4c Linux-2.6.12-rc2 |
1327 |
newsk->sk_backlog_rcv = tcp_v4_do_rcv; |
cfb6eeb4c [TCP]: MD5 Signat... |
1328 1329 1330 |
#ifdef CONFIG_TCP_MD5SIG newtp->af_specific = &tcp_sock_ipv6_mapped_specific; #endif |
676a1184e ipv6: nullify ipv... |
1331 1332 |
newnp->ipv6_ac_list = NULL; newnp->ipv6_fl_list = NULL; |
1da177e4c Linux-2.6.12-rc2 |
1333 1334 |
newnp->pktoptions = NULL; newnp->opt = NULL; |
505cbfc57 [IPV6]: Generalis... |
1335 |
newnp->mcast_oif = inet6_iif(skb); |
0660e03f6 [SK_BUFF]: Introd... |
1336 |
newnp->mcast_hops = ipv6_hdr(skb)->hop_limit; |
1da177e4c Linux-2.6.12-rc2 |
1337 |
|
e6848976b [NET]: Cleanup IN... |
1338 1339 1340 1341 |
/* * No need to charge this sock to the relevant IPv6 refcnt debug socks count * here, tcp_create_openreq_child now does this for us, see the comment in * that function for the gory details. -acme |
1da177e4c Linux-2.6.12-rc2 |
1342 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
1343 1344 |
/* It is tricky place. Until this moment IPv4 tcp |
8292a17a3 [ICSK]: Rename st... |
1345 |
worked with IPv6 icsk.icsk_af_ops. |
1da177e4c Linux-2.6.12-rc2 |
1346 1347 |
Sync it now. */ |
d83d8461f [IP_SOCKGLUE]: Re... |
1348 |
tcp_sync_mss(newsk, inet_csk(newsk)->icsk_pmtu_cookie); |
1da177e4c Linux-2.6.12-rc2 |
1349 1350 1351 |
return newsk; } |
78d15e827 tcp_ipv6: fix use... |
1352 |
treq = inet6_rsk(req); |
1da177e4c Linux-2.6.12-rc2 |
1353 1354 1355 1356 |
opt = np->opt; if (sk_acceptq_is_full(sk)) goto out_overflow; |
493f377d6 tcp: Add timewait... |
1357 1358 1359 |
if (!dst) { dst = inet6_csk_route_req(sk, req); if (!dst) |
1da177e4c Linux-2.6.12-rc2 |
1360 |
goto out; |
1ab1457c4 [NET] IPV6: Fix w... |
1361 |
} |
1da177e4c Linux-2.6.12-rc2 |
1362 1363 1364 |
newsk = tcp_create_openreq_child(sk, req, skb); if (newsk == NULL) |
093d28232 tproxy: fix hash ... |
1365 |
goto out_nonewsk; |
1da177e4c Linux-2.6.12-rc2 |
1366 |
|
e6848976b [NET]: Cleanup IN... |
1367 1368 1369 1370 1371 |
/* * No need to charge this sock to the relevant IPv6 refcnt debug socks * count here, tcp_create_openreq_child now does this for us, see the * comment in that function for the gory details. -acme */ |
1da177e4c Linux-2.6.12-rc2 |
1372 |
|
59eed279c [IPV6]: Segmentat... |
1373 |
newsk->sk_gso_type = SKB_GSO_TCPV6; |
8e1ef0a95 [IPV6]: Cache sou... |
1374 |
__ip6_dst_store(newsk, dst, NULL, NULL); |
1da177e4c Linux-2.6.12-rc2 |
1375 1376 1377 1378 1379 1380 1381 1382 1383 |
newtcp6sk = (struct tcp6_sock *)newsk; inet_sk(newsk)->pinet6 = &newtcp6sk->inet6; newtp = tcp_sk(newsk); newinet = inet_sk(newsk); newnp = inet6_sk(newsk); memcpy(newnp, np, sizeof(struct ipv6_pinfo)); |
4e3fd7a06 net: remove ipv6_... |
1384 1385 1386 |
newnp->daddr = treq->rmt_addr; newnp->saddr = treq->loc_addr; newnp->rcv_saddr = treq->loc_addr; |
2e6599cb8 [NET] Generalise ... |
1387 |
newsk->sk_bound_dev_if = treq->iif; |
1da177e4c Linux-2.6.12-rc2 |
1388 |
|
1ab1457c4 [NET] IPV6: Fix w... |
1389 |
/* Now IPv6 options... |
1da177e4c Linux-2.6.12-rc2 |
1390 1391 1392 |
First: no IPv4 options. */ |
f6d8bd051 inet: add RCU pro... |
1393 |
newinet->inet_opt = NULL; |
676a1184e ipv6: nullify ipv... |
1394 |
newnp->ipv6_ac_list = NULL; |
d35690bed [IPV6]: ipv6_fl_s... |
1395 |
newnp->ipv6_fl_list = NULL; |
1da177e4c Linux-2.6.12-rc2 |
1396 1397 1398 1399 1400 1401 |
/* Clone RX bits */ newnp->rxopt.all = np->rxopt.all; /* Clone pktoptions received with SYN */ newnp->pktoptions = NULL; |
2e6599cb8 [NET] Generalise ... |
1402 1403 1404 1405 |
if (treq->pktopts != NULL) { newnp->pktoptions = skb_clone(treq->pktopts, GFP_ATOMIC); kfree_skb(treq->pktopts); treq->pktopts = NULL; |
1da177e4c Linux-2.6.12-rc2 |
1406 1407 1408 1409 |
if (newnp->pktoptions) skb_set_owner_r(newnp->pktoptions, newsk); } newnp->opt = NULL; |
505cbfc57 [IPV6]: Generalis... |
1410 |
newnp->mcast_oif = inet6_iif(skb); |
0660e03f6 [SK_BUFF]: Introd... |
1411 |
newnp->mcast_hops = ipv6_hdr(skb)->hop_limit; |
1da177e4c Linux-2.6.12-rc2 |
1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 |
/* Clone native IPv6 options from listening socket (if any) Yes, keeping reference count would be much more clever, but we make one more one thing there: reattach optmem to newsk. */ if (opt) { newnp->opt = ipv6_dup_options(newsk, opt); if (opt != np->opt) sock_kfree_s(sk, opt, opt->tot_len); } |
d83d8461f [IP_SOCKGLUE]: Re... |
1424 |
inet_csk(newsk)->icsk_ext_hdr_len = 0; |
1da177e4c Linux-2.6.12-rc2 |
1425 |
if (newnp->opt) |
d83d8461f [IP_SOCKGLUE]: Re... |
1426 1427 |
inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen + newnp->opt->opt_flen); |
1da177e4c Linux-2.6.12-rc2 |
1428 |
|
5d424d5a6 [TCP]: MTU probing |
1429 |
tcp_mtup_init(newsk); |
1da177e4c Linux-2.6.12-rc2 |
1430 |
tcp_sync_mss(newsk, dst_mtu(dst)); |
0dbaee3b3 net: Abstract def... |
1431 |
newtp->advmss = dst_metric_advmss(dst); |
1da177e4c Linux-2.6.12-rc2 |
1432 |
tcp_initialize_rcv_mss(newsk); |
9ad7c049f tcp: RFC2988bis +... |
1433 1434 1435 1436 |
if (tcp_rsk(req)->snt_synack) tcp_valid_rtt_meas(newsk, tcp_time_stamp - tcp_rsk(req)->snt_synack); newtp->total_retrans = req->retrans; |
1da177e4c Linux-2.6.12-rc2 |
1437 |
|
c720c7e83 inet: rename some... |
1438 1439 |
newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6; newinet->inet_rcv_saddr = LOOPBACK4_IPV6; |
1da177e4c Linux-2.6.12-rc2 |
1440 |
|
cfb6eeb4c [TCP]: MD5 Signat... |
1441 1442 1443 1444 1445 1446 1447 1448 |
#ifdef CONFIG_TCP_MD5SIG /* Copy over the MD5 key from the original socket */ if ((key = tcp_v6_md5_do_lookup(sk, &newnp->daddr)) != NULL) { /* 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. */ |
af879cc70 [IPV6]: Use kmemdup |
1449 1450 |
char *newkey = kmemdup(key->key, key->keylen, GFP_ATOMIC); if (newkey != NULL) |
e547bc1ec tcp: Use correct ... |
1451 |
tcp_v6_md5_do_add(newsk, &newnp->daddr, |
cfb6eeb4c [TCP]: MD5 Signat... |
1452 |
newkey, key->keylen); |
cfb6eeb4c [TCP]: MD5 Signat... |
1453 1454 |
} #endif |
093d28232 tproxy: fix hash ... |
1455 1456 1457 1458 |
if (__inet_inherit_port(sk, newsk) < 0) { sock_put(newsk); goto out; } |
9327f7053 tcp: Fix a connec... |
1459 |
__inet6_hash(newsk, NULL); |
1da177e4c Linux-2.6.12-rc2 |
1460 1461 1462 1463 |
return newsk; out_overflow: |
de0744af1 mib: add net to N... |
1464 |
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS); |
093d28232 tproxy: fix hash ... |
1465 |
out_nonewsk: |
1da177e4c Linux-2.6.12-rc2 |
1466 1467 1468 |
if (opt && opt != np->opt) sock_kfree_s(sk, opt, opt->tot_len); dst_release(dst); |
093d28232 tproxy: fix hash ... |
1469 1470 |
out: NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); |
1da177e4c Linux-2.6.12-rc2 |
1471 1472 |
return NULL; } |
b51655b95 [NET]: Annotate _... |
1473 |
static __sum16 tcp_v6_checksum_init(struct sk_buff *skb) |
1da177e4c Linux-2.6.12-rc2 |
1474 |
{ |
84fa7933a [NET]: Replace CH... |
1475 |
if (skb->ip_summed == CHECKSUM_COMPLETE) { |
684f21760 tcp6: Add GRO sup... |
1476 |
if (!tcp_v6_check(skb->len, &ipv6_hdr(skb)->saddr, |
0660e03f6 [SK_BUFF]: Introd... |
1477 |
&ipv6_hdr(skb)->daddr, skb->csum)) { |
fb286bb29 [NET]: Detect har... |
1478 |
skb->ip_summed = CHECKSUM_UNNECESSARY; |
1da177e4c Linux-2.6.12-rc2 |
1479 |
return 0; |
fb286bb29 [NET]: Detect har... |
1480 |
} |
1da177e4c Linux-2.6.12-rc2 |
1481 |
} |
fb286bb29 [NET]: Detect har... |
1482 |
|
684f21760 tcp6: Add GRO sup... |
1483 |
skb->csum = ~csum_unfold(tcp_v6_check(skb->len, |
0660e03f6 [SK_BUFF]: Introd... |
1484 1485 |
&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, 0)); |
fb286bb29 [NET]: Detect har... |
1486 |
|
1da177e4c Linux-2.6.12-rc2 |
1487 |
if (skb->len <= 76) { |
fb286bb29 [NET]: Detect har... |
1488 |
return __skb_checksum_complete(skb); |
1da177e4c Linux-2.6.12-rc2 |
1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 |
} return 0; } /* The socket must have it's spinlock held when we get * here. * * 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. */ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) { struct ipv6_pinfo *np = inet6_sk(sk); struct tcp_sock *tp; struct sk_buff *opt_skb = NULL; /* Imagine: socket is IPv6. IPv4 packet arrives, goes to IPv4 receive handler and backlogged. From backlog it always goes here. Kerboom... Fortunately, tcp_rcv_established and rcv_established handle them correctly, but it is not case with tcp_v6_hnd_req and tcp_v6_send_reset(). --ANK */ if (skb->protocol == htons(ETH_P_IP)) return tcp_v4_do_rcv(sk, skb); |
cfb6eeb4c [TCP]: MD5 Signat... |
1517 1518 1519 1520 |
#ifdef CONFIG_TCP_MD5SIG if (tcp_v6_inbound_md5_hash (sk, skb)) goto discard; #endif |
fda9ef5d6 [NET]: Fix sk->sk... |
1521 |
if (sk_filter(sk, skb)) |
1da177e4c Linux-2.6.12-rc2 |
1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 |
goto discard; /* * socket locking is here for SMP purposes as backlog rcv * is currently called with bh processing disabled. */ /* Do Stevens' IPV6_PKTOPTIONS. Yes, guys, it is the only place in our code, where we may make it not affecting IPv4. The rest of code is protocol independent, and I do not like idea to uglify IPv4. Actually, all the idea behind IPV6_PKTOPTIONS looks not very well thought. For now we latch options, received in the last packet, enqueued by tcp. Feel free to propose better solution. |
1ab1457c4 [NET] IPV6: Fix w... |
1540 |
--ANK (980728) |
1da177e4c Linux-2.6.12-rc2 |
1541 1542 1543 1544 1545 |
*/ if (np->rxopt.all) opt_skb = skb_clone(skb, GFP_ATOMIC); if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */ |
bdeab9919 rps: Add flag to ... |
1546 |
sock_rps_save_rxhash(sk, skb); |
aa8223c7b [SK_BUFF]: Introd... |
1547 |
if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) |
1da177e4c Linux-2.6.12-rc2 |
1548 |
goto reset; |
1da177e4c Linux-2.6.12-rc2 |
1549 1550 1551 1552 |
if (opt_skb) goto ipv6_pktoptions; return 0; } |
ab6a5bb6b [TCP]: Introduce ... |
1553 |
if (skb->len < tcp_hdrlen(skb) || tcp_checksum_complete(skb)) |
1da177e4c Linux-2.6.12-rc2 |
1554 |
goto csum_err; |
1ab1457c4 [NET] IPV6: Fix w... |
1555 |
if (sk->sk_state == TCP_LISTEN) { |
1da177e4c Linux-2.6.12-rc2 |
1556 1557 1558 1559 1560 1561 1562 1563 1564 |
struct sock *nsk = tcp_v6_hnd_req(sk, skb); if (!nsk) goto discard; /* * Queue it on the new socket if the new socket is active, * otherwise we just shortcircuit this and continue with * the new socket.. */ |
1ab1457c4 [NET] IPV6: Fix w... |
1565 |
if(nsk != sk) { |
bdeab9919 rps: Add flag to ... |
1566 |
sock_rps_save_rxhash(nsk, skb); |
1da177e4c Linux-2.6.12-rc2 |
1567 1568 1569 1570 1571 1572 |
if (tcp_child_process(sk, nsk, skb)) goto reset; if (opt_skb) __kfree_skb(opt_skb); return 0; } |
47482f132 ipv6: Enable RFS ... |
1573 |
} else |
bdeab9919 rps: Add flag to ... |
1574 |
sock_rps_save_rxhash(sk, skb); |
1da177e4c Linux-2.6.12-rc2 |
1575 |
|
aa8223c7b [SK_BUFF]: Introd... |
1576 |
if (tcp_rcv_state_process(sk, skb, tcp_hdr(skb), skb->len)) |
1da177e4c Linux-2.6.12-rc2 |
1577 |
goto reset; |
1da177e4c Linux-2.6.12-rc2 |
1578 1579 1580 1581 1582 |
if (opt_skb) goto ipv6_pktoptions; return 0; reset: |
cfb6eeb4c [TCP]: MD5 Signat... |
1583 |
tcp_v6_send_reset(sk, skb); |
1da177e4c Linux-2.6.12-rc2 |
1584 1585 1586 1587 1588 1589 |
discard: if (opt_skb) __kfree_skb(opt_skb); kfree_skb(skb); return 0; csum_err: |
63231bddf mib: add net to T... |
1590 |
TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_INERRS); |
1da177e4c Linux-2.6.12-rc2 |
1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 |
goto discard; ipv6_pktoptions: /* Do you ask, what is it? 1. skb was enqueued by tcp. 2. skb is added to tail of read queue, rather than out of order. 3. socket is not in passive state. 4. Finally, it really contains options, which user wants to receive. */ tp = tcp_sk(sk); if (TCP_SKB_CB(opt_skb)->end_seq == tp->rcv_nxt && !((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) { |
333fad536 [IPV6]: Support s... |
1605 |
if (np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo) |
505cbfc57 [IPV6]: Generalis... |
1606 |
np->mcast_oif = inet6_iif(opt_skb); |
333fad536 [IPV6]: Support s... |
1607 |
if (np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) |
0660e03f6 [SK_BUFF]: Introd... |
1608 |
np->mcast_hops = ipv6_hdr(opt_skb)->hop_limit; |
1da177e4c Linux-2.6.12-rc2 |
1609 1610 1611 1612 1613 1614 1615 1616 |
if (ipv6_opt_accepted(sk, opt_skb)) { skb_set_owner_r(opt_skb, sk); opt_skb = xchg(&np->pktoptions, opt_skb); } else { __kfree_skb(opt_skb); opt_skb = xchg(&np->pktoptions, NULL); } } |
800d55f14 ipv6: Remove some... |
1617 |
kfree_skb(opt_skb); |
1da177e4c Linux-2.6.12-rc2 |
1618 1619 |
return 0; } |
e5bbef20e [IPV6]: Replace s... |
1620 |
static int tcp_v6_rcv(struct sk_buff *skb) |
1da177e4c Linux-2.6.12-rc2 |
1621 |
{ |
cf533ea53 tcp: add const qu... |
1622 |
const struct tcphdr *th; |
b71d1d426 inet: constify ip... |
1623 |
const struct ipv6hdr *hdr; |
1da177e4c Linux-2.6.12-rc2 |
1624 1625 |
struct sock *sk; int ret; |
a86b1e301 inet: prepare str... |
1626 |
struct net *net = dev_net(skb->dev); |
1da177e4c Linux-2.6.12-rc2 |
1627 1628 1629 1630 1631 1632 1633 |
if (skb->pkt_type != PACKET_HOST) goto discard_it; /* * Count it even if it's bad. */ |
63231bddf mib: add net to T... |
1634 |
TCP_INC_STATS_BH(net, TCP_MIB_INSEGS); |
1da177e4c Linux-2.6.12-rc2 |
1635 1636 1637 |
if (!pskb_may_pull(skb, sizeof(struct tcphdr))) goto discard_it; |
aa8223c7b [SK_BUFF]: Introd... |
1638 |
th = tcp_hdr(skb); |
1da177e4c Linux-2.6.12-rc2 |
1639 1640 1641 1642 1643 |
if (th->doff < sizeof(struct tcphdr)/4) goto bad_packet; if (!pskb_may_pull(skb, th->doff*4)) goto discard_it; |
604763722 [NET]: Treat CHEC... |
1644 |
if (!skb_csum_unnecessary(skb) && tcp_v6_checksum_init(skb)) |
1da177e4c Linux-2.6.12-rc2 |
1645 |
goto bad_packet; |
aa8223c7b [SK_BUFF]: Introd... |
1646 |
th = tcp_hdr(skb); |
e802af9ca IPv6: Generic TTL... |
1647 |
hdr = ipv6_hdr(skb); |
1da177e4c Linux-2.6.12-rc2 |
1648 1649 1650 1651 1652 |
TCP_SKB_CB(skb)->seq = ntohl(th->seq); TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + skb->len - th->doff*4); TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); TCP_SKB_CB(skb)->when = 0; |
b82d1bb4f tcp: unalias tcp_... |
1653 |
TCP_SKB_CB(skb)->ip_dsfield = ipv6_get_dsfield(hdr); |
1da177e4c Linux-2.6.12-rc2 |
1654 |
TCP_SKB_CB(skb)->sacked = 0; |
9a1f27c48 inet_hashtables: ... |
1655 |
sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest); |
1da177e4c Linux-2.6.12-rc2 |
1656 1657 1658 1659 1660 1661 |
if (!sk) goto no_tcp_socket; process: if (sk->sk_state == TCP_TIME_WAIT) goto do_time_wait; |
e802af9ca IPv6: Generic TTL... |
1662 1663 1664 1665 |
if (hdr->hop_limit < inet6_sk(sk)->min_hopcount) { NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP); goto discard_and_relse; } |
1da177e4c Linux-2.6.12-rc2 |
1666 1667 |
if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) goto discard_and_relse; |
fda9ef5d6 [NET]: Fix sk->sk... |
1668 |
if (sk_filter(sk, skb)) |
1da177e4c Linux-2.6.12-rc2 |
1669 1670 1671 |
goto discard_and_relse; skb->dev = NULL; |
293b9c425 [IPV6]: bh_lock_s... |
1672 |
bh_lock_sock_nested(sk); |
1da177e4c Linux-2.6.12-rc2 |
1673 1674 |
ret = 0; if (!sock_owned_by_user(sk)) { |
1a2449a87 [I/OAT]: TCP recv... |
1675 |
#ifdef CONFIG_NET_DMA |
1ab1457c4 [NET] IPV6: Fix w... |
1676 |
struct tcp_sock *tp = tcp_sk(sk); |
b4caea8aa [TCP]: Add missin... |
1677 |
if (!tp->ucopy.dma_chan && tp->ucopy.pinned_list) |
f67b45999 net_dma: convert ... |
1678 |
tp->ucopy.dma_chan = dma_find_channel(DMA_MEMCPY); |
1ab1457c4 [NET] IPV6: Fix w... |
1679 1680 1681 |
if (tp->ucopy.dma_chan) ret = tcp_v6_do_rcv(sk, skb); else |
1a2449a87 [I/OAT]: TCP recv... |
1682 1683 1684 1685 1686 |
#endif { if (!tcp_prequeue(sk, skb)) ret = tcp_v6_do_rcv(sk, skb); } |
6cce09f87 tcp: Add SNMP cou... |
1687 |
} else if (unlikely(sk_add_backlog(sk, skb))) { |
6b03a53a5 tcp: use limited ... |
1688 |
bh_unlock_sock(sk); |
6cce09f87 tcp: Add SNMP cou... |
1689 |
NET_INC_STATS_BH(net, LINUX_MIB_TCPBACKLOGDROP); |
6b03a53a5 tcp: use limited ... |
1690 1691 |
goto discard_and_relse; } |
1da177e4c Linux-2.6.12-rc2 |
1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 |
bh_unlock_sock(sk); sock_put(sk); return ret ? -1 : 0; no_tcp_socket: if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) goto discard_it; if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) { bad_packet: |
63231bddf mib: add net to T... |
1703 |
TCP_INC_STATS_BH(net, TCP_MIB_INERRS); |
1da177e4c Linux-2.6.12-rc2 |
1704 |
} else { |
cfb6eeb4c [TCP]: MD5 Signat... |
1705 |
tcp_v6_send_reset(NULL, skb); |
1da177e4c Linux-2.6.12-rc2 |
1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 |
} discard_it: /* * Discard frame */ kfree_skb(skb); return 0; discard_and_relse: sock_put(sk); goto discard_it; do_time_wait: if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { |
9469c7b4a [NET]: Use typesa... |
1723 |
inet_twsk_put(inet_twsk(sk)); |
1da177e4c Linux-2.6.12-rc2 |
1724 1725 1726 1727 |
goto discard_it; } if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) { |
63231bddf mib: add net to T... |
1728 |
TCP_INC_STATS_BH(net, TCP_MIB_INERRS); |
9469c7b4a [NET]: Use typesa... |
1729 |
inet_twsk_put(inet_twsk(sk)); |
1da177e4c Linux-2.6.12-rc2 |
1730 1731 |
goto discard_it; } |
9469c7b4a [NET]: Use typesa... |
1732 |
switch (tcp_timewait_state_process(inet_twsk(sk), skb, th)) { |
1da177e4c Linux-2.6.12-rc2 |
1733 1734 1735 |
case TCP_TW_SYN: { struct sock *sk2; |
c346dca10 [NET] NETNS: Omit... |
1736 |
sk2 = inet6_lookup_listener(dev_net(skb->dev), &tcp_hashinfo, |
0660e03f6 [SK_BUFF]: Introd... |
1737 |
&ipv6_hdr(skb)->daddr, |
505cbfc57 [IPV6]: Generalis... |
1738 |
ntohs(th->dest), inet6_iif(skb)); |
1da177e4c Linux-2.6.12-rc2 |
1739 |
if (sk2 != NULL) { |
295ff7edb [TIMEWAIT]: Intro... |
1740 1741 1742 |
struct inet_timewait_sock *tw = inet_twsk(sk); inet_twsk_deschedule(tw, &tcp_death_row); inet_twsk_put(tw); |
1da177e4c Linux-2.6.12-rc2 |
1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 |
sk = sk2; goto process; } /* Fall through to ACK */ } case TCP_TW_ACK: tcp_v6_timewait_ack(sk, skb); break; case TCP_TW_RST: goto no_tcp_socket; case TCP_TW_SUCCESS:; } goto discard_it; } |
ccb7c410d timewait_sock: Cr... |
1757 1758 |
static struct inet_peer *tcp_v6_get_peer(struct sock *sk, bool *release_it) { |
db3949c45 tcp: Implement ip... |
1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 |
struct rt6_info *rt = (struct rt6_info *) __sk_dst_get(sk); struct ipv6_pinfo *np = inet6_sk(sk); struct inet_peer *peer; if (!rt || !ipv6_addr_equal(&np->daddr, &rt->rt6i_dst.addr)) { peer = inet_getpeer_v6(&np->daddr, 1); *release_it = true; } else { if (!rt->rt6i_peer) rt6_bind_peer(rt, 1); peer = rt->rt6i_peer; |
457de4383 ipv6: Fix 'releas... |
1771 |
*release_it = false; |
db3949c45 tcp: Implement ip... |
1772 1773 1774 |
} return peer; |
ccb7c410d timewait_sock: Cr... |
1775 1776 1777 |
} static void *tcp_v6_tw_get_peer(struct sock *sk) |
1da177e4c Linux-2.6.12-rc2 |
1778 |
{ |
cf533ea53 tcp: add const qu... |
1779 1780 |
const struct inet6_timewait_sock *tw6 = inet6_twsk(sk); const struct inet_timewait_sock *tw = inet_twsk(sk); |
ccb7c410d timewait_sock: Cr... |
1781 1782 1783 |
if (tw->tw_family == AF_INET) return tcp_v4_tw_get_peer(sk); |
db3949c45 tcp: Implement ip... |
1784 |
return inet_getpeer_v6(&tw6->tw_v6_daddr, 1); |
1da177e4c Linux-2.6.12-rc2 |
1785 |
} |
ccb7c410d timewait_sock: Cr... |
1786 1787 1788 1789 1790 1791 |
static struct timewait_sock_ops tcp6_timewait_sock_ops = { .twsk_obj_size = sizeof(struct tcp6_timewait_sock), .twsk_unique = tcp_twsk_unique, .twsk_destructor= tcp_twsk_destructor, .twsk_getpeer = tcp_v6_tw_get_peer, }; |
3b401a81c inet: inet_connec... |
1792 |
static const struct inet_connection_sock_af_ops ipv6_specific = { |
543d9cfee [NET]: Identation... |
1793 1794 1795 1796 1797 |
.queue_xmit = inet6_csk_xmit, .send_check = tcp_v6_send_check, .rebuild_header = inet6_sk_rebuild_header, .conn_request = tcp_v6_conn_request, .syn_recv_sock = tcp_v6_syn_recv_sock, |
3f419d2d4 inet: Turn ->reme... |
1798 |
.get_peer = tcp_v6_get_peer, |
543d9cfee [NET]: Identation... |
1799 1800 1801 1802 1803 |
.net_header_len = sizeof(struct ipv6hdr), .setsockopt = ipv6_setsockopt, .getsockopt = ipv6_getsockopt, .addr2sockaddr = inet6_csk_addr2sockaddr, .sockaddr_len = sizeof(struct sockaddr_in6), |
ab1e0a13d [SOCK] proto: Add... |
1804 |
.bind_conflict = inet6_csk_bind_conflict, |
3fdadf7d2 [NET]: {get|set}s... |
1805 |
#ifdef CONFIG_COMPAT |
543d9cfee [NET]: Identation... |
1806 1807 |
.compat_setsockopt = compat_ipv6_setsockopt, .compat_getsockopt = compat_ipv6_getsockopt, |
3fdadf7d2 [NET]: {get|set}s... |
1808 |
#endif |
1da177e4c Linux-2.6.12-rc2 |
1809 |
}; |
cfb6eeb4c [TCP]: MD5 Signat... |
1810 |
#ifdef CONFIG_TCP_MD5SIG |
b2e4b3deb tcp: MD5 operatio... |
1811 |
static const struct tcp_sock_af_ops tcp_sock_ipv6_specific = { |
cfb6eeb4c [TCP]: MD5 Signat... |
1812 |
.md5_lookup = tcp_v6_md5_lookup, |
49a72dfb8 tcp: Fix MD5 sign... |
1813 |
.calc_md5_hash = tcp_v6_md5_hash_skb, |
cfb6eeb4c [TCP]: MD5 Signat... |
1814 1815 |
.md5_add = tcp_v6_md5_add_func, .md5_parse = tcp_v6_parse_md5_keys, |
cfb6eeb4c [TCP]: MD5 Signat... |
1816 |
}; |
a928630a2 [TCP]: Fix some w... |
1817 |
#endif |
cfb6eeb4c [TCP]: MD5 Signat... |
1818 |
|
1da177e4c Linux-2.6.12-rc2 |
1819 1820 1821 |
/* * TCP over IPv4 via INET6 API */ |
3b401a81c inet: inet_connec... |
1822 |
static const struct inet_connection_sock_af_ops ipv6_mapped = { |
543d9cfee [NET]: Identation... |
1823 1824 1825 1826 1827 |
.queue_xmit = ip_queue_xmit, .send_check = tcp_v4_send_check, .rebuild_header = inet_sk_rebuild_header, .conn_request = tcp_v6_conn_request, .syn_recv_sock = tcp_v6_syn_recv_sock, |
3f419d2d4 inet: Turn ->reme... |
1828 |
.get_peer = tcp_v4_get_peer, |
543d9cfee [NET]: Identation... |
1829 1830 1831 1832 1833 |
.net_header_len = sizeof(struct iphdr), .setsockopt = ipv6_setsockopt, .getsockopt = ipv6_getsockopt, .addr2sockaddr = inet6_csk_addr2sockaddr, .sockaddr_len = sizeof(struct sockaddr_in6), |
ab1e0a13d [SOCK] proto: Add... |
1834 |
.bind_conflict = inet6_csk_bind_conflict, |
3fdadf7d2 [NET]: {get|set}s... |
1835 |
#ifdef CONFIG_COMPAT |
543d9cfee [NET]: Identation... |
1836 1837 |
.compat_setsockopt = compat_ipv6_setsockopt, .compat_getsockopt = compat_ipv6_getsockopt, |
3fdadf7d2 [NET]: {get|set}s... |
1838 |
#endif |
1da177e4c Linux-2.6.12-rc2 |
1839 |
}; |
cfb6eeb4c [TCP]: MD5 Signat... |
1840 |
#ifdef CONFIG_TCP_MD5SIG |
b2e4b3deb tcp: MD5 operatio... |
1841 |
static const struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific = { |
cfb6eeb4c [TCP]: MD5 Signat... |
1842 |
.md5_lookup = tcp_v4_md5_lookup, |
49a72dfb8 tcp: Fix MD5 sign... |
1843 |
.calc_md5_hash = tcp_v4_md5_hash_skb, |
cfb6eeb4c [TCP]: MD5 Signat... |
1844 1845 |
.md5_add = tcp_v6_md5_add_func, .md5_parse = tcp_v6_parse_md5_keys, |
cfb6eeb4c [TCP]: MD5 Signat... |
1846 |
}; |
a928630a2 [TCP]: Fix some w... |
1847 |
#endif |
cfb6eeb4c [TCP]: MD5 Signat... |
1848 |
|
1da177e4c Linux-2.6.12-rc2 |
1849 1850 1851 1852 1853 |
/* NOTE: A lot of things set to zero explicitly by call to * sk_alloc() so need not be done here. */ static int tcp_v6_init_sock(struct sock *sk) { |
6687e988d [ICSK]: Move TCP ... |
1854 |
struct inet_connection_sock *icsk = inet_csk(sk); |
1da177e4c Linux-2.6.12-rc2 |
1855 1856 1857 1858 1859 |
struct tcp_sock *tp = tcp_sk(sk); skb_queue_head_init(&tp->out_of_order_queue); tcp_init_xmit_timers(sk); tcp_prequeue_init(tp); |
6687e988d [ICSK]: Move TCP ... |
1860 |
icsk->icsk_rto = TCP_TIMEOUT_INIT; |
1da177e4c Linux-2.6.12-rc2 |
1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 |
tp->mdev = TCP_TIMEOUT_INIT; /* So many TCP implementations out there (incorrectly) count the * initial SYN frame in their delayed-ACK and congestion control * algorithms that we must have the following bandaid to talk * efficiently to them. -DaveM */ tp->snd_cwnd = 2; /* See draft-stevens-tcpca-spec-01 for discussion of the * initialization of these values. */ |
0b6a05c1d tcp: fix ssthresh... |
1873 |
tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; |
1da177e4c Linux-2.6.12-rc2 |
1874 |
tp->snd_cwnd_clamp = ~0; |
bee7ca9ec net: TCP_MSS_DEFA... |
1875 |
tp->mss_cache = TCP_MSS_DEFAULT; |
1da177e4c Linux-2.6.12-rc2 |
1876 1877 1878 1879 |
tp->reordering = sysctl_tcp_reordering; sk->sk_state = TCP_CLOSE; |
8292a17a3 [ICSK]: Rename st... |
1880 |
icsk->icsk_af_ops = &ipv6_specific; |
6687e988d [ICSK]: Move TCP ... |
1881 |
icsk->icsk_ca_ops = &tcp_init_congestion_ops; |
d83d8461f [IP_SOCKGLUE]: Re... |
1882 |
icsk->icsk_sync_mss = tcp_sync_mss; |
1da177e4c Linux-2.6.12-rc2 |
1883 1884 |
sk->sk_write_space = sk_stream_write_space; sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); |
cfb6eeb4c [TCP]: MD5 Signat... |
1885 1886 1887 |
#ifdef CONFIG_TCP_MD5SIG tp->af_specific = &tcp_sock_ipv6_specific; #endif |
435cf559f TCPCT part 1d: de... |
1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 |
/* TCP Cookie Transactions */ if (sysctl_tcp_cookie_size > 0) { /* Default, cookies without s_data_payload. */ tp->cookie_values = kzalloc(sizeof(*tp->cookie_values), sk->sk_allocation); if (tp->cookie_values != NULL) kref_init(&tp->cookie_values->kref); } /* Presumed zeroed, in order of appearance: * cookie_in_always, cookie_out_never, * s_data_constant, s_data_in, s_data_out */ |
1da177e4c Linux-2.6.12-rc2 |
1901 1902 |
sk->sk_sndbuf = sysctl_tcp_wmem[1]; sk->sk_rcvbuf = sysctl_tcp_rmem[1]; |
eb4dea585 net: Fix percpu c... |
1903 |
local_bh_disable(); |
d1a4c0b37 tcp memory pressu... |
1904 |
sock_update_memcg(sk); |
180d8cd94 foundations of pe... |
1905 |
sk_sockets_allocated_inc(sk); |
eb4dea585 net: Fix percpu c... |
1906 |
local_bh_enable(); |
1da177e4c Linux-2.6.12-rc2 |
1907 1908 1909 |
return 0; } |
7d06b2e05 net: change proto... |
1910 |
static void tcp_v6_destroy_sock(struct sock *sk) |
1da177e4c Linux-2.6.12-rc2 |
1911 |
{ |
cfb6eeb4c [TCP]: MD5 Signat... |
1912 1913 1914 1915 1916 |
#ifdef CONFIG_TCP_MD5SIG /* Clean up the MD5 key list */ if (tcp_sk(sk)->md5sig_info) tcp_v6_clear_md5_list(sk); #endif |
1da177e4c Linux-2.6.12-rc2 |
1917 |
tcp_v4_destroy_sock(sk); |
7d06b2e05 net: change proto... |
1918 |
inet6_destroy_sock(sk); |
1da177e4c Linux-2.6.12-rc2 |
1919 |
} |
952a10be3 [IPV6] SNMP: Fix ... |
1920 |
#ifdef CONFIG_PROC_FS |
1da177e4c Linux-2.6.12-rc2 |
1921 |
/* Proc filesystem TCPv6 sock list dumping. */ |
1ab1457c4 [NET] IPV6: Fix w... |
1922 |
static void get_openreq6(struct seq_file *seq, |
cf533ea53 tcp: add const qu... |
1923 |
const struct sock *sk, struct request_sock *req, int i, int uid) |
1da177e4c Linux-2.6.12-rc2 |
1924 |
{ |
1da177e4c Linux-2.6.12-rc2 |
1925 |
int ttd = req->expires - jiffies; |
b71d1d426 inet: constify ip... |
1926 1927 |
const struct in6_addr *src = &inet6_rsk(req)->loc_addr; const struct in6_addr *dest = &inet6_rsk(req)->rmt_addr; |
1da177e4c Linux-2.6.12-rc2 |
1928 1929 1930 |
if (ttd < 0) ttd = 0; |
1da177e4c Linux-2.6.12-rc2 |
1931 1932 |
seq_printf(seq, "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " |
71338aa7d net: convert %p u... |
1933 1934 |
"%02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %pK ", |
1da177e4c Linux-2.6.12-rc2 |
1935 1936 1937 |
i, src->s6_addr32[0], src->s6_addr32[1], src->s6_addr32[2], src->s6_addr32[3], |
fd5070370 tcp: Fix IPv6 fal... |
1938 |
ntohs(inet_rsk(req)->loc_port), |
1da177e4c Linux-2.6.12-rc2 |
1939 1940 |
dest->s6_addr32[0], dest->s6_addr32[1], dest->s6_addr32[2], dest->s6_addr32[3], |
2e6599cb8 [NET] Generalise ... |
1941 |
ntohs(inet_rsk(req)->rmt_port), |
1da177e4c Linux-2.6.12-rc2 |
1942 1943 |
TCP_SYN_RECV, 0,0, /* could print option size, but that is af dependent. */ |
1ab1457c4 [NET] IPV6: Fix w... |
1944 1945 |
1, /* timers active (only the expire timer) */ jiffies_to_clock_t(ttd), |
1da177e4c Linux-2.6.12-rc2 |
1946 1947 |
req->retrans, uid, |
1ab1457c4 [NET] IPV6: Fix w... |
1948 |
0, /* non standard timer */ |
1da177e4c Linux-2.6.12-rc2 |
1949 1950 1951 1952 1953 1954 |
0, /* open_requests have no inode */ 0, req); } static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i) { |
b71d1d426 inet: constify ip... |
1955 |
const struct in6_addr *dest, *src; |
1da177e4c Linux-2.6.12-rc2 |
1956 1957 1958 |
__u16 destp, srcp; int timer_active; unsigned long timer_expires; |
cf533ea53 tcp: add const qu... |
1959 1960 |
const struct inet_sock *inet = inet_sk(sp); const struct tcp_sock *tp = tcp_sk(sp); |
463c84b97 [NET]: Introduce ... |
1961 |
const struct inet_connection_sock *icsk = inet_csk(sp); |
cf533ea53 tcp: add const qu... |
1962 |
const struct ipv6_pinfo *np = inet6_sk(sp); |
1da177e4c Linux-2.6.12-rc2 |
1963 1964 1965 |
dest = &np->daddr; src = &np->rcv_saddr; |
c720c7e83 inet: rename some... |
1966 1967 |
destp = ntohs(inet->inet_dport); srcp = ntohs(inet->inet_sport); |
463c84b97 [NET]: Introduce ... |
1968 1969 |
if (icsk->icsk_pending == ICSK_TIME_RETRANS) { |
1da177e4c Linux-2.6.12-rc2 |
1970 |
timer_active = 1; |
463c84b97 [NET]: Introduce ... |
1971 1972 |
timer_expires = icsk->icsk_timeout; } else if (icsk->icsk_pending == ICSK_TIME_PROBE0) { |
1da177e4c Linux-2.6.12-rc2 |
1973 |
timer_active = 4; |
463c84b97 [NET]: Introduce ... |
1974 |
timer_expires = icsk->icsk_timeout; |
1da177e4c Linux-2.6.12-rc2 |
1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 |
} else if (timer_pending(&sp->sk_timer)) { timer_active = 2; timer_expires = sp->sk_timer.expires; } else { timer_active = 0; timer_expires = jiffies; } seq_printf(seq, "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " |
71338aa7d net: convert %p u... |
1985 1986 |
"%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %pK %lu %lu %u %u %d ", |
1da177e4c Linux-2.6.12-rc2 |
1987 1988 1989 1990 1991 |
i, src->s6_addr32[0], src->s6_addr32[1], src->s6_addr32[2], src->s6_addr32[3], srcp, dest->s6_addr32[0], dest->s6_addr32[1], dest->s6_addr32[2], dest->s6_addr32[3], destp, |
1ab1457c4 [NET] IPV6: Fix w... |
1992 |
sp->sk_state, |
47da8ee68 [TCP]: Export acc... |
1993 1994 |
tp->write_seq-tp->snd_una, (sp->sk_state == TCP_LISTEN) ? sp->sk_ack_backlog : (tp->rcv_nxt - tp->copied_seq), |
1da177e4c Linux-2.6.12-rc2 |
1995 1996 |
timer_active, jiffies_to_clock_t(timer_expires - jiffies), |
463c84b97 [NET]: Introduce ... |
1997 |
icsk->icsk_retransmits, |
1da177e4c Linux-2.6.12-rc2 |
1998 |
sock_i_uid(sp), |
6687e988d [ICSK]: Move TCP ... |
1999 |
icsk->icsk_probes_out, |
1da177e4c Linux-2.6.12-rc2 |
2000 2001 |
sock_i_ino(sp), atomic_read(&sp->sk_refcnt), sp, |
7be87351a tcp: /proc/net/tc... |
2002 2003 |
jiffies_to_clock_t(icsk->icsk_rto), jiffies_to_clock_t(icsk->icsk_ack.ato), |
463c84b97 [NET]: Introduce ... |
2004 |
(icsk->icsk_ack.quick << 1 ) | icsk->icsk_ack.pingpong, |
0b6a05c1d tcp: fix ssthresh... |
2005 2006 |
tp->snd_cwnd, tcp_in_initial_slowstart(tp) ? -1 : tp->snd_ssthresh |
1da177e4c Linux-2.6.12-rc2 |
2007 2008 |
); } |
1ab1457c4 [NET] IPV6: Fix w... |
2009 |
static void get_timewait6_sock(struct seq_file *seq, |
8feaf0c0a [INET]: Generalis... |
2010 |
struct inet_timewait_sock *tw, int i) |
1da177e4c Linux-2.6.12-rc2 |
2011 |
{ |
b71d1d426 inet: constify ip... |
2012 |
const struct in6_addr *dest, *src; |
1da177e4c Linux-2.6.12-rc2 |
2013 |
__u16 destp, srcp; |
cf533ea53 tcp: add const qu... |
2014 |
const struct inet6_timewait_sock *tw6 = inet6_twsk((struct sock *)tw); |
1da177e4c Linux-2.6.12-rc2 |
2015 2016 2017 2018 |
int ttd = tw->tw_ttd - jiffies; if (ttd < 0) ttd = 0; |
0fa1a53e1 [IPV6]: Introduce... |
2019 2020 |
dest = &tw6->tw_v6_daddr; src = &tw6->tw_v6_rcv_saddr; |
1da177e4c Linux-2.6.12-rc2 |
2021 2022 2023 2024 2025 |
destp = ntohs(tw->tw_dport); srcp = ntohs(tw->tw_sport); seq_printf(seq, "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " |
71338aa7d net: convert %p u... |
2026 2027 |
"%02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %pK ", |
1da177e4c Linux-2.6.12-rc2 |
2028 2029 2030 2031 2032 2033 2034 2035 2036 |
i, src->s6_addr32[0], src->s6_addr32[1], src->s6_addr32[2], src->s6_addr32[3], srcp, dest->s6_addr32[0], dest->s6_addr32[1], dest->s6_addr32[2], dest->s6_addr32[3], destp, tw->tw_substate, 0, 0, 3, jiffies_to_clock_t(ttd), 0, 0, 0, 0, atomic_read(&tw->tw_refcnt), tw); } |
1da177e4c Linux-2.6.12-rc2 |
2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 |
static int tcp6_seq_show(struct seq_file *seq, void *v) { struct tcp_iter_state *st; if (v == SEQ_START_TOKEN) { seq_puts(seq, " sl " "local_address " "remote_address " "st tx_queue rx_queue tr tm->when retrnsmt" " uid timeout inode "); goto out; } st = seq->private; switch (st->state) { case TCP_SEQ_STATE_LISTENING: case TCP_SEQ_STATE_ESTABLISHED: get_tcp6_sock(seq, v, st->num); break; case TCP_SEQ_STATE_OPENREQ: get_openreq6(seq, st->syn_wait_sk, v, st->num, st->uid); break; case TCP_SEQ_STATE_TIME_WAIT: get_timewait6_sock(seq, v, st->num); break; } out: return 0; } |
73cb88ecb net: make the tcp... |
2068 2069 2070 2071 2072 2073 2074 |
static const struct file_operations tcp6_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 |
2075 |
static struct tcp_seq_afinfo tcp6_seq_afinfo = { |
1da177e4c Linux-2.6.12-rc2 |
2076 2077 |
.name = "tcp6", .family = AF_INET6, |
73cb88ecb net: make the tcp... |
2078 |
.seq_fops = &tcp6_afinfo_seq_fops, |
9427c4b36 [TCP]: Move seq_o... |
2079 2080 2081 |
.seq_ops = { .show = tcp6_seq_show, }, |
1da177e4c Linux-2.6.12-rc2 |
2082 |
}; |
2c8c1e729 net: spread __net... |
2083 |
int __net_init tcp6_proc_init(struct net *net) |
1da177e4c Linux-2.6.12-rc2 |
2084 |
{ |
6f8b13bcb [NETNS][IPV6] tcp... |
2085 |
return tcp_proc_register(net, &tcp6_seq_afinfo); |
1da177e4c Linux-2.6.12-rc2 |
2086 |
} |
6f8b13bcb [NETNS][IPV6] tcp... |
2087 |
void tcp6_proc_exit(struct net *net) |
1da177e4c Linux-2.6.12-rc2 |
2088 |
{ |
6f8b13bcb [NETNS][IPV6] tcp... |
2089 |
tcp_proc_unregister(net, &tcp6_seq_afinfo); |
1da177e4c Linux-2.6.12-rc2 |
2090 2091 2092 2093 2094 2095 2096 2097 2098 |
} #endif struct proto tcpv6_prot = { .name = "TCPv6", .owner = THIS_MODULE, .close = tcp_close, .connect = tcp_v6_connect, .disconnect = tcp_disconnect, |
463c84b97 [NET]: Introduce ... |
2099 |
.accept = inet_csk_accept, |
1da177e4c Linux-2.6.12-rc2 |
2100 2101 2102 2103 2104 2105 |
.ioctl = tcp_ioctl, .init = tcp_v6_init_sock, .destroy = tcp_v6_destroy_sock, .shutdown = tcp_shutdown, .setsockopt = tcp_setsockopt, .getsockopt = tcp_getsockopt, |
1da177e4c Linux-2.6.12-rc2 |
2106 |
.recvmsg = tcp_recvmsg, |
7ba429100 inet, inet6: make... |
2107 2108 |
.sendmsg = tcp_sendmsg, .sendpage = tcp_sendpage, |
1da177e4c Linux-2.6.12-rc2 |
2109 2110 |
.backlog_rcv = tcp_v6_do_rcv, .hash = tcp_v6_hash, |
ab1e0a13d [SOCK] proto: Add... |
2111 2112 |
.unhash = inet_unhash, .get_port = inet_csk_get_port, |
1da177e4c Linux-2.6.12-rc2 |
2113 2114 2115 2116 |
.enter_memory_pressure = tcp_enter_memory_pressure, .sockets_allocated = &tcp_sockets_allocated, .memory_allocated = &tcp_memory_allocated, .memory_pressure = &tcp_memory_pressure, |
0a5578cf8 [ICSK]: Generalis... |
2117 |
.orphan_count = &tcp_orphan_count, |
1da177e4c Linux-2.6.12-rc2 |
2118 2119 2120 2121 |
.sysctl_wmem = sysctl_tcp_wmem, .sysctl_rmem = sysctl_tcp_rmem, .max_header = MAX_TCP_HEADER, .obj_size = sizeof(struct tcp6_sock), |
3ab5aee7f net: Convert TCP ... |
2122 |
.slab_flags = SLAB_DESTROY_BY_RCU, |
6d6ee43e0 [TWSK]: Introduce... |
2123 |
.twsk_prot = &tcp6_timewait_sock_ops, |
60236fdd0 [NET] Rename open... |
2124 |
.rsk_prot = &tcp6_request_sock_ops, |
39d8cda76 [SOCK]: Add udp_h... |
2125 |
.h.hashinfo = &tcp_hashinfo, |
7ba429100 inet, inet6: make... |
2126 |
.no_autobind = true, |
543d9cfee [NET]: Identation... |
2127 2128 2129 2130 |
#ifdef CONFIG_COMPAT .compat_setsockopt = compat_tcp_setsockopt, .compat_getsockopt = compat_tcp_getsockopt, #endif |
d1a4c0b37 tcp memory pressu... |
2131 2132 2133 |
#ifdef CONFIG_CGROUP_MEM_RES_CTLR_KMEM .proto_cgroup = tcp_proto_cgroup, #endif |
1da177e4c Linux-2.6.12-rc2 |
2134 |
}; |
41135cc83 net: constify str... |
2135 |
static const struct inet6_protocol tcpv6_protocol = { |
1da177e4c Linux-2.6.12-rc2 |
2136 2137 |
.handler = tcp_v6_rcv, .err_handler = tcp_v6_err, |
a430a43d0 [NET] gso: Fix up... |
2138 |
.gso_send_check = tcp_v6_gso_send_check, |
adcfc7d0b [IPV6]: Added GSO... |
2139 |
.gso_segment = tcp_tso_segment, |
684f21760 tcp6: Add GRO sup... |
2140 2141 |
.gro_receive = tcp6_gro_receive, .gro_complete = tcp6_gro_complete, |
1da177e4c Linux-2.6.12-rc2 |
2142 2143 |
.flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, }; |
1da177e4c Linux-2.6.12-rc2 |
2144 2145 2146 2147 2148 |
static struct inet_protosw tcpv6_protosw = { .type = SOCK_STREAM, .protocol = IPPROTO_TCP, .prot = &tcpv6_prot, .ops = &inet6_stream_ops, |
1da177e4c Linux-2.6.12-rc2 |
2149 |
.no_check = 0, |
d83d8461f [IP_SOCKGLUE]: Re... |
2150 2151 |
.flags = INET_PROTOSW_PERMANENT | INET_PROTOSW_ICSK, |
1da177e4c Linux-2.6.12-rc2 |
2152 |
}; |
2c8c1e729 net: spread __net... |
2153 |
static int __net_init tcpv6_net_init(struct net *net) |
93ec926b0 [NETNS][IPV6] tcp... |
2154 |
{ |
5677242f4 [NETNS]: Inet con... |
2155 2156 |
return inet_ctl_sock_create(&net->ipv6.tcp_sk, PF_INET6, SOCK_RAW, IPPROTO_TCP, net); |
93ec926b0 [NETNS][IPV6] tcp... |
2157 |
} |
2c8c1e729 net: spread __net... |
2158 |
static void __net_exit tcpv6_net_exit(struct net *net) |
93ec926b0 [NETNS][IPV6] tcp... |
2159 |
{ |
5677242f4 [NETNS]: Inet con... |
2160 |
inet_ctl_sock_destroy(net->ipv6.tcp_sk); |
b099ce260 net: Batch inet_t... |
2161 |
} |
2c8c1e729 net: spread __net... |
2162 |
static void __net_exit tcpv6_net_exit_batch(struct list_head *net_exit_list) |
b099ce260 net: Batch inet_t... |
2163 2164 |
{ inet_twsk_purge(&tcp_hashinfo, &tcp_death_row, AF_INET6); |
93ec926b0 [NETNS][IPV6] tcp... |
2165 2166 2167 |
} static struct pernet_operations tcpv6_net_ops = { |
b099ce260 net: Batch inet_t... |
2168 2169 2170 |
.init = tcpv6_net_init, .exit = tcpv6_net_exit, .exit_batch = tcpv6_net_exit_batch, |
93ec926b0 [NETNS][IPV6] tcp... |
2171 |
}; |
7f4e4868f [IPV6]: make the ... |
2172 |
int __init tcpv6_init(void) |
1da177e4c Linux-2.6.12-rc2 |
2173 |
{ |
7f4e4868f [IPV6]: make the ... |
2174 2175 2176 2177 2178 |
int ret; ret = inet6_add_protocol(&tcpv6_protocol, IPPROTO_TCP); if (ret) goto out; |
1da177e4c Linux-2.6.12-rc2 |
2179 |
/* register inet6 protocol */ |
7f4e4868f [IPV6]: make the ... |
2180 2181 2182 |
ret = inet6_register_protosw(&tcpv6_protosw); if (ret) goto out_tcpv6_protocol; |
93ec926b0 [NETNS][IPV6] tcp... |
2183 |
ret = register_pernet_subsys(&tcpv6_net_ops); |
7f4e4868f [IPV6]: make the ... |
2184 2185 2186 2187 |
if (ret) goto out_tcpv6_protosw; out: return ret; |
ae0f7d5f8 [IPV6]: Avoid cal... |
2188 |
|
7f4e4868f [IPV6]: make the ... |
2189 2190 2191 2192 2193 2194 |
out_tcpv6_protocol: inet6_del_protocol(&tcpv6_protocol, IPPROTO_TCP); out_tcpv6_protosw: inet6_unregister_protosw(&tcpv6_protosw); goto out; } |
09f7709f4 [IPV6]: fix secti... |
2195 |
void tcpv6_exit(void) |
7f4e4868f [IPV6]: make the ... |
2196 |
{ |
93ec926b0 [NETNS][IPV6] tcp... |
2197 |
unregister_pernet_subsys(&tcpv6_net_ops); |
7f4e4868f [IPV6]: make the ... |
2198 2199 |
inet6_unregister_protosw(&tcpv6_protosw); inet6_del_protocol(&tcpv6_protocol, IPPROTO_TCP); |
1da177e4c Linux-2.6.12-rc2 |
2200 |
} |