Commit 4990509f authored by Daniel Lezcano's avatar Daniel Lezcano Committed by David S. Miller

[NETNS][IPV6]: Make sysctls route per namespace.

All the sysctl concerning the routes are moved to the network
namespace structure. A helper function is called to initialize the
variables.

Because the ipv6 protocol is not yet per namespace, the variables are
accessed relatively from the network namespace.
Signed-off-by: default avatarDaniel Lezcano <dlezcano@fr.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7c76509d
...@@ -43,8 +43,6 @@ extern struct rt6_info ip6_prohibit_entry; ...@@ -43,8 +43,6 @@ extern struct rt6_info ip6_prohibit_entry;
extern struct rt6_info ip6_blk_hole_entry; extern struct rt6_info ip6_blk_hole_entry;
#endif #endif
extern int ip6_rt_gc_interval;
extern void ip6_route_input(struct sk_buff *skb); extern void ip6_route_input(struct sk_buff *skb);
extern struct dst_entry * ip6_route_output(struct sock *sk, extern struct dst_entry * ip6_route_output(struct sock *sk,
......
...@@ -15,6 +15,14 @@ struct netns_sysctl_ipv6 { ...@@ -15,6 +15,14 @@ struct netns_sysctl_ipv6 {
#endif #endif
struct inet_frags_ctl frags; struct inet_frags_ctl frags;
int bindv6only; int bindv6only;
int flush_delay;
int ip6_rt_max_size;
int ip6_rt_gc_min_interval;
int ip6_rt_gc_timeout;
int ip6_rt_gc_interval;
int ip6_rt_gc_elasticity;
int ip6_rt_mtu_expires;
int ip6_rt_min_advmss;
}; };
struct netns_ipv6 { struct netns_ipv6 {
......
...@@ -726,6 +726,14 @@ static int inet6_net_init(struct net *net) ...@@ -726,6 +726,14 @@ static int inet6_net_init(struct net *net)
net->ipv6.sysctl.frags.low_thresh = 192 * 1024; net->ipv6.sysctl.frags.low_thresh = 192 * 1024;
net->ipv6.sysctl.frags.timeout = IPV6_FRAG_TIMEOUT; net->ipv6.sysctl.frags.timeout = IPV6_FRAG_TIMEOUT;
net->ipv6.sysctl.frags.secret_interval = 10 * 60 * HZ; net->ipv6.sysctl.frags.secret_interval = 10 * 60 * HZ;
net->ipv6.sysctl.flush_delay = 0;
net->ipv6.sysctl.ip6_rt_max_size = 4096;
net->ipv6.sysctl.ip6_rt_gc_min_interval = HZ / 2;
net->ipv6.sysctl.ip6_rt_gc_timeout = 60*HZ;
net->ipv6.sysctl.ip6_rt_gc_interval = 30*HZ;
net->ipv6.sysctl.ip6_rt_gc_elasticity = 9;
net->ipv6.sysctl.ip6_rt_mtu_expires = 10*60*HZ;
net->ipv6.sysctl.ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40;
ipv6_frag_sysctl_init(net); ipv6_frag_sysctl_init(net);
return 0; return 0;
......
...@@ -681,13 +681,15 @@ static __inline__ void fib6_start_gc(struct rt6_info *rt) ...@@ -681,13 +681,15 @@ static __inline__ void fib6_start_gc(struct rt6_info *rt)
{ {
if (ip6_fib_timer.expires == 0 && if (ip6_fib_timer.expires == 0 &&
(rt->rt6i_flags & (RTF_EXPIRES|RTF_CACHE))) (rt->rt6i_flags & (RTF_EXPIRES|RTF_CACHE)))
mod_timer(&ip6_fib_timer, jiffies + ip6_rt_gc_interval); mod_timer(&ip6_fib_timer, jiffies +
init_net.ipv6.sysctl.ip6_rt_gc_interval);
} }
void fib6_force_start_gc(void) void fib6_force_start_gc(void)
{ {
if (ip6_fib_timer.expires == 0) if (ip6_fib_timer.expires == 0)
mod_timer(&ip6_fib_timer, jiffies + ip6_rt_gc_interval); mod_timer(&ip6_fib_timer, jiffies +
init_net.ipv6.sysctl.ip6_rt_gc_interval);
} }
/* /*
...@@ -1447,7 +1449,8 @@ void fib6_run_gc(unsigned long dummy) ...@@ -1447,7 +1449,8 @@ void fib6_run_gc(unsigned long dummy)
{ {
if (dummy != ~0UL) { if (dummy != ~0UL) {
spin_lock_bh(&fib6_gc_lock); spin_lock_bh(&fib6_gc_lock);
gc_args.timeout = dummy ? (int)dummy : ip6_rt_gc_interval; gc_args.timeout = dummy ? (int)dummy :
init_net.ipv6.sysctl.ip6_rt_gc_interval;
} else { } else {
local_bh_disable(); local_bh_disable();
if (!spin_trylock(&fib6_gc_lock)) { if (!spin_trylock(&fib6_gc_lock)) {
...@@ -1455,7 +1458,7 @@ void fib6_run_gc(unsigned long dummy) ...@@ -1455,7 +1458,7 @@ void fib6_run_gc(unsigned long dummy)
local_bh_enable(); local_bh_enable();
return; return;
} }
gc_args.timeout = ip6_rt_gc_interval; gc_args.timeout = init_net.ipv6.sysctl.ip6_rt_gc_interval;
} }
gc_args.more = 0; gc_args.more = 0;
...@@ -1463,7 +1466,8 @@ void fib6_run_gc(unsigned long dummy) ...@@ -1463,7 +1466,8 @@ void fib6_run_gc(unsigned long dummy)
fib6_clean_all(fib6_age, 0, NULL); fib6_clean_all(fib6_age, 0, NULL);
if (gc_args.more) if (gc_args.more)
mod_timer(&ip6_fib_timer, jiffies + ip6_rt_gc_interval); mod_timer(&ip6_fib_timer, jiffies +
init_net.ipv6.sysctl.ip6_rt_gc_interval);
else { else {
del_timer(&ip6_fib_timer); del_timer(&ip6_fib_timer);
ip6_fib_timer.expires = 0; ip6_fib_timer.expires = 0;
......
...@@ -73,14 +73,6 @@ ...@@ -73,14 +73,6 @@
#define CLONE_OFFLINK_ROUTE 0 #define CLONE_OFFLINK_ROUTE 0
static int ip6_rt_max_size = 4096;
static int ip6_rt_gc_min_interval = HZ / 2;
static int ip6_rt_gc_timeout = 60*HZ;
int ip6_rt_gc_interval = 30*HZ;
static int ip6_rt_gc_elasticity = 9;
static int ip6_rt_mtu_expires = 10*60*HZ;
static int ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40;
static struct rt6_info * ip6_rt_copy(struct rt6_info *ort); static struct rt6_info * ip6_rt_copy(struct rt6_info *ort);
static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie); static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie);
static struct dst_entry *ip6_negative_advice(struct dst_entry *); static struct dst_entry *ip6_negative_advice(struct dst_entry *);
...@@ -894,8 +886,8 @@ static inline unsigned int ipv6_advmss(unsigned int mtu) ...@@ -894,8 +886,8 @@ static inline unsigned int ipv6_advmss(unsigned int mtu)
{ {
mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr); mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr);
if (mtu < ip6_rt_min_advmss) if (mtu < init_net.ipv6.sysctl.ip6_rt_min_advmss)
mtu = ip6_rt_min_advmss; mtu = init_net.ipv6.sysctl.ip6_rt_min_advmss;
/* /*
* Maximal non-jumbo IPv6 payload is IPV6_MAXPLEN and * Maximal non-jumbo IPv6 payload is IPV6_MAXPLEN and
...@@ -995,19 +987,19 @@ static int ip6_dst_gc(void) ...@@ -995,19 +987,19 @@ static int ip6_dst_gc(void)
static unsigned long last_gc; static unsigned long last_gc;
unsigned long now = jiffies; unsigned long now = jiffies;
if (time_after(last_gc + ip6_rt_gc_min_interval, now) && if (time_after(last_gc + init_net.ipv6.sysctl.ip6_rt_gc_min_interval, now) &&
atomic_read(&ip6_dst_ops.entries) <= ip6_rt_max_size) atomic_read(&ip6_dst_ops.entries) <= init_net.ipv6.sysctl.ip6_rt_max_size)
goto out; goto out;
expire++; expire++;
fib6_run_gc(expire); fib6_run_gc(expire);
last_gc = now; last_gc = now;
if (atomic_read(&ip6_dst_ops.entries) < ip6_dst_ops.gc_thresh) if (atomic_read(&ip6_dst_ops.entries) < ip6_dst_ops.gc_thresh)
expire = ip6_rt_gc_timeout>>1; expire = init_net.ipv6.sysctl.ip6_rt_gc_timeout>>1;
out: out:
expire -= expire>>ip6_rt_gc_elasticity; expire -= expire>>init_net.ipv6.sysctl.ip6_rt_gc_elasticity;
return (atomic_read(&ip6_dst_ops.entries) > ip6_rt_max_size); return (atomic_read(&ip6_dst_ops.entries) > init_net.ipv6.sysctl.ip6_rt_max_size);
} }
/* Clean host part of a prefix. Not necessary in radix tree, /* Clean host part of a prefix. Not necessary in radix tree,
...@@ -1513,7 +1505,7 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr, ...@@ -1513,7 +1505,7 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
rt->u.dst.metrics[RTAX_MTU-1] = pmtu; rt->u.dst.metrics[RTAX_MTU-1] = pmtu;
if (allfrag) if (allfrag)
rt->u.dst.metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG; rt->u.dst.metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG;
dst_set_expires(&rt->u.dst, ip6_rt_mtu_expires); dst_set_expires(&rt->u.dst, init_net.ipv6.sysctl.ip6_rt_mtu_expires);
rt->rt6i_flags |= RTF_MODIFIED|RTF_EXPIRES; rt->rt6i_flags |= RTF_MODIFIED|RTF_EXPIRES;
goto out; goto out;
} }
...@@ -1539,7 +1531,7 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr, ...@@ -1539,7 +1531,7 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
* which is 10 mins. After 10 mins the decreased pmtu is expired * which is 10 mins. After 10 mins the decreased pmtu is expired
* and detecting PMTU increase will be automatically happened. * and detecting PMTU increase will be automatically happened.
*/ */
dst_set_expires(&nrt->u.dst, ip6_rt_mtu_expires); dst_set_expires(&nrt->u.dst, init_net.ipv6.sysctl.ip6_rt_mtu_expires);
nrt->rt6i_flags |= RTF_DYNAMIC|RTF_EXPIRES; nrt->rt6i_flags |= RTF_DYNAMIC|RTF_EXPIRES;
ip6_ins_rt(nrt); ip6_ins_rt(nrt);
...@@ -2395,15 +2387,14 @@ static inline void ipv6_route_proc_fini(struct net *net) ...@@ -2395,15 +2387,14 @@ static inline void ipv6_route_proc_fini(struct net *net)
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
static int flush_delay;
static static
int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write, struct file * filp, int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write, struct file * filp,
void __user *buffer, size_t *lenp, loff_t *ppos) void __user *buffer, size_t *lenp, loff_t *ppos)
{ {
int delay = init_net.ipv6.sysctl.flush_delay;
if (write) { if (write) {
proc_dointvec(ctl, write, filp, buffer, lenp, ppos); proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
fib6_run_gc(flush_delay <= 0 ? ~0UL : (unsigned long)flush_delay); fib6_run_gc(delay <= 0 ? ~0UL : (unsigned long)delay);
return 0; return 0;
} else } else
return -EINVAL; return -EINVAL;
...@@ -2412,7 +2403,7 @@ int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write, struct file * filp, ...@@ -2412,7 +2403,7 @@ int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write, struct file * filp,
ctl_table ipv6_route_table_template[] = { ctl_table ipv6_route_table_template[] = {
{ {
.procname = "flush", .procname = "flush",
.data = &flush_delay, .data = &init_net.ipv6.sysctl.flush_delay,
.maxlen = sizeof(int), .maxlen = sizeof(int),
.mode = 0200, .mode = 0200,
.proc_handler = &ipv6_sysctl_rtcache_flush .proc_handler = &ipv6_sysctl_rtcache_flush
...@@ -2428,7 +2419,7 @@ ctl_table ipv6_route_table_template[] = { ...@@ -2428,7 +2419,7 @@ ctl_table ipv6_route_table_template[] = {
{ {
.ctl_name = NET_IPV6_ROUTE_MAX_SIZE, .ctl_name = NET_IPV6_ROUTE_MAX_SIZE,
.procname = "max_size", .procname = "max_size",
.data = &ip6_rt_max_size, .data = &init_net.ipv6.sysctl.ip6_rt_max_size,
.maxlen = sizeof(int), .maxlen = sizeof(int),
.mode = 0644, .mode = 0644,
.proc_handler = &proc_dointvec, .proc_handler = &proc_dointvec,
...@@ -2436,7 +2427,7 @@ ctl_table ipv6_route_table_template[] = { ...@@ -2436,7 +2427,7 @@ ctl_table ipv6_route_table_template[] = {
{ {
.ctl_name = NET_IPV6_ROUTE_GC_MIN_INTERVAL, .ctl_name = NET_IPV6_ROUTE_GC_MIN_INTERVAL,
.procname = "gc_min_interval", .procname = "gc_min_interval",
.data = &ip6_rt_gc_min_interval, .data = &init_net.ipv6.sysctl.ip6_rt_gc_min_interval,
.maxlen = sizeof(int), .maxlen = sizeof(int),
.mode = 0644, .mode = 0644,
.proc_handler = &proc_dointvec_jiffies, .proc_handler = &proc_dointvec_jiffies,
...@@ -2445,7 +2436,7 @@ ctl_table ipv6_route_table_template[] = { ...@@ -2445,7 +2436,7 @@ ctl_table ipv6_route_table_template[] = {
{ {
.ctl_name = NET_IPV6_ROUTE_GC_TIMEOUT, .ctl_name = NET_IPV6_ROUTE_GC_TIMEOUT,
.procname = "gc_timeout", .procname = "gc_timeout",
.data = &ip6_rt_gc_timeout, .data = &init_net.ipv6.sysctl.ip6_rt_gc_timeout,
.maxlen = sizeof(int), .maxlen = sizeof(int),
.mode = 0644, .mode = 0644,
.proc_handler = &proc_dointvec_jiffies, .proc_handler = &proc_dointvec_jiffies,
...@@ -2454,7 +2445,7 @@ ctl_table ipv6_route_table_template[] = { ...@@ -2454,7 +2445,7 @@ ctl_table ipv6_route_table_template[] = {
{ {
.ctl_name = NET_IPV6_ROUTE_GC_INTERVAL, .ctl_name = NET_IPV6_ROUTE_GC_INTERVAL,
.procname = "gc_interval", .procname = "gc_interval",
.data = &ip6_rt_gc_interval, .data = &init_net.ipv6.sysctl.ip6_rt_gc_interval,
.maxlen = sizeof(int), .maxlen = sizeof(int),
.mode = 0644, .mode = 0644,
.proc_handler = &proc_dointvec_jiffies, .proc_handler = &proc_dointvec_jiffies,
...@@ -2463,7 +2454,7 @@ ctl_table ipv6_route_table_template[] = { ...@@ -2463,7 +2454,7 @@ ctl_table ipv6_route_table_template[] = {
{ {
.ctl_name = NET_IPV6_ROUTE_GC_ELASTICITY, .ctl_name = NET_IPV6_ROUTE_GC_ELASTICITY,
.procname = "gc_elasticity", .procname = "gc_elasticity",
.data = &ip6_rt_gc_elasticity, .data = &init_net.ipv6.sysctl.ip6_rt_gc_elasticity,
.maxlen = sizeof(int), .maxlen = sizeof(int),
.mode = 0644, .mode = 0644,
.proc_handler = &proc_dointvec_jiffies, .proc_handler = &proc_dointvec_jiffies,
...@@ -2472,7 +2463,7 @@ ctl_table ipv6_route_table_template[] = { ...@@ -2472,7 +2463,7 @@ ctl_table ipv6_route_table_template[] = {
{ {
.ctl_name = NET_IPV6_ROUTE_MTU_EXPIRES, .ctl_name = NET_IPV6_ROUTE_MTU_EXPIRES,
.procname = "mtu_expires", .procname = "mtu_expires",
.data = &ip6_rt_mtu_expires, .data = &init_net.ipv6.sysctl.ip6_rt_mtu_expires,
.maxlen = sizeof(int), .maxlen = sizeof(int),
.mode = 0644, .mode = 0644,
.proc_handler = &proc_dointvec_jiffies, .proc_handler = &proc_dointvec_jiffies,
...@@ -2481,7 +2472,7 @@ ctl_table ipv6_route_table_template[] = { ...@@ -2481,7 +2472,7 @@ ctl_table ipv6_route_table_template[] = {
{ {
.ctl_name = NET_IPV6_ROUTE_MIN_ADVMSS, .ctl_name = NET_IPV6_ROUTE_MIN_ADVMSS,
.procname = "min_adv_mss", .procname = "min_adv_mss",
.data = &ip6_rt_min_advmss, .data = &init_net.ipv6.sysctl.ip6_rt_min_advmss,
.maxlen = sizeof(int), .maxlen = sizeof(int),
.mode = 0644, .mode = 0644,
.proc_handler = &proc_dointvec_jiffies, .proc_handler = &proc_dointvec_jiffies,
...@@ -2490,7 +2481,7 @@ ctl_table ipv6_route_table_template[] = { ...@@ -2490,7 +2481,7 @@ ctl_table ipv6_route_table_template[] = {
{ {
.ctl_name = NET_IPV6_ROUTE_GC_MIN_INTERVAL_MS, .ctl_name = NET_IPV6_ROUTE_GC_MIN_INTERVAL_MS,
.procname = "gc_min_interval_ms", .procname = "gc_min_interval_ms",
.data = &ip6_rt_gc_min_interval, .data = &init_net.ipv6.sysctl.ip6_rt_gc_min_interval,
.maxlen = sizeof(int), .maxlen = sizeof(int),
.mode = 0644, .mode = 0644,
.proc_handler = &proc_dointvec_ms_jiffies, .proc_handler = &proc_dointvec_ms_jiffies,
......
...@@ -113,7 +113,18 @@ static int ipv6_sysctl_net_init(struct net *net) ...@@ -113,7 +113,18 @@ static int ipv6_sysctl_net_init(struct net *net)
if (!ipv6_icmp_table) if (!ipv6_icmp_table)
goto out_ipv6_route_table; goto out_ipv6_route_table;
ipv6_route_table[0].data = &net->ipv6.sysctl.flush_delay;
/* ipv6_route_table[1].data will be handled when we have
routes per namespace */
ipv6_route_table[2].data = &net->ipv6.sysctl.ip6_rt_max_size;
ipv6_route_table[3].data = &net->ipv6.sysctl.ip6_rt_gc_min_interval;
ipv6_route_table[4].data = &net->ipv6.sysctl.ip6_rt_gc_timeout;
ipv6_route_table[5].data = &net->ipv6.sysctl.ip6_rt_gc_interval;
ipv6_route_table[6].data = &net->ipv6.sysctl.ip6_rt_gc_elasticity;
ipv6_route_table[7].data = &net->ipv6.sysctl.ip6_rt_mtu_expires;
ipv6_route_table[8].data = &net->ipv6.sysctl.ip6_rt_min_advmss;
ipv6_table[0].child = ipv6_route_table; ipv6_table[0].child = ipv6_route_table;
ipv6_table[1].child = ipv6_icmp_table; ipv6_table[1].child = ipv6_icmp_table;
ipv6_table[2].data = &net->ipv6.sysctl.bindv6only; ipv6_table[2].data = &net->ipv6.sysctl.bindv6only;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment