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 26 struct ubus_context *ubus_ctx = NULL; 27 static struct blob_buf b; 28 static const char *ubus_path; 29 static struct udebug_ubus udebug; 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_EXCLUDE, 58 __HR_MAX 59 }; 60 61 static const struct blobmsg_policy route_policy[__HR_MAX] = { 62 [HR_TARGET] = { .name = "target", .type = BLOBMSG_TYPE_STRING }, 63 [HR_V6] = { .name = "v6", .type = BLOBMSG_TYPE_BOOL }, 64 [HR_INTERFACE] = { .name = "interface", .type = BLOBMSG_TYPE_STRING }, 65 [HR_EXCLUDE] = { .name = "exclude", .type = BLOBMSG_TYPE_BOOL }, 66 }; 67 68 static int 69 netifd_add_host_route(struct ubus_context *ctx, struct ubus_object *obj, 70 struct ubus_request_data *req, const char *method, 71 struct blob_attr *msg) 72 { 73 struct blob_attr *tb[__HR_MAX]; 74 struct interface *iface = NULL; 75 union if_addr a; 76 bool v6 = false; 77 bool exclude = false; 78 79 blobmsg_parse_attr(route_policy, __HR_MAX, tb, msg); 80 if (!tb[HR_TARGET]) 81 return UBUS_STATUS_INVALID_ARGUMENT; 82 83 if (tb[HR_V6]) 84 v6 = blobmsg_get_bool(tb[HR_V6]); 85 86 if (tb[HR_EXCLUDE]) 87 exclude = blobmsg_get_bool(tb[HR_EXCLUDE]); 88 89 if (tb[HR_INTERFACE]) 90 iface = vlist_find(&interfaces, blobmsg_data(tb[HR_INTERFACE]), iface, node); 91 92 memset(&a, 0, sizeof(a)); 93 if (!inet_pton(v6 ? AF_INET6 : AF_INET, blobmsg_data(tb[HR_TARGET]), &a)) 94 return UBUS_STATUS_INVALID_ARGUMENT; 95 96 iface = interface_ip_add_target_route(&a, v6, iface, exclude); 97 if (!iface) 98 return UBUS_STATUS_NOT_FOUND; 99 100 blob_buf_init(&b, 0); 101 blobmsg_add_string(&b, "interface", iface->name); 102 ubus_send_reply(ctx, req, b.head); 103 104 return 0; 105 } 106 107 static int 108 netifd_get_proto_handlers(struct ubus_context *ctx, struct ubus_object *obj, 109 struct ubus_request_data *req, const char *method, 110 struct blob_attr *msg) 111 { 112 blob_buf_init(&b, 0); 113 proto_dump_handlers(&b); 114 ubus_send_reply(ctx, req, b.head); 115 116 return 0; 117 } 118 119 120 enum { 121 DI_NAME, 122 __DI_MAX 123 }; 124 125 static const struct blobmsg_policy dynamic_policy[__DI_MAX] = { 126 [DI_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING }, 127 }; 128 129 static int 130 netifd_add_dynamic(struct ubus_context *ctx, struct ubus_object *obj, 131 struct ubus_request_data *req, const char *method, 132 struct blob_attr *msg) 133 { 134 struct blob_attr *tb[__DI_MAX]; 135 struct interface *iface; 136 struct blob_attr *config; 137 138 blobmsg_parse_attr(dynamic_policy, __DI_MAX, tb, msg); 139 140 if (!tb[DI_NAME]) 141 return UBUS_STATUS_INVALID_ARGUMENT; 142 143 const char *name = blobmsg_get_string(tb[DI_NAME]); 144 145 iface = interface_alloc(name, msg, true); 146 if (!iface) 147 return UBUS_STATUS_UNKNOWN_ERROR; 148 149 config = blob_memdup(msg); 150 if (!config) 151 goto error; 152 153 if (!interface_add(iface, config)) 154 goto error_free_config; 155 156 return UBUS_STATUS_OK; 157 158 error_free_config: 159 free(config); 160 error: 161 free(iface); 162 return UBUS_STATUS_UNKNOWN_ERROR; 163 } 164 165 enum { 166 NETNS_UPDOWN_JAIL, 167 NETNS_UPDOWN_START, 168 __NETNS_UPDOWN_MAX 169 }; 170 171 static const struct blobmsg_policy netns_updown_policy[__NETNS_UPDOWN_MAX] = { 172 [NETNS_UPDOWN_JAIL] = { .name = "jail", .type = BLOBMSG_TYPE_STRING }, 173 [NETNS_UPDOWN_START] = { .name = "start", .type = BLOBMSG_TYPE_BOOL }, 174 }; 175 176 static int 177 netifd_netns_updown(struct ubus_context *ctx, struct ubus_object *obj, 178 struct ubus_request_data *req, const char *method, 179 struct blob_attr *msg) 180 { 181 int target_netns_fd = ubus_request_get_caller_fd(req); 182 struct blob_attr *tb[__NETNS_UPDOWN_MAX]; 183 bool start; 184 185 if (target_netns_fd < 0) 186 return UBUS_STATUS_INVALID_ARGUMENT; 187 188 blobmsg_parse_attr(netns_updown_policy, __NETNS_UPDOWN_MAX, tb, msg); 189 190 start = tb[NETNS_UPDOWN_START] && blobmsg_get_bool(tb[NETNS_UPDOWN_START]); 191 192 if (start) { 193 if (!tb[NETNS_UPDOWN_JAIL]) 194 return UBUS_STATUS_INVALID_ARGUMENT; 195 196 interface_start_jail(target_netns_fd, blobmsg_get_string(tb[NETNS_UPDOWN_JAIL])); 197 } else { 198 interface_stop_jail(target_netns_fd); 199 } 200 close(target_netns_fd); 201 202 return UBUS_STATUS_OK; 203 } 204 205 static struct ubus_method main_object_methods[] = { 206 { .name = "restart", .handler = netifd_handle_restart }, 207 { .name = "reload", .handler = netifd_handle_reload }, 208 UBUS_METHOD("add_host_route", netifd_add_host_route, route_policy), 209 { .name = "get_proto_handlers", .handler = netifd_get_proto_handlers }, 210 UBUS_METHOD("add_dynamic", netifd_add_dynamic, dynamic_policy), 211 UBUS_METHOD("netns_updown", netifd_netns_updown, netns_updown_policy), 212 }; 213 214 static struct ubus_object_type main_object_type = 215 UBUS_OBJECT_TYPE("netifd", main_object_methods); 216 217 static struct ubus_object main_object = { 218 .name = "network", 219 .type = &main_object_type, 220 .methods = main_object_methods, 221 .n_methods = ARRAY_SIZE(main_object_methods), 222 }; 223 224 enum { 225 DEV_NAME, 226 __DEV_MAX, 227 }; 228 229 static const struct blobmsg_policy dev_policy[__DEV_MAX] = { 230 [DEV_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING }, 231 }; 232 233 static int 234 netifd_dev_status(struct ubus_context *ctx, struct ubus_object *obj, 235 struct ubus_request_data *req, const char *method, 236 struct blob_attr *msg) 237 { 238 struct device *dev = NULL; 239 struct blob_attr *tb[__DEV_MAX]; 240 241 blobmsg_parse_attr(dev_policy, __DEV_MAX, tb, msg); 242 243 if (tb[DEV_NAME]) { 244 dev = device_find(blobmsg_data(tb[DEV_NAME])); 245 if (!dev) 246 return UBUS_STATUS_INVALID_ARGUMENT; 247 } 248 249 blob_buf_init(&b, 0); 250 device_dump_status(&b, dev); 251 ubus_send_reply(ctx, req, b.head); 252 253 return 0; 254 } 255 256 enum { 257 ALIAS_ATTR_ALIAS, 258 ALIAS_ATTR_DEV, 259 __ALIAS_ATTR_MAX, 260 }; 261 262 static const struct blobmsg_policy alias_attrs[__ALIAS_ATTR_MAX] = { 263 [ALIAS_ATTR_ALIAS] = { "alias", BLOBMSG_TYPE_ARRAY }, 264 [ALIAS_ATTR_DEV] = { "device", BLOBMSG_TYPE_STRING }, 265 }; 266 267 static int 268 netifd_handle_alias(struct ubus_context *ctx, struct ubus_object *obj, 269 struct ubus_request_data *req, const char *method, 270 struct blob_attr *msg) 271 { 272 struct device *dev = NULL; 273 struct blob_attr *tb[__ALIAS_ATTR_MAX]; 274 struct blob_attr *cur; 275 size_t rem; 276 277 blobmsg_parse_attr(alias_attrs, __ALIAS_ATTR_MAX, tb, msg); 278 279 if (!tb[ALIAS_ATTR_ALIAS]) 280 return UBUS_STATUS_INVALID_ARGUMENT; 281 282 if ((cur = tb[ALIAS_ATTR_DEV]) != NULL) { 283 dev = device_get(blobmsg_data(cur), true); 284 if (!dev) 285 return UBUS_STATUS_NOT_FOUND; 286 } 287 288 blobmsg_for_each_attr(cur, tb[ALIAS_ATTR_ALIAS], rem) { 289 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING) 290 goto error; 291 292 if (!blobmsg_check_attr(cur, false)) 293 goto error; 294 295 alias_notify_device(blobmsg_data(cur), dev); 296 } 297 return 0; 298 299 error: 300 device_free_unused(); 301 return UBUS_STATUS_INVALID_ARGUMENT; 302 } 303 304 enum { 305 DEV_STATE_NAME, 306 DEV_STATE_DEFER, 307 DEV_STATE_AUTH_STATUS, 308 DEV_STATE_AUTH_VLANS, 309 __DEV_STATE_MAX, 310 }; 311 312 static const struct blobmsg_policy dev_state_policy[__DEV_STATE_MAX] = { 313 [DEV_STATE_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING }, 314 [DEV_STATE_DEFER] = { .name = "defer", .type = BLOBMSG_TYPE_BOOL }, 315 [DEV_STATE_AUTH_STATUS] = { .name = "auth_status", .type = BLOBMSG_TYPE_BOOL }, 316 [DEV_STATE_AUTH_VLANS] = { .name = "auth_vlans", BLOBMSG_TYPE_ARRAY }, 317 }; 318 319 static int 320 netifd_handle_set_state(struct ubus_context *ctx, struct ubus_object *obj, 321 struct ubus_request_data *req, const char *method, 322 struct blob_attr *msg) 323 { 324 struct device *dev = NULL; 325 struct blob_attr *tb[__DEV_STATE_MAX]; 326 struct blob_attr *cur; 327 bool auth_status; 328 329 blobmsg_parse_attr(dev_state_policy, __DEV_STATE_MAX, tb, msg); 330 331 cur = tb[DEV_STATE_NAME]; 332 if (!cur) 333 return UBUS_STATUS_INVALID_ARGUMENT; 334 335 dev = device_find(blobmsg_data(cur)); 336 if (!dev) 337 return UBUS_STATUS_NOT_FOUND; 338 339 cur = tb[DEV_STATE_DEFER]; 340 if (cur) 341 device_set_deferred(dev, !!blobmsg_get_u8(cur)); 342 343 if ((cur = tb[DEV_STATE_AUTH_STATUS]) != NULL) 344 auth_status = blobmsg_get_bool(cur); 345 else 346 auth_status = dev->auth_status; 347 if (tb[DEV_STATE_AUTH_STATUS] || tb[DEV_STATE_AUTH_VLANS]) 348 device_set_auth_status(dev, auth_status, tb[DEV_STATE_AUTH_VLANS]); 349 350 return 0; 351 } 352 353 #ifdef DUMMY_MODE 354 enum { 355 DEV_HOTPLUG_ATTR_NAME, 356 DEV_HOTPLUG_ATTR_ADD, 357 __DEV_HOTPLUG_ATTR_MAX, 358 }; 359 360 static const struct blobmsg_policy dev_hotplug_policy[__DEV_HOTPLUG_ATTR_MAX] = { 361 [DEV_HOTPLUG_ATTR_NAME] = { "name", BLOBMSG_TYPE_STRING }, 362 [DEV_HOTPLUG_ATTR_ADD] = { "add", BLOBMSG_TYPE_BOOL }, 363 }; 364 365 static int 366 netifd_handle_dev_hotplug(struct ubus_context *ctx, struct ubus_object *obj, 367 struct ubus_request_data *req, const char *method, 368 struct blob_attr *msg) 369 { 370 struct blob_attr *tb[__DEV_HOTPLUG_ATTR_MAX]; 371 const char *name; 372 373 blobmsg_parse_attr(dev_hotplug_policy, __DEV_HOTPLUG_ATTR_MAX, tb, msg); 374 375 if (!tb[DEV_HOTPLUG_ATTR_NAME] || !tb[DEV_HOTPLUG_ATTR_ADD]) 376 return UBUS_STATUS_INVALID_ARGUMENT; 377 378 name = blobmsg_get_string(tb[DEV_HOTPLUG_ATTR_NAME]); 379 device_hotplug_event(name, blobmsg_get_bool(tb[DEV_HOTPLUG_ATTR_ADD])); 380 381 return 0; 382 } 383 #endif 384 385 static int 386 netifd_handle_stp_init(struct ubus_context *ctx, struct ubus_object *obj, 387 struct ubus_request_data *req, const char *method, 388 struct blob_attr *msg) 389 { 390 device_stp_init(); 391 392 return 0; 393 } 394 395 static struct ubus_method dev_object_methods[] = { 396 UBUS_METHOD("status", netifd_dev_status, dev_policy), 397 UBUS_METHOD("set_alias", netifd_handle_alias, alias_attrs), 398 UBUS_METHOD("set_state", netifd_handle_set_state, dev_state_policy), 399 #ifdef DUMMY_MODE 400 UBUS_METHOD("hotplug_event", netifd_handle_dev_hotplug, dev_hotplug_policy), 401 #endif 402 UBUS_METHOD_NOARG("stp_init", netifd_handle_stp_init) 403 }; 404 405 static struct ubus_object_type dev_object_type = 406 UBUS_OBJECT_TYPE("device", dev_object_methods); 407 408 static struct ubus_object dev_object = { 409 .name = "network.device", 410 .type = &dev_object_type, 411 .methods = dev_object_methods, 412 .n_methods = ARRAY_SIZE(dev_object_methods), 413 }; 414 415 static void 416 netifd_ubus_add_fd(void) 417 { 418 ubus_add_uloop(ubus_ctx); 419 system_fd_set_cloexec(ubus_ctx->sock.fd); 420 } 421 422 void netifd_ubus_device_notify(const char *event, struct blob_attr *data, int timeout) 423 { 424 ubus_notify(ubus_ctx, &dev_object, event, data, timeout); 425 } 426 427 static void 428 netifd_ubus_reconnect_timer(struct uloop_timeout *timeout) 429 { 430 static struct uloop_timeout retry = { 431 .cb = netifd_ubus_reconnect_timer, 432 }; 433 int t = 2; 434 435 if (ubus_reconnect(ubus_ctx, ubus_path) != 0) { 436 D(SYSTEM, "failed to reconnect, trying again in %d seconds", t); 437 uloop_timeout_set(&retry, t * 1000); 438 return; 439 } 440 441 D(SYSTEM, "reconnected to ubus, new id: %08x", ubus_ctx->local_id); 442 netifd_ubus_add_fd(); 443 } 444 445 static void 446 netifd_ubus_connection_lost(struct ubus_context *ctx) 447 { 448 netifd_ubus_reconnect_timer(NULL); 449 } 450 451 /* per-interface object */ 452 453 static int 454 netifd_handle_up(struct ubus_context *ctx, struct ubus_object *obj, 455 struct ubus_request_data *req, const char *method, 456 struct blob_attr *msg) 457 { 458 struct interface *iface; 459 460 iface = container_of(obj, struct interface, ubus); 461 interface_set_up(iface); 462 463 return 0; 464 } 465 466 static int 467 netifd_handle_down(struct ubus_context *ctx, struct ubus_object *obj, 468 struct ubus_request_data *req, const char *method, 469 struct blob_attr *msg) 470 { 471 struct interface *iface; 472 473 iface = container_of(obj, struct interface, ubus); 474 interface_set_down(iface); 475 476 return 0; 477 } 478 479 static int 480 netifd_handle_renew(struct ubus_context *ctx, struct ubus_object *obj, 481 struct ubus_request_data *req, const char *method, 482 struct blob_attr *msg) 483 { 484 struct interface *iface; 485 486 iface = container_of(obj, struct interface, ubus); 487 interface_renew(iface); 488 489 return 0; 490 } 491 492 static void 493 netifd_add_interface_errors(struct blob_buf *b, struct interface *iface) 494 { 495 struct interface_error *error; 496 void *e, *e2, *e3; 497 int i; 498 499 e = blobmsg_open_array(b, "errors"); 500 list_for_each_entry(error, &iface->errors, list) { 501 e2 = blobmsg_open_table(b, NULL); 502 503 blobmsg_add_string(b, "subsystem", error->subsystem); 504 blobmsg_add_string(b, "code", error->code); 505 if (error->data[0]) { 506 e3 = blobmsg_open_array(b, "data"); 507 for (i = 0; error->data[i]; i++) 508 blobmsg_add_string(b, NULL, error->data[i]); 509 blobmsg_close_array(b, e3); 510 } 511 512 blobmsg_close_table(b, e2); 513 } 514 blobmsg_close_array(b, e); 515 } 516 517 static void 518 interface_ip_dump_address_list(struct interface_ip_settings *ip, bool v6, bool enabled) 519 { 520 struct device_addr *addr; 521 char *buf; 522 void *a; 523 int buflen = 128; 524 int af; 525 526 time_t now = system_get_rtime(); 527 vlist_for_each_element(&ip->addr, addr, node) { 528 if (addr->enabled != enabled) 529 continue; 530 531 if ((addr->flags & DEVADDR_FAMILY) == DEVADDR_INET4) 532 af = AF_INET; 533 else 534 af = AF_INET6; 535 536 if (af != (v6 ? AF_INET6 : AF_INET)) 537 continue; 538 539 a = blobmsg_open_table(&b, NULL); 540 541 buf = blobmsg_alloc_string_buffer(&b, "address", buflen); 542 inet_ntop(af, &addr->addr, buf, buflen); 543 blobmsg_add_string_buffer(&b); 544 545 blobmsg_add_u32(&b, "mask", addr->mask); 546 547 if (addr->point_to_point) { 548 buf = blobmsg_alloc_string_buffer(&b, "ptpaddress", buflen); 549 inet_ntop(af, &addr->point_to_point, buf, buflen); 550 blobmsg_add_string_buffer(&b); 551 } 552 553 if (addr->preferred_until) { 554 int preferred = addr->preferred_until - now; 555 if (preferred < 0) 556 preferred = 0; 557 blobmsg_add_u32(&b, "preferred", preferred); 558 } 559 560 if (addr->valid_until) 561 blobmsg_add_u32(&b, "valid", addr->valid_until - now); 562 563 if (addr->pclass) 564 blobmsg_add_string(&b, "class", addr->pclass); 565 566 blobmsg_close_table(&b, a); 567 } 568 } 569 570 static void 571 interface_ip_dump_neighbor_list(struct interface_ip_settings *ip, bool enabled) 572 { 573 struct device_neighbor *neighbor; 574 int buflen = 128; 575 char *buf; 576 void *r; 577 int af; 578 579 vlist_for_each_element(&ip->neighbor, neighbor, node) { 580 if (neighbor->enabled != enabled) 581 continue; 582 583 if ((neighbor->flags & DEVADDR_FAMILY) == DEVADDR_INET4) 584 af = AF_INET; 585 else 586 af = AF_INET6; 587 588 r = blobmsg_open_table(&b, NULL); 589 590 if (neighbor->flags & DEVNEIGH_MAC) 591 blobmsg_add_string(&b, "mac", format_macaddr(neighbor->macaddr)); 592 593 buf = blobmsg_alloc_string_buffer(&b , "address", buflen); 594 inet_ntop(af, &neighbor->addr, buf, buflen); 595 blobmsg_add_string_buffer(&b); 596 597 if (neighbor->proxy) 598 blobmsg_add_u32(&b, "proxy", neighbor->proxy); 599 600 if (neighbor->router) 601 blobmsg_add_u32(&b, "router", neighbor->router); 602 603 blobmsg_close_table(&b, r); 604 } 605 } 606 607 static void 608 interface_ip_dump_route_list(struct interface_ip_settings *ip, bool enabled) 609 { 610 struct device_route *route; 611 int buflen = 128; 612 char *buf; 613 void *r; 614 int af; 615 616 time_t now = system_get_rtime(); 617 vlist_for_each_element(&ip->route, route, node) { 618 if (route->enabled != enabled) 619 continue; 620 621 if ((ip->no_defaultroute == enabled) && !route->mask) 622 continue; 623 624 if ((route->flags & DEVADDR_FAMILY) == DEVADDR_INET4) 625 af = AF_INET; 626 else 627 af = AF_INET6; 628 629 r = blobmsg_open_table(&b, NULL); 630 631 buf = blobmsg_alloc_string_buffer(&b, "target", buflen); 632 inet_ntop(af, &route->addr, buf, buflen); 633 blobmsg_add_string_buffer(&b); 634 635 blobmsg_add_u32(&b, "mask", route->mask); 636 637 buf = blobmsg_alloc_string_buffer(&b, "nexthop", buflen); 638 inet_ntop(af, &route->nexthop, buf, buflen); 639 blobmsg_add_string_buffer(&b); 640 641 if (route->flags & DEVROUTE_TYPE) 642 blobmsg_add_u32(&b, "type", route->type); 643 644 if (route->flags & DEVROUTE_PROTO) 645 blobmsg_add_u32(&b, "proto", route->proto); 646 647 if (route->flags & DEVROUTE_MTU) 648 blobmsg_add_u32(&b, "mtu", route->mtu); 649 650 if (route->flags & DEVROUTE_METRIC) 651 blobmsg_add_u32(&b, "metric", route->metric); 652 653 if (route->flags & DEVROUTE_TABLE) 654 blobmsg_add_u32(&b, "table", route->table); 655 656 if (route->valid_until) 657 blobmsg_add_u32(&b, "valid", route->valid_until - now); 658 659 buf = blobmsg_alloc_string_buffer(&b, "source", buflen); 660 inet_ntop(af, &route->source, buf, buflen); 661 snprintf(buf + strlen(buf), buflen - strlen(buf), "/%u", route->sourcemask); 662 blobmsg_add_string_buffer(&b); 663 664 blobmsg_close_table(&b, r); 665 } 666 } 667 668 669 static void 670 interface_ip_dump_prefix_list(struct interface_ip_settings *ip) 671 { 672 struct device_prefix *prefix; 673 char *buf; 674 void *a, *c; 675 const int buflen = INET6_ADDRSTRLEN; 676 677 time_t now = system_get_rtime(); 678 vlist_for_each_element(&ip->prefix, prefix, node) { 679 a = blobmsg_open_table(&b, NULL); 680 681 buf = blobmsg_alloc_string_buffer(&b, "address", buflen); 682 inet_ntop(AF_INET6, &prefix->addr, buf, buflen); 683 blobmsg_add_string_buffer(&b); 684 685 blobmsg_add_u32(&b, "mask", prefix->length); 686 687 if (prefix->preferred_until) { 688 int preferred = prefix->preferred_until - now; 689 if (preferred < 0) 690 preferred = 0; 691 blobmsg_add_u32(&b, "preferred", preferred); 692 } 693 694 if (prefix->valid_until) 695 blobmsg_add_u32(&b, "valid", prefix->valid_until - now); 696 697 blobmsg_add_string(&b, "class", prefix->pclass); 698 699 c = blobmsg_open_table(&b, "assigned"); 700 struct device_prefix_assignment *assign; 701 list_for_each_entry(assign, &prefix->assignments, head) { 702 if (!assign->name[0]) 703 continue; 704 705 struct in6_addr addr = prefix->addr; 706 addr.s6_addr32[1] |= htonl(assign->assigned); 707 708 void *d = blobmsg_open_table(&b, assign->name); 709 710 buf = blobmsg_alloc_string_buffer(&b, "address", buflen); 711 inet_ntop(AF_INET6, &addr, buf, buflen); 712 blobmsg_add_string_buffer(&b); 713 714 blobmsg_add_u32(&b, "mask", assign->length); 715 716 blobmsg_close_table(&b, d); 717 } 718 blobmsg_close_table(&b, c); 719 720 blobmsg_close_table(&b, a); 721 } 722 } 723 724 725 static void 726 interface_ip_dump_prefix_assignment_list(struct interface *iface) 727 { 728 void *a; 729 char *buf; 730 const int buflen = INET6_ADDRSTRLEN; 731 time_t now = system_get_rtime(); 732 733 struct device_prefix *prefix; 734 list_for_each_entry(prefix, &prefixes, head) { 735 struct device_prefix_assignment *assign; 736 list_for_each_entry(assign, &prefix->assignments, head) { 737 if (strcmp(assign->name, iface->name)) 738 continue; 739 740 struct in6_addr addr = prefix->addr; 741 addr.s6_addr32[1] |= htonl(assign->assigned); 742 743 a = blobmsg_open_table(&b, NULL); 744 745 buf = blobmsg_alloc_string_buffer(&b, "address", buflen); 746 inet_ntop(AF_INET6, &addr, buf, buflen); 747 blobmsg_add_string_buffer(&b); 748 749 blobmsg_add_u32(&b, "mask", assign->length); 750 751 if (prefix->preferred_until) { 752 int preferred = prefix->preferred_until - now; 753 if (preferred < 0) 754 preferred = 0; 755 blobmsg_add_u32(&b, "preferred", preferred); 756 } 757 758 if (prefix->valid_until) 759 blobmsg_add_u32(&b, "valid", prefix->valid_until - now); 760 761 void *c = blobmsg_open_table(&b, "local-address"); 762 if (assign->enabled) { 763 buf = blobmsg_alloc_string_buffer(&b, "address", buflen); 764 inet_ntop(AF_INET6, &assign->addr, buf, buflen); 765 blobmsg_add_string_buffer(&b); 766 767 blobmsg_add_u32(&b, "mask", assign->length); 768 } 769 blobmsg_close_table(&b, c); 770 771 blobmsg_close_table(&b, a); 772 } 773 } 774 } 775 776 static void 777 interface_ip_dump_dns_server_list(struct interface_ip_settings *ip, bool enabled) 778 { 779 struct dns_server *dns; 780 int buflen = 128; 781 char *buf; 782 783 vlist_simple_for_each_element(&ip->dns_servers, dns, node) { 784 if (ip->no_dns == enabled) 785 continue; 786 787 buf = blobmsg_alloc_string_buffer(&b, NULL, buflen); 788 inet_ntop(dns->af, &dns->addr, buf, buflen); 789 blobmsg_add_string_buffer(&b); 790 } 791 } 792 793 static void 794 interface_ip_dump_dns_search_list(struct interface_ip_settings *ip, bool enabled) 795 { 796 struct dns_search_domain *dns; 797 798 vlist_simple_for_each_element(&ip->dns_search, dns, node) { 799 if (ip->no_dns == enabled) 800 continue; 801 802 blobmsg_add_string(&b, NULL, dns->name); 803 } 804 } 805 806 static void 807 netifd_dump_status(struct interface *iface) 808 { 809 struct interface_data *data; 810 struct device *dev; 811 void *a, *inactive; 812 813 blobmsg_add_u8(&b, "up", iface->state == IFS_UP); 814 blobmsg_add_u8(&b, "pending", iface->state == IFS_SETUP); 815 blobmsg_add_u8(&b, "available", iface->available); 816 blobmsg_add_u8(&b, "autostart", iface->autostart); 817 blobmsg_add_u8(&b, "dynamic", iface->dynamic); 818 819 if (iface->state == IFS_UP) { 820 time_t cur = system_get_rtime(); 821 blobmsg_add_u32(&b, "uptime", cur - iface->start_time); 822 if (iface->l3_dev.dev) 823 blobmsg_add_string(&b, "l3_device", iface->l3_dev.dev->ifname); 824 } 825 826 if (iface->proto_handler) 827 blobmsg_add_string(&b, "proto", iface->proto_handler->name); 828 829 dev = iface->main_dev.dev; 830 if (dev && !dev->hidden && iface->proto_handler && 831 !(iface->proto_handler->flags & PROTO_FLAG_NODEV)) 832 blobmsg_add_string(&b, "device", dev->ifname); 833 834 if (iface->jail) 835 blobmsg_add_string(&b, "jail", iface->jail); 836 837 if (iface->jail_device) 838 blobmsg_add_string(&b, "jail_device", iface->jail_device); 839 if (iface->tags) 840 blobmsg_add_blob(&b, iface->tags); 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_attr(dev_link_policy, __DEV_LINK_MAX, tb, 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_attr(&iface_policy, 1, &tb, 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 int 1189 netifd_extdev_invoke(uint32_t id, const char *method, struct blob_attr *msg, 1190 ubus_data_handler_t data_cb, void *data) 1191 { 1192 return ubus_invoke(ubus_ctx, id, method, msg, data_cb, data, 3000); 1193 } 1194 1195 int 1196 netifd_ubus_init(const char *path) 1197 { 1198 ubus_path = path; 1199 1200 ubus_ctx = ubus_connect(path); 1201 if (!ubus_ctx) 1202 return -EIO; 1203 1204 D(SYSTEM, "connected as %08x", ubus_ctx->local_id); 1205 ubus_ctx->connection_lost = netifd_ubus_connection_lost; 1206 netifd_ubus_add_fd(); 1207 1208 netifd_add_object(&main_object); 1209 netifd_add_object(&dev_object); 1210 netifd_add_iface_object(); 1211 1212 udebug_ubus_init(&udebug, ubus_ctx, "netifd", netifd_udebug_config); 1213 1214 return 0; 1215 } 1216 1217 void 1218 netifd_ubus_done(void) 1219 { 1220 udebug_ubus_free(&udebug); 1221 ubus_free(ubus_ctx); 1222 } 1223 1224 void 1225 netifd_ubus_interface_event(struct interface *iface, bool up) 1226 { 1227 blob_buf_init(&b, 0); 1228 blobmsg_add_string(&b, "action", up ? "ifup" : "ifdown"); 1229 blobmsg_add_string(&b, "interface", iface->name); 1230 ubus_send_event(ubus_ctx, "network.interface", b.head); 1231 } 1232 1233 void 1234 netifd_ubus_interface_notify(struct interface *iface, bool up) 1235 { 1236 const char *event = (up) ? "interface.update" : "interface.down"; 1237 blob_buf_init(&b, 0); 1238 blobmsg_add_string(&b, "interface", iface->name); 1239 netifd_dump_status(iface); 1240 ubus_notify(ubus_ctx, &iface_object, event, b.head, -1); 1241 ubus_notify(ubus_ctx, &iface->ubus, event, b.head, -1); 1242 } 1243 1244 void 1245 netifd_ubus_add_interface(struct interface *iface) 1246 { 1247 struct ubus_object *obj = &iface->ubus; 1248 char *name = NULL; 1249 1250 if (asprintf(&name, "%s.interface.%s", main_object.name, iface->name) == -1) 1251 return; 1252 1253 obj->name = name; 1254 obj->type = &iface_object_type; 1255 obj->methods = iface_object_methods; 1256 obj->n_methods = ARRAY_SIZE(iface_object_methods); 1257 if (ubus_add_object(ubus_ctx, &iface->ubus)) { 1258 D(SYSTEM, "failed to publish ubus object for interface '%s'", iface->name); 1259 free(name); 1260 obj->name = NULL; 1261 } 1262 } 1263 1264 void 1265 netifd_ubus_remove_interface(struct interface *iface) 1266 { 1267 if (!iface->ubus.name) 1268 return; 1269 1270 ubus_remove_object(ubus_ctx, &iface->ubus); 1271 free((void *) iface->ubus.name); 1272 } 1273 1274 static void 1275 netifd_ubus_data_cb(struct ubus_request *req, int type, struct blob_attr *msg) 1276 { 1277 struct blob_attr *srv, *in, *t, *data; 1278 procd_data_cb cb = req->priv; 1279 size_t rem, rem2, rem3, rem4; 1280 1281 blobmsg_for_each_attr(srv, msg, rem) { 1282 if (!blobmsg_check_attr(srv, true) || 1283 blobmsg_type(srv) != BLOBMSG_TYPE_TABLE) 1284 continue; 1285 blobmsg_for_each_attr(in, srv, rem2) { 1286 if (!blobmsg_check_attr(in , true) || 1287 blobmsg_type(in) != BLOBMSG_TYPE_TABLE) 1288 continue; 1289 blobmsg_for_each_attr(t, in, rem3) { 1290 if (!blobmsg_check_attr(t, true) || 1291 blobmsg_type(t) != BLOBMSG_TYPE_TABLE) 1292 continue; 1293 blobmsg_for_each_attr(data, t, rem4) { 1294 if (!blobmsg_check_attr(data, true) || 1295 blobmsg_type(data) != BLOBMSG_TYPE_TABLE) 1296 continue; 1297 cb(data); 1298 } 1299 } 1300 } 1301 } 1302 } 1303 1304 void netifd_ubus_get_procd_data(const char *type, procd_data_cb cb) 1305 { 1306 uint32_t id; 1307 1308 if (ubus_lookup_id(ubus_ctx, "service", &id)) 1309 return; 1310 1311 blob_buf_init(&b, 0); 1312 blobmsg_add_string(&b, "type", type); 1313 ubus_invoke(ubus_ctx, id, "get_data", b.head, netifd_ubus_data_cb, cb, 30000); 1314 } 1315
This page was automatically generated by LXR 0.3.1. • OpenWrt