aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/tcp_ipv6.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r--net/ipv6/tcp_ipv6.c78
1 files changed, 7 insertions, 71 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index bf41f84d6692..5a10d30cec4a 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -48,6 +48,7 @@
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/inet6_hashtables.h>
51#include <net/inet6_connection_sock.h>
51#include <net/ipv6.h> 52#include <net/ipv6.h>
52#include <net/transp_v6.h> 53#include <net/transp_v6.h>
53#include <net/addrconf.h> 54#include <net/addrconf.h>
@@ -118,60 +119,6 @@ static void tcp_v6_hash(struct sock *sk)
118 } 119 }
119} 120}
120 121
121/*
122 * Open request hash tables.
123 */
124
125static u32 tcp_v6_synq_hash(const struct in6_addr *raddr, const u16 rport, const u32 rnd)
126{
127 u32 a, b, c;
128
129 a = raddr->s6_addr32[0];
130 b = raddr->s6_addr32[1];
131 c = raddr->s6_addr32[2];
132
133 a += JHASH_GOLDEN_RATIO;
134 b += JHASH_GOLDEN_RATIO;
135 c += rnd;
136 __jhash_mix(a, b, c);
137
138 a += raddr->s6_addr32[3];
139 b += (u32) rport;
140 __jhash_mix(a, b, c);
141
142 return c & (TCP_SYNQ_HSIZE - 1);
143}
144
145static struct request_sock *tcp_v6_search_req(const struct sock *sk,
146 struct request_sock ***prevp,
147 __u16 rport,
148 struct in6_addr *raddr,
149 struct in6_addr *laddr,
150 int iif)
151{
152 const struct inet_connection_sock *icsk = inet_csk(sk);
153 struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt;
154 struct request_sock *req, **prev;
155
156 for (prev = &lopt->syn_table[tcp_v6_synq_hash(raddr, rport, lopt->hash_rnd)];
157 (req = *prev) != NULL;
158 prev = &req->dl_next) {
159 const struct tcp6_request_sock *treq = tcp6_rsk(req);
160
161 if (inet_rsk(req)->rmt_port == rport &&
162 req->rsk_ops->family == AF_INET6 &&
163 ipv6_addr_equal(&treq->rmt_addr, raddr) &&
164 ipv6_addr_equal(&treq->loc_addr, laddr) &&
165 (!treq->iif || treq->iif == iif)) {
166 BUG_TRAP(req->sk == NULL);
167 *prevp = prev;
168 return req;
169 }
170 }
171
172 return NULL;
173}
174
175static __inline__ u16 tcp_v6_check(struct tcphdr *th, int len, 122static __inline__ u16 tcp_v6_check(struct tcphdr *th, int len,
176 struct in6_addr *saddr, 123 struct in6_addr *saddr,
177 struct in6_addr *daddr, 124 struct in6_addr *daddr,
@@ -662,8 +609,8 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
662 if (sock_owned_by_user(sk)) 609 if (sock_owned_by_user(sk))
663 goto out; 610 goto out;
664 611
665 req = tcp_v6_search_req(sk, &prev, th->dest, &hdr->daddr, 612 req = inet6_csk_search_req(sk, &prev, th->dest, &hdr->daddr,
666 &hdr->saddr, inet6_iif(skb)); 613 &hdr->saddr, inet6_iif(skb));
667 if (!req) 614 if (!req)
668 goto out; 615 goto out;
669 616
@@ -978,8 +925,9 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
978 struct sock *nsk; 925 struct sock *nsk;
979 926
980 /* Find possible connection requests. */ 927 /* Find possible connection requests. */
981 req = tcp_v6_search_req(sk, &prev, th->source, &skb->nh.ipv6h->saddr, 928 req = inet6_csk_search_req(sk, &prev, th->source,
982 &skb->nh.ipv6h->daddr, inet6_iif(skb)); 929 &skb->nh.ipv6h->saddr,
930 &skb->nh.ipv6h->daddr, inet6_iif(skb));
983 if (req) 931 if (req)
984 return tcp_check_req(sk, skb, req, prev); 932 return tcp_check_req(sk, skb, req, prev);
985 933
@@ -1003,17 +951,6 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
1003 return sk; 951 return sk;
1004} 952}
1005 953
1006static void tcp_v6_synq_add(struct sock *sk, struct request_sock *req)
1007{
1008 struct inet_connection_sock *icsk = inet_csk(sk);
1009 struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt;
1010 const u32 h = tcp_v6_synq_hash(&tcp6_rsk(req)->rmt_addr, inet_rsk(req)->rmt_port, lopt->hash_rnd);
1011
1012 reqsk_queue_hash_req(&icsk->icsk_accept_queue, h, req, TCP_TIMEOUT_INIT);
1013 inet_csk_reqsk_queue_added(sk, TCP_TIMEOUT_INIT);
1014}
1015
1016
1017/* FIXME: this is substantially similar to the ipv4 code. 954/* FIXME: this is substantially similar to the ipv4 code.
1018 * Can some kind of merge be done? -- erics 955 * Can some kind of merge be done? -- erics
1019 */ 956 */
@@ -1083,8 +1020,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1083 if (tcp_v6_send_synack(sk, req, NULL)) 1020 if (tcp_v6_send_synack(sk, req, NULL))
1084 goto drop; 1021 goto drop;
1085 1022
1086 tcp_v6_synq_add(sk, req); 1023 inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT);
1087
1088 return 0; 1024 return 0;
1089 1025
1090drop: 1026drop: