scripts/netifd-wireless.sh: add support for specifying the operating band
[project/netifd.git] / wireless.c
1 /*
2 * netifd - network interface daemon
3 * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2
7 * as published by the Free Software Foundation
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14 #include <signal.h>
15 #include "netifd.h"
16 #include "wireless.h"
17 #include "handler.h"
18 #include "ubus.h"
19
20 #define WIRELESS_SETUP_RETRY 3
21
22 struct vlist_tree wireless_devices;
23 struct avl_tree wireless_drivers;
24 static struct blob_buf b;
25 static int drv_fd;
26 static LIST_HEAD(handlers);
27 static bool handler_pending;
28
29 enum {
30 WDEV_ATTR_DISABLED,
31 WDEV_ATTR_RECONF,
32 WDEV_ATTR_SERIALIZE,
33 __WDEV_ATTR_MAX,
34 };
35
36 static const struct blobmsg_policy wdev_policy[__WDEV_ATTR_MAX] = {
37 [WDEV_ATTR_DISABLED] = { .name = "disabled", .type = BLOBMSG_TYPE_BOOL },
38 [WDEV_ATTR_RECONF] = { .name = "reconf", .type = BLOBMSG_TYPE_BOOL },
39 [WDEV_ATTR_SERIALIZE] = { .name = "serialize", .type = BLOBMSG_TYPE_BOOL },
40 };
41
42 static const struct uci_blob_param_list wdev_param = {
43 .n_params = ARRAY_SIZE(wdev_policy),
44 .params = wdev_policy,
45 };
46
47 enum {
48 VIF_ATTR_DISABLED,
49 VIF_ATTR_NETWORK,
50 VIF_ATTR_ISOLATE,
51 VIF_ATTR_MODE,
52 __VIF_ATTR_MAX,
53 };
54
55 static const struct blobmsg_policy vif_policy[__VIF_ATTR_MAX] = {
56 [VIF_ATTR_DISABLED] = { .name = "disabled", .type = BLOBMSG_TYPE_BOOL },
57 [VIF_ATTR_NETWORK] = { .name = "network", .type = BLOBMSG_TYPE_ARRAY },
58 [VIF_ATTR_ISOLATE] = { .name = "isolate", .type = BLOBMSG_TYPE_BOOL },
59 [VIF_ATTR_MODE] = { .name = "mode", .type = BLOBMSG_TYPE_STRING },
60 };
61
62 static const struct uci_blob_param_list vif_param = {
63 .n_params = ARRAY_SIZE(vif_policy),
64 .params = vif_policy,
65 };
66
67 enum {
68 VLAN_ATTR_DISABLED,
69 VLAN_ATTR_NETWORK,
70 VLAN_ATTR_ISOLATE,
71 __VLAN_ATTR_MAX,
72 };
73
74 static const struct blobmsg_policy vlan_policy[__VLAN_ATTR_MAX] = {
75 [VLAN_ATTR_DISABLED] = { .name = "disabled", .type = BLOBMSG_TYPE_BOOL },
76 [VLAN_ATTR_NETWORK] = { .name = "network", .type = BLOBMSG_TYPE_ARRAY },
77 [VLAN_ATTR_ISOLATE] = { .name = "isolate", .type = BLOBMSG_TYPE_BOOL },
78 };
79
80 static const struct uci_blob_param_list vlan_param = {
81 .n_params = ARRAY_SIZE(vlan_policy),
82 .params = vlan_policy,
83 };
84
85 enum {
86 STA_ATTR_DISABLED,
87 __STA_ATTR_MAX,
88 };
89
90 static const struct blobmsg_policy sta_policy[__STA_ATTR_MAX] = {
91 [STA_ATTR_DISABLED] = { .name = "disabled", .type = BLOBMSG_TYPE_BOOL },
92 };
93
94 static const struct uci_blob_param_list station_param = {
95 .n_params = ARRAY_SIZE(sta_policy),
96 .params = sta_policy,
97 };
98
99 static void
100 wireless_handler_stop(struct wireless_device *wdev)
101 {
102 if (wdev->handler_pending) {
103 wdev->handler_pending = false;
104 list_del(&wdev->handler);
105 }
106 }
107
108 static void
109 put_container(struct blob_buf *buf, struct blob_attr *attr, const char *name)
110 {
111 void *c = blobmsg_open_table(buf, name);
112 blob_put_raw(buf, blob_data(attr), blob_len(attr));
113 blobmsg_close_table(buf, c);
114 }
115
116 static void
117 vif_config_add_bridge(struct blob_buf *buf, struct blob_attr *networks, bool prepare)
118 {
119 struct interface *iface;
120 struct device *dev = NULL;
121 struct blob_attr *cur;
122 const char *network;
123 int rem;
124
125 if (!networks)
126 return;
127
128 blobmsg_for_each_attr(cur, networks, rem) {
129 network = blobmsg_data(cur);
130
131 iface = vlist_find(&interfaces, network, iface, node);
132 if (!iface)
133 continue;
134
135 dev = iface->main_dev.dev;
136 if (!dev)
137 return;
138
139 if (!dev->hotplug_ops)
140 return;
141 }
142
143 if (!dev)
144 return;
145
146 if (dev->hotplug_ops && dev->hotplug_ops->prepare)
147 dev->hotplug_ops->prepare(dev, &dev);
148
149 if (!dev || !dev->type->bridge_capability)
150 return;
151
152 blobmsg_add_string(buf, "bridge", dev->ifname);
153
154 if (dev->settings.flags & DEV_OPT_MULTICAST_TO_UNICAST)
155 blobmsg_add_u8(buf, "multicast_to_unicast",
156 dev->settings.multicast_to_unicast);
157 }
158
159 static void
160 prepare_config(struct wireless_device *wdev, struct blob_buf *buf, bool up)
161 {
162 struct wireless_interface *vif;
163 struct wireless_vlan *vlan;
164 struct wireless_station *sta;
165 void *l, *i, *j, *k;
166
167 blob_buf_init(&b, 0);
168 put_container(&b, wdev->config, "config");
169 if (wdev->data)
170 blobmsg_add_blob(&b, wdev->data);
171
172 l = blobmsg_open_table(&b, "interfaces");
173 vlist_for_each_element(&wdev->interfaces, vif, node) {
174 i = blobmsg_open_table(&b, vif->name);
175 vif_config_add_bridge(&b, vif->network, up);
176 put_container(&b, vif->config, "config");
177 if (vif->data)
178 blobmsg_add_blob(&b, vif->data);
179
180 j = blobmsg_open_table(&b, "vlans");
181 vlist_for_each_element(&wdev->vlans, vlan, node) {
182 if (strcmp(vlan->vif, vif->name))
183 continue;
184 k = blobmsg_open_table(&b, vlan->name);
185 vif_config_add_bridge(&b, vlan->network, up);
186 put_container(&b, vlan->config, "config");
187 if (vlan->data)
188 blobmsg_add_blob(&b, vlan->data);
189 blobmsg_close_table(&b, k);
190 }
191 blobmsg_close_table(&b, j);
192
193 j = blobmsg_open_table(&b, "stas");
194 vlist_for_each_element(&wdev->stations, sta, node) {
195 if (strcmp(sta->vif, vif->name))
196 continue;
197 k = blobmsg_open_table(&b, sta->name);
198 put_container(&b, sta->config, "config");
199 if (sta->data)
200 blobmsg_add_blob(&b, sta->data);
201 blobmsg_close_table(&b, k);
202 }
203 blobmsg_close_table(&b, j);
204 blobmsg_close_table(&b, i);
205 }
206 blobmsg_close_table(&b, l);
207
208 }
209
210 static bool
211 wireless_process_check(struct wireless_process *proc)
212 {
213 return check_pid_path(proc->pid, proc->exe);
214 }
215
216 static void
217 wireless_complete_kill_request(struct wireless_device *wdev)
218 {
219 if (!wdev->kill_request)
220 return;
221
222 ubus_complete_deferred_request(ubus_ctx, wdev->kill_request, 0);
223 free(wdev->kill_request);
224 wdev->kill_request = NULL;
225 }
226
227 static void
228 wireless_process_free(struct wireless_device *wdev, struct wireless_process *proc)
229 {
230 D(WIRELESS, "Wireless device '%s' free pid %d\n", wdev->name, proc->pid);
231 list_del(&proc->list);
232 free(proc);
233
234 if (list_empty(&wdev->script_proc))
235 wireless_complete_kill_request(wdev);
236 }
237
238 static void
239 wireless_close_script_proc_fd(struct wireless_device *wdev)
240 {
241 if (wdev->script_proc_fd.fd < 0)
242 return;
243
244 uloop_fd_delete(&wdev->script_proc_fd);
245 close(wdev->script_proc_fd.fd);
246 wdev->script_proc_fd.fd = -1;
247 }
248
249 static void
250 wireless_process_kill_all(struct wireless_device *wdev, int signal, bool free)
251 {
252 struct wireless_process *proc, *tmp;
253
254 list_for_each_entry_safe(proc, tmp, &wdev->script_proc, list) {
255 bool check = wireless_process_check(proc);
256
257 if (check && !proc->keep) {
258 D(WIRELESS, "Wireless device '%s' kill pid %d\n", wdev->name, proc->pid);
259 kill(proc->pid, signal);
260 }
261
262 if (free || !check)
263 wireless_process_free(wdev, proc);
264 }
265
266 if (free)
267 wireless_close_script_proc_fd(wdev);
268 }
269
270 static void
271 wireless_device_free_state(struct wireless_device *wdev)
272 {
273 struct wireless_interface *vif;
274 struct wireless_vlan *vlan;
275 struct wireless_station *sta;
276
277 wireless_handler_stop(wdev);
278 uloop_timeout_cancel(&wdev->script_check);
279 uloop_timeout_cancel(&wdev->timeout);
280 wireless_complete_kill_request(wdev);
281 free(wdev->data);
282 wdev->data = NULL;
283 vlist_for_each_element(&wdev->interfaces, vif, node) {
284 free(vif->data);
285 vif->data = NULL;
286 vif->ifname = NULL;
287 }
288 vlist_for_each_element(&wdev->vlans, vlan, node) {
289 free(vlan->data);
290 vlan->data = NULL;
291 vlan->ifname = NULL;
292 }
293 vlist_for_each_element(&wdev->stations, sta, node) {
294 free(sta->data);
295 sta->data = NULL;
296 }
297 }
298
299 static void wireless_interface_handle_link(struct wireless_interface *vif, bool up)
300 {
301 struct interface *iface;
302 struct blob_attr *cur;
303 const char *network;
304 int rem;
305
306 if (!vif->network || !vif->ifname)
307 return;
308
309 if (up) {
310 struct device *dev = device_get(vif->ifname, 2);
311 if (dev) {
312 dev->wireless_isolate = vif->isolate;
313 dev->wireless = true;
314 dev->wireless_ap = vif->ap_mode;
315 }
316 }
317
318 blobmsg_for_each_attr(cur, vif->network, rem) {
319 network = blobmsg_data(cur);
320
321 iface = vlist_find(&interfaces, network, iface, node);
322 if (!iface)
323 continue;
324
325 interface_handle_link(iface, vif->ifname, NULL, up, true);
326 }
327 }
328
329 static void wireless_vlan_handle_link(struct wireless_vlan *vlan, bool up)
330 {
331 struct interface *iface;
332 struct blob_attr *cur;
333 const char *network;
334 int rem;
335
336 if (!vlan->network || !vlan->ifname)
337 return;
338
339 if (up) {
340 struct device *dev = device_get(vlan->ifname, 2);
341 if (dev) {
342 dev->wireless_isolate = vlan->isolate;
343 dev->wireless = true;
344 dev->wireless_ap = true;
345 }
346 }
347
348 blobmsg_for_each_attr(cur, vlan->network, rem) {
349 network = blobmsg_data(cur);
350
351 iface = vlist_find(&interfaces, network, iface, node);
352 if (!iface)
353 continue;
354
355 interface_handle_link(iface, vlan->ifname, NULL, up, true);
356 }
357 }
358
359 static void
360 wireless_device_setup_cancel(struct wireless_device *wdev)
361 {
362 if (wdev->cancel)
363 return;
364
365 wireless_handler_stop(wdev);
366 D(WIRELESS, "Cancel wireless device '%s' setup\n", wdev->name);
367 wdev->cancel = true;
368 uloop_timeout_set(&wdev->timeout, 10 * 1000);
369 }
370
371 static void
372 wireless_device_run_handler(struct wireless_device *wdev, bool up)
373 {
374 const char *action = up ? "setup" : "teardown";
375 const char *argv[6];
376 char *config;
377 int i = 0;
378 int fds[2] = { -1, -1 };
379
380 wireless_handler_stop(wdev);
381
382 if (handler_pending && wdev->serialize) {
383 wdev->handler_action = up;
384 wdev->handler_pending = true;
385 list_add_tail(&wdev->handler, &handlers);
386 return;
387 }
388 if (wdev->serialize)
389 handler_pending = true;
390
391 D(WIRELESS, "Wireless device '%s' run %s handler\n", wdev->name, action);
392 if (!up && wdev->prev_config) {
393 config = blobmsg_format_json(wdev->prev_config, true);
394 free(wdev->prev_config);
395 wdev->prev_config = NULL;
396 } else {
397 prepare_config(wdev, &b, up);
398 config = blobmsg_format_json(b.head, true);
399 }
400
401 argv[i++] = wdev->drv->script;
402 argv[i++] = wdev->drv->name;
403 argv[i++] = action;
404 argv[i++] = wdev->name;
405 argv[i++] = config;
406 argv[i] = NULL;
407
408 if (up && pipe(fds) == 0) {
409 wdev->script_proc_fd.fd = fds[0];
410 uloop_fd_add(&wdev->script_proc_fd,
411 ULOOP_READ | ULOOP_EDGE_TRIGGER);
412 }
413
414 netifd_start_process(argv, NULL, &wdev->script_task);
415
416 if (fds[1] >= 0)
417 close(fds[1]);
418
419 free(config);
420 }
421
422 static void
423 wireless_handler_next(void)
424 {
425 struct wireless_device *wdev;
426
427 if (handler_pending)
428 return;
429 if (list_empty(&handlers))
430 return;
431 wdev = list_first_entry(&handlers, struct wireless_device, handler);
432 list_del(&wdev->handler);
433 wdev->handler_pending = false;
434 wireless_device_run_handler(wdev, wdev->handler_action);
435 }
436
437 static void
438 __wireless_device_set_up(struct wireless_device *wdev, int force)
439 {
440 if (wdev->disabled)
441 return;
442
443 if (wdev->retry_setup_failed)
444 return;
445
446 if (!wdev->autostart)
447 return;
448
449 if (!force && (wdev->state != IFS_DOWN || config_init))
450 return;
451
452 free(wdev->prev_config);
453 wdev->prev_config = NULL;
454 wdev->state = IFS_SETUP;
455 wireless_device_run_handler(wdev, true);
456 }
457
458 static void
459 wireless_device_free(struct wireless_device *wdev)
460 {
461 wireless_handler_stop(wdev);
462 vlist_flush_all(&wdev->interfaces);
463 vlist_flush_all(&wdev->vlans);
464 vlist_flush_all(&wdev->stations);
465 avl_delete(&wireless_devices.avl, &wdev->node.avl);
466 free(wdev->config);
467 free(wdev->prev_config);
468 free(wdev);
469 }
470
471 static void
472 wdev_handle_config_change(struct wireless_device *wdev)
473 {
474 enum interface_config_state state = wdev->config_state;
475
476 switch(state) {
477 case IFC_NORMAL:
478 case IFC_RELOAD:
479 __wireless_device_set_up(wdev, 0);
480
481 wdev->config_state = IFC_NORMAL;
482 break;
483 case IFC_REMOVE:
484 wireless_device_free(wdev);
485 break;
486 }
487 }
488
489 static void
490 wireless_device_mark_down(struct wireless_device *wdev)
491 {
492 struct wireless_interface *vif;
493 struct wireless_vlan *vlan;
494
495 D(WIRELESS, "Wireless device '%s' is now down\n", wdev->name);
496
497 vlist_for_each_element(&wdev->vlans, vlan, node)
498 wireless_vlan_handle_link(vlan, false);
499
500 vlist_for_each_element(&wdev->interfaces, vif, node)
501 wireless_interface_handle_link(vif, false);
502
503 wireless_process_kill_all(wdev, SIGTERM, true);
504
505 wdev->cancel = false;
506 wdev->state = IFS_DOWN;
507 wireless_device_free_state(wdev);
508 wdev_handle_config_change(wdev);
509 }
510
511 static void
512 wireless_device_setup_timeout(struct uloop_timeout *timeout)
513 {
514 struct wireless_device *wdev = container_of(timeout, struct wireless_device, timeout);
515
516 if (wdev->handler_pending) {
517 wdev->handler_pending = false;
518 list_del(&wdev->handler);
519 }
520 netifd_kill_process(&wdev->script_task);
521 wdev->script_task.cb(&wdev->script_task, -1);
522 wireless_device_mark_down(wdev);
523 }
524
525 void
526 wireless_device_set_up(struct wireless_device *wdev)
527 {
528 wdev->retry = WIRELESS_SETUP_RETRY;
529 wdev->autostart = true;
530 __wireless_device_set_up(wdev, 0);
531 }
532
533 void
534 wireless_device_reconf(struct wireless_device *wdev)
535 {
536 wdev->retry = WIRELESS_SETUP_RETRY;
537 wdev->autostart = true;
538 __wireless_device_set_up(wdev, wdev->reconf && (wdev->state == IFS_UP));
539 }
540
541 static void
542 __wireless_device_set_down(struct wireless_device *wdev)
543 {
544 if (wdev->state == IFS_TEARDOWN || wdev->state == IFS_DOWN)
545 return;
546
547 if (wdev->script_task.uloop.pending) {
548 wireless_device_setup_cancel(wdev);
549 return;
550 }
551
552 wdev->state = IFS_TEARDOWN;
553 wireless_device_run_handler(wdev, false);
554 }
555
556 static void
557 wireless_device_mark_up(struct wireless_device *wdev)
558 {
559 struct wireless_interface *vif;
560 struct wireless_vlan *vlan;
561
562 if (wdev->cancel) {
563 wdev->cancel = false;
564 __wireless_device_set_down(wdev);
565 return;
566 }
567
568 D(WIRELESS, "Wireless device '%s' is now up\n", wdev->name);
569 wdev->state = IFS_UP;
570 vlist_for_each_element(&wdev->interfaces, vif, node)
571 wireless_interface_handle_link(vif, true);
572 vlist_for_each_element(&wdev->vlans, vlan, node)
573 wireless_vlan_handle_link(vlan, true);
574 }
575
576 static void
577 wireless_device_retry_setup(struct wireless_device *wdev)
578 {
579 if (wdev->state == IFS_TEARDOWN || wdev->state == IFS_DOWN || wdev->cancel)
580 return;
581
582 if (--wdev->retry < 0)
583 wdev->retry_setup_failed = true;
584
585 __wireless_device_set_down(wdev);
586 }
587
588 static void
589 wireless_device_script_task_cb(struct netifd_process *proc, int ret)
590 {
591 struct wireless_device *wdev = container_of(proc, struct wireless_device, script_task);
592
593 switch (wdev->state) {
594 case IFS_SETUP:
595 wireless_device_retry_setup(wdev);
596 break;
597 case IFS_TEARDOWN:
598 wireless_device_mark_down(wdev);
599 break;
600 default:
601 break;
602 }
603
604 if (wdev->serialize) {
605 handler_pending = false;
606 wireless_handler_next();
607 }
608 }
609
610 void
611 wireless_device_set_down(struct wireless_device *wdev)
612 {
613 wdev->retry_setup_failed = false;
614 wdev->autostart = false;
615 __wireless_device_set_down(wdev);
616 }
617
618 static void
619 wdev_set_config_state(struct wireless_device *wdev, enum interface_config_state s)
620 {
621 if (wdev->config_state != IFC_NORMAL)
622 return;
623
624 wdev->config_state = s;
625 if (wdev->state == IFS_DOWN)
626 wdev_handle_config_change(wdev);
627 else if (!wdev->reconf || wdev->state != IFS_UP)
628 __wireless_device_set_down(wdev);
629 }
630
631 static void
632 wdev_prepare_prev_config(struct wireless_device *wdev)
633 {
634 if (wdev->prev_config)
635 return;
636
637 prepare_config(wdev, &b, false);
638 wdev->prev_config = blob_memdup(b.head);
639 }
640
641 static void
642 wdev_change_config(struct wireless_device *wdev, struct wireless_device *wd_new)
643 {
644 struct blob_attr *new_config = wd_new->config;
645 bool disabled = wd_new->disabled;
646
647 free(wd_new);
648
649 wdev_prepare_prev_config(wdev);
650 if (blob_attr_equal(wdev->config, new_config) && wdev->disabled == disabled)
651 return;
652
653 D(WIRELESS, "Update configuration of wireless device '%s'\n", wdev->name);
654 free(wdev->config);
655 wdev->config = blob_memdup(new_config);
656 wdev->disabled = disabled;
657 wdev->retry_setup_failed = false;
658 wdev_set_config_state(wdev, IFC_RELOAD);
659 }
660
661 static void
662 wdev_create(struct wireless_device *wdev)
663 {
664 wdev->retry = WIRELESS_SETUP_RETRY;
665 wdev->config = blob_memdup(wdev->config);
666 }
667
668 static void
669 wdev_update(struct vlist_tree *tree, struct vlist_node *node_new,
670 struct vlist_node *node_old)
671 {
672 struct wireless_device *wd_old = container_of(node_old, struct wireless_device, node);
673 struct wireless_device *wd_new = container_of(node_new, struct wireless_device, node);
674
675 if (wd_old && wd_new) {
676 D(WIRELESS, "Update wireless device '%s'\n", wd_old->name);
677 wdev_change_config(wd_old, wd_new);
678 } else if (wd_old) {
679 D(WIRELESS, "Delete wireless device '%s'\n", wd_old->name);
680 wdev_set_config_state(wd_old, IFC_REMOVE);
681 } else if (wd_new) {
682 D(WIRELESS, "Create wireless device '%s'\n", wd_new->name);
683 wdev_create(wd_new);
684 }
685 }
686
687 static void
688 wireless_add_handler(const char *script, const char *name, json_object *obj)
689 {
690 struct wireless_driver *drv;
691 char *name_str, *script_str;
692 json_object *dev_config_obj, *iface_config_obj, *vlan_config_obj, *station_config_obj;
693 struct uci_blob_param_list *dev_config, *iface_config, *vlan_config, *station_config;
694
695 dev_config_obj = json_get_field(obj, "device", json_type_array);
696 iface_config_obj = json_get_field(obj, "iface", json_type_array);
697 vlan_config_obj = json_get_field(obj, "vlan", json_type_array);
698 station_config_obj = json_get_field(obj, "station", json_type_array);
699
700 if (!dev_config_obj || !iface_config_obj || !vlan_config_obj || !station_config_obj)
701 return;
702
703 drv = calloc_a(sizeof(*drv),
704 &dev_config, sizeof(*dev_config) + sizeof(void *),
705 &iface_config, sizeof(*iface_config) + sizeof(void *),
706 &vlan_config, sizeof(*vlan_config) + sizeof(void *),
707 &station_config, sizeof(*station_config) + sizeof(void *),
708 &name_str, strlen(name) + 1,
709 &script_str, strlen(script) + 1);
710
711 drv->name = strcpy(name_str, name);
712 drv->script = strcpy(script_str, script);
713
714 dev_config->n_next = 1;
715 dev_config->next[0] = &wdev_param;
716 drv->device.config = dev_config;
717
718 iface_config->n_next = 1;
719 iface_config->next[0] = &vif_param;
720 drv->interface.config = iface_config;
721
722 vlan_config->n_next = 1;
723 vlan_config->next[0] = &vlan_param;
724 drv->vlan.config = vlan_config;
725
726 station_config->n_next = 1;
727 station_config->next[0] = &station_param;
728 drv->station.config = station_config;
729
730 drv->device.buf = netifd_handler_parse_config(drv->device.config, dev_config_obj);
731 drv->interface.buf = netifd_handler_parse_config(drv->interface.config, iface_config_obj);
732 drv->vlan.buf = netifd_handler_parse_config(drv->vlan.config, vlan_config_obj);
733 drv->station.buf = netifd_handler_parse_config(drv->station.config, station_config_obj);
734
735 drv->node.key = drv->name;
736 avl_insert(&wireless_drivers, &drv->node);
737 D(WIRELESS, "Add handler for script %s: %s\n", script, name);
738 }
739
740 void wireless_init(void)
741 {
742 vlist_init(&wireless_devices, avl_strcmp, wdev_update);
743 wireless_devices.keep_old = true;
744 wireless_devices.no_delete = true;
745
746 avl_init(&wireless_drivers, avl_strcmp, false, NULL);
747 drv_fd = netifd_open_subdir("wireless");
748 if (drv_fd < 0)
749 return;
750
751 netifd_init_script_handlers(drv_fd, wireless_add_handler);
752 }
753
754 static void
755 wireless_interface_init_config(struct wireless_interface *vif)
756 {
757 struct blob_attr *tb[__VIF_ATTR_MAX];
758 struct blob_attr *cur;
759
760 vif->network = NULL;
761 blobmsg_parse(vif_policy, __VIF_ATTR_MAX, tb, blob_data(vif->config), blob_len(vif->config));
762
763 if ((cur = tb[VIF_ATTR_NETWORK]))
764 vif->network = cur;
765
766 cur = tb[VIF_ATTR_ISOLATE];
767 if (cur)
768 vif->isolate = blobmsg_get_bool(cur);
769
770 cur = tb[VIF_ATTR_MODE];
771 if (cur)
772 vif->ap_mode = !strcmp(blobmsg_get_string(cur), "ap");
773 }
774
775 static void
776 vif_update(struct vlist_tree *tree, struct vlist_node *node_new,
777 struct vlist_node *node_old)
778 {
779 struct wireless_interface *vif_old = container_of(node_old, struct wireless_interface, node);
780 struct wireless_interface *vif_new = container_of(node_new, struct wireless_interface, node);
781 struct wireless_device *wdev;
782
783 if (vif_old)
784 wdev = vif_old->wdev;
785 else
786 wdev = vif_new->wdev;
787
788 if (vif_old && vif_new) {
789 free((void *) vif_old->section);
790 vif_old->section = strdup(vif_new->section);
791 if (blob_attr_equal(vif_old->config, vif_new->config)) {
792 free(vif_new);
793 return;
794 }
795
796 D(WIRELESS, "Update wireless interface %s on device %s\n", vif_new->name, wdev->name);
797 wireless_interface_handle_link(vif_old, false);
798 free(vif_old->config);
799 vif_old->config = blob_memdup(vif_new->config);
800 vif_old->isolate = vif_new->isolate;
801 vif_old->ap_mode = vif_new->ap_mode;
802 wireless_interface_init_config(vif_old);
803 free(vif_new);
804 } else if (vif_new) {
805 D(WIRELESS, "Create new wireless interface %s on device %s\n", vif_new->name, wdev->name);
806 vif_new->section = strdup(vif_new->section);
807 vif_new->config = blob_memdup(vif_new->config);
808 wireless_interface_init_config(vif_new);
809 } else if (vif_old) {
810 D(WIRELESS, "Delete wireless interface %s on device %s\n", vif_old->name, wdev->name);
811 wireless_interface_handle_link(vif_old, false);
812 free((void *) vif_old->section);
813 free(vif_old->config);
814 free(vif_old);
815 }
816
817 wdev_set_config_state(wdev, IFC_RELOAD);
818 }
819
820 static void
821 wireless_vlan_init_config(struct wireless_vlan *vlan)
822 {
823 struct blob_attr *tb[__VLAN_ATTR_MAX];
824 struct blob_attr *cur;
825
826 vlan->network = NULL;
827 blobmsg_parse(vlan_policy, __VLAN_ATTR_MAX, tb, blob_data(vlan->config), blob_len(vlan->config));
828
829 if ((cur = tb[VLAN_ATTR_NETWORK]))
830 vlan->network = cur;
831
832 cur = tb[VLAN_ATTR_ISOLATE];
833 if (cur)
834 vlan->isolate = blobmsg_get_bool(cur);
835 }
836
837 static void
838 vlan_update(struct vlist_tree *tree, struct vlist_node *node_new,
839 struct vlist_node *node_old)
840 {
841 struct wireless_vlan *vlan_old = container_of(node_old, struct wireless_vlan, node);
842 struct wireless_vlan *vlan_new = container_of(node_new, struct wireless_vlan, node);
843 struct wireless_device *wdev;
844
845 if (vlan_old)
846 wdev = vlan_old->wdev;
847 else
848 wdev = vlan_new->wdev;
849
850 if (vlan_old && vlan_new) {
851 free((void *) vlan_old->section);
852 vlan_old->section = strdup(vlan_new->section);
853 if (blob_attr_equal(vlan_old->config, vlan_new->config)) {
854 free(vlan_new);
855 return;
856 }
857
858 D(WIRELESS, "Update wireless vlan %s on device %s\n", vlan_new->name, wdev->name);
859 wireless_vlan_handle_link(vlan_old, false);
860 free(vlan_old->config);
861 vlan_old->config = blob_memdup(vlan_new->config);
862 vlan_old->isolate = vlan_new->isolate;
863 wireless_vlan_init_config(vlan_old);
864 free(vlan_new);
865 } else if (vlan_new) {
866 D(WIRELESS, "Create new wireless vlan %s on device %s\n", vlan_new->name, wdev->name);
867 vlan_new->section = strdup(vlan_new->section);
868 vlan_new->config = blob_memdup(vlan_new->config);
869 wireless_vlan_init_config(vlan_new);
870 } else if (vlan_old) {
871 D(WIRELESS, "Delete wireless interface %s on device %s\n", vlan_old->name, wdev->name);
872 wireless_vlan_handle_link(vlan_old, false);
873 free((void *) vlan_old->section);
874 free(vlan_old->config);
875 free(vlan_old);
876 }
877
878 wdev_set_config_state(wdev, IFC_RELOAD);
879 }
880
881 static void
882 station_update(struct vlist_tree *tree, struct vlist_node *node_new,
883 struct vlist_node *node_old)
884 {
885 struct wireless_station *sta_old = container_of(node_old, struct wireless_station, node);
886 struct wireless_station *sta_new = container_of(node_new, struct wireless_station, node);
887 struct wireless_device *wdev;
888
889 if (sta_old)
890 wdev = sta_old->wdev;
891 else
892 wdev = sta_new->wdev;
893
894 if (sta_old && sta_new) {
895 free((void *) sta_old->section);
896 sta_old->section = strdup(sta_new->section);
897 if (blob_attr_equal(sta_old->config, sta_new->config)) {
898 free(sta_new);
899 return;
900 }
901
902 D(WIRELESS, "Update wireless station %s on device %s\n", sta_new->name, wdev->name);
903 free(sta_old->config);
904 sta_old->config = blob_memdup(sta_new->config);
905 free(sta_new);
906 } else if (sta_new) {
907 D(WIRELESS, "Create new wireless station %s on device %s\n", sta_new->name, wdev->name);
908 sta_new->section = strdup(sta_new->section);
909 sta_new->config = blob_memdup(sta_new->config);
910 } else if (sta_old) {
911 D(WIRELESS, "Delete wireless station %s on device %s\n", sta_old->name, wdev->name);
912 free((void *) sta_old->section);
913 free(sta_old->config);
914 free(sta_old);
915 }
916
917 wdev_set_config_state(wdev, IFC_RELOAD);
918 }
919
920 static void
921 wireless_proc_poll_fd(struct uloop_fd *fd, unsigned int events)
922 {
923 struct wireless_device *wdev = container_of(fd, struct wireless_device, script_proc_fd);
924 char buf[128];
925
926 while (1) {
927 int b = read(fd->fd, buf, sizeof(buf));
928 if (b < 0) {
929 if (errno == EINTR)
930 continue;
931
932 if (errno == EAGAIN)
933 return;
934
935 goto done;
936 }
937
938 if (!b)
939 goto done;
940 }
941
942 done:
943 uloop_timeout_set(&wdev->script_check, 0);
944 wireless_close_script_proc_fd(wdev);
945 }
946
947 static void
948 wireless_device_check_script_tasks(struct uloop_timeout *timeout)
949 {
950 struct wireless_device *wdev = container_of(timeout, struct wireless_device, script_check);
951 struct wireless_process *proc, *tmp;
952 bool restart = false;
953
954 list_for_each_entry_safe(proc, tmp, &wdev->script_proc, list) {
955 if (wireless_process_check(proc))
956 continue;
957
958 D(WIRELESS, "Wireless device '%s' pid %d has terminated\n", wdev->name, proc->pid);
959 if (proc->required)
960 restart = true;
961
962 wireless_process_free(wdev, proc);
963 }
964
965 if (restart)
966 wireless_device_retry_setup(wdev);
967 else
968 uloop_timeout_set(&wdev->script_check, 1000);
969 }
970
971 void
972 wireless_device_create(struct wireless_driver *drv, const char *name, struct blob_attr *data)
973 {
974 struct wireless_device *wdev;
975 char *name_buf;
976 struct blob_attr *tb[__WDEV_ATTR_MAX];
977 struct blob_attr *cur;
978
979 blobmsg_parse(wdev_policy, __WDEV_ATTR_MAX, tb, blob_data(data), blob_len(data));
980
981 wdev = calloc_a(sizeof(*wdev), &name_buf, strlen(name) + 1);
982
983 cur = tb[WDEV_ATTR_DISABLED];
984 wdev->disabled = cur && blobmsg_get_bool(cur);
985
986 wdev->drv = drv;
987 wdev->state = IFS_DOWN;
988 wdev->config_state = IFC_NORMAL;
989 wdev->name = strcpy(name_buf, name);
990 wdev->config = data;
991 wdev->handler_pending = false;
992
993 cur = tb[WDEV_ATTR_SERIALIZE];
994 wdev->serialize = cur && blobmsg_get_bool(cur);
995
996 cur = tb[WDEV_ATTR_RECONF];
997 wdev->reconf = cur && blobmsg_get_bool(cur);
998
999 wdev->retry_setup_failed = false;
1000 wdev->autostart = true;
1001 INIT_LIST_HEAD(&wdev->script_proc);
1002 vlist_init(&wdev->interfaces, avl_strcmp, vif_update);
1003 wdev->interfaces.keep_old = true;
1004 vlist_init(&wdev->vlans, avl_strcmp, vlan_update);
1005 wdev->vlans.keep_old = true;
1006 vlist_init(&wdev->stations, avl_strcmp, station_update);
1007 wdev->stations.keep_old = true;
1008
1009 wdev->timeout.cb = wireless_device_setup_timeout;
1010 wdev->script_task.cb = wireless_device_script_task_cb;
1011 wdev->script_task.dir_fd = drv_fd;
1012 wdev->script_task.log_prefix = wdev->name;
1013
1014 wdev->script_proc_fd.fd = -1;
1015 wdev->script_proc_fd.cb = wireless_proc_poll_fd;
1016
1017 wdev->script_check.cb = wireless_device_check_script_tasks;
1018
1019 vlist_add(&wireless_devices, &wdev->node, wdev->name);
1020 }
1021
1022 void
1023 wireless_station_create(struct wireless_device *wdev, char *vif, struct blob_attr *data, const char *section)
1024 {
1025 struct wireless_station *sta;
1026 struct blob_attr *tb[__STA_ATTR_MAX];
1027 struct blob_attr *cur;
1028 char *name_buf, *vif_buf;
1029 char name[8];
1030
1031 blobmsg_parse(sta_policy, __STA_ATTR_MAX, tb, blob_data(data), blob_len(data));
1032
1033 cur = tb[STA_ATTR_DISABLED];
1034 if (cur && blobmsg_get_bool(cur))
1035 return;
1036
1037 sprintf(name, "%d", wdev->vlan_idx++);
1038
1039 sta = calloc_a(sizeof(*sta),
1040 &name_buf, strlen(name) + 1,
1041 &vif_buf, strlen(vif) + 1);
1042 sta->name = strcpy(name_buf, name);
1043 sta->vif = strcpy(vif_buf, vif);
1044 sta->wdev = wdev;
1045 sta->config = data;
1046 sta->section = section;
1047
1048 vlist_add(&wdev->stations, &sta->node, sta->name);
1049 }
1050
1051 static void
1052 wireless_station_status(struct wireless_station *sta, struct blob_buf *b)
1053 {
1054 void *i;
1055
1056 i = blobmsg_open_table(b, NULL);
1057 if (sta->section)
1058 blobmsg_add_string(b, "section", sta->section);
1059 put_container(b, sta->config, "config");
1060 blobmsg_close_table(b, i);
1061 }
1062
1063 void
1064 wireless_vlan_create(struct wireless_device *wdev, char *vif, struct blob_attr *data, const char *section)
1065 {
1066 struct wireless_vlan *vlan;
1067 struct blob_attr *tb[__VLAN_ATTR_MAX];
1068 struct blob_attr *cur;
1069 char *name_buf, *vif_buf;
1070 char name[8];
1071
1072 blobmsg_parse(vlan_policy, __VLAN_ATTR_MAX, tb, blob_data(data), blob_len(data));
1073
1074 cur = tb[VLAN_ATTR_DISABLED];
1075 if (cur && blobmsg_get_bool(cur))
1076 return;
1077
1078 sprintf(name, "%d", wdev->vlan_idx++);
1079
1080 vlan = calloc_a(sizeof(*vlan),
1081 &name_buf, strlen(name) + 1,
1082 &vif_buf, strlen(vif) + 1);
1083 vlan->name = strcpy(name_buf, name);
1084 vlan->vif = strcpy(vif_buf, vif);
1085 vlan->wdev = wdev;
1086 vlan->config = data;
1087 vlan->section = section;
1088 vlan->isolate = false;
1089
1090 vlist_add(&wdev->vlans, &vlan->node, vlan->name);
1091 }
1092
1093 static void
1094 wireless_vlan_status(struct wireless_vlan *vlan, struct blob_buf *b)
1095 {
1096 void *i;
1097
1098 i = blobmsg_open_table(b, NULL);
1099 if (vlan->section)
1100 blobmsg_add_string(b, "section", vlan->section);
1101 if (vlan->ifname)
1102 blobmsg_add_string(b, "ifname", vlan->ifname);
1103 put_container(b, vlan->config, "config");
1104 blobmsg_close_table(b, i);
1105 }
1106
1107 struct wireless_interface* wireless_interface_create(struct wireless_device *wdev, struct blob_attr *data, const char *section)
1108 {
1109 struct wireless_interface *vif;
1110 struct blob_attr *tb[__VIF_ATTR_MAX];
1111 struct blob_attr *cur;
1112 char *name_buf;
1113 char name[8];
1114
1115 blobmsg_parse(vif_policy, __VIF_ATTR_MAX, tb, blob_data(data), blob_len(data));
1116
1117 cur = tb[VIF_ATTR_DISABLED];
1118 if (cur && blobmsg_get_bool(cur))
1119 return NULL;
1120
1121 sprintf(name, "%d", wdev->vif_idx++);
1122
1123 vif = calloc_a(sizeof(*vif),
1124 &name_buf, strlen(name) + 1);
1125 vif->name = strcpy(name_buf, name);
1126 vif->wdev = wdev;
1127 vif->config = data;
1128 vif->section = section;
1129 vif->isolate = false;
1130
1131 vlist_add(&wdev->interfaces, &vif->node, vif->name);
1132
1133 return vlist_find(&wdev->interfaces, name, vif, node);
1134 }
1135
1136 static void
1137 wireless_interface_status(struct wireless_interface *iface, struct blob_buf *b)
1138 {
1139 struct wireless_vlan *vlan;
1140 struct wireless_station *sta;
1141 void *i, *j;
1142
1143 i = blobmsg_open_table(b, NULL);
1144 if (iface->section)
1145 blobmsg_add_string(b, "section", iface->section);
1146 if (iface->ifname)
1147 blobmsg_add_string(b, "ifname", iface->ifname);
1148 put_container(b, iface->config, "config");
1149 j = blobmsg_open_array(b, "vlans");
1150 vlist_for_each_element(&iface->wdev->vlans, vlan, node)
1151 if (!strcmp(iface->name, vlan->vif))
1152 wireless_vlan_status(vlan, b);
1153 blobmsg_close_array(b, j);
1154 j = blobmsg_open_array(b, "stations");
1155 vlist_for_each_element(&iface->wdev->stations, sta, node)
1156 if (!strcmp(iface->name, sta->vif))
1157 wireless_station_status(sta, b);
1158 blobmsg_close_array(b, j);
1159 blobmsg_close_table(b, i);
1160 }
1161
1162 void
1163 wireless_device_status(struct wireless_device *wdev, struct blob_buf *b)
1164 {
1165 struct wireless_interface *iface;
1166 void *c, *i;
1167
1168 c = blobmsg_open_table(b, wdev->name);
1169 blobmsg_add_u8(b, "up", wdev->state == IFS_UP);
1170 blobmsg_add_u8(b, "pending", wdev->state == IFS_SETUP || wdev->state == IFS_TEARDOWN);
1171 blobmsg_add_u8(b, "autostart", wdev->autostart);
1172 blobmsg_add_u8(b, "disabled", wdev->disabled);
1173 blobmsg_add_u8(b, "retry_setup_failed", wdev->retry_setup_failed);
1174 put_container(b, wdev->config, "config");
1175
1176 i = blobmsg_open_array(b, "interfaces");
1177 vlist_for_each_element(&wdev->interfaces, iface, node)
1178 wireless_interface_status(iface, b);
1179 blobmsg_close_array(b, i);
1180 blobmsg_close_table(b, c);
1181 }
1182
1183 void
1184 wireless_device_get_validate(struct wireless_device *wdev, struct blob_buf *b)
1185 {
1186 struct uci_blob_param_list *p;
1187 void *c, *d;
1188 int i;
1189
1190 c = blobmsg_open_table(b, wdev->name);
1191
1192 d = blobmsg_open_table(b, "device");
1193 p = wdev->drv->device.config;
1194 for (i = 0; i < p->n_params; i++)
1195 blobmsg_add_string(b, p->params[i].name, uci_get_validate_string(p, i));
1196 blobmsg_close_table(b, d);
1197
1198 d = blobmsg_open_table(b, "interface");
1199 p = wdev->drv->interface.config;
1200 for (i = 0; i < p->n_params; i++)
1201 blobmsg_add_string(b, p->params[i].name, uci_get_validate_string(p, i));
1202 blobmsg_close_table(b, d);
1203
1204 blobmsg_close_table(b, c);
1205 }
1206
1207 static void
1208 wireless_interface_set_data(struct wireless_interface *vif)
1209 {
1210 enum {
1211 VIF_DATA_IFNAME,
1212 __VIF_DATA_MAX,
1213 };
1214 static const struct blobmsg_policy data_policy[__VIF_DATA_MAX] = {
1215 [VIF_DATA_IFNAME] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING },
1216 };
1217 struct blob_attr *tb[__VIF_DATA_MAX];
1218 struct blob_attr *cur;
1219
1220 blobmsg_parse(data_policy, __VIF_DATA_MAX, tb,
1221 blobmsg_data(vif->data), blobmsg_data_len(vif->data));
1222
1223 if ((cur = tb[VIF_DATA_IFNAME]))
1224 vif->ifname = blobmsg_data(cur);
1225 }
1226
1227 static void
1228 wireless_vlan_set_data(struct wireless_vlan *vlan)
1229 {
1230 enum {
1231 VLAN_DATA_IFNAME,
1232 __VLAN_DATA_MAX,
1233 };
1234 static const struct blobmsg_policy data_policy[__VLAN_DATA_MAX] = {
1235 [VLAN_DATA_IFNAME] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING },
1236 };
1237 struct blob_attr *tb[__VLAN_DATA_MAX];
1238 struct blob_attr *cur;
1239
1240 blobmsg_parse(data_policy, __VLAN_DATA_MAX, tb,
1241 blobmsg_data(vlan->data), blobmsg_data_len(vlan->data));
1242
1243 if ((cur = tb[VLAN_DATA_IFNAME]))
1244 vlan->ifname = blobmsg_data(cur);
1245 }
1246
1247 static int
1248 wireless_device_add_process(struct wireless_device *wdev, struct blob_attr *data)
1249 {
1250 enum {
1251 PROC_ATTR_PID,
1252 PROC_ATTR_EXE,
1253 PROC_ATTR_REQUIRED,
1254 PROC_ATTR_KEEP,
1255 __PROC_ATTR_MAX
1256 };
1257 static const struct blobmsg_policy proc_policy[__PROC_ATTR_MAX] = {
1258 [PROC_ATTR_PID] = { .name = "pid", .type = BLOBMSG_TYPE_INT32 },
1259 [PROC_ATTR_EXE] = { .name = "exe", .type = BLOBMSG_TYPE_STRING },
1260 [PROC_ATTR_REQUIRED] = { .name = "required", .type = BLOBMSG_TYPE_BOOL },
1261 [PROC_ATTR_KEEP] = { .name = "keep", .type = BLOBMSG_TYPE_BOOL },
1262 };
1263 struct blob_attr *tb[__PROC_ATTR_MAX];
1264 struct wireless_process *proc;
1265 char *name;
1266 int pid;
1267
1268 if (!data)
1269 return UBUS_STATUS_INVALID_ARGUMENT;
1270
1271 blobmsg_parse(proc_policy, __PROC_ATTR_MAX, tb, blobmsg_data(data), blobmsg_data_len(data));
1272 if (!tb[PROC_ATTR_PID] || !tb[PROC_ATTR_EXE])
1273 return UBUS_STATUS_INVALID_ARGUMENT;
1274
1275 pid = blobmsg_get_u32(tb[PROC_ATTR_PID]);
1276 if (pid < 2)
1277 return UBUS_STATUS_INVALID_ARGUMENT;
1278
1279 proc = calloc_a(sizeof(*proc),
1280 &name, strlen(blobmsg_data(tb[PROC_ATTR_EXE])) + 1);
1281
1282 proc->pid = pid;
1283 proc->exe = strcpy(name, blobmsg_data(tb[PROC_ATTR_EXE]));
1284
1285 if (tb[PROC_ATTR_REQUIRED])
1286 proc->required = blobmsg_get_bool(tb[PROC_ATTR_REQUIRED]);
1287
1288 if (tb[PROC_ATTR_KEEP])
1289 proc->keep = blobmsg_get_bool(tb[PROC_ATTR_KEEP]);
1290
1291 D(WIRELESS, "Wireless device '%s' add pid %d\n", wdev->name, proc->pid);
1292 list_add(&proc->list, &wdev->script_proc);
1293 uloop_timeout_set(&wdev->script_check, 0);
1294
1295 return 0;
1296 }
1297
1298 static int
1299 wireless_device_process_kill_all(struct wireless_device *wdev, struct blob_attr *data,
1300 struct ubus_request_data *req)
1301 {
1302 enum {
1303 KILL_ATTR_SIGNAL,
1304 KILL_ATTR_IMMEDIATE,
1305 __KILL_ATTR_MAX
1306 };
1307 static const struct blobmsg_policy kill_policy[__KILL_ATTR_MAX] = {
1308 [KILL_ATTR_SIGNAL] = { .name = "signal", .type = BLOBMSG_TYPE_INT32 },
1309 [KILL_ATTR_IMMEDIATE] = { .name = "immediate", .type = BLOBMSG_TYPE_BOOL },
1310 };
1311 struct blob_attr *tb[__KILL_ATTR_MAX];
1312 struct blob_attr *cur;
1313 bool immediate = false;
1314 int signal = SIGTERM;
1315
1316 blobmsg_parse(kill_policy, __KILL_ATTR_MAX, tb, blobmsg_data(data), blobmsg_data_len(data));
1317
1318 if ((cur = tb[KILL_ATTR_SIGNAL]))
1319 signal = blobmsg_get_u32(cur);
1320
1321 if ((cur = tb[KILL_ATTR_IMMEDIATE]))
1322 immediate = blobmsg_get_bool(cur);
1323
1324 if (wdev->state != IFS_TEARDOWN || wdev->kill_request)
1325 return UBUS_STATUS_PERMISSION_DENIED;
1326
1327 wireless_process_kill_all(wdev, signal, immediate);
1328
1329 if (list_empty(&wdev->script_proc))
1330 return 0;
1331
1332 wdev->kill_request = calloc(1, sizeof(*wdev->kill_request));
1333 ubus_defer_request(ubus_ctx, req, wdev->kill_request);
1334
1335 return 0;
1336 }
1337
1338 static int
1339 wireless_device_set_retry(struct wireless_device *wdev, struct blob_attr *data)
1340 {
1341 static const struct blobmsg_policy retry_policy = {
1342 .name = "retry", .type = BLOBMSG_TYPE_INT32
1343 };
1344 struct blob_attr *val;
1345
1346 blobmsg_parse(&retry_policy, 1, &val, blobmsg_data(data), blobmsg_data_len(data));
1347 if (!val)
1348 return UBUS_STATUS_INVALID_ARGUMENT;
1349
1350 wdev->retry = blobmsg_get_u32(val);
1351 return 0;
1352 }
1353
1354 enum {
1355 NOTIFY_CMD_UP = 0,
1356 NOTIFY_CMD_SET_DATA = 1,
1357 NOTIFY_CMD_PROCESS_ADD = 2,
1358 NOTIFY_CMD_PROCESS_KILL_ALL = 3,
1359 NOTIFY_CMD_SET_RETRY = 4,
1360 };
1361
1362 int
1363 wireless_device_notify(struct wireless_device *wdev, struct blob_attr *data,
1364 struct ubus_request_data *req)
1365 {
1366 enum {
1367 NOTIFY_ATTR_COMMAND,
1368 NOTIFY_ATTR_VIF,
1369 NOTIFY_ATTR_VLAN,
1370 NOTIFY_ATTR_DATA,
1371 __NOTIFY_MAX,
1372 };
1373 static const struct blobmsg_policy notify_policy[__NOTIFY_MAX] = {
1374 [NOTIFY_ATTR_COMMAND] = { .name = "command", .type = BLOBMSG_TYPE_INT32 },
1375 [NOTIFY_ATTR_VIF] = { .name = "interface", .type = BLOBMSG_TYPE_STRING },
1376 [NOTIFY_ATTR_VLAN] = { .name = "vlan", .type = BLOBMSG_TYPE_STRING },
1377 [NOTIFY_ATTR_DATA] = { .name = "data", .type = BLOBMSG_TYPE_TABLE },
1378 };
1379 struct wireless_interface *vif = NULL;
1380 struct wireless_vlan *vlan = NULL;
1381 struct blob_attr *tb[__NOTIFY_MAX];
1382 struct blob_attr *cur, **pdata;
1383
1384 blobmsg_parse(notify_policy, __NOTIFY_MAX, tb, blob_data(data), blob_len(data));
1385
1386 if (!tb[NOTIFY_ATTR_COMMAND])
1387 return UBUS_STATUS_INVALID_ARGUMENT;
1388
1389 if ((cur = tb[NOTIFY_ATTR_VIF]) != NULL) {
1390 vif = vlist_find(&wdev->interfaces, blobmsg_data(cur), vif, node);
1391 if (!vif)
1392 return UBUS_STATUS_NOT_FOUND;
1393 }
1394
1395 if ((cur = tb[NOTIFY_ATTR_VLAN]) != NULL) {
1396 vlan = vlist_find(&wdev->vlans, blobmsg_data(cur), vlan, node);
1397 if (!vlan)
1398 return UBUS_STATUS_NOT_FOUND;
1399 }
1400
1401 cur = tb[NOTIFY_ATTR_DATA];
1402 if (!cur)
1403 return UBUS_STATUS_INVALID_ARGUMENT;
1404
1405 switch (blobmsg_get_u32(tb[NOTIFY_ATTR_COMMAND])) {
1406 case NOTIFY_CMD_UP:
1407 if (vif || vlan)
1408 return UBUS_STATUS_INVALID_ARGUMENT;
1409
1410 if (wdev->state != IFS_SETUP)
1411 return UBUS_STATUS_PERMISSION_DENIED;
1412
1413 wireless_device_mark_up(wdev);
1414 break;
1415 case NOTIFY_CMD_SET_DATA:
1416 if (vif)
1417 pdata = &vif->data;
1418 else if (vlan)
1419 pdata = &vlan->data;
1420 else
1421 pdata = &wdev->data;
1422
1423 if (*pdata)
1424 return UBUS_STATUS_INVALID_ARGUMENT;
1425
1426 *pdata = blob_memdup(cur);
1427 if (vif)
1428 wireless_interface_set_data(vif);
1429 else if (vlan)
1430 wireless_vlan_set_data(vlan);
1431 break;
1432 case NOTIFY_CMD_PROCESS_ADD:
1433 return wireless_device_add_process(wdev, cur);
1434 case NOTIFY_CMD_PROCESS_KILL_ALL:
1435 return wireless_device_process_kill_all(wdev, cur, req);
1436 case NOTIFY_CMD_SET_RETRY:
1437 return wireless_device_set_retry(wdev, cur);
1438 default:
1439 return UBUS_STATUS_INVALID_ARGUMENT;
1440 }
1441
1442 return 0;
1443 }
1444
1445 void
1446 wireless_start_pending(void)
1447 {
1448 struct wireless_device *wdev;
1449
1450 vlist_for_each_element(&wireless_devices, wdev, node)
1451 __wireless_device_set_up(wdev, 0);
1452 }