aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorVitaliy Gusev <vgusev@openvz.org>2010-03-15 21:07:51 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-04-01 19:02:01 -0400
commitb4aedbe935216fd8db97163b0e6dba6036391bcf (patch)
tree4697cb167fac4b8fa7d6b13721122042ae46092c /net
parent3a8010e6225a3548e9921d986a53ae93bda433fa (diff)
route: Fix caught BUG_ON during rt_secret_rebuild_oneshot()
[ Upstream commit 858a18a6a2f74e8f0e5b2e9671d4b74694aba708 ] route: Fix caught BUG_ON during rt_secret_rebuild_oneshot() Call rt_secret_rebuild can cause BUG_ON(timer_pending(&net->ipv4.rt_secret_timer)) in add_timer as there is not any synchronization for call rt_secret_rebuild_oneshot() for the same net namespace. Also this issue affects to rt_secret_reschedule(). Thus use mod_timer enstead. Signed-off-by: Vitaliy Gusev <vgusev@openvz.org> Acked-by: Neil Horman <nhorman@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/route.c16
1 files changed, 6 insertions, 10 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index d62b05d33384..555d27873e03 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -922,10 +922,8 @@ static void rt_secret_rebuild_oneshot(struct net *net)
922{ 922{
923 del_timer_sync(&net->ipv4.rt_secret_timer); 923 del_timer_sync(&net->ipv4.rt_secret_timer);
924 rt_cache_invalidate(net); 924 rt_cache_invalidate(net);
925 if (ip_rt_secret_interval) { 925 if (ip_rt_secret_interval)
926 net->ipv4.rt_secret_timer.expires += ip_rt_secret_interval; 926 mod_timer(&net->ipv4.rt_secret_timer, jiffies + ip_rt_secret_interval);
927 add_timer(&net->ipv4.rt_secret_timer);
928 }
929} 927}
930 928
931static void rt_emergency_hash_rebuild(struct net *net) 929static void rt_emergency_hash_rebuild(struct net *net)
@@ -3072,22 +3070,20 @@ static void rt_secret_reschedule(int old)
3072 rtnl_lock(); 3070 rtnl_lock();
3073 for_each_net(net) { 3071 for_each_net(net) {
3074 int deleted = del_timer_sync(&net->ipv4.rt_secret_timer); 3072 int deleted = del_timer_sync(&net->ipv4.rt_secret_timer);
3073 long time;
3075 3074
3076 if (!new) 3075 if (!new)
3077 continue; 3076 continue;
3078 3077
3079 if (deleted) { 3078 if (deleted) {
3080 long time = net->ipv4.rt_secret_timer.expires - jiffies; 3079 time = net->ipv4.rt_secret_timer.expires - jiffies;
3081 3080
3082 if (time <= 0 || (time += diff) <= 0) 3081 if (time <= 0 || (time += diff) <= 0)
3083 time = 0; 3082 time = 0;
3084
3085 net->ipv4.rt_secret_timer.expires = time;
3086 } else 3083 } else
3087 net->ipv4.rt_secret_timer.expires = new; 3084 time = new;
3088 3085
3089 net->ipv4.rt_secret_timer.expires += jiffies; 3086 mod_timer(&net->ipv4.rt_secret_timer, jiffies + time);
3090 add_timer(&net->ipv4.rt_secret_timer);
3091 } 3087 }
3092 rtnl_unlock(); 3088 rtnl_unlock();
3093} 3089}