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