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