diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-11-28 03:58:46 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-11-28 03:58:46 +0000 |
commit | b63ad0882a16a5d28003e57f2b0b81dee3fb322b (patch) | |
tree | 0a343ce219e2b8b38a5d702d66032c57b83d9720 /net/ipv4 | |
parent | a9d7bff9a84dba79609a0002e5321b74c4d64c64 (diff) |
Merge with 2.4.0-test11.
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/af_inet.c | 2 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 4 | ||||
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 147 |
3 files changed, 74 insertions, 79 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 584814ad8..3222d25d1 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -5,7 +5,7 @@ * * PF_INET protocol family socket handler. * - * Version: $Id: af_inet.c,v 1.121 2000/10/24 21:26:18 davem Exp $ + * Version: $Id: af_inet.c,v 1.123 2000/11/10 01:42:43 davem Exp $ * * Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 0f97c2d27..6b254e2ad 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp.c,v 1.176 2000/10/06 22:45:41 davem Exp $ + * Version: $Id: tcp.c,v 1.179 2000/11/10 04:02:04 davem Exp $ * * Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> @@ -2011,7 +2011,7 @@ static int wait_for_connect(struct sock * sk, long timeo) */ add_wait_queue_exclusive(sk->sleep, &wait); for (;;) { - current->state = TASK_EXCLUSIVE | TASK_INTERRUPTIBLE; + current->state = TASK_INTERRUPTIBLE; release_sock(sk); if (sk->tp_pinfo.af_tcp.accept_queue == NULL) timeo = schedule_timeout(timeo); diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 1a0f278b4..9f16a976c 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_ipv4.c,v 1.218 2000/10/18 18:04:22 davem Exp $ + * Version: $Id: tcp_ipv4.c,v 1.220 2000/11/14 07:26:02 davem Exp $ * * IPv4 specific functions * @@ -301,7 +301,7 @@ void tcp_put_port(struct sock *sk) local_bh_enable(); } -/* This lock without TASK_EXCLUSIVE is good on UP and it can be very bad on SMP. +/* This lock without WQ_FLAG_EXCLUSIVE is good on UP and it can be very bad on SMP. * Look, when several writers sleep and reader wakes them up, all but one * immediately hit write lock and grab all the cpus. Exclusive sleep solves * this, _but_ remember, it adds useless work on UP machines (wake up each @@ -317,7 +317,7 @@ void tcp_listen_wlock(void) add_wait_queue_exclusive(&tcp_lhash_wait, &wait); for (;;) { - set_current_state(TASK_UNINTERRUPTIBLE|TASK_EXCLUSIVE); + set_current_state(TASK_UNINTERRUPTIBLE); if (atomic_read(&tcp_lhash_users) == 0) break; write_unlock_bh(&tcp_lhash_lock); @@ -1721,93 +1721,88 @@ static void __tcp_v4_rehash(struct sock *sk) sk->prot->hash(sk); } -int tcp_v4_rebuild_header(struct sock *sk) +static int tcp_v4_reselect_saddr(struct sock *sk) { - struct rtable *rt = (struct rtable *)__sk_dst_check(sk, 0); + int err; + struct rtable *rt; + __u32 old_saddr = sk->saddr; __u32 new_saddr; - int want_rewrite = sysctl_ip_dynaddr && sk->state == TCP_SYN_SENT && - !(sk->userlocks & SOCK_BINDADDR_LOCK); + __u32 daddr = sk->daddr; - if (rt == NULL) { - int err; + if(sk->protinfo.af_inet.opt && sk->protinfo.af_inet.opt->srr) + daddr = sk->protinfo.af_inet.opt->faddr; - u32 daddr = sk->daddr; + /* Query new route. */ + err = ip_route_connect(&rt, daddr, 0, + RT_TOS(sk->protinfo.af_inet.tos)|sk->localroute, + sk->bound_dev_if); + if (err) + return err; - if(sk->protinfo.af_inet.opt && sk->protinfo.af_inet.opt->srr) - daddr = sk->protinfo.af_inet.opt->faddr; + __sk_dst_set(sk, &rt->u.dst); + /* sk->route_caps = rt->u.dst.dev->features; */ - err = ip_route_output(&rt, daddr, sk->saddr, - RT_TOS(sk->protinfo.af_inet.tos) | RTO_CONN | sk->localroute, - sk->bound_dev_if); - if (err) { - sk->err_soft=-err; - sk->error_report(sk); - return -1; - } - __sk_dst_set(sk, &rt->u.dst); - } + new_saddr = rt->rt_src; - /* Force route checking if want_rewrite. */ - if (want_rewrite) { - int tmp; - struct rtable *new_rt; - __u32 old_saddr = rt->rt_src; - - /* Query new route using another rt buffer */ - tmp = ip_route_connect(&new_rt, rt->rt_dst, 0, - RT_TOS(sk->protinfo.af_inet.tos)|sk->localroute, - sk->bound_dev_if); - - /* Only useful if different source addrs */ - if (tmp == 0) { - /* - * Only useful if different source addrs - */ - if (new_rt->rt_src != old_saddr ) { - __sk_dst_set(sk, &new_rt->u.dst); - rt = new_rt; - goto do_rewrite; - } - dst_release(&new_rt->u.dst); - } + if (new_saddr == old_saddr) + return 0; + + if (sysctl_ip_dynaddr > 1) { + printk(KERN_INFO "tcp_v4_rebuild_header(): shifting sk->saddr " + "from %d.%d.%d.%d to %d.%d.%d.%d\n", + NIPQUAD(old_saddr), + NIPQUAD(new_saddr)); } + sk->saddr = new_saddr; + sk->rcv_saddr = new_saddr; + + /* XXX The only one ugly spot where we need to + * XXX really change the sockets identity after + * XXX it has entered the hashes. -DaveM + * + * Besides that, it does not check for connection + * uniqueness. Wait for troubles. + */ + __tcp_v4_rehash(sk); return 0; +} -do_rewrite: - new_saddr = rt->rt_src; - - /* Ouch!, this should not happen. */ - if (!sk->saddr || !sk->rcv_saddr) { - printk(KERN_WARNING "tcp_v4_rebuild_header(): not valid sock addrs: " - "saddr=%08X rcv_saddr=%08X\n", - ntohl(sk->saddr), - ntohl(sk->rcv_saddr)); - return -1; - } +int tcp_v4_rebuild_header(struct sock *sk) +{ + struct rtable *rt = (struct rtable *)__sk_dst_check(sk, 0); + u32 daddr; + int err; - if (new_saddr != sk->saddr) { - if (sysctl_ip_dynaddr > 1) { - printk(KERN_INFO "tcp_v4_rebuild_header(): shifting sk->saddr " - "from %d.%d.%d.%d to %d.%d.%d.%d\n", - NIPQUAD(sk->saddr), - NIPQUAD(new_saddr)); - } + /* Route is OK, nothing to do. */ + if (rt != NULL) + return 0; - sk->saddr = new_saddr; - sk->rcv_saddr = new_saddr; + /* Reroute. */ + daddr = sk->daddr; + if(sk->protinfo.af_inet.opt && sk->protinfo.af_inet.opt->srr) + daddr = sk->protinfo.af_inet.opt->faddr; - /* XXX The only one ugly spot where we need to - * XXX really change the sockets identity after - * XXX it has entered the hashes. -DaveM - * - * Besides that, it does not check for connection - * uniqueness. Wait for troubles. - */ - __tcp_v4_rehash(sk); - } - - return 0; + err = ip_route_output(&rt, daddr, sk->saddr, + RT_TOS(sk->protinfo.af_inet.tos) | RTO_CONN | sk->localroute, + sk->bound_dev_if); + if (!err) { + __sk_dst_set(sk, &rt->u.dst); + /* sk->route_caps = rt->u.dst.dev->features; */ + return 0; + } + + /* Routing failed... */ + /* sk->route_caps = 0; */ + + if (!sysctl_ip_dynaddr || + sk->state != TCP_SYN_SENT || + (sk->userlocks & SOCK_BINDADDR_LOCK) || + (err = tcp_v4_reselect_saddr(sk)) != 0) { + sk->err_soft=-err; + /* sk->error_report(sk); */ + } + return err; } static void v4_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr) |