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