ubus.c 34 KB

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