2 * Copyright 2006-2010, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
6 * Axel Dörfler, axeld@pinc-software.de
10 #include "device_interfaces.h"
12 #include "interfaces.h"
13 #include "stack_private.h"
16 #include <net_device.h>
19 #include <util/AutoLock.h>
21 #include <KernelExport.h>
23 #include <net/if_dl.h>
24 #include <netinet/in.h>
31 //#define TRACE_DEVICE_INTERFACES
32 #ifdef TRACE_DEVICE_INTERFACES
33 # define TRACE(x) dprintf x
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
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) {
57 status
= device
->module
->receive_data(device
, &buffer
);
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
);
70 fifo_enqueue_buffer(&interface
->receive_queue
, buffer
);
71 } else if (status
== B_DEVICE_NOT_FOUND
) {
72 device_removed(device
);
74 // In case of error, give the other threads some
75 // time to run since this is a high priority time thread.
85 device_consumer_thread(void* _interface
)
87 net_device_interface
* interface
= (net_device_interface
*)_interface
;
88 net_device
* device
= interface
->device
;
92 ssize_t status
= fifo_dequeue_buffer(&interface
->receive_queue
, 0,
93 B_INFINITE_TIMEOUT
, &buffer
);
95 if (status
== B_INTERRUPTED
)
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
)
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
125 if ((handler
->type
== genericType
126 || handler
->type
== specificType
)
127 && handler
->func(handler
->cookie
, device
, buffer
) == B_OK
)
133 gNetBufferModule
.free(buffer
);
140 /*! The domain's device receive handler - this will inject the net_buffers into
141 the protocol layer (the domain's registered receive handler).
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
))
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
)
173 recursive_lock_init(&interface
->receive_lock
, "device interface receive");
174 recursive_lock_init(&interface
->monitor_lock
, "device interface monitors");
177 snprintf(name
, sizeof(name
), "%s receive queue", device
->name
);
179 if (init_fifo(&interface
->receive_queue
, name
, 16 * 1024 * 1024) < B_OK
)
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
)
196 resume_thread(interface
->consumer_thread
);
198 // TODO: proper interface index allocation
199 device
->index
= ++sDeviceIndex
;
200 device
->module
= module
;
202 sInterfaces
.Add(interface
);
206 uninit_fifo(&interface
->receive_queue
);
208 recursive_lock_destroy(&interface
->receive_lock
);
209 recursive_lock_destroy(&interface
->monitor_lock
);
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
234 dump_device_interface(int argc
, char** argv
)
237 kprintf("usage: %s [address]\n", argv
[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());
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
);
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)
301 get_device_interface_address(net_device_interface
* interface
,
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
;
322 count_device_interfaces()
324 MutexLocker
locker(sLock
);
326 DeviceInterfaceList::Iterator iterator
= sInterfaces
.GetIterator();
329 while (iterator
.HasNext()) {
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
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();
369 /*! Releases the reference for the interface. When all references are
370 released, the interface is removed.
373 put_device_interface(struct net_device_interface
* interface
)
375 if (interface
== NULL
)
378 if (atomic_add(&interface
->ref_count
, -1) != 1)
381 MutexLocker
locker(sLock
);
382 sInterfaces
.Remove(interface
);
385 uninit_fifo(&interface
->receive_queue
);
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
);
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)
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)
434 // try to recreate interface - it just got removed
440 void* cookie
= open_module_list("network/devices");
445 char moduleName
[B_FILE_NAME_LENGTH
];
446 size_t length
= sizeof(moduleName
);
447 if (read_next_module_name(cookie
, moduleName
, &length
) != B_OK
)
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
) {
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
)
461 module
->uninit_device(device
);
463 put_module(moduleName
);
467 close_module_list(cookie
);
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.
478 device_interface_monitor_receive(net_device_interface
* interface
,
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
);
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
++;
504 status_t status
= device
->module
->up(device
);
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;
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
557 wait_for_thread(readerThread
, &status
);
562 // #pragma mark - devices stack API
565 /*! Unregisters a previously registered deframer function. */
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
;
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).
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
)
608 interface
->deframe_func
= deframeFunc
;
609 interface
->deframe_ref_count
++;
614 /*! Registers a domain to receive net_buffers from the specified \a device. */
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
)
623 return register_device_handler(device
, type
, &domain_receive_adapter
,
628 /*! Registers a receiving function callback for the specified \a device. */
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
)
653 net_device_handler
* handler
= new(std::nothrow
) net_device_handler
;
657 handler
->func
= receiveFunc
;
658 handler
->type
= type
;
659 handler
->cookie
= cookie
;
660 interface
->receive_funcs
.Add(handler
);
665 /*! Unregisters a previously registered device handler. */
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
) {
695 /*! Registers a device monitor for the specified device. */
697 register_device_monitor(net_device
* device
, net_device_monitor
* monitor
)
699 if (monitor
->receive
== NULL
|| monitor
->event
== NULL
)
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);
717 /*! Unregisters a previously registered device monitor. */
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
) {
737 atomic_add(&interface
->monitor_count
, -1);
746 /*! This function is called by device modules in case their link
747 state changed, ie. if an ethernet cable was plugged in or
751 device_link_changed(net_device
* device
)
753 notify_link_changed(device
);
758 /*! This function is called by device modules once their device got
759 physically removed, ie. a USB networking card is unplugged.
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
);
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
);
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");
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
);
835 mutex_destroy(&sLock
);