~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to net/decnet/sysctl_net_decnet.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 <SteveW@ACM.org>
 
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
                        /* Fallthrough */
 
78
                case 0:
 
79
                        return;
 
80
                }
 
81
                str++;
 
82
        }
 
83
}
 
84
 
 
85
/*
 
86
 * Simple routine to parse an ascii DECnet address
 
87
 * into a network order address.
 
88
 */
 
89
static int parse_addr(__le16 *addr, char *str)
 
90
{
 
91
        __u16 area, node;
 
92
 
 
93
        while(*str && !ISNUM(*str)) str++;
 
94
 
 
95
        if (*str == 0)
 
96
                return -1;
 
97
 
 
98
        area = (*str++ - '0');
 
99
        if (ISNUM(*str)) {
 
100
                area *= 10;
 
101
                area += (*str++ - '0');
 
102
        }
 
103
 
 
104
        if (*str++ != '.')
 
105
                return -1;
 
106
 
 
107
        if (!ISNUM(*str))
 
108
                return -1;
 
109
 
 
110
        node = *str++ - '0';
 
111
        if (ISNUM(*str)) {
 
112
                node *= 10;
 
113
                node += (*str++ - '0');
 
114
        }
 
115
        if (ISNUM(*str)) {
 
116
                node *= 10;
 
117
                node += (*str++ - '0');
 
118
        }
 
119
        if (ISNUM(*str)) {
 
120
                node *= 10;
 
121
                node += (*str++ - '0');
 
122
        }
 
123
 
 
124
        if ((node > 1023) || (area > 63))
 
125
                return -1;
 
126
 
 
127
        if (INVALID_END_CHAR(*str))
 
128
                return -1;
 
129
 
 
130
        *addr = cpu_to_le16((area << 10) | node);
 
131
 
 
132
        return 0;
 
133
}
 
134
 
 
135
static int dn_node_address_handler(ctl_table *table, int write,
 
136
                                void __user *buffer,
 
137
                                size_t *lenp, loff_t *ppos)
 
138
{
 
139
        char addr[DN_ASCBUF_LEN];
 
140
        size_t len;
 
141
        __le16 dnaddr;
 
142
 
 
143
        if (!*lenp || (*ppos && !write)) {
 
144
                *lenp = 0;
 
145
                return 0;
 
146
        }
 
147
 
 
148
        if (write) {
 
149
                len = (*lenp < DN_ASCBUF_LEN) ? *lenp : (DN_ASCBUF_LEN-1);
 
150
 
 
151
                if (copy_from_user(addr, buffer, len))
 
152
                        return -EFAULT;
 
153
 
 
154
                addr[len] = 0;
 
155
                strip_it(addr);
 
156
 
 
157
                if (parse_addr(&dnaddr, addr))
 
158
                        return -EINVAL;
 
159
 
 
160
                dn_dev_devices_off();
 
161
 
 
162
                decnet_address = dnaddr;
 
163
 
 
164
                dn_dev_devices_on();
 
165
 
 
166
                *ppos += len;
 
167
 
 
168
                return 0;
 
169
        }
 
170
 
 
171
        dn_addr2asc(le16_to_cpu(decnet_address), addr);
 
172
        len = strlen(addr);
 
173
        addr[len++] = '\n';
 
174
 
 
175
        if (len > *lenp) len = *lenp;
 
176
 
 
177
        if (copy_to_user(buffer, addr, len))
 
178
                return -EFAULT;
 
179
 
 
180
        *lenp = len;
 
181
        *ppos += len;
 
182
 
 
183
        return 0;
 
184
}
 
185
 
 
186
static int dn_def_dev_handler(ctl_table *table, int write,
 
187
                                void __user *buffer,
 
188
                                size_t *lenp, loff_t *ppos)
 
189
{
 
190
        size_t len;
 
191
        struct net_device *dev;
 
192
        char devname[17];
 
193
 
 
194
        if (!*lenp || (*ppos && !write)) {
 
195
                *lenp = 0;
 
196
                return 0;
 
197
        }
 
198
 
 
199
        if (write) {
 
200
                if (*lenp > 16)
 
201
                        return -E2BIG;
 
202
 
 
203
                if (copy_from_user(devname, buffer, *lenp))
 
204
                        return -EFAULT;
 
205
 
 
206
                devname[*lenp] = 0;
 
207
                strip_it(devname);
 
208
 
 
209
                dev = dev_get_by_name(&init_net, devname);
 
210
                if (dev == NULL)
 
211
                        return -ENODEV;
 
212
 
 
213
                if (dev->dn_ptr == NULL) {
 
214
                        dev_put(dev);
 
215
                        return -ENODEV;
 
216
                }
 
217
 
 
218
                if (dn_dev_set_default(dev, 1)) {
 
219
                        dev_put(dev);
 
220
                        return -ENODEV;
 
221
                }
 
222
                *ppos += *lenp;
 
223
 
 
224
                return 0;
 
225
        }
 
226
 
 
227
        dev = dn_dev_get_default();
 
228
        if (dev == NULL) {
 
229
                *lenp = 0;
 
230
                return 0;
 
231
        }
 
232
 
 
233
        strcpy(devname, dev->name);
 
234
        dev_put(dev);
 
235
        len = strlen(devname);
 
236
        devname[len++] = '\n';
 
237
 
 
238
        if (len > *lenp) len = *lenp;
 
239
 
 
240
        if (copy_to_user(buffer, devname, len))
 
241
                return -EFAULT;
 
242
 
 
243
        *lenp = len;
 
244
        *ppos += len;
 
245
 
 
246
        return 0;
 
247
}
 
248
 
 
249
static ctl_table dn_table[] = {
 
250
        {
 
251
                .procname = "node_address",
 
252
                .maxlen = 7,
 
253
                .mode = 0644,
 
254
                .proc_handler = dn_node_address_handler,
 
255
        },
 
256
        {
 
257
                .procname = "node_name",
 
258
                .data = node_name,
 
259
                .maxlen = 7,
 
260
                .mode = 0644,
 
261
                .proc_handler = proc_dostring,
 
262
        },
 
263
        {
 
264
                .procname = "default_device",
 
265
                .maxlen = 16,
 
266
                .mode = 0644,
 
267
                .proc_handler = dn_def_dev_handler,
 
268
        },
 
269
        {
 
270
                .procname = "time_wait",
 
271
                .data = &decnet_time_wait,
 
272
                .maxlen = sizeof(int),
 
273
                .mode = 0644,
 
274
                .proc_handler = proc_dointvec_minmax,
 
275
                .extra1 = &min_decnet_time_wait,
 
276
                .extra2 = &max_decnet_time_wait
 
277
        },
 
278
        {
 
279
                .procname = "dn_count",
 
280
                .data = &decnet_dn_count,
 
281
                .maxlen = sizeof(int),
 
282
                .mode = 0644,
 
283
                .proc_handler = proc_dointvec_minmax,
 
284
                .extra1 = &min_state_count,
 
285
                .extra2 = &max_state_count
 
286
        },
 
287
        {
 
288
                .procname = "di_count",
 
289
                .data = &decnet_di_count,
 
290
                .maxlen = sizeof(int),
 
291
                .mode = 0644,
 
292
                .proc_handler = proc_dointvec_minmax,
 
293
                .extra1 = &min_state_count,
 
294
                .extra2 = &max_state_count
 
295
        },
 
296
        {
 
297
                .procname = "dr_count",
 
298
                .data = &decnet_dr_count,
 
299
                .maxlen = sizeof(int),
 
300
                .mode = 0644,
 
301
                .proc_handler = proc_dointvec_minmax,
 
302
                .extra1 = &min_state_count,
 
303
                .extra2 = &max_state_count
 
304
        },
 
305
        {
 
306
                .procname = "dst_gc_interval",
 
307
                .data = &decnet_dst_gc_interval,
 
308
                .maxlen = sizeof(int),
 
309
                .mode = 0644,
 
310
                .proc_handler = proc_dointvec_minmax,
 
311
                .extra1 = &min_decnet_dst_gc_interval,
 
312
                .extra2 = &max_decnet_dst_gc_interval
 
313
        },
 
314
        {
 
315
                .procname = "no_fc_max_cwnd",
 
316
                .data = &decnet_no_fc_max_cwnd,
 
317
                .maxlen = sizeof(int),
 
318
                .mode = 0644,
 
319
                .proc_handler = proc_dointvec_minmax,
 
320
                .extra1 = &min_decnet_no_fc_max_cwnd,
 
321
                .extra2 = &max_decnet_no_fc_max_cwnd
 
322
        },
 
323
       {
 
324
                .procname = "decnet_mem",
 
325
                .data = &sysctl_decnet_mem,
 
326
                .maxlen = sizeof(sysctl_decnet_mem),
 
327
                .mode = 0644,
 
328
                .proc_handler = proc_doulongvec_minmax
 
329
        },
 
330
        {
 
331
                .procname = "decnet_rmem",
 
332
                .data = &sysctl_decnet_rmem,
 
333
                .maxlen = sizeof(sysctl_decnet_rmem),
 
334
                .mode = 0644,
 
335
                .proc_handler = proc_dointvec,
 
336
        },
 
337
        {
 
338
                .procname = "decnet_wmem",
 
339
                .data = &sysctl_decnet_wmem,
 
340
                .maxlen = sizeof(sysctl_decnet_wmem),
 
341
                .mode = 0644,
 
342
                .proc_handler = proc_dointvec,
 
343
        },
 
344
        {
 
345
                .procname = "debug",
 
346
                .data = &decnet_debug_level,
 
347
                .maxlen = sizeof(int),
 
348
                .mode = 0644,
 
349
                .proc_handler = proc_dointvec,
 
350
        },
 
351
        { }
 
352
};
 
353
 
 
354
static struct ctl_path dn_path[] = {
 
355
        { .procname = "net", },
 
356
        { .procname = "decnet", },
 
357
        { }
 
358
};
 
359
 
 
360
void dn_register_sysctl(void)
 
361
{
 
362
        dn_table_header = register_sysctl_paths(dn_path, dn_table);
 
363
}
 
364
 
 
365
void dn_unregister_sysctl(void)
 
366
{
 
367
        unregister_sysctl_table(dn_table_header);
 
368
}
 
369
 
 
370
#else  /* CONFIG_SYSCTL */
 
371
void dn_unregister_sysctl(void)
 
372
{
 
373
}
 
374
void dn_register_sysctl(void)
 
375
{
 
376
}
 
377
 
 
378
#endif