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(p: ax25_param_table, size: 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(buf: path, size: sizeof(path), fmt: "net/ax25/%s" , ax25_dev->dev->name); |
162 | ax25_dev->sysheader = register_net_sysctl_sz(net: &init_net, path, table, |
163 | ARRAY_SIZE(ax25_param_table)); |
164 | if (!ax25_dev->sysheader) { |
165 | kfree(objp: 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 * = 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(objp: table); |
181 | } |
182 | } |
183 | |