1 #include <string.h> 2 #include <stdlib.h> 3 #include <stdio.h> 4 #include <assert.h> 5 6 #include "netifd.h" 7 #include "device.h" 8 #include "system.h" 9 10 enum { 11 VRF_ATTR_PORTS, 12 VRF_ATTR_TABLE, 13 __VRF_ATTR_MAX 14 }; 15 16 static const struct blobmsg_policy vrf_attrs[__VRF_ATTR_MAX] = { 17 [VRF_ATTR_PORTS] = { "ports", BLOBMSG_TYPE_ARRAY }, 18 [VRF_ATTR_TABLE] = { "table", BLOBMSG_TYPE_STRING }, 19 }; 20 21 static const struct uci_blob_param_info vrf_attr_info[__VRF_ATTR_MAX] = { 22 [VRF_ATTR_PORTS] = { .type = BLOBMSG_TYPE_STRING }, 23 }; 24 25 static const struct uci_blob_param_list vrf_attr_list = { 26 .n_params = __VRF_ATTR_MAX, 27 .params = vrf_attrs, 28 .info = vrf_attr_info, 29 30 .n_next = 1, 31 .next = { &device_attr_list }, 32 }; 33 34 static struct device *vrf_create(const char *name, struct device_type *devtype, 35 struct blob_attr *attr); 36 static void vrf_config_init(struct device *dev); 37 static void vrf_free(struct device *dev); 38 static void vrf_dump_info(struct device *dev, struct blob_buf *b); 39 static enum dev_change_type 40 vrf_reload(struct device *dev, struct blob_attr *attr); 41 42 static struct device_type vrf_state_type = { 43 .name = "vrf", 44 .config_params = &vrf_attr_list, 45 46 .bridge_capability = true, 47 48 .create = vrf_create, 49 .config_init = vrf_config_init, 50 .reload = vrf_reload, 51 .free = vrf_free, 52 .dump_info = vrf_dump_info, 53 }; 54 55 struct vrf_state { 56 struct device dev; 57 device_state_cb set_state; 58 59 struct blob_attr *config_data; 60 unsigned int table; 61 bool vrf_empty; 62 struct blob_attr *ports; 63 bool active; 64 bool force_active; 65 66 struct uloop_timeout retry; 67 struct vrf_member *primary_port; 68 struct vlist_tree members; 69 int n_present; 70 int n_failed; 71 }; 72 73 struct vrf_member { 74 struct vlist_node node; 75 struct vrf_state *vst; 76 struct device_user dev; 77 bool present; 78 bool active; 79 char name[]; 80 }; 81 82 static void 83 vrf_reset_primary(struct vrf_state *vst) 84 { 85 struct vrf_member *vm; 86 87 if (!vst->primary_port && 88 (vst->dev.settings.flags & DEV_OPT_MACADDR)) 89 return; 90 91 vst->primary_port = NULL; 92 vst->dev.settings.flags &= ~DEV_OPT_MACADDR; 93 vlist_for_each_element(&vst->members, vm, node) { 94 uint8_t *macaddr; 95 96 if (!vm->present) 97 continue; 98 99 vst->primary_port = vm; 100 if (vm->dev.dev->settings.flags & DEV_OPT_MACADDR) 101 macaddr = vm->dev.dev->settings.macaddr; 102 else 103 macaddr = vm->dev.dev->orig_settings.macaddr; 104 memcpy(vst->dev.settings.macaddr, macaddr, 6); 105 vst->dev.settings.flags |= DEV_OPT_MACADDR; 106 return; 107 } 108 } 109 110 static int 111 vrf_disable_member(struct vrf_member *vm, bool keep_dev) 112 { 113 struct vrf_state *vst = vm->vst; 114 115 if (!vm->present || !vm->active) 116 return 0; 117 118 vm->active = false; 119 120 system_vrf_delif(&vst->dev, vm->dev.dev); 121 if (!keep_dev) 122 device_release(&vm->dev); 123 124 device_broadcast_event(&vst->dev, DEV_EVENT_TOPO_CHANGE); 125 126 return 0; 127 } 128 129 static int 130 vrf_enable_interface(struct vrf_state *vst) 131 { 132 int ret; 133 134 if (vst->active) 135 return 0; 136 137 ret = system_vrf_addvrf(&vst->dev, vst->table); 138 if (ret < 0) 139 return ret; 140 141 vst->active = true; 142 return 0; 143 } 144 145 static void 146 vrf_disable_interface(struct vrf_state *vst) 147 { 148 if (!vst->active) 149 return; 150 151 system_vrf_delvrf(&vst->dev); 152 vst->active = false; 153 } 154 155 static int 156 vrf_enable_member(struct vrf_member *vm) 157 { 158 struct vrf_state *vst = vm->vst; 159 struct device *dev; 160 int ret; 161 162 if (!vm->present) 163 return 0; 164 165 ret = vrf_enable_interface(vst); 166 if (ret) 167 goto error; 168 169 /* Disable IPv6 for vrf ports */ 170 if (!(vm->dev.dev->settings.flags & DEV_OPT_IPV6)) { 171 vm->dev.dev->settings.ipv6 = 0; 172 vm->dev.dev->settings.flags |= DEV_OPT_IPV6; 173 } 174 175 ret = device_claim(&vm->dev); 176 if (ret < 0) 177 goto error; 178 179 dev = vm->dev.dev; 180 if (dev->settings.auth && !dev->auth_status) 181 return -1; 182 183 if (vm->active) 184 return 0; 185 186 ret = system_vrf_addif(&vst->dev, vm->dev.dev); 187 if (ret < 0) { 188 D(DEVICE, "Vrf device %s could not be added\n", vm->dev.dev->ifname); 189 goto error; 190 } 191 192 vm->active = true; 193 device_set_present(&vst->dev, true); 194 device_broadcast_event(&vst->dev, DEV_EVENT_TOPO_CHANGE); 195 196 return 0; 197 198 error: 199 vst->n_failed++; 200 vm->present = false; 201 vst->n_present--; 202 device_release(&vm->dev); 203 204 return ret; 205 } 206 207 static void 208 vrf_remove_member(struct vrf_member *vm) 209 { 210 struct vrf_state *vst = vm->vst; 211 212 if (!vm->present) 213 return; 214 215 if (vst->dev.active) 216 vrf_disable_member(vm, false); 217 218 vm->present = false; 219 vm->vst->n_present--; 220 221 if (vm == vst->primary_port) 222 vrf_reset_primary(vst); 223 224 if (vst->vrf_empty) 225 return; 226 227 vst->force_active = false; 228 if (vst->n_present == 0) 229 device_set_present(&vst->dev, false); 230 } 231 232 static void 233 vrf_free_member(struct vrf_member *vm) 234 { 235 struct device *dev = vm->dev.dev; 236 237 vrf_remove_member(vm); 238 device_remove_user(&vm->dev); 239 240 /* 241 * When reloading the config and moving a device from one vrf to 242 * another, the other vrf may have tried to claim this device 243 * before it was removed here. 244 * Ensure that claiming the device is retried by toggling its present 245 * state 246 */ 247 if (dev->present) { 248 device_set_present(dev, false); 249 device_set_present(dev, true); 250 } 251 252 free(vm); 253 } 254 255 static void 256 vrf_check_retry(struct vrf_state *vst) 257 { 258 if (!vst->n_failed) 259 return; 260 261 uloop_timeout_set(&vst->retry, 100); 262 } 263 264 static void 265 vrf_member_cb(struct device_user *dep, enum device_event ev) 266 { 267 struct vrf_member *vm = container_of(dep, struct vrf_member, dev); 268 struct vrf_state *vst = vm->vst; 269 struct device *dev = dep->dev; 270 271 switch (ev) { 272 case DEV_EVENT_ADD: 273 assert(!vm->present); 274 275 vm->present = true; 276 vst->n_present++; 277 278 if (vst->n_present == 1) 279 device_set_present(&vst->dev, true); 280 fallthrough; 281 case DEV_EVENT_AUTH_UP: 282 if (!vst->dev.active) 283 break; 284 285 if (vrf_enable_member(vm)) 286 break; 287 288 /* 289 * Adding a vrf port can overwrite the vrf device mtu 290 * in the kernel, apply the vrf settings in case the 291 * vrf device mtu is set 292 */ 293 system_if_apply_settings(&vst->dev, &vst->dev.settings, 294 DEV_OPT_MTU | DEV_OPT_MTU6); 295 break; 296 case DEV_EVENT_LINK_DOWN: 297 if (!dev->settings.auth) 298 break; 299 300 vrf_disable_member(vm, true); 301 break; 302 case DEV_EVENT_REMOVE: 303 if (dep->hotplug && !dev->sys_present) { 304 vlist_delete(&vst->members, &vm->node); 305 return; 306 } 307 308 if (vm->present) 309 vrf_remove_member(vm); 310 311 break; 312 default: 313 return; 314 } 315 } 316 317 static int 318 vrf_set_down(struct vrf_state *vst) 319 { 320 struct vrf_member *vm; 321 322 vst->set_state(&vst->dev, false); 323 324 vlist_for_each_element(&vst->members, vm, node) 325 vrf_disable_member(vm, false); 326 327 vrf_disable_interface(vst); 328 329 return 0; 330 } 331 332 static int 333 vrf_set_up(struct vrf_state *vst) 334 { 335 struct vrf_member *vm; 336 int ret; 337 338 if (!vst->n_present) { 339 if (!vst->force_active) 340 return -ENOENT; 341 342 ret = vrf_enable_interface(vst); 343 if (ret) 344 return ret; 345 } 346 347 vst->n_failed = 0; 348 vlist_for_each_element(&vst->members, vm, node) 349 vrf_enable_member(vm); 350 vrf_check_retry(vst); 351 352 if (!vst->force_active && !vst->n_present) { 353 /* initialization of all port member failed */ 354 vrf_disable_interface(vst); 355 device_set_present(&vst->dev, false); 356 return -ENOENT; 357 } 358 359 vrf_reset_primary(vst); 360 ret = vst->set_state(&vst->dev, true); 361 if (ret < 0) 362 vrf_set_down(vst); 363 364 return ret; 365 } 366 367 static int 368 vrf_set_state(struct device *dev, bool up) 369 { 370 struct vrf_state *vst; 371 372 vst = container_of(dev, struct vrf_state, dev); 373 374 if (up) 375 return vrf_set_up(vst); 376 else 377 return vrf_set_down(vst); 378 } 379 380 static struct vrf_member * 381 vrf_create_member(struct vrf_state *vst, const char *name, 382 struct device *dev, bool hotplug) 383 { 384 struct vrf_member *vm; 385 386 vm = calloc(1, sizeof(*vm) + strlen(name) + 1); 387 if (!vm) 388 return NULL; 389 390 vm->vst = vst; 391 vm->dev.cb = vrf_member_cb; 392 vm->dev.hotplug = hotplug; 393 strcpy(vm->name, name); 394 vm->dev.dev = dev; 395 vlist_add(&vst->members, &vm->node, vm->name); 396 /* 397 * Need to look up the vrf port again as the above 398 * created pointer will be freed in case the vrf port 399 * already existed 400 */ 401 vm = vlist_find(&vst->members, name, vm, node); 402 if (hotplug && vm) 403 vm->node.version = -1; 404 405 return vm; 406 } 407 408 static void 409 vrf_member_update(struct vlist_tree *tree, struct vlist_node *node_new, 410 struct vlist_node *node_old) 411 { 412 struct vrf_member *vm; 413 struct device *dev; 414 415 if (node_new) { 416 vm = container_of(node_new, struct vrf_member, node); 417 418 if (node_old) { 419 free(vm); 420 return; 421 } 422 423 dev = vm->dev.dev; 424 vm->dev.dev = NULL; 425 device_add_user(&vm->dev, dev); 426 } 427 428 429 if (node_old) { 430 vm = container_of(node_old, struct vrf_member, node); 431 vrf_free_member(vm); 432 } 433 } 434 435 static void 436 vrf_add_member(struct vrf_state *vst, const char *name) 437 { 438 struct device *dev; 439 440 dev = device_get(name, true); 441 if (!dev) 442 return; 443 444 vrf_create_member(vst, name, dev, false); 445 } 446 447 static int 448 vrf_hotplug_add(struct device *dev, struct device *member, struct blob_attr *vlan) 449 { 450 struct vrf_state *vst = container_of(dev, struct vrf_state, dev); 451 struct vrf_member *vm; 452 453 vm = vlist_find(&vst->members, member->ifname, vm, node); 454 if (!vm) 455 vrf_create_member(vst, member->ifname, member, true); 456 457 return 0; 458 } 459 460 static int 461 vrf_hotplug_del(struct device *dev, struct device *member, struct blob_attr *vlan) 462 { 463 struct vrf_state *vst = container_of(dev, struct vrf_state, dev); 464 struct vrf_member *vm; 465 466 vm = vlist_find(&vst->members, member->ifname, vm, node); 467 if (!vm) 468 return UBUS_STATUS_NOT_FOUND; 469 470 if (vm->dev.hotplug) 471 vlist_delete(&vst->members, &vm->node); 472 473 return 0; 474 } 475 476 static int 477 vrf_hotplug_prepare(struct device *dev, struct device **vrf_dev) 478 { 479 struct vrf_state *vst; 480 481 if (vrf_dev) 482 *vrf_dev = dev; 483 484 vst = container_of(dev, struct vrf_state, dev); 485 vst->force_active = true; 486 device_set_present(&vst->dev, true); 487 488 return 0; 489 } 490 491 static const struct device_hotplug_ops vrf_ops = { 492 .prepare = vrf_hotplug_prepare, 493 .add = vrf_hotplug_add, 494 .del = vrf_hotplug_del 495 }; 496 497 static void 498 vrf_free(struct device *dev) 499 { 500 struct vrf_state *vst; 501 502 vst = container_of(dev, struct vrf_state, dev); 503 vlist_flush_all(&vst->members); 504 free(vst->config_data); 505 free(vst); 506 } 507 508 static void 509 vrf_dump_info(struct device *dev, struct blob_buf *b) 510 { 511 struct vrf_state *vst; 512 struct vrf_member *vm; 513 void *list; 514 515 vst = container_of(dev, struct vrf_state, dev); 516 517 system_if_dump_info(dev, b); 518 list = blobmsg_open_array(b, "vrf-members"); 519 520 vlist_for_each_element(&vst->members, vm, node) { 521 if (vm->dev.dev->hidden) 522 continue; 523 524 blobmsg_add_string(b, NULL, vm->dev.dev->ifname); 525 } 526 527 blobmsg_close_array(b, list); 528 } 529 530 static void 531 vrf_config_init(struct device *dev) 532 { 533 struct vrf_state *vst; 534 struct blob_attr *cur; 535 size_t rem; 536 537 vst = container_of(dev, struct vrf_state, dev); 538 539 if (vst->vrf_empty) { 540 vst->force_active = true; 541 device_set_present(&vst->dev, true); 542 } 543 544 vst->n_failed = 0; 545 vlist_update(&vst->members); 546 if (vst->ports) { 547 blobmsg_for_each_attr(cur, vst->ports, rem) { 548 vrf_add_member(vst, blobmsg_data(cur)); 549 } 550 } 551 552 vlist_flush(&vst->members); 553 vrf_check_retry(vst); 554 } 555 556 static void 557 vrf_apply_settings(struct vrf_state *vst, struct blob_attr **tb) 558 { 559 struct blob_attr *cur; 560 561 vst->vrf_empty = true; 562 // default vrf routing table 563 vst->table = 10; 564 if ((cur = tb[VRF_ATTR_TABLE])) 565 system_resolve_rt_table(blobmsg_data(cur), &vst->table); 566 } 567 568 static enum dev_change_type 569 vrf_reload(struct device *dev, struct blob_attr *attr) 570 { 571 struct blob_attr *tb_dev[__DEV_ATTR_MAX]; 572 struct blob_attr *tb_v[__VRF_ATTR_MAX]; 573 enum dev_change_type ret = DEV_CONFIG_APPLIED; 574 struct vrf_state *vst; 575 unsigned long diff[2]; 576 577 BUILD_BUG_ON(sizeof(diff) < __VRF_ATTR_MAX / BITS_PER_LONG); 578 BUILD_BUG_ON(sizeof(diff) < __DEV_ATTR_MAX / BITS_PER_LONG); 579 580 vst = container_of(dev, struct vrf_state, dev); 581 attr = blob_memdup(attr); 582 583 blobmsg_parse(device_attr_list.params, __DEV_ATTR_MAX, tb_dev, 584 blob_data(attr), blob_len(attr)); 585 blobmsg_parse(vrf_attrs, __VRF_ATTR_MAX, tb_v, 586 blob_data(attr), blob_len(attr)); 587 588 if (tb_dev[DEV_ATTR_MACADDR]) 589 vst->primary_port = NULL; 590 591 vst->ports = tb_v[VRF_ATTR_PORTS]; 592 device_init_settings(dev, tb_dev); 593 vrf_apply_settings(vst, tb_v); 594 595 if (vst->config_data) { 596 struct blob_attr *otb_dev[__DEV_ATTR_MAX]; 597 struct blob_attr *otb_v[__VRF_ATTR_MAX]; 598 599 blobmsg_parse(device_attr_list.params, __DEV_ATTR_MAX, otb_dev, 600 blob_data(vst->config_data), blob_len(vst->config_data)); 601 602 diff[0] = diff[1] = 0; 603 uci_blob_diff(tb_dev, otb_dev, &device_attr_list, diff); 604 if (diff[0] | diff[1]) { 605 ret = DEV_CONFIG_RESTART; 606 D(DEVICE, "Vrf %s device attributes have changed, diff=[%lx %lx]\n", 607 dev->ifname, diff[1], diff[0]); 608 } 609 610 blobmsg_parse(vrf_attrs, __VRF_ATTR_MAX, otb_v, 611 blob_data(vst->config_data), blob_len(vst->config_data)); 612 613 diff[0] = diff[1] = 0; 614 uci_blob_diff(tb_v, otb_v, &vrf_attr_list, diff); 615 if (diff[0] & ~(1 << VRF_ATTR_PORTS)) { 616 ret = DEV_CONFIG_RESTART; 617 D(DEVICE, "Vrf %s attributes have changed, diff=[%lx %lx]\n", 618 dev->ifname, diff[1], diff[0]); 619 } 620 621 vrf_config_init(dev); 622 } 623 624 free(vst->config_data); 625 vst->config_data = attr; 626 return ret; 627 } 628 629 static void 630 vrf_retry_members(struct uloop_timeout *timeout) 631 { 632 struct vrf_state *vst = container_of(timeout, struct vrf_state, retry); 633 struct vrf_member *vm; 634 635 vst->n_failed = 0; 636 vlist_for_each_element(&vst->members, vm, node) { 637 if (vm->present) 638 continue; 639 640 if (!vm->dev.dev->present) 641 continue; 642 643 vm->present = true; 644 vst->n_present++; 645 vrf_enable_member(vm); 646 } 647 } 648 649 static struct device * 650 vrf_create(const char *name, struct device_type *devtype, 651 struct blob_attr *attr) 652 { 653 struct vrf_state *vst; 654 struct device *dev = NULL; 655 656 vst = calloc(1, sizeof(*vst)); 657 if (!vst) 658 return NULL; 659 660 dev = &vst->dev; 661 662 if (device_init(dev, devtype, name) < 0) { 663 device_cleanup(dev); 664 free(vst); 665 return NULL; 666 } 667 668 dev->config_pending = true; 669 vst->retry.cb = vrf_retry_members; 670 671 vst->set_state = dev->set_state; 672 dev->set_state = vrf_set_state; 673 674 dev->hotplug_ops = &vrf_ops; 675 676 vlist_init(&vst->members, avl_strcmp, vrf_member_update); 677 vst->members.keep_old = true; 678 679 vrf_reload(dev, attr); 680 681 return dev; 682 } 683 684 static void __init vrf_state_type_init(void) 685 { 686 device_type_add(&vrf_state_type); 687 } 688
This page was automatically generated by LXR 0.3.1. • OpenWrt