X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fnetifd.git;a=blobdiff_plain;f=wireless.c;h=508d35e4e7b9def434b4b0dc2c820a33ec87a2cc;hp=daa4df74bdb8afc64de46084e18ad2940e81c73e;hb=45df0e856445469c8647bfcd89c96872d274ef94;hpb=37769eb666aa614b76df9b537db35c2c70e3ac7a diff --git a/wireless.c b/wireless.c index daa4df7..508d35e 100644 --- a/wireless.c +++ b/wireless.c @@ -76,6 +76,9 @@ vif_config_add_bridge(struct blob_buf *buf, const char *network, bool prepare) if (dev->type != &bridge_device_type) return; + if (dev->hotplug_ops && dev->hotplug_ops->prepare) + dev->hotplug_ops->prepare(dev); + blobmsg_add_string(buf, "bridge", dev->ifname); } @@ -122,6 +125,7 @@ wireless_complete_kill_request(struct wireless_device *wdev) static void wireless_process_free(struct wireless_device *wdev, struct wireless_process *proc) { + D(WIRELESS, "Wireless device '%s' free pid %d\n", wdev->name, proc->pid); list_del(&proc->list); free(proc); @@ -148,8 +152,10 @@ wireless_process_kill_all(struct wireless_device *wdev, int signal, bool free) list_for_each_entry_safe(proc, tmp, &wdev->script_proc, list) { bool check = wireless_process_check(proc); - if (check) + if (check) { + D(WIRELESS, "Wireless device '%s' kill pid %d\n", wdev->name, proc->pid); kill(proc->pid, signal); + } if (free || !check) wireless_process_free(wdev, proc); @@ -164,6 +170,7 @@ wireless_device_free_state(struct wireless_device *wdev) { struct wireless_interface *vif; + uloop_timeout_cancel(&wdev->timeout); wireless_complete_kill_request(wdev); free(wdev->data); wdev->data = NULL; @@ -194,6 +201,7 @@ wireless_device_setup_cancel(struct wireless_device *wdev) if (wdev->cancel) return; + D(WIRELESS, "Cancel wireless device '%s' setup\n", wdev->name); wdev->cancel = true; uloop_timeout_set(&wdev->timeout, 10 * 1000); } @@ -207,6 +215,7 @@ wireless_device_run_handler(struct wireless_device *wdev, bool up) int i = 0; int fds[2] = { -1, -1 }; + D(WIRELESS, "Wireless device '%s' run %s handler\n", wdev->name, action); prepare_config(wdev, &b, up); config = blobmsg_format_json(b.head, true); @@ -242,20 +251,47 @@ __wireless_device_set_up(struct wireless_device *wdev) } static void +wireless_device_free(struct wireless_device *wdev) +{ + vlist_flush_all(&wdev->interfaces); + free(wdev->config); + free(wdev); +} + +static void +wdev_handle_config_change(struct wireless_device *wdev) +{ + enum interface_config_state state = wdev->config_state; + + wdev->config_state = IFC_NORMAL; + switch(state) { + case IFC_NORMAL: + case IFC_RELOAD: + if (wdev->autostart) + __wireless_device_set_up(wdev); + break; + case IFC_REMOVE: + wireless_device_free(wdev); + break; + } +} + +static void wireless_device_mark_down(struct wireless_device *wdev) { struct wireless_interface *vif; + D(WIRELESS, "Wireless device '%s' is now down\n", wdev->name); + vlist_for_each_element(&wdev->interfaces, vif, node) wireless_interface_handle_link(vif, false); wireless_process_kill_all(wdev, SIGTERM, true); + wdev->cancel = false; wdev->state = IFS_DOWN; wireless_device_free_state(wdev); - - if (wdev->autostart) - __wireless_device_set_up(wdev); + wdev_handle_config_change(wdev); } static void @@ -263,6 +299,7 @@ wireless_device_mark_up(struct wireless_device *wdev) { struct wireless_interface *vif; + D(WIRELESS, "Wireless device '%s' is now up\n", wdev->name); wdev->state = IFS_UP; vlist_for_each_element(&wdev->interfaces, vif, node) wireless_interface_handle_link(vif, true); @@ -304,6 +341,9 @@ __wireless_device_set_down(struct wireless_device *wdev) static void wireless_device_retry_setup(struct wireless_device *wdev) { + if (wdev->state == IFS_TEARDOWN || wdev->state == IFS_DOWN || wdev->cancel) + return; + if (--wdev->retry < 0) wdev->autostart = false; @@ -335,30 +375,6 @@ wireless_device_set_down(struct wireless_device *wdev) } static void -wireless_device_free(struct wireless_device *wdev) -{ - vlist_flush_all(&wdev->interfaces); - free(wdev->config); - free(wdev); -} - -static void -wdev_handle_config_change(struct wireless_device *wdev) -{ - switch(wdev->config_state) { - case IFC_NORMAL: - break; - case IFC_RELOAD: - if (wdev->autostart) - __wireless_device_set_up(wdev); - break; - case IFC_REMOVE: - wireless_device_free(wdev); - break; - } -} - -static void wdev_set_config_state(struct wireless_device *wdev, enum interface_config_state s) { enum interface_config_state old_state = wdev->config_state; @@ -557,6 +573,7 @@ wireless_device_check_script_tasks(struct uloop_timeout *timeout) if (wireless_process_check(proc)) continue; + D(WIRELESS, "Wireless device '%s' pid %d has terminated\n", wdev->name, proc->pid); if (proc->required) restart = true; @@ -634,7 +651,7 @@ wireless_interface_status(struct wireless_interface *iface, struct blob_buf *b) { void *i; - i = blobmsg_open_table(b, iface->name); + i = blobmsg_open_table(b, NULL); if (iface->section) blobmsg_add_string(b, "section", iface->section); if (iface->ifname) @@ -654,10 +671,10 @@ wireless_device_status(struct wireless_device *wdev, struct blob_buf *b) blobmsg_add_u8(b, "up", wdev->state == IFS_UP); blobmsg_add_u8(b, "pending", wdev->state == IFS_SETUP || wdev->state == IFS_TEARDOWN); blobmsg_add_u8(b, "autostart", wdev->autostart); - i = blobmsg_open_table(b, "interfaces"); + i = blobmsg_open_array(b, "interfaces"); vlist_for_each_element(&wdev->interfaces, iface, node) wireless_interface_status(iface, b); - blobmsg_close_table(b, i); + blobmsg_close_array(b, i); blobmsg_close_table(b, c); } @@ -698,6 +715,7 @@ wireless_device_add_process(struct wireless_device *wdev, struct blob_attr *data struct blob_attr *tb[__PROC_ATTR_MAX]; struct wireless_process *proc; char *name; + int pid; if (!data) return UBUS_STATUS_INVALID_ARGUMENT; @@ -706,15 +724,20 @@ wireless_device_add_process(struct wireless_device *wdev, struct blob_attr *data if (!tb[PROC_ATTR_PID] || !tb[PROC_ATTR_EXE]) return UBUS_STATUS_INVALID_ARGUMENT; + pid = blobmsg_get_u32(tb[PROC_ATTR_PID]); + if (pid < 2) + return UBUS_STATUS_INVALID_ARGUMENT; + proc = calloc_a(sizeof(*proc), &name, strlen(blobmsg_data(tb[PROC_ATTR_EXE])) + 1); - proc->pid = blobmsg_get_u32(tb[PROC_ATTR_PID]); + proc->pid = pid; proc->exe = strcpy(name, blobmsg_data(tb[PROC_ATTR_EXE])); if (tb[PROC_ATTR_REQUIRED]) proc->required = blobmsg_get_bool(tb[PROC_ATTR_REQUIRED]); + D(WIRELESS, "Wireless device '%s' add pid %d\n", wdev->name, proc->pid); list_add(&proc->list, &wdev->script_proc); uloop_timeout_set(&wdev->script_check, 0); @@ -745,7 +768,7 @@ wireless_device_process_kill_all(struct wireless_device *wdev, struct blob_attr signal = blobmsg_get_u32(cur); if ((cur = tb[KILL_ATTR_IMMEDIATE])) - immediate = blobmsg_get_u32(cur); + immediate = blobmsg_get_bool(cur); if (wdev->state != IFS_TEARDOWN || wdev->kill_request) return UBUS_STATUS_PERMISSION_DENIED;