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.28-rc8 379 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{ 84 struct wan_device *wandev; 85 loff_t l = *pos; 86 87 lock_kernel(); 88 if (!l--) 89 return SEQ_START_TOKEN; 90 for (wandev = wanrouter_router_devlist; l-- && wandev; 91 wandev = wandev->next) 92 ; 93 return wandev; 94} 95 96static void *r_next(struct seq_file *m, void *v, loff_t *pos) 97{ 98 struct wan_device *wandev = v; 99 (*pos)++; 100 return (v == SEQ_START_TOKEN) ? wanrouter_router_devlist : wandev->next; 101} 102 103static void r_stop(struct seq_file *m, void *v) 104{ 105 unlock_kernel(); 106} 107 108static int config_show(struct seq_file *m, void *v) 109{ 110 struct wan_device *p = v; 111 if (v == SEQ_START_TOKEN) { 112 seq_puts(m, "Device name | port |IRQ|DMA| mem.addr |" 113 "mem.size|option1|option2|option3|option4\n"); 114 return 0; 115 } 116 if (!p->state) 117 return 0; 118 seq_printf(m, "%-15s|0x%-4X|%3u|%3u| 0x%-8lX |0x%-6X|%7u|%7u|%7u|%7u\n", 119 p->name, p->ioport, p->irq, p->dma, p->maddr, p->msize, 120 p->hw_opt[0], p->hw_opt[1], p->hw_opt[2], p->hw_opt[3]); 121 return 0; 122} 123 124static int status_show(struct seq_file *m, void *v) 125{ 126 struct wan_device *p = v; 127 if (v == SEQ_START_TOKEN) { 128 seq_puts(m, "Device name |protocol|station|interface|" 129 "clocking|baud rate| MTU |ndev|link state\n"); 130 return 0; 131 } 132 if (!p->state) 133 return 0; 134 seq_printf(m, "%-15s|%-8s| %-7s| %-9s|%-8s|%9u|%5u|%3u |", 135 p->name, 136 PROT_DECODE(p->config_id), 137 p->config_id == WANCONFIG_FR ? 138 (p->station ? "Node" : "CPE") : 139 (p->config_id == WANCONFIG_X25 ? 140 (p->station ? "DCE" : "DTE") : 141 ("N/A")), 142 p->interface ? "V.35" : "RS-232", 143 p->clocking ? "internal" : "external", 144 p->bps, 145 p->mtu, 146 p->ndev); 147 148 switch (p->state) { 149 case WAN_UNCONFIGURED: 150 seq_printf(m, "%-12s\n", "unconfigured"); 151 break; 152 case WAN_DISCONNECTED: 153 seq_printf(m, "%-12s\n", "disconnected"); 154 break; 155 case WAN_CONNECTING: 156 seq_printf(m, "%-12s\n", "connecting"); 157 break; 158 case WAN_CONNECTED: 159 seq_printf(m, "%-12s\n", "connected"); 160 break; 161 default: 162 seq_printf(m, "%-12s\n", "invalid"); 163 break; 164 } 165 return 0; 166} 167 168static const struct seq_operations config_op = { 169 .start = r_start, 170 .next = r_next, 171 .stop = r_stop, 172 .show = config_show, 173}; 174 175static const struct seq_operations status_op = { 176 .start = r_start, 177 .next = r_next, 178 .stop = r_stop, 179 .show = status_show, 180}; 181 182static int config_open(struct inode *inode, struct file *file) 183{ 184 return seq_open(file, &config_op); 185} 186 187static int status_open(struct inode *inode, struct file *file) 188{ 189 return seq_open(file, &status_op); 190} 191 192static const struct file_operations config_fops = { 193 .owner = THIS_MODULE, 194 .open = config_open, 195 .read = seq_read, 196 .llseek = seq_lseek, 197 .release = seq_release, 198}; 199 200static const struct file_operations status_fops = { 201 .owner = THIS_MODULE, 202 .open = status_open, 203 .read = seq_read, 204 .llseek = seq_lseek, 205 .release = seq_release, 206}; 207 208static int wandev_show(struct seq_file *m, void *v) 209{ 210 struct wan_device *wandev = m->private; 211 212 if (wandev->magic != ROUTER_MAGIC) 213 return 0; 214 215 if (!wandev->state) { 216 seq_puts(m, "device is not configured!\n"); 217 return 0; 218 } 219 220 /* Update device statistics */ 221 if (wandev->update) { 222 int err = wandev->update(wandev); 223 if (err == -EAGAIN) { 224 seq_puts(m, "Device is busy!\n"); 225 return 0; 226 } 227 if (err) { 228 seq_puts(m, "Device is not configured!\n"); 229 return 0; 230 } 231 } 232 233 seq_printf(m, PROC_STATS_FORMAT, 234 "total packets received", wandev->stats.rx_packets); 235 seq_printf(m, PROC_STATS_FORMAT, 236 "total packets transmitted", wandev->stats.tx_packets); 237 seq_printf(m, PROC_STATS_FORMAT, 238 "total bytes received", wandev->stats.rx_bytes); 239 seq_printf(m, PROC_STATS_FORMAT, 240 "total bytes transmitted", wandev->stats.tx_bytes); 241 seq_printf(m, PROC_STATS_FORMAT, 242 "bad packets received", wandev->stats.rx_errors); 243 seq_printf(m, PROC_STATS_FORMAT, 244 "packet transmit problems", wandev->stats.tx_errors); 245 seq_printf(m, PROC_STATS_FORMAT, 246 "received frames dropped", wandev->stats.rx_dropped); 247 seq_printf(m, PROC_STATS_FORMAT, 248 "transmit frames dropped", wandev->stats.tx_dropped); 249 seq_printf(m, PROC_STATS_FORMAT, 250 "multicast packets received", wandev->stats.multicast); 251 seq_printf(m, PROC_STATS_FORMAT, 252 "transmit collisions", wandev->stats.collisions); 253 seq_printf(m, PROC_STATS_FORMAT, 254 "receive length errors", wandev->stats.rx_length_errors); 255 seq_printf(m, PROC_STATS_FORMAT, 256 "receiver overrun errors", wandev->stats.rx_over_errors); 257 seq_printf(m, PROC_STATS_FORMAT, 258 "CRC errors", wandev->stats.rx_crc_errors); 259 seq_printf(m, PROC_STATS_FORMAT, 260 "frame format errors (aborts)", wandev->stats.rx_frame_errors); 261 seq_printf(m, PROC_STATS_FORMAT, 262 "receiver fifo overrun", wandev->stats.rx_fifo_errors); 263 seq_printf(m, PROC_STATS_FORMAT, 264 "receiver missed packet", wandev->stats.rx_missed_errors); 265 seq_printf(m, PROC_STATS_FORMAT, 266 "aborted frames transmitted", wandev->stats.tx_aborted_errors); 267 return 0; 268} 269 270static int wandev_open(struct inode *inode, struct file *file) 271{ 272 return single_open(file, wandev_show, PDE(inode)->data); 273} 274 275static const struct file_operations wandev_fops = { 276 .owner = THIS_MODULE, 277 .open = wandev_open, 278 .read = seq_read, 279 .llseek = seq_lseek, 280 .release = single_release, 281 .unlocked_ioctl = wanrouter_ioctl, 282}; 283 284/* 285 * Initialize router proc interface. 286 */ 287 288int __init wanrouter_proc_init(void) 289{ 290 struct proc_dir_entry *p; 291 proc_router = proc_mkdir(ROUTER_NAME, init_net.proc_net); 292 if (!proc_router) 293 goto fail; 294 295 p = proc_create("config", S_IRUGO, proc_router, &config_fops); 296 if (!p) 297 goto fail_config; 298 p = proc_create("status", S_IRUGO, proc_router, &status_fops); 299 if (!p) 300 goto fail_stat; 301 return 0; 302fail_stat: 303 remove_proc_entry("config", proc_router); 304fail_config: 305 remove_proc_entry(ROUTER_NAME, init_net.proc_net); 306fail: 307 return -ENOMEM; 308} 309 310/* 311 * Clean up router proc interface. 312 */ 313 314void wanrouter_proc_cleanup(void) 315{ 316 remove_proc_entry("config", proc_router); 317 remove_proc_entry("status", proc_router); 318 remove_proc_entry(ROUTER_NAME, init_net.proc_net); 319} 320 321/* 322 * Add directory entry for WAN device. 323 */ 324 325int wanrouter_proc_add(struct wan_device* wandev) 326{ 327 if (wandev->magic != ROUTER_MAGIC) 328 return -EINVAL; 329 330 wandev->dent = proc_create(wandev->name, S_IRUGO, 331 proc_router, &wandev_fops); 332 if (!wandev->dent) 333 return -ENOMEM; 334 wandev->dent->data = wandev; 335 return 0; 336} 337 338/* 339 * Delete directory entry for WAN device. 340 */ 341int wanrouter_proc_delete(struct wan_device* wandev) 342{ 343 if (wandev->magic != ROUTER_MAGIC) 344 return -EINVAL; 345 remove_proc_entry(wandev->name, proc_router); 346 return 0; 347} 348 349#else 350 351/* 352 * No /proc - output stubs 353 */ 354 355int __init wanrouter_proc_init(void) 356{ 357 return 0; 358} 359 360void wanrouter_proc_cleanup(void) 361{ 362} 363 364int wanrouter_proc_add(struct wan_device *wandev) 365{ 366 return 0; 367} 368 369int wanrouter_proc_delete(struct wan_device *wandev) 370{ 371 return 0; 372} 373 374#endif 375 376/* 377 * End 378 */ 379