root/net/ipv6/sysctl_net_ipv6.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. proc_rt6_multipath_hash_policy
  2. ipv6_sysctl_net_init
  3. ipv6_sysctl_net_exit
  4. ipv6_sysctl_register
  5. ipv6_sysctl_unregister

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * sysctl_net_ipv6.c: sysctl interface to net IPV6 subsystem.
   4  *
   5  * Changes:
   6  * YOSHIFUJI Hideaki @USAGI:    added icmp sysctl table.
   7  */
   8 
   9 #include <linux/mm.h>
  10 #include <linux/sysctl.h>
  11 #include <linux/in6.h>
  12 #include <linux/ipv6.h>
  13 #include <linux/slab.h>
  14 #include <linux/export.h>
  15 #include <net/ndisc.h>
  16 #include <net/ipv6.h>
  17 #include <net/addrconf.h>
  18 #include <net/inet_frag.h>
  19 #include <net/netevent.h>
  20 #ifdef CONFIG_NETLABEL
  21 #include <net/calipso.h>
  22 #endif
  23 
  24 static int flowlabel_reflect_max = 0x7;
  25 static int auto_flowlabels_min;
  26 static int auto_flowlabels_max = IP6_AUTO_FLOW_LABEL_MAX;
  27 
  28 static int proc_rt6_multipath_hash_policy(struct ctl_table *table, int write,
  29                                           void __user *buffer, size_t *lenp,
  30                                           loff_t *ppos)
  31 {
  32         struct net *net;
  33         int ret;
  34 
  35         net = container_of(table->data, struct net,
  36                            ipv6.sysctl.multipath_hash_policy);
  37         ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
  38         if (write && ret == 0)
  39                 call_netevent_notifiers(NETEVENT_IPV6_MPATH_HASH_UPDATE, net);
  40 
  41         return ret;
  42 }
  43 
  44 static struct ctl_table ipv6_table_template[] = {
  45         {
  46                 .procname       = "bindv6only",
  47                 .data           = &init_net.ipv6.sysctl.bindv6only,
  48                 .maxlen         = sizeof(int),
  49                 .mode           = 0644,
  50                 .proc_handler   = proc_dointvec
  51         },
  52         {
  53                 .procname       = "anycast_src_echo_reply",
  54                 .data           = &init_net.ipv6.sysctl.anycast_src_echo_reply,
  55                 .maxlen         = sizeof(int),
  56                 .mode           = 0644,
  57                 .proc_handler   = proc_dointvec
  58         },
  59         {
  60                 .procname       = "flowlabel_consistency",
  61                 .data           = &init_net.ipv6.sysctl.flowlabel_consistency,
  62                 .maxlen         = sizeof(int),
  63                 .mode           = 0644,
  64                 .proc_handler   = proc_dointvec
  65         },
  66         {
  67                 .procname       = "auto_flowlabels",
  68                 .data           = &init_net.ipv6.sysctl.auto_flowlabels,
  69                 .maxlen         = sizeof(int),
  70                 .mode           = 0644,
  71                 .proc_handler   = proc_dointvec_minmax,
  72                 .extra1         = &auto_flowlabels_min,
  73                 .extra2         = &auto_flowlabels_max
  74         },
  75         {
  76                 .procname       = "fwmark_reflect",
  77                 .data           = &init_net.ipv6.sysctl.fwmark_reflect,
  78                 .maxlen         = sizeof(int),
  79                 .mode           = 0644,
  80                 .proc_handler   = proc_dointvec
  81         },
  82         {
  83                 .procname       = "idgen_retries",
  84                 .data           = &init_net.ipv6.sysctl.idgen_retries,
  85                 .maxlen         = sizeof(int),
  86                 .mode           = 0644,
  87                 .proc_handler   = proc_dointvec,
  88         },
  89         {
  90                 .procname       = "idgen_delay",
  91                 .data           = &init_net.ipv6.sysctl.idgen_delay,
  92                 .maxlen         = sizeof(int),
  93                 .mode           = 0644,
  94                 .proc_handler   = proc_dointvec_jiffies,
  95         },
  96         {
  97                 .procname       = "flowlabel_state_ranges",
  98                 .data           = &init_net.ipv6.sysctl.flowlabel_state_ranges,
  99                 .maxlen         = sizeof(int),
 100                 .mode           = 0644,
 101                 .proc_handler   = proc_dointvec
 102         },
 103         {
 104                 .procname       = "ip_nonlocal_bind",
 105                 .data           = &init_net.ipv6.sysctl.ip_nonlocal_bind,
 106                 .maxlen         = sizeof(int),
 107                 .mode           = 0644,
 108                 .proc_handler   = proc_dointvec
 109         },
 110         {
 111                 .procname       = "flowlabel_reflect",
 112                 .data           = &init_net.ipv6.sysctl.flowlabel_reflect,
 113                 .maxlen         = sizeof(int),
 114                 .mode           = 0644,
 115                 .proc_handler   = proc_dointvec_minmax,
 116                 .extra1         = SYSCTL_ZERO,
 117                 .extra2         = &flowlabel_reflect_max,
 118         },
 119         {
 120                 .procname       = "max_dst_opts_number",
 121                 .data           = &init_net.ipv6.sysctl.max_dst_opts_cnt,
 122                 .maxlen         = sizeof(int),
 123                 .mode           = 0644,
 124                 .proc_handler   = proc_dointvec
 125         },
 126         {
 127                 .procname       = "max_hbh_opts_number",
 128                 .data           = &init_net.ipv6.sysctl.max_hbh_opts_cnt,
 129                 .maxlen         = sizeof(int),
 130                 .mode           = 0644,
 131                 .proc_handler   = proc_dointvec
 132         },
 133         {
 134                 .procname       = "max_dst_opts_length",
 135                 .data           = &init_net.ipv6.sysctl.max_dst_opts_len,
 136                 .maxlen         = sizeof(int),
 137                 .mode           = 0644,
 138                 .proc_handler   = proc_dointvec
 139         },
 140         {
 141                 .procname       = "max_hbh_length",
 142                 .data           = &init_net.ipv6.sysctl.max_hbh_opts_len,
 143                 .maxlen         = sizeof(int),
 144                 .mode           = 0644,
 145                 .proc_handler   = proc_dointvec
 146         },
 147         {
 148                 .procname       = "fib_multipath_hash_policy",
 149                 .data           = &init_net.ipv6.sysctl.multipath_hash_policy,
 150                 .maxlen         = sizeof(int),
 151                 .mode           = 0644,
 152                 .proc_handler   = proc_rt6_multipath_hash_policy,
 153                 .extra1         = SYSCTL_ZERO,
 154                 .extra2         = SYSCTL_ONE,
 155         },
 156         {
 157                 .procname       = "seg6_flowlabel",
 158                 .data           = &init_net.ipv6.sysctl.seg6_flowlabel,
 159                 .maxlen         = sizeof(int),
 160                 .mode           = 0644,
 161                 .proc_handler   = proc_dointvec
 162         },
 163         { }
 164 };
 165 
 166 static struct ctl_table ipv6_rotable[] = {
 167         {
 168                 .procname       = "mld_max_msf",
 169                 .data           = &sysctl_mld_max_msf,
 170                 .maxlen         = sizeof(int),
 171                 .mode           = 0644,
 172                 .proc_handler   = proc_dointvec
 173         },
 174         {
 175                 .procname       = "mld_qrv",
 176                 .data           = &sysctl_mld_qrv,
 177                 .maxlen         = sizeof(int),
 178                 .mode           = 0644,
 179                 .proc_handler   = proc_dointvec_minmax,
 180                 .extra1         = SYSCTL_ONE
 181         },
 182 #ifdef CONFIG_NETLABEL
 183         {
 184                 .procname       = "calipso_cache_enable",
 185                 .data           = &calipso_cache_enabled,
 186                 .maxlen         = sizeof(int),
 187                 .mode           = 0644,
 188                 .proc_handler   = proc_dointvec,
 189         },
 190         {
 191                 .procname       = "calipso_cache_bucket_size",
 192                 .data           = &calipso_cache_bucketsize,
 193                 .maxlen         = sizeof(int),
 194                 .mode           = 0644,
 195                 .proc_handler   = proc_dointvec,
 196         },
 197 #endif /* CONFIG_NETLABEL */
 198         { }
 199 };
 200 
 201 static int __net_init ipv6_sysctl_net_init(struct net *net)
 202 {
 203         struct ctl_table *ipv6_table;
 204         struct ctl_table *ipv6_route_table;
 205         struct ctl_table *ipv6_icmp_table;
 206         int err;
 207 
 208         err = -ENOMEM;
 209         ipv6_table = kmemdup(ipv6_table_template, sizeof(ipv6_table_template),
 210                              GFP_KERNEL);
 211         if (!ipv6_table)
 212                 goto out;
 213         ipv6_table[0].data = &net->ipv6.sysctl.bindv6only;
 214         ipv6_table[1].data = &net->ipv6.sysctl.anycast_src_echo_reply;
 215         ipv6_table[2].data = &net->ipv6.sysctl.flowlabel_consistency;
 216         ipv6_table[3].data = &net->ipv6.sysctl.auto_flowlabels;
 217         ipv6_table[4].data = &net->ipv6.sysctl.fwmark_reflect;
 218         ipv6_table[5].data = &net->ipv6.sysctl.idgen_retries;
 219         ipv6_table[6].data = &net->ipv6.sysctl.idgen_delay;
 220         ipv6_table[7].data = &net->ipv6.sysctl.flowlabel_state_ranges;
 221         ipv6_table[8].data = &net->ipv6.sysctl.ip_nonlocal_bind;
 222         ipv6_table[9].data = &net->ipv6.sysctl.flowlabel_reflect;
 223         ipv6_table[10].data = &net->ipv6.sysctl.max_dst_opts_cnt;
 224         ipv6_table[11].data = &net->ipv6.sysctl.max_hbh_opts_cnt;
 225         ipv6_table[12].data = &net->ipv6.sysctl.max_dst_opts_len;
 226         ipv6_table[13].data = &net->ipv6.sysctl.max_hbh_opts_len;
 227         ipv6_table[14].data = &net->ipv6.sysctl.multipath_hash_policy,
 228         ipv6_table[15].data = &net->ipv6.sysctl.seg6_flowlabel;
 229 
 230         ipv6_route_table = ipv6_route_sysctl_init(net);
 231         if (!ipv6_route_table)
 232                 goto out_ipv6_table;
 233 
 234         ipv6_icmp_table = ipv6_icmp_sysctl_init(net);
 235         if (!ipv6_icmp_table)
 236                 goto out_ipv6_route_table;
 237 
 238         net->ipv6.sysctl.hdr = register_net_sysctl(net, "net/ipv6", ipv6_table);
 239         if (!net->ipv6.sysctl.hdr)
 240                 goto out_ipv6_icmp_table;
 241 
 242         net->ipv6.sysctl.route_hdr =
 243                 register_net_sysctl(net, "net/ipv6/route", ipv6_route_table);
 244         if (!net->ipv6.sysctl.route_hdr)
 245                 goto out_unregister_ipv6_table;
 246 
 247         net->ipv6.sysctl.icmp_hdr =
 248                 register_net_sysctl(net, "net/ipv6/icmp", ipv6_icmp_table);
 249         if (!net->ipv6.sysctl.icmp_hdr)
 250                 goto out_unregister_route_table;
 251 
 252         err = 0;
 253 out:
 254         return err;
 255 out_unregister_route_table:
 256         unregister_net_sysctl_table(net->ipv6.sysctl.route_hdr);
 257 out_unregister_ipv6_table:
 258         unregister_net_sysctl_table(net->ipv6.sysctl.hdr);
 259 out_ipv6_icmp_table:
 260         kfree(ipv6_icmp_table);
 261 out_ipv6_route_table:
 262         kfree(ipv6_route_table);
 263 out_ipv6_table:
 264         kfree(ipv6_table);
 265         goto out;
 266 }
 267 
 268 static void __net_exit ipv6_sysctl_net_exit(struct net *net)
 269 {
 270         struct ctl_table *ipv6_table;
 271         struct ctl_table *ipv6_route_table;
 272         struct ctl_table *ipv6_icmp_table;
 273 
 274         ipv6_table = net->ipv6.sysctl.hdr->ctl_table_arg;
 275         ipv6_route_table = net->ipv6.sysctl.route_hdr->ctl_table_arg;
 276         ipv6_icmp_table = net->ipv6.sysctl.icmp_hdr->ctl_table_arg;
 277 
 278         unregister_net_sysctl_table(net->ipv6.sysctl.icmp_hdr);
 279         unregister_net_sysctl_table(net->ipv6.sysctl.route_hdr);
 280         unregister_net_sysctl_table(net->ipv6.sysctl.hdr);
 281 
 282         kfree(ipv6_table);
 283         kfree(ipv6_route_table);
 284         kfree(ipv6_icmp_table);
 285 }
 286 
 287 static struct pernet_operations ipv6_sysctl_net_ops = {
 288         .init = ipv6_sysctl_net_init,
 289         .exit = ipv6_sysctl_net_exit,
 290 };
 291 
 292 static struct ctl_table_header *ip6_header;
 293 
 294 int ipv6_sysctl_register(void)
 295 {
 296         int err = -ENOMEM;
 297 
 298         ip6_header = register_net_sysctl(&init_net, "net/ipv6", ipv6_rotable);
 299         if (!ip6_header)
 300                 goto out;
 301 
 302         err = register_pernet_subsys(&ipv6_sysctl_net_ops);
 303         if (err)
 304                 goto err_pernet;
 305 out:
 306         return err;
 307 
 308 err_pernet:
 309         unregister_net_sysctl_table(ip6_header);
 310         goto out;
 311 }
 312 
 313 void ipv6_sysctl_unregister(void)
 314 {
 315         unregister_net_sysctl_table(ip6_header);
 316         unregister_pernet_subsys(&ipv6_sysctl_net_ops);
 317 }

/* [<][>][^][v][top][bottom][index][help] */