diff options
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 437 |
1 files changed, 153 insertions, 284 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index ef29cfd936d3..794734f1d230 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -47,6 +47,7 @@ | |||
47 | 47 | ||
48 | #include <net/tcp.h> | 48 | #include <net/tcp.h> |
49 | #include <net/ndisc.h> | 49 | #include <net/ndisc.h> |
50 | #include <net/inet6_hashtables.h> | ||
50 | #include <net/ipv6.h> | 51 | #include <net/ipv6.h> |
51 | #include <net/transp_v6.h> | 52 | #include <net/transp_v6.h> |
52 | #include <net/addrconf.h> | 53 | #include <net/addrconf.h> |
@@ -75,34 +76,11 @@ static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok); | |||
75 | static struct tcp_func ipv6_mapped; | 76 | static struct tcp_func ipv6_mapped; |
76 | static struct tcp_func ipv6_specific; | 77 | static struct tcp_func ipv6_specific; |
77 | 78 | ||
78 | /* I have no idea if this is a good hash for v6 or not. -DaveM */ | 79 | static inline int tcp_v6_bind_conflict(const struct sock *sk, |
79 | static __inline__ int tcp_v6_hashfn(struct in6_addr *laddr, u16 lport, | 80 | const struct inet_bind_bucket *tb) |
80 | struct in6_addr *faddr, u16 fport) | ||
81 | { | 81 | { |
82 | int hashent = (lport ^ fport); | 82 | const struct sock *sk2; |
83 | 83 | const struct hlist_node *node; | |
84 | hashent ^= (laddr->s6_addr32[3] ^ faddr->s6_addr32[3]); | ||
85 | hashent ^= hashent>>16; | ||
86 | hashent ^= hashent>>8; | ||
87 | return (hashent & (tcp_ehash_size - 1)); | ||
88 | } | ||
89 | |||
90 | static __inline__ int tcp_v6_sk_hashfn(struct sock *sk) | ||
91 | { | ||
92 | struct inet_sock *inet = inet_sk(sk); | ||
93 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
94 | struct in6_addr *laddr = &np->rcv_saddr; | ||
95 | struct in6_addr *faddr = &np->daddr; | ||
96 | __u16 lport = inet->num; | ||
97 | __u16 fport = inet->dport; | ||
98 | return tcp_v6_hashfn(laddr, lport, faddr, fport); | ||
99 | } | ||
100 | |||
101 | static inline int tcp_v6_bind_conflict(struct sock *sk, | ||
102 | struct tcp_bind_bucket *tb) | ||
103 | { | ||
104 | struct sock *sk2; | ||
105 | struct hlist_node *node; | ||
106 | 84 | ||
107 | /* We must walk the whole port owner list in this case. -DaveM */ | 85 | /* We must walk the whole port owner list in this case. -DaveM */ |
108 | sk_for_each_bound(sk2, node, &tb->owners) { | 86 | sk_for_each_bound(sk2, node, &tb->owners) { |
@@ -126,8 +104,8 @@ static inline int tcp_v6_bind_conflict(struct sock *sk, | |||
126 | */ | 104 | */ |
127 | static int tcp_v6_get_port(struct sock *sk, unsigned short snum) | 105 | static int tcp_v6_get_port(struct sock *sk, unsigned short snum) |
128 | { | 106 | { |
129 | struct tcp_bind_hashbucket *head; | 107 | struct inet_bind_hashbucket *head; |
130 | struct tcp_bind_bucket *tb; | 108 | struct inet_bind_bucket *tb; |
131 | struct hlist_node *node; | 109 | struct hlist_node *node; |
132 | int ret; | 110 | int ret; |
133 | 111 | ||
@@ -138,25 +116,25 @@ static int tcp_v6_get_port(struct sock *sk, unsigned short snum) | |||
138 | int remaining = (high - low) + 1; | 116 | int remaining = (high - low) + 1; |
139 | int rover; | 117 | int rover; |
140 | 118 | ||
141 | spin_lock(&tcp_portalloc_lock); | 119 | spin_lock(&tcp_hashinfo.portalloc_lock); |
142 | if (tcp_port_rover < low) | 120 | if (tcp_hashinfo.port_rover < low) |
143 | rover = low; | 121 | rover = low; |
144 | else | 122 | else |
145 | rover = tcp_port_rover; | 123 | rover = tcp_hashinfo.port_rover; |
146 | do { rover++; | 124 | do { rover++; |
147 | if (rover > high) | 125 | if (rover > high) |
148 | rover = low; | 126 | rover = low; |
149 | head = &tcp_bhash[tcp_bhashfn(rover)]; | 127 | head = &tcp_hashinfo.bhash[inet_bhashfn(rover, tcp_hashinfo.bhash_size)]; |
150 | spin_lock(&head->lock); | 128 | spin_lock(&head->lock); |
151 | tb_for_each(tb, node, &head->chain) | 129 | inet_bind_bucket_for_each(tb, node, &head->chain) |
152 | if (tb->port == rover) | 130 | if (tb->port == rover) |
153 | goto next; | 131 | goto next; |
154 | break; | 132 | break; |
155 | next: | 133 | next: |
156 | spin_unlock(&head->lock); | 134 | spin_unlock(&head->lock); |
157 | } while (--remaining > 0); | 135 | } while (--remaining > 0); |
158 | tcp_port_rover = rover; | 136 | tcp_hashinfo.port_rover = rover; |
159 | spin_unlock(&tcp_portalloc_lock); | 137 | spin_unlock(&tcp_hashinfo.portalloc_lock); |
160 | 138 | ||
161 | /* Exhausted local port range during search? It is not | 139 | /* Exhausted local port range during search? It is not |
162 | * possible for us to be holding one of the bind hash | 140 | * possible for us to be holding one of the bind hash |
@@ -171,9 +149,9 @@ static int tcp_v6_get_port(struct sock *sk, unsigned short snum) | |||
171 | /* OK, here is the one we will use. */ | 149 | /* OK, here is the one we will use. */ |
172 | snum = rover; | 150 | snum = rover; |
173 | } else { | 151 | } else { |
174 | head = &tcp_bhash[tcp_bhashfn(snum)]; | 152 | head = &tcp_hashinfo.bhash[inet_bhashfn(snum, tcp_hashinfo.bhash_size)]; |
175 | spin_lock(&head->lock); | 153 | spin_lock(&head->lock); |
176 | tb_for_each(tb, node, &head->chain) | 154 | inet_bind_bucket_for_each(tb, node, &head->chain) |
177 | if (tb->port == snum) | 155 | if (tb->port == snum) |
178 | goto tb_found; | 156 | goto tb_found; |
179 | } | 157 | } |
@@ -192,8 +170,11 @@ tb_found: | |||
192 | } | 170 | } |
193 | tb_not_found: | 171 | tb_not_found: |
194 | ret = 1; | 172 | ret = 1; |
195 | if (!tb && (tb = tcp_bucket_create(head, snum)) == NULL) | 173 | if (tb == NULL) { |
196 | goto fail_unlock; | 174 | tb = inet_bind_bucket_create(tcp_hashinfo.bind_bucket_cachep, head, snum); |
175 | if (tb == NULL) | ||
176 | goto fail_unlock; | ||
177 | } | ||
197 | if (hlist_empty(&tb->owners)) { | 178 | if (hlist_empty(&tb->owners)) { |
198 | if (sk->sk_reuse && sk->sk_state != TCP_LISTEN) | 179 | if (sk->sk_reuse && sk->sk_state != TCP_LISTEN) |
199 | tb->fastreuse = 1; | 180 | tb->fastreuse = 1; |
@@ -204,9 +185,9 @@ tb_not_found: | |||
204 | tb->fastreuse = 0; | 185 | tb->fastreuse = 0; |
205 | 186 | ||
206 | success: | 187 | success: |
207 | if (!tcp_sk(sk)->bind_hash) | 188 | if (!inet_csk(sk)->icsk_bind_hash) |
208 | tcp_bind_hash(sk, tb, snum); | 189 | inet_bind_hash(sk, tb, snum); |
209 | BUG_TRAP(tcp_sk(sk)->bind_hash == tb); | 190 | BUG_TRAP(inet_csk(sk)->icsk_bind_hash == tb); |
210 | ret = 0; | 191 | ret = 0; |
211 | 192 | ||
212 | fail_unlock: | 193 | fail_unlock: |
@@ -224,13 +205,13 @@ static __inline__ void __tcp_v6_hash(struct sock *sk) | |||
224 | BUG_TRAP(sk_unhashed(sk)); | 205 | BUG_TRAP(sk_unhashed(sk)); |
225 | 206 | ||
226 | if (sk->sk_state == TCP_LISTEN) { | 207 | if (sk->sk_state == TCP_LISTEN) { |
227 | list = &tcp_listening_hash[tcp_sk_listen_hashfn(sk)]; | 208 | list = &tcp_hashinfo.listening_hash[inet_sk_listen_hashfn(sk)]; |
228 | lock = &tcp_lhash_lock; | 209 | lock = &tcp_hashinfo.lhash_lock; |
229 | tcp_listen_wlock(); | 210 | inet_listen_wlock(&tcp_hashinfo); |
230 | } else { | 211 | } else { |
231 | sk->sk_hashent = tcp_v6_sk_hashfn(sk); | 212 | sk->sk_hashent = inet6_sk_ehashfn(sk, tcp_hashinfo.ehash_size); |
232 | list = &tcp_ehash[sk->sk_hashent].chain; | 213 | list = &tcp_hashinfo.ehash[sk->sk_hashent].chain; |
233 | lock = &tcp_ehash[sk->sk_hashent].lock; | 214 | lock = &tcp_hashinfo.ehash[sk->sk_hashent].lock; |
234 | write_lock(lock); | 215 | write_lock(lock); |
235 | } | 216 | } |
236 | 217 | ||
@@ -255,131 +236,11 @@ static void tcp_v6_hash(struct sock *sk) | |||
255 | } | 236 | } |
256 | } | 237 | } |
257 | 238 | ||
258 | static struct sock *tcp_v6_lookup_listener(struct in6_addr *daddr, unsigned short hnum, int dif) | ||
259 | { | ||
260 | struct sock *sk; | ||
261 | struct hlist_node *node; | ||
262 | struct sock *result = NULL; | ||
263 | int score, hiscore; | ||
264 | |||
265 | hiscore=0; | ||
266 | read_lock(&tcp_lhash_lock); | ||
267 | sk_for_each(sk, node, &tcp_listening_hash[tcp_lhashfn(hnum)]) { | ||
268 | if (inet_sk(sk)->num == hnum && sk->sk_family == PF_INET6) { | ||
269 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
270 | |||
271 | score = 1; | ||
272 | if (!ipv6_addr_any(&np->rcv_saddr)) { | ||
273 | if (!ipv6_addr_equal(&np->rcv_saddr, daddr)) | ||
274 | continue; | ||
275 | score++; | ||
276 | } | ||
277 | if (sk->sk_bound_dev_if) { | ||
278 | if (sk->sk_bound_dev_if != dif) | ||
279 | continue; | ||
280 | score++; | ||
281 | } | ||
282 | if (score == 3) { | ||
283 | result = sk; | ||
284 | break; | ||
285 | } | ||
286 | if (score > hiscore) { | ||
287 | hiscore = score; | ||
288 | result = sk; | ||
289 | } | ||
290 | } | ||
291 | } | ||
292 | if (result) | ||
293 | sock_hold(result); | ||
294 | read_unlock(&tcp_lhash_lock); | ||
295 | return result; | ||
296 | } | ||
297 | |||
298 | /* Sockets in TCP_CLOSE state are _always_ taken out of the hash, so | ||
299 | * we need not check it for TCP lookups anymore, thanks Alexey. -DaveM | ||
300 | * | ||
301 | * The sockhash lock must be held as a reader here. | ||
302 | */ | ||
303 | |||
304 | static inline struct sock *__tcp_v6_lookup_established(struct in6_addr *saddr, u16 sport, | ||
305 | struct in6_addr *daddr, u16 hnum, | ||
306 | int dif) | ||
307 | { | ||
308 | struct tcp_ehash_bucket *head; | ||
309 | struct sock *sk; | ||
310 | struct hlist_node *node; | ||
311 | __u32 ports = TCP_COMBINED_PORTS(sport, hnum); | ||
312 | int hash; | ||
313 | |||
314 | /* Optimize here for direct hit, only listening connections can | ||
315 | * have wildcards anyways. | ||
316 | */ | ||
317 | hash = tcp_v6_hashfn(daddr, hnum, saddr, sport); | ||
318 | head = &tcp_ehash[hash]; | ||
319 | read_lock(&head->lock); | ||
320 | sk_for_each(sk, node, &head->chain) { | ||
321 | /* For IPV6 do the cheaper port and family tests first. */ | ||
322 | if(TCP_IPV6_MATCH(sk, saddr, daddr, ports, dif)) | ||
323 | goto hit; /* You sunk my battleship! */ | ||
324 | } | ||
325 | /* Must check for a TIME_WAIT'er before going to listener hash. */ | ||
326 | sk_for_each(sk, node, &(head + tcp_ehash_size)->chain) { | ||
327 | /* FIXME: acme: check this... */ | ||
328 | struct tcp_tw_bucket *tw = (struct tcp_tw_bucket *)sk; | ||
329 | |||
330 | if(*((__u32 *)&(tw->tw_dport)) == ports && | ||
331 | sk->sk_family == PF_INET6) { | ||
332 | if(ipv6_addr_equal(&tw->tw_v6_daddr, saddr) && | ||
333 | ipv6_addr_equal(&tw->tw_v6_rcv_saddr, daddr) && | ||
334 | (!sk->sk_bound_dev_if || sk->sk_bound_dev_if == dif)) | ||
335 | goto hit; | ||
336 | } | ||
337 | } | ||
338 | read_unlock(&head->lock); | ||
339 | return NULL; | ||
340 | |||
341 | hit: | ||
342 | sock_hold(sk); | ||
343 | read_unlock(&head->lock); | ||
344 | return sk; | ||
345 | } | ||
346 | |||
347 | |||
348 | static inline struct sock *__tcp_v6_lookup(struct in6_addr *saddr, u16 sport, | ||
349 | struct in6_addr *daddr, u16 hnum, | ||
350 | int dif) | ||
351 | { | ||
352 | struct sock *sk; | ||
353 | |||
354 | sk = __tcp_v6_lookup_established(saddr, sport, daddr, hnum, dif); | ||
355 | |||
356 | if (sk) | ||
357 | return sk; | ||
358 | |||
359 | return tcp_v6_lookup_listener(daddr, hnum, dif); | ||
360 | } | ||
361 | |||
362 | inline struct sock *tcp_v6_lookup(struct in6_addr *saddr, u16 sport, | ||
363 | struct in6_addr *daddr, u16 dport, | ||
364 | int dif) | ||
365 | { | ||
366 | struct sock *sk; | ||
367 | |||
368 | local_bh_disable(); | ||
369 | sk = __tcp_v6_lookup(saddr, sport, daddr, ntohs(dport), dif); | ||
370 | local_bh_enable(); | ||
371 | |||
372 | return sk; | ||
373 | } | ||
374 | |||
375 | EXPORT_SYMBOL_GPL(tcp_v6_lookup); | ||
376 | |||
377 | |||
378 | /* | 239 | /* |
379 | * Open request hash tables. | 240 | * Open request hash tables. |
380 | */ | 241 | */ |
381 | 242 | ||
382 | static u32 tcp_v6_synq_hash(struct in6_addr *raddr, u16 rport, u32 rnd) | 243 | static u32 tcp_v6_synq_hash(const struct in6_addr *raddr, const u16 rport, const u32 rnd) |
383 | { | 244 | { |
384 | u32 a, b, c; | 245 | u32 a, b, c; |
385 | 246 | ||
@@ -399,14 +260,15 @@ static u32 tcp_v6_synq_hash(struct in6_addr *raddr, u16 rport, u32 rnd) | |||
399 | return c & (TCP_SYNQ_HSIZE - 1); | 260 | return c & (TCP_SYNQ_HSIZE - 1); |
400 | } | 261 | } |
401 | 262 | ||
402 | static struct request_sock *tcp_v6_search_req(struct tcp_sock *tp, | 263 | static struct request_sock *tcp_v6_search_req(const struct sock *sk, |
403 | struct request_sock ***prevp, | 264 | struct request_sock ***prevp, |
404 | __u16 rport, | 265 | __u16 rport, |
405 | struct in6_addr *raddr, | 266 | struct in6_addr *raddr, |
406 | struct in6_addr *laddr, | 267 | struct in6_addr *laddr, |
407 | int iif) | 268 | int iif) |
408 | { | 269 | { |
409 | struct listen_sock *lopt = tp->accept_queue.listen_opt; | 270 | const struct inet_connection_sock *icsk = inet_csk(sk); |
271 | struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt; | ||
410 | struct request_sock *req, **prev; | 272 | struct request_sock *req, **prev; |
411 | 273 | ||
412 | for (prev = &lopt->syn_table[tcp_v6_synq_hash(raddr, rport, lopt->hash_rnd)]; | 274 | for (prev = &lopt->syn_table[tcp_v6_synq_hash(raddr, rport, lopt->hash_rnd)]; |
@@ -451,44 +313,48 @@ static __u32 tcp_v6_init_sequence(struct sock *sk, struct sk_buff *skb) | |||
451 | } | 313 | } |
452 | } | 314 | } |
453 | 315 | ||
454 | static int __tcp_v6_check_established(struct sock *sk, __u16 lport, | 316 | static int __tcp_v6_check_established(struct sock *sk, const __u16 lport, |
455 | struct tcp_tw_bucket **twp) | 317 | struct inet_timewait_sock **twp) |
456 | { | 318 | { |
457 | struct inet_sock *inet = inet_sk(sk); | 319 | struct inet_sock *inet = inet_sk(sk); |
458 | struct ipv6_pinfo *np = inet6_sk(sk); | 320 | const struct ipv6_pinfo *np = inet6_sk(sk); |
459 | struct in6_addr *daddr = &np->rcv_saddr; | 321 | const struct in6_addr *daddr = &np->rcv_saddr; |
460 | struct in6_addr *saddr = &np->daddr; | 322 | const struct in6_addr *saddr = &np->daddr; |
461 | int dif = sk->sk_bound_dev_if; | 323 | const int dif = sk->sk_bound_dev_if; |
462 | u32 ports = TCP_COMBINED_PORTS(inet->dport, lport); | 324 | const u32 ports = INET_COMBINED_PORTS(inet->dport, lport); |
463 | int hash = tcp_v6_hashfn(daddr, inet->num, saddr, inet->dport); | 325 | const int hash = inet6_ehashfn(daddr, inet->num, saddr, inet->dport, |
464 | struct tcp_ehash_bucket *head = &tcp_ehash[hash]; | 326 | tcp_hashinfo.ehash_size); |
327 | struct inet_ehash_bucket *head = &tcp_hashinfo.ehash[hash]; | ||
465 | struct sock *sk2; | 328 | struct sock *sk2; |
466 | struct hlist_node *node; | 329 | const struct hlist_node *node; |
467 | struct tcp_tw_bucket *tw; | 330 | struct inet_timewait_sock *tw; |
468 | 331 | ||
469 | write_lock(&head->lock); | 332 | write_lock(&head->lock); |
470 | 333 | ||
471 | /* Check TIME-WAIT sockets first. */ | 334 | /* Check TIME-WAIT sockets first. */ |
472 | sk_for_each(sk2, node, &(head + tcp_ehash_size)->chain) { | 335 | sk_for_each(sk2, node, &(head + tcp_hashinfo.ehash_size)->chain) { |
473 | tw = (struct tcp_tw_bucket*)sk2; | 336 | const struct tcp6_timewait_sock *tcp6tw = tcp6_twsk(sk2); |
337 | |||
338 | tw = inet_twsk(sk2); | ||
474 | 339 | ||
475 | if(*((__u32 *)&(tw->tw_dport)) == ports && | 340 | if(*((__u32 *)&(tw->tw_dport)) == ports && |
476 | sk2->sk_family == PF_INET6 && | 341 | sk2->sk_family == PF_INET6 && |
477 | ipv6_addr_equal(&tw->tw_v6_daddr, saddr) && | 342 | ipv6_addr_equal(&tcp6tw->tw_v6_daddr, saddr) && |
478 | ipv6_addr_equal(&tw->tw_v6_rcv_saddr, daddr) && | 343 | ipv6_addr_equal(&tcp6tw->tw_v6_rcv_saddr, daddr) && |
479 | sk2->sk_bound_dev_if == sk->sk_bound_dev_if) { | 344 | sk2->sk_bound_dev_if == sk->sk_bound_dev_if) { |
345 | const struct tcp_timewait_sock *tcptw = tcp_twsk(sk2); | ||
480 | struct tcp_sock *tp = tcp_sk(sk); | 346 | struct tcp_sock *tp = tcp_sk(sk); |
481 | 347 | ||
482 | if (tw->tw_ts_recent_stamp && | 348 | if (tcptw->tw_ts_recent_stamp && |
483 | (!twp || (sysctl_tcp_tw_reuse && | 349 | (!twp || |
484 | xtime.tv_sec - | 350 | (sysctl_tcp_tw_reuse && |
485 | tw->tw_ts_recent_stamp > 1))) { | 351 | xtime.tv_sec - tcptw->tw_ts_recent_stamp > 1))) { |
486 | /* See comment in tcp_ipv4.c */ | 352 | /* See comment in tcp_ipv4.c */ |
487 | tp->write_seq = tw->tw_snd_nxt + 65535 + 2; | 353 | tp->write_seq = tcptw->tw_snd_nxt + 65535 + 2; |
488 | if (!tp->write_seq) | 354 | if (!tp->write_seq) |
489 | tp->write_seq = 1; | 355 | tp->write_seq = 1; |
490 | tp->rx_opt.ts_recent = tw->tw_ts_recent; | 356 | tp->rx_opt.ts_recent = tcptw->tw_ts_recent; |
491 | tp->rx_opt.ts_recent_stamp = tw->tw_ts_recent_stamp; | 357 | tp->rx_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp; |
492 | sock_hold(sk2); | 358 | sock_hold(sk2); |
493 | goto unique; | 359 | goto unique; |
494 | } else | 360 | } else |
@@ -499,7 +365,7 @@ static int __tcp_v6_check_established(struct sock *sk, __u16 lport, | |||
499 | 365 | ||
500 | /* And established part... */ | 366 | /* And established part... */ |
501 | sk_for_each(sk2, node, &head->chain) { | 367 | sk_for_each(sk2, node, &head->chain) { |
502 | if(TCP_IPV6_MATCH(sk2, saddr, daddr, ports, dif)) | 368 | if (INET6_MATCH(sk2, saddr, daddr, ports, dif)) |
503 | goto not_unique; | 369 | goto not_unique; |
504 | } | 370 | } |
505 | 371 | ||
@@ -515,10 +381,10 @@ unique: | |||
515 | NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED); | 381 | NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED); |
516 | } else if (tw) { | 382 | } else if (tw) { |
517 | /* Silly. Should hash-dance instead... */ | 383 | /* Silly. Should hash-dance instead... */ |
518 | tcp_tw_deschedule(tw); | 384 | inet_twsk_deschedule(tw, &tcp_death_row); |
519 | NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED); | 385 | NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED); |
520 | 386 | ||
521 | tcp_tw_put(tw); | 387 | inet_twsk_put(tw); |
522 | } | 388 | } |
523 | return 0; | 389 | return 0; |
524 | 390 | ||
@@ -540,8 +406,8 @@ static inline u32 tcpv6_port_offset(const struct sock *sk) | |||
540 | static int tcp_v6_hash_connect(struct sock *sk) | 406 | static int tcp_v6_hash_connect(struct sock *sk) |
541 | { | 407 | { |
542 | unsigned short snum = inet_sk(sk)->num; | 408 | unsigned short snum = inet_sk(sk)->num; |
543 | struct tcp_bind_hashbucket *head; | 409 | struct inet_bind_hashbucket *head; |
544 | struct tcp_bind_bucket *tb; | 410 | struct inet_bind_bucket *tb; |
545 | int ret; | 411 | int ret; |
546 | 412 | ||
547 | if (!snum) { | 413 | if (!snum) { |
@@ -553,19 +419,19 @@ static int tcp_v6_hash_connect(struct sock *sk) | |||
553 | static u32 hint; | 419 | static u32 hint; |
554 | u32 offset = hint + tcpv6_port_offset(sk); | 420 | u32 offset = hint + tcpv6_port_offset(sk); |
555 | struct hlist_node *node; | 421 | struct hlist_node *node; |
556 | struct tcp_tw_bucket *tw = NULL; | 422 | struct inet_timewait_sock *tw = NULL; |
557 | 423 | ||
558 | local_bh_disable(); | 424 | local_bh_disable(); |
559 | for (i = 1; i <= range; i++) { | 425 | for (i = 1; i <= range; i++) { |
560 | port = low + (i + offset) % range; | 426 | port = low + (i + offset) % range; |
561 | head = &tcp_bhash[tcp_bhashfn(port)]; | 427 | head = &tcp_hashinfo.bhash[inet_bhashfn(port, tcp_hashinfo.bhash_size)]; |
562 | spin_lock(&head->lock); | 428 | spin_lock(&head->lock); |
563 | 429 | ||
564 | /* Does not bother with rcv_saddr checks, | 430 | /* Does not bother with rcv_saddr checks, |
565 | * because the established check is already | 431 | * because the established check is already |
566 | * unique enough. | 432 | * unique enough. |
567 | */ | 433 | */ |
568 | tb_for_each(tb, node, &head->chain) { | 434 | inet_bind_bucket_for_each(tb, node, &head->chain) { |
569 | if (tb->port == port) { | 435 | if (tb->port == port) { |
570 | BUG_TRAP(!hlist_empty(&tb->owners)); | 436 | BUG_TRAP(!hlist_empty(&tb->owners)); |
571 | if (tb->fastreuse >= 0) | 437 | if (tb->fastreuse >= 0) |
@@ -578,7 +444,7 @@ static int tcp_v6_hash_connect(struct sock *sk) | |||
578 | } | 444 | } |
579 | } | 445 | } |
580 | 446 | ||
581 | tb = tcp_bucket_create(head, port); | 447 | tb = inet_bind_bucket_create(tcp_hashinfo.bind_bucket_cachep, head, port); |
582 | if (!tb) { | 448 | if (!tb) { |
583 | spin_unlock(&head->lock); | 449 | spin_unlock(&head->lock); |
584 | break; | 450 | break; |
@@ -597,7 +463,7 @@ ok: | |||
597 | hint += i; | 463 | hint += i; |
598 | 464 | ||
599 | /* Head lock still held and bh's disabled */ | 465 | /* Head lock still held and bh's disabled */ |
600 | tcp_bind_hash(sk, tb, port); | 466 | inet_bind_hash(sk, tb, port); |
601 | if (sk_unhashed(sk)) { | 467 | if (sk_unhashed(sk)) { |
602 | inet_sk(sk)->sport = htons(port); | 468 | inet_sk(sk)->sport = htons(port); |
603 | __tcp_v6_hash(sk); | 469 | __tcp_v6_hash(sk); |
@@ -605,16 +471,16 @@ ok: | |||
605 | spin_unlock(&head->lock); | 471 | spin_unlock(&head->lock); |
606 | 472 | ||
607 | if (tw) { | 473 | if (tw) { |
608 | tcp_tw_deschedule(tw); | 474 | inet_twsk_deschedule(tw, &tcp_death_row); |
609 | tcp_tw_put(tw); | 475 | inet_twsk_put(tw); |
610 | } | 476 | } |
611 | 477 | ||
612 | ret = 0; | 478 | ret = 0; |
613 | goto out; | 479 | goto out; |
614 | } | 480 | } |
615 | 481 | ||
616 | head = &tcp_bhash[tcp_bhashfn(snum)]; | 482 | head = &tcp_hashinfo.bhash[inet_bhashfn(snum, tcp_hashinfo.bhash_size)]; |
617 | tb = tcp_sk(sk)->bind_hash; | 483 | tb = inet_csk(sk)->icsk_bind_hash; |
618 | spin_lock_bh(&head->lock); | 484 | spin_lock_bh(&head->lock); |
619 | 485 | ||
620 | if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) { | 486 | if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) { |
@@ -631,11 +497,6 @@ out: | |||
631 | } | 497 | } |
632 | } | 498 | } |
633 | 499 | ||
634 | static __inline__ int tcp_v6_iif(struct sk_buff *skb) | ||
635 | { | ||
636 | return IP6CB(skb)->iif; | ||
637 | } | ||
638 | |||
639 | static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | 500 | static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, |
640 | int addr_len) | 501 | int addr_len) |
641 | { | 502 | { |
@@ -827,14 +688,15 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
827 | int type, int code, int offset, __u32 info) | 688 | int type, int code, int offset, __u32 info) |
828 | { | 689 | { |
829 | struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data; | 690 | struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data; |
830 | struct tcphdr *th = (struct tcphdr *)(skb->data+offset); | 691 | const struct tcphdr *th = (struct tcphdr *)(skb->data+offset); |
831 | struct ipv6_pinfo *np; | 692 | struct ipv6_pinfo *np; |
832 | struct sock *sk; | 693 | struct sock *sk; |
833 | int err; | 694 | int err; |
834 | struct tcp_sock *tp; | 695 | struct tcp_sock *tp; |
835 | __u32 seq; | 696 | __u32 seq; |
836 | 697 | ||
837 | sk = tcp_v6_lookup(&hdr->daddr, th->dest, &hdr->saddr, th->source, skb->dev->ifindex); | 698 | sk = inet6_lookup(&tcp_hashinfo, &hdr->daddr, th->dest, &hdr->saddr, |
699 | th->source, skb->dev->ifindex); | ||
838 | 700 | ||
839 | if (sk == NULL) { | 701 | if (sk == NULL) { |
840 | ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS); | 702 | ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS); |
@@ -842,7 +704,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
842 | } | 704 | } |
843 | 705 | ||
844 | if (sk->sk_state == TCP_TIME_WAIT) { | 706 | if (sk->sk_state == TCP_TIME_WAIT) { |
845 | tcp_tw_put((struct tcp_tw_bucket*)sk); | 707 | inet_twsk_put((struct inet_timewait_sock *)sk); |
846 | return; | 708 | return; |
847 | } | 709 | } |
848 | 710 | ||
@@ -920,8 +782,8 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
920 | if (sock_owned_by_user(sk)) | 782 | if (sock_owned_by_user(sk)) |
921 | goto out; | 783 | goto out; |
922 | 784 | ||
923 | req = tcp_v6_search_req(tp, &prev, th->dest, &hdr->daddr, | 785 | req = tcp_v6_search_req(sk, &prev, th->dest, &hdr->daddr, |
924 | &hdr->saddr, tcp_v6_iif(skb)); | 786 | &hdr->saddr, inet6_iif(skb)); |
925 | if (!req) | 787 | if (!req) |
926 | goto out; | 788 | goto out; |
927 | 789 | ||
@@ -935,7 +797,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
935 | goto out; | 797 | goto out; |
936 | } | 798 | } |
937 | 799 | ||
938 | tcp_synq_drop(sk, req, prev); | 800 | inet_csk_reqsk_queue_drop(sk, req, prev); |
939 | goto out; | 801 | goto out; |
940 | 802 | ||
941 | case TCP_SYN_SENT: | 803 | case TCP_SYN_SENT: |
@@ -1132,7 +994,7 @@ static void tcp_v6_send_reset(struct sk_buff *skb) | |||
1132 | buff->csum); | 994 | buff->csum); |
1133 | 995 | ||
1134 | fl.proto = IPPROTO_TCP; | 996 | fl.proto = IPPROTO_TCP; |
1135 | fl.oif = tcp_v6_iif(skb); | 997 | fl.oif = inet6_iif(skb); |
1136 | fl.fl_ip_dport = t1->dest; | 998 | fl.fl_ip_dport = t1->dest; |
1137 | fl.fl_ip_sport = t1->source; | 999 | fl.fl_ip_sport = t1->source; |
1138 | 1000 | ||
@@ -1201,7 +1063,7 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 | |||
1201 | buff->csum); | 1063 | buff->csum); |
1202 | 1064 | ||
1203 | fl.proto = IPPROTO_TCP; | 1065 | fl.proto = IPPROTO_TCP; |
1204 | fl.oif = tcp_v6_iif(skb); | 1066 | fl.oif = inet6_iif(skb); |
1205 | fl.fl_ip_dport = t1->dest; | 1067 | fl.fl_ip_dport = t1->dest; |
1206 | fl.fl_ip_sport = t1->source; | 1068 | fl.fl_ip_sport = t1->source; |
1207 | 1069 | ||
@@ -1220,12 +1082,14 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 | |||
1220 | 1082 | ||
1221 | static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) | 1083 | static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) |
1222 | { | 1084 | { |
1223 | struct tcp_tw_bucket *tw = (struct tcp_tw_bucket *)sk; | 1085 | struct inet_timewait_sock *tw = inet_twsk(sk); |
1086 | const struct tcp_timewait_sock *tcptw = tcp_twsk(sk); | ||
1224 | 1087 | ||
1225 | tcp_v6_send_ack(skb, tw->tw_snd_nxt, tw->tw_rcv_nxt, | 1088 | tcp_v6_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, |
1226 | tw->tw_rcv_wnd >> tw->tw_rcv_wscale, tw->tw_ts_recent); | 1089 | tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, |
1090 | tcptw->tw_ts_recent); | ||
1227 | 1091 | ||
1228 | tcp_tw_put(tw); | 1092 | inet_twsk_put(tw); |
1229 | } | 1093 | } |
1230 | 1094 | ||
1231 | static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req) | 1095 | static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req) |
@@ -1237,28 +1101,25 @@ static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req) | |||
1237 | static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb) | 1101 | static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb) |
1238 | { | 1102 | { |
1239 | struct request_sock *req, **prev; | 1103 | struct request_sock *req, **prev; |
1240 | struct tcphdr *th = skb->h.th; | 1104 | const struct tcphdr *th = skb->h.th; |
1241 | struct tcp_sock *tp = tcp_sk(sk); | ||
1242 | struct sock *nsk; | 1105 | struct sock *nsk; |
1243 | 1106 | ||
1244 | /* Find possible connection requests. */ | 1107 | /* Find possible connection requests. */ |
1245 | req = tcp_v6_search_req(tp, &prev, th->source, &skb->nh.ipv6h->saddr, | 1108 | req = tcp_v6_search_req(sk, &prev, th->source, &skb->nh.ipv6h->saddr, |
1246 | &skb->nh.ipv6h->daddr, tcp_v6_iif(skb)); | 1109 | &skb->nh.ipv6h->daddr, inet6_iif(skb)); |
1247 | if (req) | 1110 | if (req) |
1248 | return tcp_check_req(sk, skb, req, prev); | 1111 | return tcp_check_req(sk, skb, req, prev); |
1249 | 1112 | ||
1250 | nsk = __tcp_v6_lookup_established(&skb->nh.ipv6h->saddr, | 1113 | nsk = __inet6_lookup_established(&tcp_hashinfo, &skb->nh.ipv6h->saddr, |
1251 | th->source, | 1114 | th->source, &skb->nh.ipv6h->daddr, |
1252 | &skb->nh.ipv6h->daddr, | 1115 | ntohs(th->dest), inet6_iif(skb)); |
1253 | ntohs(th->dest), | ||
1254 | tcp_v6_iif(skb)); | ||
1255 | 1116 | ||
1256 | if (nsk) { | 1117 | if (nsk) { |
1257 | if (nsk->sk_state != TCP_TIME_WAIT) { | 1118 | if (nsk->sk_state != TCP_TIME_WAIT) { |
1258 | bh_lock_sock(nsk); | 1119 | bh_lock_sock(nsk); |
1259 | return nsk; | 1120 | return nsk; |
1260 | } | 1121 | } |
1261 | tcp_tw_put((struct tcp_tw_bucket*)nsk); | 1122 | inet_twsk_put((struct inet_timewait_sock *)nsk); |
1262 | return NULL; | 1123 | return NULL; |
1263 | } | 1124 | } |
1264 | 1125 | ||
@@ -1271,12 +1132,12 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb) | |||
1271 | 1132 | ||
1272 | static void tcp_v6_synq_add(struct sock *sk, struct request_sock *req) | 1133 | static void tcp_v6_synq_add(struct sock *sk, struct request_sock *req) |
1273 | { | 1134 | { |
1274 | struct tcp_sock *tp = tcp_sk(sk); | 1135 | struct inet_connection_sock *icsk = inet_csk(sk); |
1275 | struct listen_sock *lopt = tp->accept_queue.listen_opt; | 1136 | struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt; |
1276 | u32 h = tcp_v6_synq_hash(&tcp6_rsk(req)->rmt_addr, inet_rsk(req)->rmt_port, lopt->hash_rnd); | 1137 | const u32 h = tcp_v6_synq_hash(&tcp6_rsk(req)->rmt_addr, inet_rsk(req)->rmt_port, lopt->hash_rnd); |
1277 | 1138 | ||
1278 | reqsk_queue_hash_req(&tp->accept_queue, h, req, TCP_TIMEOUT_INIT); | 1139 | reqsk_queue_hash_req(&icsk->icsk_accept_queue, h, req, TCP_TIMEOUT_INIT); |
1279 | tcp_synq_added(sk); | 1140 | inet_csk_reqsk_queue_added(sk, TCP_TIMEOUT_INIT); |
1280 | } | 1141 | } |
1281 | 1142 | ||
1282 | 1143 | ||
@@ -1301,13 +1162,13 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | |||
1301 | /* | 1162 | /* |
1302 | * There are no SYN attacks on IPv6, yet... | 1163 | * There are no SYN attacks on IPv6, yet... |
1303 | */ | 1164 | */ |
1304 | if (tcp_synq_is_full(sk) && !isn) { | 1165 | if (inet_csk_reqsk_queue_is_full(sk) && !isn) { |
1305 | if (net_ratelimit()) | 1166 | if (net_ratelimit()) |
1306 | printk(KERN_INFO "TCPv6: dropping request, synflood is possible\n"); | 1167 | printk(KERN_INFO "TCPv6: dropping request, synflood is possible\n"); |
1307 | goto drop; | 1168 | goto drop; |
1308 | } | 1169 | } |
1309 | 1170 | ||
1310 | if (sk_acceptq_is_full(sk) && tcp_synq_young(sk) > 1) | 1171 | if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) |
1311 | goto drop; | 1172 | goto drop; |
1312 | 1173 | ||
1313 | req = reqsk_alloc(&tcp6_request_sock_ops); | 1174 | req = reqsk_alloc(&tcp6_request_sock_ops); |
@@ -1339,7 +1200,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | |||
1339 | /* So that link locals have meaning */ | 1200 | /* So that link locals have meaning */ |
1340 | if (!sk->sk_bound_dev_if && | 1201 | if (!sk->sk_bound_dev_if && |
1341 | ipv6_addr_type(&treq->rmt_addr) & IPV6_ADDR_LINKLOCAL) | 1202 | ipv6_addr_type(&treq->rmt_addr) & IPV6_ADDR_LINKLOCAL) |
1342 | treq->iif = tcp_v6_iif(skb); | 1203 | treq->iif = inet6_iif(skb); |
1343 | 1204 | ||
1344 | if (isn == 0) | 1205 | if (isn == 0) |
1345 | isn = tcp_v6_init_sequence(sk,skb); | 1206 | isn = tcp_v6_init_sequence(sk,skb); |
@@ -1404,15 +1265,14 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1404 | newsk->sk_backlog_rcv = tcp_v4_do_rcv; | 1265 | newsk->sk_backlog_rcv = tcp_v4_do_rcv; |
1405 | newnp->pktoptions = NULL; | 1266 | newnp->pktoptions = NULL; |
1406 | newnp->opt = NULL; | 1267 | newnp->opt = NULL; |
1407 | newnp->mcast_oif = tcp_v6_iif(skb); | 1268 | newnp->mcast_oif = inet6_iif(skb); |
1408 | newnp->mcast_hops = skb->nh.ipv6h->hop_limit; | 1269 | newnp->mcast_hops = skb->nh.ipv6h->hop_limit; |
1409 | 1270 | ||
1410 | /* Charge newly allocated IPv6 socket. Though it is mapped, | 1271 | /* |
1411 | * it is IPv6 yet. | 1272 | * No need to charge this sock to the relevant IPv6 refcnt debug socks count |
1273 | * here, tcp_create_openreq_child now does this for us, see the comment in | ||
1274 | * that function for the gory details. -acme | ||
1412 | */ | 1275 | */ |
1413 | #ifdef INET_REFCNT_DEBUG | ||
1414 | atomic_inc(&inet6_sock_nr); | ||
1415 | #endif | ||
1416 | 1276 | ||
1417 | /* It is tricky place. Until this moment IPv4 tcp | 1277 | /* It is tricky place. Until this moment IPv4 tcp |
1418 | worked with IPv6 af_tcp.af_specific. | 1278 | worked with IPv6 af_tcp.af_specific. |
@@ -1467,10 +1327,11 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1467 | if (newsk == NULL) | 1327 | if (newsk == NULL) |
1468 | goto out; | 1328 | goto out; |
1469 | 1329 | ||
1470 | /* Charge newly allocated IPv6 socket */ | 1330 | /* |
1471 | #ifdef INET_REFCNT_DEBUG | 1331 | * No need to charge this sock to the relevant IPv6 refcnt debug socks |
1472 | atomic_inc(&inet6_sock_nr); | 1332 | * count here, tcp_create_openreq_child now does this for us, see the |
1473 | #endif | 1333 | * comment in that function for the gory details. -acme |
1334 | */ | ||
1474 | 1335 | ||
1475 | ip6_dst_store(newsk, dst, NULL); | 1336 | ip6_dst_store(newsk, dst, NULL); |
1476 | newsk->sk_route_caps = dst->dev->features & | 1337 | newsk->sk_route_caps = dst->dev->features & |
@@ -1509,7 +1370,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1509 | skb_set_owner_r(newnp->pktoptions, newsk); | 1370 | skb_set_owner_r(newnp->pktoptions, newsk); |
1510 | } | 1371 | } |
1511 | newnp->opt = NULL; | 1372 | newnp->opt = NULL; |
1512 | newnp->mcast_oif = tcp_v6_iif(skb); | 1373 | newnp->mcast_oif = inet6_iif(skb); |
1513 | newnp->mcast_hops = skb->nh.ipv6h->hop_limit; | 1374 | newnp->mcast_hops = skb->nh.ipv6h->hop_limit; |
1514 | 1375 | ||
1515 | /* Clone native IPv6 options from listening socket (if any) | 1376 | /* Clone native IPv6 options from listening socket (if any) |
@@ -1536,7 +1397,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1536 | newinet->daddr = newinet->saddr = newinet->rcv_saddr = LOOPBACK4_IPV6; | 1397 | newinet->daddr = newinet->saddr = newinet->rcv_saddr = LOOPBACK4_IPV6; |
1537 | 1398 | ||
1538 | __tcp_v6_hash(newsk); | 1399 | __tcp_v6_hash(newsk); |
1539 | tcp_inherit_port(sk, newsk); | 1400 | inet_inherit_port(&tcp_hashinfo, sk, newsk); |
1540 | 1401 | ||
1541 | return newsk; | 1402 | return newsk; |
1542 | 1403 | ||
@@ -1557,7 +1418,7 @@ static int tcp_v6_checksum_init(struct sk_buff *skb) | |||
1557 | if (!tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr, | 1418 | if (!tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr, |
1558 | &skb->nh.ipv6h->daddr,skb->csum)) | 1419 | &skb->nh.ipv6h->daddr,skb->csum)) |
1559 | return 0; | 1420 | return 0; |
1560 | LIMIT_NETDEBUG(printk(KERN_DEBUG "hw tcp v6 csum failed\n")); | 1421 | LIMIT_NETDEBUG(KERN_DEBUG "hw tcp v6 csum failed\n"); |
1561 | } | 1422 | } |
1562 | if (skb->len <= 76) { | 1423 | if (skb->len <= 76) { |
1563 | if (tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr, | 1424 | if (tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr, |
@@ -1684,7 +1545,7 @@ ipv6_pktoptions: | |||
1684 | if (TCP_SKB_CB(opt_skb)->end_seq == tp->rcv_nxt && | 1545 | if (TCP_SKB_CB(opt_skb)->end_seq == tp->rcv_nxt && |
1685 | !((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) { | 1546 | !((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) { |
1686 | if (np->rxopt.bits.rxinfo) | 1547 | if (np->rxopt.bits.rxinfo) |
1687 | np->mcast_oif = tcp_v6_iif(opt_skb); | 1548 | np->mcast_oif = inet6_iif(opt_skb); |
1688 | if (np->rxopt.bits.rxhlim) | 1549 | if (np->rxopt.bits.rxhlim) |
1689 | np->mcast_hops = opt_skb->nh.ipv6h->hop_limit; | 1550 | np->mcast_hops = opt_skb->nh.ipv6h->hop_limit; |
1690 | if (ipv6_opt_accepted(sk, opt_skb)) { | 1551 | if (ipv6_opt_accepted(sk, opt_skb)) { |
@@ -1739,8 +1600,9 @@ static int tcp_v6_rcv(struct sk_buff **pskb, unsigned int *nhoffp) | |||
1739 | TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(skb->nh.ipv6h); | 1600 | TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(skb->nh.ipv6h); |
1740 | TCP_SKB_CB(skb)->sacked = 0; | 1601 | TCP_SKB_CB(skb)->sacked = 0; |
1741 | 1602 | ||
1742 | sk = __tcp_v6_lookup(&skb->nh.ipv6h->saddr, th->source, | 1603 | sk = __inet6_lookup(&tcp_hashinfo, &skb->nh.ipv6h->saddr, th->source, |
1743 | &skb->nh.ipv6h->daddr, ntohs(th->dest), tcp_v6_iif(skb)); | 1604 | &skb->nh.ipv6h->daddr, ntohs(th->dest), |
1605 | inet6_iif(skb)); | ||
1744 | 1606 | ||
1745 | if (!sk) | 1607 | if (!sk) |
1746 | goto no_tcp_socket; | 1608 | goto no_tcp_socket; |
@@ -1795,26 +1657,29 @@ discard_and_relse: | |||
1795 | 1657 | ||
1796 | do_time_wait: | 1658 | do_time_wait: |
1797 | if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { | 1659 | if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { |
1798 | tcp_tw_put((struct tcp_tw_bucket *) sk); | 1660 | inet_twsk_put((struct inet_timewait_sock *)sk); |
1799 | goto discard_it; | 1661 | goto discard_it; |
1800 | } | 1662 | } |
1801 | 1663 | ||
1802 | if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) { | 1664 | if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) { |
1803 | TCP_INC_STATS_BH(TCP_MIB_INERRS); | 1665 | TCP_INC_STATS_BH(TCP_MIB_INERRS); |
1804 | tcp_tw_put((struct tcp_tw_bucket *) sk); | 1666 | inet_twsk_put((struct inet_timewait_sock *)sk); |
1805 | goto discard_it; | 1667 | goto discard_it; |
1806 | } | 1668 | } |
1807 | 1669 | ||
1808 | switch(tcp_timewait_state_process((struct tcp_tw_bucket *)sk, | 1670 | switch (tcp_timewait_state_process((struct inet_timewait_sock *)sk, |
1809 | skb, th, skb->len)) { | 1671 | skb, th)) { |
1810 | case TCP_TW_SYN: | 1672 | case TCP_TW_SYN: |
1811 | { | 1673 | { |
1812 | struct sock *sk2; | 1674 | struct sock *sk2; |
1813 | 1675 | ||
1814 | sk2 = tcp_v6_lookup_listener(&skb->nh.ipv6h->daddr, ntohs(th->dest), tcp_v6_iif(skb)); | 1676 | sk2 = inet6_lookup_listener(&tcp_hashinfo, |
1677 | &skb->nh.ipv6h->daddr, | ||
1678 | ntohs(th->dest), inet6_iif(skb)); | ||
1815 | if (sk2 != NULL) { | 1679 | if (sk2 != NULL) { |
1816 | tcp_tw_deschedule((struct tcp_tw_bucket *)sk); | 1680 | struct inet_timewait_sock *tw = inet_twsk(sk); |
1817 | tcp_tw_put((struct tcp_tw_bucket *)sk); | 1681 | inet_twsk_deschedule(tw, &tcp_death_row); |
1682 | inet_twsk_put(tw); | ||
1818 | sk = sk2; | 1683 | sk = sk2; |
1819 | goto process; | 1684 | goto process; |
1820 | } | 1685 | } |
@@ -1983,7 +1848,7 @@ static struct tcp_func ipv6_specific = { | |||
1983 | static struct tcp_func ipv6_mapped = { | 1848 | static struct tcp_func ipv6_mapped = { |
1984 | .queue_xmit = ip_queue_xmit, | 1849 | .queue_xmit = ip_queue_xmit, |
1985 | .send_check = tcp_v4_send_check, | 1850 | .send_check = tcp_v4_send_check, |
1986 | .rebuild_header = tcp_v4_rebuild_header, | 1851 | .rebuild_header = inet_sk_rebuild_header, |
1987 | .conn_request = tcp_v6_conn_request, | 1852 | .conn_request = tcp_v6_conn_request, |
1988 | .syn_recv_sock = tcp_v6_syn_recv_sock, | 1853 | .syn_recv_sock = tcp_v6_syn_recv_sock, |
1989 | .remember_stamp = tcp_v4_remember_stamp, | 1854 | .remember_stamp = tcp_v4_remember_stamp, |
@@ -2002,13 +1867,14 @@ static struct tcp_func ipv6_mapped = { | |||
2002 | */ | 1867 | */ |
2003 | static int tcp_v6_init_sock(struct sock *sk) | 1868 | static int tcp_v6_init_sock(struct sock *sk) |
2004 | { | 1869 | { |
1870 | struct inet_connection_sock *icsk = inet_csk(sk); | ||
2005 | struct tcp_sock *tp = tcp_sk(sk); | 1871 | struct tcp_sock *tp = tcp_sk(sk); |
2006 | 1872 | ||
2007 | skb_queue_head_init(&tp->out_of_order_queue); | 1873 | skb_queue_head_init(&tp->out_of_order_queue); |
2008 | tcp_init_xmit_timers(sk); | 1874 | tcp_init_xmit_timers(sk); |
2009 | tcp_prequeue_init(tp); | 1875 | tcp_prequeue_init(tp); |
2010 | 1876 | ||
2011 | tp->rto = TCP_TIMEOUT_INIT; | 1877 | icsk->icsk_rto = TCP_TIMEOUT_INIT; |
2012 | tp->mdev = TCP_TIMEOUT_INIT; | 1878 | tp->mdev = TCP_TIMEOUT_INIT; |
2013 | 1879 | ||
2014 | /* So many TCP implementations out there (incorrectly) count the | 1880 | /* So many TCP implementations out there (incorrectly) count the |
@@ -2030,7 +1896,7 @@ static int tcp_v6_init_sock(struct sock *sk) | |||
2030 | sk->sk_state = TCP_CLOSE; | 1896 | sk->sk_state = TCP_CLOSE; |
2031 | 1897 | ||
2032 | tp->af_specific = &ipv6_specific; | 1898 | tp->af_specific = &ipv6_specific; |
2033 | tp->ca_ops = &tcp_init_congestion_ops; | 1899 | icsk->icsk_ca_ops = &tcp_init_congestion_ops; |
2034 | sk->sk_write_space = sk_stream_write_space; | 1900 | sk->sk_write_space = sk_stream_write_space; |
2035 | sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); | 1901 | sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); |
2036 | 1902 | ||
@@ -2044,8 +1910,6 @@ static int tcp_v6_init_sock(struct sock *sk) | |||
2044 | 1910 | ||
2045 | static int tcp_v6_destroy_sock(struct sock *sk) | 1911 | static int tcp_v6_destroy_sock(struct sock *sk) |
2046 | { | 1912 | { |
2047 | extern int tcp_v4_destroy_sock(struct sock *sk); | ||
2048 | |||
2049 | tcp_v4_destroy_sock(sk); | 1913 | tcp_v4_destroy_sock(sk); |
2050 | return inet6_destroy_sock(sk); | 1914 | return inet6_destroy_sock(sk); |
2051 | } | 1915 | } |
@@ -2091,18 +1955,20 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i) | |||
2091 | unsigned long timer_expires; | 1955 | unsigned long timer_expires; |
2092 | struct inet_sock *inet = inet_sk(sp); | 1956 | struct inet_sock *inet = inet_sk(sp); |
2093 | struct tcp_sock *tp = tcp_sk(sp); | 1957 | struct tcp_sock *tp = tcp_sk(sp); |
1958 | const struct inet_connection_sock *icsk = inet_csk(sp); | ||
2094 | struct ipv6_pinfo *np = inet6_sk(sp); | 1959 | struct ipv6_pinfo *np = inet6_sk(sp); |
2095 | 1960 | ||
2096 | dest = &np->daddr; | 1961 | dest = &np->daddr; |
2097 | src = &np->rcv_saddr; | 1962 | src = &np->rcv_saddr; |
2098 | destp = ntohs(inet->dport); | 1963 | destp = ntohs(inet->dport); |
2099 | srcp = ntohs(inet->sport); | 1964 | srcp = ntohs(inet->sport); |
2100 | if (tp->pending == TCP_TIME_RETRANS) { | 1965 | |
1966 | if (icsk->icsk_pending == ICSK_TIME_RETRANS) { | ||
2101 | timer_active = 1; | 1967 | timer_active = 1; |
2102 | timer_expires = tp->timeout; | 1968 | timer_expires = icsk->icsk_timeout; |
2103 | } else if (tp->pending == TCP_TIME_PROBE0) { | 1969 | } else if (icsk->icsk_pending == ICSK_TIME_PROBE0) { |
2104 | timer_active = 4; | 1970 | timer_active = 4; |
2105 | timer_expires = tp->timeout; | 1971 | timer_expires = icsk->icsk_timeout; |
2106 | } else if (timer_pending(&sp->sk_timer)) { | 1972 | } else if (timer_pending(&sp->sk_timer)) { |
2107 | timer_active = 2; | 1973 | timer_active = 2; |
2108 | timer_expires = sp->sk_timer.expires; | 1974 | timer_expires = sp->sk_timer.expires; |
@@ -2123,28 +1989,31 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i) | |||
2123 | tp->write_seq-tp->snd_una, tp->rcv_nxt-tp->copied_seq, | 1989 | tp->write_seq-tp->snd_una, tp->rcv_nxt-tp->copied_seq, |
2124 | timer_active, | 1990 | timer_active, |
2125 | jiffies_to_clock_t(timer_expires - jiffies), | 1991 | jiffies_to_clock_t(timer_expires - jiffies), |
2126 | tp->retransmits, | 1992 | icsk->icsk_retransmits, |
2127 | sock_i_uid(sp), | 1993 | sock_i_uid(sp), |
2128 | tp->probes_out, | 1994 | icsk->icsk_probes_out, |
2129 | sock_i_ino(sp), | 1995 | sock_i_ino(sp), |
2130 | atomic_read(&sp->sk_refcnt), sp, | 1996 | atomic_read(&sp->sk_refcnt), sp, |
2131 | tp->rto, tp->ack.ato, (tp->ack.quick<<1)|tp->ack.pingpong, | 1997 | icsk->icsk_rto, |
1998 | icsk->icsk_ack.ato, | ||
1999 | (icsk->icsk_ack.quick << 1 ) | icsk->icsk_ack.pingpong, | ||
2132 | tp->snd_cwnd, tp->snd_ssthresh>=0xFFFF?-1:tp->snd_ssthresh | 2000 | tp->snd_cwnd, tp->snd_ssthresh>=0xFFFF?-1:tp->snd_ssthresh |
2133 | ); | 2001 | ); |
2134 | } | 2002 | } |
2135 | 2003 | ||
2136 | static void get_timewait6_sock(struct seq_file *seq, | 2004 | static void get_timewait6_sock(struct seq_file *seq, |
2137 | struct tcp_tw_bucket *tw, int i) | 2005 | struct inet_timewait_sock *tw, int i) |
2138 | { | 2006 | { |
2139 | struct in6_addr *dest, *src; | 2007 | struct in6_addr *dest, *src; |
2140 | __u16 destp, srcp; | 2008 | __u16 destp, srcp; |
2009 | struct tcp6_timewait_sock *tcp6tw = tcp6_twsk((struct sock *)tw); | ||
2141 | int ttd = tw->tw_ttd - jiffies; | 2010 | int ttd = tw->tw_ttd - jiffies; |
2142 | 2011 | ||
2143 | if (ttd < 0) | 2012 | if (ttd < 0) |
2144 | ttd = 0; | 2013 | ttd = 0; |
2145 | 2014 | ||
2146 | dest = &tw->tw_v6_daddr; | 2015 | dest = &tcp6tw->tw_v6_daddr; |
2147 | src = &tw->tw_v6_rcv_saddr; | 2016 | src = &tcp6tw->tw_v6_rcv_saddr; |
2148 | destp = ntohs(tw->tw_dport); | 2017 | destp = ntohs(tw->tw_dport); |
2149 | srcp = ntohs(tw->tw_sport); | 2018 | srcp = ntohs(tw->tw_sport); |
2150 | 2019 | ||
@@ -2219,7 +2088,7 @@ struct proto tcpv6_prot = { | |||
2219 | .close = tcp_close, | 2088 | .close = tcp_close, |
2220 | .connect = tcp_v6_connect, | 2089 | .connect = tcp_v6_connect, |
2221 | .disconnect = tcp_disconnect, | 2090 | .disconnect = tcp_disconnect, |
2222 | .accept = tcp_accept, | 2091 | .accept = inet_csk_accept, |
2223 | .ioctl = tcp_ioctl, | 2092 | .ioctl = tcp_ioctl, |
2224 | .init = tcp_v6_init_sock, | 2093 | .init = tcp_v6_init_sock, |
2225 | .destroy = tcp_v6_destroy_sock, | 2094 | .destroy = tcp_v6_destroy_sock, |
@@ -2236,11 +2105,13 @@ struct proto tcpv6_prot = { | |||
2236 | .sockets_allocated = &tcp_sockets_allocated, | 2105 | .sockets_allocated = &tcp_sockets_allocated, |
2237 | .memory_allocated = &tcp_memory_allocated, | 2106 | .memory_allocated = &tcp_memory_allocated, |
2238 | .memory_pressure = &tcp_memory_pressure, | 2107 | .memory_pressure = &tcp_memory_pressure, |
2108 | .orphan_count = &tcp_orphan_count, | ||
2239 | .sysctl_mem = sysctl_tcp_mem, | 2109 | .sysctl_mem = sysctl_tcp_mem, |
2240 | .sysctl_wmem = sysctl_tcp_wmem, | 2110 | .sysctl_wmem = sysctl_tcp_wmem, |
2241 | .sysctl_rmem = sysctl_tcp_rmem, | 2111 | .sysctl_rmem = sysctl_tcp_rmem, |
2242 | .max_header = MAX_TCP_HEADER, | 2112 | .max_header = MAX_TCP_HEADER, |
2243 | .obj_size = sizeof(struct tcp6_sock), | 2113 | .obj_size = sizeof(struct tcp6_sock), |
2114 | .twsk_obj_size = sizeof(struct tcp6_timewait_sock), | ||
2244 | .rsk_prot = &tcp6_request_sock_ops, | 2115 | .rsk_prot = &tcp6_request_sock_ops, |
2245 | }; | 2116 | }; |
2246 | 2117 | ||
@@ -2250,8 +2121,6 @@ static struct inet6_protocol tcpv6_protocol = { | |||
2250 | .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, | 2121 | .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, |
2251 | }; | 2122 | }; |
2252 | 2123 | ||
2253 | extern struct proto_ops inet6_stream_ops; | ||
2254 | |||
2255 | static struct inet_protosw tcpv6_protosw = { | 2124 | static struct inet_protosw tcpv6_protosw = { |
2256 | .type = SOCK_STREAM, | 2125 | .type = SOCK_STREAM, |
2257 | .protocol = IPPROTO_TCP, | 2126 | .protocol = IPPROTO_TCP, |