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