Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.19 512 lines 11 kB view raw
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 */ 41int 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 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 */ 88static 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 = dn_htons((area << 10) | node); 130 131 return 0; 132} 133 134 135static int dn_node_address_strategy(ctl_table *table, int __user *name, int nlen, 136 void __user *oldval, size_t __user *oldlenp, 137 void __user *newval, size_t newlen, 138 void **context) 139{ 140 size_t len; 141 __le16 addr; 142 143 if (oldval && oldlenp) { 144 if (get_user(len, oldlenp)) 145 return -EFAULT; 146 if (len) { 147 if (len != sizeof(unsigned short)) 148 return -EINVAL; 149 if (put_user(decnet_address, (__le16 __user *)oldval)) 150 return -EFAULT; 151 } 152 } 153 if (newval && newlen) { 154 if (newlen != sizeof(unsigned short)) 155 return -EINVAL; 156 if (get_user(addr, (__le16 __user *)newval)) 157 return -EFAULT; 158 159 dn_dev_devices_off(); 160 161 decnet_address = addr; 162 163 dn_dev_devices_on(); 164 } 165 return 0; 166} 167 168static int dn_node_address_handler(ctl_table *table, int write, 169 struct file *filp, 170 void __user *buffer, 171 size_t *lenp, loff_t *ppos) 172{ 173 char addr[DN_ASCBUF_LEN]; 174 size_t len; 175 __le16 dnaddr; 176 177 if (!*lenp || (*ppos && !write)) { 178 *lenp = 0; 179 return 0; 180 } 181 182 if (write) { 183 int len = (*lenp < DN_ASCBUF_LEN) ? *lenp : (DN_ASCBUF_LEN-1); 184 185 if (copy_from_user(addr, buffer, len)) 186 return -EFAULT; 187 188 addr[len] = 0; 189 strip_it(addr); 190 191 if (parse_addr(&dnaddr, addr)) 192 return -EINVAL; 193 194 dn_dev_devices_off(); 195 196 decnet_address = dnaddr; 197 198 dn_dev_devices_on(); 199 200 *ppos += len; 201 202 return 0; 203 } 204 205 dn_addr2asc(dn_ntohs(decnet_address), addr); 206 len = strlen(addr); 207 addr[len++] = '\n'; 208 209 if (len > *lenp) len = *lenp; 210 211 if (copy_to_user(buffer, addr, len)) 212 return -EFAULT; 213 214 *lenp = len; 215 *ppos += len; 216 217 return 0; 218} 219 220 221static int dn_def_dev_strategy(ctl_table *table, int __user *name, int nlen, 222 void __user *oldval, size_t __user *oldlenp, 223 void __user *newval, size_t newlen, 224 void **context) 225{ 226 size_t len; 227 struct net_device *dev; 228 char devname[17]; 229 size_t namel; 230 int rv = 0; 231 232 devname[0] = 0; 233 234 if (oldval && oldlenp) { 235 if (get_user(len, oldlenp)) 236 return -EFAULT; 237 if (len) { 238 dev = dn_dev_get_default(); 239 if (dev) { 240 strcpy(devname, dev->name); 241 dev_put(dev); 242 } 243 244 namel = strlen(devname) + 1; 245 if (len > namel) len = namel; 246 247 if (copy_to_user(oldval, devname, len)) 248 return -EFAULT; 249 250 if (put_user(len, oldlenp)) 251 return -EFAULT; 252 } 253 } 254 255 if (newval && newlen) { 256 if (newlen > 16) 257 return -E2BIG; 258 259 if (copy_from_user(devname, newval, newlen)) 260 return -EFAULT; 261 262 devname[newlen] = 0; 263 264 dev = dev_get_by_name(devname); 265 if (dev == NULL) 266 return -ENODEV; 267 268 rv = -ENODEV; 269 if (dev->dn_ptr != NULL) { 270 rv = dn_dev_set_default(dev, 1); 271 if (rv) 272 dev_put(dev); 273 } 274 } 275 276 return rv; 277} 278 279 280static int dn_def_dev_handler(ctl_table *table, int write, 281 struct file * filp, 282 void __user *buffer, 283 size_t *lenp, loff_t *ppos) 284{ 285 size_t len; 286 struct net_device *dev; 287 char devname[17]; 288 289 if (!*lenp || (*ppos && !write)) { 290 *lenp = 0; 291 return 0; 292 } 293 294 if (write) { 295 if (*lenp > 16) 296 return -E2BIG; 297 298 if (copy_from_user(devname, buffer, *lenp)) 299 return -EFAULT; 300 301 devname[*lenp] = 0; 302 strip_it(devname); 303 304 dev = dev_get_by_name(devname); 305 if (dev == NULL) 306 return -ENODEV; 307 308 if (dev->dn_ptr == NULL) { 309 dev_put(dev); 310 return -ENODEV; 311 } 312 313 if (dn_dev_set_default(dev, 1)) { 314 dev_put(dev); 315 return -ENODEV; 316 } 317 *ppos += *lenp; 318 319 return 0; 320 } 321 322 dev = dn_dev_get_default(); 323 if (dev == NULL) { 324 *lenp = 0; 325 return 0; 326 } 327 328 strcpy(devname, dev->name); 329 dev_put(dev); 330 len = strlen(devname); 331 devname[len++] = '\n'; 332 333 if (len > *lenp) len = *lenp; 334 335 if (copy_to_user(buffer, devname, len)) 336 return -EFAULT; 337 338 *lenp = len; 339 *ppos += len; 340 341 return 0; 342} 343 344static ctl_table dn_table[] = { 345 { 346 .ctl_name = NET_DECNET_NODE_ADDRESS, 347 .procname = "node_address", 348 .maxlen = 7, 349 .mode = 0644, 350 .proc_handler = dn_node_address_handler, 351 .strategy = dn_node_address_strategy, 352 }, 353 { 354 .ctl_name = NET_DECNET_NODE_NAME, 355 .procname = "node_name", 356 .data = node_name, 357 .maxlen = 7, 358 .mode = 0644, 359 .proc_handler = &proc_dostring, 360 .strategy = &sysctl_string, 361 }, 362 { 363 .ctl_name = NET_DECNET_DEFAULT_DEVICE, 364 .procname = "default_device", 365 .maxlen = 16, 366 .mode = 0644, 367 .proc_handler = dn_def_dev_handler, 368 .strategy = dn_def_dev_strategy, 369 }, 370 { 371 .ctl_name = NET_DECNET_TIME_WAIT, 372 .procname = "time_wait", 373 .data = &decnet_time_wait, 374 .maxlen = sizeof(int), 375 .mode = 0644, 376 .proc_handler = &proc_dointvec_minmax, 377 .strategy = &sysctl_intvec, 378 .extra1 = &min_decnet_time_wait, 379 .extra2 = &max_decnet_time_wait 380 }, 381 { 382 .ctl_name = NET_DECNET_DN_COUNT, 383 .procname = "dn_count", 384 .data = &decnet_dn_count, 385 .maxlen = sizeof(int), 386 .mode = 0644, 387 .proc_handler = &proc_dointvec_minmax, 388 .strategy = &sysctl_intvec, 389 .extra1 = &min_state_count, 390 .extra2 = &max_state_count 391 }, 392 { 393 .ctl_name = NET_DECNET_DI_COUNT, 394 .procname = "di_count", 395 .data = &decnet_di_count, 396 .maxlen = sizeof(int), 397 .mode = 0644, 398 .proc_handler = &proc_dointvec_minmax, 399 .strategy = &sysctl_intvec, 400 .extra1 = &min_state_count, 401 .extra2 = &max_state_count 402 }, 403 { 404 .ctl_name = NET_DECNET_DR_COUNT, 405 .procname = "dr_count", 406 .data = &decnet_dr_count, 407 .maxlen = sizeof(int), 408 .mode = 0644, 409 .proc_handler = &proc_dointvec_minmax, 410 .strategy = &sysctl_intvec, 411 .extra1 = &min_state_count, 412 .extra2 = &max_state_count 413 }, 414 { 415 .ctl_name = NET_DECNET_DST_GC_INTERVAL, 416 .procname = "dst_gc_interval", 417 .data = &decnet_dst_gc_interval, 418 .maxlen = sizeof(int), 419 .mode = 0644, 420 .proc_handler = &proc_dointvec_minmax, 421 .strategy = &sysctl_intvec, 422 .extra1 = &min_decnet_dst_gc_interval, 423 .extra2 = &max_decnet_dst_gc_interval 424 }, 425 { 426 .ctl_name = NET_DECNET_NO_FC_MAX_CWND, 427 .procname = "no_fc_max_cwnd", 428 .data = &decnet_no_fc_max_cwnd, 429 .maxlen = sizeof(int), 430 .mode = 0644, 431 .proc_handler = &proc_dointvec_minmax, 432 .strategy = &sysctl_intvec, 433 .extra1 = &min_decnet_no_fc_max_cwnd, 434 .extra2 = &max_decnet_no_fc_max_cwnd 435 }, 436 { 437 .ctl_name = NET_DECNET_MEM, 438 .procname = "decnet_mem", 439 .data = &sysctl_decnet_mem, 440 .maxlen = sizeof(sysctl_decnet_mem), 441 .mode = 0644, 442 .proc_handler = &proc_dointvec, 443 .strategy = &sysctl_intvec, 444 }, 445 { 446 .ctl_name = NET_DECNET_RMEM, 447 .procname = "decnet_rmem", 448 .data = &sysctl_decnet_rmem, 449 .maxlen = sizeof(sysctl_decnet_rmem), 450 .mode = 0644, 451 .proc_handler = &proc_dointvec, 452 .strategy = &sysctl_intvec, 453 }, 454 { 455 .ctl_name = NET_DECNET_WMEM, 456 .procname = "decnet_wmem", 457 .data = &sysctl_decnet_wmem, 458 .maxlen = sizeof(sysctl_decnet_wmem), 459 .mode = 0644, 460 .proc_handler = &proc_dointvec, 461 .strategy = &sysctl_intvec, 462 }, 463 { 464 .ctl_name = NET_DECNET_DEBUG_LEVEL, 465 .procname = "debug", 466 .data = &decnet_debug_level, 467 .maxlen = sizeof(int), 468 .mode = 0644, 469 .proc_handler = &proc_dointvec, 470 .strategy = &sysctl_intvec, 471 }, 472 {0} 473}; 474 475static ctl_table dn_dir_table[] = { 476 { 477 .ctl_name = NET_DECNET, 478 .procname = "decnet", 479 .mode = 0555, 480 .child = dn_table}, 481 {0} 482}; 483 484static ctl_table dn_root_table[] = { 485 { 486 .ctl_name = CTL_NET, 487 .procname = "net", 488 .mode = 0555, 489 .child = dn_dir_table 490 }, 491 {0} 492}; 493 494void dn_register_sysctl(void) 495{ 496 dn_table_header = register_sysctl_table(dn_root_table, 1); 497} 498 499void dn_unregister_sysctl(void) 500{ 501 unregister_sysctl_table(dn_table_header); 502} 503 504#else /* CONFIG_SYSCTL */ 505void dn_unregister_sysctl(void) 506{ 507} 508void dn_register_sysctl(void) 509{ 510} 511 512#endif