fa7cbe42052d28b37ffd797fb263e35537da3d2c
[project/netifd.git] / config.c
1 /*
2 * netifd - network interface daemon
3 * Copyright (C) 2012 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 #define _GNU_SOURCE
15 #include <string.h>
16 #include <stdlib.h>
17 #include <stdio.h>
18
19 #include <uci.h>
20
21 #include <libubox/blobmsg_json.h>
22
23 #include "netifd.h"
24 #include "interface.h"
25 #include "interface-ip.h"
26 #include "iprule.h"
27 #include "proto.h"
28 #include "wireless.h"
29 #include "config.h"
30
31 bool config_init = false;
32
33 static struct uci_context *uci_ctx;
34 static struct uci_package *uci_network;
35 static struct uci_package *uci_wireless;
36 static struct blob_attr *board_netdevs;
37 static struct blob_buf b;
38
39 static int
40 config_section_idx(struct uci_section *s)
41 {
42 struct uci_element *e;
43 int idx = 0;
44
45 uci_foreach_element(&uci_wireless->sections, e) {
46 struct uci_section *cur = uci_to_section(e);
47
48 if (s == cur)
49 return idx;
50
51 if (!strcmp(cur->type, s->type))
52 idx++;
53 }
54
55 return -1;
56 }
57
58 static bool
59 config_bridge_has_vlans(const char *br_name)
60 {
61 struct uci_element *e;
62
63 uci_foreach_element(&uci_network->sections, e) {
64 struct uci_section *s = uci_to_section(e);
65 const char *name;
66
67 if (strcmp(s->type, "bridge-vlan") != 0)
68 continue;
69
70 name = uci_lookup_option_string(uci_ctx, s, "device");
71 if (!name)
72 continue;
73
74 if (!strcmp(name, br_name))
75 return true;
76 }
77
78 return false;
79 }
80
81 static void
82 config_fixup_bridge_var(struct uci_section *s, const char *name, const char *val)
83 {
84 struct uci_ptr ptr = {
85 .p = s->package,
86 .s = s,
87 .option = name,
88 .value = val,
89 };
90
91 uci_lookup_ptr(uci_ctx, &ptr, NULL, false);
92 if (ptr.o)
93 return;
94
95 uci_set(uci_ctx, &ptr);
96 }
97
98 static void
99 config_fixup_bridge_vlan_filtering(struct uci_section *s, const char *name)
100 {
101 bool has_vlans = config_bridge_has_vlans(name);
102
103 config_fixup_bridge_var(s, "__has_vlans", has_vlans ? "1" : "0");
104
105 if (!has_vlans)
106 return;
107
108 config_fixup_bridge_var(s, "vlan_filtering", "1");
109 }
110
111 static int
112 config_parse_bridge_interface(struct uci_section *s, struct device_type *devtype)
113 {
114 char *name;
115
116 name = alloca(strlen(s->e.name) + strlen(devtype->name_prefix) + 2);
117 sprintf(name, "%s-%s", devtype->name_prefix, s->e.name);
118 blobmsg_add_string(&b, "name", name);
119
120 config_fixup_bridge_vlan_filtering(s, name);
121 uci_to_blob(&b, s, devtype->config_params);
122 if (!device_create(name, devtype, b.head)) {
123 D(INTERFACE, "Failed to create '%s' device for interface '%s'\n",
124 devtype->name, s->e.name);
125 }
126
127 blob_buf_init(&b, 0);
128 blobmsg_add_string(&b, "ifname", name);
129 return 0;
130 }
131
132 static void
133 config_parse_interface(struct uci_section *s, bool alias)
134 {
135 struct interface *iface;
136 const char *type = NULL, *disabled;
137 struct blob_attr *config;
138 bool bridge = false;
139 struct device_type *devtype = NULL;
140
141 disabled = uci_lookup_option_string(uci_ctx, s, "disabled");
142 if (disabled && !strcmp(disabled, "1"))
143 return;
144
145 blob_buf_init(&b, 0);
146
147 if (!alias)
148 type = uci_lookup_option_string(uci_ctx, s, "type");
149
150 if (type)
151 devtype = device_type_get(type);
152
153 if (devtype && devtype->bridge_capability) {
154 if (config_parse_bridge_interface(s, devtype))
155 return;
156
157 bridge = true;
158 }
159
160 uci_to_blob(&b, s, &interface_attr_list);
161
162 iface = interface_alloc(s->e.name, b.head, false);
163 if (!iface)
164 return;
165
166 if (iface->proto_handler && iface->proto_handler->config_params)
167 uci_to_blob(&b, s, iface->proto_handler->config_params);
168
169 if (!bridge && uci_to_blob(&b, s, simple_device_type.config_params))
170 iface->device_config = true;
171
172 config = blob_memdup(b.head);
173 if (!config)
174 goto error;
175
176 if (alias) {
177 if (!interface_add_alias(iface, config))
178 goto error_free_config;
179 } else {
180 if (!interface_add(iface, config))
181 goto error_free_config;
182 }
183 return;
184
185 error_free_config:
186 free(config);
187 error:
188 free(iface);
189 }
190
191 static void
192 config_parse_route(struct uci_section *s, bool v6)
193 {
194 void *route;
195
196 blob_buf_init(&b, 0);
197 route = blobmsg_open_array(&b, "route");
198 uci_to_blob(&b, s, &route_attr_list);
199 blobmsg_close_array(&b, route);
200 interface_ip_add_route(NULL, blob_data(b.head), v6);
201 }
202
203 static void
204 config_parse_neighbor(struct uci_section *s, bool v6)
205 {
206 void *neighbor;
207 blob_buf_init(&b,0);
208 neighbor = blobmsg_open_array(&b, "neighbor");
209 uci_to_blob(&b,s, &neighbor_attr_list);
210 blobmsg_close_array(&b, neighbor);
211 interface_ip_add_neighbor(NULL, blob_data(b.head), v6);
212 }
213
214 static void
215 config_parse_rule(struct uci_section *s, bool v6)
216 {
217 void *rule;
218
219 blob_buf_init(&b, 0);
220 rule = blobmsg_open_array(&b, "rule");
221 uci_to_blob(&b, s, &rule_attr_list);
222 blobmsg_close_array(&b, rule);
223 iprule_add(blob_data(b.head), v6);
224 }
225
226 static void
227 config_init_devices(bool bridge)
228 {
229 struct uci_element *e;
230
231 uci_foreach_element(&uci_network->sections, e) {
232 const struct uci_blob_param_list *params = NULL;
233 struct uci_section *s = uci_to_section(e);
234 struct device_type *devtype = NULL;
235 struct device *dev;
236 const char *type, *name;
237
238 if (strcmp(s->type, "device") != 0)
239 continue;
240
241 name = uci_lookup_option_string(uci_ctx, s, "name");
242 if (!name)
243 continue;
244
245 type = uci_lookup_option_string(uci_ctx, s, "type");
246 if (type)
247 devtype = device_type_get(type);
248
249 if (bridge != (devtype && devtype->bridge_capability))
250 continue;
251
252 if (devtype)
253 params = devtype->config_params;
254 if (!params)
255 params = simple_device_type.config_params;
256
257 if (devtype && devtype->bridge_capability)
258 config_fixup_bridge_vlan_filtering(s, name);
259
260 blob_buf_init(&b, 0);
261 uci_to_blob(&b, s, params);
262 if (devtype) {
263 dev = device_create(name, devtype, b.head);
264 if (!dev)
265 continue;
266 } else {
267 dev = device_get(name, 1);
268 if (!dev)
269 continue;
270
271 dev->current_config = true;
272 device_apply_config(dev, dev->type, b.head);
273 }
274 dev->default_config = false;
275 }
276 }
277
278 static void
279 config_parse_vlan(struct device *dev, struct uci_section *s)
280 {
281 enum {
282 BRVLAN_ATTR_VID,
283 BRVLAN_ATTR_LOCAL,
284 BRVLAN_ATTR_PORTS,
285 BRVLAN_ATTR_ALIAS,
286 __BRVLAN_ATTR_MAX,
287 };
288 static const struct blobmsg_policy vlan_attrs[__BRVLAN_ATTR_MAX] = {
289 [BRVLAN_ATTR_VID] = { "vlan", BLOBMSG_TYPE_INT32 },
290 [BRVLAN_ATTR_LOCAL] = { "local", BLOBMSG_TYPE_BOOL },
291 [BRVLAN_ATTR_PORTS] = { "ports", BLOBMSG_TYPE_ARRAY },
292 [BRVLAN_ATTR_ALIAS] = { "alias", BLOBMSG_TYPE_ARRAY },
293 };
294 static const struct uci_blob_param_info vlan_attr_info[__BRVLAN_ATTR_MAX] = {
295 [BRVLAN_ATTR_PORTS] = { .type = BLOBMSG_TYPE_STRING },
296 [BRVLAN_ATTR_ALIAS] = { .type = BLOBMSG_TYPE_STRING },
297 };
298 static const struct uci_blob_param_list vlan_attr_list = {
299 .n_params = __BRVLAN_ATTR_MAX,
300 .params = vlan_attrs,
301 .info = vlan_attr_info,
302 };
303 struct blob_attr *tb[__BRVLAN_ATTR_MAX];
304 struct blob_attr *cur;
305 struct bridge_vlan_port *port;
306 struct bridge_vlan *vlan;
307 unsigned int vid;
308 const char *val;
309 char *name_buf;
310 int name_len = 0;
311 int n_ports = 0;
312 int rem;
313
314 val = uci_lookup_option_string(uci_ctx, s, "vlan");
315 if (!val)
316 return;
317
318 blob_buf_init(&b, 0);
319 uci_to_blob(&b, s, &vlan_attr_list);
320 blobmsg_parse(vlan_attrs, __BRVLAN_ATTR_MAX, tb, blob_data(b.head), blob_len(b.head));
321
322 if (!tb[BRVLAN_ATTR_VID])
323 return;
324
325 vid = blobmsg_get_u32(tb[BRVLAN_ATTR_VID]);
326 if (!vid || vid > 4095)
327 return;
328
329 blobmsg_for_each_attr(cur, tb[BRVLAN_ATTR_PORTS], rem) {
330 name_len += strlen(blobmsg_get_string(cur)) + 1;
331 n_ports++;
332 }
333
334 vlan = calloc(1, sizeof(*vlan) + n_ports * sizeof(*port) + name_len);
335 if (!vlan)
336 return;
337
338 vlan->vid = vid;
339 vlan->local = true;
340 if (tb[BRVLAN_ATTR_LOCAL])
341 vlan->local = blobmsg_get_bool(tb[BRVLAN_ATTR_LOCAL]);
342
343 vlan->n_ports = n_ports;
344 vlan->ports = port = (struct bridge_vlan_port *)&vlan[1];
345 INIT_LIST_HEAD(&vlan->hotplug_ports);
346 name_buf = (char *)&port[n_ports];
347
348 blobmsg_for_each_attr(cur, tb[BRVLAN_ATTR_PORTS], rem) {
349 char *sep;
350
351 port->ifname = name_buf;
352 port->flags = BRVLAN_F_UNTAGGED;
353 strcpy(name_buf, blobmsg_get_string(cur));
354
355 sep = strchr(name_buf, ':');
356 if (sep) {
357 for (*sep = 0, sep++; *sep; sep++)
358 switch (*sep) {
359 case '*':
360 port->flags |= BRVLAN_F_PVID;
361 break;
362 case 't':
363 port->flags &= ~BRVLAN_F_UNTAGGED;
364 break;
365 }
366 }
367
368 name_buf += strlen(name_buf) + 1;
369 port++;
370 }
371
372 blobmsg_for_each_attr(cur, tb[BRVLAN_ATTR_ALIAS], rem)
373 kvlist_set(&dev->vlan_aliases, blobmsg_get_string(cur), &vid);
374
375 vlist_add(&dev->vlans, &vlan->node, &vlan->vid);
376 }
377
378
379 static void
380 config_init_vlans(void)
381 {
382 struct uci_element *e;
383 struct device *dev;
384
385 device_vlan_update(false);
386 uci_foreach_element(&uci_network->sections, e) {
387 struct uci_section *s = uci_to_section(e);
388 const char *name;
389
390 if (strcmp(s->type, "bridge-vlan") != 0)
391 continue;
392
393 name = uci_lookup_option_string(uci_ctx, s, "device");
394 if (!name)
395 continue;
396
397 dev = device_get(name, 0);
398 if (!dev || !dev->vlans.update)
399 continue;
400
401 config_parse_vlan(dev, s);
402 }
403 device_vlan_update(true);
404 }
405
406 static struct uci_package *
407 config_init_package(const char *config)
408 {
409 struct uci_context *ctx = uci_ctx;
410 struct uci_package *p = NULL;
411
412 if (!ctx) {
413 ctx = uci_alloc_context();
414 uci_ctx = ctx;
415
416 ctx->flags &= ~UCI_FLAG_STRICT;
417 if (config_path)
418 uci_set_confdir(ctx, config_path);
419
420 #ifdef DUMMY_MODE
421 uci_set_savedir(ctx, "./tmp");
422 #endif
423 } else {
424 p = uci_lookup_package(ctx, config);
425 if (p)
426 uci_unload(ctx, p);
427 }
428
429 if (uci_load(ctx, config, &p))
430 return NULL;
431
432 return p;
433 }
434
435 static void
436 config_init_interfaces(void)
437 {
438 struct uci_element *e;
439
440 uci_foreach_element(&uci_network->sections, e) {
441 struct uci_section *s = uci_to_section(e);
442
443 if (!strcmp(s->type, "interface"))
444 config_parse_interface(s, false);
445 }
446
447 uci_foreach_element(&uci_network->sections, e) {
448 struct uci_section *s = uci_to_section(e);
449
450 if (!strcmp(s->type, "alias"))
451 config_parse_interface(s, true);
452 }
453 }
454
455 static void
456 config_init_ip(void)
457 {
458 struct interface *iface;
459 struct uci_element *e;
460
461 vlist_for_each_element(&interfaces, iface, node)
462 interface_ip_update_start(&iface->config_ip);
463
464 uci_foreach_element(&uci_network->sections, e) {
465 struct uci_section *s = uci_to_section(e);
466
467 if (!strcmp(s->type, "route"))
468 config_parse_route(s, false);
469 else if (!strcmp(s->type, "route6"))
470 config_parse_route(s, true);
471 if (!strcmp(s->type, "neighbor"))
472 config_parse_neighbor(s, false);
473 else if (!strcmp(s->type, "neighbor6"))
474 config_parse_neighbor(s, true);
475 }
476
477 vlist_for_each_element(&interfaces, iface, node)
478 interface_ip_update_complete(&iface->config_ip);
479 }
480
481 static void
482 config_init_rules(void)
483 {
484 struct uci_element *e;
485
486 iprule_update_start();
487
488 uci_foreach_element(&uci_network->sections, e) {
489 struct uci_section *s = uci_to_section(e);
490
491 if (!strcmp(s->type, "rule"))
492 config_parse_rule(s, false);
493 else if (!strcmp(s->type, "rule6"))
494 config_parse_rule(s, true);
495 }
496
497 iprule_update_complete();
498 }
499
500 static void
501 config_init_globals(void)
502 {
503 struct uci_section *globals = uci_lookup_section(
504 uci_ctx, uci_network, "globals");
505 if (!globals)
506 return;
507
508 const char *ula_prefix = uci_lookup_option_string(
509 uci_ctx, globals, "ula_prefix");
510 interface_ip_set_ula_prefix(ula_prefix);
511 }
512
513 static void
514 config_parse_wireless_device(struct uci_section *s)
515 {
516 struct wireless_driver *drv;
517 const char *driver_name;
518
519 driver_name = uci_lookup_option_string(uci_ctx, s, "type");
520 if (!driver_name)
521 return;
522
523 drv = avl_find_element(&wireless_drivers, driver_name, drv, node);
524 if (!drv)
525 return;
526
527 blob_buf_init(&b, 0);
528 uci_to_blob(&b, s, drv->device.config);
529 wireless_device_create(drv, s->e.name, b.head);
530 }
531
532 static struct wireless_interface*
533 config_parse_wireless_interface(struct wireless_device *wdev, struct uci_section *s)
534 {
535 char *name;
536
537 name = alloca(strlen(s->type) + 16);
538 sprintf(name, "@%s[%d]", s->type, config_section_idx(s));
539
540 blob_buf_init(&b, 0);
541 uci_to_blob(&b, s, wdev->drv->interface.config);
542 return wireless_interface_create(wdev, b.head, s->anonymous ? name : s->e.name);
543 }
544
545 static void
546 config_parse_wireless_vlan(struct wireless_device *wdev, char *vif, struct uci_section *s)
547 {
548 char *name;
549
550 name = alloca(strlen(s->type) + 16);
551 sprintf(name, "@%s[%d]", s->type, config_section_idx(s));
552
553 blob_buf_init(&b, 0);
554 uci_to_blob(&b, s, wdev->drv->vlan.config);
555 wireless_vlan_create(wdev, vif, b.head, s->anonymous ? name : s->e.name);
556 }
557
558 static void
559 config_parse_wireless_station(struct wireless_device *wdev, char *vif, struct uci_section *s)
560 {
561 char *name;
562
563 name = alloca(strlen(s->type) + 16);
564 sprintf(name, "@%s[%d]", s->type, config_section_idx(s));
565
566 blob_buf_init(&b, 0);
567 uci_to_blob(&b, s, wdev->drv->station.config);
568 wireless_station_create(wdev, vif, b.head, s->anonymous ? name : s->e.name);
569 }
570
571 static void
572 config_init_wireless(void)
573 {
574 struct wireless_device *wdev;
575 struct uci_element *e;
576 const char *dev_name;
577
578 if (!uci_wireless) {
579 DPRINTF("No wireless configuration found\n");
580 return;
581 }
582
583 vlist_update(&wireless_devices);
584
585 uci_foreach_element(&uci_wireless->sections, e) {
586 struct uci_section *s = uci_to_section(e);
587 if (strcmp(s->type, "wifi-device") != 0)
588 continue;
589
590 config_parse_wireless_device(s);
591 }
592
593 vlist_flush(&wireless_devices);
594
595 vlist_for_each_element(&wireless_devices, wdev, node) {
596 wdev->vif_idx = 0;
597 vlist_update(&wdev->interfaces);
598 wdev->vlan_idx = 0;
599 vlist_update(&wdev->vlans);
600 wdev->sta_idx = 0;
601 vlist_update(&wdev->stations);
602 }
603
604 uci_foreach_element(&uci_wireless->sections, e) {
605 struct uci_section *s = uci_to_section(e);
606 struct wireless_interface *vif;
607 struct uci_element *f;
608
609 if (strcmp(s->type, "wifi-iface") != 0)
610 continue;
611
612 dev_name = uci_lookup_option_string(uci_ctx, s, "device");
613 if (!dev_name)
614 continue;
615
616 wdev = vlist_find(&wireless_devices, dev_name, wdev, node);
617 if (!wdev) {
618 DPRINTF("device %s not found!\n", dev_name);
619 continue;
620 }
621
622 vif = config_parse_wireless_interface(wdev, s);
623
624 if (!vif || s->anonymous)
625 continue;
626 uci_foreach_element(&uci_wireless->sections, f) {
627 struct uci_section *s = uci_to_section(f);
628 const char *vif_name;
629
630 if (strcmp(s->type, "wifi-vlan") != 0)
631 continue;
632
633 vif_name = uci_lookup_option_string(uci_ctx, s, "iface");
634 if (vif_name && strcmp(e->name, vif_name))
635 continue;
636 config_parse_wireless_vlan(wdev, vif->name, s);
637 }
638
639 uci_foreach_element(&uci_wireless->sections, f) {
640 struct uci_section *s = uci_to_section(f);
641 const char *vif_name;
642
643 if (strcmp(s->type, "wifi-station") != 0)
644 continue;
645
646 vif_name = uci_lookup_option_string(uci_ctx, s, "iface");
647 if (vif_name && strcmp(e->name, vif_name))
648 continue;
649 config_parse_wireless_station(wdev, vif->name, s);
650 }
651 }
652
653 vlist_for_each_element(&wireless_devices, wdev, node) {
654 vlist_flush(&wdev->interfaces);
655 vlist_flush(&wdev->vlans);
656 vlist_flush(&wdev->stations);
657 }
658 }
659
660
661 static struct blob_attr *
662 config_find_blobmsg_attr(struct blob_attr *attr, const char *name, int type)
663 {
664 struct blobmsg_policy policy = { .name = name, .type = type };
665 struct blob_attr *cur;
666
667 blobmsg_parse(&policy, 1, &cur, blobmsg_data(attr), blobmsg_len(attr));
668
669 return cur;
670 }
671
672 struct ether_addr *config_get_default_macaddr(const char *ifname)
673 {
674 struct blob_attr *cur;
675
676 if (!board_netdevs)
677 return NULL;
678
679 cur = config_find_blobmsg_attr(board_netdevs, ifname, BLOBMSG_TYPE_TABLE);
680 if (!cur)
681 return NULL;
682
683 cur = config_find_blobmsg_attr(cur, "macaddr", BLOBMSG_TYPE_STRING);
684 if (!cur)
685 return NULL;
686
687 return ether_aton(blobmsg_get_string(cur));
688 }
689
690 static void
691 config_init_board(void)
692 {
693 struct blob_attr *cur;
694
695 blob_buf_init(&b, 0);
696
697 if (!blobmsg_add_json_from_file(&b, DEFAULT_BOARD_JSON))
698 return;
699
700 free(board_netdevs);
701 board_netdevs = NULL;
702
703 cur = config_find_blobmsg_attr(b.head, "network-device",
704 BLOBMSG_TYPE_TABLE);
705 if (!cur)
706 return;
707
708 board_netdevs = blob_memdup(cur);
709 }
710
711 int
712 config_init_all(void)
713 {
714 int ret = 0;
715 char *err;
716
717 uci_network = config_init_package("network");
718 if (!uci_network) {
719 uci_get_errorstr(uci_ctx, &err, NULL);
720 netifd_log_message(L_CRIT, "Failed to load network config (%s)\n", err);
721 free(err);
722 return -1;
723 }
724
725 uci_wireless = config_init_package("wireless");
726 if (!uci_wireless && uci_ctx->err != UCI_ERR_NOTFOUND) {
727 uci_get_errorstr(uci_ctx, &err, NULL);
728 netifd_log_message(L_CRIT, "Failed to load wireless config (%s)\n", err);
729 free(err);
730 ret = -1;
731 }
732
733 config_init_board();
734
735 vlist_update(&interfaces);
736 config_init = true;
737 device_lock();
738
739 device_reset_config();
740 config_init_devices(true);
741 config_init_vlans();
742 config_init_devices(false);
743 config_init_interfaces();
744 config_init_ip();
745 config_init_rules();
746 config_init_globals();
747 config_init_wireless();
748
749 config_init = false;
750 device_unlock();
751
752 device_reset_old();
753 device_init_pending();
754 vlist_flush(&interfaces);
755 device_free_unused(NULL);
756 interface_refresh_assignments(false);
757 interface_start_pending();
758 wireless_start_pending();
759
760 return ret;
761 }