aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@mandriva.com>2005-08-12 08:19:38 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2005-08-29 18:57:24 -0400
commit505cbfc577f3fa778005e2800b869eca25727d5f (patch)
treea823df4b3e919b06b08d49014ad233c48a5903ff
parentb766b305d3f2d8be173e5d9853534ea1afdbabba (diff)
[IPV6]: Generalise the tcp_v6_lookup routines
In the same way as was done with the v4 counterparts, this will be moved to inet6_hashtables.c. Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/ipv6.h5
-rw-r--r--include/net/inet6_hashtables.h26
-rw-r--r--net/ipv4/Kconfig3
-rw-r--r--net/ipv4/tcp_diag.c40
-rw-r--r--net/ipv6/tcp_ipv6.c139
5 files changed, 122 insertions, 91 deletions
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 777339b68464..3c7dbc6a0a70 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -193,6 +193,11 @@ struct inet6_skb_parm {
193 193
194#define IP6CB(skb) ((struct inet6_skb_parm*)((skb)->cb)) 194#define IP6CB(skb) ((struct inet6_skb_parm*)((skb)->cb))
195 195
196static inline int inet6_iif(const struct sk_buff *skb)
197{
198 return IP6CB(skb)->iif;
199}
200
196struct tcp6_request_sock { 201struct tcp6_request_sock {
197 struct tcp_request_sock req; 202 struct tcp_request_sock req;
198 struct in6_addr loc_addr; 203 struct in6_addr loc_addr;
diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h
new file mode 100644
index 000000000000..297c2b16967a
--- /dev/null
+++ b/include/net/inet6_hashtables.h
@@ -0,0 +1,26 @@
1/*
2 * INET An implementation of the TCP/IP protocol suite for the LINUX
3 * operating system. INET is implemented using the BSD Socket
4 * interface as the means of communication with the user level.
5 *
6 * Authors: Lotsa people, from code originally in tcp
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 */
13
14#ifndef _INET6_HASHTABLES_H
15#define _INET6_HASHTABLES_H
16
17#include <linux/types.h>
18
19struct in6_addr;
20struct inet_hashinfo;
21
22extern struct sock *inet6_lookup(struct inet_hashinfo *hashinfo,
23 const struct in6_addr *saddr, const u16 sport,
24 const struct in6_addr *daddr, const u16 dport,
25 const int dif);
26#endif /* _INET6_HASHTABLES_H */
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index c844954c1ad5..a79b4f9c10c5 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -425,9 +425,6 @@ config IP_TCPDIAG
425 425
426 If unsure, say Y. 426 If unsure, say Y.
427 427
428config IP_TCPDIAG_IPV6
429 def_bool (IP_TCPDIAG=y && IPV6=y) || (IP_TCPDIAG=m && IPV6)
430
431config IP_TCPDIAG_DCCP 428config IP_TCPDIAG_DCCP
432 def_bool (IP_TCPDIAG=y && IP_DCCP=y) || (IP_TCPDIAG=m && IP_DCCP) 429 def_bool (IP_TCPDIAG=y && IP_DCCP=y) || (IP_TCPDIAG=m && IP_DCCP)
433 430
diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c
index 8bf495c698f8..b812191b2f5c 100644
--- a/net/ipv4/tcp_diag.c
+++ b/net/ipv4/tcp_diag.c
@@ -24,6 +24,10 @@
24#include <net/tcp.h> 24#include <net/tcp.h>
25#include <net/ipv6.h> 25#include <net/ipv6.h>
26#include <net/inet_common.h> 26#include <net/inet_common.h>
27#include <net/inet_connection_sock.h>
28#include <net/inet_hashtables.h>
29#include <net/inet_timewait_sock.h>
30#include <net/inet6_hashtables.h>
27 31
28#include <linux/inet.h> 32#include <linux/inet.h>
29#include <linux/stddef.h> 33#include <linux/stddef.h>
@@ -102,7 +106,7 @@ static int tcpdiag_fill(struct sk_buff *skb, struct sock *sk,
102 r->tcpdiag_wqueue = 0; 106 r->tcpdiag_wqueue = 0;
103 r->tcpdiag_uid = 0; 107 r->tcpdiag_uid = 0;
104 r->tcpdiag_inode = 0; 108 r->tcpdiag_inode = 0;
105#ifdef CONFIG_IP_TCPDIAG_IPV6 109#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
106 if (r->tcpdiag_family == AF_INET6) { 110 if (r->tcpdiag_family == AF_INET6) {
107 const struct tcp6_timewait_sock *tcp6tw = tcp6_twsk(sk); 111 const struct tcp6_timewait_sock *tcp6tw = tcp6_twsk(sk);
108 112
@@ -121,7 +125,7 @@ static int tcpdiag_fill(struct sk_buff *skb, struct sock *sk,
121 r->id.tcpdiag_src[0] = inet->rcv_saddr; 125 r->id.tcpdiag_src[0] = inet->rcv_saddr;
122 r->id.tcpdiag_dst[0] = inet->daddr; 126 r->id.tcpdiag_dst[0] = inet->daddr;
123 127
124#ifdef CONFIG_IP_TCPDIAG_IPV6 128#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
125 if (r->tcpdiag_family == AF_INET6) { 129 if (r->tcpdiag_family == AF_INET6) {
126 struct ipv6_pinfo *np = inet6_sk(sk); 130 struct ipv6_pinfo *np = inet6_sk(sk);
127 131
@@ -196,19 +200,6 @@ nlmsg_failure:
196 return -1; 200 return -1;
197} 201}
198 202
199#ifdef CONFIG_IP_TCPDIAG_IPV6
200extern struct sock *tcp_v6_lookup(struct in6_addr *saddr, u16 sport,
201 struct in6_addr *daddr, u16 dport,
202 int dif);
203#else
204static inline struct sock *tcp_v6_lookup(struct in6_addr *saddr, u16 sport,
205 struct in6_addr *daddr, u16 dport,
206 int dif)
207{
208 return NULL;
209}
210#endif
211
212static int tcpdiag_get_exact(struct sk_buff *in_skb, const struct nlmsghdr *nlh) 203static int tcpdiag_get_exact(struct sk_buff *in_skb, const struct nlmsghdr *nlh)
213{ 204{
214 int err; 205 int err;
@@ -225,11 +216,14 @@ static int tcpdiag_get_exact(struct sk_buff *in_skb, const struct nlmsghdr *nlh)
225 req->id.tcpdiag_dport, req->id.tcpdiag_src[0], 216 req->id.tcpdiag_dport, req->id.tcpdiag_src[0],
226 req->id.tcpdiag_sport, req->id.tcpdiag_if); 217 req->id.tcpdiag_sport, req->id.tcpdiag_if);
227 } 218 }
228#ifdef CONFIG_IP_TCPDIAG_IPV6 219#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
229 else if (req->tcpdiag_family == AF_INET6) { 220 else if (req->tcpdiag_family == AF_INET6) {
230 sk = tcp_v6_lookup((struct in6_addr*)req->id.tcpdiag_dst, req->id.tcpdiag_dport, 221 sk = inet6_lookup(hashinfo,
231 (struct in6_addr*)req->id.tcpdiag_src, req->id.tcpdiag_sport, 222 (struct in6_addr*)req->id.tcpdiag_dst,
232 req->id.tcpdiag_if); 223 req->id.tcpdiag_dport,
224 (struct in6_addr*)req->id.tcpdiag_src,
225 req->id.tcpdiag_sport,
226 req->id.tcpdiag_if);
233 } 227 }
234#endif 228#endif
235 else { 229 else {
@@ -440,7 +434,7 @@ static int tcpdiag_dump_sock(struct sk_buff *skb, struct sock *sk,
440 struct inet_sock *inet = inet_sk(sk); 434 struct inet_sock *inet = inet_sk(sk);
441 435
442 entry.family = sk->sk_family; 436 entry.family = sk->sk_family;
443#ifdef CONFIG_IP_TCPDIAG_IPV6 437#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
444 if (entry.family == AF_INET6) { 438 if (entry.family == AF_INET6) {
445 struct ipv6_pinfo *np = inet6_sk(sk); 439 struct ipv6_pinfo *np = inet6_sk(sk);
446 440
@@ -502,7 +496,7 @@ static int tcpdiag_fill_req(struct sk_buff *skb, struct sock *sk,
502 r->tcpdiag_wqueue = 0; 496 r->tcpdiag_wqueue = 0;
503 r->tcpdiag_uid = sock_i_uid(sk); 497 r->tcpdiag_uid = sock_i_uid(sk);
504 r->tcpdiag_inode = 0; 498 r->tcpdiag_inode = 0;
505#ifdef CONFIG_IP_TCPDIAG_IPV6 499#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
506 if (r->tcpdiag_family == AF_INET6) { 500 if (r->tcpdiag_family == AF_INET6) {
507 ipv6_addr_copy((struct in6_addr *)r->id.tcpdiag_src, 501 ipv6_addr_copy((struct in6_addr *)r->id.tcpdiag_src,
508 &tcp6_rsk(req)->loc_addr); 502 &tcp6_rsk(req)->loc_addr);
@@ -567,13 +561,13 @@ static int tcpdiag_dump_reqs(struct sk_buff *skb, struct sock *sk,
567 561
568 if (bc) { 562 if (bc) {
569 entry.saddr = 563 entry.saddr =
570#ifdef CONFIG_IP_TCPDIAG_IPV6 564#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
571 (entry.family == AF_INET6) ? 565 (entry.family == AF_INET6) ?
572 tcp6_rsk(req)->loc_addr.s6_addr32 : 566 tcp6_rsk(req)->loc_addr.s6_addr32 :
573#endif 567#endif
574 &ireq->loc_addr; 568 &ireq->loc_addr;
575 entry.daddr = 569 entry.daddr =
576#ifdef CONFIG_IP_TCPDIAG_IPV6 570#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
577 (entry.family == AF_INET6) ? 571 (entry.family == AF_INET6) ?
578 tcp6_rsk(req)->rmt_addr.s6_addr32 : 572 tcp6_rsk(req)->rmt_addr.s6_addr32 :
579#endif 573#endif
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 3312cb8742e2..2bc7fafe7668 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -76,26 +76,27 @@ static struct tcp_func ipv6_mapped;
76static struct tcp_func ipv6_specific; 76static struct tcp_func ipv6_specific;
77 77
78/* I have no idea if this is a good hash for v6 or not. -DaveM */ 78/* I have no idea if this is a good hash for v6 or not. -DaveM */
79static __inline__ int tcp_v6_hashfn(struct in6_addr *laddr, u16 lport, 79static inline int inet6_ehashfn(const struct in6_addr *laddr, const u16 lport,
80 struct in6_addr *faddr, u16 fport) 80 const struct in6_addr *faddr, const u16 fport,
81 const int ehash_size)
81{ 82{
82 int hashent = (lport ^ fport); 83 int hashent = (lport ^ fport);
83 84
84 hashent ^= (laddr->s6_addr32[3] ^ faddr->s6_addr32[3]); 85 hashent ^= (laddr->s6_addr32[3] ^ faddr->s6_addr32[3]);
85 hashent ^= hashent>>16; 86 hashent ^= hashent>>16;
86 hashent ^= hashent>>8; 87 hashent ^= hashent>>8;
87 return (hashent & (tcp_hashinfo.ehash_size - 1)); 88 return (hashent & (ehash_size - 1));
88} 89}
89 90
90static __inline__ int tcp_v6_sk_hashfn(struct sock *sk) 91static inline int inet6_sk_ehashfn(const struct sock *sk, const int ehash_size)
91{ 92{
92 struct inet_sock *inet = inet_sk(sk); 93 const struct inet_sock *inet = inet_sk(sk);
93 struct ipv6_pinfo *np = inet6_sk(sk); 94 const struct ipv6_pinfo *np = inet6_sk(sk);
94 struct in6_addr *laddr = &np->rcv_saddr; 95 const struct in6_addr *laddr = &np->rcv_saddr;
95 struct in6_addr *faddr = &np->daddr; 96 const struct in6_addr *faddr = &np->daddr;
96 __u16 lport = inet->num; 97 const __u16 lport = inet->num;
97 __u16 fport = inet->dport; 98 const __u16 fport = inet->dport;
98 return tcp_v6_hashfn(laddr, lport, faddr, fport); 99 return inet6_ehashfn(laddr, lport, faddr, fport, ehash_size);
99} 100}
100 101
101static inline int tcp_v6_bind_conflict(const struct sock *sk, 102static inline int tcp_v6_bind_conflict(const struct sock *sk,
@@ -231,7 +232,7 @@ static __inline__ void __tcp_v6_hash(struct sock *sk)
231 lock = &tcp_hashinfo.lhash_lock; 232 lock = &tcp_hashinfo.lhash_lock;
232 inet_listen_wlock(&tcp_hashinfo); 233 inet_listen_wlock(&tcp_hashinfo);
233 } else { 234 } else {
234 sk->sk_hashent = tcp_v6_sk_hashfn(sk); 235 sk->sk_hashent = inet6_sk_ehashfn(sk, tcp_hashinfo.ehash_size);
235 list = &tcp_hashinfo.ehash[sk->sk_hashent].chain; 236 list = &tcp_hashinfo.ehash[sk->sk_hashent].chain;
236 lock = &tcp_hashinfo.ehash[sk->sk_hashent].lock; 237 lock = &tcp_hashinfo.ehash[sk->sk_hashent].lock;
237 write_lock(lock); 238 write_lock(lock);
@@ -258,7 +259,10 @@ static void tcp_v6_hash(struct sock *sk)
258 } 259 }
259} 260}
260 261
261static struct sock *tcp_v6_lookup_listener(struct in6_addr *daddr, unsigned short hnum, int dif) 262static struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo,
263 const struct in6_addr *daddr,
264 const unsigned short hnum,
265 const int dif)
262{ 266{
263 struct sock *sk; 267 struct sock *sk;
264 struct hlist_node *node; 268 struct hlist_node *node;
@@ -266,8 +270,8 @@ static struct sock *tcp_v6_lookup_listener(struct in6_addr *daddr, unsigned shor
266 int score, hiscore; 270 int score, hiscore;
267 271
268 hiscore=0; 272 hiscore=0;
269 read_lock(&tcp_hashinfo.lhash_lock); 273 read_lock(&hashinfo->lhash_lock);
270 sk_for_each(sk, node, &tcp_hashinfo.listening_hash[inet_lhashfn(hnum)]) { 274 sk_for_each(sk, node, &hashinfo->listening_hash[inet_lhashfn(hnum)]) {
271 if (inet_sk(sk)->num == hnum && sk->sk_family == PF_INET6) { 275 if (inet_sk(sk)->num == hnum && sk->sk_family == PF_INET6) {
272 struct ipv6_pinfo *np = inet6_sk(sk); 276 struct ipv6_pinfo *np = inet6_sk(sk);
273 277
@@ -294,7 +298,7 @@ static struct sock *tcp_v6_lookup_listener(struct in6_addr *daddr, unsigned shor
294 } 298 }
295 if (result) 299 if (result)
296 sock_hold(result); 300 sock_hold(result);
297 read_unlock(&tcp_hashinfo.lhash_lock); 301 read_unlock(&hashinfo->lhash_lock);
298 return result; 302 return result;
299} 303}
300 304
@@ -304,9 +308,13 @@ static struct sock *tcp_v6_lookup_listener(struct in6_addr *daddr, unsigned shor
304 * The sockhash lock must be held as a reader here. 308 * The sockhash lock must be held as a reader here.
305 */ 309 */
306 310
307static inline struct sock *__tcp_v6_lookup_established(struct in6_addr *saddr, u16 sport, 311static inline struct sock *
308 struct in6_addr *daddr, u16 hnum, 312 __inet6_lookup_established(struct inet_hashinfo *hashinfo,
309 int dif) 313 const struct in6_addr *saddr,
314 const u16 sport,
315 const struct in6_addr *daddr,
316 const u16 hnum,
317 const int dif)
310{ 318{
311 struct sock *sk; 319 struct sock *sk;
312 const struct hlist_node *node; 320 const struct hlist_node *node;
@@ -314,8 +322,9 @@ static inline struct sock *__tcp_v6_lookup_established(struct in6_addr *saddr, u
314 /* Optimize here for direct hit, only listening connections can 322 /* Optimize here for direct hit, only listening connections can
315 * have wildcards anyways. 323 * have wildcards anyways.
316 */ 324 */
317 const int hash = tcp_v6_hashfn(daddr, hnum, saddr, sport); 325 const int hash = inet6_ehashfn(daddr, hnum, saddr, sport,
318 struct inet_ehash_bucket *head = &tcp_hashinfo.ehash[hash]; 326 hashinfo->ehash_size);
327 struct inet_ehash_bucket *head = &hashinfo->ehash[hash];
319 328
320 read_lock(&head->lock); 329 read_lock(&head->lock);
321 sk_for_each(sk, node, &head->chain) { 330 sk_for_each(sk, node, &head->chain) {
@@ -324,7 +333,7 @@ static inline struct sock *__tcp_v6_lookup_established(struct in6_addr *saddr, u
324 goto hit; /* You sunk my battleship! */ 333 goto hit; /* You sunk my battleship! */
325 } 334 }
326 /* Must check for a TIME_WAIT'er before going to listener hash. */ 335 /* Must check for a TIME_WAIT'er before going to listener hash. */
327 sk_for_each(sk, node, &(head + tcp_hashinfo.ehash_size)->chain) { 336 sk_for_each(sk, node, &(head + hashinfo->ehash_size)->chain) {
328 const struct inet_timewait_sock *tw = inet_twsk(sk); 337 const struct inet_timewait_sock *tw = inet_twsk(sk);
329 338
330 if(*((__u32 *)&(tw->tw_dport)) == ports && 339 if(*((__u32 *)&(tw->tw_dport)) == ports &&
@@ -347,34 +356,36 @@ hit:
347} 356}
348 357
349 358
350static inline struct sock *__tcp_v6_lookup(struct in6_addr *saddr, u16 sport, 359static inline struct sock *__inet6_lookup(struct inet_hashinfo *hashinfo,
351 struct in6_addr *daddr, u16 hnum, 360 const struct in6_addr *saddr,
352 int dif) 361 const u16 sport,
362 const struct in6_addr *daddr,
363 const u16 hnum,
364 const int dif)
353{ 365{
354 struct sock *sk; 366 struct sock *sk = __inet6_lookup_established(hashinfo, saddr, sport,
355 367 daddr, hnum, dif);
356 sk = __tcp_v6_lookup_established(saddr, sport, daddr, hnum, dif);
357
358 if (sk) 368 if (sk)
359 return sk; 369 return sk;
360 370
361 return tcp_v6_lookup_listener(daddr, hnum, dif); 371 return inet6_lookup_listener(hashinfo, daddr, hnum, dif);
362} 372}
363 373
364inline struct sock *tcp_v6_lookup(struct in6_addr *saddr, u16 sport, 374inline struct sock *inet6_lookup(struct inet_hashinfo *hashinfo,
365 struct in6_addr *daddr, u16 dport, 375 const struct in6_addr *saddr, const u16 sport,
366 int dif) 376 const struct in6_addr *daddr, const u16 dport,
377 const int dif)
367{ 378{
368 struct sock *sk; 379 struct sock *sk;
369 380
370 local_bh_disable(); 381 local_bh_disable();
371 sk = __tcp_v6_lookup(saddr, sport, daddr, ntohs(dport), dif); 382 sk = __inet6_lookup(hashinfo, saddr, sport, daddr, ntohs(dport), dif);
372 local_bh_enable(); 383 local_bh_enable();
373 384
374 return sk; 385 return sk;
375} 386}
376 387
377EXPORT_SYMBOL_GPL(tcp_v6_lookup); 388EXPORT_SYMBOL_GPL(inet6_lookup);
378 389
379 390
380/* 391/*
@@ -454,16 +465,17 @@ static __u32 tcp_v6_init_sequence(struct sock *sk, struct sk_buff *skb)
454 } 465 }
455} 466}
456 467
457static int __tcp_v6_check_established(struct sock *sk, __u16 lport, 468static int __tcp_v6_check_established(struct sock *sk, const __u16 lport,
458 struct inet_timewait_sock **twp) 469 struct inet_timewait_sock **twp)
459{ 470{
460 struct inet_sock *inet = inet_sk(sk); 471 struct inet_sock *inet = inet_sk(sk);
461 struct ipv6_pinfo *np = inet6_sk(sk); 472 const struct ipv6_pinfo *np = inet6_sk(sk);
462 struct in6_addr *daddr = &np->rcv_saddr; 473 const struct in6_addr *daddr = &np->rcv_saddr;
463 struct in6_addr *saddr = &np->daddr; 474 const struct in6_addr *saddr = &np->daddr;
464 int dif = sk->sk_bound_dev_if; 475 const int dif = sk->sk_bound_dev_if;
465 const u32 ports = INET_COMBINED_PORTS(inet->dport, lport); 476 const u32 ports = INET_COMBINED_PORTS(inet->dport, lport);
466 const int hash = tcp_v6_hashfn(daddr, inet->num, saddr, inet->dport); 477 const int hash = inet6_ehashfn(daddr, inet->num, saddr, inet->dport,
478 tcp_hashinfo.ehash_size);
467 struct inet_ehash_bucket *head = &tcp_hashinfo.ehash[hash]; 479 struct inet_ehash_bucket *head = &tcp_hashinfo.ehash[hash];
468 struct sock *sk2; 480 struct sock *sk2;
469 const struct hlist_node *node; 481 const struct hlist_node *node;
@@ -637,11 +649,6 @@ out:
637 } 649 }
638} 650}
639 651
640static __inline__ int tcp_v6_iif(struct sk_buff *skb)
641{
642 return IP6CB(skb)->iif;
643}
644
645static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, 652static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
646 int addr_len) 653 int addr_len)
647{ 654{
@@ -833,14 +840,15 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
833 int type, int code, int offset, __u32 info) 840 int type, int code, int offset, __u32 info)
834{ 841{
835 struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data; 842 struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data;
836 struct tcphdr *th = (struct tcphdr *)(skb->data+offset); 843 const struct tcphdr *th = (struct tcphdr *)(skb->data+offset);
837 struct ipv6_pinfo *np; 844 struct ipv6_pinfo *np;
838 struct sock *sk; 845 struct sock *sk;
839 int err; 846 int err;
840 struct tcp_sock *tp; 847 struct tcp_sock *tp;
841 __u32 seq; 848 __u32 seq;
842 849
843 sk = tcp_v6_lookup(&hdr->daddr, th->dest, &hdr->saddr, th->source, skb->dev->ifindex); 850 sk = inet6_lookup(&tcp_hashinfo, &hdr->daddr, th->dest, &hdr->saddr,
851 th->source, skb->dev->ifindex);
844 852
845 if (sk == NULL) { 853 if (sk == NULL) {
846 ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS); 854 ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS);
@@ -927,7 +935,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
927 goto out; 935 goto out;
928 936
929 req = tcp_v6_search_req(sk, &prev, th->dest, &hdr->daddr, 937 req = tcp_v6_search_req(sk, &prev, th->dest, &hdr->daddr,
930 &hdr->saddr, tcp_v6_iif(skb)); 938 &hdr->saddr, inet6_iif(skb));
931 if (!req) 939 if (!req)
932 goto out; 940 goto out;
933 941
@@ -1138,7 +1146,7 @@ static void tcp_v6_send_reset(struct sk_buff *skb)
1138 buff->csum); 1146 buff->csum);
1139 1147
1140 fl.proto = IPPROTO_TCP; 1148 fl.proto = IPPROTO_TCP;
1141 fl.oif = tcp_v6_iif(skb); 1149 fl.oif = inet6_iif(skb);
1142 fl.fl_ip_dport = t1->dest; 1150 fl.fl_ip_dport = t1->dest;
1143 fl.fl_ip_sport = t1->source; 1151 fl.fl_ip_sport = t1->source;
1144 1152
@@ -1207,7 +1215,7 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
1207 buff->csum); 1215 buff->csum);
1208 1216
1209 fl.proto = IPPROTO_TCP; 1217 fl.proto = IPPROTO_TCP;
1210 fl.oif = tcp_v6_iif(skb); 1218 fl.oif = inet6_iif(skb);
1211 fl.fl_ip_dport = t1->dest; 1219 fl.fl_ip_dport = t1->dest;
1212 fl.fl_ip_sport = t1->source; 1220 fl.fl_ip_sport = t1->source;
1213 1221
@@ -1245,20 +1253,18 @@ static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req)
1245static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb) 1253static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
1246{ 1254{
1247 struct request_sock *req, **prev; 1255 struct request_sock *req, **prev;
1248 struct tcphdr *th = skb->h.th; 1256 const struct tcphdr *th = skb->h.th;
1249 struct sock *nsk; 1257 struct sock *nsk;
1250 1258
1251 /* Find possible connection requests. */ 1259 /* Find possible connection requests. */
1252 req = tcp_v6_search_req(sk, &prev, th->source, &skb->nh.ipv6h->saddr, 1260 req = tcp_v6_search_req(sk, &prev, th->source, &skb->nh.ipv6h->saddr,
1253 &skb->nh.ipv6h->daddr, tcp_v6_iif(skb)); 1261 &skb->nh.ipv6h->daddr, inet6_iif(skb));
1254 if (req) 1262 if (req)
1255 return tcp_check_req(sk, skb, req, prev); 1263 return tcp_check_req(sk, skb, req, prev);
1256 1264
1257 nsk = __tcp_v6_lookup_established(&skb->nh.ipv6h->saddr, 1265 nsk = __inet6_lookup_established(&tcp_hashinfo, &skb->nh.ipv6h->saddr,
1258 th->source, 1266 th->source, &skb->nh.ipv6h->daddr,
1259 &skb->nh.ipv6h->daddr, 1267 ntohs(th->dest), inet6_iif(skb));
1260 ntohs(th->dest),
1261 tcp_v6_iif(skb));
1262 1268
1263 if (nsk) { 1269 if (nsk) {
1264 if (nsk->sk_state != TCP_TIME_WAIT) { 1270 if (nsk->sk_state != TCP_TIME_WAIT) {
@@ -1346,7 +1352,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1346 /* So that link locals have meaning */ 1352 /* So that link locals have meaning */
1347 if (!sk->sk_bound_dev_if && 1353 if (!sk->sk_bound_dev_if &&
1348 ipv6_addr_type(&treq->rmt_addr) & IPV6_ADDR_LINKLOCAL) 1354 ipv6_addr_type(&treq->rmt_addr) & IPV6_ADDR_LINKLOCAL)
1349 treq->iif = tcp_v6_iif(skb); 1355 treq->iif = inet6_iif(skb);
1350 1356
1351 if (isn == 0) 1357 if (isn == 0)
1352 isn = tcp_v6_init_sequence(sk,skb); 1358 isn = tcp_v6_init_sequence(sk,skb);
@@ -1411,7 +1417,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1411 newsk->sk_backlog_rcv = tcp_v4_do_rcv; 1417 newsk->sk_backlog_rcv = tcp_v4_do_rcv;
1412 newnp->pktoptions = NULL; 1418 newnp->pktoptions = NULL;
1413 newnp->opt = NULL; 1419 newnp->opt = NULL;
1414 newnp->mcast_oif = tcp_v6_iif(skb); 1420 newnp->mcast_oif = inet6_iif(skb);
1415 newnp->mcast_hops = skb->nh.ipv6h->hop_limit; 1421 newnp->mcast_hops = skb->nh.ipv6h->hop_limit;
1416 1422
1417 /* 1423 /*
@@ -1516,7 +1522,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1516 skb_set_owner_r(newnp->pktoptions, newsk); 1522 skb_set_owner_r(newnp->pktoptions, newsk);
1517 } 1523 }
1518 newnp->opt = NULL; 1524 newnp->opt = NULL;
1519 newnp->mcast_oif = tcp_v6_iif(skb); 1525 newnp->mcast_oif = inet6_iif(skb);
1520 newnp->mcast_hops = skb->nh.ipv6h->hop_limit; 1526 newnp->mcast_hops = skb->nh.ipv6h->hop_limit;
1521 1527
1522 /* Clone native IPv6 options from listening socket (if any) 1528 /* Clone native IPv6 options from listening socket (if any)
@@ -1691,7 +1697,7 @@ ipv6_pktoptions:
1691 if (TCP_SKB_CB(opt_skb)->end_seq == tp->rcv_nxt && 1697 if (TCP_SKB_CB(opt_skb)->end_seq == tp->rcv_nxt &&
1692 !((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) { 1698 !((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) {
1693 if (np->rxopt.bits.rxinfo) 1699 if (np->rxopt.bits.rxinfo)
1694 np->mcast_oif = tcp_v6_iif(opt_skb); 1700 np->mcast_oif = inet6_iif(opt_skb);
1695 if (np->rxopt.bits.rxhlim) 1701 if (np->rxopt.bits.rxhlim)
1696 np->mcast_hops = opt_skb->nh.ipv6h->hop_limit; 1702 np->mcast_hops = opt_skb->nh.ipv6h->hop_limit;
1697 if (ipv6_opt_accepted(sk, opt_skb)) { 1703 if (ipv6_opt_accepted(sk, opt_skb)) {
@@ -1746,8 +1752,9 @@ static int tcp_v6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
1746 TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(skb->nh.ipv6h); 1752 TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(skb->nh.ipv6h);
1747 TCP_SKB_CB(skb)->sacked = 0; 1753 TCP_SKB_CB(skb)->sacked = 0;
1748 1754
1749 sk = __tcp_v6_lookup(&skb->nh.ipv6h->saddr, th->source, 1755 sk = __inet6_lookup(&tcp_hashinfo, &skb->nh.ipv6h->saddr, th->source,
1750 &skb->nh.ipv6h->daddr, ntohs(th->dest), tcp_v6_iif(skb)); 1756 &skb->nh.ipv6h->daddr, ntohs(th->dest),
1757 inet6_iif(skb));
1751 1758
1752 if (!sk) 1759 if (!sk)
1753 goto no_tcp_socket; 1760 goto no_tcp_socket;
@@ -1818,7 +1825,9 @@ do_time_wait:
1818 { 1825 {
1819 struct sock *sk2; 1826 struct sock *sk2;
1820 1827
1821 sk2 = tcp_v6_lookup_listener(&skb->nh.ipv6h->daddr, ntohs(th->dest), tcp_v6_iif(skb)); 1828 sk2 = inet6_lookup_listener(&tcp_hashinfo,
1829 &skb->nh.ipv6h->daddr,
1830 ntohs(th->dest), inet6_iif(skb));
1822 if (sk2 != NULL) { 1831 if (sk2 != NULL) {
1823 struct inet_timewait_sock *tw = inet_twsk(sk); 1832 struct inet_timewait_sock *tw = inet_twsk(sk);
1824 inet_twsk_deschedule(tw, &tcp_death_row); 1833 inet_twsk_deschedule(tw, &tcp_death_row);