summaryrefslogtreecommitdiffstats
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.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 0a4a95c7c..5fa45dce5 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -5,7 +5,7 @@
* Authors:
* Pedro Roque <roque@di.fc.ul.pt>
*
- * $Id: tcp_ipv6.c,v 1.80 1998/05/02 12:47:15 davem Exp $
+ * $Id: tcp_ipv6.c,v 1.82 1998/06/11 03:15:52 davem Exp $
*
* Based on:
* linux/net/ipv4/tcp.c
@@ -64,9 +64,7 @@ static __inline__ int tcp_v6_hashfn(struct in6_addr *laddr, u16 lport,
{
int hashent = (lport ^ fport);
- hashent ^= (laddr->s6_addr32[0] ^ laddr->s6_addr32[1]);
- hashent ^= (faddr->s6_addr32[0] ^ faddr->s6_addr32[1]);
- hashent ^= (faddr->s6_addr32[2] ^ faddr->s6_addr32[3]);
+ hashent ^= (laddr->s6_addr32[3] ^ faddr->s6_addr32[3]);
return (hashent & ((TCP_HTABLE_SIZE/2) - 1));
}
@@ -145,6 +143,13 @@ go_like_smoke:
static void tcp_v6_hash(struct sock *sk)
{
+ /* Well, I know that it is ugly...
+ All this ->prot, ->af_specific etc. need LARGE cleanup --ANK
+ */
+ if (sk->tp_pinfo.af_tcp.af_specific == &ipv6_mapped) {
+ tcp_prot.hash(sk);
+ return;
+ }
if(sk->state != TCP_CLOSE) {
struct sock **skp;
@@ -213,7 +218,7 @@ static struct sock *tcp_v6_lookup_listener(struct in6_addr *daddr, unsigned shor
hiscore=0;
sk = tcp_listening_hash[tcp_lhashfn(hnum)];
for(; sk; sk = sk->next) {
- if((sk->num == hnum) && (sk->family == AF_INET6)) {
+ if((sk->num == hnum) && (sk->family == PF_INET6)) {
struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
score = 1;
@@ -272,7 +277,7 @@ static inline struct sock *__tcp_v6_lookup(struct tcphdr *th,
/* Must check for a TIME_WAIT'er before going to listener hash. */
for(sk = tcp_established_hash[hash+(TCP_HTABLE_SIZE/2)]; sk; sk = sk->next) {
if(*((__u32 *)&(sk->dport)) == ports &&
- sk->family == AF_INET6) {
+ sk->family == PF_INET6) {
struct tcp_tw_bucket *tw = (struct tcp_tw_bucket *)sk;
if(!ipv6_addr_cmp(&tw->v6_daddr, saddr) &&
!ipv6_addr_cmp(&tw->v6_rcv_saddr, daddr) &&
@@ -415,8 +420,14 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
if (err) {
sk->tp_pinfo.af_tcp.af_specific = &ipv6_specific;
sk->backlog_rcv = tcp_v6_do_rcv;
+ } else {
+ /* Yuup... And it is not the only place... --ANK */
+ ipv6_addr_set(&np->saddr, 0, 0, __constant_htonl(0x0000FFFF),
+ sk->saddr);
+ ipv6_addr_set(&np->rcv_saddr, 0, 0, __constant_htonl(0x0000FFFF),
+ sk->rcv_saddr);
}
-
+
return err;
}