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 <assert.h> 18 #include <errno.h> 19 20 #include "netifd.h" 21 #include "device.h" 22 #include "interface.h" 23 #include "system.h" 24 #include "ubus.h" 25 26 enum { 27 BRIDGE_ATTR_PORTS, 28 BRIDGE_ATTR_STP, 29 BRIDGE_ATTR_FORWARD_DELAY, 30 BRIDGE_ATTR_PRIORITY, 31 BRIDGE_ATTR_IGMP_SNOOP, 32 BRIDGE_ATTR_AGEING_TIME, 33 BRIDGE_ATTR_HELLO_TIME, 34 BRIDGE_ATTR_MAX_AGE, 35 BRIDGE_ATTR_BRIDGE_EMPTY, 36 BRIDGE_ATTR_MULTICAST_QUERIER, 37 BRIDGE_ATTR_HASH_MAX, 38 BRIDGE_ATTR_ROBUSTNESS, 39 BRIDGE_ATTR_QUERY_INTERVAL, 40 BRIDGE_ATTR_QUERY_RESPONSE_INTERVAL, 41 BRIDGE_ATTR_LAST_MEMBER_INTERVAL, 42 BRIDGE_ATTR_VLAN_FILTERING, 43 BRIDGE_ATTR_HAS_VLANS, 44 BRIDGE_ATTR_STP_KERNEL, 45 BRIDGE_ATTR_STP_PROTO, 46 __BRIDGE_ATTR_MAX 47 }; 48 49 static const struct blobmsg_policy bridge_attrs[__BRIDGE_ATTR_MAX] = { 50 [BRIDGE_ATTR_PORTS] = { "ports", BLOBMSG_TYPE_ARRAY }, 51 [BRIDGE_ATTR_STP] = { "stp", BLOBMSG_TYPE_BOOL }, 52 [BRIDGE_ATTR_FORWARD_DELAY] = { "forward_delay", BLOBMSG_TYPE_INT32 }, 53 [BRIDGE_ATTR_PRIORITY] = { "priority", BLOBMSG_TYPE_INT32 }, 54 [BRIDGE_ATTR_AGEING_TIME] = { "ageing_time", BLOBMSG_TYPE_INT32 }, 55 [BRIDGE_ATTR_HELLO_TIME] = { "hello_time", BLOBMSG_TYPE_INT32 }, 56 [BRIDGE_ATTR_MAX_AGE] = { "max_age", BLOBMSG_TYPE_INT32 }, 57 [BRIDGE_ATTR_IGMP_SNOOP] = { "igmp_snooping", BLOBMSG_TYPE_BOOL }, 58 [BRIDGE_ATTR_BRIDGE_EMPTY] = { "bridge_empty", BLOBMSG_TYPE_BOOL }, 59 [BRIDGE_ATTR_MULTICAST_QUERIER] = { "multicast_querier", BLOBMSG_TYPE_BOOL }, 60 [BRIDGE_ATTR_HASH_MAX] = { "hash_max", BLOBMSG_TYPE_INT32 }, 61 [BRIDGE_ATTR_ROBUSTNESS] = { "robustness", BLOBMSG_TYPE_INT32 }, 62 [BRIDGE_ATTR_QUERY_INTERVAL] = { "query_interval", BLOBMSG_TYPE_INT32 }, 63 [BRIDGE_ATTR_QUERY_RESPONSE_INTERVAL] = { "query_response_interval", BLOBMSG_TYPE_INT32 }, 64 [BRIDGE_ATTR_LAST_MEMBER_INTERVAL] = { "last_member_interval", BLOBMSG_TYPE_INT32 }, 65 [BRIDGE_ATTR_VLAN_FILTERING] = { "vlan_filtering", BLOBMSG_TYPE_BOOL }, 66 [BRIDGE_ATTR_HAS_VLANS] = { "__has_vlans", BLOBMSG_TYPE_BOOL }, /* internal */ 67 [BRIDGE_ATTR_STP_KERNEL] = { "stp_kernel", BLOBMSG_TYPE_BOOL }, 68 [BRIDGE_ATTR_STP_PROTO] = { "stp_proto", BLOBMSG_TYPE_STRING }, 69 }; 70 71 static const struct uci_blob_param_info bridge_attr_info[__BRIDGE_ATTR_MAX] = { 72 [BRIDGE_ATTR_PORTS] = { .type = BLOBMSG_TYPE_STRING }, 73 }; 74 75 static const struct uci_blob_param_list bridge_attr_list = { 76 .n_params = __BRIDGE_ATTR_MAX, 77 .params = bridge_attrs, 78 .info = bridge_attr_info, 79 80 .n_next = 1, 81 .next = { &device_attr_list }, 82 }; 83 84 static struct blob_buf b; 85 static struct device *bridge_create(const char *name, struct device_type *devtype, 86 struct blob_attr *attr); 87 static void bridge_config_init(struct device *dev); 88 static void bridge_dev_vlan_update(struct device *dev); 89 static void bridge_free(struct device *dev); 90 static void bridge_stp_init(struct device *dev); 91 static void bridge_dump_info(struct device *dev, struct blob_buf *b); 92 static enum dev_change_type 93 bridge_reload(struct device *dev, struct blob_attr *attr); 94 95 static struct device_type bridge_device_type = { 96 .name = "bridge", 97 .config_params = &bridge_attr_list, 98 99 .bridge_capability = true, 100 .name_prefix = "br", 101 102 .create = bridge_create, 103 .config_init = bridge_config_init, 104 .vlan_update = bridge_dev_vlan_update, 105 .reload = bridge_reload, 106 .free = bridge_free, 107 .dump_info = bridge_dump_info, 108 .stp_init = bridge_stp_init, 109 }; 110 111 struct bridge_state { 112 struct device dev; 113 device_state_cb set_state; 114 115 struct blob_attr *config_data; 116 struct bridge_config config; 117 struct blob_attr *ports; 118 bool active; 119 bool force_active; 120 bool has_vlans; 121 122 struct uloop_timeout retry; 123 struct bridge_member *primary_port; 124 struct vlist_tree members; 125 int n_present; 126 int n_failed; 127 }; 128 129 struct bridge_member { 130 struct vlist_node node; 131 struct bridge_state *bst; 132 struct device_user dev; 133 struct uloop_timeout check_timer; 134 struct device_vlan_range *extra_vlan; 135 int n_extra_vlan; 136 uint16_t pvid; 137 bool present; 138 bool active; 139 char name[]; 140 }; 141 142 static void 143 bridge_reset_primary(struct bridge_state *bst) 144 { 145 struct bridge_member *bm; 146 147 if (!bst->primary_port && 148 (bst->dev.settings.flags & DEV_OPT_MACADDR)) 149 return; 150 151 bst->primary_port = NULL; 152 bst->dev.settings.flags &= ~DEV_OPT_MACADDR; 153 vlist_for_each_element(&bst->members, bm, node) { 154 uint8_t *macaddr; 155 156 if (!bm->present) 157 continue; 158 159 bst->primary_port = bm; 160 if (bm->dev.dev->settings.flags & DEV_OPT_MACADDR) 161 macaddr = bm->dev.dev->settings.macaddr; 162 else 163 macaddr = bm->dev.dev->orig_settings.macaddr; 164 memcpy(bst->dev.settings.macaddr, macaddr, 6); 165 bst->dev.settings.flags |= DEV_OPT_MACADDR; 166 return; 167 } 168 } 169 170 static struct bridge_vlan_port * 171 bridge_find_vlan_member_port(struct bridge_member *bm, struct bridge_vlan *vlan) 172 { 173 struct bridge_vlan_hotplug_port *port; 174 const char *ifname = bm->dev.dev->ifname; 175 int i; 176 177 for (i = 0; i < vlan->n_ports; i++) { 178 if (strcmp(vlan->ports[i].ifname, ifname) != 0) 179 continue; 180 181 return &vlan->ports[i]; 182 } 183 184 list_for_each_entry(port, &vlan->hotplug_ports, list) { 185 if (strcmp(port->port.ifname, ifname) != 0) 186 continue; 187 188 return &port->port; 189 } 190 191 return NULL; 192 } 193 194 static bool 195 bridge_member_vlan_is_pvid(struct bridge_member *bm, struct bridge_vlan_port *port) 196 { 197 return (!bm->pvid && (port->flags & BRVLAN_F_UNTAGGED)) || 198 (port->flags & BRVLAN_F_PVID); 199 } 200 201 static void 202 __bridge_set_member_vlan(struct bridge_member *bm, struct bridge_vlan *vlan, 203 struct bridge_vlan_port *port, bool add) 204 { 205 uint16_t flags; 206 207 flags = port->flags; 208 if (bm->pvid == vlan->vid) 209 flags |= BRVLAN_F_PVID; 210 211 system_bridge_vlan(port->ifname, vlan->vid, -1, add, flags); 212 } 213 214 static void 215 bridge_set_member_vlan(struct bridge_member *bm, struct bridge_vlan *vlan, bool add) 216 { 217 struct bridge_vlan_port *port; 218 219 if (!bm->present) 220 return; 221 222 port = bridge_find_vlan_member_port(bm, vlan); 223 if (!port) 224 return; 225 226 if (!add && bm->pvid == vlan->vid) 227 bm->pvid = 0; 228 else if (add && bridge_member_vlan_is_pvid(bm, port)) 229 bm->pvid = vlan->vid; 230 231 __bridge_set_member_vlan(bm, vlan, port, add); 232 } 233 234 static void 235 bridge_set_local_vlan(struct bridge_state *bst, struct bridge_vlan *vlan, bool add) 236 { 237 if (!vlan->local && add) 238 return; 239 240 system_bridge_vlan(bst->dev.ifname, vlan->vid, -1, add, BRVLAN_F_SELF); 241 } 242 243 static void 244 bridge_set_local_vlans(struct bridge_state *bst, bool add) 245 { 246 struct bridge_vlan *vlan; 247 248 vlist_for_each_element(&bst->dev.vlans, vlan, node) 249 bridge_set_local_vlan(bst, vlan, add); 250 } 251 252 static struct bridge_vlan * 253 bridge_recalc_member_pvid(struct bridge_member *bm) 254 { 255 struct bridge_state *bst = bm->bst; 256 struct bridge_vlan_port *port; 257 struct bridge_vlan *vlan, *ret = NULL; 258 259 vlist_for_each_element(&bst->dev.vlans, vlan, node) { 260 port = bridge_find_vlan_member_port(bm, vlan); 261 if (!port) 262 continue; 263 264 if (!bridge_member_vlan_is_pvid(bm, port)) 265 continue; 266 267 ret = vlan; 268 if (port->flags & BRVLAN_F_PVID) 269 break; 270 } 271 272 return ret; 273 } 274 275 static void 276 bridge_set_vlan_state(struct bridge_state *bst, struct bridge_vlan *vlan, bool add) 277 { 278 struct bridge_member *bm; 279 struct bridge_vlan *vlan2; 280 bool clear_pvid = false; 281 282 bridge_set_local_vlan(bst, vlan, add); 283 284 vlist_for_each_element(&bst->members, bm, node) { 285 struct bridge_vlan_port *port; 286 287 port = bridge_find_vlan_member_port(bm, vlan); 288 if (!port) 289 continue; 290 291 if (add) { 292 if (bridge_member_vlan_is_pvid(bm, port)) 293 bm->pvid = vlan->vid; 294 } else if (bm->pvid == vlan->vid) { 295 vlan2 = bridge_recalc_member_pvid(bm); 296 if (vlan2 && vlan2->vid != vlan->vid) { 297 bridge_set_member_vlan(bm, vlan2, false); 298 bm->pvid = vlan2->vid; 299 bridge_set_member_vlan(bm, vlan2, true); 300 } else if (!vlan2) { 301 clear_pvid = true; 302 } 303 } 304 305 if (bm->present) 306 __bridge_set_member_vlan(bm, vlan, port, add); 307 308 if (clear_pvid) 309 bm->pvid = 0; 310 } 311 } 312 313 static int 314 bridge_disable_member(struct bridge_member *bm, bool keep_dev) 315 { 316 struct bridge_state *bst = bm->bst; 317 struct bridge_vlan *vlan; 318 319 if (!bm->present || !bm->active) 320 return 0; 321 322 bm->active = false; 323 vlist_for_each_element(&bst->dev.vlans, vlan, node) 324 bridge_set_member_vlan(bm, vlan, false); 325 326 system_bridge_delif(&bst->dev, bm->dev.dev); 327 if (!keep_dev) 328 device_release(&bm->dev); 329 330 if (bm->dev.dev->settings.flags & DEV_OPT_IPV6) { 331 bm->dev.dev->settings.ipv6 = 1; 332 bm->dev.dev->settings.flags &= ~DEV_OPT_IPV6; 333 } 334 335 device_broadcast_event(&bst->dev, DEV_EVENT_TOPO_CHANGE); 336 337 return 0; 338 } 339 340 static void bridge_stp_notify(struct bridge_state *bst) 341 { 342 struct bridge_config *cfg = &bst->config; 343 344 if (!cfg->stp || cfg->stp_kernel) 345 return; 346 347 blob_buf_init(&b, 0); 348 blobmsg_add_string(&b, "name", bst->dev.ifname); 349 if (cfg->stp_proto) 350 blobmsg_add_string(&b, "proto", cfg->stp_proto); 351 blobmsg_add_u32(&b, "forward_delay", cfg->forward_delay); 352 blobmsg_add_u32(&b, "hello_time", cfg->hello_time); 353 blobmsg_add_u32(&b, "max_age", cfg->max_age); 354 if (cfg->flags & BRIDGE_OPT_AGEING_TIME) 355 blobmsg_add_u32(&b, "ageing_time", cfg->ageing_time); 356 netifd_ubus_device_notify("stp_init", b.head, 1000); 357 } 358 359 static int 360 bridge_enable_interface(struct bridge_state *bst) 361 { 362 struct device *dev = &bst->dev; 363 int i, ret; 364 365 if (bst->active) 366 return 0; 367 368 bridge_stp_notify(bst); 369 ret = system_bridge_addbr(dev, &bst->config); 370 if (ret < 0) 371 return ret; 372 373 if (bst->has_vlans) { 374 /* delete default VLAN 1 */ 375 system_bridge_vlan(bst->dev.ifname, 1, -1, false, BRVLAN_F_SELF); 376 377 bridge_set_local_vlans(bst, true); 378 } 379 380 for (i = 0; i < dev->n_extra_vlan; i++) 381 system_bridge_vlan(dev->ifname, dev->extra_vlan[i].start, 382 dev->extra_vlan[i].end, true, BRVLAN_F_SELF); 383 384 bst->active = true; 385 return 0; 386 } 387 388 static void 389 bridge_stp_init(struct device *dev) 390 { 391 struct bridge_state *bst; 392 393 bst = container_of(dev, struct bridge_state, dev); 394 if (!bst->config.stp || !bst->active) 395 return; 396 397 bridge_stp_notify(bst); 398 system_bridge_set_stp_state(&bst->dev, false); 399 system_bridge_set_stp_state(&bst->dev, true); 400 } 401 402 static void 403 bridge_disable_interface(struct bridge_state *bst) 404 { 405 if (!bst->active) 406 return; 407 408 system_bridge_delbr(&bst->dev); 409 bst->active = false; 410 } 411 412 static struct bridge_vlan * 413 bridge_hotplug_get_vlan(struct bridge_state *bst, uint16_t vid, bool create) 414 { 415 struct bridge_vlan *vlan; 416 417 vlan = vlist_find(&bst->dev.vlans, &vid, vlan, node); 418 if (vlan || !create) 419 return vlan; 420 421 vlan = calloc(1, sizeof(*vlan)); 422 vlan->vid = vid; 423 vlan->local = true; 424 INIT_LIST_HEAD(&vlan->hotplug_ports); 425 vlist_add(&bst->dev.vlans, &vlan->node, &vlan->vid); 426 vlan->node.version = -1; 427 428 return vlan; 429 } 430 431 static struct bridge_vlan_hotplug_port * 432 bridge_hotplug_get_vlan_port(struct bridge_vlan *vlan, const char *ifname) 433 { 434 struct bridge_vlan_hotplug_port *port; 435 436 list_for_each_entry(port, &vlan->hotplug_ports, list) 437 if (!strcmp(port->port.ifname, ifname)) 438 return port; 439 440 return NULL; 441 } 442 443 static void 444 bridge_hotplug_set_member_vlans(struct bridge_state *bst, struct blob_attr *vlans, 445 struct bridge_member *bm, bool add, bool untracked) 446 { 447 const char *ifname = bm->name; 448 struct device_vlan_range *r; 449 struct bridge_vlan *vlan; 450 struct blob_attr *cur; 451 int n_vlans; 452 size_t rem; 453 454 if (!vlans) 455 return; 456 457 if (add) { 458 bm->n_extra_vlan = 0; 459 n_vlans = blobmsg_check_array(vlans, BLOBMSG_TYPE_STRING); 460 if (n_vlans < 1) 461 return; 462 463 bm->extra_vlan = realloc(bm->extra_vlan, n_vlans * sizeof(*bm->extra_vlan)); 464 } 465 466 blobmsg_for_each_attr(cur, vlans, rem) { 467 struct bridge_vlan_hotplug_port *port; 468 unsigned int vid, vid_end; 469 uint16_t flags = 0; 470 char *name_buf; 471 char *end; 472 473 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING) 474 continue; 475 476 vid = strtoul(blobmsg_get_string(cur), &end, 0); 477 vid_end = vid; 478 if (!vid || vid > 4095) 479 continue; 480 481 if (*end == '-') { 482 vid_end = strtoul(end + 1, &end, 0); 483 if (vid_end < vid) 484 continue; 485 } 486 487 if (end && *end) { 488 if (*end != ':') 489 continue; 490 491 for (end++; *end; end++) { 492 switch (*end) { 493 case 'u': 494 flags |= BRVLAN_F_UNTAGGED; 495 fallthrough; 496 case '*': 497 flags |= BRVLAN_F_PVID; 498 break; 499 } 500 } 501 } 502 503 vlan = bridge_hotplug_get_vlan(bst, vid, !!flags); 504 if (!vlan || vid_end > vid || untracked) { 505 if (add) { 506 if (!untracked) { 507 r = &bm->extra_vlan[bm->n_extra_vlan++]; 508 r->start = vid; 509 r->end = vid_end; 510 } 511 if (bm->active) 512 system_bridge_vlan(ifname, vid, vid_end, true, flags); 513 } else if (bm->active) { 514 system_bridge_vlan(ifname, vid, vid_end, false, 0); 515 } 516 continue; 517 } 518 519 if (vlan->pending) { 520 vlan->pending = false; 521 bridge_set_vlan_state(bst, vlan, true); 522 } 523 524 port = bridge_hotplug_get_vlan_port(vlan, ifname); 525 if (!add) { 526 if (!port) 527 continue; 528 529 __bridge_set_member_vlan(bm, vlan, &port->port, false); 530 list_del(&port->list); 531 free(port); 532 continue; 533 } 534 535 if (port) { 536 if (port->port.flags == flags) 537 continue; 538 539 __bridge_set_member_vlan(bm, vlan, &port->port, false); 540 port->port.flags = flags; 541 __bridge_set_member_vlan(bm, vlan, &port->port, true); 542 continue; 543 } 544 545 port = calloc_a(sizeof(*port), &name_buf, strlen(ifname) + 1); 546 if (!port) 547 continue; 548 549 port->port.flags = flags; 550 port->port.ifname = strcpy(name_buf, ifname); 551 list_add_tail(&port->list, &vlan->hotplug_ports); 552 553 if (!bm) 554 continue; 555 556 __bridge_set_member_vlan(bm, vlan, &port->port, true); 557 } 558 } 559 560 561 static void 562 bridge_member_add_extra_vlans(struct bridge_member *bm) 563 { 564 struct device *dev = bm->dev.dev; 565 int i; 566 567 for (i = 0; i < dev->n_extra_vlan; i++) 568 system_bridge_vlan(dev->ifname, dev->extra_vlan[i].start, 569 dev->extra_vlan[i].end, true, 0); 570 for (i = 0; i < bm->n_extra_vlan; i++) 571 system_bridge_vlan(dev->ifname, bm->extra_vlan[i].start, 572 bm->extra_vlan[i].end, true, 0); 573 } 574 575 static void 576 bridge_member_enable_vlans(struct bridge_member *bm) 577 { 578 struct bridge_state *bst = bm->bst; 579 struct device *dev = bm->dev.dev; 580 struct bridge_vlan *vlan; 581 582 if (dev->settings.auth) { 583 bridge_hotplug_set_member_vlans(bst, dev->config_auth_vlans, bm, 584 !dev->auth_status, true); 585 bridge_hotplug_set_member_vlans(bst, dev->auth_vlans, bm, 586 dev->auth_status, true); 587 } 588 589 if (dev->settings.auth && !dev->auth_status) 590 return; 591 592 bridge_member_add_extra_vlans(bm); 593 vlist_for_each_element(&bst->dev.vlans, vlan, node) 594 bridge_set_member_vlan(bm, vlan, true); 595 } 596 597 static int 598 bridge_enable_member(struct bridge_member *bm) 599 { 600 struct bridge_state *bst = bm->bst; 601 struct device *dev; 602 int ret; 603 604 if (!bm->present) 605 return 0; 606 607 ret = bridge_enable_interface(bst); 608 if (ret) 609 goto error; 610 611 /* Disable IPv6 for bridge members */ 612 if (!(bm->dev.dev->settings.flags & DEV_OPT_IPV6)) { 613 bm->dev.dev->settings.ipv6 = 0; 614 bm->dev.dev->settings.flags |= DEV_OPT_IPV6; 615 } 616 617 ret = device_claim(&bm->dev); 618 if (ret < 0) 619 goto error; 620 621 dev = bm->dev.dev; 622 if (dev->settings.auth && !bst->has_vlans && !dev->auth_status) 623 return -1; 624 625 if (!bm->active) { 626 ret = system_bridge_addif(&bst->dev, bm->dev.dev); 627 if (ret < 0) { 628 D(DEVICE, "Bridge device %s could not be added", bm->dev.dev->ifname); 629 goto error; 630 } 631 632 bm->active = true; 633 } 634 635 if (bst->has_vlans) { 636 /* delete default VLAN 1 */ 637 system_bridge_vlan(bm->dev.dev->ifname, 1, -1, false, 0); 638 639 bridge_member_enable_vlans(bm); 640 } 641 642 device_set_present(&bst->dev, true); 643 if (!dev->settings.auth || dev->auth_status) 644 device_broadcast_event(&bst->dev, DEV_EVENT_TOPO_CHANGE); 645 646 return 0; 647 648 error: 649 bst->n_failed++; 650 bm->present = false; 651 bst->n_present--; 652 device_release(&bm->dev); 653 654 return ret; 655 } 656 657 static void 658 bridge_remove_member(struct bridge_member *bm) 659 { 660 struct bridge_state *bst = bm->bst; 661 662 if (!bm->present) 663 return; 664 665 if (bst->dev.active) 666 bridge_disable_member(bm, false); 667 668 bm->present = false; 669 bm->bst->n_present--; 670 671 if (bm == bst->primary_port) 672 bridge_reset_primary(bst); 673 674 if (bst->config.bridge_empty) 675 return; 676 677 bst->force_active = false; 678 if (bst->n_present == 0) 679 device_set_present(&bst->dev, false); 680 } 681 682 static void 683 bridge_free_member(struct bridge_member *bm) 684 { 685 struct bridge_state *bst = bm->bst; 686 struct device *dev = bm->dev.dev; 687 const char *ifname = dev->ifname; 688 struct bridge_vlan *vlan; 689 690 bridge_remove_member(bm); 691 692 restart: 693 vlist_for_each_element(&bst->dev.vlans, vlan, node) { 694 struct bridge_vlan_hotplug_port *port, *tmp; 695 bool free_port = false; 696 697 list_for_each_entry_safe(port, tmp, &vlan->hotplug_ports, list) { 698 if (strcmp(port->port.ifname, ifname) != 0) 699 continue; 700 701 list_del(&port->list); 702 free(port); 703 free_port = true; 704 } 705 706 if (!free_port || !list_empty(&vlan->hotplug_ports) || 707 vlan->n_ports || vlan->node.version != -1) 708 continue; 709 710 vlist_delete(&bst->dev.vlans, &vlan->node); 711 goto restart; 712 } 713 714 device_remove_user(&bm->dev); 715 uloop_timeout_cancel(&bm->check_timer); 716 717 /* 718 * When reloading the config and moving a device from one bridge to 719 * another, the other bridge may have tried to claim this device 720 * before it was removed here. 721 * Ensure that claiming the device is retried by toggling its present 722 * state 723 */ 724 if (dev->present) { 725 device_set_present(dev, false); 726 device_set_present(dev, true); 727 } 728 729 free(bm); 730 } 731 732 static void 733 bridge_check_retry(struct bridge_state *bst) 734 { 735 if (!bst->n_failed) 736 return; 737 738 uloop_timeout_set(&bst->retry, 100); 739 } 740 741 static void 742 bridge_member_check_cb(struct uloop_timeout *t) 743 { 744 struct bridge_member *bm; 745 struct bridge_state *bst; 746 747 bm = container_of(t, struct bridge_member, check_timer); 748 bst = bm->bst; 749 750 if (system_bridge_vlan_check(&bst->dev, bm->dev.dev->ifname) <= 0) 751 return; 752 753 bridge_disable_member(bm, true); 754 bridge_enable_member(bm); 755 } 756 757 static void 758 bridge_member_cb(struct device_user *dep, enum device_event ev) 759 { 760 struct bridge_member *bm = container_of(dep, struct bridge_member, dev); 761 struct bridge_state *bst = bm->bst; 762 struct device *dev = dep->dev; 763 764 switch (ev) { 765 case DEV_EVENT_ADD: 766 assert(!bm->present); 767 768 bm->present = true; 769 bst->n_present++; 770 771 if (bst->n_present == 1) 772 device_set_present(&bst->dev, true); 773 fallthrough; 774 case DEV_EVENT_AUTH_UP: 775 if (!bst->dev.active) 776 break; 777 778 if (bridge_enable_member(bm)) 779 break; 780 781 /* 782 * Adding a bridge member can overwrite the bridge mtu 783 * in the kernel, apply the bridge settings in case the 784 * bridge mtu is set 785 */ 786 system_if_apply_settings(&bst->dev, &bst->dev.settings, 787 DEV_OPT_MTU | DEV_OPT_MTU6); 788 break; 789 case DEV_EVENT_LINK_UP: 790 if (!bst->has_vlans) 791 break; 792 793 if (dev->settings.auth) 794 bridge_enable_member(bm); 795 796 uloop_timeout_set(&bm->check_timer, 1000); 797 break; 798 case DEV_EVENT_LINK_DOWN: 799 if (!dev->settings.auth) 800 break; 801 802 bridge_disable_member(bm, true); 803 break; 804 case DEV_EVENT_REMOVE: 805 if (dep->hotplug && !dev->sys_present) { 806 vlist_delete(&bst->members, &bm->node); 807 return; 808 } 809 810 if (bm->present) 811 bridge_remove_member(bm); 812 813 break; 814 default: 815 return; 816 } 817 } 818 819 static int 820 bridge_set_down(struct bridge_state *bst) 821 { 822 struct bridge_member *bm; 823 824 bst->set_state(&bst->dev, false); 825 826 vlist_for_each_element(&bst->members, bm, node) 827 bridge_disable_member(bm, false); 828 829 bridge_disable_interface(bst); 830 831 return 0; 832 } 833 834 static int 835 bridge_set_up(struct bridge_state *bst) 836 { 837 struct bridge_member *bm; 838 int ret; 839 840 bst->has_vlans = !avl_is_empty(&bst->dev.vlans.avl); 841 if (!bst->n_present) { 842 if (!bst->force_active) 843 return -ENOENT; 844 845 ret = bridge_enable_interface(bst); 846 if (ret) 847 return ret; 848 } 849 850 bst->n_failed = 0; 851 vlist_for_each_element(&bst->members, bm, node) 852 bridge_enable_member(bm); 853 bridge_check_retry(bst); 854 855 if (!bst->force_active && !bst->n_present) { 856 /* initialization of all member interfaces failed */ 857 bridge_disable_interface(bst); 858 device_set_present(&bst->dev, false); 859 return -ENOENT; 860 } 861 862 bridge_reset_primary(bst); 863 ret = bst->set_state(&bst->dev, true); 864 if (ret < 0) 865 bridge_set_down(bst); 866 867 return ret; 868 } 869 870 static int 871 bridge_set_state(struct device *dev, bool up) 872 { 873 struct bridge_state *bst; 874 875 bst = container_of(dev, struct bridge_state, dev); 876 877 if (up) 878 return bridge_set_up(bst); 879 else 880 return bridge_set_down(bst); 881 } 882 883 static struct bridge_member * 884 bridge_alloc_member(struct bridge_state *bst, const char *name, 885 struct device *dev, bool hotplug) 886 { 887 struct bridge_member *bm; 888 889 bm = calloc(1, sizeof(*bm) + strlen(name) + 1); 890 if (!bm) 891 return NULL; 892 893 bm->bst = bst; 894 bm->dev.cb = bridge_member_cb; 895 bm->dev.hotplug = hotplug; 896 bm->check_timer.cb = bridge_member_check_cb; 897 strcpy(bm->name, name); 898 bm->dev.dev = dev; 899 900 return bm; 901 } 902 903 static void bridge_insert_member(struct bridge_member *bm, const char *name) 904 { 905 struct bridge_state *bst = bm->bst; 906 bool hotplug = bm->dev.hotplug; 907 908 vlist_add(&bst->members, &bm->node, bm->name); 909 /* 910 * Need to look up the bridge member again as the above 911 * created pointer will be freed in case the bridge member 912 * already existed 913 */ 914 bm = vlist_find(&bst->members, name, bm, node); 915 if (hotplug && bm) 916 bm->node.version = -1; 917 } 918 919 static void 920 bridge_create_member(struct bridge_state *bst, const char *name, 921 struct device *dev, bool hotplug) 922 { 923 struct bridge_member *bm; 924 925 bm = bridge_alloc_member(bst, name, dev, hotplug); 926 if (bm) 927 bridge_insert_member(bm, name); 928 } 929 930 static void 931 bridge_member_update(struct vlist_tree *tree, struct vlist_node *node_new, 932 struct vlist_node *node_old) 933 { 934 struct bridge_member *bm; 935 struct device *dev; 936 937 if (node_new) { 938 bm = container_of(node_new, struct bridge_member, node); 939 940 if (node_old) { 941 free(bm); 942 return; 943 } 944 945 dev = bm->dev.dev; 946 bm->dev.dev = NULL; 947 device_add_user(&bm->dev, dev); 948 } 949 950 951 if (node_old) { 952 bm = container_of(node_old, struct bridge_member, node); 953 bridge_free_member(bm); 954 } 955 } 956 957 958 static void 959 bridge_add_member(struct bridge_state *bst, const char *name) 960 { 961 struct device *dev; 962 963 dev = device_get(name, true); 964 if (!dev) 965 return; 966 967 bridge_create_member(bst, name, dev, false); 968 } 969 970 static int 971 bridge_hotplug_add(struct device *dev, struct device *member, struct blob_attr *vlan) 972 { 973 struct bridge_state *bst = container_of(dev, struct bridge_state, dev); 974 struct bridge_member *bm; 975 bool new_entry = false; 976 977 bm = vlist_find(&bst->members, member->ifname, bm, node); 978 if (!bm) { 979 new_entry = true; 980 bm = bridge_alloc_member(bst, member->ifname, member, true); 981 } 982 bridge_hotplug_set_member_vlans(bst, vlan, bm, true, false); 983 if (new_entry) 984 bridge_insert_member(bm, member->ifname); 985 986 return 0; 987 } 988 989 static int 990 bridge_hotplug_del(struct device *dev, struct device *member, struct blob_attr *vlan) 991 { 992 struct bridge_state *bst = container_of(dev, struct bridge_state, dev); 993 struct bridge_member *bm; 994 995 bm = vlist_find(&bst->members, member->ifname, bm, node); 996 if (!bm) 997 return UBUS_STATUS_NOT_FOUND; 998 999 bridge_hotplug_set_member_vlans(bst, vlan, bm, false, false); 1000 if (!bm->dev.hotplug) 1001 return 0; 1002 1003 vlist_delete(&bst->members, &bm->node); 1004 return 0; 1005 } 1006 1007 static int 1008 bridge_hotplug_prepare(struct device *dev, struct device **bridge_dev) 1009 { 1010 struct bridge_state *bst; 1011 1012 if (bridge_dev) 1013 *bridge_dev = dev; 1014 1015 bst = container_of(dev, struct bridge_state, dev); 1016 bst->force_active = true; 1017 device_set_present(&bst->dev, true); 1018 1019 return 0; 1020 } 1021 1022 static const struct device_hotplug_ops bridge_ops = { 1023 .prepare = bridge_hotplug_prepare, 1024 .add = bridge_hotplug_add, 1025 .del = bridge_hotplug_del 1026 }; 1027 1028 static void 1029 bridge_free(struct device *dev) 1030 { 1031 struct bridge_state *bst; 1032 1033 bst = container_of(dev, struct bridge_state, dev); 1034 vlist_flush_all(&bst->members); 1035 vlist_flush_all(&dev->vlans); 1036 kvlist_free(&dev->vlan_aliases); 1037 free(bst->config_data); 1038 free(bst); 1039 } 1040 1041 static void 1042 bridge_dump_port(struct blob_buf *b, struct bridge_vlan_port *port) 1043 { 1044 bool tagged = !(port->flags & BRVLAN_F_UNTAGGED); 1045 bool pvid = (port->flags & BRVLAN_F_PVID); 1046 1047 blobmsg_printf(b, NULL, "%s%s%s%s", port->ifname, 1048 tagged || pvid ? ":" : "", 1049 tagged ? "t" : "", 1050 pvid ? "*" : ""); 1051 } 1052 1053 static void 1054 bridge_dump_vlan(struct blob_buf *b, struct bridge_vlan *vlan) 1055 { 1056 struct bridge_vlan_hotplug_port *port; 1057 void *c, *p; 1058 int i; 1059 1060 c = blobmsg_open_table(b, NULL); 1061 1062 blobmsg_add_u32(b, "id", vlan->vid); 1063 blobmsg_add_u8(b, "local", vlan->local); 1064 1065 p = blobmsg_open_array(b, "ports"); 1066 1067 for (i = 0; i < vlan->n_ports; i++) 1068 bridge_dump_port(b, &vlan->ports[i]); 1069 1070 list_for_each_entry(port, &vlan->hotplug_ports, list) 1071 bridge_dump_port(b, &port->port); 1072 1073 blobmsg_close_array(b, p); 1074 1075 blobmsg_close_table(b, c); 1076 } 1077 1078 static void 1079 bridge_dump_info(struct device *dev, struct blob_buf *b) 1080 { 1081 struct bridge_config *cfg; 1082 struct bridge_state *bst; 1083 struct bridge_member *bm; 1084 struct bridge_vlan *vlan; 1085 void *list; 1086 void *c; 1087 1088 bst = container_of(dev, struct bridge_state, dev); 1089 cfg = &bst->config; 1090 1091 system_if_dump_info(dev, b); 1092 list = blobmsg_open_array(b, "bridge-members"); 1093 1094 vlist_for_each_element(&bst->members, bm, node) { 1095 if (bm->dev.dev->hidden) 1096 continue; 1097 1098 blobmsg_add_string(b, NULL, bm->dev.dev->ifname); 1099 } 1100 1101 blobmsg_close_array(b, list); 1102 1103 c = blobmsg_open_table(b, "bridge-attributes"); 1104 1105 blobmsg_add_u8(b, "stp", cfg->stp); 1106 blobmsg_add_u32(b, "forward_delay", cfg->forward_delay); 1107 blobmsg_add_u32(b, "priority", cfg->priority); 1108 blobmsg_add_u32(b, "ageing_time", cfg->ageing_time); 1109 blobmsg_add_u32(b, "hello_time", cfg->hello_time); 1110 blobmsg_add_u32(b, "max_age", cfg->max_age); 1111 blobmsg_add_u8(b, "igmp_snooping", cfg->igmp_snoop); 1112 blobmsg_add_u8(b, "bridge_empty", cfg->bridge_empty); 1113 blobmsg_add_u8(b, "multicast_querier", cfg->multicast_querier); 1114 blobmsg_add_u32(b, "hash_max", cfg->hash_max); 1115 blobmsg_add_u32(b, "robustness", cfg->robustness); 1116 blobmsg_add_u32(b, "query_interval", cfg->query_interval); 1117 blobmsg_add_u32(b, "query_response_interval", cfg->query_response_interval); 1118 blobmsg_add_u32(b, "last_member_interval", cfg->last_member_interval); 1119 blobmsg_add_u8(b, "vlan_filtering", cfg->vlan_filtering); 1120 blobmsg_add_u8(b, "stp_kernel", cfg->stp_kernel); 1121 if (cfg->stp_proto) 1122 blobmsg_add_string(b, "stp_proto", cfg->stp_proto); 1123 1124 blobmsg_close_table(b, c); 1125 1126 if (avl_is_empty(&dev->vlans.avl)) 1127 return; 1128 1129 list = blobmsg_open_array(b, "bridge-vlans"); 1130 1131 vlist_for_each_element(&bst->dev.vlans, vlan, node) 1132 bridge_dump_vlan(b, vlan); 1133 1134 blobmsg_close_array(b, list); 1135 } 1136 1137 static void 1138 bridge_config_init(struct device *dev) 1139 { 1140 struct bridge_state *bst; 1141 struct bridge_vlan *vlan; 1142 struct blob_attr *cur; 1143 size_t rem; 1144 int i; 1145 1146 bst = container_of(dev, struct bridge_state, dev); 1147 1148 if (bst->config.bridge_empty) { 1149 bst->force_active = true; 1150 device_set_present(&bst->dev, true); 1151 } 1152 1153 bst->n_failed = 0; 1154 vlist_update(&bst->members); 1155 if (bst->ports) { 1156 blobmsg_for_each_attr(cur, bst->ports, rem) { 1157 bridge_add_member(bst, blobmsg_data(cur)); 1158 } 1159 } 1160 1161 vlist_for_each_element(&bst->dev.vlans, vlan, node) 1162 for (i = 0; i < vlan->n_ports; i++) 1163 bridge_add_member(bst, vlan->ports[i].ifname); 1164 1165 vlist_flush(&bst->members); 1166 bridge_check_retry(bst); 1167 } 1168 1169 static void 1170 bridge_apply_settings(struct bridge_state *bst, struct blob_attr **tb) 1171 { 1172 struct bridge_config *cfg = &bst->config; 1173 struct blob_attr *cur; 1174 1175 /* defaults */ 1176 memset(cfg, 0, sizeof(*cfg)); 1177 cfg->stp = false; 1178 cfg->stp_kernel = false; 1179 cfg->robustness = 2; 1180 cfg->igmp_snoop = false; 1181 cfg->multicast_querier = false; 1182 cfg->query_interval = 12500; 1183 cfg->query_response_interval = 1000; 1184 cfg->last_member_interval = 100; 1185 cfg->hash_max = 512; 1186 cfg->bridge_empty = false; 1187 cfg->priority = 0x7FFF; 1188 cfg->vlan_filtering = false; 1189 1190 cfg->forward_delay = 8; 1191 cfg->max_age = 10; 1192 cfg->hello_time = 1; 1193 1194 if ((cur = tb[BRIDGE_ATTR_STP])) 1195 cfg->stp = blobmsg_get_bool(cur); 1196 1197 if ((cur = tb[BRIDGE_ATTR_STP_KERNEL])) 1198 cfg->stp = blobmsg_get_bool(cur); 1199 1200 if ((cur = tb[BRIDGE_ATTR_STP_PROTO])) 1201 cfg->stp_proto = blobmsg_get_string(cur); 1202 1203 if ((cur = tb[BRIDGE_ATTR_FORWARD_DELAY])) 1204 cfg->forward_delay = blobmsg_get_u32(cur); 1205 1206 if ((cur = tb[BRIDGE_ATTR_PRIORITY])) 1207 cfg->priority = blobmsg_get_u32(cur); 1208 1209 if ((cur = tb[BRIDGE_ATTR_IGMP_SNOOP])) 1210 cfg->multicast_querier = cfg->igmp_snoop = blobmsg_get_bool(cur); 1211 1212 if ((cur = tb[BRIDGE_ATTR_MULTICAST_QUERIER])) 1213 cfg->multicast_querier = blobmsg_get_bool(cur); 1214 1215 if ((cur = tb[BRIDGE_ATTR_HASH_MAX])) 1216 cfg->hash_max = blobmsg_get_u32(cur); 1217 1218 if ((cur = tb[BRIDGE_ATTR_ROBUSTNESS])) { 1219 cfg->robustness = blobmsg_get_u32(cur); 1220 cfg->flags |= BRIDGE_OPT_ROBUSTNESS; 1221 } 1222 1223 if ((cur = tb[BRIDGE_ATTR_QUERY_INTERVAL])) { 1224 cfg->query_interval = blobmsg_get_u32(cur); 1225 cfg->flags |= BRIDGE_OPT_QUERY_INTERVAL; 1226 } 1227 1228 if ((cur = tb[BRIDGE_ATTR_QUERY_RESPONSE_INTERVAL])) { 1229 cfg->query_response_interval = blobmsg_get_u32(cur); 1230 cfg->flags |= BRIDGE_OPT_QUERY_RESPONSE_INTERVAL; 1231 } 1232 1233 if ((cur = tb[BRIDGE_ATTR_LAST_MEMBER_INTERVAL])) { 1234 cfg->last_member_interval = blobmsg_get_u32(cur); 1235 cfg->flags |= BRIDGE_OPT_LAST_MEMBER_INTERVAL; 1236 } 1237 1238 if ((cur = tb[BRIDGE_ATTR_AGEING_TIME])) { 1239 cfg->ageing_time = blobmsg_get_u32(cur); 1240 cfg->flags |= BRIDGE_OPT_AGEING_TIME; 1241 } 1242 1243 if ((cur = tb[BRIDGE_ATTR_HELLO_TIME])) 1244 cfg->hello_time = blobmsg_get_u32(cur); 1245 1246 if ((cur = tb[BRIDGE_ATTR_MAX_AGE])) 1247 cfg->max_age = blobmsg_get_u32(cur); 1248 1249 if ((cur = tb[BRIDGE_ATTR_BRIDGE_EMPTY])) 1250 cfg->bridge_empty = blobmsg_get_bool(cur); 1251 1252 if ((cur = tb[BRIDGE_ATTR_VLAN_FILTERING])) 1253 cfg->vlan_filtering = blobmsg_get_bool(cur); 1254 } 1255 1256 static enum dev_change_type 1257 bridge_reload(struct device *dev, struct blob_attr *attr) 1258 { 1259 struct blob_attr *tb_dev[__DEV_ATTR_MAX]; 1260 struct blob_attr *tb_br[__BRIDGE_ATTR_MAX]; 1261 enum dev_change_type ret = DEV_CONFIG_APPLIED; 1262 struct bridge_state *bst; 1263 unsigned long diff[2] = {}; 1264 1265 BUILD_BUG_ON(sizeof(diff) < __BRIDGE_ATTR_MAX / BITS_PER_LONG); 1266 BUILD_BUG_ON(sizeof(diff) < __DEV_ATTR_MAX / BITS_PER_LONG); 1267 1268 bst = container_of(dev, struct bridge_state, dev); 1269 attr = blob_memdup(attr); 1270 1271 blobmsg_parse(device_attr_list.params, __DEV_ATTR_MAX, tb_dev, 1272 blob_data(attr), blob_len(attr)); 1273 blobmsg_parse(bridge_attrs, __BRIDGE_ATTR_MAX, tb_br, 1274 blob_data(attr), blob_len(attr)); 1275 1276 if (tb_dev[DEV_ATTR_MACADDR]) 1277 bst->primary_port = NULL; 1278 1279 bst->ports = tb_br[BRIDGE_ATTR_PORTS]; 1280 device_init_settings(dev, tb_dev); 1281 bridge_apply_settings(bst, tb_br); 1282 1283 if (bst->config_data) { 1284 struct blob_attr *otb_dev[__DEV_ATTR_MAX]; 1285 struct blob_attr *otb_br[__BRIDGE_ATTR_MAX]; 1286 1287 blobmsg_parse(device_attr_list.params, __DEV_ATTR_MAX, otb_dev, 1288 blob_data(bst->config_data), blob_len(bst->config_data)); 1289 1290 uci_blob_diff(tb_dev, otb_dev, &device_attr_list, diff); 1291 if (diff[0] | diff[1]) { 1292 ret = DEV_CONFIG_RESTART; 1293 D(DEVICE, "Bridge %s device attributes have changed, diff=[%lx %lx]", 1294 dev->ifname, diff[1], diff[0]); 1295 } 1296 1297 blobmsg_parse(bridge_attrs, __BRIDGE_ATTR_MAX, otb_br, 1298 blob_data(bst->config_data), blob_len(bst->config_data)); 1299 1300 diff[0] = diff[1] = 0; 1301 uci_blob_diff(tb_br, otb_br, &bridge_attr_list, diff); 1302 if (diff[0] & ~(1 << BRIDGE_ATTR_PORTS)) { 1303 ret = DEV_CONFIG_RESTART; 1304 D(DEVICE, "Bridge %s attributes have changed, diff=[%lx %lx]", 1305 dev->ifname, diff[1], diff[0]); 1306 } 1307 1308 bridge_config_init(dev); 1309 } 1310 1311 free(bst->config_data); 1312 bst->config_data = attr; 1313 return ret; 1314 } 1315 1316 static void 1317 bridge_retry_members(struct uloop_timeout *timeout) 1318 { 1319 struct bridge_state *bst = container_of(timeout, struct bridge_state, retry); 1320 struct bridge_member *bm; 1321 1322 bst->n_failed = 0; 1323 vlist_for_each_element(&bst->members, bm, node) { 1324 if (bm->present) 1325 continue; 1326 1327 if (!bm->dev.dev->present) 1328 continue; 1329 1330 bm->present = true; 1331 bst->n_present++; 1332 bridge_enable_member(bm); 1333 } 1334 } 1335 1336 static int bridge_avl_cmp_u16(const void *k1, const void *k2, void *ptr) 1337 { 1338 const uint16_t *i1 = k1, *i2 = k2; 1339 1340 return *i1 - *i2; 1341 } 1342 1343 static bool 1344 bridge_vlan_equal(struct bridge_vlan *v1, struct bridge_vlan *v2) 1345 { 1346 int i; 1347 1348 if (v1->n_ports != v2->n_ports) 1349 return false; 1350 1351 for (i = 0; i < v1->n_ports; i++) 1352 if (v1->ports[i].flags != v2->ports[i].flags || 1353 strcmp(v1->ports[i].ifname, v2->ports[i].ifname) != 0) 1354 return false; 1355 1356 return true; 1357 } 1358 1359 static void 1360 bridge_vlan_free(struct bridge_vlan *vlan) 1361 { 1362 struct bridge_vlan_hotplug_port *port, *tmp; 1363 1364 if (!vlan) 1365 return; 1366 1367 list_for_each_entry_safe(port, tmp, &vlan->hotplug_ports, list) 1368 free(port); 1369 1370 free(vlan); 1371 } 1372 1373 static void 1374 bridge_vlan_update(struct vlist_tree *tree, struct vlist_node *node_new, 1375 struct vlist_node *node_old) 1376 { 1377 struct bridge_state *bst = container_of(tree, struct bridge_state, dev.vlans); 1378 struct bridge_vlan *vlan_new = NULL, *vlan_old = NULL; 1379 1380 if (node_old) 1381 vlan_old = container_of(node_old, struct bridge_vlan, node); 1382 if (node_new) 1383 vlan_new = container_of(node_new, struct bridge_vlan, node); 1384 1385 if (!bst->has_vlans || !bst->active) 1386 goto out; 1387 1388 if (node_new && node_old && bridge_vlan_equal(vlan_old, vlan_new)) { 1389 list_splice_init(&vlan_old->hotplug_ports, &vlan_new->hotplug_ports); 1390 goto out; 1391 } 1392 1393 if (node_old) 1394 bridge_set_vlan_state(bst, vlan_old, false); 1395 1396 if (node_old && node_new) 1397 list_splice_init(&vlan_old->hotplug_ports, &vlan_new->hotplug_ports); 1398 1399 if (node_new) 1400 vlan_new->pending = true; 1401 1402 out: 1403 bst->dev.config_pending = true; 1404 bridge_vlan_free(vlan_old); 1405 } 1406 1407 static void 1408 bridge_dev_vlan_update(struct device *dev) 1409 { 1410 struct bridge_state *bst = container_of(dev, struct bridge_state, dev); 1411 struct bridge_vlan *vlan; 1412 1413 vlist_for_each_element(&dev->vlans, vlan, node) { 1414 if (!vlan->pending) 1415 continue; 1416 1417 vlan->pending = false; 1418 bridge_set_vlan_state(bst, vlan, true); 1419 } 1420 } 1421 1422 static struct device * 1423 bridge_create(const char *name, struct device_type *devtype, 1424 struct blob_attr *attr) 1425 { 1426 struct bridge_state *bst; 1427 struct device *dev = NULL; 1428 1429 bst = calloc(1, sizeof(*bst)); 1430 if (!bst) 1431 return NULL; 1432 1433 dev = &bst->dev; 1434 1435 if (device_init(dev, devtype, name) < 0) { 1436 device_cleanup(dev); 1437 free(bst); 1438 return NULL; 1439 } 1440 1441 dev->config_pending = true; 1442 bst->retry.cb = bridge_retry_members; 1443 1444 bst->set_state = dev->set_state; 1445 dev->set_state = bridge_set_state; 1446 1447 dev->hotplug_ops = &bridge_ops; 1448 1449 vlist_init(&bst->members, avl_strcmp, bridge_member_update); 1450 bst->members.keep_old = true; 1451 1452 vlist_init(&dev->vlans, bridge_avl_cmp_u16, bridge_vlan_update); 1453 1454 bridge_reload(dev, attr); 1455 1456 return dev; 1457 } 1458 1459 static void __init bridge_device_type_init(void) 1460 { 1461 device_type_add(&bridge_device_type); 1462 } 1463
This page was automatically generated by LXR 0.3.1. • OpenWrt