X-Git-Url: https://git.rohieb.name/openwrt.git/blobdiff_plain/f52d66ff00b24111f87c274d3d7085ef2e1d27b1..c291b847846f5921d669b17478cbf59f0c83ee19:/package/switch/src/switch-core.c diff --git a/package/switch/src/switch-core.c b/package/switch/src/switch-core.c index 7bf705afe..c34386b76 100644 --- a/package/switch/src/switch-core.c +++ b/package/switch/src/switch-core.c @@ -32,7 +32,7 @@ * ports: same syntax as for nvram's vlan*ports (eg. "1 2 3 4 5*") */ -#include +#include #include #include #include @@ -100,6 +100,7 @@ static ssize_t switch_proc_read(struct file *file, char *buf, size_t count, loff len = 0; } + kfree(page); return len; } @@ -138,18 +139,18 @@ static ssize_t switch_proc_write(struct file *file, const char *buf, size_t coun static int handle_driver_name(void *driver, char *buf, int nr) { - char *name = ((switch_driver *) driver)->name; + const char *name = ((switch_driver *) driver)->name; return sprintf(buf, "%s\n", name); } static int handle_driver_version(void *driver, char *buf, int nr) { - char *version = ((switch_driver *) driver)->version; + const char *version = ((switch_driver *) driver)->version; strcpy(buf, version); return sprintf(buf, "%s\n", version); } -static void add_handler(switch_driver *driver, switch_config *handler, struct proc_dir_entry *parent, int nr) +static void add_handler(switch_driver *driver, const switch_config *handler, struct proc_dir_entry *parent, int nr) { switch_priv *priv = (switch_priv *) driver->data; struct proc_dir_entry *p; @@ -157,6 +158,8 @@ static void add_handler(switch_driver *driver, switch_config *handler, struct pr switch_proc_handler *tmp; tmp = (switch_proc_handler *) kmalloc(sizeof(switch_proc_handler), GFP_KERNEL); + if (!tmp) + return; INIT_LIST_HEAD(&tmp->list); tmp->parent = parent; tmp->nr = nr; @@ -174,7 +177,7 @@ static void add_handler(switch_driver *driver, switch_config *handler, struct pr } } -static inline void add_handlers(switch_driver *driver, switch_config *handlers, struct proc_dir_entry *parent, int nr) +static inline void add_handlers(switch_driver *driver, const switch_config *handlers, struct proc_dir_entry *parent, int nr) { int i; @@ -238,11 +241,26 @@ static int do_register(switch_driver *driver) switch_priv *priv; int i; char buf[4]; - - if ((priv = kmalloc(sizeof(switch_priv), GFP_KERNEL)) == NULL) - return -ENOBUFS; + + priv = kmalloc(sizeof(switch_priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; driver->data = (void *) priv; + priv->ports = kmalloc((driver->ports + 1) * sizeof(struct proc_dir_entry *), + GFP_KERNEL); + if (!priv->ports) { + kfree(priv); + return -ENOMEM; + } + priv->vlans = kmalloc((driver->vlans + 1) * sizeof(struct proc_dir_entry *), + GFP_KERNEL); + if (!priv->vlans) { + kfree(priv->ports); + kfree(priv); + return -ENOMEM; + } + INIT_LIST_HEAD(&priv->data.list); priv->nr = drv_num++; @@ -253,7 +271,6 @@ static int do_register(switch_driver *driver) } priv->port_dir = proc_mkdir("port", priv->driver_dir); - priv->ports = kmalloc((driver->ports + 1) * sizeof(struct proc_dir_entry *), GFP_KERNEL); for (i = 0; i < driver->ports; i++) { sprintf(buf, "%d", i); priv->ports[i] = proc_mkdir(buf, priv->port_dir); @@ -263,7 +280,6 @@ static int do_register(switch_driver *driver) priv->ports[i] = NULL; priv->vlan_dir = proc_mkdir("vlan", priv->driver_dir); - priv->vlans = kmalloc((driver->vlans + 1) * sizeof(struct proc_dir_entry *), GFP_KERNEL); for (i = 0; i < driver->vlans; i++) { sprintf(buf, "%d", i); priv->vlans[i] = proc_mkdir(buf, priv->vlan_dir); @@ -338,6 +354,8 @@ switch_vlan_config *switch_parse_vlan(switch_driver *driver, char *buf) int j, u, p, s; c = kmalloc(sizeof(switch_vlan_config), GFP_KERNEL); + if (!c) + return NULL; memset(c, 0, sizeof(switch_vlan_config)); while (isspace(*buf)) buf++; @@ -386,12 +404,27 @@ switch_vlan_config *switch_parse_vlan(switch_driver *driver, char *buf) } +int switch_device_registered (char* device) { + struct list_head *pos; + switch_driver *new; + + list_for_each(pos, &drivers.list) { + if (strcmp(list_entry(pos, switch_driver, list)->interface, device) == 0) { + printk("There is already a switch registered on the device '%s'\n", device); + return -EINVAL; + } + } + + return 0; +} + + int switch_register_driver(switch_driver *driver) { struct list_head *pos; switch_driver *new; int ret; - + list_for_each(pos, &drivers.list) { if (strcmp(list_entry(pos, switch_driver, list)->name, driver->name) == 0) { printk("Switch driver '%s' already exists in the kernel\n", driver->name); @@ -404,10 +437,12 @@ int switch_register_driver(switch_driver *driver) } new = kmalloc(sizeof(switch_driver), GFP_KERNEL); + if (!new) + return -ENOMEM; memcpy(new, driver, sizeof(switch_driver)); new->name = strdup(driver->name); new->interface = strdup(driver->interface); - + if ((ret = do_register(new)) < 0) { kfree(new->name); kfree(new); @@ -456,6 +491,7 @@ static void __exit switch_exit(void) MODULE_AUTHOR("Felix Fietkau "); MODULE_LICENSE("GPL"); +EXPORT_SYMBOL(switch_device_registered); EXPORT_SYMBOL(switch_register_driver); EXPORT_SYMBOL(switch_unregister_driver); EXPORT_SYMBOL(switch_parse_vlan);