Skip to content

Commit

Permalink
ipv4: Disable route secret interval on zero interval
Browse files Browse the repository at this point in the history
Let me first state that disabling the route cache hash rebuild
should not be done without extensive analysis on the risk profile
and careful deliberation.

However, there are times when this can be done safely or for
testing.  For example, when you have mechanisms for ensuring
that offending parties do not exist in your network.

This patch lets the user disable the rebuild if the interval is
set to zero.  This also incidentally fixes a divide-by-zero error
with name-spaces.

In addition, this patch makes the effect of an interval change
immediate rather than it taking effect at the next rebuild as
is currently the case.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Herbert Xu authored and David S. Miller committed Aug 15, 2008
1 parent 323c048 commit c6153b5
Showing 1 changed file with 70 additions and 6 deletions.
76 changes: 70 additions & 6 deletions net/ipv4/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -2914,6 +2914,68 @@ static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table,
return 0;
}

static void rt_secret_reschedule(int old)
{
struct net *net;
int new = ip_rt_secret_interval;
int diff = new - old;

if (!diff)
return;

rtnl_lock();
for_each_net(net) {
int deleted = del_timer_sync(&net->ipv4.rt_secret_timer);

if (!new)
continue;

if (deleted) {
long time = net->ipv4.rt_secret_timer.expires - jiffies;

if (time <= 0 || (time += diff) <= 0)
time = 0;

net->ipv4.rt_secret_timer.expires = time;
} else
net->ipv4.rt_secret_timer.expires = new;

net->ipv4.rt_secret_timer.expires += jiffies;
add_timer(&net->ipv4.rt_secret_timer);
}
rtnl_unlock();
}

static int ipv4_sysctl_rt_secret_interval(ctl_table *ctl, int write,
struct file *filp,
void __user *buffer, size_t *lenp,
loff_t *ppos)
{
int old = ip_rt_secret_interval;
int ret = proc_dointvec_jiffies(ctl, write, filp, buffer, lenp, ppos);

rt_secret_reschedule(old);

return ret;
}

static int ipv4_sysctl_rt_secret_interval_strategy(ctl_table *table,
int __user *name,
int nlen,
void __user *oldval,
size_t __user *oldlenp,
void __user *newval,
size_t newlen)
{
int old = ip_rt_secret_interval;
int ret = sysctl_jiffies(table, name, nlen, oldval, oldlenp, newval,
newlen);

rt_secret_reschedule(old);

return ret;
}

static ctl_table ipv4_route_table[] = {
{
.ctl_name = NET_IPV4_ROUTE_GC_THRESH,
Expand Down Expand Up @@ -3048,8 +3110,8 @@ static ctl_table ipv4_route_table[] = {
.data = &ip_rt_secret_interval,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec_jiffies,
.strategy = &sysctl_jiffies,
.proc_handler = &ipv4_sysctl_rt_secret_interval,
.strategy = &ipv4_sysctl_rt_secret_interval_strategy,
},
{ .ctl_name = 0 }
};
Expand Down Expand Up @@ -3126,10 +3188,12 @@ static __net_init int rt_secret_timer_init(struct net *net)
net->ipv4.rt_secret_timer.data = (unsigned long)net;
init_timer_deferrable(&net->ipv4.rt_secret_timer);

net->ipv4.rt_secret_timer.expires =
jiffies + net_random() % ip_rt_secret_interval +
ip_rt_secret_interval;
add_timer(&net->ipv4.rt_secret_timer);
if (ip_rt_secret_interval) {
net->ipv4.rt_secret_timer.expires =
jiffies + net_random() % ip_rt_secret_interval +
ip_rt_secret_interval;
add_timer(&net->ipv4.rt_secret_timer);
}
return 0;
}

Expand Down

0 comments on commit c6153b5

Please sign in to comment.