diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-24 13:01:12 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-24 13:01:12 -0400 |
commit | 09ce42d3167e3f20b501fa780c2415332330fac5 (patch) | |
tree | 2f0a6e2e3ec51187f4df78e8c75aa31602a6edd4 /net/ipv4 | |
parent | d7ed9c05ebf56c04811276207d7110706debe09f (diff) | |
parent | 7959ea254ed18faee41160b1c50b3c9664735967 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6:
bnx2: Fix the behavior of ethtool when ONBOOT=no
qla3xxx: Don't sleep while holding lock.
qla3xxx: Give the PHY time to come out of reset.
ipv4 routing: Ensure that route cache entries are usable and reclaimable with caching is off
net: Move rx skb_orphan call to where needed
ipv6: Use correct data types for ICMPv6 type and code
net: let KS8842 driver depend on HAS_IOMEM
can: let SJA1000 driver depend on HAS_IOMEM
netxen: fix firmware init handshake
netxen: fix build with without CONFIG_PM
netfilter: xt_rateest: fix comparison with self
netfilter: xt_quota: fix incomplete initialization
netfilter: nf_log: fix direct userspace memory access in proc handler
netfilter: fix some sparse endianess warnings
netfilter: nf_conntrack: fix conntrack lookup race
netfilter: nf_conntrack: fix confirmation race condition
netfilter: nf_conntrack: death_by_timeout() fix
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/route.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 65b3a8b11a6c..278f46f5011b 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -1093,8 +1093,27 @@ restart: | |||
1093 | * If we drop it here, the callers have no way to resolve routes | 1093 | * If we drop it here, the callers have no way to resolve routes |
1094 | * when we're not caching. Instead, just point *rp at rt, so | 1094 | * when we're not caching. Instead, just point *rp at rt, so |
1095 | * the caller gets a single use out of the route | 1095 | * the caller gets a single use out of the route |
1096 | * Note that we do rt_free on this new route entry, so that | ||
1097 | * once its refcount hits zero, we are still able to reap it | ||
1098 | * (Thanks Alexey) | ||
1099 | * Note also the rt_free uses call_rcu. We don't actually | ||
1100 | * need rcu protection here, this is just our path to get | ||
1101 | * on the route gc list. | ||
1096 | */ | 1102 | */ |
1097 | goto report_and_exit; | 1103 | |
1104 | if (rt->rt_type == RTN_UNICAST || rt->fl.iif == 0) { | ||
1105 | int err = arp_bind_neighbour(&rt->u.dst); | ||
1106 | if (err) { | ||
1107 | if (net_ratelimit()) | ||
1108 | printk(KERN_WARNING | ||
1109 | "Neighbour table failure & not caching routes.\n"); | ||
1110 | rt_drop(rt); | ||
1111 | return err; | ||
1112 | } | ||
1113 | } | ||
1114 | |||
1115 | rt_free(rt); | ||
1116 | goto skip_hashing; | ||
1098 | } | 1117 | } |
1099 | 1118 | ||
1100 | rthp = &rt_hash_table[hash].chain; | 1119 | rthp = &rt_hash_table[hash].chain; |
@@ -1211,7 +1230,8 @@ restart: | |||
1211 | #if RT_CACHE_DEBUG >= 2 | 1230 | #if RT_CACHE_DEBUG >= 2 |
1212 | if (rt->u.dst.rt_next) { | 1231 | if (rt->u.dst.rt_next) { |
1213 | struct rtable *trt; | 1232 | struct rtable *trt; |
1214 | printk(KERN_DEBUG "rt_cache @%02x: %pI4", hash, &rt->rt_dst); | 1233 | printk(KERN_DEBUG "rt_cache @%02x: %pI4", |
1234 | hash, &rt->rt_dst); | ||
1215 | for (trt = rt->u.dst.rt_next; trt; trt = trt->u.dst.rt_next) | 1235 | for (trt = rt->u.dst.rt_next; trt; trt = trt->u.dst.rt_next) |
1216 | printk(" . %pI4", &trt->rt_dst); | 1236 | printk(" . %pI4", &trt->rt_dst); |
1217 | printk("\n"); | 1237 | printk("\n"); |
@@ -1226,7 +1246,7 @@ restart: | |||
1226 | 1246 | ||
1227 | spin_unlock_bh(rt_hash_lock_addr(hash)); | 1247 | spin_unlock_bh(rt_hash_lock_addr(hash)); |
1228 | 1248 | ||
1229 | report_and_exit: | 1249 | skip_hashing: |
1230 | if (rp) | 1250 | if (rp) |
1231 | *rp = rt; | 1251 | *rp = rt; |
1232 | else | 1252 | else |