2
0

config.c 20 KB

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