1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * 4 * Copyright (C) 1996 Mike Shaver (shaver@zeroknowledge.com) 5 */ 6 #include <linux/mm.h> 7 #include <linux/slab.h> 8 #include <linux/sysctl.h> 9 #include <linux/spinlock.h> 10 #include <net/ax25.h> 11 12 static int min_ipdefmode[1], max_ipdefmode[] = {1}; 13 static int min_axdefmode[1], max_axdefmode[] = {1}; 14 static int min_backoff[1], max_backoff[] = {2}; 15 static int min_conmode[1], max_conmode[] = {2}; 16 static int min_window[] = {1}, max_window[] = {7}; 17 static int min_ewindow[] = {1}, max_ewindow[] = {63}; 18 static int min_t1[] = {1}, max_t1[] = {30000}; 19 static int min_t2[] = {1}, max_t2[] = {20000}; 20 static int min_t3[1], max_t3[] = {3600000}; 21 static int min_idle[1], max_idle[] = {65535000}; 22 static int min_n2[] = {1}, max_n2[] = {31}; 23 static int min_paclen[] = {1}, max_paclen[] = {512}; 24 static int min_proto[1], max_proto[] = { AX25_PROTO_MAX }; 25 #ifdef CONFIG_AX25_DAMA_SLAVE 26 static int min_ds_timeout[1], max_ds_timeout[] = {65535000}; 27 #endif 28 29 static const struct ctl_table ax25_param_table[] = { 30 { 31 .procname = "ip_default_mode", 32 .maxlen = sizeof(int), 33 .mode = 0644, 34 .proc_handler = proc_dointvec_minmax, 35 .extra1 = &min_ipdefmode, 36 .extra2 = &max_ipdefmode 37 }, 38 { 39 .procname = "ax25_default_mode", 40 .maxlen = sizeof(int), 41 .mode = 0644, 42 .proc_handler = proc_dointvec_minmax, 43 .extra1 = &min_axdefmode, 44 .extra2 = &max_axdefmode 45 }, 46 { 47 .procname = "backoff_type", 48 .maxlen = sizeof(int), 49 .mode = 0644, 50 .proc_handler = proc_dointvec_minmax, 51 .extra1 = &min_backoff, 52 .extra2 = &max_backoff 53 }, 54 { 55 .procname = "connect_mode", 56 .maxlen = sizeof(int), 57 .mode = 0644, 58 .proc_handler = proc_dointvec_minmax, 59 .extra1 = &min_conmode, 60 .extra2 = &max_conmode 61 }, 62 { 63 .procname = "standard_window_size", 64 .maxlen = sizeof(int), 65 .mode = 0644, 66 .proc_handler = proc_dointvec_minmax, 67 .extra1 = &min_window, 68 .extra2 = &max_window 69 }, 70 { 71 .procname = "extended_window_size", 72 .maxlen = sizeof(int), 73 .mode = 0644, 74 .proc_handler = proc_dointvec_minmax, 75 .extra1 = &min_ewindow, 76 .extra2 = &max_ewindow 77 }, 78 { 79 .procname = "t1_timeout", 80 .maxlen = sizeof(int), 81 .mode = 0644, 82 .proc_handler = proc_dointvec_minmax, 83 .extra1 = &min_t1, 84 .extra2 = &max_t1 85 }, 86 { 87 .procname = "t2_timeout", 88 .maxlen = sizeof(int), 89 .mode = 0644, 90 .proc_handler = proc_dointvec_minmax, 91 .extra1 = &min_t2, 92 .extra2 = &max_t2 93 }, 94 { 95 .procname = "t3_timeout", 96 .maxlen = sizeof(int), 97 .mode = 0644, 98 .proc_handler = proc_dointvec_minmax, 99 .extra1 = &min_t3, 100 .extra2 = &max_t3 101 }, 102 { 103 .procname = "idle_timeout", 104 .maxlen = sizeof(int), 105 .mode = 0644, 106 .proc_handler = proc_dointvec_minmax, 107 .extra1 = &min_idle, 108 .extra2 = &max_idle 109 }, 110 { 111 .procname = "maximum_retry_count", 112 .maxlen = sizeof(int), 113 .mode = 0644, 114 .proc_handler = proc_dointvec_minmax, 115 .extra1 = &min_n2, 116 .extra2 = &max_n2 117 }, 118 { 119 .procname = "maximum_packet_length", 120 .maxlen = sizeof(int), 121 .mode = 0644, 122 .proc_handler = proc_dointvec_minmax, 123 .extra1 = &min_paclen, 124 .extra2 = &max_paclen 125 }, 126 { 127 .procname = "protocol", 128 .maxlen = sizeof(int), 129 .mode = 0644, 130 .proc_handler = proc_dointvec_minmax, 131 .extra1 = &min_proto, 132 .extra2 = &max_proto 133 }, 134 #ifdef CONFIG_AX25_DAMA_SLAVE 135 { 136 .procname = "dama_slave_timeout", 137 .maxlen = sizeof(int), 138 .mode = 0644, 139 .proc_handler = proc_dointvec_minmax, 140 .extra1 = &min_ds_timeout, 141 .extra2 = &max_ds_timeout 142 }, 143 #endif 144 145 { } /* that's all, folks! */ 146 }; 147 148 int ax25_register_dev_sysctl(ax25_dev *ax25_dev) 149 { 150 char path[sizeof("net/ax25/") + IFNAMSIZ]; 151 int k; 152 struct ctl_table *table; 153 154 table = kmemdup(ax25_param_table, sizeof(ax25_param_table), GFP_KERNEL); 155 if (!table) 156 return -ENOMEM; 157 158 for (k = 0; k < AX25_MAX_VALUES; k++) 159 table[k].data = &ax25_dev->values[k]; 160 161 snprintf(path, sizeof(path), "net/ax25/%s", ax25_dev->dev->name); 162 ax25_dev->sysheader = register_net_sysctl_sz(&init_net, path, table, 163 ARRAY_SIZE(ax25_param_table)); 164 if (!ax25_dev->sysheader) { 165 kfree(table); 166 return -ENOMEM; 167 } 168 return 0; 169 } 170 171 void ax25_unregister_dev_sysctl(ax25_dev *ax25_dev) 172 { 173 struct ctl_table_header *header = ax25_dev->sysheader; 174 struct ctl_table *table; 175 176 if (header) { 177 ax25_dev->sysheader = NULL; 178 table = header->ctl_table_arg; 179 unregister_net_sysctl_table(header); 180 kfree(table); 181 } 182 } 183