LCOV - code coverage report
Current view: top level - net/ipv6 - sysctl_net_ipv6.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 46 92 50.0 %
Date: 2022-04-01 14:35:51 Functions: 2 5 40.0 %
Branches: 8 18 44.4 %

           Branch data     Line data    Source code
       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                 :          0 : 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                 :          0 :         struct net *net;
      33                 :          0 :         int ret;
      34                 :            : 
      35                 :          0 :         net = container_of(table->data, struct net,
      36                 :            :                            ipv6.sysctl.multipath_hash_policy);
      37                 :          0 :         ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
      38         [ #  # ]:          0 :         if (write && ret == 0)
      39                 :          0 :                 call_netevent_notifiers(NETEVENT_IPV6_MPATH_HASH_UPDATE, net);
      40                 :            : 
      41                 :          0 :         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                 :         21 : static int __net_init ipv6_sysctl_net_init(struct net *net)
     202                 :            : {
     203                 :         21 :         struct ctl_table *ipv6_table;
     204                 :         21 :         struct ctl_table *ipv6_route_table;
     205                 :         21 :         struct ctl_table *ipv6_icmp_table;
     206                 :         21 :         int err;
     207                 :            : 
     208                 :         21 :         err = -ENOMEM;
     209                 :         21 :         ipv6_table = kmemdup(ipv6_table_template, sizeof(ipv6_table_template),
     210                 :            :                              GFP_KERNEL);
     211         [ -  + ]:         21 :         if (!ipv6_table)
     212                 :          0 :                 goto out;
     213                 :         21 :         ipv6_table[0].data = &net->ipv6.sysctl.bindv6only;
     214                 :         21 :         ipv6_table[1].data = &net->ipv6.sysctl.anycast_src_echo_reply;
     215                 :         21 :         ipv6_table[2].data = &net->ipv6.sysctl.flowlabel_consistency;
     216                 :         21 :         ipv6_table[3].data = &net->ipv6.sysctl.auto_flowlabels;
     217                 :         21 :         ipv6_table[4].data = &net->ipv6.sysctl.fwmark_reflect;
     218                 :         21 :         ipv6_table[5].data = &net->ipv6.sysctl.idgen_retries;
     219                 :         21 :         ipv6_table[6].data = &net->ipv6.sysctl.idgen_delay;
     220                 :         21 :         ipv6_table[7].data = &net->ipv6.sysctl.flowlabel_state_ranges;
     221                 :         21 :         ipv6_table[8].data = &net->ipv6.sysctl.ip_nonlocal_bind;
     222                 :         21 :         ipv6_table[9].data = &net->ipv6.sysctl.flowlabel_reflect;
     223                 :         21 :         ipv6_table[10].data = &net->ipv6.sysctl.max_dst_opts_cnt;
     224                 :         21 :         ipv6_table[11].data = &net->ipv6.sysctl.max_hbh_opts_cnt;
     225                 :         21 :         ipv6_table[12].data = &net->ipv6.sysctl.max_dst_opts_len;
     226                 :         21 :         ipv6_table[13].data = &net->ipv6.sysctl.max_hbh_opts_len;
     227                 :         21 :         ipv6_table[14].data = &net->ipv6.sysctl.multipath_hash_policy,
     228                 :         21 :         ipv6_table[15].data = &net->ipv6.sysctl.seg6_flowlabel;
     229                 :            : 
     230                 :         21 :         ipv6_route_table = ipv6_route_sysctl_init(net);
     231         [ -  + ]:         21 :         if (!ipv6_route_table)
     232                 :          0 :                 goto out_ipv6_table;
     233                 :            : 
     234                 :         21 :         ipv6_icmp_table = ipv6_icmp_sysctl_init(net);
     235         [ -  + ]:         21 :         if (!ipv6_icmp_table)
     236                 :          0 :                 goto out_ipv6_route_table;
     237                 :            : 
     238                 :         21 :         net->ipv6.sysctl.hdr = register_net_sysctl(net, "net/ipv6", ipv6_table);
     239         [ -  + ]:         21 :         if (!net->ipv6.sysctl.hdr)
     240                 :          0 :                 goto out_ipv6_icmp_table;
     241                 :            : 
     242                 :         42 :         net->ipv6.sysctl.route_hdr =
     243                 :         21 :                 register_net_sysctl(net, "net/ipv6/route", ipv6_route_table);
     244         [ -  + ]:         21 :         if (!net->ipv6.sysctl.route_hdr)
     245                 :          0 :                 goto out_unregister_ipv6_table;
     246                 :            : 
     247                 :         42 :         net->ipv6.sysctl.icmp_hdr =
     248                 :         21 :                 register_net_sysctl(net, "net/ipv6/icmp", ipv6_icmp_table);
     249         [ -  + ]:         21 :         if (!net->ipv6.sysctl.icmp_hdr)
     250                 :          0 :                 goto out_unregister_route_table;
     251                 :            : 
     252                 :            :         err = 0;
     253                 :         21 : out:
     254                 :         21 :         return err;
     255                 :            : out_unregister_route_table:
     256                 :          0 :         unregister_net_sysctl_table(net->ipv6.sysctl.route_hdr);
     257                 :          0 : out_unregister_ipv6_table:
     258                 :          0 :         unregister_net_sysctl_table(net->ipv6.sysctl.hdr);
     259                 :          0 : out_ipv6_icmp_table:
     260                 :          0 :         kfree(ipv6_icmp_table);
     261                 :          0 : out_ipv6_route_table:
     262                 :          0 :         kfree(ipv6_route_table);
     263                 :          0 : out_ipv6_table:
     264                 :          0 :         kfree(ipv6_table);
     265                 :          0 :         goto out;
     266                 :            : }
     267                 :            : 
     268                 :          0 : static void __net_exit ipv6_sysctl_net_exit(struct net *net)
     269                 :            : {
     270                 :          0 :         struct ctl_table *ipv6_table;
     271                 :          0 :         struct ctl_table *ipv6_route_table;
     272                 :          0 :         struct ctl_table *ipv6_icmp_table;
     273                 :            : 
     274                 :          0 :         ipv6_table = net->ipv6.sysctl.hdr->ctl_table_arg;
     275                 :          0 :         ipv6_route_table = net->ipv6.sysctl.route_hdr->ctl_table_arg;
     276                 :          0 :         ipv6_icmp_table = net->ipv6.sysctl.icmp_hdr->ctl_table_arg;
     277                 :            : 
     278                 :          0 :         unregister_net_sysctl_table(net->ipv6.sysctl.icmp_hdr);
     279                 :          0 :         unregister_net_sysctl_table(net->ipv6.sysctl.route_hdr);
     280                 :          0 :         unregister_net_sysctl_table(net->ipv6.sysctl.hdr);
     281                 :            : 
     282                 :          0 :         kfree(ipv6_table);
     283                 :          0 :         kfree(ipv6_route_table);
     284                 :          0 :         kfree(ipv6_icmp_table);
     285                 :          0 : }
     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                 :         21 : int ipv6_sysctl_register(void)
     295                 :            : {
     296                 :         21 :         int err = -ENOMEM;
     297                 :            : 
     298                 :         21 :         ip6_header = register_net_sysctl(&init_net, "net/ipv6", ipv6_rotable);
     299         [ -  + ]:         21 :         if (!ip6_header)
     300                 :          0 :                 goto out;
     301                 :            : 
     302                 :         21 :         err = register_pernet_subsys(&ipv6_sysctl_net_ops);
     303         [ +  - ]:         21 :         if (err)
     304                 :          0 :                 goto err_pernet;
     305                 :         21 : out:
     306                 :         21 :         return err;
     307                 :            : 
     308                 :            : err_pernet:
     309                 :          0 :         unregister_net_sysctl_table(ip6_header);
     310                 :          0 :         goto out;
     311                 :            : }
     312                 :            : 
     313                 :          0 : void ipv6_sysctl_unregister(void)
     314                 :            : {
     315                 :          0 :         unregister_net_sysctl_table(ip6_header);
     316                 :          0 :         unregister_pernet_subsys(&ipv6_sysctl_net_ops);
     317                 :          0 : }

Generated by: LCOV version 1.14