1 /* 2 * Copyright 2006-2007, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Axel Dörfler, axeld@pinc-software.de 7 */ 8 9 10 #include "domains.h" 11 #include "interfaces.h" 12 #include "stack_private.h" 13 #include "utility.h" 14 15 #include <net_device.h> 16 17 #include <lock.h> 18 #include <util/AutoLock.h> 19 20 #include <KernelExport.h> 21 22 #include <net/if_dl.h> 23 #include <new> 24 #include <stdio.h> 25 #include <stdlib.h> 26 #include <string.h> 27 28 29 #define TRACE_INTERFACES 30 #ifdef TRACE_INTERFACES 31 # define TRACE(x) dprintf x 32 #else 33 # define TRACE(x) ; 34 #endif 35 36 37 static mutex sInterfaceLock; 38 static DeviceInterfaceList sInterfaces; 39 static uint32 sInterfaceIndex; 40 static uint32 sDeviceIndex; 41 42 43 static status_t 44 device_consumer_thread(void *_interface) 45 { 46 net_device_interface *interface = (net_device_interface *)_interface; 47 net_device *device = interface->device; 48 net_buffer *buffer; 49 50 while (true) { 51 ssize_t status = fifo_dequeue_buffer(&interface->receive_queue, 0, 52 B_INFINITE_TIMEOUT, &buffer); 53 if (status == B_INTERRUPTED) 54 continue; 55 else if (status < B_OK) 56 break; 57 58 if (buffer->interface != NULL) { 59 // if the interface is already specified this buffer was 60 // delivered locally. 61 62 net_domain *domain = buffer->interface->domain; 63 64 if (domain->module->receive_data(buffer) == B_OK) 65 buffer = NULL; 66 } else { 67 // find handler for this packet 68 DeviceHandlerList::Iterator it2 = 69 interface->receive_funcs.GetIterator(); 70 while (buffer && it2.HasNext()) { 71 net_device_handler *handler = it2.Next(); 72 73 // if the handler returns B_OK, it consumed the buffer 74 if (handler->type == buffer->type 75 && handler->func(handler->cookie, device, buffer) == B_OK) 76 buffer = NULL; 77 } 78 } 79 80 if (buffer) 81 gNetBufferModule.free(buffer); 82 } 83 84 return B_OK; 85 } 86 87 88 static net_device_interface * 89 find_device_interface(const char *name) 90 { 91 DeviceInterfaceList::Iterator iterator = sInterfaces.GetIterator(); 92 93 while (iterator.HasNext()) { 94 net_device_interface *interface = iterator.Next(); 95 96 if (!strcmp(interface->device->name, name)) 97 return interface; 98 } 99 100 return NULL; 101 } 102 103 104 static status_t 105 domain_receive_adapter(void *cookie, net_device *device, net_buffer *buffer) 106 { 107 net_domain_private *domain = (net_domain_private *)cookie; 108 109 buffer->interface = find_interface(domain, device->index); 110 return domain->module->receive_data(buffer); 111 } 112 113 114 static net_device_interface * 115 allocate_device_interface(net_device *device, net_device_module_info *module) 116 { 117 net_device_interface *interface = new (std::nothrow) net_device_interface; 118 if (interface == NULL) 119 goto error_0; 120 121 recursive_lock_init(&interface->rx_lock, "rx lock"); 122 123 char name[128]; 124 snprintf(name, sizeof(name), "%s receive queue", device->name); 125 126 if (init_fifo(&interface->receive_queue, name, 16 * 1024 * 1024) < B_OK) 127 goto error_2; 128 129 interface->device = device; 130 interface->up_count = 0; 131 interface->ref_count = 1; 132 interface->deframe_func = NULL; 133 interface->deframe_ref_count = 0; 134 135 snprintf(name, sizeof(name), "%s consumer", device->name); 136 137 interface->reader_thread = -1; 138 interface->consumer_thread = spawn_kernel_thread(device_consumer_thread, 139 name, B_DISPLAY_PRIORITY, interface); 140 if (interface->consumer_thread < B_OK) 141 goto error_3; 142 resume_thread(interface->consumer_thread); 143 144 // TODO: proper interface index allocation 145 device->index = ++sDeviceIndex; 146 device->module = module; 147 148 sInterfaces.Add(interface); 149 return interface; 150 151 error_3: 152 uninit_fifo(&interface->receive_queue); 153 154 error_2: 155 recursive_lock_destroy(&interface->rx_lock); 156 delete interface; 157 158 error_0: 159 return NULL; 160 } 161 162 163 net_device_interface * 164 grab_device_interface(net_device_interface *interface) 165 { 166 if (interface == NULL || atomic_add(&interface->ref_count, 1) == 0) 167 return NULL; 168 169 return interface; 170 } 171 172 173 static void 174 notify_device_monitors(net_device_interface *interface, int32 event) 175 { 176 DeviceMonitorList::Iterator iterator = interface->monitor_funcs.GetIterator(); 177 while (iterator.HasNext()) { 178 // when we call Next() the next item in the list is obtained 179 // so it's safe for the "current" item to remove itself. 180 net_device_monitor *monitor = iterator.Next(); 181 182 monitor->event(monitor, event); 183 } 184 } 185 186 187 // #pragma mark - interfaces 188 189 190 /*! 191 Searches for a specific interface in a domain by name. 192 You need to have the domain's lock hold when calling this function. 193 */ 194 struct net_interface_private * 195 find_interface(struct net_domain *domain, const char *name) 196 { 197 net_interface_private *interface = NULL; 198 199 while (true) { 200 interface = (net_interface_private *)list_get_next_item( 201 &domain->interfaces, interface); 202 if (interface == NULL) 203 break; 204 205 if (!strcmp(interface->name, name)) 206 return interface; 207 } 208 209 return NULL; 210 } 211 212 213 /*! 214 Searches for a specific interface in a domain by index. 215 You need to have the domain's lock hold when calling this function. 216 */ 217 struct net_interface_private * 218 find_interface(struct net_domain *domain, uint32 index) 219 { 220 net_interface_private *interface = NULL; 221 222 while (true) { 223 interface = (net_interface_private *)list_get_next_item( 224 &domain->interfaces, interface); 225 if (interface == NULL) 226 break; 227 228 if (interface->index == index) 229 return interface; 230 } 231 232 return NULL; 233 } 234 235 236 status_t 237 create_interface(net_domain *domain, const char *name, const char *baseName, 238 net_device_interface *deviceInterface, net_interface_private **_interface) 239 { 240 net_interface_private *interface = 241 new (std::nothrow) net_interface_private; 242 if (interface == NULL) 243 return B_NO_MEMORY; 244 245 strlcpy(interface->name, name, IF_NAMESIZE); 246 strlcpy(interface->base_name, baseName, IF_NAMESIZE); 247 interface->domain = domain; 248 interface->device = deviceInterface->device; 249 250 interface->address = NULL; 251 interface->destination = NULL; 252 interface->mask = NULL; 253 254 interface->index = ++sInterfaceIndex; 255 interface->flags = 0; 256 interface->type = 0; 257 interface->mtu = deviceInterface->device->mtu; 258 interface->metric = 0; 259 interface->device_interface = grab_device_interface(deviceInterface); 260 261 status_t status = get_domain_datalink_protocols(interface); 262 if (status < B_OK) { 263 delete interface; 264 return status; 265 } 266 267 // Grab a reference to the networking stack, to make sure it won't be 268 // unloaded as long as an interface exists 269 module_info *module; 270 get_module(gNetStackInterfaceModule.info.name, &module); 271 272 *_interface = interface; 273 return B_OK; 274 } 275 276 277 void 278 interface_set_down(net_interface *interface) 279 { 280 if ((interface->flags & IFF_UP) == 0) 281 return; 282 283 interface->flags &= ~IFF_UP; 284 interface->first_info->interface_down(interface->first_protocol); 285 } 286 287 288 void 289 delete_interface(net_interface_private *interface) 290 { 291 // deleting an interface is fairly complex as we need 292 // to clear all references to it throughout the stack 293 294 // this will possibly call (if IFF_UP): 295 // interface_protocol_down() 296 // domain_interface_went_down() 297 // invalidate_routes() 298 // remove_route() 299 // update_route_infos() 300 // get_route_internal() 301 // down_device_interface() -- if upcount reaches 0 302 interface_set_down(interface); 303 304 // This call requires the RX Lock to be a recursive 305 // lock since each uninit_protocol() call may call 306 // again into the stack to unregister a reader for 307 // instance, which tries to obtain the RX lock again. 308 put_domain_datalink_protocols(interface); 309 310 put_device_interface(interface->device_interface); 311 312 free(interface->address); 313 free(interface->destination); 314 free(interface->mask); 315 316 delete interface; 317 318 // Release reference of the stack - at this point, our stack may be unloaded 319 // if no other interfaces or sockets are left 320 put_module(gNetStackInterfaceModule.info.name); 321 } 322 323 324 void 325 put_interface(struct net_interface_private *interface) 326 { 327 // TODO: reference counting 328 // TODO: better locking scheme 329 mutex_unlock(&((net_domain_private *)interface->domain)->lock); 330 } 331 332 333 struct net_interface_private * 334 get_interface(net_domain *_domain, const char *name) 335 { 336 net_domain_private *domain = (net_domain_private *)_domain; 337 mutex_lock(&domain->lock); 338 339 net_interface_private *interface = NULL; 340 while (true) { 341 interface = (net_interface_private *)list_get_next_item( 342 &domain->interfaces, interface); 343 if (interface == NULL) 344 break; 345 346 if (!strcmp(interface->name, name)) 347 return interface; 348 } 349 350 mutex_unlock(&domain->lock); 351 return NULL; 352 } 353 354 355 // #pragma mark - device interfaces 356 357 358 void 359 get_device_interface_address(net_device_interface *interface, sockaddr *_address) 360 { 361 sockaddr_dl &address = *(sockaddr_dl *)_address; 362 363 address.sdl_family = AF_LINK; 364 address.sdl_index = interface->device->index; 365 address.sdl_type = interface->device->type; 366 address.sdl_nlen = strlen(interface->device->name); 367 address.sdl_slen = 0; 368 memcpy(address.sdl_data, interface->device->name, address.sdl_nlen); 369 370 address.sdl_alen = interface->device->address.length; 371 memcpy(LLADDR(&address), interface->device->address.data, address.sdl_alen); 372 373 address.sdl_len = sizeof(sockaddr_dl) - sizeof(address.sdl_data) 374 + address.sdl_nlen + address.sdl_alen; 375 } 376 377 378 uint32 379 count_device_interfaces() 380 { 381 MutexLocker locker(sInterfaceLock); 382 383 DeviceInterfaceList::Iterator iterator = sInterfaces.GetIterator(); 384 uint32 count = 0; 385 386 while (iterator.HasNext()) { 387 iterator.Next(); 388 count++; 389 } 390 391 return count; 392 } 393 394 395 /*! 396 Dumps a list of all interfaces into the supplied userland buffer. 397 If the interfaces don't fit into the buffer, an error (\c ENOBUFS) is 398 returned. 399 */ 400 status_t 401 list_device_interfaces(void *_buffer, size_t *bufferSize) 402 { 403 MutexLocker locker(sInterfaceLock); 404 405 DeviceInterfaceList::Iterator iterator = sInterfaces.GetIterator(); 406 UserBuffer buffer(_buffer, *bufferSize); 407 408 while (iterator.HasNext()) { 409 net_device_interface *interface = iterator.Next(); 410 411 ifreq request; 412 strlcpy(request.ifr_name, interface->device->name, IF_NAMESIZE); 413 get_device_interface_address(interface, &request.ifr_addr); 414 415 if (buffer.Copy(&request, IF_NAMESIZE 416 + request.ifr_addr.sa_len) == NULL) 417 return buffer.Status(); 418 } 419 420 *bufferSize = buffer.ConsumedAmount(); 421 return B_OK; 422 } 423 424 425 /*! 426 Releases the reference for the interface. When all references are 427 released, the interface is removed. 428 */ 429 void 430 put_device_interface(struct net_device_interface *interface) 431 { 432 if (atomic_add(&interface->ref_count, -1) != 1) 433 return; 434 435 { 436 MutexLocker locker(sInterfaceLock); 437 sInterfaces.Remove(interface); 438 } 439 440 uninit_fifo(&interface->receive_queue); 441 status_t status; 442 wait_for_thread(interface->consumer_thread, &status); 443 444 net_device *device = interface->device; 445 device->module->uninit_device(device); 446 put_module(device->module->info.name); 447 448 recursive_lock_destroy(&interface->rx_lock); 449 delete interface; 450 } 451 452 453 /*! 454 Finds an interface by the specified index and grabs a reference to it. 455 */ 456 struct net_device_interface * 457 get_device_interface(uint32 index) 458 { 459 MutexLocker locker(sInterfaceLock); 460 DeviceInterfaceList::Iterator iterator = sInterfaces.GetIterator(); 461 462 while (iterator.HasNext()) { 463 net_device_interface *interface = iterator.Next(); 464 465 if (interface->device->index == index) { 466 if (atomic_add(&interface->ref_count, 1) != 0) 467 return interface; 468 } 469 } 470 471 return NULL; 472 } 473 474 475 /*! 476 Finds an interface by the specified name and grabs a reference to it. 477 If the interface does not yet exist, a new one is created. 478 */ 479 struct net_device_interface * 480 get_device_interface(const char *name, bool create) 481 { 482 MutexLocker locker(sInterfaceLock); 483 484 net_device_interface *interface = find_device_interface(name); 485 if (interface != NULL) { 486 if (atomic_add(&interface->ref_count, 1) != 0) 487 return interface; 488 489 // try to recreate interface - it just got removed 490 } 491 492 if (!create) 493 return NULL; 494 495 void *cookie = open_module_list("network/devices"); 496 if (cookie == NULL) 497 return NULL; 498 499 while (true) { 500 char moduleName[B_FILE_NAME_LENGTH]; 501 size_t length = sizeof(moduleName); 502 if (read_next_module_name(cookie, moduleName, &length) != B_OK) 503 break; 504 505 TRACE(("get_device_interface: ask \"%s\" for %s\n", moduleName, name)); 506 507 net_device_module_info *module; 508 if (get_module(moduleName, (module_info **)&module) == B_OK) { 509 net_device *device; 510 status_t status = module->init_device(name, &device); 511 if (status == B_OK) { 512 interface = allocate_device_interface(device, module); 513 if (interface) 514 return interface; 515 module->uninit_device(device); 516 } 517 put_module(moduleName); 518 } 519 } 520 521 return NULL; 522 } 523 524 525 void 526 down_device_interface(net_device_interface *interface) 527 { 528 // RX lock must be held when calling down_device_interface. 529 // Known callers are `interface_protocol_down' which gets 530 // here via one of the following paths: 531 // 532 // - domain_interface_control() [rx lock held, domain lock held] 533 // interface_set_down() 534 // interface_protocol_down() 535 // 536 // - domain_interface_control() [rx lock held, domain lock held] 537 // remove_interface_from_domain() 538 // delete_interface() 539 // interface_set_down() 540 541 net_device *device = interface->device; 542 543 device->flags &= ~IFF_UP; 544 device->module->down(device); 545 546 notify_device_monitors(interface, B_DEVICE_GOING_DOWN); 547 548 if (device->module->receive_data != NULL) { 549 thread_id reader_thread = interface->reader_thread; 550 551 // TODO when setting the interface down, 552 // should we clear the receive queue? 553 554 // one of the callers must hold a reference to the net_device_interface 555 // usually it is one of the net_interfaces. 556 recursive_lock_unlock(&interface->rx_lock); 557 558 // make sure the reader thread is gone before shutting down the interface 559 status_t status; 560 wait_for_thread(reader_thread, &status); 561 562 recursive_lock_lock(&interface->rx_lock); 563 } 564 } 565 566 567 // #pragma mark - devices 568 569 570 /*! 571 Unregisters a previously registered deframer function. 572 This function is part of the net_manager_module_info API. 573 */ 574 status_t 575 unregister_device_deframer(net_device *device) 576 { 577 MutexLocker locker(sInterfaceLock); 578 579 // find device interface for this device 580 net_device_interface *interface = find_device_interface(device->name); 581 if (interface == NULL) 582 return ENODEV; 583 584 RecursiveLocker _(interface->rx_lock); 585 586 if (--interface->deframe_ref_count == 0) 587 interface->deframe_func = NULL; 588 589 return B_OK; 590 } 591 592 593 /*! 594 Registers the deframer function for the specified \a device. 595 Note, however, that right now, you can only register one single 596 deframer function per device. 597 598 If the need arises, we might want to lift that limitation at a 599 later time (which would require a slight API change, though). 600 601 This function is part of the net_manager_module_info API. 602 */ 603 status_t 604 register_device_deframer(net_device *device, net_deframe_func deframeFunc) 605 { 606 MutexLocker locker(sInterfaceLock); 607 608 // find device interface for this device 609 net_device_interface *interface = find_device_interface(device->name); 610 if (interface == NULL) 611 return ENODEV; 612 613 RecursiveLocker _(interface->rx_lock); 614 615 if (interface->deframe_func != NULL && interface->deframe_func != deframeFunc) 616 return B_ERROR; 617 618 interface->deframe_func = deframeFunc; 619 interface->deframe_ref_count++; 620 return B_OK; 621 } 622 623 624 status_t 625 register_domain_device_handler(struct net_device *device, int32 type, 626 struct net_domain *_domain) 627 { 628 net_domain_private *domain = (net_domain_private *)_domain; 629 if (domain->module == NULL || domain->module->receive_data == NULL) 630 return B_BAD_VALUE; 631 632 return register_device_handler(device, type, &domain_receive_adapter, domain); 633 } 634 635 636 status_t 637 register_device_handler(struct net_device *device, int32 type, 638 net_receive_func receiveFunc, void *cookie) 639 { 640 MutexLocker locker(sInterfaceLock); 641 642 // find device interface for this device 643 net_device_interface *interface = find_device_interface(device->name); 644 if (interface == NULL) 645 return ENODEV; 646 647 RecursiveLocker _(interface->rx_lock); 648 649 // see if such a handler already for this device 650 651 DeviceHandlerList::Iterator iterator = interface->receive_funcs.GetIterator(); 652 while (iterator.HasNext()) { 653 net_device_handler *handler = iterator.Next(); 654 655 if (handler->type == type) 656 return B_ERROR; 657 } 658 659 // Add new handler 660 661 net_device_handler *handler = new (std::nothrow) net_device_handler; 662 if (handler == NULL) 663 return B_NO_MEMORY; 664 665 handler->func = receiveFunc; 666 handler->type = type; 667 handler->cookie = cookie; 668 interface->receive_funcs.Add(handler); 669 return B_OK; 670 } 671 672 673 status_t 674 unregister_device_handler(struct net_device *device, int32 type) 675 { 676 MutexLocker locker(sInterfaceLock); 677 678 // find device interface for this device 679 net_device_interface *interface = find_device_interface(device->name); 680 if (interface == NULL) 681 return ENODEV; 682 683 RecursiveLocker _(interface->rx_lock); 684 685 // search for the handler 686 687 DeviceHandlerList::Iterator iterator = interface->receive_funcs.GetIterator(); 688 while (iterator.HasNext()) { 689 net_device_handler *handler = iterator.Next(); 690 691 if (handler->type == type) { 692 // found it 693 iterator.Remove(); 694 delete handler; 695 return B_OK; 696 } 697 } 698 699 return B_BAD_VALUE; 700 } 701 702 703 status_t 704 register_device_monitor(net_device *device, net_device_monitor *monitor) 705 { 706 if (monitor->receive == NULL || monitor->event == NULL) 707 return B_BAD_VALUE; 708 709 MutexLocker locker(sInterfaceLock); 710 711 // find device interface for this device 712 net_device_interface *interface = find_device_interface(device->name); 713 if (interface == NULL) 714 return ENODEV; 715 716 RecursiveLocker _(interface->rx_lock); 717 interface->monitor_funcs.Add(monitor); 718 return B_OK; 719 } 720 721 722 status_t 723 unregister_device_monitor(net_device *device, net_device_monitor *monitor) 724 { 725 MutexLocker locker(sInterfaceLock); 726 727 // find device interface for this device 728 net_device_interface *interface = find_device_interface(device->name); 729 if (interface == NULL) 730 return ENODEV; 731 732 RecursiveLocker _(interface->rx_lock); 733 734 // search for the monitor 735 736 DeviceMonitorList::Iterator iterator = interface->monitor_funcs.GetIterator(); 737 while (iterator.HasNext()) { 738 if (iterator.Next() == monitor) { 739 iterator.Remove(); 740 return B_OK; 741 } 742 } 743 744 return B_BAD_VALUE; 745 } 746 747 748 /*! 749 This function is called by device modules in case their link 750 state changed, ie. if an ethernet cable was plugged in or 751 removed. 752 */ 753 status_t 754 device_link_changed(net_device *device) 755 { 756 return B_OK; 757 } 758 759 760 /*! 761 This function is called by device modules once their device got 762 physically removed, ie. a USB networking card is unplugged. 763 It is part of the net_manager_module_info API. 764 */ 765 status_t 766 device_removed(net_device *device) 767 { 768 MutexLocker locker(sInterfaceLock); 769 770 // hold a reference to the device interface being removed 771 // so our put_() will (eventually) do the final cleanup 772 net_device_interface *interface = get_device_interface(device->name, false); 773 if (interface == NULL) 774 return ENODEV; 775 776 // Propagate the loss of the device throughout the stack. 777 // This is very complex, refer to delete_interface() for 778 // further details. 779 780 RecursiveLocker _(interface->rx_lock); 781 782 // this will possibly call: 783 // remove_interface_from_domain() [domain gets locked] 784 // delete_interface() 785 // ... [see delete_interface()] 786 domain_removed_device_interface(interface); 787 788 notify_device_monitors(interface, B_DEVICE_BEING_REMOVED); 789 790 // By now all of the monitors must have removed themselves. If they 791 // didn't, they'll probably wait forever to be callback'ed again. 792 interface->monitor_funcs.RemoveAll(); 793 794 // All of the readers should be gone as well since we are out of 795 // interfaces and `put_domain_datalink_protocols' is called for 796 // each delete_interface(). 797 798 put_device_interface(interface); 799 800 return B_OK; 801 } 802 803 804 status_t 805 device_enqueue_buffer(net_device *device, net_buffer *buffer) 806 { 807 net_device_interface *interface = get_device_interface(device->index); 808 809 if (interface == NULL) 810 return ENODEV; 811 812 status_t status = fifo_enqueue_buffer(&interface->receive_queue, buffer); 813 814 put_device_interface(interface); 815 return status; 816 } 817 818 819 // #pragma mark - 820 821 822 status_t 823 init_interfaces() 824 { 825 mutex_init(&sInterfaceLock, "net interfaces"); 826 827 new (&sInterfaces) DeviceInterfaceList; 828 // static C++ objects are not initialized in the module startup 829 return B_OK; 830 } 831 832 833 status_t 834 uninit_interfaces() 835 { 836 mutex_destroy(&sInterfaceLock); 837 return B_OK; 838 } 839 840