Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/net/decnet/sysctl_net_decnet.c
15109 views
1
/*
2
* DECnet An implementation of the DECnet protocol suite for the LINUX
3
* operating system. DECnet is implemented using the BSD Socket
4
* interface as the means of communication with the user level.
5
*
6
* DECnet sysctl support functions
7
*
8
* Author: Steve Whitehouse <[email protected]>
9
*
10
*
11
* Changes:
12
* Steve Whitehouse - C99 changes and default device handling
13
* Steve Whitehouse - Memory buffer settings, like the tcp ones
14
*
15
*/
16
#include <linux/mm.h>
17
#include <linux/sysctl.h>
18
#include <linux/fs.h>
19
#include <linux/netdevice.h>
20
#include <linux/string.h>
21
#include <net/neighbour.h>
22
#include <net/dst.h>
23
#include <net/flow.h>
24
25
#include <asm/uaccess.h>
26
27
#include <net/dn.h>
28
#include <net/dn_dev.h>
29
#include <net/dn_route.h>
30
31
32
int decnet_debug_level;
33
int decnet_time_wait = 30;
34
int decnet_dn_count = 1;
35
int decnet_di_count = 3;
36
int decnet_dr_count = 3;
37
int decnet_log_martians = 1;
38
int decnet_no_fc_max_cwnd = NSP_MIN_WINDOW;
39
40
/* Reasonable defaults, I hope, based on tcp's defaults */
41
long sysctl_decnet_mem[3] = { 768 << 3, 1024 << 3, 1536 << 3 };
42
int sysctl_decnet_wmem[3] = { 4 * 1024, 16 * 1024, 128 * 1024 };
43
int sysctl_decnet_rmem[3] = { 4 * 1024, 87380, 87380 * 2 };
44
45
#ifdef CONFIG_SYSCTL
46
extern int decnet_dst_gc_interval;
47
static int min_decnet_time_wait[] = { 5 };
48
static int max_decnet_time_wait[] = { 600 };
49
static int min_state_count[] = { 1 };
50
static int max_state_count[] = { NSP_MAXRXTSHIFT };
51
static int min_decnet_dst_gc_interval[] = { 1 };
52
static int max_decnet_dst_gc_interval[] = { 60 };
53
static int min_decnet_no_fc_max_cwnd[] = { NSP_MIN_WINDOW };
54
static int max_decnet_no_fc_max_cwnd[] = { NSP_MAX_WINDOW };
55
static char node_name[7] = "???";
56
57
static struct ctl_table_header *dn_table_header = NULL;
58
59
/*
60
* ctype.h :-)
61
*/
62
#define ISNUM(x) (((x) >= '0') && ((x) <= '9'))
63
#define ISLOWER(x) (((x) >= 'a') && ((x) <= 'z'))
64
#define ISUPPER(x) (((x) >= 'A') && ((x) <= 'Z'))
65
#define ISALPHA(x) (ISLOWER(x) || ISUPPER(x))
66
#define INVALID_END_CHAR(x) (ISNUM(x) || ISALPHA(x))
67
68
static void strip_it(char *str)
69
{
70
for(;;) {
71
switch(*str) {
72
case ' ':
73
case '\n':
74
case '\r':
75
case ':':
76
*str = 0;
77
case 0:
78
return;
79
}
80
str++;
81
}
82
}
83
84
/*
85
* Simple routine to parse an ascii DECnet address
86
* into a network order address.
87
*/
88
static int parse_addr(__le16 *addr, char *str)
89
{
90
__u16 area, node;
91
92
while(*str && !ISNUM(*str)) str++;
93
94
if (*str == 0)
95
return -1;
96
97
area = (*str++ - '0');
98
if (ISNUM(*str)) {
99
area *= 10;
100
area += (*str++ - '0');
101
}
102
103
if (*str++ != '.')
104
return -1;
105
106
if (!ISNUM(*str))
107
return -1;
108
109
node = *str++ - '0';
110
if (ISNUM(*str)) {
111
node *= 10;
112
node += (*str++ - '0');
113
}
114
if (ISNUM(*str)) {
115
node *= 10;
116
node += (*str++ - '0');
117
}
118
if (ISNUM(*str)) {
119
node *= 10;
120
node += (*str++ - '0');
121
}
122
123
if ((node > 1023) || (area > 63))
124
return -1;
125
126
if (INVALID_END_CHAR(*str))
127
return -1;
128
129
*addr = cpu_to_le16((area << 10) | node);
130
131
return 0;
132
}
133
134
static int dn_node_address_handler(ctl_table *table, int write,
135
void __user *buffer,
136
size_t *lenp, loff_t *ppos)
137
{
138
char addr[DN_ASCBUF_LEN];
139
size_t len;
140
__le16 dnaddr;
141
142
if (!*lenp || (*ppos && !write)) {
143
*lenp = 0;
144
return 0;
145
}
146
147
if (write) {
148
len = (*lenp < DN_ASCBUF_LEN) ? *lenp : (DN_ASCBUF_LEN-1);
149
150
if (copy_from_user(addr, buffer, len))
151
return -EFAULT;
152
153
addr[len] = 0;
154
strip_it(addr);
155
156
if (parse_addr(&dnaddr, addr))
157
return -EINVAL;
158
159
dn_dev_devices_off();
160
161
decnet_address = dnaddr;
162
163
dn_dev_devices_on();
164
165
*ppos += len;
166
167
return 0;
168
}
169
170
dn_addr2asc(le16_to_cpu(decnet_address), addr);
171
len = strlen(addr);
172
addr[len++] = '\n';
173
174
if (len > *lenp) len = *lenp;
175
176
if (copy_to_user(buffer, addr, len))
177
return -EFAULT;
178
179
*lenp = len;
180
*ppos += len;
181
182
return 0;
183
}
184
185
static int dn_def_dev_handler(ctl_table *table, int write,
186
void __user *buffer,
187
size_t *lenp, loff_t *ppos)
188
{
189
size_t len;
190
struct net_device *dev;
191
char devname[17];
192
193
if (!*lenp || (*ppos && !write)) {
194
*lenp = 0;
195
return 0;
196
}
197
198
if (write) {
199
if (*lenp > 16)
200
return -E2BIG;
201
202
if (copy_from_user(devname, buffer, *lenp))
203
return -EFAULT;
204
205
devname[*lenp] = 0;
206
strip_it(devname);
207
208
dev = dev_get_by_name(&init_net, devname);
209
if (dev == NULL)
210
return -ENODEV;
211
212
if (dev->dn_ptr == NULL) {
213
dev_put(dev);
214
return -ENODEV;
215
}
216
217
if (dn_dev_set_default(dev, 1)) {
218
dev_put(dev);
219
return -ENODEV;
220
}
221
*ppos += *lenp;
222
223
return 0;
224
}
225
226
dev = dn_dev_get_default();
227
if (dev == NULL) {
228
*lenp = 0;
229
return 0;
230
}
231
232
strcpy(devname, dev->name);
233
dev_put(dev);
234
len = strlen(devname);
235
devname[len++] = '\n';
236
237
if (len > *lenp) len = *lenp;
238
239
if (copy_to_user(buffer, devname, len))
240
return -EFAULT;
241
242
*lenp = len;
243
*ppos += len;
244
245
return 0;
246
}
247
248
static ctl_table dn_table[] = {
249
{
250
.procname = "node_address",
251
.maxlen = 7,
252
.mode = 0644,
253
.proc_handler = dn_node_address_handler,
254
},
255
{
256
.procname = "node_name",
257
.data = node_name,
258
.maxlen = 7,
259
.mode = 0644,
260
.proc_handler = proc_dostring,
261
},
262
{
263
.procname = "default_device",
264
.maxlen = 16,
265
.mode = 0644,
266
.proc_handler = dn_def_dev_handler,
267
},
268
{
269
.procname = "time_wait",
270
.data = &decnet_time_wait,
271
.maxlen = sizeof(int),
272
.mode = 0644,
273
.proc_handler = proc_dointvec_minmax,
274
.extra1 = &min_decnet_time_wait,
275
.extra2 = &max_decnet_time_wait
276
},
277
{
278
.procname = "dn_count",
279
.data = &decnet_dn_count,
280
.maxlen = sizeof(int),
281
.mode = 0644,
282
.proc_handler = proc_dointvec_minmax,
283
.extra1 = &min_state_count,
284
.extra2 = &max_state_count
285
},
286
{
287
.procname = "di_count",
288
.data = &decnet_di_count,
289
.maxlen = sizeof(int),
290
.mode = 0644,
291
.proc_handler = proc_dointvec_minmax,
292
.extra1 = &min_state_count,
293
.extra2 = &max_state_count
294
},
295
{
296
.procname = "dr_count",
297
.data = &decnet_dr_count,
298
.maxlen = sizeof(int),
299
.mode = 0644,
300
.proc_handler = proc_dointvec_minmax,
301
.extra1 = &min_state_count,
302
.extra2 = &max_state_count
303
},
304
{
305
.procname = "dst_gc_interval",
306
.data = &decnet_dst_gc_interval,
307
.maxlen = sizeof(int),
308
.mode = 0644,
309
.proc_handler = proc_dointvec_minmax,
310
.extra1 = &min_decnet_dst_gc_interval,
311
.extra2 = &max_decnet_dst_gc_interval
312
},
313
{
314
.procname = "no_fc_max_cwnd",
315
.data = &decnet_no_fc_max_cwnd,
316
.maxlen = sizeof(int),
317
.mode = 0644,
318
.proc_handler = proc_dointvec_minmax,
319
.extra1 = &min_decnet_no_fc_max_cwnd,
320
.extra2 = &max_decnet_no_fc_max_cwnd
321
},
322
{
323
.procname = "decnet_mem",
324
.data = &sysctl_decnet_mem,
325
.maxlen = sizeof(sysctl_decnet_mem),
326
.mode = 0644,
327
.proc_handler = proc_doulongvec_minmax
328
},
329
{
330
.procname = "decnet_rmem",
331
.data = &sysctl_decnet_rmem,
332
.maxlen = sizeof(sysctl_decnet_rmem),
333
.mode = 0644,
334
.proc_handler = proc_dointvec,
335
},
336
{
337
.procname = "decnet_wmem",
338
.data = &sysctl_decnet_wmem,
339
.maxlen = sizeof(sysctl_decnet_wmem),
340
.mode = 0644,
341
.proc_handler = proc_dointvec,
342
},
343
{
344
.procname = "debug",
345
.data = &decnet_debug_level,
346
.maxlen = sizeof(int),
347
.mode = 0644,
348
.proc_handler = proc_dointvec,
349
},
350
{ }
351
};
352
353
static struct ctl_path dn_path[] = {
354
{ .procname = "net", },
355
{ .procname = "decnet", },
356
{ }
357
};
358
359
void dn_register_sysctl(void)
360
{
361
dn_table_header = register_sysctl_paths(dn_path, dn_table);
362
}
363
364
void dn_unregister_sysctl(void)
365
{
366
unregister_sysctl_table(dn_table_header);
367
}
368
369
#else /* CONFIG_SYSCTL */
370
void dn_unregister_sysctl(void)
371
{
372
}
373
void dn_register_sysctl(void)
374
{
375
}
376
377
#endif
378
379