diff options
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/icmp.c | 6 | ||||
-rw-r--r-- | net/ipv4/ip_input.c | 5 | ||||
-rw-r--r-- | net/ipv4/protocol.c | 17 | ||||
-rw-r--r-- | net/ipv4/tcp_input.c | 12 | ||||
-rw-r--r-- | net/ipv4/udp.c | 3 |
5 files changed, 24 insertions, 19 deletions
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index c01d447b1..d7da63f4e 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -3,7 +3,7 @@ * * Alan Cox, <alan@redhat.com> * - * Version: $Id: icmp.c,v 1.64 2000/02/09 11:16:40 davem Exp $ + * Version: $Id: icmp.c,v 1.65 2000/02/22 23:54:25 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -801,9 +801,10 @@ static void icmp_unreach(struct icmphdr *icmph, struct sk_buff *skb, int len) /* * This can't change while we are doing it. + * Callers have obtained BR_NETPROTO_LOCK so + * we are OK. */ - read_lock(&inet_protocol_lock); ipprot = (struct inet_protocol *) inet_protos[hash]; while(ipprot != NULL) { struct inet_protocol *nextip; @@ -822,7 +823,6 @@ static void icmp_unreach(struct icmphdr *icmph, struct sk_buff *skb, int len) ipprot = nextip; } - read_unlock(&inet_protocol_lock); } diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 23389d249..0c755dbcd 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -5,7 +5,7 @@ * * The Internet Protocol (IP) module. * - * Version: $Id: ip_input.c,v 1.45 2000/01/16 05:11:22 davem Exp $ + * Version: $Id: ip_input.c,v 1.46 2000/02/22 23:54:26 davem Exp $ * * Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> @@ -241,7 +241,6 @@ static inline int ip_local_deliver_finish(struct sk_buff *skb) if(raw_sk != NULL) raw_sk = raw_v4_input(skb, iph, hash); - read_lock(&inet_protocol_lock); ipprot = (struct inet_protocol *) inet_protos[hash]; flag = 0; if(ipprot != NULL) { @@ -254,13 +253,11 @@ static inline int ip_local_deliver_finish(struct sk_buff *skb) ret = ipprot->handler(skb, (ntohs(iph->tot_len) - (iph->ihl * 4))); - read_unlock(&inet_protocol_lock); return ret; } else { flag = ip_run_ipprot(skb, iph, ipprot, (raw_sk != NULL)); } } - read_unlock(&inet_protocol_lock); /* All protocols checked. * If this packet was a broadcast, we may *not* reply to it, since that diff --git a/net/ipv4/protocol.c b/net/ipv4/protocol.c index 2b61e6466..4839764e8 100644 --- a/net/ipv4/protocol.c +++ b/net/ipv4/protocol.c @@ -5,7 +5,7 @@ * * INET protocol dispatch tables. * - * Version: $Id: protocol.c,v 1.10 1999/08/20 11:05:55 davem Exp $ + * Version: $Id: protocol.c,v 1.11 2000/02/22 23:54:26 davem Exp $ * * Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> @@ -35,6 +35,7 @@ #include <linux/inet.h> #include <linux/netdevice.h> #include <linux/timer.h> +#include <linux/brlock.h> #include <net/ip.h> #include <net/protocol.h> #include <net/tcp.h> @@ -116,8 +117,6 @@ struct inet_protocol *inet_protos[MAX_INET_PROTOS] = NULL }; -rwlock_t inet_protocol_lock = RW_LOCK_UNLOCKED; - /* * Add a protocol handler to the hash tables */ @@ -128,7 +127,7 @@ void inet_add_protocol(struct inet_protocol *prot) struct inet_protocol *p2; hash = prot->protocol & (MAX_INET_PROTOS - 1); - write_lock_bh(&inet_protocol_lock); + br_write_lock_bh(BR_NETPROTO_LOCK); prot ->next = inet_protos[hash]; inet_protos[hash] = prot; prot->copy = 0; @@ -147,7 +146,7 @@ void inet_add_protocol(struct inet_protocol *prot) } p2 = (struct inet_protocol *) p2->next; } - write_unlock_bh(&inet_protocol_lock); + br_write_unlock_bh(BR_NETPROTO_LOCK); } /* @@ -161,11 +160,11 @@ int inet_del_protocol(struct inet_protocol *prot) unsigned char hash; hash = prot->protocol & (MAX_INET_PROTOS - 1); - write_lock_bh(&inet_protocol_lock); + br_write_lock_bh(BR_NETPROTO_LOCK); if (prot == inet_protos[hash]) { inet_protos[hash] = (struct inet_protocol *) inet_protos[hash]->next; - write_unlock_bh(&inet_protocol_lock); + br_write_unlock_bh(BR_NETPROTO_LOCK); return(0); } @@ -186,7 +185,7 @@ int inet_del_protocol(struct inet_protocol *prot) if (p->copy == 0 && lp != NULL) lp->copy = 0; p->next = prot->next; - write_unlock_bh(&inet_protocol_lock); + br_write_unlock_bh(BR_NETPROTO_LOCK); return(0); } if (p->next != NULL && p->next->protocol == prot->protocol) @@ -194,6 +193,6 @@ int inet_del_protocol(struct inet_protocol *prot) p = (struct inet_protocol *) p->next; } - write_unlock_bh(&inet_protocol_lock); + br_write_unlock_bh(BR_NETPROTO_LOCK); return(-1); } diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 88483d516..d431c682c 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_input.c,v 1.188 2000/02/08 21:27:14 davem Exp $ + * Version: $Id: tcp_input.c,v 1.189 2000/02/27 19:52:55 davem Exp $ * * Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> @@ -534,6 +534,9 @@ static void tcp_reset(struct sock *sk) sk->err = ECONNRESET; } + if (!sk->dead) + sk->error_report(sk); + tcp_done(sk); } @@ -1660,7 +1663,12 @@ static void tcp_fin(struct sk_buff *skb, struct sock *sk, struct tcphdr *th) if (!sk->dead) { sk->state_change(sk); - sock_wake_async(sk->socket, 1, POLL_HUP); + + /* Do not send POLL_HUP for half duplex close. */ + if (sk->shutdown == SHUTDOWN_MASK || sk->state == TCP_CLOSE) + sock_wake_async(sk->socket, 1, POLL_HUP); + else + sock_wake_async(sk->socket, 1, POLL_IN); } } diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index c052d2eb8..e188b4997 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -5,7 +5,7 @@ * * The User Datagram Protocol (UDP). * - * Version: $Id: udp.c,v 1.79 2000/01/18 08:24:20 davem Exp $ + * Version: $Id: udp.c,v 1.80 2000/02/27 19:51:43 davem Exp $ * * Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> @@ -798,6 +798,7 @@ int udp_disconnect(struct sock *sk, int flags) sk->rcv_saddr = 0; sk->daddr = 0; sk->dport = 0; + sk->bound_dev_if = 0; sk_dst_reset(sk); return 0; } |