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.33-rc8 381 lines 9.3 kB view raw
1/***************************************************************************** 2* wanproc.c WAN Router Module. /proc filesystem interface. 3* 4* This module is completely hardware-independent and provides 5* access to the router using Linux /proc filesystem. 6* 7* Author: Gideon Hack 8* 9* Copyright: (c) 1995-1999 Sangoma Technologies Inc. 10* 11* This program is free software; you can redistribute it and/or 12* modify it under the terms of the GNU General Public License 13* as published by the Free Software Foundation; either version 14* 2 of the License, or (at your option) any later version. 15* ============================================================================ 16* Jun 02, 1999 Gideon Hack Updates for Linux 2.2.X kernels. 17* Jun 29, 1997 Alan Cox Merged with 1.0.3 vendor code 18* Jan 29, 1997 Gene Kozin v1.0.1. Implemented /proc read routines 19* Jan 30, 1997 Alan Cox Hacked around for 2.1 20* Dec 13, 1996 Gene Kozin Initial version (based on Sangoma's WANPIPE) 21*****************************************************************************/ 22 23#include <linux/init.h> /* __initfunc et al. */ 24#include <linux/stddef.h> /* offsetof(), etc. */ 25#include <linux/errno.h> /* return codes */ 26#include <linux/kernel.h> 27#include <linux/module.h> 28#include <linux/wanrouter.h> /* WAN router API definitions */ 29#include <linux/seq_file.h> 30#include <linux/smp_lock.h> 31 32#include <net/net_namespace.h> 33#include <asm/io.h> 34 35#define PROC_STATS_FORMAT "%30s: %12lu\n" 36 37/****** Defines and Macros **************************************************/ 38 39#define PROT_DECODE(prot) ((prot == WANCONFIG_FR) ? " FR" :\ 40 (prot == WANCONFIG_X25) ? " X25" : \ 41 (prot == WANCONFIG_PPP) ? " PPP" : \ 42 (prot == WANCONFIG_CHDLC) ? " CHDLC": \ 43 (prot == WANCONFIG_MPPP) ? " MPPP" : \ 44 " Unknown" ) 45 46/****** Function Prototypes *************************************************/ 47 48#ifdef CONFIG_PROC_FS 49 50/* Miscellaneous */ 51 52/* 53 * Structures for interfacing with the /proc filesystem. 54 * Router creates its own directory /proc/net/router with the folowing 55 * entries: 56 * config device configuration 57 * status global device statistics 58 * <device> entry for each WAN device 59 */ 60 61/* 62 * Generic /proc/net/router/<file> file and inode operations 63 */ 64 65/* 66 * /proc/net/router 67 */ 68 69static struct proc_dir_entry *proc_router; 70 71/* Strings */ 72 73/* 74 * Interface functions 75 */ 76 77/****** Proc filesystem entry points ****************************************/ 78 79/* 80 * Iterator 81 */ 82static void *r_start(struct seq_file *m, loff_t *pos) 83 __acquires(kernel_lock) 84{ 85 struct wan_device *wandev; 86 loff_t l = *pos; 87 88 lock_kernel(); 89 if (!l--) 90 return SEQ_START_TOKEN; 91 for (wandev = wanrouter_router_devlist; l-- && wandev; 92 wandev = wandev->next) 93 ; 94 return wandev; 95} 96 97static void *r_next(struct seq_file *m, void *v, loff_t *pos) 98{ 99 struct wan_device *wandev = v; 100 (*pos)++; 101 return (v == SEQ_START_TOKEN) ? wanrouter_router_devlist : wandev->next; 102} 103 104static void r_stop(struct seq_file *m, void *v) 105 __releases(kernel_lock) 106{ 107 unlock_kernel(); 108} 109 110static int config_show(struct seq_file *m, void *v) 111{ 112 struct wan_device *p = v; 113 if (v == SEQ_START_TOKEN) { 114 seq_puts(m, "Device name | port |IRQ|DMA| mem.addr |" 115 "mem.size|option1|option2|option3|option4\n"); 116 return 0; 117 } 118 if (!p->state) 119 return 0; 120 seq_printf(m, "%-15s|0x%-4X|%3u|%3u| 0x%-8lX |0x%-6X|%7u|%7u|%7u|%7u\n", 121 p->name, p->ioport, p->irq, p->dma, p->maddr, p->msize, 122 p->hw_opt[0], p->hw_opt[1], p->hw_opt[2], p->hw_opt[3]); 123 return 0; 124} 125 126static int status_show(struct seq_file *m, void *v) 127{ 128 struct wan_device *p = v; 129 if (v == SEQ_START_TOKEN) { 130 seq_puts(m, "Device name |protocol|station|interface|" 131 "clocking|baud rate| MTU |ndev|link state\n"); 132 return 0; 133 } 134 if (!p->state) 135 return 0; 136 seq_printf(m, "%-15s|%-8s| %-7s| %-9s|%-8s|%9u|%5u|%3u |", 137 p->name, 138 PROT_DECODE(p->config_id), 139 p->config_id == WANCONFIG_FR ? 140 (p->station ? "Node" : "CPE") : 141 (p->config_id == WANCONFIG_X25 ? 142 (p->station ? "DCE" : "DTE") : 143 ("N/A")), 144 p->interface ? "V.35" : "RS-232", 145 p->clocking ? "internal" : "external", 146 p->bps, 147 p->mtu, 148 p->ndev); 149 150 switch (p->state) { 151 case WAN_UNCONFIGURED: 152 seq_printf(m, "%-12s\n", "unconfigured"); 153 break; 154 case WAN_DISCONNECTED: 155 seq_printf(m, "%-12s\n", "disconnected"); 156 break; 157 case WAN_CONNECTING: 158 seq_printf(m, "%-12s\n", "connecting"); 159 break; 160 case WAN_CONNECTED: 161 seq_printf(m, "%-12s\n", "connected"); 162 break; 163 default: 164 seq_printf(m, "%-12s\n", "invalid"); 165 break; 166 } 167 return 0; 168} 169 170static const struct seq_operations config_op = { 171 .start = r_start, 172 .next = r_next, 173 .stop = r_stop, 174 .show = config_show, 175}; 176 177static const struct seq_operations status_op = { 178 .start = r_start, 179 .next = r_next, 180 .stop = r_stop, 181 .show = status_show, 182}; 183 184static int config_open(struct inode *inode, struct file *file) 185{ 186 return seq_open(file, &config_op); 187} 188 189static int status_open(struct inode *inode, struct file *file) 190{ 191 return seq_open(file, &status_op); 192} 193 194static const struct file_operations config_fops = { 195 .owner = THIS_MODULE, 196 .open = config_open, 197 .read = seq_read, 198 .llseek = seq_lseek, 199 .release = seq_release, 200}; 201 202static const struct file_operations status_fops = { 203 .owner = THIS_MODULE, 204 .open = status_open, 205 .read = seq_read, 206 .llseek = seq_lseek, 207 .release = seq_release, 208}; 209 210static int wandev_show(struct seq_file *m, void *v) 211{ 212 struct wan_device *wandev = m->private; 213 214 if (wandev->magic != ROUTER_MAGIC) 215 return 0; 216 217 if (!wandev->state) { 218 seq_puts(m, "device is not configured!\n"); 219 return 0; 220 } 221 222 /* Update device statistics */ 223 if (wandev->update) { 224 int err = wandev->update(wandev); 225 if (err == -EAGAIN) { 226 seq_puts(m, "Device is busy!\n"); 227 return 0; 228 } 229 if (err) { 230 seq_puts(m, "Device is not configured!\n"); 231 return 0; 232 } 233 } 234 235 seq_printf(m, PROC_STATS_FORMAT, 236 "total packets received", wandev->stats.rx_packets); 237 seq_printf(m, PROC_STATS_FORMAT, 238 "total packets transmitted", wandev->stats.tx_packets); 239 seq_printf(m, PROC_STATS_FORMAT, 240 "total bytes received", wandev->stats.rx_bytes); 241 seq_printf(m, PROC_STATS_FORMAT, 242 "total bytes transmitted", wandev->stats.tx_bytes); 243 seq_printf(m, PROC_STATS_FORMAT, 244 "bad packets received", wandev->stats.rx_errors); 245 seq_printf(m, PROC_STATS_FORMAT, 246 "packet transmit problems", wandev->stats.tx_errors); 247 seq_printf(m, PROC_STATS_FORMAT, 248 "received frames dropped", wandev->stats.rx_dropped); 249 seq_printf(m, PROC_STATS_FORMAT, 250 "transmit frames dropped", wandev->stats.tx_dropped); 251 seq_printf(m, PROC_STATS_FORMAT, 252 "multicast packets received", wandev->stats.multicast); 253 seq_printf(m, PROC_STATS_FORMAT, 254 "transmit collisions", wandev->stats.collisions); 255 seq_printf(m, PROC_STATS_FORMAT, 256 "receive length errors", wandev->stats.rx_length_errors); 257 seq_printf(m, PROC_STATS_FORMAT, 258 "receiver overrun errors", wandev->stats.rx_over_errors); 259 seq_printf(m, PROC_STATS_FORMAT, 260 "CRC errors", wandev->stats.rx_crc_errors); 261 seq_printf(m, PROC_STATS_FORMAT, 262 "frame format errors (aborts)", wandev->stats.rx_frame_errors); 263 seq_printf(m, PROC_STATS_FORMAT, 264 "receiver fifo overrun", wandev->stats.rx_fifo_errors); 265 seq_printf(m, PROC_STATS_FORMAT, 266 "receiver missed packet", wandev->stats.rx_missed_errors); 267 seq_printf(m, PROC_STATS_FORMAT, 268 "aborted frames transmitted", wandev->stats.tx_aborted_errors); 269 return 0; 270} 271 272static int wandev_open(struct inode *inode, struct file *file) 273{ 274 return single_open(file, wandev_show, PDE(inode)->data); 275} 276 277static const struct file_operations wandev_fops = { 278 .owner = THIS_MODULE, 279 .open = wandev_open, 280 .read = seq_read, 281 .llseek = seq_lseek, 282 .release = single_release, 283 .unlocked_ioctl = wanrouter_ioctl, 284}; 285 286/* 287 * Initialize router proc interface. 288 */ 289 290int __init wanrouter_proc_init(void) 291{ 292 struct proc_dir_entry *p; 293 proc_router = proc_mkdir(ROUTER_NAME, init_net.proc_net); 294 if (!proc_router) 295 goto fail; 296 297 p = proc_create("config", S_IRUGO, proc_router, &config_fops); 298 if (!p) 299 goto fail_config; 300 p = proc_create("status", S_IRUGO, proc_router, &status_fops); 301 if (!p) 302 goto fail_stat; 303 return 0; 304fail_stat: 305 remove_proc_entry("config", proc_router); 306fail_config: 307 remove_proc_entry(ROUTER_NAME, init_net.proc_net); 308fail: 309 return -ENOMEM; 310} 311 312/* 313 * Clean up router proc interface. 314 */ 315 316void wanrouter_proc_cleanup(void) 317{ 318 remove_proc_entry("config", proc_router); 319 remove_proc_entry("status", proc_router); 320 remove_proc_entry(ROUTER_NAME, init_net.proc_net); 321} 322 323/* 324 * Add directory entry for WAN device. 325 */ 326 327int wanrouter_proc_add(struct wan_device* wandev) 328{ 329 if (wandev->magic != ROUTER_MAGIC) 330 return -EINVAL; 331 332 wandev->dent = proc_create(wandev->name, S_IRUGO, 333 proc_router, &wandev_fops); 334 if (!wandev->dent) 335 return -ENOMEM; 336 wandev->dent->data = wandev; 337 return 0; 338} 339 340/* 341 * Delete directory entry for WAN device. 342 */ 343int wanrouter_proc_delete(struct wan_device* wandev) 344{ 345 if (wandev->magic != ROUTER_MAGIC) 346 return -EINVAL; 347 remove_proc_entry(wandev->name, proc_router); 348 return 0; 349} 350 351#else 352 353/* 354 * No /proc - output stubs 355 */ 356 357int __init wanrouter_proc_init(void) 358{ 359 return 0; 360} 361 362void wanrouter_proc_cleanup(void) 363{ 364} 365 366int wanrouter_proc_add(struct wan_device *wandev) 367{ 368 return 0; 369} 370 371int wanrouter_proc_delete(struct wan_device *wandev) 372{ 373 return 0; 374} 375 376#endif 377 378/* 379 * End 380 */ 381