1 /* 2 * Copyright 2006, 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 14 #include <net_device.h> 15 16 #include <lock.h> 17 #include <util/AutoLock.h> 18 19 #include <KernelExport.h> 20 21 #include <net/if_dl.h> 22 #include <new> 23 #include <stdlib.h> 24 #include <string.h> 25 26 27 #define TRACE_INTERFACES 28 #ifdef TRACE_INTERFACES 29 # define TRACE(x) dprintf x 30 #else 31 # define TRACE(x) ; 32 #endif 33 34 35 static benaphore sInterfaceLock; 36 static list sInterfaces; 37 static uint32 sInterfaceIndex; 38 static uint32 sDeviceIndex; 39 40 41 static net_device_interface * 42 find_device_interface(const char *name) 43 { 44 net_device_interface *interface = NULL; 45 46 while (true) { 47 interface = (net_device_interface *)list_get_next_item(&sInterfaces, interface); 48 if (interface == NULL) 49 break; 50 51 if (!strcmp(interface->name, name)) 52 return interface; 53 } 54 55 return NULL; 56 } 57 58 59 static status_t 60 domain_receive_adapter(void *cookie, net_buffer *buffer) 61 { 62 net_domain_private *domain = (net_domain_private *)cookie; 63 return domain->module->receive_data(buffer); 64 } 65 66 67 // #pragma mark - interfaces 68 69 70 /*! 71 Searches for a specific interface in a domain by name. 72 You need to have the domain's lock hold when calling this function. 73 */ 74 struct net_interface_private * 75 find_interface(struct net_domain *domain, const char *name) 76 { 77 net_interface_private *interface = NULL; 78 79 while (true) { 80 interface = (net_interface_private *)list_get_next_item( 81 &domain->interfaces, interface); 82 if (interface == NULL) 83 break; 84 85 if (!strcmp(interface->name, name)) 86 return interface; 87 } 88 89 return NULL; 90 } 91 92 93 /*! 94 Searches for a specific interface in a domain by index. 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, uint32 index) 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 (interface->index == index) 109 return interface; 110 } 111 112 return NULL; 113 } 114 115 116 status_t 117 create_interface(net_domain *domain, const char *name, const char *baseName, 118 net_device_interface *deviceInterface, net_interface_private **_interface) 119 { 120 net_interface_private *interface = 121 new (std::nothrow) net_interface_private; 122 if (interface == NULL) 123 return B_NO_MEMORY; 124 125 strlcpy(interface->name, name, IF_NAMESIZE); 126 strlcpy(interface->base_name, baseName, IF_NAMESIZE); 127 interface->domain = domain; 128 interface->device = deviceInterface->device; 129 130 interface->address = NULL; 131 interface->destination = NULL; 132 interface->mask = NULL; 133 134 interface->index = ++sInterfaceIndex; 135 interface->flags = deviceInterface->device->flags & ~IFF_UP; 136 interface->type = 0; 137 interface->mtu = deviceInterface->device->mtu; 138 interface->metric = 0; 139 interface->device_interface = deviceInterface; 140 141 status_t status = get_domain_datalink_protocols(interface); 142 if (status < B_OK) { 143 delete interface; 144 return status; 145 } 146 147 // Grab a reference to the networking stack, to make sure it won't be 148 // unloaded as long as an interface exists 149 module_info *module; 150 get_module(NET_STARTER_MODULE_NAME, &module); 151 152 *_interface = interface; 153 return B_OK; 154 } 155 156 157 void 158 delete_interface(net_interface_private *interface) 159 { 160 put_device_interface(interface->device_interface); 161 162 free(interface->address); 163 free(interface->destination); 164 free(interface->mask); 165 166 delete interface; 167 168 // Release reference of the stack - at this point, our stack may be unloaded 169 // if no other interfaces or sockets are left 170 put_module(NET_STARTER_MODULE_NAME); 171 } 172 173 174 void 175 put_interface(struct net_interface_private *interface) 176 { 177 // TODO: reference counting 178 // TODO: better locking scheme 179 benaphore_unlock(&((net_domain_private *)interface->domain)->lock); 180 } 181 182 183 struct net_interface_private * 184 get_interface(net_domain *_domain, const char *name) 185 { 186 net_domain_private *domain = (net_domain_private *)_domain; 187 benaphore_lock(&domain->lock); 188 189 net_interface_private *interface = NULL; 190 while (true) { 191 interface = (net_interface_private *)list_get_next_item( 192 &domain->interfaces, interface); 193 if (interface == NULL) 194 break; 195 196 if (!strcmp(interface->name, name)) 197 return interface; 198 } 199 200 benaphore_unlock(&domain->lock); 201 return NULL; 202 } 203 204 205 // #pragma mark - device interfaces 206 207 208 void 209 get_device_interface_address(net_device_interface *interface, sockaddr *_address) 210 { 211 sockaddr_dl &address = *(sockaddr_dl *)_address; 212 213 address.sdl_family = AF_LINK; 214 address.sdl_index = interface->device->index; 215 address.sdl_type = interface->device->type; 216 address.sdl_nlen = strlen(interface->name); 217 address.sdl_slen = 0; 218 memcpy(address.sdl_data, interface->name, address.sdl_nlen); 219 220 address.sdl_alen = interface->device->address.length; 221 memcpy(LLADDR(&address), interface->device->address.data, address.sdl_alen); 222 223 address.sdl_len = sizeof(sockaddr_dl) - sizeof(address.sdl_data) 224 + address.sdl_nlen + address.sdl_alen; 225 } 226 227 228 uint32 229 count_device_interfaces() 230 { 231 BenaphoreLocker locker(sInterfaceLock); 232 233 net_device_interface *interface = NULL; 234 uint32 count = 0; 235 236 while (true) { 237 interface = (net_device_interface *)list_get_next_item(&sInterfaces, 238 interface); 239 if (interface == NULL) 240 break; 241 242 count++; 243 } 244 245 return count; 246 } 247 248 249 /*! 250 Dumps a list of all interfaces into the supplied userland buffer. 251 If the interfaces don't fit into the buffer, an error (\c ENOBUFS) is 252 returned. 253 */ 254 status_t 255 list_device_interfaces(void *buffer, size_t size) 256 { 257 BenaphoreLocker locker(sInterfaceLock); 258 259 net_device_interface *interface = NULL; 260 size_t spaceLeft = size; 261 262 while (true) { 263 interface = (net_device_interface *)list_get_next_item(&sInterfaces, 264 interface); 265 if (interface == NULL) 266 break; 267 268 ifreq request; 269 strlcpy(request.ifr_name, interface->name, IF_NAMESIZE); 270 get_device_interface_address(interface, &request.ifr_addr); 271 272 size = IF_NAMESIZE + request.ifr_addr.sa_len; 273 if (spaceLeft < size) 274 return ENOBUFS; 275 276 if (user_memcpy(buffer, &request, size) < B_OK) 277 return B_BAD_ADDRESS; 278 279 buffer = (void *)((addr_t)buffer + size); 280 spaceLeft -= size; 281 } 282 283 return B_OK; 284 } 285 286 287 /*! 288 Releases the reference for the interface. When all references are 289 released, the interface is removed. 290 */ 291 void 292 put_device_interface(struct net_device_interface *interface) 293 { 294 if (atomic_add(&interface->ref_count, -1) != 1) 295 return; 296 297 // we need to remove this interface! 298 299 { 300 BenaphoreLocker locker(sInterfaceLock); 301 list_remove_item(&sInterfaces, interface); 302 } 303 304 interface->module->uninit_device(interface->device); 305 put_module(interface->module->info.name); 306 } 307 308 309 /*! 310 Finds an interface by the specified index and grabs a reference to it. 311 */ 312 struct net_device_interface * 313 get_device_interface(uint32 index) 314 { 315 BenaphoreLocker locker(sInterfaceLock); 316 net_device_interface *interface = NULL; 317 318 while (true) { 319 interface = (net_device_interface *)list_get_next_item(&sInterfaces, interface); 320 if (interface == NULL) 321 break; 322 323 if (interface->device->index == index) { 324 if (atomic_add(&interface->ref_count, 1) != 0) 325 return interface; 326 } 327 } 328 329 return NULL; 330 } 331 332 333 /*! 334 Finds an interface by the specified name and grabs a reference to it. 335 If the interface does not yet exist, a new one is created. 336 */ 337 struct net_device_interface * 338 get_device_interface(const char *name) 339 { 340 BenaphoreLocker locker(sInterfaceLock); 341 342 net_device_interface *interface = find_device_interface(name); 343 if (interface != NULL) { 344 if (atomic_add(&interface->ref_count, 1) != 0) 345 return interface; 346 347 // try to recreate interface - it just got removed 348 } 349 350 void *cookie = open_module_list("network/devices"); 351 if (cookie == NULL) 352 return NULL; 353 354 while (true) { 355 char moduleName[B_FILE_NAME_LENGTH]; 356 size_t length = sizeof(moduleName); 357 if (read_next_module_name(cookie, moduleName, &length) != B_OK) 358 break; 359 360 TRACE(("get_device_interface: ask \"%s\" for %s\n", moduleName, name)); 361 362 net_device_module_info *module; 363 if (get_module(moduleName, (module_info **)&module) == B_OK) { 364 net_device *device; 365 status_t status = module->init_device(name, &device); 366 if (status == B_OK) { 367 // create new module interface for this 368 interface = new (std::nothrow) net_device_interface; 369 if (interface != NULL) { 370 interface->name = device->name; 371 interface->module = module; 372 interface->device = device; 373 interface->up_count = 0; 374 interface->ref_count = 1; 375 interface->deframe_func = NULL; 376 interface->deframe_ref_count = 0; 377 378 device->index = ++sDeviceIndex; 379 device->module = module; 380 381 list_add_item(&sInterfaces, interface); 382 return interface; 383 } else 384 module->uninit_device(device); 385 } 386 387 put_module(moduleName); 388 } 389 } 390 391 return NULL; 392 } 393 394 395 // #pragma mark - devices 396 397 398 /*! 399 Unregisters a previously registered deframer function. 400 This function is part of the net_manager_module_info API. 401 */ 402 status_t 403 unregister_device_deframer(net_device *device) 404 { 405 BenaphoreLocker locker(sInterfaceLock); 406 407 // find device interface for this device 408 net_device_interface *interface = find_device_interface(device->name); 409 if (interface == NULL) 410 return ENODEV; 411 412 if (--interface->deframe_ref_count == 0) 413 interface->deframe_func = NULL; 414 415 return B_OK; 416 } 417 418 419 /*! 420 Registers the deframer function for the specified \a device. 421 Note, however, that right now, you can only register one single 422 deframer function per device. 423 424 If the need arises, we might want to lift that limitation at a 425 later time (which would require a slight API change, though). 426 427 This function is part of the net_manager_module_info API. 428 */ 429 status_t 430 register_device_deframer(net_device *device, net_deframe_func deframeFunc) 431 { 432 BenaphoreLocker locker(sInterfaceLock); 433 434 // find device interface for this device 435 net_device_interface *interface = find_device_interface(device->name); 436 if (interface == NULL) 437 return ENODEV; 438 439 if (interface->deframe_func != NULL && interface->deframe_func != deframeFunc) 440 return B_ERROR; 441 442 interface->deframe_func = deframeFunc; 443 interface->deframe_ref_count++; 444 return B_OK; 445 } 446 447 448 status_t 449 register_domain_device_handler(struct net_device *device, int32 type, 450 struct net_domain *_domain) 451 { 452 net_domain_private *domain = (net_domain_private *)_domain; 453 if (domain->module == NULL || domain->module->receive_data == NULL) 454 return B_BAD_VALUE; 455 456 return register_device_handler(device, type, &domain_receive_adapter, domain); 457 } 458 459 460 status_t 461 register_device_handler(struct net_device *device, int32 type, 462 net_receive_func receiveFunc, void *cookie) 463 { 464 BenaphoreLocker locker(sInterfaceLock); 465 466 // find device interface for this device 467 net_device_interface *interface = find_device_interface(device->name); 468 if (interface == NULL) 469 return ENODEV; 470 471 // see if such a handler already for this device 472 473 DeviceHandlerList::Iterator iterator = interface->receive_funcs.GetIterator(); 474 while (iterator.HasNext()) { 475 net_device_handler *handler = iterator.Next(); 476 477 if (handler->type == type) 478 return B_ERROR; 479 } 480 481 // Add new handler 482 483 net_device_handler *handler = new (std::nothrow) net_device_handler; 484 if (handler == NULL) 485 return B_NO_MEMORY; 486 487 handler->func = receiveFunc; 488 handler->type = type; 489 handler->cookie = cookie; 490 interface->receive_funcs.Add(handler); 491 return B_OK; 492 } 493 494 495 status_t 496 unregister_device_handler(struct net_device *device, int32 type) 497 { 498 BenaphoreLocker locker(sInterfaceLock); 499 500 // find device interface for this device 501 net_device_interface *interface = find_device_interface(device->name); 502 if (interface == NULL) 503 return ENODEV; 504 505 // search for the handler 506 507 DeviceHandlerList::Iterator iterator = interface->receive_funcs.GetIterator(); 508 while (iterator.HasNext()) { 509 net_device_handler *handler = iterator.Next(); 510 511 if (handler->type == type) { 512 // found it 513 iterator.Remove(); 514 delete handler; 515 return B_OK; 516 } 517 } 518 519 return B_BAD_VALUE; 520 } 521 522 523 status_t 524 register_device_monitor(struct net_device *device, 525 net_receive_func receiveFunc, void *cookie) 526 { 527 BenaphoreLocker locker(sInterfaceLock); 528 529 // find device interface for this device 530 net_device_interface *interface = find_device_interface(device->name); 531 if (interface == NULL) 532 return ENODEV; 533 534 // Add new monitor 535 536 net_device_monitor *monitor = new (std::nothrow) net_device_monitor; 537 if (monitor == NULL) 538 return B_NO_MEMORY; 539 540 monitor->func = receiveFunc; 541 monitor->cookie = cookie; 542 interface->monitor_funcs.Add(monitor); 543 return B_OK; 544 } 545 546 547 status_t 548 unregister_device_monitor(struct net_device *device, 549 net_receive_func receiveFunc, void *cookie) 550 { 551 BenaphoreLocker locker(sInterfaceLock); 552 553 // find device interface for this device 554 net_device_interface *interface = find_device_interface(device->name); 555 if (interface == NULL) 556 return ENODEV; 557 558 // search for the monitor 559 560 DeviceMonitorList::Iterator iterator = interface->monitor_funcs.GetIterator(); 561 while (iterator.HasNext()) { 562 net_device_monitor *monitor = iterator.Next(); 563 564 if (monitor->cookie == cookie && monitor->func == receiveFunc) { 565 // found it 566 iterator.Remove(); 567 delete monitor; 568 return B_OK; 569 } 570 } 571 572 return B_BAD_VALUE; 573 } 574 575 576 /*! 577 This function is called by device modules once their device got 578 physically removed, ie. a USB networking card is unplugged. 579 It is part of the net_manager_module_info API. 580 */ 581 status_t 582 device_removed(net_device *device) 583 { 584 BenaphoreLocker locker(sInterfaceLock); 585 // TODO: all what this function should do is to clear the IFF_UP flag of the interfaces. 586 return B_OK; 587 } 588 589 590 // #pragma mark - 591 592 593 status_t 594 init_interfaces() 595 { 596 if (benaphore_init(&sInterfaceLock, "net interfaces") < B_OK) 597 return B_ERROR; 598 599 list_init(&sInterfaces); 600 return B_OK; 601 } 602 603 604 status_t 605 uninit_interfaces() 606 { 607 benaphore_destroy(&sInterfaceLock); 608 return B_OK; 609 } 610 611