ubus.c 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438
  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 <arpa/inet.h>
  16. #include <string.h>
  17. #include <stdio.h>
  18. #include "netifd.h"
  19. #include "interface.h"
  20. #include "proto.h"
  21. #include "ubus.h"
  22. #include "system.h"
  23. #include "wireless.h"
  24. struct ubus_context *ubus_ctx = NULL;
  25. static struct blob_buf b;
  26. static const char *ubus_path;
  27. /* global object */
  28. static int
  29. netifd_handle_restart(struct ubus_context *ctx, struct ubus_object *obj,
  30. struct ubus_request_data *req, const char *method,
  31. struct blob_attr *msg)
  32. {
  33. netifd_restart();
  34. return 0;
  35. }
  36. static int
  37. netifd_handle_reload(struct ubus_context *ctx, struct ubus_object *obj,
  38. struct ubus_request_data *req, const char *method,
  39. struct blob_attr *msg)
  40. {
  41. if (netifd_reload())
  42. return UBUS_STATUS_NOT_FOUND;
  43. return UBUS_STATUS_OK;
  44. }
  45. enum {
  46. HR_TARGET,
  47. HR_V6,
  48. HR_INTERFACE,
  49. HR_EXCLUDE,
  50. __HR_MAX
  51. };
  52. static const struct blobmsg_policy route_policy[__HR_MAX] = {
  53. [HR_TARGET] = { .name = "target", .type = BLOBMSG_TYPE_STRING },
  54. [HR_V6] = { .name = "v6", .type = BLOBMSG_TYPE_BOOL },
  55. [HR_INTERFACE] = { .name = "interface", .type = BLOBMSG_TYPE_STRING },
  56. [HR_EXCLUDE] = { .name = "exclude", .type = BLOBMSG_TYPE_BOOL },
  57. };
  58. static int
  59. netifd_add_host_route(struct ubus_context *ctx, struct ubus_object *obj,
  60. struct ubus_request_data *req, const char *method,
  61. struct blob_attr *msg)
  62. {
  63. struct blob_attr *tb[__HR_MAX];
  64. struct interface *iface = NULL;
  65. union if_addr a;
  66. bool v6 = false;
  67. bool exclude = false;
  68. blobmsg_parse(route_policy, __HR_MAX, tb, blob_data(msg), blob_len(msg));
  69. if (!tb[HR_TARGET])
  70. return UBUS_STATUS_INVALID_ARGUMENT;
  71. if (tb[HR_V6])
  72. v6 = blobmsg_get_bool(tb[HR_V6]);
  73. if (tb[HR_EXCLUDE])
  74. exclude = blobmsg_get_bool(tb[HR_EXCLUDE]);
  75. if (tb[HR_INTERFACE])
  76. iface = vlist_find(&interfaces, blobmsg_data(tb[HR_INTERFACE]), iface, node);
  77. memset(&a, 0, sizeof(a));
  78. if (!inet_pton(v6 ? AF_INET6 : AF_INET, blobmsg_data(tb[HR_TARGET]), &a))
  79. return UBUS_STATUS_INVALID_ARGUMENT;
  80. iface = interface_ip_add_target_route(&a, v6, iface, exclude);
  81. if (!iface)
  82. return UBUS_STATUS_NOT_FOUND;
  83. blob_buf_init(&b, 0);
  84. blobmsg_add_string(&b, "interface", iface->name);
  85. ubus_send_reply(ctx, req, b.head);
  86. return 0;
  87. }
  88. static int
  89. netifd_get_proto_handlers(struct ubus_context *ctx, struct ubus_object *obj,
  90. struct ubus_request_data *req, const char *method,
  91. struct blob_attr *msg)
  92. {
  93. blob_buf_init(&b, 0);
  94. proto_dump_handlers(&b);
  95. ubus_send_reply(ctx, req, b.head);
  96. return 0;
  97. }
  98. enum {
  99. DI_NAME,
  100. __DI_MAX
  101. };
  102. static const struct blobmsg_policy dynamic_policy[__DI_MAX] = {
  103. [DI_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING },
  104. };
  105. static int
  106. netifd_add_dynamic(struct ubus_context *ctx, struct ubus_object *obj,
  107. struct ubus_request_data *req, const char *method,
  108. struct blob_attr *msg)
  109. {
  110. struct blob_attr *tb[__DI_MAX];
  111. struct interface *iface;
  112. struct blob_attr *config;
  113. blobmsg_parse(dynamic_policy, __DI_MAX, tb, blob_data(msg), blob_len(msg));
  114. if (!tb[DI_NAME])
  115. return UBUS_STATUS_INVALID_ARGUMENT;
  116. const char *name = blobmsg_get_string(tb[DI_NAME]);
  117. iface = interface_alloc(name, msg, true);
  118. if (!iface)
  119. return UBUS_STATUS_UNKNOWN_ERROR;
  120. config = blob_memdup(msg);
  121. if (!config)
  122. goto error;
  123. if (!interface_add(iface, config))
  124. goto error_free_config;
  125. return UBUS_STATUS_OK;
  126. error_free_config:
  127. free(config);
  128. error:
  129. free(iface);
  130. return UBUS_STATUS_UNKNOWN_ERROR;
  131. }
  132. enum {
  133. NETNS_UPDOWN_JAIL,
  134. NETNS_UPDOWN_START,
  135. __NETNS_UPDOWN_MAX
  136. };
  137. static const struct blobmsg_policy netns_updown_policy[__NETNS_UPDOWN_MAX] = {
  138. [NETNS_UPDOWN_JAIL] = { .name = "jail", .type = BLOBMSG_TYPE_STRING },
  139. [NETNS_UPDOWN_START] = { .name = "start", .type = BLOBMSG_TYPE_BOOL },
  140. };
  141. static int
  142. netifd_netns_updown(struct ubus_context *ctx, struct ubus_object *obj,
  143. struct ubus_request_data *req, const char *method,
  144. struct blob_attr *msg)
  145. {
  146. int target_netns_fd = ubus_request_get_caller_fd(req);
  147. struct blob_attr *tb[__NETNS_UPDOWN_MAX];
  148. bool start;
  149. if (target_netns_fd < 0)
  150. return UBUS_STATUS_INVALID_ARGUMENT;
  151. blobmsg_parse(netns_updown_policy, __NETNS_UPDOWN_MAX, tb, blob_data(msg), blob_len(msg));
  152. start = tb[NETNS_UPDOWN_START] && blobmsg_get_bool(tb[NETNS_UPDOWN_START]);
  153. if (start) {
  154. if (!tb[NETNS_UPDOWN_JAIL])
  155. return UBUS_STATUS_INVALID_ARGUMENT;
  156. interface_start_jail(target_netns_fd, blobmsg_get_string(tb[NETNS_UPDOWN_JAIL]));
  157. } else {
  158. interface_stop_jail(target_netns_fd);
  159. }
  160. close(target_netns_fd);
  161. return UBUS_STATUS_OK;
  162. }
  163. static struct ubus_method main_object_methods[] = {
  164. { .name = "restart", .handler = netifd_handle_restart },
  165. { .name = "reload", .handler = netifd_handle_reload },
  166. UBUS_METHOD("add_host_route", netifd_add_host_route, route_policy),
  167. { .name = "get_proto_handlers", .handler = netifd_get_proto_handlers },
  168. UBUS_METHOD("add_dynamic", netifd_add_dynamic, dynamic_policy),
  169. UBUS_METHOD("netns_updown", netifd_netns_updown, netns_updown_policy),
  170. };
  171. static struct ubus_object_type main_object_type =
  172. UBUS_OBJECT_TYPE("netifd", main_object_methods);
  173. static struct ubus_object main_object = {
  174. .name = "network",
  175. .type = &main_object_type,
  176. .methods = main_object_methods,
  177. .n_methods = ARRAY_SIZE(main_object_methods),
  178. };
  179. enum {
  180. DEV_NAME,
  181. __DEV_MAX,
  182. };
  183. static const struct blobmsg_policy dev_policy[__DEV_MAX] = {
  184. [DEV_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING },
  185. };
  186. static int
  187. netifd_dev_status(struct ubus_context *ctx, struct ubus_object *obj,
  188. struct ubus_request_data *req, const char *method,
  189. struct blob_attr *msg)
  190. {
  191. struct device *dev = NULL;
  192. struct blob_attr *tb[__DEV_MAX];
  193. blobmsg_parse(dev_policy, __DEV_MAX, tb, blob_data(msg), blob_len(msg));
  194. if (tb[DEV_NAME]) {
  195. dev = device_find(blobmsg_data(tb[DEV_NAME]));
  196. if (!dev)
  197. return UBUS_STATUS_INVALID_ARGUMENT;
  198. }
  199. blob_buf_init(&b, 0);
  200. device_dump_status(&b, dev);
  201. ubus_send_reply(ctx, req, b.head);
  202. return 0;
  203. }
  204. enum {
  205. ALIAS_ATTR_ALIAS,
  206. ALIAS_ATTR_DEV,
  207. __ALIAS_ATTR_MAX,
  208. };
  209. static const struct blobmsg_policy alias_attrs[__ALIAS_ATTR_MAX] = {
  210. [ALIAS_ATTR_ALIAS] = { "alias", BLOBMSG_TYPE_ARRAY },
  211. [ALIAS_ATTR_DEV] = { "device", BLOBMSG_TYPE_STRING },
  212. };
  213. static int
  214. netifd_handle_alias(struct ubus_context *ctx, struct ubus_object *obj,
  215. struct ubus_request_data *req, const char *method,
  216. struct blob_attr *msg)
  217. {
  218. struct device *dev = NULL;
  219. struct blob_attr *tb[__ALIAS_ATTR_MAX];
  220. struct blob_attr *cur;
  221. size_t rem;
  222. blobmsg_parse(alias_attrs, __ALIAS_ATTR_MAX, tb, blob_data(msg), blob_len(msg));
  223. if (!tb[ALIAS_ATTR_ALIAS])
  224. return UBUS_STATUS_INVALID_ARGUMENT;
  225. if ((cur = tb[ALIAS_ATTR_DEV]) != NULL) {
  226. dev = device_get(blobmsg_data(cur), true);
  227. if (!dev)
  228. return UBUS_STATUS_NOT_FOUND;
  229. }
  230. blobmsg_for_each_attr(cur, tb[ALIAS_ATTR_ALIAS], rem) {
  231. if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING)
  232. goto error;
  233. if (!blobmsg_check_attr(cur, false))
  234. goto error;
  235. alias_notify_device(blobmsg_data(cur), dev);
  236. }
  237. return 0;
  238. error:
  239. device_free_unused();
  240. return UBUS_STATUS_INVALID_ARGUMENT;
  241. }
  242. enum {
  243. DEV_STATE_NAME,
  244. DEV_STATE_DEFER,
  245. DEV_STATE_AUTH_STATUS,
  246. __DEV_STATE_MAX,
  247. };
  248. static const struct blobmsg_policy dev_state_policy[__DEV_STATE_MAX] = {
  249. [DEV_STATE_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING },
  250. [DEV_STATE_DEFER] = { .name = "defer", .type = BLOBMSG_TYPE_BOOL },
  251. [DEV_STATE_AUTH_STATUS] = { .name = "auth_status", .type = BLOBMSG_TYPE_BOOL },
  252. };
  253. static int
  254. netifd_handle_set_state(struct ubus_context *ctx, struct ubus_object *obj,
  255. struct ubus_request_data *req, const char *method,
  256. struct blob_attr *msg)
  257. {
  258. struct device *dev = NULL;
  259. struct blob_attr *tb[__DEV_STATE_MAX];
  260. struct blob_attr *cur;
  261. blobmsg_parse(dev_state_policy, __DEV_STATE_MAX, tb, blob_data(msg), blob_len(msg));
  262. cur = tb[DEV_STATE_NAME];
  263. if (!cur)
  264. return UBUS_STATUS_INVALID_ARGUMENT;
  265. dev = device_find(blobmsg_data(cur));
  266. if (!dev)
  267. return UBUS_STATUS_NOT_FOUND;
  268. cur = tb[DEV_STATE_DEFER];
  269. if (cur)
  270. device_set_deferred(dev, !!blobmsg_get_u8(cur));
  271. cur = tb[DEV_STATE_AUTH_STATUS];
  272. if (cur)
  273. device_set_auth_status(dev, !!blobmsg_get_u8(cur));
  274. return 0;
  275. }
  276. #ifdef DUMMY_MODE
  277. enum {
  278. DEV_HOTPLUG_ATTR_NAME,
  279. DEV_HOTPLUG_ATTR_ADD,
  280. __DEV_HOTPLUG_ATTR_MAX,
  281. };
  282. static const struct blobmsg_policy dev_hotplug_policy[__DEV_HOTPLUG_ATTR_MAX] = {
  283. [DEV_HOTPLUG_ATTR_NAME] = { "name", BLOBMSG_TYPE_STRING },
  284. [DEV_HOTPLUG_ATTR_ADD] = { "add", BLOBMSG_TYPE_BOOL },
  285. };
  286. static int
  287. netifd_handle_dev_hotplug(struct ubus_context *ctx, struct ubus_object *obj,
  288. struct ubus_request_data *req, const char *method,
  289. struct blob_attr *msg)
  290. {
  291. struct blob_attr *tb[__DEV_HOTPLUG_ATTR_MAX];
  292. const char *name;
  293. blobmsg_parse(dev_hotplug_policy, __DEV_HOTPLUG_ATTR_MAX, tb,
  294. blob_data(msg), blob_len(msg));
  295. if (!tb[DEV_HOTPLUG_ATTR_NAME] || !tb[DEV_HOTPLUG_ATTR_ADD])
  296. return UBUS_STATUS_INVALID_ARGUMENT;
  297. name = blobmsg_get_string(tb[DEV_HOTPLUG_ATTR_NAME]);
  298. device_hotplug_event(name, blobmsg_get_bool(tb[DEV_HOTPLUG_ATTR_ADD]));
  299. return 0;
  300. }
  301. #endif
  302. static int
  303. netifd_handle_stp_init(struct ubus_context *ctx, struct ubus_object *obj,
  304. struct ubus_request_data *req, const char *method,
  305. struct blob_attr *msg)
  306. {
  307. device_stp_init();
  308. return 0;
  309. }
  310. static struct ubus_method dev_object_methods[] = {
  311. UBUS_METHOD("status", netifd_dev_status, dev_policy),
  312. UBUS_METHOD("set_alias", netifd_handle_alias, alias_attrs),
  313. UBUS_METHOD("set_state", netifd_handle_set_state, dev_state_policy),
  314. #ifdef DUMMY_MODE
  315. UBUS_METHOD("hotplug_event", netifd_handle_dev_hotplug, dev_hotplug_policy),
  316. #endif
  317. UBUS_METHOD_NOARG("stp_init", netifd_handle_stp_init)
  318. };
  319. static struct ubus_object_type dev_object_type =
  320. UBUS_OBJECT_TYPE("device", dev_object_methods);
  321. static struct ubus_object dev_object = {
  322. .name = "network.device",
  323. .type = &dev_object_type,
  324. .methods = dev_object_methods,
  325. .n_methods = ARRAY_SIZE(dev_object_methods),
  326. };
  327. static void
  328. netifd_ubus_add_fd(void)
  329. {
  330. ubus_add_uloop(ubus_ctx);
  331. system_fd_set_cloexec(ubus_ctx->sock.fd);
  332. }
  333. void netifd_ubus_device_notify(const char *event, struct blob_attr *data, int timeout)
  334. {
  335. ubus_notify(ubus_ctx, &dev_object, event, data, timeout);
  336. }
  337. static void
  338. netifd_ubus_reconnect_timer(struct uloop_timeout *timeout)
  339. {
  340. static struct uloop_timeout retry = {
  341. .cb = netifd_ubus_reconnect_timer,
  342. };
  343. int t = 2;
  344. if (ubus_reconnect(ubus_ctx, ubus_path) != 0) {
  345. DPRINTF("failed to reconnect, trying again in %d seconds\n", t);
  346. uloop_timeout_set(&retry, t * 1000);
  347. return;
  348. }
  349. DPRINTF("reconnected to ubus, new id: %08x\n", ubus_ctx->local_id);
  350. netifd_ubus_add_fd();
  351. }
  352. static void
  353. netifd_ubus_connection_lost(struct ubus_context *ctx)
  354. {
  355. netifd_ubus_reconnect_timer(NULL);
  356. }
  357. /* per-interface object */
  358. static int
  359. netifd_handle_up(struct ubus_context *ctx, struct ubus_object *obj,
  360. struct ubus_request_data *req, const char *method,
  361. struct blob_attr *msg)
  362. {
  363. struct interface *iface;
  364. iface = container_of(obj, struct interface, ubus);
  365. interface_set_up(iface);
  366. return 0;
  367. }
  368. static int
  369. netifd_handle_down(struct ubus_context *ctx, struct ubus_object *obj,
  370. struct ubus_request_data *req, const char *method,
  371. struct blob_attr *msg)
  372. {
  373. struct interface *iface;
  374. iface = container_of(obj, struct interface, ubus);
  375. interface_set_down(iface);
  376. return 0;
  377. }
  378. static int
  379. netifd_handle_renew(struct ubus_context *ctx, struct ubus_object *obj,
  380. struct ubus_request_data *req, const char *method,
  381. struct blob_attr *msg)
  382. {
  383. struct interface *iface;
  384. iface = container_of(obj, struct interface, ubus);
  385. interface_renew(iface);
  386. return 0;
  387. }
  388. static void
  389. netifd_add_interface_errors(struct blob_buf *b, struct interface *iface)
  390. {
  391. struct interface_error *error;
  392. void *e, *e2, *e3;
  393. int i;
  394. e = blobmsg_open_array(b, "errors");
  395. list_for_each_entry(error, &iface->errors, list) {
  396. e2 = blobmsg_open_table(b, NULL);
  397. blobmsg_add_string(b, "subsystem", error->subsystem);
  398. blobmsg_add_string(b, "code", error->code);
  399. if (error->data[0]) {
  400. e3 = blobmsg_open_array(b, "data");
  401. for (i = 0; error->data[i]; i++)
  402. blobmsg_add_string(b, NULL, error->data[i]);
  403. blobmsg_close_array(b, e3);
  404. }
  405. blobmsg_close_table(b, e2);
  406. }
  407. blobmsg_close_array(b, e);
  408. }
  409. static void
  410. interface_ip_dump_address_list(struct interface_ip_settings *ip, bool v6, bool enabled)
  411. {
  412. struct device_addr *addr;
  413. char *buf;
  414. void *a;
  415. int buflen = 128;
  416. int af;
  417. time_t now = system_get_rtime();
  418. vlist_for_each_element(&ip->addr, addr, node) {
  419. if (addr->enabled != enabled)
  420. continue;
  421. if ((addr->flags & DEVADDR_FAMILY) == DEVADDR_INET4)
  422. af = AF_INET;
  423. else
  424. af = AF_INET6;
  425. if (af != (v6 ? AF_INET6 : AF_INET))
  426. continue;
  427. a = blobmsg_open_table(&b, NULL);
  428. buf = blobmsg_alloc_string_buffer(&b, "address", buflen);
  429. inet_ntop(af, &addr->addr, buf, buflen);
  430. blobmsg_add_string_buffer(&b);
  431. blobmsg_add_u32(&b, "mask", addr->mask);
  432. if (addr->point_to_point) {
  433. buf = blobmsg_alloc_string_buffer(&b, "ptpaddress", buflen);
  434. inet_ntop(af, &addr->point_to_point, buf, buflen);
  435. blobmsg_add_string_buffer(&b);
  436. }
  437. if (addr->preferred_until) {
  438. int preferred = addr->preferred_until - now;
  439. if (preferred < 0)
  440. preferred = 0;
  441. blobmsg_add_u32(&b, "preferred", preferred);
  442. }
  443. if (addr->valid_until)
  444. blobmsg_add_u32(&b, "valid", addr->valid_until - now);
  445. if (addr->pclass)
  446. blobmsg_add_string(&b, "class", addr->pclass);
  447. blobmsg_close_table(&b, a);
  448. }
  449. }
  450. static void
  451. interface_ip_dump_neighbor_list(struct interface_ip_settings *ip, bool enabled)
  452. {
  453. struct device_neighbor *neighbor;
  454. int buflen = 128;
  455. char *buf;
  456. void *r;
  457. int af;
  458. vlist_for_each_element(&ip->neighbor, neighbor, node) {
  459. if (neighbor->enabled != enabled)
  460. continue;
  461. if ((neighbor->flags & DEVADDR_FAMILY) == DEVADDR_INET4)
  462. af = AF_INET;
  463. else
  464. af = AF_INET6;
  465. r = blobmsg_open_table(&b, NULL);
  466. if (neighbor->flags & DEVNEIGH_MAC)
  467. blobmsg_add_string(&b, "mac", format_macaddr(neighbor->macaddr));
  468. buf = blobmsg_alloc_string_buffer(&b , "address", buflen);
  469. inet_ntop(af, &neighbor->addr, buf, buflen);
  470. blobmsg_add_string_buffer(&b);
  471. if (neighbor->proxy)
  472. blobmsg_add_u32(&b, "proxy", neighbor->proxy);
  473. if (neighbor->router)
  474. blobmsg_add_u32(&b, "router", neighbor->router);
  475. blobmsg_close_table(&b, r);
  476. }
  477. }
  478. static void
  479. interface_ip_dump_route_list(struct interface_ip_settings *ip, bool enabled)
  480. {
  481. struct device_route *route;
  482. int buflen = 128;
  483. char *buf;
  484. void *r;
  485. int af;
  486. time_t now = system_get_rtime();
  487. vlist_for_each_element(&ip->route, route, node) {
  488. if (route->enabled != enabled)
  489. continue;
  490. if ((ip->no_defaultroute == enabled) && !route->mask)
  491. continue;
  492. if ((route->flags & DEVADDR_FAMILY) == DEVADDR_INET4)
  493. af = AF_INET;
  494. else
  495. af = AF_INET6;
  496. r = blobmsg_open_table(&b, NULL);
  497. buf = blobmsg_alloc_string_buffer(&b, "target", buflen);
  498. inet_ntop(af, &route->addr, buf, buflen);
  499. blobmsg_add_string_buffer(&b);
  500. blobmsg_add_u32(&b, "mask", route->mask);
  501. buf = blobmsg_alloc_string_buffer(&b, "nexthop", buflen);
  502. inet_ntop(af, &route->nexthop, buf, buflen);
  503. blobmsg_add_string_buffer(&b);
  504. if (route->flags & DEVROUTE_TYPE)
  505. blobmsg_add_u32(&b, "type", route->type);
  506. if (route->flags & DEVROUTE_PROTO)
  507. blobmsg_add_u32(&b, "proto", route->proto);
  508. if (route->flags & DEVROUTE_MTU)
  509. blobmsg_add_u32(&b, "mtu", route->mtu);
  510. if (route->flags & DEVROUTE_METRIC)
  511. blobmsg_add_u32(&b, "metric", route->metric);
  512. if (route->flags & DEVROUTE_TABLE)
  513. blobmsg_add_u32(&b, "table", route->table);
  514. if (route->valid_until)
  515. blobmsg_add_u32(&b, "valid", route->valid_until - now);
  516. buf = blobmsg_alloc_string_buffer(&b, "source", buflen);
  517. inet_ntop(af, &route->source, buf, buflen);
  518. snprintf(buf + strlen(buf), buflen - strlen(buf), "/%u", route->sourcemask);
  519. blobmsg_add_string_buffer(&b);
  520. blobmsg_close_table(&b, r);
  521. }
  522. }
  523. static void
  524. interface_ip_dump_prefix_list(struct interface_ip_settings *ip)
  525. {
  526. struct device_prefix *prefix;
  527. char *buf;
  528. void *a, *c;
  529. const int buflen = INET6_ADDRSTRLEN;
  530. time_t now = system_get_rtime();
  531. vlist_for_each_element(&ip->prefix, prefix, node) {
  532. a = blobmsg_open_table(&b, NULL);
  533. buf = blobmsg_alloc_string_buffer(&b, "address", buflen);
  534. inet_ntop(AF_INET6, &prefix->addr, buf, buflen);
  535. blobmsg_add_string_buffer(&b);
  536. blobmsg_add_u32(&b, "mask", prefix->length);
  537. if (prefix->preferred_until) {
  538. int preferred = prefix->preferred_until - now;
  539. if (preferred < 0)
  540. preferred = 0;
  541. blobmsg_add_u32(&b, "preferred", preferred);
  542. }
  543. if (prefix->valid_until)
  544. blobmsg_add_u32(&b, "valid", prefix->valid_until - now);
  545. blobmsg_add_string(&b, "class", prefix->pclass);
  546. c = blobmsg_open_table(&b, "assigned");
  547. struct device_prefix_assignment *assign;
  548. list_for_each_entry(assign, &prefix->assignments, head) {
  549. if (!assign->name[0])
  550. continue;
  551. struct in6_addr addr = prefix->addr;
  552. addr.s6_addr32[1] |= htonl(assign->assigned);
  553. void *d = blobmsg_open_table(&b, assign->name);
  554. buf = blobmsg_alloc_string_buffer(&b, "address", buflen);
  555. inet_ntop(AF_INET6, &addr, buf, buflen);
  556. blobmsg_add_string_buffer(&b);
  557. blobmsg_add_u32(&b, "mask", assign->length);
  558. blobmsg_close_table(&b, d);
  559. }
  560. blobmsg_close_table(&b, c);
  561. blobmsg_close_table(&b, a);
  562. }
  563. }
  564. static void
  565. interface_ip_dump_prefix_assignment_list(struct interface *iface)
  566. {
  567. void *a;
  568. char *buf;
  569. const int buflen = INET6_ADDRSTRLEN;
  570. time_t now = system_get_rtime();
  571. struct device_prefix *prefix;
  572. list_for_each_entry(prefix, &prefixes, head) {
  573. struct device_prefix_assignment *assign;
  574. list_for_each_entry(assign, &prefix->assignments, head) {
  575. if (strcmp(assign->name, iface->name))
  576. continue;
  577. struct in6_addr addr = prefix->addr;
  578. addr.s6_addr32[1] |= htonl(assign->assigned);
  579. a = blobmsg_open_table(&b, NULL);
  580. buf = blobmsg_alloc_string_buffer(&b, "address", buflen);
  581. inet_ntop(AF_INET6, &addr, buf, buflen);
  582. blobmsg_add_string_buffer(&b);
  583. blobmsg_add_u32(&b, "mask", assign->length);
  584. if (prefix->preferred_until) {
  585. int preferred = prefix->preferred_until - now;
  586. if (preferred < 0)
  587. preferred = 0;
  588. blobmsg_add_u32(&b, "preferred", preferred);
  589. }
  590. if (prefix->valid_until)
  591. blobmsg_add_u32(&b, "valid", prefix->valid_until - now);
  592. void *c = blobmsg_open_table(&b, "local-address");
  593. if (assign->enabled) {
  594. buf = blobmsg_alloc_string_buffer(&b, "address", buflen);
  595. inet_ntop(AF_INET6, &assign->addr, buf, buflen);
  596. blobmsg_add_string_buffer(&b);
  597. blobmsg_add_u32(&b, "mask", assign->length);
  598. }
  599. blobmsg_close_table(&b, c);
  600. blobmsg_close_table(&b, a);
  601. }
  602. }
  603. }
  604. static void
  605. interface_ip_dump_dns_server_list(struct interface_ip_settings *ip, bool enabled)
  606. {
  607. struct dns_server *dns;
  608. int buflen = 128;
  609. char *buf;
  610. vlist_simple_for_each_element(&ip->dns_servers, dns, node) {
  611. if (ip->no_dns == enabled)
  612. continue;
  613. buf = blobmsg_alloc_string_buffer(&b, NULL, buflen);
  614. inet_ntop(dns->af, &dns->addr, buf, buflen);
  615. blobmsg_add_string_buffer(&b);
  616. }
  617. }
  618. static void
  619. interface_ip_dump_dns_search_list(struct interface_ip_settings *ip, bool enabled)
  620. {
  621. struct dns_search_domain *dns;
  622. vlist_simple_for_each_element(&ip->dns_search, dns, node) {
  623. if (ip->no_dns == enabled)
  624. continue;
  625. blobmsg_add_string(&b, NULL, dns->name);
  626. }
  627. }
  628. static void
  629. netifd_dump_status(struct interface *iface)
  630. {
  631. struct interface_data *data;
  632. struct device *dev;
  633. void *a, *inactive;
  634. blobmsg_add_u8(&b, "up", iface->state == IFS_UP);
  635. blobmsg_add_u8(&b, "pending", iface->state == IFS_SETUP);
  636. blobmsg_add_u8(&b, "available", iface->available);
  637. blobmsg_add_u8(&b, "autostart", iface->autostart);
  638. blobmsg_add_u8(&b, "dynamic", iface->dynamic);
  639. if (iface->state == IFS_UP) {
  640. time_t cur = system_get_rtime();
  641. blobmsg_add_u32(&b, "uptime", cur - iface->start_time);
  642. if (iface->l3_dev.dev)
  643. blobmsg_add_string(&b, "l3_device", iface->l3_dev.dev->ifname);
  644. }
  645. if (iface->proto_handler)
  646. blobmsg_add_string(&b, "proto", iface->proto_handler->name);
  647. dev = iface->main_dev.dev;
  648. if (dev && !dev->hidden && iface->proto_handler &&
  649. !(iface->proto_handler->flags & PROTO_FLAG_NODEV))
  650. blobmsg_add_string(&b, "device", dev->ifname);
  651. if (iface->jail)
  652. blobmsg_add_string(&b, "jail", iface->jail);
  653. if (iface->jail_device)
  654. blobmsg_add_string(&b, "jail_device", iface->jail_device);
  655. if (iface->state == IFS_UP) {
  656. if (iface->updated) {
  657. a = blobmsg_open_array(&b, "updated");
  658. if (iface->updated & IUF_ADDRESS)
  659. blobmsg_add_string(&b, NULL, "addresses");
  660. if (iface->updated & IUF_ROUTE)
  661. blobmsg_add_string(&b, NULL, "routes");
  662. if (iface->updated & IUF_PREFIX)
  663. blobmsg_add_string(&b, NULL, "prefixes");
  664. if (iface->updated & IUF_DATA)
  665. blobmsg_add_string(&b, NULL, "data");
  666. blobmsg_close_array(&b, a);
  667. }
  668. if (iface->ip4table)
  669. blobmsg_add_u32(&b, "ip4table", iface->ip4table);
  670. if (iface->ip6table)
  671. blobmsg_add_u32(&b, "ip6table", iface->ip6table);
  672. blobmsg_add_u32(&b, "metric", iface->metric);
  673. blobmsg_add_u32(&b, "dns_metric", iface->dns_metric);
  674. blobmsg_add_u8(&b, "delegation", !iface->proto_ip.no_delegation);
  675. if (iface->assignment_weight)
  676. blobmsg_add_u32(&b, "ip6weight", iface->assignment_weight);
  677. a = blobmsg_open_array(&b, "ipv4-address");
  678. interface_ip_dump_address_list(&iface->config_ip, false, true);
  679. interface_ip_dump_address_list(&iface->proto_ip, false, true);
  680. blobmsg_close_array(&b, a);
  681. a = blobmsg_open_array(&b, "ipv6-address");
  682. interface_ip_dump_address_list(&iface->config_ip, true, true);
  683. interface_ip_dump_address_list(&iface->proto_ip, true, true);
  684. blobmsg_close_array(&b, a);
  685. a = blobmsg_open_array(&b, "ipv6-prefix");
  686. interface_ip_dump_prefix_list(&iface->config_ip);
  687. interface_ip_dump_prefix_list(&iface->proto_ip);
  688. blobmsg_close_array(&b, a);
  689. a = blobmsg_open_array(&b, "ipv6-prefix-assignment");
  690. interface_ip_dump_prefix_assignment_list(iface);
  691. blobmsg_close_array(&b, a);
  692. a = blobmsg_open_array(&b, "route");
  693. interface_ip_dump_route_list(&iface->config_ip, true);
  694. interface_ip_dump_route_list(&iface->proto_ip, true);
  695. blobmsg_close_array(&b, a);
  696. a = blobmsg_open_array(&b, "dns-server");
  697. interface_ip_dump_dns_server_list(&iface->config_ip, true);
  698. interface_ip_dump_dns_server_list(&iface->proto_ip, true);
  699. blobmsg_close_array(&b, a);
  700. a = blobmsg_open_array(&b, "dns-search");
  701. interface_ip_dump_dns_search_list(&iface->config_ip, true);
  702. interface_ip_dump_dns_search_list(&iface->proto_ip, true);
  703. blobmsg_close_array(&b, a);
  704. a = blobmsg_open_array(&b, "neighbors");
  705. interface_ip_dump_neighbor_list(&iface->config_ip, true);
  706. interface_ip_dump_neighbor_list(&iface->proto_ip, true);
  707. blobmsg_close_array(&b, a);
  708. inactive = blobmsg_open_table(&b, "inactive");
  709. a = blobmsg_open_array(&b, "ipv4-address");
  710. interface_ip_dump_address_list(&iface->config_ip, false, false);
  711. interface_ip_dump_address_list(&iface->proto_ip, false, false);
  712. blobmsg_close_array(&b, a);
  713. a = blobmsg_open_array(&b, "ipv6-address");
  714. interface_ip_dump_address_list(&iface->config_ip, true, false);
  715. interface_ip_dump_address_list(&iface->proto_ip, true, false);
  716. blobmsg_close_array(&b, a);
  717. a = blobmsg_open_array(&b, "route");
  718. interface_ip_dump_route_list(&iface->config_ip, false);
  719. interface_ip_dump_route_list(&iface->proto_ip, false);
  720. blobmsg_close_array(&b, a);
  721. a = blobmsg_open_array(&b, "dns-server");
  722. interface_ip_dump_dns_server_list(&iface->config_ip, false);
  723. interface_ip_dump_dns_server_list(&iface->proto_ip, false);
  724. blobmsg_close_array(&b, a);
  725. a = blobmsg_open_array(&b, "dns-search");
  726. interface_ip_dump_dns_search_list(&iface->config_ip, false);
  727. interface_ip_dump_dns_search_list(&iface->proto_ip, false);
  728. blobmsg_close_array(&b, a);
  729. a = blobmsg_open_array(&b, "neighbors");
  730. interface_ip_dump_neighbor_list(&iface->config_ip, false);
  731. interface_ip_dump_neighbor_list(&iface->proto_ip, false);
  732. blobmsg_close_array(&b, a);
  733. blobmsg_close_table(&b, inactive);
  734. }
  735. a = blobmsg_open_table(&b, "data");
  736. if (iface->zone)
  737. blobmsg_add_string(&b, "zone", iface->zone);
  738. avl_for_each_element(&iface->data, data, node)
  739. blobmsg_add_blob(&b, data->data);
  740. blobmsg_close_table(&b, a);
  741. if (!list_empty(&iface->errors))
  742. netifd_add_interface_errors(&b, iface);
  743. }
  744. static int
  745. netifd_handle_status(struct ubus_context *ctx, struct ubus_object *obj,
  746. struct ubus_request_data *req, const char *method,
  747. struct blob_attr *msg)
  748. {
  749. struct interface *iface = container_of(obj, struct interface, ubus);
  750. blob_buf_init(&b, 0);
  751. netifd_dump_status(iface);
  752. ubus_send_reply(ctx, req, b.head);
  753. return 0;
  754. }
  755. static int
  756. netifd_handle_dump(struct ubus_context *ctx, struct ubus_object *obj,
  757. struct ubus_request_data *req, const char *method,
  758. struct blob_attr *msg)
  759. {
  760. blob_buf_init(&b, 0);
  761. void *a = blobmsg_open_array(&b, "interface");
  762. struct interface *iface;
  763. vlist_for_each_element(&interfaces, iface, node) {
  764. void *i = blobmsg_open_table(&b, NULL);
  765. blobmsg_add_string(&b, "interface", iface->name);
  766. netifd_dump_status(iface);
  767. blobmsg_close_table(&b, i);
  768. }
  769. blobmsg_close_array(&b, a);
  770. ubus_send_reply(ctx, req, b.head);
  771. return 0;
  772. }
  773. enum {
  774. DEV_LINK_NAME,
  775. DEV_LINK_EXT,
  776. DEV_LINK_VLAN,
  777. __DEV_LINK_MAX,
  778. };
  779. static const struct blobmsg_policy dev_link_policy[__DEV_LINK_MAX] = {
  780. [DEV_LINK_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING },
  781. [DEV_LINK_EXT] = { .name = "link-ext", .type = BLOBMSG_TYPE_BOOL },
  782. [DEV_LINK_VLAN] = { .name = "vlan", .type = BLOBMSG_TYPE_ARRAY },
  783. };
  784. static int
  785. netifd_iface_handle_device(struct ubus_context *ctx, struct ubus_object *obj,
  786. struct ubus_request_data *req, const char *method,
  787. struct blob_attr *msg)
  788. {
  789. struct blob_attr *tb[__DEV_LINK_MAX];
  790. struct blob_attr *cur;
  791. struct interface *iface;
  792. bool add = !strncmp(method, "add", 3);
  793. bool link_ext = true;
  794. iface = container_of(obj, struct interface, ubus);
  795. blobmsg_parse(dev_link_policy, __DEV_LINK_MAX, tb, blob_data(msg), blob_len(msg));
  796. if (!tb[DEV_LINK_NAME])
  797. return UBUS_STATUS_INVALID_ARGUMENT;
  798. cur = tb[DEV_LINK_EXT];
  799. if (cur)
  800. link_ext = blobmsg_get_bool(cur);
  801. return interface_handle_link(iface, blobmsg_data(tb[DEV_LINK_NAME]),
  802. tb[DEV_LINK_VLAN], add, link_ext);
  803. }
  804. static int
  805. netifd_iface_notify_proto(struct ubus_context *ctx, struct ubus_object *obj,
  806. struct ubus_request_data *req, const char *method,
  807. struct blob_attr *msg)
  808. {
  809. struct interface *iface;
  810. iface = container_of(obj, struct interface, ubus);
  811. if (!iface->proto || !iface->proto->notify)
  812. return UBUS_STATUS_NOT_SUPPORTED;
  813. return iface->proto->notify(iface->proto, msg);
  814. }
  815. static void
  816. netifd_iface_do_remove(struct uloop_timeout *timeout)
  817. {
  818. struct interface *iface;
  819. iface = container_of(timeout, struct interface, remove_timer);
  820. vlist_delete(&interfaces, &iface->node);
  821. }
  822. static int
  823. netifd_iface_remove(struct ubus_context *ctx, struct ubus_object *obj,
  824. struct ubus_request_data *req, const char *method,
  825. struct blob_attr *msg)
  826. {
  827. struct interface *iface;
  828. iface = container_of(obj, struct interface, ubus);
  829. if (iface->remove_timer.cb)
  830. return UBUS_STATUS_INVALID_ARGUMENT;
  831. iface->remove_timer.cb = netifd_iface_do_remove;
  832. uloop_timeout_set(&iface->remove_timer, 100);
  833. return 0;
  834. }
  835. static int
  836. netifd_handle_iface_prepare(struct ubus_context *ctx, struct ubus_object *obj,
  837. struct ubus_request_data *req, const char *method,
  838. struct blob_attr *msg)
  839. {
  840. struct interface *iface;
  841. struct device *dev, *bridge_dev = NULL;
  842. const struct device_hotplug_ops *ops;
  843. iface = container_of(obj, struct interface, ubus);
  844. dev = iface->main_dev.dev;
  845. if (!dev)
  846. goto out;
  847. ops = dev->hotplug_ops;
  848. if (!ops)
  849. goto out;
  850. ops->prepare(dev, &bridge_dev);
  851. out:
  852. blob_buf_init(&b, 0);
  853. if (bridge_dev)
  854. blobmsg_add_string(&b, "bridge", bridge_dev->ifname);
  855. ubus_send_reply(ctx, req, b.head);
  856. return 0;
  857. }
  858. static int
  859. netifd_handle_set_data(struct ubus_context *ctx, struct ubus_object *obj,
  860. struct ubus_request_data *req, const char *method,
  861. struct blob_attr *msg)
  862. {
  863. struct interface *iface;
  864. iface = container_of(obj, struct interface, ubus);
  865. return interface_parse_data(iface, msg);
  866. }
  867. static struct ubus_method iface_object_methods[] = {
  868. { .name = "up", .handler = netifd_handle_up },
  869. { .name = "down", .handler = netifd_handle_down },
  870. { .name = "renew", .handler = netifd_handle_renew },
  871. { .name = "status", .handler = netifd_handle_status },
  872. { .name = "prepare", .handler = netifd_handle_iface_prepare },
  873. { .name = "dump", .handler = netifd_handle_dump },
  874. UBUS_METHOD("add_device", netifd_iface_handle_device, dev_link_policy ),
  875. UBUS_METHOD("remove_device", netifd_iface_handle_device, dev_link_policy ),
  876. { .name = "notify_proto", .handler = netifd_iface_notify_proto },
  877. { .name = "remove", .handler = netifd_iface_remove },
  878. { .name = "set_data", .handler = netifd_handle_set_data },
  879. };
  880. static struct ubus_object_type iface_object_type =
  881. UBUS_OBJECT_TYPE("netifd_iface", iface_object_methods);
  882. static struct ubus_object iface_object = {
  883. .name = "network.interface",
  884. .type = &iface_object_type,
  885. .n_methods = ARRAY_SIZE(iface_object_methods),
  886. };
  887. static void netifd_add_object(struct ubus_object *obj)
  888. {
  889. int ret = ubus_add_object(ubus_ctx, obj);
  890. if (ret != 0)
  891. fprintf(stderr, "Failed to publish object '%s': %s\n", obj->name, ubus_strerror(ret));
  892. }
  893. static const struct blobmsg_policy iface_policy = {
  894. .name = "interface",
  895. .type = BLOBMSG_TYPE_STRING,
  896. };
  897. static int
  898. netifd_handle_iface(struct ubus_context *ctx, struct ubus_object *obj,
  899. struct ubus_request_data *req, const char *method,
  900. struct blob_attr *msg)
  901. {
  902. struct interface *iface;
  903. struct blob_attr *tb;
  904. size_t i;
  905. blobmsg_parse(&iface_policy, 1, &tb, blob_data(msg), blob_len(msg));
  906. if (!tb)
  907. return UBUS_STATUS_INVALID_ARGUMENT;
  908. iface = vlist_find(&interfaces, blobmsg_data(tb), iface, node);
  909. if (!iface)
  910. return UBUS_STATUS_NOT_FOUND;
  911. for (i = 0; i < ARRAY_SIZE(iface_object_methods); i++) {
  912. ubus_handler_t cb;
  913. if (strcmp(method, iface_object_methods[i].name) != 0)
  914. continue;
  915. cb = iface_object_methods[i].handler;
  916. return cb(ctx, &iface->ubus, req, method, msg);
  917. }
  918. return UBUS_STATUS_INVALID_ARGUMENT;
  919. }
  920. static void netifd_add_iface_object(void)
  921. {
  922. struct ubus_method *methods;
  923. size_t i;
  924. methods = calloc(1, sizeof(iface_object_methods));
  925. if (!methods)
  926. return;
  927. memcpy(methods, iface_object_methods, sizeof(iface_object_methods));
  928. iface_object.methods = methods;
  929. for (i = 0; i < ARRAY_SIZE(iface_object_methods); i++) {
  930. if (methods[i].handler == netifd_handle_dump)
  931. continue;
  932. methods[i].handler = netifd_handle_iface;
  933. methods[i].policy = &iface_policy;
  934. methods[i].n_policy = 1;
  935. }
  936. netifd_add_object(&iface_object);
  937. }
  938. static struct wireless_device *
  939. get_wdev(struct blob_attr *msg, int *ret)
  940. {
  941. struct blobmsg_policy wdev_policy = {
  942. .name = "device",
  943. .type = BLOBMSG_TYPE_STRING,
  944. };
  945. struct blob_attr *dev_attr;
  946. struct wireless_device *wdev = NULL;
  947. blobmsg_parse(&wdev_policy, 1, &dev_attr, blob_data(msg), blob_len(msg));
  948. if (!dev_attr) {
  949. *ret = UBUS_STATUS_INVALID_ARGUMENT;
  950. return NULL;
  951. }
  952. wdev = vlist_find(&wireless_devices, blobmsg_data(dev_attr), wdev, node);
  953. if (!wdev) {
  954. *ret = UBUS_STATUS_NOT_FOUND;
  955. return NULL;
  956. }
  957. *ret = 0;
  958. return wdev;
  959. }
  960. static int
  961. netifd_handle_wdev_reconf(struct ubus_context *ctx, struct ubus_object *obj,
  962. struct ubus_request_data *req, const char *method,
  963. struct blob_attr *msg)
  964. {
  965. struct wireless_device *wdev;
  966. int ret;
  967. wdev = get_wdev(msg, &ret);
  968. if (ret == UBUS_STATUS_NOT_FOUND)
  969. return ret;
  970. if (wdev) {
  971. wireless_device_reconf(wdev);
  972. } else {
  973. vlist_for_each_element(&wireless_devices, wdev, node)
  974. wireless_device_reconf(wdev);
  975. }
  976. return 0;
  977. }
  978. static int
  979. netifd_handle_wdev_up(struct ubus_context *ctx, struct ubus_object *obj,
  980. struct ubus_request_data *req, const char *method,
  981. struct blob_attr *msg)
  982. {
  983. struct wireless_device *wdev;
  984. int ret;
  985. wdev = get_wdev(msg, &ret);
  986. if (ret == UBUS_STATUS_NOT_FOUND)
  987. return ret;
  988. if (wdev) {
  989. wireless_device_set_up(wdev);
  990. } else {
  991. vlist_for_each_element(&wireless_devices, wdev, node)
  992. wireless_device_set_up(wdev);
  993. }
  994. return 0;
  995. }
  996. static int
  997. netifd_handle_wdev_down(struct ubus_context *ctx, struct ubus_object *obj,
  998. struct ubus_request_data *req, const char *method,
  999. struct blob_attr *msg)
  1000. {
  1001. struct wireless_device *wdev;
  1002. int ret;
  1003. wdev = get_wdev(msg, &ret);
  1004. if (ret == UBUS_STATUS_NOT_FOUND)
  1005. return ret;
  1006. if (wdev) {
  1007. wireless_device_set_down(wdev);
  1008. } else {
  1009. vlist_for_each_element(&wireless_devices, wdev, node)
  1010. wireless_device_set_down(wdev);
  1011. }
  1012. return 0;
  1013. }
  1014. static int
  1015. netifd_handle_wdev_status(struct ubus_context *ctx, struct ubus_object *obj,
  1016. struct ubus_request_data *req, const char *method,
  1017. struct blob_attr *msg)
  1018. {
  1019. struct wireless_device *wdev;
  1020. int ret;
  1021. wdev = get_wdev(msg, &ret);
  1022. if (ret == UBUS_STATUS_NOT_FOUND)
  1023. return ret;
  1024. blob_buf_init(&b, 0);
  1025. if (wdev) {
  1026. wireless_device_status(wdev, &b);
  1027. } else {
  1028. vlist_for_each_element(&wireless_devices, wdev, node)
  1029. wireless_device_status(wdev, &b);
  1030. }
  1031. ubus_send_reply(ctx, req, b.head);
  1032. return 0;
  1033. }
  1034. static int
  1035. netifd_handle_wdev_get_validate(struct ubus_context *ctx, struct ubus_object *obj,
  1036. struct ubus_request_data *req, const char *method,
  1037. struct blob_attr *msg)
  1038. {
  1039. struct wireless_device *wdev;
  1040. int ret;
  1041. wdev = get_wdev(msg, &ret);
  1042. if (ret == UBUS_STATUS_NOT_FOUND)
  1043. return ret;
  1044. blob_buf_init(&b, 0);
  1045. if (wdev) {
  1046. wireless_device_get_validate(wdev, &b);
  1047. } else {
  1048. vlist_for_each_element(&wireless_devices, wdev, node)
  1049. wireless_device_get_validate(wdev, &b);
  1050. }
  1051. ubus_send_reply(ctx, req, b.head);
  1052. return 0;
  1053. }
  1054. static int
  1055. netifd_handle_wdev_notify(struct ubus_context *ctx, struct ubus_object *obj,
  1056. struct ubus_request_data *req, const char *method,
  1057. struct blob_attr *msg)
  1058. {
  1059. struct wireless_device *wdev;
  1060. int ret;
  1061. wdev = get_wdev(msg, &ret);
  1062. if (!wdev)
  1063. return ret;
  1064. return wireless_device_notify(wdev, msg, req);
  1065. }
  1066. static struct ubus_method wireless_object_methods[] = {
  1067. { .name = "up", .handler = netifd_handle_wdev_up },
  1068. { .name = "down", .handler = netifd_handle_wdev_down },
  1069. { .name = "reconf", .handler = netifd_handle_wdev_reconf },
  1070. { .name = "status", .handler = netifd_handle_wdev_status },
  1071. { .name = "notify", .handler = netifd_handle_wdev_notify },
  1072. { .name = "get_validate", .handler = netifd_handle_wdev_get_validate },
  1073. };
  1074. static struct ubus_object_type wireless_object_type =
  1075. UBUS_OBJECT_TYPE("netifd_iface", wireless_object_methods);
  1076. static struct ubus_object wireless_object = {
  1077. .name = "network.wireless",
  1078. .type = &wireless_object_type,
  1079. .methods = wireless_object_methods,
  1080. .n_methods = ARRAY_SIZE(wireless_object_methods),
  1081. };
  1082. int
  1083. netifd_extdev_invoke(uint32_t id, const char *method, struct blob_attr *msg,
  1084. ubus_data_handler_t data_cb, void *data)
  1085. {
  1086. return ubus_invoke(ubus_ctx, id, method, msg, data_cb, data, 3000);
  1087. }
  1088. int
  1089. netifd_ubus_init(const char *path)
  1090. {
  1091. uloop_init();
  1092. ubus_path = path;
  1093. ubus_ctx = ubus_connect(path);
  1094. if (!ubus_ctx)
  1095. return -EIO;
  1096. DPRINTF("connected as %08x\n", ubus_ctx->local_id);
  1097. ubus_ctx->connection_lost = netifd_ubus_connection_lost;
  1098. netifd_ubus_add_fd();
  1099. netifd_add_object(&main_object);
  1100. netifd_add_object(&dev_object);
  1101. netifd_add_object(&wireless_object);
  1102. netifd_add_iface_object();
  1103. return 0;
  1104. }
  1105. void
  1106. netifd_ubus_done(void)
  1107. {
  1108. ubus_free(ubus_ctx);
  1109. }
  1110. void
  1111. netifd_ubus_interface_event(struct interface *iface, bool up)
  1112. {
  1113. blob_buf_init(&b, 0);
  1114. blobmsg_add_string(&b, "action", up ? "ifup" : "ifdown");
  1115. blobmsg_add_string(&b, "interface", iface->name);
  1116. ubus_send_event(ubus_ctx, "network.interface", b.head);
  1117. }
  1118. void
  1119. netifd_ubus_interface_notify(struct interface *iface, bool up)
  1120. {
  1121. const char *event = (up) ? "interface.update" : "interface.down";
  1122. blob_buf_init(&b, 0);
  1123. blobmsg_add_string(&b, "interface", iface->name);
  1124. netifd_dump_status(iface);
  1125. ubus_notify(ubus_ctx, &iface_object, event, b.head, -1);
  1126. ubus_notify(ubus_ctx, &iface->ubus, event, b.head, -1);
  1127. }
  1128. void
  1129. netifd_ubus_add_interface(struct interface *iface)
  1130. {
  1131. struct ubus_object *obj = &iface->ubus;
  1132. char *name = NULL;
  1133. if (asprintf(&name, "%s.interface.%s", main_object.name, iface->name) == -1)
  1134. return;
  1135. obj->name = name;
  1136. obj->type = &iface_object_type;
  1137. obj->methods = iface_object_methods;
  1138. obj->n_methods = ARRAY_SIZE(iface_object_methods);
  1139. if (ubus_add_object(ubus_ctx, &iface->ubus)) {
  1140. DPRINTF("failed to publish ubus object for interface '%s'\n", iface->name);
  1141. free(name);
  1142. obj->name = NULL;
  1143. }
  1144. }
  1145. void
  1146. netifd_ubus_remove_interface(struct interface *iface)
  1147. {
  1148. if (!iface->ubus.name)
  1149. return;
  1150. ubus_remove_object(ubus_ctx, &iface->ubus);
  1151. free((void *) iface->ubus.name);
  1152. }