X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fnetifd.git;a=blobdiff_plain;f=wireless.c;h=531311910411327dbe05f7d7ea6928a5cdeb18ae;hp=508d35e4e7b9def434b4b0dc2c820a33ec87a2cc;hb=9cd56141e80ea7d19350584d382d303f884d0aa5;hpb=45df0e856445469c8647bfcd89c96872d274ef94 diff --git a/wireless.c b/wireless.c index 508d35e..5313119 100644 --- a/wireless.c +++ b/wireless.c @@ -40,7 +40,7 @@ enum { static const struct blobmsg_policy vif_policy[__VIF_ATTR_MAX] = { [VIF_ATTR_DISABLED] = { .name = "disabled", .type = BLOBMSG_TYPE_BOOL }, - [VIF_ATTR_NETWORK] = { .name = "network", .type = BLOBMSG_TYPE_STRING }, + [VIF_ATTR_NETWORK] = { .name = "network", .type = BLOBMSG_TYPE_ARRAY }, }; static const struct uci_blob_param_list vif_param = { @@ -57,23 +57,33 @@ put_container(struct blob_buf *buf, struct blob_attr *attr, const char *name) } static void -vif_config_add_bridge(struct blob_buf *buf, const char *network, bool prepare) +vif_config_add_bridge(struct blob_buf *buf, struct blob_attr *networks, bool prepare) { struct interface *iface; - struct device *dev; + struct device *dev = NULL; + struct blob_attr *cur; + const char *network; + int rem; - if (!network) + if (!networks) return; - iface = vlist_find(&interfaces, network, iface, node); - if (!iface) - return; + blobmsg_for_each_attr(cur, networks, rem) { + network = blobmsg_data(cur); - dev = iface->main_dev.dev; - if (!dev) - return; + iface = vlist_find(&interfaces, network, iface, node); + if (!iface) + continue; + + dev = iface->main_dev.dev; + if (!dev) + return; + + if (dev->type != &bridge_device_type) + return; + } - if (dev->type != &bridge_device_type) + if (!dev) return; if (dev->hotplug_ops && dev->hotplug_ops->prepare) @@ -170,6 +180,7 @@ wireless_device_free_state(struct wireless_device *wdev) { struct wireless_interface *vif; + uloop_timeout_cancel(&wdev->script_check); uloop_timeout_cancel(&wdev->timeout); wireless_complete_kill_request(wdev); free(wdev->data); @@ -184,15 +195,22 @@ wireless_device_free_state(struct wireless_device *wdev) static void wireless_interface_handle_link(struct wireless_interface *vif, bool up) { struct interface *iface; + struct blob_attr *cur; + const char *network; + int rem; if (!vif->network || !vif->ifname) return; - iface = vlist_find(&interfaces, vif->network, iface, node); - if (!iface) - return; + blobmsg_for_each_attr(cur, vif->network, rem) { + network = blobmsg_data(cur); + + iface = vlist_find(&interfaces, network, iface, node); + if (!iface) + continue; - interface_handle_link(iface, vif->ifname, up); + interface_handle_link(iface, vif->ifname, up); + } } static void @@ -253,9 +271,10 @@ __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); + vlist_flush_all(&wdev->interfaces); + avl_delete(&wireless_devices.avl, &wdev->node.avl); + free(wdev->config); + free(wdev); } static void @@ -263,10 +282,10 @@ 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: + wdev->config_state = IFC_NORMAL; if (wdev->autostart) __wireless_device_set_up(wdev); break; @@ -377,12 +396,10 @@ wireless_device_set_down(struct wireless_device *wdev) static void wdev_set_config_state(struct wireless_device *wdev, enum interface_config_state s) { - enum interface_config_state old_state = wdev->config_state; - - wdev->config_state = s; - if (old_state != IFC_NORMAL) + if (wdev->config_state != IFC_NORMAL) return; + wdev->config_state = s; if (wdev->state == IFS_DOWN) wdev_handle_config_change(wdev); else @@ -445,10 +462,10 @@ wireless_add_handler(const char *script, const char *name, json_object *obj) return; drv = calloc_a(sizeof(*drv), - &name_str, strlen(name) + 1, - &script_str, strlen(script) + 1, &dev_config, sizeof(*dev_config) + sizeof(void *), - &iface_config, sizeof(*iface_config) + sizeof(void *)); + &iface_config, sizeof(*iface_config) + sizeof(void *), + &name_str, strlen(name) + 1, + &script_str, strlen(script) + 1); drv->name = strcpy(name_str, name); drv->script = strcpy(script_str, script); @@ -494,7 +511,7 @@ wireless_interface_init_config(struct wireless_interface *vif) blobmsg_parse(vif_policy, __VIF_ATTR_MAX, tb, blob_data(vif->config), blob_len(vif->config)); if ((cur = tb[VIF_ATTR_NETWORK])) - vif->network = blobmsg_data(cur); + vif->network = cur; } static void @@ -608,7 +625,6 @@ wireless_device_create(struct wireless_driver *drv, const char *name, struct blo INIT_LIST_HEAD(&wdev->script_proc); vlist_init(&wdev->interfaces, avl_strcmp, vif_update); wdev->interfaces.keep_old = true; - wdev->interfaces.no_delete = true; vlist_add(&wireless_devices, &wdev->node, wdev->name); wdev->timeout.cb = wireless_device_setup_timeout;