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 #include <string.h> 15 #include <stdlib.h> 16 #include <stdio.h> 17 #include <sys/types.h> 18 #include <sys/wait.h> 19 20 #include "netifd.h" 21 #include "device.h" 22 #include "interface.h" 23 #include "interface-ip.h" 24 #include "proto.h" 25 #include "ubus.h" 26 #include "config.h" 27 #include "system.h" 28 #include "wireless.h" 29 30 struct vlist_tree interfaces; 31 static LIST_HEAD(iface_all_users); 32 33 enum { 34 IFACE_ATTR_DEVICE, 35 IFACE_ATTR_IFNAME, /* Backward compatibility */ 36 IFACE_ATTR_PROTO, 37 IFACE_ATTR_AUTO, 38 IFACE_ATTR_ZONE, 39 IFACE_ATTR_JAIL, 40 IFACE_ATTR_JAIL_DEVICE, 41 IFACE_ATTR_JAIL_IFNAME, 42 IFACE_ATTR_HOST_DEVICE, 43 IFACE_ATTR_DEFAULTROUTE, 44 IFACE_ATTR_PEERDNS, 45 IFACE_ATTR_DNS, 46 IFACE_ATTR_DNS_SEARCH, 47 IFACE_ATTR_DNS_METRIC, 48 IFACE_ATTR_RENEW, 49 IFACE_ATTR_METRIC, 50 IFACE_ATTR_INTERFACE, 51 IFACE_ATTR_IP6ASSIGN, 52 IFACE_ATTR_IP6HINT, 53 IFACE_ATTR_IP4TABLE, 54 IFACE_ATTR_IP6TABLE, 55 IFACE_ATTR_IP6CLASS, 56 IFACE_ATTR_DELEGATE, 57 IFACE_ATTR_IP6IFACEID, 58 IFACE_ATTR_FORCE_LINK, 59 IFACE_ATTR_IP6WEIGHT, 60 IFACE_ATTR_MAX 61 }; 62 63 static const struct blobmsg_policy iface_attrs[IFACE_ATTR_MAX] = { 64 [IFACE_ATTR_DEVICE] = { .name = "device", .type = BLOBMSG_TYPE_STRING }, 65 [IFACE_ATTR_PROTO] = { .name = "proto", .type = BLOBMSG_TYPE_STRING }, 66 [IFACE_ATTR_IFNAME] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING }, 67 [IFACE_ATTR_AUTO] = { .name = "auto", .type = BLOBMSG_TYPE_BOOL }, 68 [IFACE_ATTR_ZONE] = { .name = "zone", .type = BLOBMSG_TYPE_STRING }, 69 [IFACE_ATTR_JAIL] = { .name = "jail", .type = BLOBMSG_TYPE_STRING }, 70 [IFACE_ATTR_JAIL_DEVICE] = { .name = "jail_device", .type = BLOBMSG_TYPE_STRING }, 71 [IFACE_ATTR_JAIL_IFNAME] = { .name = "jail_ifname", .type = BLOBMSG_TYPE_STRING }, 72 [IFACE_ATTR_HOST_DEVICE] = { .name = "host_device", .type = BLOBMSG_TYPE_STRING }, 73 [IFACE_ATTR_DEFAULTROUTE] = { .name = "defaultroute", .type = BLOBMSG_TYPE_BOOL }, 74 [IFACE_ATTR_PEERDNS] = { .name = "peerdns", .type = BLOBMSG_TYPE_BOOL }, 75 [IFACE_ATTR_METRIC] = { .name = "metric", .type = BLOBMSG_TYPE_INT32 }, 76 [IFACE_ATTR_DNS] = { .name = "dns", .type = BLOBMSG_TYPE_ARRAY }, 77 [IFACE_ATTR_RENEW] = { .name = "renew", .type = BLOBMSG_TYPE_BOOL }, 78 [IFACE_ATTR_DNS_SEARCH] = { .name = "dns_search", .type = BLOBMSG_TYPE_ARRAY }, 79 [IFACE_ATTR_DNS_METRIC] = { .name = "dns_metric", .type = BLOBMSG_TYPE_INT32 }, 80 [IFACE_ATTR_INTERFACE] = { .name = "interface", .type = BLOBMSG_TYPE_STRING }, 81 [IFACE_ATTR_IP6ASSIGN] = { .name = "ip6assign", .type = BLOBMSG_TYPE_INT32 }, 82 [IFACE_ATTR_IP6HINT] = { .name = "ip6hint", .type = BLOBMSG_TYPE_STRING }, 83 [IFACE_ATTR_IP4TABLE] = { .name = "ip4table", .type = BLOBMSG_TYPE_STRING }, 84 [IFACE_ATTR_IP6TABLE] = { .name = "ip6table", .type = BLOBMSG_TYPE_STRING }, 85 [IFACE_ATTR_IP6CLASS] = { .name = "ip6class", .type = BLOBMSG_TYPE_ARRAY }, 86 [IFACE_ATTR_DELEGATE] = { .name = "delegate", .type = BLOBMSG_TYPE_BOOL }, 87 [IFACE_ATTR_IP6IFACEID] = { .name = "ip6ifaceid", .type = BLOBMSG_TYPE_STRING }, 88 [IFACE_ATTR_FORCE_LINK] = { .name = "force_link", .type = BLOBMSG_TYPE_BOOL }, 89 [IFACE_ATTR_IP6WEIGHT] = { .name = "ip6weight", .type = BLOBMSG_TYPE_INT32 }, 90 }; 91 92 const struct uci_blob_param_list interface_attr_list = { 93 .n_params = IFACE_ATTR_MAX, 94 .params = iface_attrs, 95 }; 96 97 static void 98 interface_set_main_dev(struct interface *iface, struct device *dev); 99 static void 100 interface_event(struct interface *iface, enum interface_event ev); 101 102 static void 103 interface_error_flush(struct interface *iface) 104 { 105 struct interface_error *error, *tmp; 106 107 list_for_each_entry_safe(error, tmp, &iface->errors, list) { 108 list_del(&error->list); 109 free(error); 110 } 111 } 112 113 static bool 114 interface_force_link(struct interface *iface) 115 { 116 struct device *dev = iface->main_dev.dev; 117 118 if (dev && dev->settings.auth) 119 return false; 120 121 return iface->force_link; 122 } 123 124 static void 125 interface_clear_errors(struct interface *iface) 126 { 127 /* don't flush the errors in case the configured protocol handler matches the 128 running protocol handler and is having the last error capability */ 129 if (!(iface->proto && 130 (iface->proto->handler->flags & PROTO_FLAG_LASTERROR) && 131 (iface->proto->handler->name == iface->proto_handler->name))) 132 interface_error_flush(iface); 133 } 134 135 void interface_add_error(struct interface *iface, const char *subsystem, 136 const char *code, const char **data, int n_data) 137 { 138 struct interface_error *error; 139 int i, len = 0; 140 int *datalen = NULL; 141 char *dest, *d_subsys, *d_code; 142 143 /* if the configured protocol handler has the last error support capability, 144 errors should only be added if the running protocol handler matches the 145 configured one */ 146 if (iface->proto && 147 (iface->proto->handler->flags & PROTO_FLAG_LASTERROR) && 148 (iface->proto->handler->name != iface->proto_handler->name)) 149 return; 150 151 if (n_data) { 152 len = n_data * sizeof(char *); 153 datalen = alloca(len); 154 for (i = 0; i < n_data; i++) { 155 datalen[i] = strlen(data[i]) + 1; 156 len += datalen[i]; 157 } 158 } 159 160 error = calloc_a(sizeof(*error) + sizeof(char *) + len, 161 &d_subsys, subsystem ? strlen(subsystem) + 1 : 0, 162 &d_code, code ? strlen(code) + 1 : 0); 163 if (!error) 164 return; 165 166 /* Only keep the last flagged error, prevent this list grows unlimitted in case the 167 protocol can't be established (e.g auth failure) */ 168 if (iface->proto_handler->flags & PROTO_FLAG_LASTERROR) 169 interface_error_flush(iface); 170 171 list_add_tail(&error->list, &iface->errors); 172 173 dest = (char *) &error->data[n_data + 1]; 174 for (i = 0; i < n_data; i++) { 175 error->data[i] = dest; 176 memcpy(dest, data[i], datalen[i]); 177 dest += datalen[i]; 178 } 179 error->data[n_data] = NULL; 180 181 if (subsystem) 182 error->subsystem = strcpy(d_subsys, subsystem); 183 184 if (code) 185 error->code = strcpy(d_code, code); 186 } 187 188 static void 189 interface_data_del(struct interface *iface, struct interface_data *data) 190 { 191 avl_delete(&iface->data, &data->node); 192 free(data); 193 } 194 195 static void 196 interface_data_flush(struct interface *iface) 197 { 198 struct interface_data *d, *tmp; 199 200 avl_for_each_element_safe(&iface->data, d, node, tmp) 201 interface_data_del(iface, d); 202 } 203 204 int 205 interface_add_data(struct interface *iface, const struct blob_attr *data) 206 { 207 struct interface_data *n, *o; 208 209 if (!blobmsg_check_attr(data, true)) 210 return UBUS_STATUS_INVALID_ARGUMENT; 211 212 const char *name = blobmsg_name(data); 213 unsigned len = blob_pad_len(data); 214 215 o = avl_find_element(&iface->data, name, o, node); 216 if (o) { 217 if (blob_pad_len(o->data) == len && !memcmp(o->data, data, len)) 218 return 0; 219 220 interface_data_del(iface, o); 221 } 222 223 n = calloc(1, sizeof(*n) + len); 224 if (!n) 225 return UBUS_STATUS_UNKNOWN_ERROR; 226 227 memcpy(n->data, data, len); 228 n->node.key = blobmsg_name(n->data); 229 avl_insert(&iface->data, &n->node); 230 231 iface->updated |= IUF_DATA; 232 return 0; 233 } 234 235 int interface_parse_data(struct interface *iface, const struct blob_attr *attr) 236 { 237 struct blob_attr *cur; 238 size_t rem; 239 int ret; 240 241 iface->updated = 0; 242 243 blob_for_each_attr(cur, attr, rem) { 244 ret = interface_add_data(iface, cur); 245 if (ret) 246 return ret; 247 } 248 249 if (iface->updated && iface->state == IFS_UP) 250 interface_event(iface, IFEV_UPDATE); 251 252 return 0; 253 } 254 255 static void 256 interface_event(struct interface *iface, enum interface_event ev) 257 { 258 struct interface_user *dep, *tmp; 259 struct device *adev = NULL; 260 261 list_for_each_entry_safe(dep, tmp, &iface->users, list) 262 dep->cb(dep, iface, ev); 263 264 list_for_each_entry_safe(dep, tmp, &iface_all_users, list) 265 dep->cb(dep, iface, ev); 266 267 switch (ev) { 268 case IFEV_UP: 269 interface_error_flush(iface); 270 adev = iface->l3_dev.dev; 271 fallthrough; 272 case IFEV_DOWN: 273 case IFEV_UP_FAILED: 274 alias_notify_device(iface->name, adev); 275 break; 276 default: 277 break; 278 } 279 } 280 281 static void 282 interface_flush_state(struct interface *iface) 283 { 284 if (iface->l3_dev.dev) 285 device_release(&iface->l3_dev); 286 interface_data_flush(iface); 287 } 288 289 static void 290 mark_interface_down(struct interface *iface) 291 { 292 enum interface_state state = iface->state; 293 294 if (state == IFS_DOWN) 295 return; 296 297 iface->link_up_event = false; 298 iface->state = IFS_DOWN; 299 switch (state) { 300 case IFS_UP: 301 case IFS_TEARDOWN: 302 interface_event(iface, IFEV_DOWN); 303 break; 304 case IFS_SETUP: 305 interface_event(iface, IFEV_UP_FAILED); 306 break; 307 default: 308 break; 309 } 310 interface_ip_set_enabled(&iface->config_ip, false); 311 interface_ip_set_enabled(&iface->proto_ip, false); 312 interface_ip_flush(&iface->proto_ip); 313 interface_flush_state(iface); 314 system_flush_routes(); 315 } 316 317 static inline void 318 __set_config_state(struct interface *iface, enum interface_config_state s) 319 { 320 iface->config_state = s; 321 } 322 323 static void 324 __interface_set_down(struct interface *iface, bool force) 325 { 326 enum interface_state state = iface->state; 327 switch (state) { 328 case IFS_UP: 329 case IFS_SETUP: 330 iface->state = IFS_TEARDOWN; 331 if (iface->dynamic) 332 __set_config_state(iface, IFC_REMOVE); 333 334 if (state == IFS_UP) 335 interface_event(iface, IFEV_DOWN); 336 337 interface_proto_event(iface->proto, PROTO_CMD_TEARDOWN, force); 338 if (force) 339 interface_flush_state(iface); 340 break; 341 342 case IFS_DOWN: 343 if (iface->main_dev.dev) 344 device_release(&iface->main_dev); 345 break; 346 case IFS_TEARDOWN: 347 default: 348 break; 349 } 350 } 351 352 static int 353 __interface_set_up(struct interface *iface) 354 { 355 int ret; 356 357 netifd_log_message(L_NOTICE, "Interface '%s' is setting up now\n", iface->name); 358 359 iface->state = IFS_SETUP; 360 ret = interface_proto_event(iface->proto, PROTO_CMD_SETUP, false); 361 if (ret) 362 mark_interface_down(iface); 363 364 return ret; 365 } 366 367 static void 368 interface_check_state(struct interface *iface) 369 { 370 bool link_state = iface->link_state || interface_force_link(iface); 371 372 switch (iface->state) { 373 case IFS_UP: 374 case IFS_SETUP: 375 if (!iface->enabled || !link_state) { 376 iface->state = IFS_TEARDOWN; 377 if (iface->dynamic) 378 __set_config_state(iface, IFC_REMOVE); 379 380 interface_proto_event(iface->proto, PROTO_CMD_TEARDOWN, false); 381 } 382 break; 383 case IFS_DOWN: 384 if (!iface->available) 385 return; 386 387 if (iface->autostart && iface->enabled && link_state && !config_init) 388 __interface_set_up(iface); 389 break; 390 default: 391 break; 392 } 393 } 394 395 static void 396 interface_set_enabled(struct interface *iface, bool new_state) 397 { 398 if (iface->enabled == new_state) 399 return; 400 401 netifd_log_message(L_NOTICE, "Interface '%s' is %s\n", iface->name, new_state ? "enabled" : "disabled"); 402 iface->enabled = new_state; 403 interface_check_state(iface); 404 } 405 406 static void 407 interface_set_link_state(struct interface *iface, bool new_state) 408 { 409 if (iface->link_state == new_state) 410 return; 411 412 netifd_log_message(L_NOTICE, "Interface '%s' has link connectivity %s\n", iface->name, new_state ? "" : "loss"); 413 iface->link_state = new_state; 414 interface_check_state(iface); 415 416 if (new_state && interface_force_link(iface) && 417 iface->state == IFS_UP && !iface->link_up_event) { 418 interface_event(iface, IFEV_LINK_UP); 419 iface->link_up_event = true; 420 } 421 } 422 423 static void 424 interface_ext_dev_cb(struct device_user *dep, enum device_event ev) 425 { 426 if (ev == DEV_EVENT_REMOVE) 427 device_remove_user(dep); 428 } 429 430 static void 431 interface_main_dev_cb(struct device_user *dep, enum device_event ev) 432 { 433 struct interface *iface; 434 435 iface = container_of(dep, struct interface, main_dev); 436 switch (ev) { 437 case DEV_EVENT_ADD: 438 interface_set_available(iface, true); 439 break; 440 case DEV_EVENT_REMOVE: 441 interface_set_available(iface, false); 442 if (dep->dev && dep->dev->external && !dep->dev->sys_present) 443 interface_set_main_dev(iface, NULL); 444 break; 445 case DEV_EVENT_UP: 446 interface_set_enabled(iface, true); 447 break; 448 case DEV_EVENT_DOWN: 449 interface_set_enabled(iface, false); 450 break; 451 case DEV_EVENT_AUTH_UP: 452 case DEV_EVENT_LINK_UP: 453 case DEV_EVENT_LINK_DOWN: 454 interface_set_link_state(iface, device_link_active(dep->dev)); 455 break; 456 case DEV_EVENT_TOPO_CHANGE: 457 if (iface->renew) 458 interface_proto_event(iface->proto, PROTO_CMD_RENEW, false); 459 return; 460 default: 461 break; 462 } 463 } 464 465 static void 466 interface_l3_dev_cb(struct device_user *dep, enum device_event ev) 467 { 468 struct interface *iface; 469 470 iface = container_of(dep, struct interface, l3_dev); 471 if (iface->l3_dev.dev == iface->main_dev.dev) 472 return; 473 474 switch (ev) { 475 case DEV_EVENT_LINK_DOWN: 476 if (iface->proto_handler->flags & PROTO_FLAG_TEARDOWN_ON_L3_LINK_DOWN) 477 interface_proto_event(iface->proto, PROTO_CMD_TEARDOWN, false); 478 break; 479 default: 480 break; 481 } 482 } 483 484 void 485 interface_set_available(struct interface *iface, bool new_state) 486 { 487 if (iface->available == new_state) 488 return; 489 490 D(INTERFACE, "Interface '%s', available=%d", iface->name, new_state); 491 iface->available = new_state; 492 493 if (new_state) { 494 if (iface->autostart && !config_init) 495 interface_set_up(iface); 496 } else 497 __interface_set_down(iface, true); 498 } 499 500 void 501 interface_add_user(struct interface_user *dep, struct interface *iface) 502 { 503 if (!iface) { 504 list_add(&dep->list, &iface_all_users); 505 return; 506 } 507 508 dep->iface = iface; 509 list_add(&dep->list, &iface->users); 510 if (iface->state == IFS_UP) 511 dep->cb(dep, iface, IFEV_UP); 512 } 513 514 void 515 interface_remove_user(struct interface_user *dep) 516 { 517 list_del_init(&dep->list); 518 dep->iface = NULL; 519 } 520 521 static void 522 interface_add_assignment_classes(struct interface *iface, struct blob_attr *list) 523 { 524 struct blob_attr *cur; 525 size_t rem; 526 527 blobmsg_for_each_attr(cur, list, rem) { 528 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING) 529 continue; 530 531 if (!blobmsg_check_attr(cur, false)) 532 continue; 533 534 struct interface_assignment_class *c = malloc(sizeof(*c) + blobmsg_data_len(cur)); 535 memcpy(c->name, blobmsg_data(cur), blobmsg_data_len(cur)); 536 list_add(&c->head, &iface->assignment_classes); 537 } 538 } 539 540 static void 541 interface_clear_assignment_classes(struct interface *iface) 542 { 543 while (!list_empty(&iface->assignment_classes)) { 544 struct interface_assignment_class *c = list_first_entry(&iface->assignment_classes, 545 struct interface_assignment_class, head); 546 list_del(&c->head); 547 free(c); 548 } 549 } 550 551 static void 552 interface_merge_assignment_data(struct interface *old, struct interface *new) 553 { 554 bool changed = (old->assignment_hint != new->assignment_hint || 555 old->assignment_length != new->assignment_length || 556 old->assignment_iface_id_selection != new->assignment_iface_id_selection || 557 old->assignment_weight != new->assignment_weight || 558 (old->assignment_iface_id_selection == IFID_FIXED && 559 memcmp(&old->assignment_fixed_iface_id, &new->assignment_fixed_iface_id, 560 sizeof(old->assignment_fixed_iface_id))) || 561 list_empty(&old->assignment_classes) != list_empty(&new->assignment_classes)); 562 563 struct interface_assignment_class *c; 564 list_for_each_entry(c, &new->assignment_classes, head) { 565 /* Compare list entries one-by-one to see if there was a change */ 566 if (list_empty(&old->assignment_classes)) /* The new list is longer */ 567 changed = true; 568 569 if (changed) 570 break; 571 572 struct interface_assignment_class *c_old = list_first_entry(&old->assignment_classes, 573 struct interface_assignment_class, head); 574 575 if (strcmp(c_old->name, c->name)) /* An entry didn't match */ 576 break; 577 578 list_del(&c_old->head); 579 free(c_old); 580 } 581 582 /* The old list was longer than the new one or the last entry didn't match */ 583 if (!list_empty(&old->assignment_classes)) { 584 interface_clear_assignment_classes(old); 585 changed = true; 586 } 587 588 list_splice_init(&new->assignment_classes, &old->assignment_classes); 589 590 if (changed) { 591 old->assignment_hint = new->assignment_hint; 592 old->assignment_length = new->assignment_length; 593 old->assignment_iface_id_selection = new->assignment_iface_id_selection; 594 old->assignment_fixed_iface_id = new->assignment_fixed_iface_id; 595 old->assignment_weight = new->assignment_weight; 596 interface_refresh_assignments(true); 597 } 598 } 599 600 static void 601 interface_alias_cb(struct interface_user *dep, struct interface *iface, enum interface_event ev) 602 { 603 struct interface *alias = container_of(dep, struct interface, parent_iface); 604 struct device *dev = iface->l3_dev.dev; 605 606 switch (ev) { 607 case IFEV_UP: 608 if (!dev) 609 return; 610 611 interface_set_main_dev(alias, dev); 612 interface_set_available(alias, true); 613 break; 614 case IFEV_DOWN: 615 case IFEV_UP_FAILED: 616 interface_set_available(alias, false); 617 interface_set_main_dev(alias, NULL); 618 break; 619 case IFEV_FREE: 620 interface_remove_user(dep); 621 break; 622 default: 623 break; 624 } 625 } 626 627 static void 628 interface_set_device_config(struct interface *iface, struct device *dev) 629 { 630 if (!dev || !dev->default_config) 631 return; 632 633 if (!iface->device_config && 634 (!dev->iface_config || dev->config_iface != iface)) 635 return; 636 637 dev->config_iface = iface; 638 dev->iface_config = iface->device_config; 639 device_apply_config(dev, dev->type, iface->config); 640 } 641 642 static void 643 interface_claim_device(struct interface *iface) 644 { 645 struct interface *parent; 646 struct device *dev = NULL; 647 648 if (iface->parent_iface.iface) 649 interface_remove_user(&iface->parent_iface); 650 651 if (iface->parent_ifname) { 652 parent = vlist_find(&interfaces, iface->parent_ifname, parent, node); 653 iface->parent_iface.cb = interface_alias_cb; 654 interface_add_user(&iface->parent_iface, parent); 655 } else if (iface->device && 656 !(iface->proto_handler->flags & PROTO_FLAG_NODEV)) { 657 dev = device_get(iface->device, true); 658 if (!(iface->proto_handler->flags & PROTO_FLAG_NODEV_CONFIG)) 659 interface_set_device_config(iface, dev); 660 } else { 661 dev = iface->ext_dev.dev; 662 } 663 664 if (dev) 665 interface_set_main_dev(iface, dev); 666 667 if (iface->proto_handler->flags & PROTO_FLAG_INIT_AVAILABLE) 668 interface_set_available(iface, true); 669 } 670 671 static void 672 interface_cleanup_state(struct interface *iface) 673 { 674 interface_set_available(iface, false); 675 676 interface_flush_state(iface); 677 interface_clear_errors(iface); 678 interface_set_proto_state(iface, NULL); 679 680 interface_set_main_dev(iface, NULL); 681 interface_set_l3_dev(iface, NULL); 682 } 683 684 static void 685 interface_cleanup(struct interface *iface) 686 { 687 struct interface_user *dep, *tmp; 688 689 uloop_timeout_cancel(&iface->remove_timer); 690 device_remove_user(&iface->ext_dev); 691 692 if (iface->parent_iface.iface) 693 interface_remove_user(&iface->parent_iface); 694 695 list_for_each_entry_safe(dep, tmp, &iface->users, list) 696 interface_remove_user(dep); 697 698 interface_clear_assignment_classes(iface); 699 interface_ip_flush(&iface->config_ip); 700 interface_cleanup_state(iface); 701 } 702 703 static void 704 interface_do_free(struct interface *iface) 705 { 706 interface_event(iface, IFEV_FREE); 707 interface_cleanup(iface); 708 free(iface->config); 709 netifd_ubus_remove_interface(iface); 710 avl_delete(&interfaces.avl, &iface->node.avl); 711 if (iface->jail) 712 free(iface->jail); 713 if (iface->jail_device) 714 free(iface->jail_device); 715 if (iface->host_device) 716 free(iface->host_device); 717 718 free(iface); 719 } 720 721 static void 722 interface_do_reload(struct interface *iface) 723 { 724 interface_event(iface, IFEV_RELOAD); 725 interface_cleanup_state(iface); 726 proto_init_interface(iface, iface->config); 727 interface_claim_device(iface); 728 } 729 730 static void 731 interface_handle_config_change(struct interface *iface) 732 { 733 enum interface_config_state state = iface->config_state; 734 735 iface->config_state = IFC_NORMAL; 736 switch(state) { 737 case IFC_NORMAL: 738 break; 739 case IFC_RELOAD: 740 interface_do_reload(iface); 741 break; 742 case IFC_REMOVE: 743 interface_do_free(iface); 744 return; 745 } 746 if (iface->autostart) 747 interface_set_up(iface); 748 } 749 750 static void 751 interface_proto_event_cb(struct interface_proto_state *state, enum interface_proto_event ev) 752 { 753 struct interface *iface = state->iface; 754 755 switch (ev) { 756 case IFPEV_UP: 757 if (iface->state != IFS_SETUP) { 758 if (iface->state == IFS_UP && iface->updated) 759 interface_event(iface, IFEV_UPDATE); 760 return; 761 } 762 763 if (!iface->l3_dev.dev) 764 interface_set_l3_dev(iface, iface->main_dev.dev); 765 766 interface_ip_set_enabled(&iface->config_ip, true); 767 interface_ip_set_enabled(&iface->proto_ip, true); 768 system_flush_routes(); 769 iface->state = IFS_UP; 770 iface->start_time = system_get_rtime(); 771 interface_event(iface, IFEV_UP); 772 netifd_log_message(L_NOTICE, "Interface '%s' is now up\n", iface->name); 773 break; 774 case IFPEV_DOWN: 775 if (iface->state == IFS_DOWN) 776 return; 777 778 netifd_log_message(L_NOTICE, "Interface '%s' is now down\n", iface->name); 779 mark_interface_down(iface); 780 interface_write_resolv_conf(iface->jail); 781 if (iface->main_dev.dev && !(iface->config_state == IFC_NORMAL && iface->autostart && iface->available)) 782 device_release(&iface->main_dev); 783 if (iface->l3_dev.dev) 784 device_remove_user(&iface->l3_dev); 785 interface_handle_config_change(iface); 786 return; 787 case IFPEV_LINK_LOST: 788 if (iface->state != IFS_UP) 789 return; 790 791 netifd_log_message(L_NOTICE, "Interface '%s' has lost the connection\n", iface->name); 792 mark_interface_down(iface); 793 iface->state = IFS_SETUP; 794 break; 795 default: 796 return; 797 } 798 799 interface_write_resolv_conf(iface->jail); 800 } 801 802 void interface_set_proto_state(struct interface *iface, struct interface_proto_state *state) 803 { 804 if (iface->proto) { 805 iface->proto->free(iface->proto); 806 iface->proto = NULL; 807 } 808 iface->state = IFS_DOWN; 809 iface->proto = state; 810 if (!state) 811 return; 812 813 state->proto_event = interface_proto_event_cb; 814 state->iface = iface; 815 } 816 817 struct interface * 818 interface_alloc(const char *name, struct blob_attr *config, bool dynamic) 819 { 820 struct interface *iface; 821 struct blob_attr *tb[IFACE_ATTR_MAX]; 822 struct blob_attr *cur; 823 const char *proto_name = NULL; 824 char *iface_name; 825 bool force_link = false; 826 827 iface = calloc_a(sizeof(*iface), &iface_name, strlen(name) + 1); 828 iface->name = strcpy(iface_name, name); 829 INIT_LIST_HEAD(&iface->errors); 830 INIT_LIST_HEAD(&iface->users); 831 INIT_LIST_HEAD(&iface->hotplug_list); 832 INIT_LIST_HEAD(&iface->assignment_classes); 833 interface_ip_init(iface); 834 avl_init(&iface->data, avl_strcmp, false, NULL); 835 iface->config_ip.enabled = false; 836 837 iface->main_dev.cb = interface_main_dev_cb; 838 iface->l3_dev.cb = interface_l3_dev_cb; 839 iface->ext_dev.cb = interface_ext_dev_cb; 840 841 blobmsg_parse(iface_attrs, IFACE_ATTR_MAX, tb, 842 blob_data(config), blob_len(config)); 843 844 iface->zone = NULL; 845 if ((cur = tb[IFACE_ATTR_ZONE])) 846 iface->zone = strdup(blobmsg_get_string(cur)); 847 848 if ((cur = tb[IFACE_ATTR_PROTO])) 849 proto_name = blobmsg_data(cur); 850 851 proto_attach_interface(iface, proto_name); 852 if (iface->proto_handler->flags & PROTO_FLAG_FORCE_LINK_DEFAULT) 853 force_link = true; 854 855 iface->autostart = blobmsg_get_bool_default(tb[IFACE_ATTR_AUTO], true); 856 iface->renew = blobmsg_get_bool_default(tb[IFACE_ATTR_RENEW], true); 857 iface->force_link = blobmsg_get_bool_default(tb[IFACE_ATTR_FORCE_LINK], force_link); 858 iface->dynamic = dynamic; 859 iface->proto_ip.no_defaultroute = 860 !blobmsg_get_bool_default(tb[IFACE_ATTR_DEFAULTROUTE], true); 861 iface->proto_ip.no_dns = 862 !blobmsg_get_bool_default(tb[IFACE_ATTR_PEERDNS], true); 863 864 if ((cur = tb[IFACE_ATTR_DNS])) 865 interface_add_dns_server_list(&iface->config_ip, cur); 866 867 if ((cur = tb[IFACE_ATTR_DNS_SEARCH])) 868 interface_add_dns_search_list(&iface->config_ip, cur); 869 870 if ((cur = tb[IFACE_ATTR_DNS_METRIC])) 871 iface->dns_metric = blobmsg_get_u32(cur); 872 873 if ((cur = tb[IFACE_ATTR_METRIC])) 874 iface->metric = blobmsg_get_u32(cur); 875 876 if ((cur = tb[IFACE_ATTR_IP6ASSIGN])) 877 iface->assignment_length = blobmsg_get_u32(cur); 878 879 /* defaults */ 880 iface->assignment_iface_id_selection = IFID_FIXED; 881 iface->assignment_fixed_iface_id = in6addr_any; 882 iface->assignment_fixed_iface_id.s6_addr[15] = 1; 883 884 if ((cur = tb[IFACE_ATTR_IP6IFACEID])) { 885 const char *ifaceid = blobmsg_data(cur); 886 if (!strcmp(ifaceid, "random")) { 887 iface->assignment_iface_id_selection = IFID_RANDOM; 888 } 889 else if (!strcmp(ifaceid, "eui64")) { 890 iface->assignment_iface_id_selection = IFID_EUI64; 891 } 892 else { 893 /* we expect an IPv6 address with network id zero here -> fixed iface id 894 if we cannot parse -> revert to iface id 1 */ 895 if (inet_pton(AF_INET6,ifaceid,&iface->assignment_fixed_iface_id) != 1 || 896 iface->assignment_fixed_iface_id.s6_addr32[0] != 0 || 897 iface->assignment_fixed_iface_id.s6_addr32[1] != 0) { 898 iface->assignment_fixed_iface_id = in6addr_any; 899 iface->assignment_fixed_iface_id.s6_addr[15] = 1; 900 netifd_log_message(L_WARNING, "Failed to parse ip6ifaceid for interface '%s', \ 901 falling back to iface id 1.\n", iface->name); 902 } 903 } 904 } 905 906 iface->assignment_hint = -1; 907 if ((cur = tb[IFACE_ATTR_IP6HINT])) 908 iface->assignment_hint = strtol(blobmsg_get_string(cur), NULL, 16) & 909 ~((1 << (64 - iface->assignment_length)) - 1); 910 911 if ((cur = tb[IFACE_ATTR_IP6CLASS])) 912 interface_add_assignment_classes(iface, cur); 913 914 if ((cur = tb[IFACE_ATTR_IP6WEIGHT])) 915 iface->assignment_weight = blobmsg_get_u32(cur); 916 917 if ((cur = tb[IFACE_ATTR_IP4TABLE])) { 918 if (!system_resolve_rt_table(blobmsg_data(cur), &iface->ip4table)) 919 D(INTERFACE, "Failed to resolve routing table: %s", (char *) blobmsg_data(cur)); 920 } 921 922 if ((cur = tb[IFACE_ATTR_IP6TABLE])) { 923 if (!system_resolve_rt_table(blobmsg_data(cur), &iface->ip6table)) 924 D(INTERFACE, "Failed to resolve routing table: %s", (char *) blobmsg_data(cur)); 925 } 926 927 iface->proto_ip.no_delegation = !blobmsg_get_bool_default(tb[IFACE_ATTR_DELEGATE], true); 928 929 iface->config_autostart = iface->autostart; 930 iface->jail = NULL; 931 932 if ((cur = tb[IFACE_ATTR_JAIL])) { 933 iface->jail = strdup(blobmsg_get_string(cur)); 934 iface->autostart = false; 935 } 936 937 iface->jail_device = NULL; 938 if ((cur = tb[IFACE_ATTR_JAIL_DEVICE])) 939 iface->jail_device = strdup(blobmsg_get_string(cur)); 940 else if ((cur = tb[IFACE_ATTR_JAIL_IFNAME])) 941 iface->jail_device = strdup(blobmsg_get_string(cur)); 942 943 iface->host_device = NULL; 944 if ((cur = tb[IFACE_ATTR_HOST_DEVICE])) 945 iface->host_device = strdup(blobmsg_get_string(cur)); 946 947 return iface; 948 } 949 950 static bool __interface_add(struct interface *iface, struct blob_attr *config, bool alias) 951 { 952 struct blob_attr *tb[IFACE_ATTR_MAX]; 953 struct blob_attr *cur; 954 char *name = NULL; 955 956 blobmsg_parse(iface_attrs, IFACE_ATTR_MAX, tb, 957 blob_data(config), blob_len(config)); 958 959 if (alias) { 960 if ((cur = tb[IFACE_ATTR_INTERFACE])) 961 iface->parent_ifname = blobmsg_data(cur); 962 963 if (!iface->parent_ifname) 964 return false; 965 } else { 966 cur = tb[IFACE_ATTR_DEVICE]; 967 if (!cur) 968 cur = tb[IFACE_ATTR_IFNAME]; 969 if (cur) 970 iface->device = blobmsg_data(cur); 971 } 972 973 if (iface->dynamic) { 974 name = strdup(iface->name); 975 976 if (!name) 977 return false; 978 } 979 980 iface->config = config; 981 vlist_add(&interfaces, &iface->node, iface->name); 982 983 if (name) { 984 iface = vlist_find(&interfaces, name, iface, node); 985 free(name); 986 987 /* Don't delete dynamic interface on reload */ 988 if (iface) 989 iface->node.version = -1; 990 } 991 992 return true; 993 } 994 995 bool 996 interface_add(struct interface *iface, struct blob_attr *config) 997 { 998 return __interface_add(iface, config, false); 999 } 1000 1001 bool 1002 interface_add_alias(struct interface *iface, struct blob_attr *config) 1003 { 1004 if (iface->proto_handler->flags & PROTO_FLAG_NODEV) 1005 return false; 1006 1007 return __interface_add(iface, config, true); 1008 } 1009 1010 void 1011 interface_set_l3_dev(struct interface *iface, struct device *dev) 1012 { 1013 bool enabled = iface->config_ip.enabled; 1014 bool claimed = iface->l3_dev.claimed; 1015 1016 if (iface->l3_dev.dev == dev) 1017 return; 1018 1019 interface_ip_set_enabled(&iface->config_ip, false); 1020 interface_ip_set_enabled(&iface->proto_ip, false); 1021 interface_ip_flush(&iface->proto_ip); 1022 device_add_user(&iface->l3_dev, dev); 1023 1024 if (dev) { 1025 if (claimed) { 1026 if (device_claim(&iface->l3_dev) < 0) 1027 return; 1028 } 1029 interface_ip_set_enabled(&iface->config_ip, enabled); 1030 interface_ip_set_enabled(&iface->proto_ip, enabled); 1031 } 1032 } 1033 1034 static void 1035 interface_set_main_dev(struct interface *iface, struct device *dev) 1036 { 1037 bool claimed = iface->l3_dev.claimed; 1038 1039 if (iface->main_dev.dev == dev) 1040 return; 1041 1042 interface_set_available(iface, false); 1043 device_add_user(&iface->main_dev, dev); 1044 if (!dev) { 1045 interface_set_link_state(iface, false); 1046 return; 1047 } 1048 1049 if (claimed) { 1050 if (device_claim(&iface->l3_dev) < 0) 1051 return; 1052 } 1053 1054 if (!iface->l3_dev.dev) 1055 interface_set_l3_dev(iface, dev); 1056 } 1057 1058 static int 1059 interface_remove_link(struct interface *iface, struct device *dev, 1060 struct blob_attr *vlan) 1061 { 1062 struct device *mdev = iface->main_dev.dev; 1063 1064 if (mdev && mdev->hotplug_ops) 1065 return mdev->hotplug_ops->del(mdev, dev, vlan); 1066 1067 if (dev == iface->ext_dev.dev) 1068 device_remove_user(&iface->ext_dev); 1069 1070 if (!iface->main_dev.hotplug) 1071 return UBUS_STATUS_INVALID_ARGUMENT; 1072 1073 if (dev != iface->main_dev.dev) 1074 return UBUS_STATUS_INVALID_ARGUMENT; 1075 1076 interface_set_main_dev(iface, NULL); 1077 return 0; 1078 } 1079 1080 static int 1081 interface_add_link(struct interface *iface, struct device *dev, 1082 struct blob_attr *vlan, bool link_ext) 1083 { 1084 struct device *mdev = iface->main_dev.dev; 1085 1086 if (mdev == dev && iface->state == IFS_UP) 1087 return 0; 1088 1089 if (iface->main_dev.hotplug) 1090 interface_set_main_dev(iface, NULL); 1091 1092 if (mdev) { 1093 if (mdev->hotplug_ops) 1094 return mdev->hotplug_ops->add(mdev, dev, vlan); 1095 else 1096 return UBUS_STATUS_NOT_SUPPORTED; 1097 } 1098 1099 if (link_ext) 1100 device_add_user(&iface->ext_dev, dev); 1101 1102 interface_set_main_dev(iface, dev); 1103 iface->main_dev.hotplug = true; 1104 return 0; 1105 } 1106 1107 int 1108 interface_handle_link(struct interface *iface, const char *name, 1109 struct blob_attr *vlan, bool add, bool link_ext) 1110 { 1111 struct device *dev; 1112 1113 dev = device_get(name, add ? (link_ext ? 2 : 1) : 0); 1114 if (!dev) 1115 return UBUS_STATUS_NOT_FOUND; 1116 1117 if (!add) 1118 return interface_remove_link(iface, dev, vlan); 1119 1120 interface_set_device_config(iface, dev); 1121 if (!link_ext) 1122 device_set_present(dev, true); 1123 1124 return interface_add_link(iface, dev, vlan, link_ext); 1125 } 1126 1127 void 1128 interface_set_up(struct interface *iface) 1129 { 1130 int ret; 1131 const char *error = NULL; 1132 1133 iface->autostart = true; 1134 wireless_check_network_enabled(); 1135 1136 if (iface->state != IFS_DOWN) 1137 return; 1138 1139 interface_clear_errors(iface); 1140 if (iface->available) { 1141 if (iface->main_dev.dev) { 1142 ret = device_claim(&iface->main_dev); 1143 if (!ret) 1144 interface_check_state(iface); 1145 else 1146 error = "DEVICE_CLAIM_FAILED"; 1147 } else { 1148 ret = __interface_set_up(iface); 1149 if (ret) 1150 error = "SETUP_FAILED"; 1151 } 1152 } else 1153 error = "NO_DEVICE"; 1154 1155 if (error) 1156 interface_add_error(iface, "interface", error, NULL, 0); 1157 } 1158 1159 void 1160 interface_set_down(struct interface *iface) 1161 { 1162 if (!iface) { 1163 vlist_for_each_element(&interfaces, iface, node) 1164 __interface_set_down(iface, false); 1165 } else { 1166 iface->autostart = false; 1167 wireless_check_network_enabled(); 1168 __interface_set_down(iface, false); 1169 } 1170 } 1171 1172 int 1173 interface_renew(struct interface *iface) 1174 { 1175 if (iface->state == IFS_TEARDOWN || iface->state == IFS_DOWN) 1176 return -1; 1177 1178 return interface_proto_event(iface->proto, PROTO_CMD_RENEW, false); 1179 } 1180 1181 void 1182 interface_start_pending(void) 1183 { 1184 struct interface *iface; 1185 1186 vlist_for_each_element(&interfaces, iface, node) { 1187 if (iface->autostart) 1188 interface_set_up(iface); 1189 } 1190 } 1191 1192 void 1193 interface_start_jail(int netns_fd, const char *jail) 1194 { 1195 struct interface *iface; 1196 1197 vlist_for_each_element(&interfaces, iface, node) { 1198 if (!iface->jail || strcmp(iface->jail, jail)) 1199 continue; 1200 1201 system_link_netns_move(iface->main_dev.dev, netns_fd, iface->jail_device); 1202 } 1203 } 1204 1205 void 1206 interface_stop_jail(int netns_fd) 1207 { 1208 struct interface *iface; 1209 char *orig_ifname; 1210 1211 vlist_for_each_element(&interfaces, iface, node) { 1212 orig_ifname = iface->host_device; 1213 interface_set_down(iface); 1214 system_link_netns_move(iface->main_dev.dev, netns_fd, orig_ifname); 1215 } 1216 } 1217 1218 static void 1219 set_config_state(struct interface *iface, enum interface_config_state s) 1220 { 1221 __set_config_state(iface, s); 1222 if (iface->state == IFS_DOWN) 1223 interface_handle_config_change(iface); 1224 else 1225 __interface_set_down(iface, false); 1226 } 1227 1228 void 1229 interface_update_start(struct interface *iface, const bool keep_old) 1230 { 1231 iface->updated = 0; 1232 1233 if (!keep_old) 1234 interface_ip_update_start(&iface->proto_ip); 1235 } 1236 1237 void 1238 interface_update_complete(struct interface *iface) 1239 { 1240 interface_ip_update_complete(&iface->proto_ip); 1241 } 1242 1243 static void 1244 interface_replace_dns(struct interface_ip_settings *new, struct interface_ip_settings *old) 1245 { 1246 vlist_simple_replace(&new->dns_servers, &old->dns_servers); 1247 vlist_simple_replace(&new->dns_search, &old->dns_search); 1248 } 1249 1250 static bool 1251 interface_device_config_changed(struct interface *if_old, struct interface *if_new) 1252 { 1253 struct blob_attr *ntb[__DEV_ATTR_MAX]; 1254 struct blob_attr *otb[__DEV_ATTR_MAX]; 1255 struct device *dev = if_old->main_dev.dev; 1256 unsigned long diff[2] = {}; 1257 1258 BUILD_BUG_ON(sizeof(diff) < __DEV_ATTR_MAX / 8); 1259 1260 if (!dev) 1261 return false; 1262 1263 if (if_old->device_config != if_new->device_config) 1264 return true; 1265 1266 if (!if_new->device_config) 1267 return false; 1268 1269 blobmsg_parse(device_attr_list.params, __DEV_ATTR_MAX, otb, 1270 blob_data(if_old->config), blob_len(if_old->config)); 1271 1272 blobmsg_parse(device_attr_list.params, __DEV_ATTR_MAX, ntb, 1273 blob_data(if_new->config), blob_len(if_new->config)); 1274 1275 uci_blob_diff(ntb, otb, &device_attr_list, diff); 1276 1277 return diff[0] | diff[1]; 1278 } 1279 1280 static void 1281 interface_change_config(struct interface *if_old, struct interface *if_new) 1282 { 1283 struct blob_attr *old_config = if_old->config; 1284 bool reload = false, reload_ip = false, update_prefix_delegation = false; 1285 1286 #define FIELD_CHANGED_STR(field) \ 1287 ((!!if_old->field != !!if_new->field) || \ 1288 (if_old->field && \ 1289 strcmp(if_old->field, if_new->field) != 0)) 1290 1291 if (FIELD_CHANGED_STR(parent_ifname)) { 1292 if (if_old->parent_iface.iface) 1293 interface_remove_user(&if_old->parent_iface); 1294 reload = true; 1295 } 1296 1297 if (!reload && interface_device_config_changed(if_old, if_new)) 1298 reload = true; 1299 1300 if (FIELD_CHANGED_STR(device) || 1301 if_old->proto_handler != if_new->proto_handler) 1302 reload = true; 1303 1304 if (!if_old->proto_handler->config_params) 1305 D(INTERFACE, "No config parameters for interface '%s'", 1306 if_old->name); 1307 else if (!uci_blob_check_equal(if_old->config, if_new->config, 1308 if_old->proto_handler->config_params)) 1309 reload = true; 1310 1311 #define UPDATE(field, __var) ({ \ 1312 bool __changed = (if_old->field != if_new->field); \ 1313 if_old->field = if_new->field; \ 1314 __var |= __changed; \ 1315 }) 1316 1317 if_old->config = if_new->config; 1318 if (if_old->config_autostart != if_new->config_autostart) { 1319 if (if_old->config_autostart) 1320 reload = true; 1321 1322 if_old->autostart = if_new->config_autostart; 1323 } 1324 1325 if_old->device_config = if_new->device_config; 1326 if_old->config_autostart = if_new->config_autostart; 1327 if (if_old->jail) 1328 free(if_old->jail); 1329 1330 if_old->jail = if_new->jail; 1331 if (if_old->jail) 1332 if_old->autostart = false; 1333 1334 if (if_old->jail_device) 1335 free(if_old->jail_device); 1336 1337 if_old->jail_device = if_new->jail_device; 1338 1339 if (if_old->host_device) 1340 free(if_old->host_device); 1341 1342 if_old->host_device = if_new->host_device; 1343 1344 if_old->device = if_new->device; 1345 if_old->parent_ifname = if_new->parent_ifname; 1346 if_old->dynamic = if_new->dynamic; 1347 if_old->proto_handler = if_new->proto_handler; 1348 if_old->force_link = if_new->force_link; 1349 if_old->dns_metric = if_new->dns_metric; 1350 1351 if (if_old->proto_ip.no_delegation != if_new->proto_ip.no_delegation) { 1352 if_old->proto_ip.no_delegation = if_new->proto_ip.no_delegation; 1353 update_prefix_delegation = true; 1354 } 1355 1356 if_old->proto_ip.no_dns = if_new->proto_ip.no_dns; 1357 interface_replace_dns(&if_old->config_ip, &if_new->config_ip); 1358 1359 UPDATE(metric, reload_ip); 1360 UPDATE(proto_ip.no_defaultroute, reload_ip); 1361 UPDATE(ip4table, reload_ip); 1362 UPDATE(ip6table, reload_ip); 1363 interface_merge_assignment_data(if_old, if_new); 1364 1365 #undef UPDATE 1366 1367 if (reload) { 1368 D(INTERFACE, "Reload interface '%s' because of config changes", 1369 if_old->name); 1370 interface_clear_errors(if_old); 1371 set_config_state(if_old, IFC_RELOAD); 1372 goto out; 1373 } 1374 1375 if (reload_ip) { 1376 bool config_ip_enabled = if_old->config_ip.enabled; 1377 bool proto_ip_enabled = if_old->proto_ip.enabled; 1378 1379 interface_ip_set_enabled(&if_old->config_ip, false); 1380 interface_ip_set_enabled(&if_old->proto_ip, false); 1381 interface_ip_set_enabled(&if_old->proto_ip, proto_ip_enabled); 1382 interface_ip_set_enabled(&if_old->config_ip, config_ip_enabled); 1383 } 1384 1385 if (update_prefix_delegation) 1386 interface_update_prefix_delegation(&if_old->proto_ip); 1387 1388 interface_write_resolv_conf(if_old->jail); 1389 if (if_old->main_dev.dev) 1390 interface_check_state(if_old); 1391 1392 out: 1393 if_new->config = NULL; 1394 interface_cleanup(if_new); 1395 free(old_config); 1396 free(if_new); 1397 } 1398 1399 static void 1400 interface_update(struct vlist_tree *tree, struct vlist_node *node_new, 1401 struct vlist_node *node_old) 1402 { 1403 struct interface *if_old = container_of(node_old, struct interface, node); 1404 struct interface *if_new = container_of(node_new, struct interface, node); 1405 1406 if (node_old && node_new) { 1407 D(INTERFACE, "Update interface '%s'", if_new->name); 1408 interface_change_config(if_old, if_new); 1409 } else if (node_old) { 1410 D(INTERFACE, "Remove interface '%s'", if_old->name); 1411 set_config_state(if_old, IFC_REMOVE); 1412 } else if (node_new) { 1413 D(INTERFACE, "Create interface '%s'", if_new->name); 1414 interface_event(if_new, IFEV_CREATE); 1415 proto_init_interface(if_new, if_new->config); 1416 interface_claim_device(if_new); 1417 netifd_ubus_add_interface(if_new); 1418 } 1419 } 1420 1421 1422 static void __init 1423 interface_init_list(void) 1424 { 1425 vlist_init(&interfaces, avl_strcmp, interface_update); 1426 interfaces.keep_old = true; 1427 interfaces.no_delete = true; 1428 } 1429
This page was automatically generated by LXR 0.3.1. • OpenWrt