aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/route.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/route.c')
-rw-r--r--net/ipv4/route.c79
1 files changed, 69 insertions, 10 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 790de32cd7d4..6fe799de9b96 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2835,6 +2835,7 @@ static int ipv4_sysctl_rtcache_flush(ctl_table *ctl, int write,
2835{ 2835{
2836 if (write) { 2836 if (write) {
2837 int flush_delay; 2837 int flush_delay;
2838 struct net *net;
2838 static DEFINE_MUTEX(flush_mutex); 2839 static DEFINE_MUTEX(flush_mutex);
2839 2840
2840 mutex_lock(&flush_mutex); 2841 mutex_lock(&flush_mutex);
@@ -2843,7 +2844,8 @@ static int ipv4_sysctl_rtcache_flush(ctl_table *ctl, int write,
2843 ctl->data = NULL; 2844 ctl->data = NULL;
2844 mutex_unlock(&flush_mutex); 2845 mutex_unlock(&flush_mutex);
2845 2846
2846 rt_cache_flush(&init_net, flush_delay); 2847 net = (struct net *)ctl->extra1;
2848 rt_cache_flush(net, flush_delay);
2847 return 0; 2849 return 0;
2848 } 2850 }
2849 2851
@@ -2859,24 +2861,18 @@ static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table,
2859 size_t newlen) 2861 size_t newlen)
2860{ 2862{
2861 int delay; 2863 int delay;
2864 struct net *net;
2862 if (newlen != sizeof(int)) 2865 if (newlen != sizeof(int))
2863 return -EINVAL; 2866 return -EINVAL;
2864 if (get_user(delay, (int __user *)newval)) 2867 if (get_user(delay, (int __user *)newval))
2865 return -EFAULT; 2868 return -EFAULT;
2866 rt_cache_flush(&init_net, delay); 2869 net = (struct net *)table->extra1;
2870 rt_cache_flush(net, delay);
2867 return 0; 2871 return 0;
2868} 2872}
2869 2873
2870ctl_table ipv4_route_table[] = { 2874ctl_table ipv4_route_table[] = {
2871 { 2875 {
2872 .ctl_name = NET_IPV4_ROUTE_FLUSH,
2873 .procname = "flush",
2874 .maxlen = sizeof(int),
2875 .mode = 0200,
2876 .proc_handler = &ipv4_sysctl_rtcache_flush,
2877 .strategy = &ipv4_sysctl_rtcache_flush_strategy,
2878 },
2879 {
2880 .ctl_name = NET_IPV4_ROUTE_GC_THRESH, 2876 .ctl_name = NET_IPV4_ROUTE_GC_THRESH,
2881 .procname = "gc_thresh", 2877 .procname = "gc_thresh",
2882 .data = &ipv4_dst_ops.gc_thresh, 2878 .data = &ipv4_dst_ops.gc_thresh,
@@ -3014,6 +3010,66 @@ ctl_table ipv4_route_table[] = {
3014 }, 3010 },
3015 { .ctl_name = 0 } 3011 { .ctl_name = 0 }
3016}; 3012};
3013
3014static __net_initdata struct ctl_path ipv4_route_path[] = {
3015 { .procname = "net", .ctl_name = CTL_NET, },
3016 { .procname = "ipv4", .ctl_name = NET_IPV4, },
3017 { .procname = "route", .ctl_name = NET_IPV4_ROUTE, },
3018 { },
3019};
3020
3021
3022static struct ctl_table ipv4_route_flush_table[] = {
3023 {
3024 .ctl_name = NET_IPV4_ROUTE_FLUSH,
3025 .procname = "flush",
3026 .maxlen = sizeof(int),
3027 .mode = 0200,
3028 .proc_handler = &ipv4_sysctl_rtcache_flush,
3029 .strategy = &ipv4_sysctl_rtcache_flush_strategy,
3030 },
3031 { .ctl_name = 0 },
3032};
3033
3034static __net_init int sysctl_route_net_init(struct net *net)
3035{
3036 struct ctl_table *tbl;
3037
3038 tbl = ipv4_route_flush_table;
3039 if (net != &init_net) {
3040 tbl = kmemdup(tbl, sizeof(ipv4_route_flush_table), GFP_KERNEL);
3041 if (tbl == NULL)
3042 goto err_dup;
3043 }
3044 tbl[0].extra1 = net;
3045
3046 net->ipv4.route_hdr =
3047 register_net_sysctl_table(net, ipv4_route_path, tbl);
3048 if (net->ipv4.route_hdr == NULL)
3049 goto err_reg;
3050 return 0;
3051
3052err_reg:
3053 if (tbl != ipv4_route_flush_table)
3054 kfree(tbl);
3055err_dup:
3056 return -ENOMEM;
3057}
3058
3059static __net_exit void sysctl_route_net_exit(struct net *net)
3060{
3061 struct ctl_table *tbl;
3062
3063 tbl = net->ipv4.route_hdr->ctl_table_arg;
3064 unregister_net_sysctl_table(net->ipv4.route_hdr);
3065 BUG_ON(tbl == ipv4_route_flush_table);
3066 kfree(tbl);
3067}
3068
3069static __net_initdata struct pernet_operations sysctl_route_ops = {
3070 .init = sysctl_route_net_init,
3071 .exit = sysctl_route_net_exit,
3072};
3017#endif 3073#endif
3018 3074
3019#ifdef CONFIG_NET_CLS_ROUTE 3075#ifdef CONFIG_NET_CLS_ROUTE
@@ -3090,6 +3146,9 @@ int __init ip_rt_init(void)
3090#endif 3146#endif
3091 rtnl_register(PF_INET, RTM_GETROUTE, inet_rtm_getroute, NULL); 3147 rtnl_register(PF_INET, RTM_GETROUTE, inet_rtm_getroute, NULL);
3092 3148
3149#ifdef CONFIG_SYSCTL
3150 register_pernet_subsys(&sysctl_route_ops);
3151#endif
3093 return rc; 3152 return rc;
3094} 3153}
3095 3154