Linux Audio

Check our new training course

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