ubus.c 37 KB

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