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