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