• source navigation  • diff markup  • identifier search  • freetext search  • 

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

This page was automatically generated by LXR 0.3.1.  •  OpenWrt