summaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-11-28 03:58:46 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-11-28 03:58:46 +0000
commitb63ad0882a16a5d28003e57f2b0b81dee3fb322b (patch)
tree0a343ce219e2b8b38a5d702d66032c57b83d9720 /net/ipv4
parenta9d7bff9a84dba79609a0002e5321b74c4d64c64 (diff)
Merge with 2.4.0-test11.
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/af_inet.c2
-rw-r--r--net/ipv4/tcp.c4
-rw-r--r--net/ipv4/tcp_ipv4.c147
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)