1 /*****************************************************************************
2 * wanmain.c WAN Multiprotocol Router Module. Main code.
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, incomming calls)
9 * o Logical connection management (switched virtual circuits)
10 * o Protocol encapsulation/decapsulation
12 * Author: Gene Kozin <genek@compuserve.com>
14 * Copyright: (c) 1995-1997 Sangoma Technologies Inc.
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 * Dec 27, 1996 Gene Kozin Initial version (based on Sangoma's WANPIPE)
22 * Jan 16, 1997 Gene Kozin router_devlist made public
23 * Jan 31, 1997 Alan Cox Hacked it about a bit for 2.1
24 * Jun 27, 1997 Alan Cox realigned with vendor code
25 * Oct 15, 1997 Farhan Thawar changed wan_encapsulate to add a pad byte of 0
26 * Apr 20, 1998 Alan Cox Fixed 2.1 symbols
27 * May 17, 1998 K. Baranowski Fixed SNAP encapsulation in wan_encapsulate
28 * Dec 15, 1998 Arnaldo Melo support for firmwares of up to 128000 bytes
29 * check wandev->setup return value
30 * Dec 22, 1998 Arnaldo Melo vmalloc/vfree used in device_setup to allocate
31 * kernel memory and copy configuration data to
32 * kernel space (for big firmwares)
33 *****************************************************************************/
35 #include <linux/config.h>
36 #include <linux/stddef.h> /* offsetof(), etc. */
37 #include <linux/errno.h> /* return codes */
38 #include <linux/kernel.h>
39 #include <linux/module.h> /* support for loadable modules */
40 #include <linux/malloc.h> /* kmalloc(), kfree() */
41 #include <linux/mm.h> /* verify_area(), etc. */
42 #include <linux/string.h> /* inline mem*, str* functions */
43 #include <linux/vmalloc.h> /* vmalloc, vfree */
44 #include <asm/segment.h> /* kernel <-> user copy */
45 #include <asm/byteorder.h> /* htons(), etc. */
46 #include <asm/uaccess.h> /* copy_to/from_user */
47 #include <linux/wanrouter.h> /* WAN router API definitions */
48 #include <linux/init.h> /* __initfunc et al. */
50 /****** Defines and Macros **************************************************/
53 #define min(a,b) (((a)<(b))?(a):(b))
56 #define max(a,b) (((a)>(b))?(a):(b))
59 /****** Function Prototypes *************************************************/
62 * Kernel loadable module interface.
66 int init_module (void);
67 void cleanup_module (void);
71 * WAN device IOCTL handlers
74 static int device_setup (wan_device_t
* wandev
, wandev_conf_t
* u_conf
);
75 static int device_stat (wan_device_t
* wandev
, wandev_stat_t
* u_stat
);
76 static int device_shutdown (wan_device_t
* wandev
);
77 static int device_new_if (wan_device_t
* wandev
, wanif_conf_t
* u_conf
);
78 static int device_del_if (wan_device_t
* wandev
, char* u_name
);
84 static wan_device_t
* find_device (char* name
);
85 static int delete_interface (wan_device_t
* wandev
, char* name
, int forse
);
91 static char fullname
[] = "WAN Router";
92 static char copyright
[] = "(c) 1995-1997 Sangoma Technologies Inc.";
93 static char modname
[] = ROUTER_NAME
; /* short module name */
94 wan_device_t
* router_devlist
= NULL
; /* list of registered devices */
95 static int devcnt
= 0;
98 * Organizationally Unique Identifiers for encapsulation/decapsulation
101 static unsigned char oui_ether
[] = { 0x00, 0x00, 0x00 };
103 static unsigned char oui_802_2
[] = { 0x00, 0x80, 0xC2 };
108 int wanrouter_init(void)
111 extern void wanpipe_init(void);
113 printk(KERN_INFO
"%s v%u.%u %s\n",
114 fullname
, ROUTER_VERSION
, ROUTER_RELEASE
, copyright
);
115 err
= wanrouter_proc_init();
117 printk(KERN_ERR
"%s: can't create entry in proc filesystem!\n", modname
);
120 * Initialise compiled in boards
123 #ifdef CONFIG_VENDOR_SANGOMA
132 * Kernel Loadable Module Entry Points
136 * Module 'insert' entry point.
137 * o print announcement
138 * o initialize static data
139 * o create /proc/net/router directory and static entries
146 int init_module (void)
150 printk(KERN_INFO
"%s v%u.%u %s\n",
151 fullname
, ROUTER_VERSION
, ROUTER_RELEASE
, copyright
);
152 err
= wanrouter_proc_init();
153 if (err
) printk(KERN_ERR
154 "%s: can't create entry in proc filesystem!\n", modname
);
159 * Module 'remove' entry point.
160 * o delete /proc/net/router directory and static entries.
163 void cleanup_module (void)
165 wanrouter_proc_cleanup();
175 * Register WAN device.
176 * o verify device credentials
177 * o create an entry for the device in the /proc/net/router directory
178 * o initialize internally maintained fields of the wan_device structure
179 * o link device data space to a singly-linked list
180 * o if it's the first device, then start kernel 'thread'
181 * o increment module use count
191 int register_wan_device(wan_device_t
* wandev
)
195 if ((wandev
== NULL
) || (wandev
->magic
!= ROUTER_MAGIC
) ||
196 (wandev
->name
== NULL
))
199 namelen
= strlen(wandev
->name
);
200 if (!namelen
|| (namelen
> WAN_DRVNAME_SZ
))
203 if (find_device(wandev
->name
) != NULL
)
207 printk(KERN_INFO
"%s: registering WAN device %s\n",
208 modname
, wandev
->name
);
212 * Register /proc directory entry
214 err
= wanrouter_proc_add(wandev
);
218 "%s: can't create /proc/net/router/%s entry!\n",
219 modname
, wandev
->name
)
225 * Initialize fields of the wan_device structure maintained by the
226 * router and update local data.
231 wandev
->next
= router_devlist
;
232 router_devlist
= wandev
;
234 MOD_INC_USE_COUNT
; /* prevent module from unloading */
239 * Unregister WAN device.
241 * o unlink device data space from the linked list
242 * o delete device entry in the /proc/net/router directory
243 * o decrement module use count
251 int unregister_wan_device(char* name
)
253 wan_device_t
*wandev
, *prev
;
258 for (wandev
= router_devlist
, prev
= NULL
;
259 wandev
&& strcmp(wandev
->name
, name
);
260 prev
= wandev
, wandev
= wandev
->next
)
266 printk(KERN_INFO
"%s: unregistering WAN device %s\n", modname
, name
);
269 if (wandev
->state
!= WAN_UNCONFIGURED
)
272 delete_interface(wandev
, wandev
->dev
->name
, 1);
273 if (wandev
->shutdown
)
274 wandev
->shutdown(wandev
);
277 prev
->next
= wandev
->next
;
279 router_devlist
= wandev
->next
;
281 wanrouter_proc_delete(wandev
);
287 * Encapsulate packet.
289 * Return: encapsulation header size
290 * < 0 - unsupported Ethertype
293 * 1. This function may be called on interrupt context.
297 int wanrouter_encapsulate (struct sk_buff
* skb
, struct device
* dev
)
301 switch (skb
->protocol
)
303 case ETH_P_IP
: /* IP datagram encapsulation */
306 skb
->data
[0] = NLPID_IP
;
309 case ETH_P_IPX
: /* SNAP encapsulation */
314 skb
->data
[1] = NLPID_SNAP
;
315 memcpy(&skb
->data
[2], oui_ether
, sizeof(oui_ether
));
316 *((unsigned short*)&skb
->data
[5]) = htons(skb
->protocol
);
319 default: /* Unknown packet type */
321 "%s: unsupported Ethertype 0x%04X on interface %s!\n",
322 modname
, skb
->protocol
, dev
->name
);
329 * Decapsulate packet.
331 * Return: Ethertype (in network order)
332 * 0 unknown encapsulation
335 * 1. This function may be called on interrupt context.
339 unsigned short wanrouter_type_trans (struct sk_buff
* skb
, struct device
* dev
)
341 int cnt
= skb
->data
[0] ? 0 : 1; /* there may be a pad present */
342 unsigned short ethertype
;
344 switch (skb
->data
[cnt
])
346 case NLPID_IP
: /* IP datagramm */
347 ethertype
= htons(ETH_P_IP
);
351 case NLPID_SNAP
: /* SNAP encapsulation */
352 if (memcmp(&skb
->data
[cnt
+ 1], oui_ether
, sizeof(oui_ether
)))
355 "%s: unsupported SNAP OUI %02X-%02X-%02X "
356 "on interface %s!\n", modname
,
357 skb
->data
[cnt
+1], skb
->data
[cnt
+2],
358 skb
->data
[cnt
+3], dev
->name
);
362 ethertype
= *((unsigned short*)&skb
->data
[cnt
+4]);
366 /* add other protocols, e.g. CLNP, ESIS, ISIS, if needed */
370 "%s: unsupported NLPID 0x%02X on interface %s!\n",
371 modname
, skb
->data
[cnt
], dev
->name
)
375 skb
->protocol
= ethertype
;
376 skb
->pkt_type
= PACKET_HOST
; /* Physically point to point */
377 skb
->mac
.raw
= skb
->data
;
384 * o find WAN device associated with this node
385 * o execute requested action or pass command to the device driver
388 int wanrouter_ioctl(struct inode
* inode
, struct file
* file
,
389 unsigned int cmd
, unsigned long arg
)
392 struct proc_dir_entry
* dent
;
393 wan_device_t
* wandev
;
395 if (!capable(CAP_NET_ADMIN
)){
399 if ((cmd
>> 8) != ROUTER_IOCTL
)
402 dent
= inode
->u
.generic_ip
;
403 if ((dent
== NULL
) || (dent
->data
== NULL
))
407 if (wandev
->magic
!= ROUTER_MAGIC
)
413 err
= device_setup(wandev
, (void*)arg
);
417 err
= device_shutdown(wandev
);
421 err
= device_stat(wandev
, (void*)arg
);
425 err
= device_new_if(wandev
, (void*)arg
);
429 err
= device_del_if(wandev
, (void*)arg
);
436 if ((cmd
>= ROUTER_USER
) &&
437 (cmd
<= ROUTER_USER_MAX
) &&
439 err
= wandev
->ioctl(wandev
, cmd
, arg
)
447 * WAN Driver IOCTL Handlers
451 * Setup WAN link device.
452 * o verify user address space
453 * o allocate kernel memory and copy configuration data to kernel space
454 * o if configuration data includes extension, copy it to kernel space too
455 * o call driver's setup() entry point
458 static int device_setup (wan_device_t
* wandev
, wandev_conf_t
* u_conf
)
464 if (wandev
->setup
== NULL
) /* Nothing to do ? */
467 conf
= kmalloc(sizeof(wandev_conf_t
), GFP_KERNEL
);
471 if(copy_from_user(conf
, u_conf
, sizeof(wandev_conf_t
)))
477 if (conf
->magic
!= ROUTER_MAGIC
)
480 if (conf
->data_size
&& conf
->data
)
482 if(conf
->data_size
> 128000 || conf
->data_size
< 0){
485 data
= vmalloc(conf
->data_size
);
488 if(!copy_from_user(data
, conf
->data
, conf
->data_size
))
491 err
= wandev
->setup(wandev
,conf
);
508 * Shutdown WAN device.
509 * o delete all not opened logical channels for this device
510 * o call driver's shutdown() entry point
513 static int device_shutdown (wan_device_t
* wandev
)
517 if (wandev
->state
== WAN_UNCONFIGURED
)
520 for (dev
= wandev
->dev
; dev
;)
522 if (delete_interface(wandev
, dev
->name
, 0))
526 return -EBUSY
; /* there are opened interfaces */
528 if (wandev
->shutdown
)
529 return wandev
->shutdown(wandev
);
534 * Get WAN device status & statistics.
537 static int device_stat (wan_device_t
* wandev
, wandev_stat_t
* u_stat
)
541 memset(&stat
, 0, sizeof(stat
));
543 /* Ask device driver to update device statistics */
544 if ((wandev
->state
!= WAN_UNCONFIGURED
) && wandev
->update
)
545 wandev
->update(wandev
);
547 /* Fill out structure */
548 stat
.ndev
= wandev
->ndev
;
549 stat
.state
= wandev
->state
;
551 if(copy_to_user(u_stat
, &stat
, sizeof(stat
)))
557 * Create new WAN interface.
558 * o verify user address space
559 * o copy configuration data to kernel address space
560 * o allocate network interface data space
561 * o call driver's new_if() entry point
562 * o make sure there is no interface name conflict
563 * o register network interface
566 static int device_new_if (wan_device_t
* wandev
, wanif_conf_t
* u_conf
)
572 if ((wandev
->state
== WAN_UNCONFIGURED
) || (wandev
->new_if
== NULL
))
575 if(copy_from_user(&conf
, u_conf
, sizeof(wanif_conf_t
)))
578 if (conf
.magic
!= ROUTER_MAGIC
)
581 dev
= kmalloc(sizeof(struct device
), GFP_KERNEL
);
585 memset(dev
, 0, sizeof(struct device
));
586 err
= wandev
->new_if(wandev
, dev
, &conf
);
589 /* Register network interface. This will invoke init()
590 * function supplied by the driver. If device registered
591 * successfully, add it to the interface list.
593 if (dev
->name
== NULL
)
596 else if (dev_get(dev
->name
))
597 err
= -EEXIST
; /* name already exists */
601 printk(KERN_INFO
"%s: registering interface %s...\n",
604 err
= register_netdev(dev
);
607 cli(); /***** critical section start *****/
608 dev
->slave
= wandev
->dev
;
611 sti(); /****** critical section end ******/
612 return 0; /* done !!! */
616 wandev
->del_if(wandev
, dev
);
623 * Delete WAN logical channel.
624 * o verify user address space
625 * o copy configuration data to kernel address space
628 static int device_del_if (wan_device_t
* wandev
, char* u_name
)
630 char name
[WAN_IFNAME_SZ
+ 1];
632 if (wandev
->state
== WAN_UNCONFIGURED
)
635 memset(name
, 0, sizeof(name
));
636 if(copy_from_user(name
, u_name
, WAN_IFNAME_SZ
))
638 return delete_interface(wandev
, name
, 0);
642 * Miscellaneous Functions
646 * Find WAN device by name.
647 * Return pointer to the WAN device data space or NULL if device not found.
650 static wan_device_t
* find_device (char* name
)
652 wan_device_t
* wandev
;
654 for (wandev
= router_devlist
;wandev
&& strcmp(wandev
->name
, name
);
655 wandev
= wandev
->next
);
660 * Delete WAN logical channel identified by its name.
661 * o find logical channel by its name
662 * o call driver's del_if() entry point
663 * o unregister network interface
664 * o unlink channel data space from linked list of channels
665 * o release channel data space
668 * -ENODEV channel not found.
669 * -EBUSY interface is open
671 * Note: If (force != 0), then device will be destroyed even if interface
672 * associated with it is open. It's caller's responsibility to make
673 * sure that opened interfaces are not removed!
676 static int delete_interface (wan_device_t
* wandev
, char* name
, int force
)
678 struct device
*dev
, *prev
;
680 for (dev
= wandev
->dev
, prev
= NULL
;
681 dev
&& strcmp(name
, dev
->name
);
682 prev
= dev
, dev
= dev
->slave
);
685 return -ENODEV
; /* interface not found */
692 "%s: deleting opened interface %s!\n",modname
, name
);
695 return -EBUSY
; /* interface in use */
698 wandev
->del_if(wandev
, dev
);
700 cli(); /***** critical section start *****/
702 prev
->slave
= dev
->slave
;
704 wandev
->dev
= dev
->slave
;
706 sti(); /****** critical section end ******/
708 printk("Unregistering '%s'\n", dev
->name
);
709 unregister_netdev(dev
);
714 EXPORT_SYMBOL(register_wan_device
);
715 EXPORT_SYMBOL(unregister_wan_device
);
716 EXPORT_SYMBOL(wanrouter_encapsulate
);
717 EXPORT_SYMBOL(wanrouter_type_trans
);