ubus.c 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364
  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->jail_ifname)
  603. blobmsg_add_string(&b, "jail_ifname", iface->jail_ifname);
  604. if (iface->state == IFS_UP) {
  605. if (iface->updated) {
  606. a = blobmsg_open_array(&b, "updated");
  607. if (iface->updated & IUF_ADDRESS)
  608. blobmsg_add_string(&b, NULL, "addresses");
  609. if (iface->updated & IUF_ROUTE)
  610. blobmsg_add_string(&b, NULL, "routes");
  611. if (iface->updated & IUF_PREFIX)
  612. blobmsg_add_string(&b, NULL, "prefixes");
  613. if (iface->updated & IUF_DATA)
  614. blobmsg_add_string(&b, NULL, "data");
  615. blobmsg_close_array(&b, a);
  616. }
  617. if (iface->ip4table)
  618. blobmsg_add_u32(&b, "ip4table", iface->ip4table);
  619. if (iface->ip6table)
  620. blobmsg_add_u32(&b, "ip6table", iface->ip6table);
  621. blobmsg_add_u32(&b, "metric", iface->metric);
  622. blobmsg_add_u32(&b, "dns_metric", iface->dns_metric);
  623. blobmsg_add_u8(&b, "delegation", !iface->proto_ip.no_delegation);
  624. if (iface->assignment_weight)
  625. blobmsg_add_u32(&b, "ip6weight", iface->assignment_weight);
  626. a = blobmsg_open_array(&b, "ipv4-address");
  627. interface_ip_dump_address_list(&iface->config_ip, false, true);
  628. interface_ip_dump_address_list(&iface->proto_ip, false, true);
  629. blobmsg_close_array(&b, a);
  630. a = blobmsg_open_array(&b, "ipv6-address");
  631. interface_ip_dump_address_list(&iface->config_ip, true, true);
  632. interface_ip_dump_address_list(&iface->proto_ip, true, true);
  633. blobmsg_close_array(&b, a);
  634. a = blobmsg_open_array(&b, "ipv6-prefix");
  635. interface_ip_dump_prefix_list(&iface->config_ip);
  636. interface_ip_dump_prefix_list(&iface->proto_ip);
  637. blobmsg_close_array(&b, a);
  638. a = blobmsg_open_array(&b, "ipv6-prefix-assignment");
  639. interface_ip_dump_prefix_assignment_list(iface);
  640. blobmsg_close_array(&b, a);
  641. a = blobmsg_open_array(&b, "route");
  642. interface_ip_dump_route_list(&iface->config_ip, true);
  643. interface_ip_dump_route_list(&iface->proto_ip, true);
  644. blobmsg_close_array(&b, a);
  645. a = blobmsg_open_array(&b, "dns-server");
  646. interface_ip_dump_dns_server_list(&iface->config_ip, true);
  647. interface_ip_dump_dns_server_list(&iface->proto_ip, true);
  648. blobmsg_close_array(&b, a);
  649. a = blobmsg_open_array(&b, "dns-search");
  650. interface_ip_dump_dns_search_list(&iface->config_ip, true);
  651. interface_ip_dump_dns_search_list(&iface->proto_ip, true);
  652. blobmsg_close_array(&b, a);
  653. a = blobmsg_open_array(&b, "neighbors");
  654. interface_ip_dump_neighbor_list(&iface->config_ip, true);
  655. interface_ip_dump_neighbor_list(&iface->proto_ip, true);
  656. blobmsg_close_array(&b, a);
  657. inactive = blobmsg_open_table(&b, "inactive");
  658. a = blobmsg_open_array(&b, "ipv4-address");
  659. interface_ip_dump_address_list(&iface->config_ip, false, false);
  660. interface_ip_dump_address_list(&iface->proto_ip, false, false);
  661. blobmsg_close_array(&b, a);
  662. a = blobmsg_open_array(&b, "ipv6-address");
  663. interface_ip_dump_address_list(&iface->config_ip, true, false);
  664. interface_ip_dump_address_list(&iface->proto_ip, true, false);
  665. blobmsg_close_array(&b, a);
  666. a = blobmsg_open_array(&b, "route");
  667. interface_ip_dump_route_list(&iface->config_ip, false);
  668. interface_ip_dump_route_list(&iface->proto_ip, false);
  669. blobmsg_close_array(&b, a);
  670. a = blobmsg_open_array(&b, "dns-server");
  671. interface_ip_dump_dns_server_list(&iface->config_ip, false);
  672. interface_ip_dump_dns_server_list(&iface->proto_ip, false);
  673. blobmsg_close_array(&b, a);
  674. a = blobmsg_open_array(&b, "dns-search");
  675. interface_ip_dump_dns_search_list(&iface->config_ip, false);
  676. interface_ip_dump_dns_search_list(&iface->proto_ip, false);
  677. blobmsg_close_array(&b, a);
  678. a = blobmsg_open_array(&b, "neighbors");
  679. interface_ip_dump_neighbor_list(&iface->config_ip, false);
  680. interface_ip_dump_neighbor_list(&iface->proto_ip, false);
  681. blobmsg_close_array(&b, a);
  682. blobmsg_close_table(&b, inactive);
  683. }
  684. a = blobmsg_open_table(&b, "data");
  685. avl_for_each_element(&iface->data, data, node)
  686. blobmsg_add_blob(&b, data->data);
  687. blobmsg_close_table(&b, a);
  688. if (!list_empty(&iface->errors))
  689. netifd_add_interface_errors(&b, iface);
  690. }
  691. static int
  692. netifd_handle_status(struct ubus_context *ctx, struct ubus_object *obj,
  693. struct ubus_request_data *req, const char *method,
  694. struct blob_attr *msg)
  695. {
  696. struct interface *iface = container_of(obj, struct interface, ubus);
  697. blob_buf_init(&b, 0);
  698. netifd_dump_status(iface);
  699. ubus_send_reply(ctx, req, b.head);
  700. return 0;
  701. }
  702. static int
  703. netifd_handle_dump(struct ubus_context *ctx, struct ubus_object *obj,
  704. struct ubus_request_data *req, const char *method,
  705. struct blob_attr *msg)
  706. {
  707. blob_buf_init(&b, 0);
  708. void *a = blobmsg_open_array(&b, "interface");
  709. struct interface *iface;
  710. vlist_for_each_element(&interfaces, iface, node) {
  711. void *i = blobmsg_open_table(&b, NULL);
  712. blobmsg_add_string(&b, "interface", iface->name);
  713. netifd_dump_status(iface);
  714. blobmsg_close_table(&b, i);
  715. }
  716. blobmsg_close_array(&b, a);
  717. ubus_send_reply(ctx, req, b.head);
  718. return 0;
  719. }
  720. enum {
  721. DEV_LINK_NAME,
  722. DEV_LINK_EXT,
  723. DEV_LINK_VLAN,
  724. __DEV_LINK_MAX,
  725. };
  726. static const struct blobmsg_policy dev_link_policy[__DEV_LINK_MAX] = {
  727. [DEV_LINK_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING },
  728. [DEV_LINK_EXT] = { .name = "link-ext", .type = BLOBMSG_TYPE_BOOL },
  729. [DEV_LINK_VLAN] = { .name = "vlan", .type = BLOBMSG_TYPE_ARRAY },
  730. };
  731. static int
  732. netifd_iface_handle_device(struct ubus_context *ctx, struct ubus_object *obj,
  733. struct ubus_request_data *req, const char *method,
  734. struct blob_attr *msg)
  735. {
  736. struct blob_attr *tb[__DEV_LINK_MAX];
  737. struct blob_attr *cur;
  738. struct interface *iface;
  739. bool add = !strncmp(method, "add", 3);
  740. bool link_ext = true;
  741. iface = container_of(obj, struct interface, ubus);
  742. blobmsg_parse(dev_link_policy, __DEV_LINK_MAX, tb, blob_data(msg), blob_len(msg));
  743. if (!tb[DEV_LINK_NAME])
  744. return UBUS_STATUS_INVALID_ARGUMENT;
  745. cur = tb[DEV_LINK_EXT];
  746. if (cur)
  747. link_ext = blobmsg_get_bool(cur);
  748. return interface_handle_link(iface, blobmsg_data(tb[DEV_LINK_NAME]),
  749. tb[DEV_LINK_VLAN], add, link_ext);
  750. }
  751. static int
  752. netifd_iface_notify_proto(struct ubus_context *ctx, struct ubus_object *obj,
  753. struct ubus_request_data *req, const char *method,
  754. struct blob_attr *msg)
  755. {
  756. struct interface *iface;
  757. iface = container_of(obj, struct interface, ubus);
  758. if (!iface->proto || !iface->proto->notify)
  759. return UBUS_STATUS_NOT_SUPPORTED;
  760. return iface->proto->notify(iface->proto, msg);
  761. }
  762. static void
  763. netifd_iface_do_remove(struct uloop_timeout *timeout)
  764. {
  765. struct interface *iface;
  766. iface = container_of(timeout, struct interface, remove_timer);
  767. vlist_delete(&interfaces, &iface->node);
  768. }
  769. static int
  770. netifd_iface_remove(struct ubus_context *ctx, struct ubus_object *obj,
  771. struct ubus_request_data *req, const char *method,
  772. struct blob_attr *msg)
  773. {
  774. struct interface *iface;
  775. iface = container_of(obj, struct interface, ubus);
  776. if (iface->remove_timer.cb)
  777. return UBUS_STATUS_INVALID_ARGUMENT;
  778. iface->remove_timer.cb = netifd_iface_do_remove;
  779. uloop_timeout_set(&iface->remove_timer, 100);
  780. return 0;
  781. }
  782. static int
  783. netifd_handle_iface_prepare(struct ubus_context *ctx, struct ubus_object *obj,
  784. struct ubus_request_data *req, const char *method,
  785. struct blob_attr *msg)
  786. {
  787. struct interface *iface;
  788. struct device *dev, *bridge_dev = NULL;
  789. const struct device_hotplug_ops *ops;
  790. iface = container_of(obj, struct interface, ubus);
  791. dev = iface->main_dev.dev;
  792. if (!dev)
  793. goto out;
  794. ops = dev->hotplug_ops;
  795. if (!ops)
  796. goto out;
  797. ops->prepare(dev, &bridge_dev);
  798. out:
  799. blob_buf_init(&b, 0);
  800. if (bridge_dev)
  801. blobmsg_add_string(&b, "bridge", bridge_dev->ifname);
  802. ubus_send_reply(ctx, req, b.head);
  803. return 0;
  804. }
  805. static int
  806. netifd_handle_set_data(struct ubus_context *ctx, struct ubus_object *obj,
  807. struct ubus_request_data *req, const char *method,
  808. struct blob_attr *msg)
  809. {
  810. struct interface *iface;
  811. iface = container_of(obj, struct interface, ubus);
  812. return interface_parse_data(iface, msg);
  813. }
  814. static struct ubus_method iface_object_methods[] = {
  815. { .name = "up", .handler = netifd_handle_up },
  816. { .name = "down", .handler = netifd_handle_down },
  817. { .name = "renew", .handler = netifd_handle_renew },
  818. { .name = "status", .handler = netifd_handle_status },
  819. { .name = "prepare", .handler = netifd_handle_iface_prepare },
  820. { .name = "dump", .handler = netifd_handle_dump },
  821. UBUS_METHOD("add_device", netifd_iface_handle_device, dev_link_policy ),
  822. UBUS_METHOD("remove_device", netifd_iface_handle_device, dev_link_policy ),
  823. { .name = "notify_proto", .handler = netifd_iface_notify_proto },
  824. { .name = "remove", .handler = netifd_iface_remove },
  825. { .name = "set_data", .handler = netifd_handle_set_data },
  826. };
  827. static struct ubus_object_type iface_object_type =
  828. UBUS_OBJECT_TYPE("netifd_iface", iface_object_methods);
  829. static struct ubus_object iface_object = {
  830. .name = "network.interface",
  831. .type = &iface_object_type,
  832. .n_methods = ARRAY_SIZE(iface_object_methods),
  833. };
  834. static void netifd_add_object(struct ubus_object *obj)
  835. {
  836. int ret = ubus_add_object(ubus_ctx, obj);
  837. if (ret != 0)
  838. fprintf(stderr, "Failed to publish object '%s': %s\n", obj->name, ubus_strerror(ret));
  839. }
  840. static const struct blobmsg_policy iface_policy = {
  841. .name = "interface",
  842. .type = BLOBMSG_TYPE_STRING,
  843. };
  844. static int
  845. netifd_handle_iface(struct ubus_context *ctx, struct ubus_object *obj,
  846. struct ubus_request_data *req, const char *method,
  847. struct blob_attr *msg)
  848. {
  849. struct interface *iface;
  850. struct blob_attr *tb;
  851. int i;
  852. blobmsg_parse(&iface_policy, 1, &tb, blob_data(msg), blob_len(msg));
  853. if (!tb)
  854. return UBUS_STATUS_INVALID_ARGUMENT;
  855. iface = vlist_find(&interfaces, blobmsg_data(tb), iface, node);
  856. if (!iface)
  857. return UBUS_STATUS_NOT_FOUND;
  858. for (i = 0; i < ARRAY_SIZE(iface_object_methods); i++) {
  859. ubus_handler_t cb;
  860. if (strcmp(method, iface_object_methods[i].name) != 0)
  861. continue;
  862. cb = iface_object_methods[i].handler;
  863. return cb(ctx, &iface->ubus, req, method, msg);
  864. }
  865. return UBUS_STATUS_INVALID_ARGUMENT;
  866. }
  867. static void netifd_add_iface_object(void)
  868. {
  869. struct ubus_method *methods;
  870. int i;
  871. methods = calloc(1, sizeof(iface_object_methods));
  872. if (!methods)
  873. return;
  874. memcpy(methods, iface_object_methods, sizeof(iface_object_methods));
  875. iface_object.methods = methods;
  876. for (i = 0; i < ARRAY_SIZE(iface_object_methods); i++) {
  877. if (methods[i].handler == netifd_handle_dump)
  878. continue;
  879. methods[i].handler = netifd_handle_iface;
  880. methods[i].policy = &iface_policy;
  881. methods[i].n_policy = 1;
  882. }
  883. netifd_add_object(&iface_object);
  884. }
  885. static struct wireless_device *
  886. get_wdev(struct blob_attr *msg, int *ret)
  887. {
  888. struct blobmsg_policy wdev_policy = {
  889. .name = "device",
  890. .type = BLOBMSG_TYPE_STRING,
  891. };
  892. struct blob_attr *dev_attr;
  893. struct wireless_device *wdev = NULL;
  894. blobmsg_parse(&wdev_policy, 1, &dev_attr, blob_data(msg), blob_len(msg));
  895. if (!dev_attr) {
  896. *ret = UBUS_STATUS_INVALID_ARGUMENT;
  897. return NULL;
  898. }
  899. wdev = vlist_find(&wireless_devices, blobmsg_data(dev_attr), wdev, node);
  900. if (!wdev) {
  901. *ret = UBUS_STATUS_NOT_FOUND;
  902. return NULL;
  903. }
  904. *ret = 0;
  905. return wdev;
  906. }
  907. static int
  908. netifd_handle_wdev_reconf(struct ubus_context *ctx, struct ubus_object *obj,
  909. struct ubus_request_data *req, const char *method,
  910. struct blob_attr *msg)
  911. {
  912. struct wireless_device *wdev;
  913. int ret;
  914. wdev = get_wdev(msg, &ret);
  915. if (ret == UBUS_STATUS_NOT_FOUND)
  916. return ret;
  917. if (wdev) {
  918. wireless_device_reconf(wdev);
  919. } else {
  920. vlist_for_each_element(&wireless_devices, wdev, node)
  921. wireless_device_reconf(wdev);
  922. }
  923. return 0;
  924. }
  925. static int
  926. netifd_handle_wdev_up(struct ubus_context *ctx, struct ubus_object *obj,
  927. struct ubus_request_data *req, const char *method,
  928. struct blob_attr *msg)
  929. {
  930. struct wireless_device *wdev;
  931. int ret;
  932. wdev = get_wdev(msg, &ret);
  933. if (ret == UBUS_STATUS_NOT_FOUND)
  934. return ret;
  935. if (wdev) {
  936. wireless_device_set_up(wdev);
  937. } else {
  938. vlist_for_each_element(&wireless_devices, wdev, node)
  939. wireless_device_set_up(wdev);
  940. }
  941. return 0;
  942. }
  943. static int
  944. netifd_handle_wdev_down(struct ubus_context *ctx, struct ubus_object *obj,
  945. struct ubus_request_data *req, const char *method,
  946. struct blob_attr *msg)
  947. {
  948. struct wireless_device *wdev;
  949. int ret;
  950. wdev = get_wdev(msg, &ret);
  951. if (ret == UBUS_STATUS_NOT_FOUND)
  952. return ret;
  953. if (wdev) {
  954. wireless_device_set_down(wdev);
  955. } else {
  956. vlist_for_each_element(&wireless_devices, wdev, node)
  957. wireless_device_set_down(wdev);
  958. }
  959. return 0;
  960. }
  961. static int
  962. netifd_handle_wdev_status(struct ubus_context *ctx, struct ubus_object *obj,
  963. struct ubus_request_data *req, const char *method,
  964. struct blob_attr *msg)
  965. {
  966. struct wireless_device *wdev;
  967. int ret;
  968. wdev = get_wdev(msg, &ret);
  969. if (ret == UBUS_STATUS_NOT_FOUND)
  970. return ret;
  971. blob_buf_init(&b, 0);
  972. if (wdev) {
  973. wireless_device_status(wdev, &b);
  974. } else {
  975. vlist_for_each_element(&wireless_devices, wdev, node)
  976. wireless_device_status(wdev, &b);
  977. }
  978. ubus_send_reply(ctx, req, b.head);
  979. return 0;
  980. }
  981. static int
  982. netifd_handle_wdev_get_validate(struct ubus_context *ctx, struct ubus_object *obj,
  983. struct ubus_request_data *req, const char *method,
  984. struct blob_attr *msg)
  985. {
  986. struct wireless_device *wdev;
  987. int ret;
  988. wdev = get_wdev(msg, &ret);
  989. if (ret == UBUS_STATUS_NOT_FOUND)
  990. return ret;
  991. blob_buf_init(&b, 0);
  992. if (wdev) {
  993. wireless_device_get_validate(wdev, &b);
  994. } else {
  995. vlist_for_each_element(&wireless_devices, wdev, node)
  996. wireless_device_get_validate(wdev, &b);
  997. }
  998. ubus_send_reply(ctx, req, b.head);
  999. return 0;
  1000. }
  1001. static int
  1002. netifd_handle_wdev_notify(struct ubus_context *ctx, struct ubus_object *obj,
  1003. struct ubus_request_data *req, const char *method,
  1004. struct blob_attr *msg)
  1005. {
  1006. struct wireless_device *wdev;
  1007. int ret;
  1008. wdev = get_wdev(msg, &ret);
  1009. if (!wdev)
  1010. return ret;
  1011. return wireless_device_notify(wdev, msg, req);
  1012. }
  1013. static struct ubus_method wireless_object_methods[] = {
  1014. { .name = "up", .handler = netifd_handle_wdev_up },
  1015. { .name = "down", .handler = netifd_handle_wdev_down },
  1016. { .name = "reconf", .handler = netifd_handle_wdev_reconf },
  1017. { .name = "status", .handler = netifd_handle_wdev_status },
  1018. { .name = "notify", .handler = netifd_handle_wdev_notify },
  1019. { .name = "get_validate", .handler = netifd_handle_wdev_get_validate },
  1020. };
  1021. static struct ubus_object_type wireless_object_type =
  1022. UBUS_OBJECT_TYPE("netifd_iface", wireless_object_methods);
  1023. static struct ubus_object wireless_object = {
  1024. .name = "network.wireless",
  1025. .type = &wireless_object_type,
  1026. .methods = wireless_object_methods,
  1027. .n_methods = ARRAY_SIZE(wireless_object_methods),
  1028. };
  1029. int
  1030. netifd_ubus_init(const char *path)
  1031. {
  1032. uloop_init();
  1033. ubus_path = path;
  1034. ubus_ctx = ubus_connect(path);
  1035. if (!ubus_ctx)
  1036. return -EIO;
  1037. DPRINTF("connected as %08x\n", ubus_ctx->local_id);
  1038. ubus_ctx->connection_lost = netifd_ubus_connection_lost;
  1039. netifd_ubus_add_fd();
  1040. netifd_add_object(&main_object);
  1041. netifd_add_object(&dev_object);
  1042. netifd_add_object(&wireless_object);
  1043. netifd_add_iface_object();
  1044. return 0;
  1045. }
  1046. void
  1047. netifd_ubus_done(void)
  1048. {
  1049. ubus_free(ubus_ctx);
  1050. }
  1051. void
  1052. netifd_ubus_interface_event(struct interface *iface, bool up)
  1053. {
  1054. blob_buf_init(&b, 0);
  1055. blobmsg_add_string(&b, "action", up ? "ifup" : "ifdown");
  1056. blobmsg_add_string(&b, "interface", iface->name);
  1057. ubus_send_event(ubus_ctx, "network.interface", b.head);
  1058. }
  1059. void
  1060. netifd_ubus_interface_notify(struct interface *iface, bool up)
  1061. {
  1062. const char *event = (up) ? "interface.update" : "interface.down";
  1063. blob_buf_init(&b, 0);
  1064. blobmsg_add_string(&b, "interface", iface->name);
  1065. netifd_dump_status(iface);
  1066. ubus_notify(ubus_ctx, &iface_object, event, b.head, -1);
  1067. ubus_notify(ubus_ctx, &iface->ubus, event, b.head, -1);
  1068. }
  1069. void
  1070. netifd_ubus_add_interface(struct interface *iface)
  1071. {
  1072. struct ubus_object *obj = &iface->ubus;
  1073. char *name = NULL;
  1074. if (asprintf(&name, "%s.interface.%s", main_object.name, iface->name) == -1)
  1075. return;
  1076. obj->name = name;
  1077. obj->type = &iface_object_type;
  1078. obj->methods = iface_object_methods;
  1079. obj->n_methods = ARRAY_SIZE(iface_object_methods);
  1080. if (ubus_add_object(ubus_ctx, &iface->ubus)) {
  1081. DPRINTF("failed to publish ubus object for interface '%s'\n", iface->name);
  1082. free(name);
  1083. obj->name = NULL;
  1084. }
  1085. }
  1086. void
  1087. netifd_ubus_remove_interface(struct interface *iface)
  1088. {
  1089. if (!iface->ubus.name)
  1090. return;
  1091. ubus_remove_object(ubus_ctx, &iface->ubus);
  1092. free((void *) iface->ubus.name);
  1093. }