BPicture: Fix archive constructor.
[haiku.git] / src / add-ons / kernel / network / stack / device_interfaces.cpp
blob01433602fab546863b7950b69317a6c2f356c5d8
1 /*
2 * Copyright 2006-2010, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Axel Dörfler, axeld@pinc-software.de
7 */
10 #include "device_interfaces.h"
11 #include "domains.h"
12 #include "interfaces.h"
13 #include "stack_private.h"
14 #include "utility.h"
16 #include <net_device.h>
18 #include <lock.h>
19 #include <util/AutoLock.h>
21 #include <KernelExport.h>
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>
31 //#define TRACE_DEVICE_INTERFACES
32 #ifdef TRACE_DEVICE_INTERFACES
33 # define TRACE(x) dprintf x
34 #else
35 # define TRACE(x) ;
36 #endif
39 static mutex sLock;
40 static DeviceInterfaceList sInterfaces;
41 static uint32 sDeviceIndex;
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.
48 static status_t
49 device_reader_thread(void* _interface)
51 net_device_interface* interface = (net_device_interface*)_interface;
52 net_device* device = interface->device;
53 status_t status = B_OK;
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);
63 ASSERT(buffer->interface_address == NULL);
65 if (interface->deframe_func(interface->device, buffer) != B_OK) {
66 gNetBufferModule.free(buffer);
67 continue;
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);
80 return status;
84 static status_t
85 device_consumer_thread(void* _interface)
87 net_device_interface* interface = (net_device_interface*)_interface;
88 net_device* device = interface->device;
89 net_buffer* buffer;
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;
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));
112 buffer->index = interface->device->index;
114 // Find handler for this packet
116 RecursiveLocker locker(interface->receive_lock);
118 DeviceHandlerList::Iterator iterator
119 = interface->receive_funcs.GetIterator();
120 while (buffer != NULL && iterator.HasNext()) {
121 net_device_handler* handler = iterator.Next();
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;
132 if (buffer != NULL)
133 gNetBufferModule.free(buffer);
136 return B_OK;
140 /*! The domain's device receive handler - this will inject the net_buffers into
141 the protocol layer (the domain's registered receive handler).
143 static status_t
144 domain_receive_adapter(void* cookie, net_device* device, net_buffer* buffer)
146 net_domain_private* domain = (net_domain_private*)cookie;
148 return domain->module->receive_data(buffer);
152 static net_device_interface*
153 find_device_interface(const char* name)
155 DeviceInterfaceList::Iterator iterator = sInterfaces.GetIterator();
157 while (net_device_interface* interface = iterator.Next()) {
158 if (!strcmp(interface->device->name, name))
159 return interface;
162 return NULL;
166 static net_device_interface*
167 allocate_device_interface(net_device* device, net_device_module_info* module)
169 net_device_interface* interface = new(std::nothrow) net_device_interface;
170 if (interface == NULL)
171 return NULL;
173 recursive_lock_init(&interface->receive_lock, "device interface receive");
174 recursive_lock_init(&interface->monitor_lock, "device interface monitors");
176 char name[128];
177 snprintf(name, sizeof(name), "%s receive queue", device->name);
179 if (init_fifo(&interface->receive_queue, name, 16 * 1024 * 1024) < B_OK)
180 goto error1;
182 interface->device = device;
183 interface->up_count = 0;
184 interface->ref_count = 1;
185 interface->monitor_count = 0;
186 interface->deframe_func = NULL;
187 interface->deframe_ref_count = 0;
189 snprintf(name, sizeof(name), "%s consumer", device->name);
191 interface->reader_thread = -1;
192 interface->consumer_thread = spawn_kernel_thread(device_consumer_thread,
193 name, B_DISPLAY_PRIORITY, interface);
194 if (interface->consumer_thread < B_OK)
195 goto error2;
196 resume_thread(interface->consumer_thread);
198 // TODO: proper interface index allocation
199 device->index = ++sDeviceIndex;
200 device->module = module;
202 sInterfaces.Add(interface);
203 return interface;
205 error2:
206 uninit_fifo(&interface->receive_queue);
207 error1:
208 recursive_lock_destroy(&interface->receive_lock);
209 recursive_lock_destroy(&interface->monitor_lock);
210 delete interface;
212 return NULL;
216 static void
217 notify_device_monitors(net_device_interface* interface, int32 event)
219 RecursiveLocker locker(interface->monitor_lock);
221 DeviceMonitorList::Iterator iterator
222 = interface->monitor_funcs.GetIterator();
223 while (net_device_monitor* monitor = iterator.Next()) {
224 // it's safe for the "current" item to remove itself.
225 monitor->event(monitor, event);
230 #if ENABLE_DEBUGGER_COMMANDS
233 static int
234 dump_device_interface(int argc, char** argv)
236 if (argc != 2) {
237 kprintf("usage: %s [address]\n", argv[0]);
238 return 0;
241 net_device_interface* interface
242 = (net_device_interface*)parse_expression(argv[1]);
244 kprintf("device: %p\n", interface->device);
245 kprintf("reader_thread: %" B_PRId32 "\n", interface->reader_thread);
246 kprintf("up_count: %" B_PRIu32 "\n", interface->up_count);
247 kprintf("ref_count: %" B_PRId32 "\n", interface->ref_count);
248 kprintf("deframe_func: %p\n", interface->deframe_func);
249 kprintf("deframe_ref_count: %" B_PRId32 "\n", interface->ref_count);
250 kprintf("consumer_thread: %" B_PRId32 "\n", interface->consumer_thread);
252 kprintf("monitor_count: %" B_PRId32 "\n", interface->monitor_count);
253 kprintf("monitor_lock: %p\n", &interface->monitor_lock);
254 kprintf("monitor_funcs:\n");
255 DeviceMonitorList::Iterator monitorIterator
256 = interface->monitor_funcs.GetIterator();
257 while (monitorIterator.HasNext())
258 kprintf(" %p\n", monitorIterator.Next());
260 kprintf("receive_lock: %p\n", &interface->receive_lock);
261 kprintf("receive_queue: %p\n", &interface->receive_queue);
262 kprintf("receive_funcs:\n");
263 DeviceHandlerList::Iterator handlerIterator
264 = interface->receive_funcs.GetIterator();
265 while (handlerIterator.HasNext())
266 kprintf(" %p\n", handlerIterator.Next());
268 return 0;
272 static int
273 dump_device_interfaces(int argc, char** argv)
275 DeviceInterfaceList::Iterator iterator = sInterfaces.GetIterator();
276 while (net_device_interface* interface = iterator.Next()) {
277 kprintf(" %p %s\n", interface, interface->device->name);
280 return 0;
284 #endif // ENABLE_DEBUGGER_COMMANDS
287 // #pragma mark - device interfaces
290 net_device_interface*
291 acquire_device_interface(net_device_interface* interface)
293 if (interface == NULL || atomic_add(&interface->ref_count, 1) == 0)
294 return NULL;
296 return interface;
300 void
301 get_device_interface_address(net_device_interface* interface,
302 sockaddr* _address)
304 sockaddr_dl &address = *(sockaddr_dl*)_address;
306 address.sdl_family = AF_LINK;
307 address.sdl_index = interface->device->index;
308 address.sdl_type = interface->device->type;
309 address.sdl_nlen = strlen(interface->device->name);
310 address.sdl_slen = 0;
311 memcpy(address.sdl_data, interface->device->name, address.sdl_nlen);
313 address.sdl_alen = interface->device->address.length;
314 memcpy(LLADDR(&address), interface->device->address.data, address.sdl_alen);
316 address.sdl_len = sizeof(sockaddr_dl) - sizeof(address.sdl_data)
317 + address.sdl_nlen + address.sdl_alen;
321 uint32
322 count_device_interfaces()
324 MutexLocker locker(sLock);
326 DeviceInterfaceList::Iterator iterator = sInterfaces.GetIterator();
327 uint32 count = 0;
329 while (iterator.HasNext()) {
330 iterator.Next();
331 count++;
334 return count;
338 /*! Dumps a list of all interfaces into the supplied userland buffer.
339 If the interfaces don't fit into the buffer, an error (\c ENOBUFS) is
340 returned.
342 status_t
343 list_device_interfaces(void* _buffer, size_t* bufferSize)
345 MutexLocker locker(sLock);
347 DeviceInterfaceList::Iterator iterator = sInterfaces.GetIterator();
348 UserBuffer buffer(_buffer, *bufferSize);
350 while (net_device_interface* interface = iterator.Next()) {
351 buffer.Push(interface->device->name, IF_NAMESIZE);
353 sockaddr_storage address;
354 get_device_interface_address(interface, (sockaddr*)&address);
356 buffer.Push(&address, address.ss_len);
357 if (IF_NAMESIZE + address.ss_len < (int)sizeof(ifreq))
358 buffer.Pad(sizeof(ifreq) - IF_NAMESIZE - address.ss_len);
360 if (buffer.Status() != B_OK)
361 return buffer.Status();
364 *bufferSize = buffer.BytesConsumed();
365 return B_OK;
369 /*! Releases the reference for the interface. When all references are
370 released, the interface is removed.
372 void
373 put_device_interface(struct net_device_interface* interface)
375 if (interface == NULL)
376 return;
378 if (atomic_add(&interface->ref_count, -1) != 1)
379 return;
381 MutexLocker locker(sLock);
382 sInterfaces.Remove(interface);
383 locker.Unlock();
385 uninit_fifo(&interface->receive_queue);
386 status_t status;
387 wait_for_thread(interface->consumer_thread, &status);
389 net_device* device = interface->device;
390 const char* moduleName = device->module->info.name;
392 device->module->uninit_device(device);
393 put_module(moduleName);
395 recursive_lock_destroy(&interface->monitor_lock);
396 recursive_lock_destroy(&interface->receive_lock);
397 delete interface;
401 /*! Finds an interface by the specified index and acquires a reference to it.
403 struct net_device_interface*
404 get_device_interface(uint32 index)
406 MutexLocker locker(sLock);
408 // TODO: maintain an array of all device interfaces instead
409 DeviceInterfaceList::Iterator iterator = sInterfaces.GetIterator();
410 while (net_device_interface* interface = iterator.Next()) {
411 if (interface->device->index == index) {
412 if (atomic_add(&interface->ref_count, 1) != 0)
413 return interface;
417 return NULL;
421 /*! Finds an interface by the specified name and grabs a reference to it.
422 If the interface does not yet exist, a new one is created.
424 struct net_device_interface*
425 get_device_interface(const char* name, bool create)
427 MutexLocker locker(sLock);
429 net_device_interface* interface = find_device_interface(name);
430 if (interface != NULL) {
431 if (atomic_add(&interface->ref_count, 1) != 0)
432 return interface;
434 // try to recreate interface - it just got removed
437 if (!create)
438 return NULL;
440 void* cookie = open_module_list("network/devices");
441 if (cookie == NULL)
442 return NULL;
444 while (true) {
445 char moduleName[B_FILE_NAME_LENGTH];
446 size_t length = sizeof(moduleName);
447 if (read_next_module_name(cookie, moduleName, &length) != B_OK)
448 break;
450 TRACE(("get_device_interface: ask \"%s\" for %s\n", moduleName, name));
452 net_device_module_info* module;
453 if (get_module(moduleName, (module_info**)&module) == B_OK) {
454 net_device* device;
455 status_t status = module->init_device(name, &device);
456 if (status == B_OK) {
457 interface = allocate_device_interface(device, module);
458 if (interface != NULL)
459 return interface;
461 module->uninit_device(device);
463 put_module(moduleName);
467 close_module_list(cookie);
469 return NULL;
473 /*! Feeds the device monitors of the \a interface with the specified \a buffer.
474 You might want to check interface::monitor_count before calling this
475 function for optimization.
477 void
478 device_interface_monitor_receive(net_device_interface* interface,
479 net_buffer* buffer)
481 RecursiveLocker locker(interface->monitor_lock);
483 DeviceMonitorList::Iterator iterator
484 = interface->monitor_funcs.GetIterator();
485 while (iterator.HasNext()) {
486 net_device_monitor* monitor = iterator.Next();
487 monitor->receive(monitor, buffer);
492 status_t
493 up_device_interface(net_device_interface* interface)
495 net_device* device = interface->device;
497 RecursiveLocker locker(interface->receive_lock);
499 if (interface->up_count != 0) {
500 interface->up_count++;
501 return B_OK;
504 status_t status = device->module->up(device);
505 if (status != B_OK)
506 return status;
508 if (device->module->receive_data != NULL) {
509 // give the thread a nice name
510 char name[B_OS_NAME_LENGTH];
511 snprintf(name, sizeof(name), "%s reader", device->name);
513 interface->reader_thread = spawn_kernel_thread(device_reader_thread,
514 name, B_REAL_TIME_DISPLAY_PRIORITY - 10, interface);
515 if (interface->reader_thread < B_OK)
516 return interface->reader_thread;
519 device->flags |= IFF_UP;
521 if (device->module->receive_data != NULL)
522 resume_thread(interface->reader_thread);
524 interface->up_count = 1;
525 return B_OK;
529 void
530 down_device_interface(net_device_interface* interface)
532 // Receive lock must be held when calling down_device_interface.
533 // Known callers are `interface_protocol_down' which gets
534 // here via one of the following paths:
536 // - domain_interface_control() [rx lock held, domain lock held]
537 // interface_set_down()
538 // interface_protocol_down()
540 // - domain_interface_control() [rx lock held, domain lock held]
541 // remove_interface_from_domain()
542 // delete_interface()
543 // interface_set_down()
545 net_device* device = interface->device;
547 device->flags &= ~IFF_UP;
548 device->module->down(device);
550 notify_device_monitors(interface, B_DEVICE_GOING_DOWN);
552 if (device->module->receive_data != NULL) {
553 thread_id readerThread = interface->reader_thread;
555 // make sure the reader thread is gone before shutting down the interface
556 status_t status;
557 wait_for_thread(readerThread, &status);
562 // #pragma mark - devices stack API
565 /*! Unregisters a previously registered deframer function. */
566 status_t
567 unregister_device_deframer(net_device* device)
569 MutexLocker locker(sLock);
571 // find device interface for this device
572 net_device_interface* interface = find_device_interface(device->name);
573 if (interface == NULL)
574 return B_DEVICE_NOT_FOUND;
576 RecursiveLocker _(interface->receive_lock);
578 if (--interface->deframe_ref_count == 0)
579 interface->deframe_func = NULL;
581 return B_OK;
585 /*! Registers the deframer function for the specified \a device.
586 Note, however, that right now, you can only register one single
587 deframer function per device.
589 If the need arises, we might want to lift that limitation at a
590 later time (which would require a slight API change, though).
592 status_t
593 register_device_deframer(net_device* device, net_deframe_func deframeFunc)
595 MutexLocker locker(sLock);
597 // find device interface for this device
598 net_device_interface* interface = find_device_interface(device->name);
599 if (interface == NULL)
600 return B_DEVICE_NOT_FOUND;
602 RecursiveLocker _(interface->receive_lock);
604 if (interface->deframe_func != NULL
605 && interface->deframe_func != deframeFunc)
606 return B_ERROR;
608 interface->deframe_func = deframeFunc;
609 interface->deframe_ref_count++;
610 return B_OK;
614 /*! Registers a domain to receive net_buffers from the specified \a device. */
615 status_t
616 register_domain_device_handler(struct net_device* device, int32 type,
617 struct net_domain* _domain)
619 net_domain_private* domain = (net_domain_private*)_domain;
620 if (domain->module == NULL || domain->module->receive_data == NULL)
621 return B_BAD_VALUE;
623 return register_device_handler(device, type, &domain_receive_adapter,
624 domain);
628 /*! Registers a receiving function callback for the specified \a device. */
629 status_t
630 register_device_handler(struct net_device* device, int32 type,
631 net_receive_func receiveFunc, void* cookie)
633 MutexLocker locker(sLock);
635 // find device interface for this device
636 net_device_interface* interface = find_device_interface(device->name);
637 if (interface == NULL)
638 return B_DEVICE_NOT_FOUND;
640 RecursiveLocker _(interface->receive_lock);
642 // see if such a handler already for this device
644 DeviceHandlerList::Iterator iterator
645 = interface->receive_funcs.GetIterator();
646 while (net_device_handler* handler = iterator.Next()) {
647 if (handler->type == type)
648 return B_ERROR;
651 // Add new handler
653 net_device_handler* handler = new(std::nothrow) net_device_handler;
654 if (handler == NULL)
655 return B_NO_MEMORY;
657 handler->func = receiveFunc;
658 handler->type = type;
659 handler->cookie = cookie;
660 interface->receive_funcs.Add(handler);
661 return B_OK;
665 /*! Unregisters a previously registered device handler. */
666 status_t
667 unregister_device_handler(struct net_device* device, int32 type)
669 MutexLocker locker(sLock);
671 // find device interface for this device
672 net_device_interface* interface = find_device_interface(device->name);
673 if (interface == NULL)
674 return B_DEVICE_NOT_FOUND;
676 RecursiveLocker _(interface->receive_lock);
678 // search for the handler
680 DeviceHandlerList::Iterator iterator
681 = interface->receive_funcs.GetIterator();
682 while (net_device_handler* handler = iterator.Next()) {
683 if (handler->type == type) {
684 // found it
685 iterator.Remove();
686 delete handler;
687 return B_OK;
691 return B_BAD_VALUE;
695 /*! Registers a device monitor for the specified device. */
696 status_t
697 register_device_monitor(net_device* device, net_device_monitor* monitor)
699 if (monitor->receive == NULL || monitor->event == NULL)
700 return B_BAD_VALUE;
702 MutexLocker locker(sLock);
704 // find device interface for this device
705 net_device_interface* interface = find_device_interface(device->name);
706 if (interface == NULL)
707 return B_DEVICE_NOT_FOUND;
709 RecursiveLocker monitorLocker(interface->monitor_lock);
710 interface->monitor_funcs.Add(monitor);
711 atomic_add(&interface->monitor_count, 1);
713 return B_OK;
717 /*! Unregisters a previously registered device monitor. */
718 status_t
719 unregister_device_monitor(net_device* device, net_device_monitor* monitor)
721 MutexLocker locker(sLock);
723 // find device interface for this device
724 net_device_interface* interface = find_device_interface(device->name);
725 if (interface == NULL)
726 return B_DEVICE_NOT_FOUND;
728 RecursiveLocker monitorLocker(interface->monitor_lock);
730 // search for the monitor
732 DeviceMonitorList::Iterator iterator
733 = interface->monitor_funcs.GetIterator();
734 while (iterator.HasNext()) {
735 if (iterator.Next() == monitor) {
736 iterator.Remove();
737 atomic_add(&interface->monitor_count, -1);
738 return B_OK;
742 return B_BAD_VALUE;
746 /*! This function is called by device modules in case their link
747 state changed, ie. if an ethernet cable was plugged in or
748 removed.
750 status_t
751 device_link_changed(net_device* device)
753 notify_link_changed(device);
754 return B_OK;
758 /*! This function is called by device modules once their device got
759 physically removed, ie. a USB networking card is unplugged.
761 status_t
762 device_removed(net_device* device)
764 MutexLocker locker(sLock);
766 // hold a reference to the device interface being removed
767 // so our put_() will (eventually) do the final cleanup
768 net_device_interface* interface = get_device_interface(device->name, false);
769 if (interface == NULL)
770 return B_DEVICE_NOT_FOUND;
772 // Propagate the loss of the device throughout the stack.
774 interface_removed_device_interface(interface);
775 notify_device_monitors(interface, B_DEVICE_BEING_REMOVED);
777 // By now all of the monitors must have removed themselves. If they
778 // didn't, they'll probably wait forever to be callback'ed again.
779 recursive_lock_lock(&interface->monitor_lock);
780 interface->monitor_funcs.RemoveAll();
782 // All of the readers should be gone as well since we are out of
783 // interfaces and put_domain_datalink_protocols() is called for
784 // each delete_interface().
786 put_device_interface(interface);
788 return B_OK;
792 status_t
793 device_enqueue_buffer(net_device* device, net_buffer* buffer)
795 net_device_interface* interface = get_device_interface(device->index);
796 if (interface == NULL)
797 return B_DEVICE_NOT_FOUND;
799 status_t status = fifo_enqueue_buffer(&interface->receive_queue, buffer);
801 put_device_interface(interface);
802 return status;
806 // #pragma mark -
809 status_t
810 init_device_interfaces()
812 mutex_init(&sLock, "net device interfaces");
814 new (&sInterfaces) DeviceInterfaceList;
815 // static C++ objects are not initialized in the module startup
817 #if ENABLE_DEBUGGER_COMMANDS
818 add_debugger_command("net_device_interface", &dump_device_interface,
819 "Dump the given network device interface");
820 add_debugger_command("net_device_interfaces", &dump_device_interfaces,
821 "Dump network device interfaces");
822 #endif
823 return B_OK;
827 status_t
828 uninit_device_interfaces()
830 #if ENABLE_DEBUGGER_COMMANDS
831 remove_debugger_command("net_device_interface", &dump_device_interface);
832 remove_debugger_command("net_device_interfaces", &dump_device_interfaces);
833 #endif
835 mutex_destroy(&sLock);
836 return B_OK;