diff options
| author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-05-31 14:07:15 +0400 |
|---|---|---|
| committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-05-31 14:07:15 +0400 |
| commit | e37c83c06c2690157a989df40dc99a6b61c9ea15 (patch) | |
| tree | 024dfb8b2c9abeec9ca7cb0c0136c276d9aacc91 /net/sctp/input.c | |
| parent | ce1f7d30766f6549db6fa0b9e595e0d26a5b7d9a (diff) | |
| parent | 67a3e12b05e055c0415c556a315a3d3eb637e29e (diff) | |
| download | linux-e37c83c06c2690157a989df40dc99a6b61c9ea15.tar.xz | |
Merge commit 'v2.6.35-rc1' into for-2.6.36
Diffstat (limited to 'net/sctp/input.c')
| -rw-r--r-- | net/sctp/input.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/net/sctp/input.c b/net/sctp/input.c index 3d74b264ea22..ea2192444ce6 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -53,6 +53,7 @@ #include <linux/socket.h> #include <linux/ip.h> #include <linux/time.h> /* For struct timeval */ +#include <linux/slab.h> #include <net/ip.h> #include <net/icmp.h> #include <net/snmp.h> @@ -439,11 +440,25 @@ void sctp_icmp_proto_unreachable(struct sock *sk, { SCTP_DEBUG_PRINTK("%s\n", __func__); - sctp_do_sm(SCTP_EVENT_T_OTHER, - SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH), - asoc->state, asoc->ep, asoc, t, - GFP_ATOMIC); + if (sock_owned_by_user(sk)) { + if (timer_pending(&t->proto_unreach_timer)) + return; + else { + if (!mod_timer(&t->proto_unreach_timer, + jiffies + (HZ/20))) + sctp_association_hold(asoc); + } + + } else { + if (timer_pending(&t->proto_unreach_timer) && + del_timer(&t->proto_unreach_timer)) + sctp_association_put(asoc); + sctp_do_sm(SCTP_EVENT_T_OTHER, + SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH), + asoc->state, asoc->ep, asoc, t, + GFP_ATOMIC); + } } /* Common lookup code for icmp/icmpv6 error handler. */ |
