aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/ip6_route.h2
-rw-r--r--include/net/netns/ipv6.h8
-rw-r--r--net/ipv6/af_inet6.c8
-rw-r--r--net/ipv6/ip6_fib.c14
-rw-r--r--net/ipv6/route.c49
-rw-r--r--net/ipv6/sysctl_net_ipv6.c11
6 files changed, 56 insertions, 36 deletions
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index 1a0698b1e86c..faac0eee1ef3 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -43,8 +43,6 @@ extern struct rt6_info ip6_prohibit_entry;
43extern struct rt6_info ip6_blk_hole_entry; 43extern struct rt6_info ip6_blk_hole_entry;
44#endif 44#endif
45 45
46extern int ip6_rt_gc_interval;
47
48extern void ip6_route_input(struct sk_buff *skb); 46extern void ip6_route_input(struct sk_buff *skb);
49 47
50extern struct dst_entry * ip6_route_output(struct sock *sk, 48extern struct dst_entry * ip6_route_output(struct sock *sk,
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
index ea4a71ac23d4..050d08809ef2 100644
--- a/include/net/netns/ipv6.h
+++ b/include/net/netns/ipv6.h
@@ -15,6 +15,14 @@ struct netns_sysctl_ipv6 {
15#endif 15#endif
16 struct inet_frags_ctl frags; 16 struct inet_frags_ctl frags;
17 int bindv6only; 17 int bindv6only;
18 int flush_delay;
19 int ip6_rt_max_size;
20 int ip6_rt_gc_min_interval;
21 int ip6_rt_gc_timeout;
22 int ip6_rt_gc_interval;
23 int ip6_rt_gc_elasticity;
24 int ip6_rt_mtu_expires;
25 int ip6_rt_min_advmss;
18}; 26};
19 27
20struct netns_ipv6 { 28struct netns_ipv6 {
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index c4a1882fa80f..3aea84a1822a 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -726,6 +726,14 @@ static int inet6_net_init(struct net *net)
726 net->ipv6.sysctl.frags.low_thresh = 192 * 1024; 726 net->ipv6.sysctl.frags.low_thresh = 192 * 1024;
727 net->ipv6.sysctl.frags.timeout = IPV6_FRAG_TIMEOUT; 727 net->ipv6.sysctl.frags.timeout = IPV6_FRAG_TIMEOUT;
728 net->ipv6.sysctl.frags.secret_interval = 10 * 60 * HZ; 728 net->ipv6.sysctl.frags.secret_interval = 10 * 60 * HZ;
729 net->ipv6.sysctl.flush_delay = 0;
730 net->ipv6.sysctl.ip6_rt_max_size = 4096;
731 net->ipv6.sysctl.ip6_rt_gc_min_interval = HZ / 2;
732 net->ipv6.sysctl.ip6_rt_gc_timeout = 60*HZ;
733 net->ipv6.sysctl.ip6_rt_gc_interval = 30*HZ;
734 net->ipv6.sysctl.ip6_rt_gc_elasticity = 9;
735 net->ipv6.sysctl.ip6_rt_mtu_expires = 10*60*HZ;
736 net->ipv6.sysctl.ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40;
729 ipv6_frag_sysctl_init(net); 737 ipv6_frag_sysctl_init(net);
730 738
731 return 0; 739 return 0;
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 7165a5e90f45..0e83164aa3e6 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -681,13 +681,15 @@ static __inline__ void fib6_start_gc(struct rt6_info *rt)
681{ 681{
682 if (ip6_fib_timer.expires == 0 && 682 if (ip6_fib_timer.expires == 0 &&
683 (rt->rt6i_flags & (RTF_EXPIRES|RTF_CACHE))) 683 (rt->rt6i_flags & (RTF_EXPIRES|RTF_CACHE)))
684 mod_timer(&ip6_fib_timer, jiffies + ip6_rt_gc_interval); 684 mod_timer(&ip6_fib_timer, jiffies +
685 init_net.ipv6.sysctl.ip6_rt_gc_interval);
685} 686}
686 687
687void fib6_force_start_gc(void) 688void fib6_force_start_gc(void)
688{ 689{
689 if (ip6_fib_timer.expires == 0) 690 if (ip6_fib_timer.expires == 0)
690 mod_timer(&ip6_fib_timer, jiffies + ip6_rt_gc_interval); 691 mod_timer(&ip6_fib_timer, jiffies +
692 init_net.ipv6.sysctl.ip6_rt_gc_interval);
691} 693}
692 694
693/* 695/*
@@ -1447,7 +1449,8 @@ void fib6_run_gc(unsigned long dummy)
1447{ 1449{
1448 if (dummy != ~0UL) { 1450 if (dummy != ~0UL) {
1449 spin_lock_bh(&fib6_gc_lock); 1451 spin_lock_bh(&fib6_gc_lock);
1450 gc_args.timeout = dummy ? (int)dummy : ip6_rt_gc_interval; 1452 gc_args.timeout = dummy ? (int)dummy :
1453 init_net.ipv6.sysctl.ip6_rt_gc_interval;
1451 } else { 1454 } else {
1452 local_bh_disable(); 1455 local_bh_disable();
1453 if (!spin_trylock(&fib6_gc_lock)) { 1456 if (!spin_trylock(&fib6_gc_lock)) {
@@ -1455,7 +1458,7 @@ void fib6_run_gc(unsigned long dummy)
1455 local_bh_enable(); 1458 local_bh_enable();
1456 return; 1459 return;
1457 } 1460 }
1458 gc_args.timeout = ip6_rt_gc_interval; 1461 gc_args.timeout = init_net.ipv6.sysctl.ip6_rt_gc_interval;
1459 } 1462 }
1460 gc_args.more = 0; 1463 gc_args.more = 0;
1461 1464
@@ -1463,7 +1466,8 @@ void fib6_run_gc(unsigned long dummy)
1463 fib6_clean_all(fib6_age, 0, NULL); 1466 fib6_clean_all(fib6_age, 0, NULL);
1464 1467
1465 if (gc_args.more) 1468 if (gc_args.more)
1466 mod_timer(&ip6_fib_timer, jiffies + ip6_rt_gc_interval); 1469 mod_timer(&ip6_fib_timer, jiffies +
1470 init_net.ipv6.sysctl.ip6_rt_gc_interval);
1467 else { 1471 else {
1468 del_timer(&ip6_fib_timer); 1472 del_timer(&ip6_fib_timer);
1469 ip6_fib_timer.expires = 0; 1473 ip6_fib_timer.expires = 0;
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 0c7382f4fb85..d2b3cf695aff 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -73,14 +73,6 @@
73 73
74#define CLONE_OFFLINK_ROUTE 0 74#define CLONE_OFFLINK_ROUTE 0
75 75
76static int ip6_rt_max_size = 4096;
77static int ip6_rt_gc_min_interval = HZ / 2;
78static int ip6_rt_gc_timeout = 60*HZ;
79int ip6_rt_gc_interval = 30*HZ;
80static int ip6_rt_gc_elasticity = 9;
81static int ip6_rt_mtu_expires = 10*60*HZ;
82static int ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40;
83
84static struct rt6_info * ip6_rt_copy(struct rt6_info *ort); 76static struct rt6_info * ip6_rt_copy(struct rt6_info *ort);
85static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie); 77static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie);
86static struct dst_entry *ip6_negative_advice(struct dst_entry *); 78static struct dst_entry *ip6_negative_advice(struct dst_entry *);
@@ -894,8 +886,8 @@ static inline unsigned int ipv6_advmss(unsigned int mtu)
894{ 886{
895 mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr); 887 mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr);
896 888
897 if (mtu < ip6_rt_min_advmss) 889 if (mtu < init_net.ipv6.sysctl.ip6_rt_min_advmss)
898 mtu = ip6_rt_min_advmss; 890 mtu = init_net.ipv6.sysctl.ip6_rt_min_advmss;
899 891
900 /* 892 /*
901 * Maximal non-jumbo IPv6 payload is IPV6_MAXPLEN and 893 * Maximal non-jumbo IPv6 payload is IPV6_MAXPLEN and
@@ -995,19 +987,19 @@ static int ip6_dst_gc(void)
995 static unsigned long last_gc; 987 static unsigned long last_gc;
996 unsigned long now = jiffies; 988 unsigned long now = jiffies;
997 989
998 if (time_after(last_gc + ip6_rt_gc_min_interval, now) && 990 if (time_after(last_gc + init_net.ipv6.sysctl.ip6_rt_gc_min_interval, now) &&
999 atomic_read(&ip6_dst_ops.entries) <= ip6_rt_max_size) 991 atomic_read(&ip6_dst_ops.entries) <= init_net.ipv6.sysctl.ip6_rt_max_size)
1000 goto out; 992 goto out;
1001 993
1002 expire++; 994 expire++;
1003 fib6_run_gc(expire); 995 fib6_run_gc(expire);
1004 last_gc = now; 996 last_gc = now;
1005 if (atomic_read(&ip6_dst_ops.entries) < ip6_dst_ops.gc_thresh) 997 if (atomic_read(&ip6_dst_ops.entries) < ip6_dst_ops.gc_thresh)
1006 expire = ip6_rt_gc_timeout>>1; 998 expire = init_net.ipv6.sysctl.ip6_rt_gc_timeout>>1;
1007 999
1008out: 1000out:
1009 expire -= expire>>ip6_rt_gc_elasticity; 1001 expire -= expire>>init_net.ipv6.sysctl.ip6_rt_gc_elasticity;
1010 return (atomic_read(&ip6_dst_ops.entries) > ip6_rt_max_size); 1002 return (atomic_read(&ip6_dst_ops.entries) > init_net.ipv6.sysctl.ip6_rt_max_size);
1011} 1003}
1012 1004
1013/* Clean host part of a prefix. Not necessary in radix tree, 1005/* 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 rt->u.dst.metrics[RTAX_MTU-1] = pmtu; 1505 rt->u.dst.metrics[RTAX_MTU-1] = pmtu;
1514 if (allfrag) 1506 if (allfrag)
1515 rt->u.dst.metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG; 1507 rt->u.dst.metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG;
1516 dst_set_expires(&rt->u.dst, ip6_rt_mtu_expires); 1508 dst_set_expires(&rt->u.dst, init_net.ipv6.sysctl.ip6_rt_mtu_expires);
1517 rt->rt6i_flags |= RTF_MODIFIED|RTF_EXPIRES; 1509 rt->rt6i_flags |= RTF_MODIFIED|RTF_EXPIRES;
1518 goto out; 1510 goto out;
1519 } 1511 }
@@ -1539,7 +1531,7 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
1539 * which is 10 mins. After 10 mins the decreased pmtu is expired 1531 * which is 10 mins. After 10 mins the decreased pmtu is expired
1540 * and detecting PMTU increase will be automatically happened. 1532 * and detecting PMTU increase will be automatically happened.
1541 */ 1533 */
1542 dst_set_expires(&nrt->u.dst, ip6_rt_mtu_expires); 1534 dst_set_expires(&nrt->u.dst, init_net.ipv6.sysctl.ip6_rt_mtu_expires);
1543 nrt->rt6i_flags |= RTF_DYNAMIC|RTF_EXPIRES; 1535 nrt->rt6i_flags |= RTF_DYNAMIC|RTF_EXPIRES;
1544 1536
1545 ip6_ins_rt(nrt); 1537 ip6_ins_rt(nrt);
@@ -2395,15 +2387,14 @@ static inline void ipv6_route_proc_fini(struct net *net)
2395 2387
2396#ifdef CONFIG_SYSCTL 2388#ifdef CONFIG_SYSCTL
2397 2389
2398static int flush_delay;
2399
2400static 2390static
2401int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write, struct file * filp, 2391int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write, struct file * filp,
2402 void __user *buffer, size_t *lenp, loff_t *ppos) 2392 void __user *buffer, size_t *lenp, loff_t *ppos)
2403{ 2393{
2394 int delay = init_net.ipv6.sysctl.flush_delay;
2404 if (write) { 2395 if (write) {
2405 proc_dointvec(ctl, write, filp, buffer, lenp, ppos); 2396 proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
2406 fib6_run_gc(flush_delay <= 0 ? ~0UL : (unsigned long)flush_delay); 2397 fib6_run_gc(delay <= 0 ? ~0UL : (unsigned long)delay);
2407 return 0; 2398 return 0;
2408 } else 2399 } else
2409 return -EINVAL; 2400 return -EINVAL;
@@ -2412,7 +2403,7 @@ int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write, struct file * filp,
2412ctl_table ipv6_route_table_template[] = { 2403ctl_table ipv6_route_table_template[] = {
2413 { 2404 {
2414 .procname = "flush", 2405 .procname = "flush",
2415 .data = &flush_delay, 2406 .data = &init_net.ipv6.sysctl.flush_delay,
2416 .maxlen = sizeof(int), 2407 .maxlen = sizeof(int),
2417 .mode = 0200, 2408 .mode = 0200,
2418 .proc_handler = &ipv6_sysctl_rtcache_flush 2409 .proc_handler = &ipv6_sysctl_rtcache_flush
@@ -2428,7 +2419,7 @@ ctl_table ipv6_route_table_template[] = {
2428 { 2419 {
2429 .ctl_name = NET_IPV6_ROUTE_MAX_SIZE, 2420 .ctl_name = NET_IPV6_ROUTE_MAX_SIZE,
2430 .procname = "max_size", 2421 .procname = "max_size",
2431 .data = &ip6_rt_max_size, 2422 .data = &init_net.ipv6.sysctl.ip6_rt_max_size,
2432 .maxlen = sizeof(int), 2423 .maxlen = sizeof(int),
2433 .mode = 0644, 2424 .mode = 0644,
2434 .proc_handler = &proc_dointvec, 2425 .proc_handler = &proc_dointvec,
@@ -2436,7 +2427,7 @@ ctl_table ipv6_route_table_template[] = {
2436 { 2427 {
2437 .ctl_name = NET_IPV6_ROUTE_GC_MIN_INTERVAL, 2428 .ctl_name = NET_IPV6_ROUTE_GC_MIN_INTERVAL,
2438 .procname = "gc_min_interval", 2429 .procname = "gc_min_interval",
2439 .data = &ip6_rt_gc_min_interval, 2430 .data = &init_net.ipv6.sysctl.ip6_rt_gc_min_interval,
2440 .maxlen = sizeof(int), 2431 .maxlen = sizeof(int),
2441 .mode = 0644, 2432 .mode = 0644,
2442 .proc_handler = &proc_dointvec_jiffies, 2433 .proc_handler = &proc_dointvec_jiffies,
@@ -2445,7 +2436,7 @@ ctl_table ipv6_route_table_template[] = {
2445 { 2436 {
2446 .ctl_name = NET_IPV6_ROUTE_GC_TIMEOUT, 2437 .ctl_name = NET_IPV6_ROUTE_GC_TIMEOUT,
2447 .procname = "gc_timeout", 2438 .procname = "gc_timeout",
2448 .data = &ip6_rt_gc_timeout, 2439 .data = &init_net.ipv6.sysctl.ip6_rt_gc_timeout,
2449 .maxlen = sizeof(int), 2440 .maxlen = sizeof(int),
2450 .mode = 0644, 2441 .mode = 0644,
2451 .proc_handler = &proc_dointvec_jiffies, 2442 .proc_handler = &proc_dointvec_jiffies,
@@ -2454,7 +2445,7 @@ ctl_table ipv6_route_table_template[] = {
2454 { 2445 {
2455 .ctl_name = NET_IPV6_ROUTE_GC_INTERVAL, 2446 .ctl_name = NET_IPV6_ROUTE_GC_INTERVAL,
2456 .procname = "gc_interval", 2447 .procname = "gc_interval",
2457 .data = &ip6_rt_gc_interval, 2448 .data = &init_net.ipv6.sysctl.ip6_rt_gc_interval,
2458 .maxlen = sizeof(int), 2449 .maxlen = sizeof(int),
2459 .mode = 0644, 2450 .mode = 0644,
2460 .proc_handler = &proc_dointvec_jiffies, 2451 .proc_handler = &proc_dointvec_jiffies,
@@ -2463,7 +2454,7 @@ ctl_table ipv6_route_table_template[] = {
2463 { 2454 {
2464 .ctl_name = NET_IPV6_ROUTE_GC_ELASTICITY, 2455 .ctl_name = NET_IPV6_ROUTE_GC_ELASTICITY,
2465 .procname = "gc_elasticity", 2456 .procname = "gc_elasticity",
2466 .data = &ip6_rt_gc_elasticity, 2457 .data = &init_net.ipv6.sysctl.ip6_rt_gc_elasticity,
2467 .maxlen = sizeof(int), 2458 .maxlen = sizeof(int),
2468 .mode = 0644, 2459 .mode = 0644,
2469 .proc_handler = &proc_dointvec_jiffies, 2460 .proc_handler = &proc_dointvec_jiffies,
@@ -2472,7 +2463,7 @@ ctl_table ipv6_route_table_template[] = {
2472 { 2463 {
2473 .ctl_name = NET_IPV6_ROUTE_MTU_EXPIRES, 2464 .ctl_name = NET_IPV6_ROUTE_MTU_EXPIRES,
2474 .procname = "mtu_expires", 2465 .procname = "mtu_expires",
2475 .data = &ip6_rt_mtu_expires, 2466 .data = &init_net.ipv6.sysctl.ip6_rt_mtu_expires,
2476 .maxlen = sizeof(int), 2467 .maxlen = sizeof(int),
2477 .mode = 0644, 2468 .mode = 0644,
2478 .proc_handler = &proc_dointvec_jiffies, 2469 .proc_handler = &proc_dointvec_jiffies,
@@ -2481,7 +2472,7 @@ ctl_table ipv6_route_table_template[] = {
2481 { 2472 {
2482 .ctl_name = NET_IPV6_ROUTE_MIN_ADVMSS, 2473 .ctl_name = NET_IPV6_ROUTE_MIN_ADVMSS,
2483 .procname = "min_adv_mss", 2474 .procname = "min_adv_mss",
2484 .data = &ip6_rt_min_advmss, 2475 .data = &init_net.ipv6.sysctl.ip6_rt_min_advmss,
2485 .maxlen = sizeof(int), 2476 .maxlen = sizeof(int),
2486 .mode = 0644, 2477 .mode = 0644,
2487 .proc_handler = &proc_dointvec_jiffies, 2478 .proc_handler = &proc_dointvec_jiffies,
@@ -2490,7 +2481,7 @@ ctl_table ipv6_route_table_template[] = {
2490 { 2481 {
2491 .ctl_name = NET_IPV6_ROUTE_GC_MIN_INTERVAL_MS, 2482 .ctl_name = NET_IPV6_ROUTE_GC_MIN_INTERVAL_MS,
2492 .procname = "gc_min_interval_ms", 2483 .procname = "gc_min_interval_ms",
2493 .data = &ip6_rt_gc_min_interval, 2484 .data = &init_net.ipv6.sysctl.ip6_rt_gc_min_interval,
2494 .maxlen = sizeof(int), 2485 .maxlen = sizeof(int),
2495 .mode = 0644, 2486 .mode = 0644,
2496 .proc_handler = &proc_dointvec_ms_jiffies, 2487 .proc_handler = &proc_dointvec_ms_jiffies,
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
index d223159638d3..b4ba422f2714 100644
--- a/net/ipv6/sysctl_net_ipv6.c
+++ b/net/ipv6/sysctl_net_ipv6.c
@@ -113,7 +113,18 @@ static int ipv6_sysctl_net_init(struct net *net)
113 if (!ipv6_icmp_table) 113 if (!ipv6_icmp_table)
114 goto out_ipv6_route_table; 114 goto out_ipv6_route_table;
115 115
116 ipv6_route_table[0].data = &net->ipv6.sysctl.flush_delay;
117 /* ipv6_route_table[1].data will be handled when we have
118 routes per namespace */
119 ipv6_route_table[2].data = &net->ipv6.sysctl.ip6_rt_max_size;
120 ipv6_route_table[3].data = &net->ipv6.sysctl.ip6_rt_gc_min_interval;
121 ipv6_route_table[4].data = &net->ipv6.sysctl.ip6_rt_gc_timeout;
122 ipv6_route_table[5].data = &net->ipv6.sysctl.ip6_rt_gc_interval;
123 ipv6_route_table[6].data = &net->ipv6.sysctl.ip6_rt_gc_elasticity;
124 ipv6_route_table[7].data = &net->ipv6.sysctl.ip6_rt_mtu_expires;
125 ipv6_route_table[8].data = &net->ipv6.sysctl.ip6_rt_min_advmss;
116 ipv6_table[0].child = ipv6_route_table; 126 ipv6_table[0].child = ipv6_route_table;
127
117 ipv6_table[1].child = ipv6_icmp_table; 128 ipv6_table[1].child = ipv6_icmp_table;
118 129
119 ipv6_table[2].data = &net->ipv6.sysctl.bindv6only; 130 ipv6_table[2].data = &net->ipv6.sysctl.bindv6only;