162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * sysctl_net_ipv6.c: sysctl interface to net IPV6 subsystem.
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Changes:
662306a36Sopenharmony_ci * YOSHIFUJI Hideaki @USAGI:	added icmp sysctl table.
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/mm.h>
1062306a36Sopenharmony_ci#include <linux/sysctl.h>
1162306a36Sopenharmony_ci#include <linux/in6.h>
1262306a36Sopenharmony_ci#include <linux/ipv6.h>
1362306a36Sopenharmony_ci#include <linux/slab.h>
1462306a36Sopenharmony_ci#include <linux/export.h>
1562306a36Sopenharmony_ci#include <net/ndisc.h>
1662306a36Sopenharmony_ci#include <net/ipv6.h>
1762306a36Sopenharmony_ci#include <net/addrconf.h>
1862306a36Sopenharmony_ci#include <net/inet_frag.h>
1962306a36Sopenharmony_ci#include <net/netevent.h>
2062306a36Sopenharmony_ci#include <net/ip_fib.h>
2162306a36Sopenharmony_ci#ifdef CONFIG_NETLABEL
2262306a36Sopenharmony_ci#include <net/calipso.h>
2362306a36Sopenharmony_ci#endif
2462306a36Sopenharmony_ci#include <linux/ioam6.h>
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_cistatic int flowlabel_reflect_max = 0x7;
2762306a36Sopenharmony_cistatic int auto_flowlabels_max = IP6_AUTO_FLOW_LABEL_MAX;
2862306a36Sopenharmony_cistatic u32 rt6_multipath_hash_fields_all_mask =
2962306a36Sopenharmony_ci	FIB_MULTIPATH_HASH_FIELD_ALL_MASK;
3062306a36Sopenharmony_cistatic u32 ioam6_id_max = IOAM6_DEFAULT_ID;
3162306a36Sopenharmony_cistatic u64 ioam6_id_wide_max = IOAM6_DEFAULT_ID_WIDE;
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_cistatic int proc_rt6_multipath_hash_policy(struct ctl_table *table, int write,
3462306a36Sopenharmony_ci					  void *buffer, size_t *lenp, loff_t *ppos)
3562306a36Sopenharmony_ci{
3662306a36Sopenharmony_ci	struct net *net;
3762306a36Sopenharmony_ci	int ret;
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci	net = container_of(table->data, struct net,
4062306a36Sopenharmony_ci			   ipv6.sysctl.multipath_hash_policy);
4162306a36Sopenharmony_ci	ret = proc_dou8vec_minmax(table, write, buffer, lenp, ppos);
4262306a36Sopenharmony_ci	if (write && ret == 0)
4362306a36Sopenharmony_ci		call_netevent_notifiers(NETEVENT_IPV6_MPATH_HASH_UPDATE, net);
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci	return ret;
4662306a36Sopenharmony_ci}
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_cistatic int
4962306a36Sopenharmony_ciproc_rt6_multipath_hash_fields(struct ctl_table *table, int write, void *buffer,
5062306a36Sopenharmony_ci			       size_t *lenp, loff_t *ppos)
5162306a36Sopenharmony_ci{
5262306a36Sopenharmony_ci	struct net *net;
5362306a36Sopenharmony_ci	int ret;
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci	net = container_of(table->data, struct net,
5662306a36Sopenharmony_ci			   ipv6.sysctl.multipath_hash_fields);
5762306a36Sopenharmony_ci	ret = proc_douintvec_minmax(table, write, buffer, lenp, ppos);
5862306a36Sopenharmony_ci	if (write && ret == 0)
5962306a36Sopenharmony_ci		call_netevent_notifiers(NETEVENT_IPV6_MPATH_HASH_UPDATE, net);
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci	return ret;
6262306a36Sopenharmony_ci}
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_cistatic struct ctl_table ipv6_table_template[] = {
6562306a36Sopenharmony_ci	{
6662306a36Sopenharmony_ci		.procname	= "bindv6only",
6762306a36Sopenharmony_ci		.data		= &init_net.ipv6.sysctl.bindv6only,
6862306a36Sopenharmony_ci		.maxlen		= sizeof(u8),
6962306a36Sopenharmony_ci		.mode		= 0644,
7062306a36Sopenharmony_ci		.proc_handler	= proc_dou8vec_minmax,
7162306a36Sopenharmony_ci	},
7262306a36Sopenharmony_ci	{
7362306a36Sopenharmony_ci		.procname	= "anycast_src_echo_reply",
7462306a36Sopenharmony_ci		.data		= &init_net.ipv6.sysctl.anycast_src_echo_reply,
7562306a36Sopenharmony_ci		.maxlen		= sizeof(u8),
7662306a36Sopenharmony_ci		.mode		= 0644,
7762306a36Sopenharmony_ci		.proc_handler	= proc_dou8vec_minmax,
7862306a36Sopenharmony_ci	},
7962306a36Sopenharmony_ci	{
8062306a36Sopenharmony_ci		.procname	= "flowlabel_consistency",
8162306a36Sopenharmony_ci		.data		= &init_net.ipv6.sysctl.flowlabel_consistency,
8262306a36Sopenharmony_ci		.maxlen		= sizeof(u8),
8362306a36Sopenharmony_ci		.mode		= 0644,
8462306a36Sopenharmony_ci		.proc_handler	= proc_dou8vec_minmax,
8562306a36Sopenharmony_ci	},
8662306a36Sopenharmony_ci	{
8762306a36Sopenharmony_ci		.procname	= "auto_flowlabels",
8862306a36Sopenharmony_ci		.data		= &init_net.ipv6.sysctl.auto_flowlabels,
8962306a36Sopenharmony_ci		.maxlen		= sizeof(u8),
9062306a36Sopenharmony_ci		.mode		= 0644,
9162306a36Sopenharmony_ci		.proc_handler	= proc_dou8vec_minmax,
9262306a36Sopenharmony_ci		.extra2		= &auto_flowlabels_max
9362306a36Sopenharmony_ci	},
9462306a36Sopenharmony_ci	{
9562306a36Sopenharmony_ci		.procname	= "fwmark_reflect",
9662306a36Sopenharmony_ci		.data		= &init_net.ipv6.sysctl.fwmark_reflect,
9762306a36Sopenharmony_ci		.maxlen		= sizeof(u8),
9862306a36Sopenharmony_ci		.mode		= 0644,
9962306a36Sopenharmony_ci		.proc_handler	= proc_dou8vec_minmax,
10062306a36Sopenharmony_ci	},
10162306a36Sopenharmony_ci	{
10262306a36Sopenharmony_ci		.procname	= "idgen_retries",
10362306a36Sopenharmony_ci		.data		= &init_net.ipv6.sysctl.idgen_retries,
10462306a36Sopenharmony_ci		.maxlen		= sizeof(int),
10562306a36Sopenharmony_ci		.mode		= 0644,
10662306a36Sopenharmony_ci		.proc_handler	= proc_dointvec,
10762306a36Sopenharmony_ci	},
10862306a36Sopenharmony_ci	{
10962306a36Sopenharmony_ci		.procname	= "idgen_delay",
11062306a36Sopenharmony_ci		.data		= &init_net.ipv6.sysctl.idgen_delay,
11162306a36Sopenharmony_ci		.maxlen		= sizeof(int),
11262306a36Sopenharmony_ci		.mode		= 0644,
11362306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_jiffies,
11462306a36Sopenharmony_ci	},
11562306a36Sopenharmony_ci	{
11662306a36Sopenharmony_ci		.procname	= "flowlabel_state_ranges",
11762306a36Sopenharmony_ci		.data		= &init_net.ipv6.sysctl.flowlabel_state_ranges,
11862306a36Sopenharmony_ci		.maxlen		= sizeof(u8),
11962306a36Sopenharmony_ci		.mode		= 0644,
12062306a36Sopenharmony_ci		.proc_handler	= proc_dou8vec_minmax,
12162306a36Sopenharmony_ci	},
12262306a36Sopenharmony_ci	{
12362306a36Sopenharmony_ci		.procname	= "ip_nonlocal_bind",
12462306a36Sopenharmony_ci		.data		= &init_net.ipv6.sysctl.ip_nonlocal_bind,
12562306a36Sopenharmony_ci		.maxlen		= sizeof(u8),
12662306a36Sopenharmony_ci		.mode		= 0644,
12762306a36Sopenharmony_ci		.proc_handler	= proc_dou8vec_minmax,
12862306a36Sopenharmony_ci	},
12962306a36Sopenharmony_ci	{
13062306a36Sopenharmony_ci		.procname	= "flowlabel_reflect",
13162306a36Sopenharmony_ci		.data		= &init_net.ipv6.sysctl.flowlabel_reflect,
13262306a36Sopenharmony_ci		.maxlen		= sizeof(int),
13362306a36Sopenharmony_ci		.mode		= 0644,
13462306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
13562306a36Sopenharmony_ci		.extra1		= SYSCTL_ZERO,
13662306a36Sopenharmony_ci		.extra2		= &flowlabel_reflect_max,
13762306a36Sopenharmony_ci	},
13862306a36Sopenharmony_ci	{
13962306a36Sopenharmony_ci		.procname	= "max_dst_opts_number",
14062306a36Sopenharmony_ci		.data		= &init_net.ipv6.sysctl.max_dst_opts_cnt,
14162306a36Sopenharmony_ci		.maxlen		= sizeof(int),
14262306a36Sopenharmony_ci		.mode		= 0644,
14362306a36Sopenharmony_ci		.proc_handler	= proc_dointvec
14462306a36Sopenharmony_ci	},
14562306a36Sopenharmony_ci	{
14662306a36Sopenharmony_ci		.procname	= "max_hbh_opts_number",
14762306a36Sopenharmony_ci		.data		= &init_net.ipv6.sysctl.max_hbh_opts_cnt,
14862306a36Sopenharmony_ci		.maxlen		= sizeof(int),
14962306a36Sopenharmony_ci		.mode		= 0644,
15062306a36Sopenharmony_ci		.proc_handler	= proc_dointvec
15162306a36Sopenharmony_ci	},
15262306a36Sopenharmony_ci	{
15362306a36Sopenharmony_ci		.procname	= "max_dst_opts_length",
15462306a36Sopenharmony_ci		.data		= &init_net.ipv6.sysctl.max_dst_opts_len,
15562306a36Sopenharmony_ci		.maxlen		= sizeof(int),
15662306a36Sopenharmony_ci		.mode		= 0644,
15762306a36Sopenharmony_ci		.proc_handler	= proc_dointvec
15862306a36Sopenharmony_ci	},
15962306a36Sopenharmony_ci	{
16062306a36Sopenharmony_ci		.procname	= "max_hbh_length",
16162306a36Sopenharmony_ci		.data		= &init_net.ipv6.sysctl.max_hbh_opts_len,
16262306a36Sopenharmony_ci		.maxlen		= sizeof(int),
16362306a36Sopenharmony_ci		.mode		= 0644,
16462306a36Sopenharmony_ci		.proc_handler	= proc_dointvec
16562306a36Sopenharmony_ci	},
16662306a36Sopenharmony_ci	{
16762306a36Sopenharmony_ci		.procname	= "fib_multipath_hash_policy",
16862306a36Sopenharmony_ci		.data		= &init_net.ipv6.sysctl.multipath_hash_policy,
16962306a36Sopenharmony_ci		.maxlen		= sizeof(u8),
17062306a36Sopenharmony_ci		.mode		= 0644,
17162306a36Sopenharmony_ci		.proc_handler   = proc_rt6_multipath_hash_policy,
17262306a36Sopenharmony_ci		.extra1		= SYSCTL_ZERO,
17362306a36Sopenharmony_ci		.extra2		= SYSCTL_THREE,
17462306a36Sopenharmony_ci	},
17562306a36Sopenharmony_ci	{
17662306a36Sopenharmony_ci		.procname	= "fib_multipath_hash_fields",
17762306a36Sopenharmony_ci		.data		= &init_net.ipv6.sysctl.multipath_hash_fields,
17862306a36Sopenharmony_ci		.maxlen		= sizeof(u32),
17962306a36Sopenharmony_ci		.mode		= 0644,
18062306a36Sopenharmony_ci		.proc_handler	= proc_rt6_multipath_hash_fields,
18162306a36Sopenharmony_ci		.extra1		= SYSCTL_ONE,
18262306a36Sopenharmony_ci		.extra2		= &rt6_multipath_hash_fields_all_mask,
18362306a36Sopenharmony_ci	},
18462306a36Sopenharmony_ci	{
18562306a36Sopenharmony_ci		.procname	= "seg6_flowlabel",
18662306a36Sopenharmony_ci		.data		= &init_net.ipv6.sysctl.seg6_flowlabel,
18762306a36Sopenharmony_ci		.maxlen		= sizeof(int),
18862306a36Sopenharmony_ci		.mode		= 0644,
18962306a36Sopenharmony_ci		.proc_handler	= proc_dointvec
19062306a36Sopenharmony_ci	},
19162306a36Sopenharmony_ci	{
19262306a36Sopenharmony_ci		.procname	= "fib_notify_on_flag_change",
19362306a36Sopenharmony_ci		.data		= &init_net.ipv6.sysctl.fib_notify_on_flag_change,
19462306a36Sopenharmony_ci		.maxlen		= sizeof(u8),
19562306a36Sopenharmony_ci		.mode		= 0644,
19662306a36Sopenharmony_ci		.proc_handler	= proc_dou8vec_minmax,
19762306a36Sopenharmony_ci		.extra1         = SYSCTL_ZERO,
19862306a36Sopenharmony_ci		.extra2         = SYSCTL_TWO,
19962306a36Sopenharmony_ci	},
20062306a36Sopenharmony_ci	{
20162306a36Sopenharmony_ci		.procname	= "ioam6_id",
20262306a36Sopenharmony_ci		.data		= &init_net.ipv6.sysctl.ioam6_id,
20362306a36Sopenharmony_ci		.maxlen		= sizeof(u32),
20462306a36Sopenharmony_ci		.mode		= 0644,
20562306a36Sopenharmony_ci		.proc_handler	= proc_douintvec_minmax,
20662306a36Sopenharmony_ci		.extra2		= &ioam6_id_max,
20762306a36Sopenharmony_ci	},
20862306a36Sopenharmony_ci	{
20962306a36Sopenharmony_ci		.procname	= "ioam6_id_wide",
21062306a36Sopenharmony_ci		.data		= &init_net.ipv6.sysctl.ioam6_id_wide,
21162306a36Sopenharmony_ci		.maxlen		= sizeof(u64),
21262306a36Sopenharmony_ci		.mode		= 0644,
21362306a36Sopenharmony_ci		.proc_handler	= proc_doulongvec_minmax,
21462306a36Sopenharmony_ci		.extra2		= &ioam6_id_wide_max,
21562306a36Sopenharmony_ci	},
21662306a36Sopenharmony_ci	{ }
21762306a36Sopenharmony_ci};
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_cistatic struct ctl_table ipv6_rotable[] = {
22062306a36Sopenharmony_ci	{
22162306a36Sopenharmony_ci		.procname	= "mld_max_msf",
22262306a36Sopenharmony_ci		.data		= &sysctl_mld_max_msf,
22362306a36Sopenharmony_ci		.maxlen		= sizeof(int),
22462306a36Sopenharmony_ci		.mode		= 0644,
22562306a36Sopenharmony_ci		.proc_handler	= proc_dointvec
22662306a36Sopenharmony_ci	},
22762306a36Sopenharmony_ci	{
22862306a36Sopenharmony_ci		.procname	= "mld_qrv",
22962306a36Sopenharmony_ci		.data		= &sysctl_mld_qrv,
23062306a36Sopenharmony_ci		.maxlen		= sizeof(int),
23162306a36Sopenharmony_ci		.mode		= 0644,
23262306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
23362306a36Sopenharmony_ci		.extra1		= SYSCTL_ONE
23462306a36Sopenharmony_ci	},
23562306a36Sopenharmony_ci#ifdef CONFIG_NETLABEL
23662306a36Sopenharmony_ci	{
23762306a36Sopenharmony_ci		.procname	= "calipso_cache_enable",
23862306a36Sopenharmony_ci		.data		= &calipso_cache_enabled,
23962306a36Sopenharmony_ci		.maxlen		= sizeof(int),
24062306a36Sopenharmony_ci		.mode		= 0644,
24162306a36Sopenharmony_ci		.proc_handler	= proc_dointvec,
24262306a36Sopenharmony_ci	},
24362306a36Sopenharmony_ci	{
24462306a36Sopenharmony_ci		.procname	= "calipso_cache_bucket_size",
24562306a36Sopenharmony_ci		.data		= &calipso_cache_bucketsize,
24662306a36Sopenharmony_ci		.maxlen		= sizeof(int),
24762306a36Sopenharmony_ci		.mode		= 0644,
24862306a36Sopenharmony_ci		.proc_handler	= proc_dointvec,
24962306a36Sopenharmony_ci	},
25062306a36Sopenharmony_ci#endif /* CONFIG_NETLABEL */
25162306a36Sopenharmony_ci	{ }
25262306a36Sopenharmony_ci};
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_cistatic int __net_init ipv6_sysctl_net_init(struct net *net)
25562306a36Sopenharmony_ci{
25662306a36Sopenharmony_ci	struct ctl_table *ipv6_table;
25762306a36Sopenharmony_ci	struct ctl_table *ipv6_route_table;
25862306a36Sopenharmony_ci	struct ctl_table *ipv6_icmp_table;
25962306a36Sopenharmony_ci	int err, i;
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci	err = -ENOMEM;
26262306a36Sopenharmony_ci	ipv6_table = kmemdup(ipv6_table_template, sizeof(ipv6_table_template),
26362306a36Sopenharmony_ci			     GFP_KERNEL);
26462306a36Sopenharmony_ci	if (!ipv6_table)
26562306a36Sopenharmony_ci		goto out;
26662306a36Sopenharmony_ci	/* Update the variables to point into the current struct net */
26762306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(ipv6_table_template) - 1; i++)
26862306a36Sopenharmony_ci		ipv6_table[i].data += (void *)net - (void *)&init_net;
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ci	ipv6_route_table = ipv6_route_sysctl_init(net);
27162306a36Sopenharmony_ci	if (!ipv6_route_table)
27262306a36Sopenharmony_ci		goto out_ipv6_table;
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_ci	ipv6_icmp_table = ipv6_icmp_sysctl_init(net);
27562306a36Sopenharmony_ci	if (!ipv6_icmp_table)
27662306a36Sopenharmony_ci		goto out_ipv6_route_table;
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_ci	net->ipv6.sysctl.hdr = register_net_sysctl_sz(net, "net/ipv6",
27962306a36Sopenharmony_ci						      ipv6_table,
28062306a36Sopenharmony_ci						      ARRAY_SIZE(ipv6_table_template));
28162306a36Sopenharmony_ci	if (!net->ipv6.sysctl.hdr)
28262306a36Sopenharmony_ci		goto out_ipv6_icmp_table;
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci	net->ipv6.sysctl.route_hdr = register_net_sysctl_sz(net,
28562306a36Sopenharmony_ci							    "net/ipv6/route",
28662306a36Sopenharmony_ci							    ipv6_route_table,
28762306a36Sopenharmony_ci							    ipv6_route_sysctl_table_size(net));
28862306a36Sopenharmony_ci	if (!net->ipv6.sysctl.route_hdr)
28962306a36Sopenharmony_ci		goto out_unregister_ipv6_table;
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ci	net->ipv6.sysctl.icmp_hdr = register_net_sysctl_sz(net,
29262306a36Sopenharmony_ci							   "net/ipv6/icmp",
29362306a36Sopenharmony_ci							   ipv6_icmp_table,
29462306a36Sopenharmony_ci							   ipv6_icmp_sysctl_table_size());
29562306a36Sopenharmony_ci	if (!net->ipv6.sysctl.icmp_hdr)
29662306a36Sopenharmony_ci		goto out_unregister_route_table;
29762306a36Sopenharmony_ci
29862306a36Sopenharmony_ci	err = 0;
29962306a36Sopenharmony_ciout:
30062306a36Sopenharmony_ci	return err;
30162306a36Sopenharmony_ciout_unregister_route_table:
30262306a36Sopenharmony_ci	unregister_net_sysctl_table(net->ipv6.sysctl.route_hdr);
30362306a36Sopenharmony_ciout_unregister_ipv6_table:
30462306a36Sopenharmony_ci	unregister_net_sysctl_table(net->ipv6.sysctl.hdr);
30562306a36Sopenharmony_ciout_ipv6_icmp_table:
30662306a36Sopenharmony_ci	kfree(ipv6_icmp_table);
30762306a36Sopenharmony_ciout_ipv6_route_table:
30862306a36Sopenharmony_ci	kfree(ipv6_route_table);
30962306a36Sopenharmony_ciout_ipv6_table:
31062306a36Sopenharmony_ci	kfree(ipv6_table);
31162306a36Sopenharmony_ci	goto out;
31262306a36Sopenharmony_ci}
31362306a36Sopenharmony_ci
31462306a36Sopenharmony_cistatic void __net_exit ipv6_sysctl_net_exit(struct net *net)
31562306a36Sopenharmony_ci{
31662306a36Sopenharmony_ci	struct ctl_table *ipv6_table;
31762306a36Sopenharmony_ci	struct ctl_table *ipv6_route_table;
31862306a36Sopenharmony_ci	struct ctl_table *ipv6_icmp_table;
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_ci	ipv6_table = net->ipv6.sysctl.hdr->ctl_table_arg;
32162306a36Sopenharmony_ci	ipv6_route_table = net->ipv6.sysctl.route_hdr->ctl_table_arg;
32262306a36Sopenharmony_ci	ipv6_icmp_table = net->ipv6.sysctl.icmp_hdr->ctl_table_arg;
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ci	unregister_net_sysctl_table(net->ipv6.sysctl.icmp_hdr);
32562306a36Sopenharmony_ci	unregister_net_sysctl_table(net->ipv6.sysctl.route_hdr);
32662306a36Sopenharmony_ci	unregister_net_sysctl_table(net->ipv6.sysctl.hdr);
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ci	kfree(ipv6_table);
32962306a36Sopenharmony_ci	kfree(ipv6_route_table);
33062306a36Sopenharmony_ci	kfree(ipv6_icmp_table);
33162306a36Sopenharmony_ci}
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_cistatic struct pernet_operations ipv6_sysctl_net_ops = {
33462306a36Sopenharmony_ci	.init = ipv6_sysctl_net_init,
33562306a36Sopenharmony_ci	.exit = ipv6_sysctl_net_exit,
33662306a36Sopenharmony_ci};
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_cistatic struct ctl_table_header *ip6_header;
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ciint ipv6_sysctl_register(void)
34162306a36Sopenharmony_ci{
34262306a36Sopenharmony_ci	int err = -ENOMEM;
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_ci	ip6_header = register_net_sysctl(&init_net, "net/ipv6", ipv6_rotable);
34562306a36Sopenharmony_ci	if (!ip6_header)
34662306a36Sopenharmony_ci		goto out;
34762306a36Sopenharmony_ci
34862306a36Sopenharmony_ci	err = register_pernet_subsys(&ipv6_sysctl_net_ops);
34962306a36Sopenharmony_ci	if (err)
35062306a36Sopenharmony_ci		goto err_pernet;
35162306a36Sopenharmony_ciout:
35262306a36Sopenharmony_ci	return err;
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_cierr_pernet:
35562306a36Sopenharmony_ci	unregister_net_sysctl_table(ip6_header);
35662306a36Sopenharmony_ci	goto out;
35762306a36Sopenharmony_ci}
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_civoid ipv6_sysctl_unregister(void)
36062306a36Sopenharmony_ci{
36162306a36Sopenharmony_ci	unregister_net_sysctl_table(ip6_header);
36262306a36Sopenharmony_ci	unregister_pernet_subsys(&ipv6_sysctl_net_ops);
36362306a36Sopenharmony_ci}
364