root/net/phonet/sysctl.c

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

DEFINITIONS

This source file includes following definitions.
  1. set_local_port_range
  2. phonet_get_local_port_range
  3. proc_local_port_range
  4. phonet_sysctl_init
  5. phonet_sysctl_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * File: sysctl.c
   4  *
   5  * Phonet /proc/sys/net/phonet interface implementation
   6  *
   7  * Copyright (C) 2008 Nokia Corporation.
   8  *
   9  * Author: RĂ©mi Denis-Courmont
  10  */
  11 
  12 #include <linux/seqlock.h>
  13 #include <linux/sysctl.h>
  14 #include <linux/errno.h>
  15 #include <linux/init.h>
  16 
  17 #include <net/sock.h>
  18 #include <linux/phonet.h>
  19 #include <net/phonet/phonet.h>
  20 
  21 #define DYNAMIC_PORT_MIN        0x40
  22 #define DYNAMIC_PORT_MAX        0x7f
  23 
  24 static DEFINE_SEQLOCK(local_port_range_lock);
  25 static int local_port_range_min[2] = {0, 0};
  26 static int local_port_range_max[2] = {1023, 1023};
  27 static int local_port_range[2] = {DYNAMIC_PORT_MIN, DYNAMIC_PORT_MAX};
  28 static struct ctl_table_header *phonet_table_hrd;
  29 
  30 static void set_local_port_range(int range[2])
  31 {
  32         write_seqlock(&local_port_range_lock);
  33         local_port_range[0] = range[0];
  34         local_port_range[1] = range[1];
  35         write_sequnlock(&local_port_range_lock);
  36 }
  37 
  38 void phonet_get_local_port_range(int *min, int *max)
  39 {
  40         unsigned int seq;
  41 
  42         do {
  43                 seq = read_seqbegin(&local_port_range_lock);
  44                 if (min)
  45                         *min = local_port_range[0];
  46                 if (max)
  47                         *max = local_port_range[1];
  48         } while (read_seqretry(&local_port_range_lock, seq));
  49 }
  50 
  51 static int proc_local_port_range(struct ctl_table *table, int write,
  52                                 void __user *buffer,
  53                                 size_t *lenp, loff_t *ppos)
  54 {
  55         int ret;
  56         int range[2] = {local_port_range[0], local_port_range[1]};
  57         struct ctl_table tmp = {
  58                 .data = &range,
  59                 .maxlen = sizeof(range),
  60                 .mode = table->mode,
  61                 .extra1 = &local_port_range_min,
  62                 .extra2 = &local_port_range_max,
  63         };
  64 
  65         ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
  66 
  67         if (write && ret == 0) {
  68                 if (range[1] < range[0])
  69                         ret = -EINVAL;
  70                 else
  71                         set_local_port_range(range);
  72         }
  73 
  74         return ret;
  75 }
  76 
  77 static struct ctl_table phonet_table[] = {
  78         {
  79                 .procname       = "local_port_range",
  80                 .data           = &local_port_range,
  81                 .maxlen         = sizeof(local_port_range),
  82                 .mode           = 0644,
  83                 .proc_handler   = proc_local_port_range,
  84         },
  85         { }
  86 };
  87 
  88 int __init phonet_sysctl_init(void)
  89 {
  90         phonet_table_hrd = register_net_sysctl(&init_net, "net/phonet", phonet_table);
  91         return phonet_table_hrd == NULL ? -ENOMEM : 0;
  92 }
  93 
  94 void phonet_sysctl_exit(void)
  95 {
  96         unregister_net_sysctl_table(phonet_table_hrd);
  97 }

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