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.16-rc5 885 lines 23 kB view raw
1/***************************************************************************** 2* wanmain.c WAN Multiprotocol Router Module. Main code. 3* 4* This module is completely hardware-independent and provides 5* the following common services for the WAN Link Drivers: 6* o WAN device managenment (registering, unregistering) 7* o Network interface management 8* o Physical connection management (dial-up, incoming calls) 9* o Logical connection management (switched virtual circuits) 10* o Protocol encapsulation/decapsulation 11* 12* Author: Gideon Hack 13* 14* Copyright: (c) 1995-1999 Sangoma Technologies Inc. 15* 16* This program is free software; you can redistribute it and/or 17* modify it under the terms of the GNU General Public License 18* as published by the Free Software Foundation; either version 19* 2 of the License, or (at your option) any later version. 20* ============================================================================ 21* Nov 24, 2000 Nenad Corbic Updated for 2.4.X kernels 22* Nov 07, 2000 Nenad Corbic Fixed the Mulit-Port PPP for kernels 2.2.16 and 23* greater. 24* Aug 2, 2000 Nenad Corbic Block the Multi-Port PPP from running on 25* kernels 2.2.16 or greater. The SyncPPP 26* has changed. 27* Jul 13, 2000 Nenad Corbic Added SyncPPP support 28* Added extra debugging in device_setup(). 29* Oct 01, 1999 Gideon Hack Update for s514 PCI card 30* Dec 27, 1996 Gene Kozin Initial version (based on Sangoma's WANPIPE) 31* Jan 16, 1997 Gene Kozin router_devlist made public 32* Jan 31, 1997 Alan Cox Hacked it about a bit for 2.1 33* Jun 27, 1997 Alan Cox realigned with vendor code 34* Oct 15, 1997 Farhan Thawar changed wan_encapsulate to add a pad byte of 0 35* Apr 20, 1998 Alan Cox Fixed 2.1 symbols 36* May 17, 1998 K. Baranowski Fixed SNAP encapsulation in wan_encapsulate 37* Dec 15, 1998 Arnaldo Melo support for firmwares of up to 128000 bytes 38* check wandev->setup return value 39* Dec 22, 1998 Arnaldo Melo vmalloc/vfree used in device_setup to allocate 40* kernel memory and copy configuration data to 41* kernel space (for big firmwares) 42* Jun 02, 1999 Gideon Hack Updates for Linux 2.0.X and 2.2.X kernels. 43*****************************************************************************/ 44 45#include <linux/config.h> 46#include <linux/stddef.h> /* offsetof(), etc. */ 47#include <linux/capability.h> 48#include <linux/errno.h> /* return codes */ 49#include <linux/kernel.h> 50#include <linux/init.h> 51#include <linux/module.h> /* support for loadable modules */ 52#include <linux/slab.h> /* kmalloc(), kfree() */ 53#include <linux/mm.h> 54#include <linux/string.h> /* inline mem*, str* functions */ 55 56#include <asm/byteorder.h> /* htons(), etc. */ 57#include <linux/wanrouter.h> /* WAN router API definitions */ 58 59#include <linux/vmalloc.h> /* vmalloc, vfree */ 60#include <asm/uaccess.h> /* copy_to/from_user */ 61#include <linux/init.h> /* __initfunc et al. */ 62#include <net/syncppp.h> 63 64#define KMEM_SAFETYZONE 8 65 66/***********FOR DEBUGGING PURPOSES********************************************* 67static void * dbg_kmalloc(unsigned int size, int prio, int line) { 68 int i = 0; 69 void * v = kmalloc(size+sizeof(unsigned int)+2*KMEM_SAFETYZONE*8,prio); 70 char * c1 = v; 71 c1 += sizeof(unsigned int); 72 *((unsigned int *)v) = size; 73 74 for (i = 0; i < KMEM_SAFETYZONE; i++) { 75 c1[0] = 'D'; c1[1] = 'E'; c1[2] = 'A'; c1[3] = 'D'; 76 c1[4] = 'B'; c1[5] = 'E'; c1[6] = 'E'; c1[7] = 'F'; 77 c1 += 8; 78 } 79 c1 += size; 80 for (i = 0; i < KMEM_SAFETYZONE; i++) { 81 c1[0] = 'M'; c1[1] = 'U'; c1[2] = 'N'; c1[3] = 'G'; 82 c1[4] = 'W'; c1[5] = 'A'; c1[6] = 'L'; c1[7] = 'L'; 83 c1 += 8; 84 } 85 v = ((char *)v) + sizeof(unsigned int) + KMEM_SAFETYZONE*8; 86 printk(KERN_INFO "line %d kmalloc(%d,%d) = %p\n",line,size,prio,v); 87 return v; 88} 89static void dbg_kfree(void * v, int line) { 90 unsigned int * sp = (unsigned int *)(((char *)v) - (sizeof(unsigned int) + KMEM_SAFETYZONE*8)); 91 unsigned int size = *sp; 92 char * c1 = ((char *)v) - KMEM_SAFETYZONE*8; 93 int i = 0; 94 for (i = 0; i < KMEM_SAFETYZONE; i++) { 95 if ( c1[0] != 'D' || c1[1] != 'E' || c1[2] != 'A' || c1[3] != 'D' 96 || c1[4] != 'B' || c1[5] != 'E' || c1[6] != 'E' || c1[7] != 'F') { 97 printk(KERN_INFO "kmalloced block at %p has been corrupted (underrun)!\n",v); 98 printk(KERN_INFO " %4x: %2x %2x %2x %2x %2x %2x %2x %2x\n", i*8, 99 c1[0],c1[1],c1[2],c1[3],c1[4],c1[5],c1[6],c1[7] ); 100 } 101 c1 += 8; 102 } 103 c1 += size; 104 for (i = 0; i < KMEM_SAFETYZONE; i++) { 105 if ( c1[0] != 'M' || c1[1] != 'U' || c1[2] != 'N' || c1[3] != 'G' 106 || c1[4] != 'W' || c1[5] != 'A' || c1[6] != 'L' || c1[7] != 'L' 107 ) { 108 printk(KERN_INFO "kmalloced block at %p has been corrupted (overrun):\n",v); 109 printk(KERN_INFO " %4x: %2x %2x %2x %2x %2x %2x %2x %2x\n", i*8, 110 c1[0],c1[1],c1[2],c1[3],c1[4],c1[5],c1[6],c1[7] ); 111 } 112 c1 += 8; 113 } 114 printk(KERN_INFO "line %d kfree(%p)\n",line,v); 115 v = ((char *)v) - (sizeof(unsigned int) + KMEM_SAFETYZONE*8); 116 kfree(v); 117} 118 119#define kmalloc(x,y) dbg_kmalloc(x,y,__LINE__) 120#define kfree(x) dbg_kfree(x,__LINE__) 121*****************************************************************************/ 122 123/* 124 * Function Prototypes 125 */ 126 127/* 128 * WAN device IOCTL handlers 129 */ 130 131static int wanrouter_device_setup(struct wan_device *wandev, 132 wandev_conf_t __user *u_conf); 133static int wanrouter_device_stat(struct wan_device *wandev, 134 wandev_stat_t __user *u_stat); 135static int wanrouter_device_shutdown(struct wan_device *wandev); 136static int wanrouter_device_new_if(struct wan_device *wandev, 137 wanif_conf_t __user *u_conf); 138static int wanrouter_device_del_if(struct wan_device *wandev, 139 char __user *u_name); 140 141/* 142 * Miscellaneous 143 */ 144 145static struct wan_device *wanrouter_find_device(char *name); 146static int wanrouter_delete_interface(struct wan_device *wandev, char *name); 147void lock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags); 148void unlock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags); 149 150 151 152/* 153 * Global Data 154 */ 155 156static char wanrouter_fullname[] = "Sangoma WANPIPE Router"; 157static char wanrouter_copyright[] = "(c) 1995-2000 Sangoma Technologies Inc."; 158static char wanrouter_modname[] = ROUTER_NAME; /* short module name */ 159struct wan_device* wanrouter_router_devlist; /* list of registered devices */ 160 161/* 162 * Organize Unique Identifiers for encapsulation/decapsulation 163 */ 164 165static unsigned char wanrouter_oui_ether[] = { 0x00, 0x00, 0x00 }; 166#if 0 167static unsigned char wanrouter_oui_802_2[] = { 0x00, 0x80, 0xC2 }; 168#endif 169 170static int __init wanrouter_init(void) 171{ 172 int err; 173 174 printk(KERN_INFO "%s v%u.%u %s\n", 175 wanrouter_fullname, ROUTER_VERSION, ROUTER_RELEASE, 176 wanrouter_copyright); 177 178 err = wanrouter_proc_init(); 179 if (err) 180 printk(KERN_INFO "%s: can't create entry in proc filesystem!\n", 181 wanrouter_modname); 182 183 return err; 184} 185 186static void __exit wanrouter_cleanup (void) 187{ 188 wanrouter_proc_cleanup(); 189} 190 191/* 192 * This is just plain dumb. We should move the bugger to drivers/net/wan, 193 * slap it first in directory and make it module_init(). The only reason 194 * for subsys_initcall() here is that net goes after drivers (why, BTW?) 195 */ 196subsys_initcall(wanrouter_init); 197module_exit(wanrouter_cleanup); 198 199/* 200 * Kernel APIs 201 */ 202 203/* 204 * Register WAN device. 205 * o verify device credentials 206 * o create an entry for the device in the /proc/net/router directory 207 * o initialize internally maintained fields of the wan_device structure 208 * o link device data space to a singly-linked list 209 * o if it's the first device, then start kernel 'thread' 210 * o increment module use count 211 * 212 * Return: 213 * 0 Ok 214 * < 0 error. 215 * 216 * Context: process 217 */ 218 219 220int register_wan_device(struct wan_device *wandev) 221{ 222 int err, namelen; 223 224 if ((wandev == NULL) || (wandev->magic != ROUTER_MAGIC) || 225 (wandev->name == NULL)) 226 return -EINVAL; 227 228 namelen = strlen(wandev->name); 229 if (!namelen || (namelen > WAN_DRVNAME_SZ)) 230 return -EINVAL; 231 232 if (wanrouter_find_device(wandev->name)) 233 return -EEXIST; 234 235#ifdef WANDEBUG 236 printk(KERN_INFO "%s: registering WAN device %s\n", 237 wanrouter_modname, wandev->name); 238#endif 239 240 /* 241 * Register /proc directory entry 242 */ 243 err = wanrouter_proc_add(wandev); 244 if (err) { 245 printk(KERN_INFO 246 "%s: can't create /proc/net/router/%s entry!\n", 247 wanrouter_modname, wandev->name); 248 return err; 249 } 250 251 /* 252 * Initialize fields of the wan_device structure maintained by the 253 * router and update local data. 254 */ 255 256 wandev->ndev = 0; 257 wandev->dev = NULL; 258 wandev->next = wanrouter_router_devlist; 259 wanrouter_router_devlist = wandev; 260 return 0; 261} 262 263/* 264 * Unregister WAN device. 265 * o shut down device 266 * o unlink device data space from the linked list 267 * o delete device entry in the /proc/net/router directory 268 * o decrement module use count 269 * 270 * Return: 0 Ok 271 * <0 error. 272 * Context: process 273 */ 274 275 276int unregister_wan_device(char *name) 277{ 278 struct wan_device *wandev, *prev; 279 280 if (name == NULL) 281 return -EINVAL; 282 283 for (wandev = wanrouter_router_devlist, prev = NULL; 284 wandev && strcmp(wandev->name, name); 285 prev = wandev, wandev = wandev->next) 286 ; 287 if (wandev == NULL) 288 return -ENODEV; 289 290#ifdef WANDEBUG 291 printk(KERN_INFO "%s: unregistering WAN device %s\n", 292 wanrouter_modname, name); 293#endif 294 295 if (wandev->state != WAN_UNCONFIGURED) 296 wanrouter_device_shutdown(wandev); 297 298 if (prev) 299 prev->next = wandev->next; 300 else 301 wanrouter_router_devlist = wandev->next; 302 303 wanrouter_proc_delete(wandev); 304 return 0; 305} 306 307/* 308 * Encapsulate packet. 309 * 310 * Return: encapsulation header size 311 * < 0 - unsupported Ethertype 312 * 313 * Notes: 314 * 1. This function may be called on interrupt context. 315 */ 316 317 318int wanrouter_encapsulate(struct sk_buff *skb, struct net_device *dev, 319 unsigned short type) 320{ 321 int hdr_len = 0; 322 323 switch (type) { 324 case ETH_P_IP: /* IP datagram encapsulation */ 325 hdr_len += 1; 326 skb_push(skb, 1); 327 skb->data[0] = NLPID_IP; 328 break; 329 330 case ETH_P_IPX: /* SNAP encapsulation */ 331 case ETH_P_ARP: 332 hdr_len += 7; 333 skb_push(skb, 7); 334 skb->data[0] = 0; 335 skb->data[1] = NLPID_SNAP; 336 memcpy(&skb->data[2], wanrouter_oui_ether, 337 sizeof(wanrouter_oui_ether)); 338 *((unsigned short*)&skb->data[5]) = htons(type); 339 break; 340 341 default: /* Unknown packet type */ 342 printk(KERN_INFO 343 "%s: unsupported Ethertype 0x%04X on interface %s!\n", 344 wanrouter_modname, type, dev->name); 345 hdr_len = -EINVAL; 346 } 347 return hdr_len; 348} 349 350 351/* 352 * Decapsulate packet. 353 * 354 * Return: Ethertype (in network order) 355 * 0 unknown encapsulation 356 * 357 * Notes: 358 * 1. This function may be called on interrupt context. 359 */ 360 361 362__be16 wanrouter_type_trans(struct sk_buff *skb, struct net_device *dev) 363{ 364 int cnt = skb->data[0] ? 0 : 1; /* there may be a pad present */ 365 __be16 ethertype; 366 367 switch (skb->data[cnt]) { 368 case NLPID_IP: /* IP datagramm */ 369 ethertype = htons(ETH_P_IP); 370 cnt += 1; 371 break; 372 373 case NLPID_SNAP: /* SNAP encapsulation */ 374 if (memcmp(&skb->data[cnt + 1], wanrouter_oui_ether, 375 sizeof(wanrouter_oui_ether))){ 376 printk(KERN_INFO 377 "%s: unsupported SNAP OUI %02X-%02X-%02X " 378 "on interface %s!\n", wanrouter_modname, 379 skb->data[cnt+1], skb->data[cnt+2], 380 skb->data[cnt+3], dev->name); 381 return 0; 382 } 383 ethertype = *((__be16*)&skb->data[cnt+4]); 384 cnt += 6; 385 break; 386 387 /* add other protocols, e.g. CLNP, ESIS, ISIS, if needed */ 388 389 default: 390 printk(KERN_INFO 391 "%s: unsupported NLPID 0x%02X on interface %s!\n", 392 wanrouter_modname, skb->data[cnt], dev->name); 393 return 0; 394 } 395 skb->protocol = ethertype; 396 skb->pkt_type = PACKET_HOST; /* Physically point to point */ 397 skb_pull(skb, cnt); 398 skb->mac.raw = skb->data; 399 return ethertype; 400} 401 402 403/* 404 * WAN device IOCTL. 405 * o find WAN device associated with this node 406 * o execute requested action or pass command to the device driver 407 */ 408 409int wanrouter_ioctl(struct inode *inode, struct file *file, 410 unsigned int cmd, unsigned long arg) 411{ 412 int err = 0; 413 struct proc_dir_entry *dent; 414 struct wan_device *wandev; 415 void __user *data = (void __user *)arg; 416 417 if (!capable(CAP_NET_ADMIN)) 418 return -EPERM; 419 420 if ((cmd >> 8) != ROUTER_IOCTL) 421 return -EINVAL; 422 423 dent = PDE(inode); 424 if ((dent == NULL) || (dent->data == NULL)) 425 return -EINVAL; 426 427 wandev = dent->data; 428 if (wandev->magic != ROUTER_MAGIC) 429 return -EINVAL; 430 431 switch (cmd) { 432 case ROUTER_SETUP: 433 err = wanrouter_device_setup(wandev, data); 434 break; 435 436 case ROUTER_DOWN: 437 err = wanrouter_device_shutdown(wandev); 438 break; 439 440 case ROUTER_STAT: 441 err = wanrouter_device_stat(wandev, data); 442 break; 443 444 case ROUTER_IFNEW: 445 err = wanrouter_device_new_if(wandev, data); 446 break; 447 448 case ROUTER_IFDEL: 449 err = wanrouter_device_del_if(wandev, data); 450 break; 451 452 case ROUTER_IFSTAT: 453 break; 454 455 default: 456 if ((cmd >= ROUTER_USER) && 457 (cmd <= ROUTER_USER_MAX) && 458 wandev->ioctl) 459 err = wandev->ioctl(wandev, cmd, arg); 460 else err = -EINVAL; 461 } 462 return err; 463} 464 465/* 466 * WAN Driver IOCTL Handlers 467 */ 468 469/* 470 * Setup WAN link device. 471 * o verify user address space 472 * o allocate kernel memory and copy configuration data to kernel space 473 * o if configuration data includes extension, copy it to kernel space too 474 * o call driver's setup() entry point 475 */ 476 477static int wanrouter_device_setup(struct wan_device *wandev, 478 wandev_conf_t __user *u_conf) 479{ 480 void *data = NULL; 481 wandev_conf_t *conf; 482 int err = -EINVAL; 483 484 if (wandev->setup == NULL) { /* Nothing to do ? */ 485 printk(KERN_INFO "%s: ERROR, No setup script: wandev->setup()\n", 486 wandev->name); 487 return 0; 488 } 489 490 conf = kmalloc(sizeof(wandev_conf_t), GFP_KERNEL); 491 if (conf == NULL){ 492 printk(KERN_INFO "%s: ERROR, Failed to allocate kernel memory !\n", 493 wandev->name); 494 return -ENOBUFS; 495 } 496 497 if (copy_from_user(conf, u_conf, sizeof(wandev_conf_t))) { 498 printk(KERN_INFO "%s: Failed to copy user config data to kernel space!\n", 499 wandev->name); 500 kfree(conf); 501 return -EFAULT; 502 } 503 504 if (conf->magic != ROUTER_MAGIC) { 505 kfree(conf); 506 printk(KERN_INFO "%s: ERROR, Invalid MAGIC Number\n", 507 wandev->name); 508 return -EINVAL; 509 } 510 511 if (conf->data_size && conf->data) { 512 if (conf->data_size > 128000 || conf->data_size < 0) { 513 printk(KERN_INFO 514 "%s: ERROR, Invalid firmware data size %i !\n", 515 wandev->name, conf->data_size); 516 kfree(conf); 517 return -EINVAL; 518 } 519 520 data = vmalloc(conf->data_size); 521 if (!data) { 522 printk(KERN_INFO 523 "%s: ERROR, Faild allocate kernel memory !\n", 524 wandev->name); 525 kfree(conf); 526 return -ENOBUFS; 527 } 528 if (!copy_from_user(data, conf->data, conf->data_size)) { 529 conf->data = data; 530 err = wandev->setup(wandev, conf); 531 } else { 532 printk(KERN_INFO 533 "%s: ERROR, Faild to copy from user data !\n", 534 wandev->name); 535 err = -EFAULT; 536 } 537 vfree(data); 538 } else { 539 printk(KERN_INFO 540 "%s: ERROR, No firmware found ! Firmware size = %i !\n", 541 wandev->name, conf->data_size); 542 } 543 544 kfree(conf); 545 return err; 546} 547 548/* 549 * Shutdown WAN device. 550 * o delete all not opened logical channels for this device 551 * o call driver's shutdown() entry point 552 */ 553 554static int wanrouter_device_shutdown(struct wan_device *wandev) 555{ 556 struct net_device *dev; 557 int err=0; 558 559 if (wandev->state == WAN_UNCONFIGURED) 560 return 0; 561 562 printk(KERN_INFO "\n%s: Shutting Down!\n",wandev->name); 563 564 for (dev = wandev->dev; dev;) { 565 err = wanrouter_delete_interface(wandev, dev->name); 566 if (err) 567 return err; 568 /* The above function deallocates the current dev 569 * structure. Therefore, we cannot use dev->priv 570 * as the next element: wandev->dev points to the 571 * next element */ 572 dev = wandev->dev; 573 } 574 575 if (wandev->ndev) 576 return -EBUSY; /* there are opened interfaces */ 577 578 if (wandev->shutdown) 579 err=wandev->shutdown(wandev); 580 581 return err; 582} 583 584/* 585 * Get WAN device status & statistics. 586 */ 587 588static int wanrouter_device_stat(struct wan_device *wandev, 589 wandev_stat_t __user *u_stat) 590{ 591 wandev_stat_t stat; 592 593 memset(&stat, 0, sizeof(stat)); 594 595 /* Ask device driver to update device statistics */ 596 if ((wandev->state != WAN_UNCONFIGURED) && wandev->update) 597 wandev->update(wandev); 598 599 /* Fill out structure */ 600 stat.ndev = wandev->ndev; 601 stat.state = wandev->state; 602 603 if (copy_to_user(u_stat, &stat, sizeof(stat))) 604 return -EFAULT; 605 606 return 0; 607} 608 609/* 610 * Create new WAN interface. 611 * o verify user address space 612 * o copy configuration data to kernel address space 613 * o allocate network interface data space 614 * o call driver's new_if() entry point 615 * o make sure there is no interface name conflict 616 * o register network interface 617 */ 618 619static int wanrouter_device_new_if(struct wan_device *wandev, 620 wanif_conf_t __user *u_conf) 621{ 622 wanif_conf_t *cnf; 623 struct net_device *dev = NULL; 624#ifdef CONFIG_WANPIPE_MULTPPP 625 struct ppp_device *pppdev=NULL; 626#endif 627 int err; 628 629 if ((wandev->state == WAN_UNCONFIGURED) || (wandev->new_if == NULL)) 630 return -ENODEV; 631 632 cnf = kmalloc(sizeof(wanif_conf_t), GFP_KERNEL); 633 if (!cnf) 634 return -ENOBUFS; 635 636 err = -EFAULT; 637 if (copy_from_user(cnf, u_conf, sizeof(wanif_conf_t))) 638 goto out; 639 640 err = -EINVAL; 641 if (cnf->magic != ROUTER_MAGIC) 642 goto out; 643 644 if (cnf->config_id == WANCONFIG_MPPP) { 645#ifdef CONFIG_WANPIPE_MULTPPP 646 pppdev = kmalloc(sizeof(struct ppp_device), GFP_KERNEL); 647 err = -ENOBUFS; 648 if (pppdev == NULL) 649 goto out; 650 memset(pppdev, 0, sizeof(struct ppp_device)); 651 pppdev->dev = kmalloc(sizeof(struct net_device), GFP_KERNEL); 652 if (pppdev->dev == NULL) { 653 kfree(pppdev); 654 err = -ENOBUFS; 655 goto out; 656 } 657 memset(pppdev->dev, 0, sizeof(struct net_device)); 658 err = wandev->new_if(wandev, (struct net_device *)pppdev, cnf); 659 dev = pppdev->dev; 660#else 661 printk(KERN_INFO "%s: Wanpipe Mulit-Port PPP support has not been compiled in!\n", 662 wandev->name); 663 err = -EPROTONOSUPPORT; 664 goto out; 665#endif 666 } else { 667 dev = kmalloc(sizeof(struct net_device), GFP_KERNEL); 668 err = -ENOBUFS; 669 if (dev == NULL) 670 goto out; 671 memset(dev, 0, sizeof(struct net_device)); 672 err = wandev->new_if(wandev, dev, cnf); 673 } 674 675 if (!err) { 676 /* Register network interface. This will invoke init() 677 * function supplied by the driver. If device registered 678 * successfully, add it to the interface list. 679 */ 680 681 if (dev->name == NULL) { 682 err = -EINVAL; 683 } else { 684 685 #ifdef WANDEBUG 686 printk(KERN_INFO "%s: registering interface %s...\n", 687 wanrouter_modname, dev->name); 688 #endif 689 690 err = register_netdev(dev); 691 if (!err) { 692 struct net_device *slave = NULL; 693 unsigned long smp_flags=0; 694 695 lock_adapter_irq(&wandev->lock, &smp_flags); 696 697 if (wandev->dev == NULL) { 698 wandev->dev = dev; 699 } else { 700 for (slave=wandev->dev; 701 *((struct net_device **)slave->priv); 702 slave = *((struct net_device **)slave->priv)); 703 704 *((struct net_device **)slave->priv) = dev; 705 } 706 ++wandev->ndev; 707 708 unlock_adapter_irq(&wandev->lock, &smp_flags); 709 err = 0; /* done !!! */ 710 goto out; 711 } 712 } 713 if (wandev->del_if) 714 wandev->del_if(wandev, dev); 715 } 716 717 /* This code has moved from del_if() function */ 718 kfree(dev->priv); 719 dev->priv = NULL; 720 721#ifdef CONFIG_WANPIPE_MULTPPP 722 if (cnf->config_id == WANCONFIG_MPPP) 723 kfree(pppdev); 724 else 725 kfree(dev); 726#else 727 /* Sync PPP is disabled */ 728 if (cnf->config_id != WANCONFIG_MPPP) 729 kfree(dev); 730#endif 731 732out: 733 kfree(cnf); 734 return err; 735} 736 737 738/* 739 * Delete WAN logical channel. 740 * o verify user address space 741 * o copy configuration data to kernel address space 742 */ 743 744static int wanrouter_device_del_if(struct wan_device *wandev, char __user *u_name) 745{ 746 char name[WAN_IFNAME_SZ + 1]; 747 int err = 0; 748 749 if (wandev->state == WAN_UNCONFIGURED) 750 return -ENODEV; 751 752 memset(name, 0, sizeof(name)); 753 754 if (copy_from_user(name, u_name, WAN_IFNAME_SZ)) 755 return -EFAULT; 756 757 err = wanrouter_delete_interface(wandev, name); 758 if (err) 759 return err; 760 761 /* If last interface being deleted, shutdown card 762 * This helps with administration at leaf nodes 763 * (You can tell if the person at the other end of the phone 764 * has an interface configured) and avoids DoS vulnerabilities 765 * in binary driver files - this fixes a problem with the current 766 * Sangoma driver going into strange states when all the network 767 * interfaces are deleted and the link irrecoverably disconnected. 768 */ 769 770 if (!wandev->ndev && wandev->shutdown) 771 err = wandev->shutdown(wandev); 772 773 return err; 774} 775 776/* 777 * Miscellaneous Functions 778 */ 779 780/* 781 * Find WAN device by name. 782 * Return pointer to the WAN device data space or NULL if device not found. 783 */ 784 785static struct wan_device *wanrouter_find_device(char *name) 786{ 787 struct wan_device *wandev; 788 789 for (wandev = wanrouter_router_devlist; 790 wandev && strcmp(wandev->name, name); 791 wandev = wandev->next); 792 return wandev; 793} 794 795/* 796 * Delete WAN logical channel identified by its name. 797 * o find logical channel by its name 798 * o call driver's del_if() entry point 799 * o unregister network interface 800 * o unlink channel data space from linked list of channels 801 * o release channel data space 802 * 803 * Return: 0 success 804 * -ENODEV channel not found. 805 * -EBUSY interface is open 806 * 807 * Note: If (force != 0), then device will be destroyed even if interface 808 * associated with it is open. It's caller's responsibility to make 809 * sure that opened interfaces are not removed! 810 */ 811 812static int wanrouter_delete_interface(struct wan_device *wandev, char *name) 813{ 814 struct net_device *dev = NULL, *prev = NULL; 815 unsigned long smp_flags=0; 816 817 lock_adapter_irq(&wandev->lock, &smp_flags); 818 dev = wandev->dev; 819 prev = NULL; 820 while (dev && strcmp(name, dev->name)) { 821 struct net_device **slave = dev->priv; 822 prev = dev; 823 dev = *slave; 824 } 825 unlock_adapter_irq(&wandev->lock, &smp_flags); 826 827 if (dev == NULL) 828 return -ENODEV; /* interface not found */ 829 830 if (netif_running(dev)) 831 return -EBUSY; /* interface in use */ 832 833 if (wandev->del_if) 834 wandev->del_if(wandev, dev); 835 836 lock_adapter_irq(&wandev->lock, &smp_flags); 837 if (prev) { 838 struct net_device **prev_slave = prev->priv; 839 struct net_device **slave = dev->priv; 840 841 *prev_slave = *slave; 842 } else { 843 struct net_device **slave = dev->priv; 844 wandev->dev = *slave; 845 } 846 --wandev->ndev; 847 unlock_adapter_irq(&wandev->lock, &smp_flags); 848 849 printk(KERN_INFO "%s: unregistering '%s'\n", wandev->name, dev->name); 850 851 /* Due to new interface linking method using dev->priv, 852 * this code has moved from del_if() function.*/ 853 kfree(dev->priv); 854 dev->priv=NULL; 855 856 unregister_netdev(dev); 857 858 free_netdev(dev); 859 860 return 0; 861} 862 863void lock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags) 864{ 865 spin_lock_irqsave(lock, *smp_flags); 866} 867 868 869void unlock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags) 870{ 871 spin_unlock_irqrestore(lock, *smp_flags); 872} 873 874EXPORT_SYMBOL(register_wan_device); 875EXPORT_SYMBOL(unregister_wan_device); 876EXPORT_SYMBOL(wanrouter_encapsulate); 877EXPORT_SYMBOL(wanrouter_type_trans); 878EXPORT_SYMBOL(lock_adapter_irq); 879EXPORT_SYMBOL(unlock_adapter_irq); 880 881MODULE_LICENSE("GPL"); 882 883/* 884 * End 885 */