ubus.c 35 KB

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