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