2 * sysctl_net_ipv6.c: sysctl interface to net IPV6 subsystem.
5 * YOSHIFUJI Hideaki @USAGI: added icmp sysctl table.
9 #include <linux/sysctl.h>
10 #include <linux/in6.h>
11 #include <linux/ipv6.h>
12 #include <linux/slab.h>
13 #include <linux/export.h>
14 #include <net/ndisc.h>
16 #include <net/addrconf.h>
17 #include <net/inet_frag.h>
20 static int auto_flowlabels_min
;
21 static int auto_flowlabels_max
= IP6_AUTO_FLOW_LABEL_MAX
;
24 static struct ctl_table ipv6_table_template
[] = {
26 .procname
= "bindv6only",
27 .data
= &init_net
.ipv6
.sysctl
.bindv6only
,
28 .maxlen
= sizeof(int),
30 .proc_handler
= proc_dointvec
33 .procname
= "anycast_src_echo_reply",
34 .data
= &init_net
.ipv6
.sysctl
.anycast_src_echo_reply
,
35 .maxlen
= sizeof(int),
37 .proc_handler
= proc_dointvec
40 .procname
= "flowlabel_consistency",
41 .data
= &init_net
.ipv6
.sysctl
.flowlabel_consistency
,
42 .maxlen
= sizeof(int),
44 .proc_handler
= proc_dointvec
47 .procname
= "auto_flowlabels",
48 .data
= &init_net
.ipv6
.sysctl
.auto_flowlabels
,
49 .maxlen
= sizeof(int),
51 .proc_handler
= proc_dointvec_minmax
,
52 .extra1
= &auto_flowlabels_min
,
53 .extra2
= &auto_flowlabels_max
56 .procname
= "fwmark_reflect",
57 .data
= &init_net
.ipv6
.sysctl
.fwmark_reflect
,
58 .maxlen
= sizeof(int),
60 .proc_handler
= proc_dointvec
63 .procname
= "idgen_retries",
64 .data
= &init_net
.ipv6
.sysctl
.idgen_retries
,
65 .maxlen
= sizeof(int),
67 .proc_handler
= proc_dointvec
,
70 .procname
= "idgen_delay",
71 .data
= &init_net
.ipv6
.sysctl
.idgen_delay
,
72 .maxlen
= sizeof(int),
74 .proc_handler
= proc_dointvec_jiffies
,
77 .procname
= "flowlabel_state_ranges",
78 .data
= &init_net
.ipv6
.sysctl
.flowlabel_state_ranges
,
79 .maxlen
= sizeof(int),
81 .proc_handler
= proc_dointvec
84 .procname
= "ip_nonlocal_bind",
85 .data
= &init_net
.ipv6
.sysctl
.ip_nonlocal_bind
,
86 .maxlen
= sizeof(int),
88 .proc_handler
= proc_dointvec
93 static struct ctl_table ipv6_rotable
[] = {
95 .procname
= "mld_max_msf",
96 .data
= &sysctl_mld_max_msf
,
97 .maxlen
= sizeof(int),
99 .proc_handler
= proc_dointvec
102 .procname
= "mld_qrv",
103 .data
= &sysctl_mld_qrv
,
104 .maxlen
= sizeof(int),
106 .proc_handler
= proc_dointvec_minmax
,
112 static int __net_init
ipv6_sysctl_net_init(struct net
*net
)
114 struct ctl_table
*ipv6_table
;
115 struct ctl_table
*ipv6_route_table
;
116 struct ctl_table
*ipv6_icmp_table
;
120 ipv6_table
= kmemdup(ipv6_table_template
, sizeof(ipv6_table_template
),
124 ipv6_table
[0].data
= &net
->ipv6
.sysctl
.bindv6only
;
125 ipv6_table
[1].data
= &net
->ipv6
.sysctl
.anycast_src_echo_reply
;
126 ipv6_table
[2].data
= &net
->ipv6
.sysctl
.flowlabel_consistency
;
127 ipv6_table
[3].data
= &net
->ipv6
.sysctl
.auto_flowlabels
;
128 ipv6_table
[4].data
= &net
->ipv6
.sysctl
.fwmark_reflect
;
129 ipv6_table
[5].data
= &net
->ipv6
.sysctl
.idgen_retries
;
130 ipv6_table
[6].data
= &net
->ipv6
.sysctl
.idgen_delay
;
131 ipv6_table
[7].data
= &net
->ipv6
.sysctl
.flowlabel_state_ranges
;
132 ipv6_table
[8].data
= &net
->ipv6
.sysctl
.ip_nonlocal_bind
;
134 ipv6_route_table
= ipv6_route_sysctl_init(net
);
135 if (!ipv6_route_table
)
138 ipv6_icmp_table
= ipv6_icmp_sysctl_init(net
);
139 if (!ipv6_icmp_table
)
140 goto out_ipv6_route_table
;
142 net
->ipv6
.sysctl
.hdr
= register_net_sysctl(net
, "net/ipv6", ipv6_table
);
143 if (!net
->ipv6
.sysctl
.hdr
)
144 goto out_ipv6_icmp_table
;
146 net
->ipv6
.sysctl
.route_hdr
=
147 register_net_sysctl(net
, "net/ipv6/route", ipv6_route_table
);
148 if (!net
->ipv6
.sysctl
.route_hdr
)
149 goto out_unregister_ipv6_table
;
151 net
->ipv6
.sysctl
.icmp_hdr
=
152 register_net_sysctl(net
, "net/ipv6/icmp", ipv6_icmp_table
);
153 if (!net
->ipv6
.sysctl
.icmp_hdr
)
154 goto out_unregister_route_table
;
159 out_unregister_route_table
:
160 unregister_net_sysctl_table(net
->ipv6
.sysctl
.route_hdr
);
161 out_unregister_ipv6_table
:
162 unregister_net_sysctl_table(net
->ipv6
.sysctl
.hdr
);
164 kfree(ipv6_icmp_table
);
165 out_ipv6_route_table
:
166 kfree(ipv6_route_table
);
172 static void __net_exit
ipv6_sysctl_net_exit(struct net
*net
)
174 struct ctl_table
*ipv6_table
;
175 struct ctl_table
*ipv6_route_table
;
176 struct ctl_table
*ipv6_icmp_table
;
178 ipv6_table
= net
->ipv6
.sysctl
.hdr
->ctl_table_arg
;
179 ipv6_route_table
= net
->ipv6
.sysctl
.route_hdr
->ctl_table_arg
;
180 ipv6_icmp_table
= net
->ipv6
.sysctl
.icmp_hdr
->ctl_table_arg
;
182 unregister_net_sysctl_table(net
->ipv6
.sysctl
.icmp_hdr
);
183 unregister_net_sysctl_table(net
->ipv6
.sysctl
.route_hdr
);
184 unregister_net_sysctl_table(net
->ipv6
.sysctl
.hdr
);
187 kfree(ipv6_route_table
);
188 kfree(ipv6_icmp_table
);
191 static struct pernet_operations ipv6_sysctl_net_ops
= {
192 .init
= ipv6_sysctl_net_init
,
193 .exit
= ipv6_sysctl_net_exit
,
196 static struct ctl_table_header
*ip6_header
;
198 int ipv6_sysctl_register(void)
202 ip6_header
= register_net_sysctl(&init_net
, "net/ipv6", ipv6_rotable
);
206 err
= register_pernet_subsys(&ipv6_sysctl_net_ops
);
213 unregister_net_sysctl_table(ip6_header
);
217 void ipv6_sysctl_unregister(void)
219 unregister_net_sysctl_table(ip6_header
);
220 unregister_pernet_subsys(&ipv6_sysctl_net_ops
);