diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1998-09-19 19:15:08 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1998-09-19 19:15:08 +0000 |
commit | 03ba4131783cc9e872f8bb26a03f15bc11f27564 (patch) | |
tree | 88db8dba75ae06ba3bad08e42c5e52efc162535c /net/ipv4/raw.c | |
parent | 257730f99381dd26e10b832fce4c94cae7ac1176 (diff) |
- Merge with Linux 2.1.121.
- Bugfixes.
Diffstat (limited to 'net/ipv4/raw.c')
-rw-r--r-- | net/ipv4/raw.c | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 8d8bdab97..e10ddc0dd 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -5,7 +5,7 @@ * * RAW - implementation of IP "raw" sockets. * - * Version: $Id: raw.c,v 1.36 1998/05/08 21:06:29 davem Exp $ + * Version: $Id: raw.c,v 1.37 1998/08/26 12:04:07 davem Exp $ * * Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> @@ -152,7 +152,7 @@ void raw_err (struct sock *sk, struct sk_buff *skb) int type = skb->h.icmph->type; int code = skb->h.icmph->code; - if (sk->ip_recverr && !sk->sock_readers) { + if (sk->ip_recverr) { struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); if (skb2 && sock_queue_err_skb(sk, skb2)) kfree_skb(skb); @@ -194,10 +194,6 @@ int raw_rcv(struct sock *sk, struct sk_buff *skb) skb->h.raw = skb->nh.raw; - if (sk->sock_readers) { - __skb_queue_tail(&sk->back_log, skb); - return 0; - } raw_rcv_skb(sk, skb); return 0; } @@ -379,10 +375,33 @@ done: static void raw_close(struct sock *sk, unsigned long timeout) { + /* Observation: when raw_close is called, processes have + no access to socket anymore. But net still has. + Step one, detach it from networking: + + A. Remove from hash tables. + */ sk->state = TCP_CLOSE; + raw_v4_unhash(sk); + /* + B. Raw sockets may have direct kernel refereneces. Kill them. + */ ip_ra_control(sk, 0, NULL); + + /* In this point socket cannot receive new packets anymore */ + + + /* But we still have packets pending on receive + queue and probably, our own packets waiting in device queues. + sock_destroy will drain receive queue, but transmitted + packets will delay socket destruction. + Set sk->dead=1 in order to prevent wakeups, when these + packet will be freed. + */ sk->dead=1; destroy_sock(sk); + + /* That's all. No races here. */ } /* This gets rid of all the nasties in af_inet. -DaveM */ @@ -474,14 +493,8 @@ done: static int raw_init(struct sock *sk) { struct raw_opt *tp = &(sk->tp_pinfo.tp_raw4); - if (sk->num == IPPROTO_ICMP) { + if (sk->num == IPPROTO_ICMP) memset(&tp->filter, 0, sizeof(tp->filter)); - - /* By default block ECHO and TIMESTAMP requests */ - - set_bit(ICMP_ECHO, &tp->filter); - set_bit(ICMP_TIMESTAMP, &tp->filter); - } return 0; } |