Commit e15147c2 authored by John Crispin's avatar John Crispin Committed by Daniel Golle

wireless: make reconf opt-in and allow serializing configuration

Add option 'reconf' to make dynamic re-configuration opt-in.
Also add option 'serialize' to 'wifi-device' section and if set
configure interfaces of wireless devices one-by-one.
Both options are disabled by default.
Signed-off-by: default avatarDaniel Golle <daniel@makrotopia.org>
parent 7a723d0c
Pipeline #181 failed with stages
......@@ -23,13 +23,25 @@ struct vlist_tree wireless_devices;
struct avl_tree wireless_drivers;
static struct blob_buf b;
static int drv_fd;
static LIST_HEAD(handlers);
static bool handler_pending;
static const struct blobmsg_policy wdev_policy =
{ .name = "disabled", .type = BLOBMSG_TYPE_BOOL };
enum {
WDEV_ATTR_DISABLED,
WDEV_ATTR_RECONF,
WDEV_ATTR_SERIALIZE,
__WDEV_ATTR_MAX,
};
static const struct blobmsg_policy wdev_policy[__WDEV_ATTR_MAX] = {
[WDEV_ATTR_DISABLED] = { .name = "disabled", .type = BLOBMSG_TYPE_BOOL },
[WDEV_ATTR_RECONF] = { .name = "reconf", .type = BLOBMSG_TYPE_BOOL },
[WDEV_ATTR_SERIALIZE] = { .name = "serialize", .type = BLOBMSG_TYPE_BOOL },
};
static const struct uci_blob_param_list wdev_param = {
.n_params = 1,
.params = &wdev_policy,
.n_params = ARRAY_SIZE(wdev_policy),
.params = wdev_policy,
};
enum {
......@@ -52,6 +64,15 @@ static const struct uci_blob_param_list vif_param = {
.params = vif_policy,
};
static void
wireless_handler_stop(struct wireless_device *wdev)
{
if (wdev->handler_pending) {
wdev->handler_pending = false;
list_del(&wdev->handler);
}
}
static void
put_container(struct blob_buf *buf, struct blob_attr *attr, const char *name)
{
......@@ -188,6 +209,7 @@ wireless_device_free_state(struct wireless_device *wdev)
{
struct wireless_interface *vif;
wireless_handler_stop(wdev);
uloop_timeout_cancel(&wdev->script_check);
uloop_timeout_cancel(&wdev->timeout);
wireless_complete_kill_request(wdev);
......@@ -236,6 +258,7 @@ wireless_device_setup_cancel(struct wireless_device *wdev)
if (wdev->cancel)
return;
wireless_handler_stop(wdev);
D(WIRELESS, "Cancel wireless device '%s' setup\n", wdev->name);
wdev->cancel = true;
uloop_timeout_set(&wdev->timeout, 10 * 1000);
......@@ -250,6 +273,17 @@ wireless_device_run_handler(struct wireless_device *wdev, bool up)
int i = 0;
int fds[2] = { -1, -1 };
wireless_handler_stop(wdev);
if (handler_pending && wdev->serialize) {
wdev->handler_action = up;
wdev->handler_pending = true;
list_add_tail(&wdev->handler, &handlers);
return;
}
if (wdev->serialize)
handler_pending = true;
D(WIRELESS, "Wireless device '%s' run %s handler\n", wdev->name, action);
if (!up && wdev->prev_config) {
config = blobmsg_format_json(wdev->prev_config, true);
......@@ -281,6 +315,21 @@ wireless_device_run_handler(struct wireless_device *wdev, bool up)
free(config);
}
static void
wireless_handler_next(void)
{
struct wireless_device *wdev;
if (handler_pending)
return;
if (list_empty(&handlers))
return;
wdev = list_first_entry(&handlers, struct wireless_device, handler);
list_del(&wdev->handler);
wdev->handler_pending = false;
wireless_device_run_handler(wdev, wdev->handler_action);
}
static void
__wireless_device_set_up(struct wireless_device *wdev, int force)
{
......@@ -305,6 +354,7 @@ __wireless_device_set_up(struct wireless_device *wdev, int force)
static void
wireless_device_free(struct wireless_device *wdev)
{
wireless_handler_stop(wdev);
vlist_flush_all(&wdev->interfaces);
avl_delete(&wireless_devices.avl, &wdev->node.avl);
free(wdev->config);
......@@ -353,6 +403,10 @@ wireless_device_setup_timeout(struct uloop_timeout *timeout)
{
struct wireless_device *wdev = container_of(timeout, struct wireless_device, timeout);
if (wdev->handler_pending) {
wdev->handler_pending = false;
list_del(&wdev->handler);
}
netifd_kill_process(&wdev->script_task);
wdev->script_task.cb(&wdev->script_task, -1);
wireless_device_mark_down(wdev);
......@@ -371,7 +425,7 @@ wireless_device_reconf(struct wireless_device *wdev)
{
wdev->retry = WIRELESS_SETUP_RETRY;
wdev->autostart = true;
__wireless_device_set_up(wdev, 1);
__wireless_device_set_up(wdev, wdev->reconf && (wdev->state == IFS_UP));
}
static void
......@@ -433,6 +487,11 @@ wireless_device_script_task_cb(struct netifd_process *proc, int ret)
default:
break;
}
if (wdev->serialize) {
handler_pending = false;
wireless_handler_next();
}
}
void
......@@ -452,7 +511,7 @@ wdev_set_config_state(struct wireless_device *wdev, enum interface_config_state
wdev->config_state = s;
if (wdev->state == IFS_DOWN)
wdev_handle_config_change(wdev);
else
else if (!wdev->reconf || wdev->state != IFS_UP)
__wireless_device_set_down(wdev);
}
......@@ -501,6 +560,7 @@ wdev_update(struct vlist_tree *tree, struct vlist_node *node_new,
struct wireless_device *wd_new = container_of(node_new, struct wireless_device, node);
if (wd_old && wd_new) {
D(WIRELESS, "Update wireless device '%s'\n", wd_old->name);
wdev_change_config(wd_old, wd_new);
} else if (wd_old) {
D(WIRELESS, "Delete wireless device '%s'\n", wd_old->name);
......@@ -686,18 +746,29 @@ wireless_device_create(struct wireless_driver *drv, const char *name, struct blo
{
struct wireless_device *wdev;
char *name_buf;
struct blob_attr *disabled;
struct blob_attr *tb[__WDEV_ATTR_MAX];
struct blob_attr *cur;
blobmsg_parse(&wdev_policy, 1, &disabled, blob_data(data), blob_len(data));
blobmsg_parse(wdev_policy, __WDEV_ATTR_MAX, tb, blob_data(data), blob_len(data));
wdev = calloc_a(sizeof(*wdev), &name_buf, strlen(name) + 1);
if (disabled && blobmsg_get_bool(disabled))
wdev->disabled = true;
cur = tb[WDEV_ATTR_DISABLED];
wdev->disabled = cur && blobmsg_get_bool(cur);
wdev->drv = drv;
wdev->state = IFS_DOWN;
wdev->config_state = IFC_NORMAL;
wdev->name = strcpy(name_buf, name);
wdev->config = data;
wdev->handler_pending = false;
cur = tb[WDEV_ATTR_SERIALIZE];
wdev->serialize = cur && blobmsg_get_bool(cur);
cur = tb[WDEV_ATTR_RECONF];
wdev->reconf = cur && blobmsg_get_bool(cur);
wdev->retry_setup_failed = false;
wdev->autostart = true;
INIT_LIST_HEAD(&wdev->script_proc);
......
......@@ -15,6 +15,7 @@
#define __NETIFD_WIRELESS_H
#include <libubox/utils.h>
#include <libubox/list.h>
#include "interface.h"
extern struct vlist_tree wireless_devices;
......@@ -35,6 +36,11 @@ struct wireless_driver {
struct wireless_device {
struct vlist_node node;
struct list_head handler;
bool handler_action;
bool handler_pending;
bool serialize;
struct wireless_driver *drv;
struct vlist_tree interfaces;
char *name;
......@@ -59,6 +65,7 @@ struct wireless_device {
enum interface_state state;
enum interface_config_state config_state;
bool reconf;
bool cancel;
int retry;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment