1/*
2 * Copyright 2006-2010, 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 "device_interfaces.h"
11#include "domains.h"
12#include "interfaces.h"
13#include "stack_private.h"
14#include "utility.h"
15
16#include <net_device.h>
17
18#include <lock.h>
19#include <util/AutoLock.h>
20
21#include <KernelExport.h>
22
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>
29
30
31//#define TRACE_DEVICE_INTERFACES
32#ifdef TRACE_DEVICE_INTERFACES
33#	define TRACE(x) dprintf x
34#else
35#	define TRACE(x) ;
36#endif
37
38
39static mutex sLock;
40static DeviceInterfaceList sInterfaces;
41static uint32 sDeviceIndex;
42
43
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.
47*/
48static status_t
49device_reader_thread(void* _interface)
50{
51	net_device_interface* interface = (net_device_interface*)_interface;
52	net_device* device = interface->device;
53	status_t status = B_OK;
54
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);
62
63			ASSERT(buffer->interface_address == NULL);
64
65			if (interface->deframe_func(interface->device, buffer) != B_OK) {
66				gNetBufferModule.free(buffer);
67				continue;
68			}
69
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);
77		}
78	}
79
80	return status;
81}
82
83
84static status_t
85device_consumer_thread(void* _interface)
86{
87	net_device_interface* interface = (net_device_interface*)_interface;
88	net_device* device = interface->device;
89	net_buffer* buffer;
90
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;
98		}
99
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));
111
112			buffer->index = interface->device->index;
113
114			// Find handler for this packet
115
116			RecursiveLocker locker(interface->receive_lock);
117
118			DeviceHandlerList::Iterator iterator
119				= interface->receive_funcs.GetIterator();
120			while (buffer != NULL && iterator.HasNext()) {
121				net_device_handler* handler = iterator.Next();
122
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;
129			}
130		}
131
132		if (buffer != NULL)
133			gNetBufferModule.free(buffer);
134	}
135
136	return B_OK;
137}
138
139
140/*!	The domain's device receive handler - this will inject the net_buffers into
141	the protocol layer (the domain's registered receive handler).
142*/
143static status_t
144domain_receive_adapter(void* cookie, net_device* device, net_buffer* buffer)
145{
146	net_domain_private* domain = (net_domain_private*)cookie;
147
148	return domain->module->receive_data(buffer);
149}
150
151
152static net_device_interface*
153find_device_interface(const char* name)
154{
155	DeviceInterfaceList::Iterator iterator = sInterfaces.GetIterator();
156
157	while (net_device_interface* interface = iterator.Next()) {
158		if (!strcmp(interface->device->name, name))
159			return interface;
160	}
161
162	return NULL;
163}
164
165
166static net_device_interface*
167allocate_device_interface(net_device* device, net_device_module_info* module)
168{
169	net_device_interface* interface = new(std::nothrow) net_device_interface;
170	if (interface == NULL)
171		return NULL;
172
173	recursive_lock_init(&interface->receive_lock, "device interface receive");
174	mutex_init(&interface->monitor_lock, "device interface monitors");
175
176	char name[128];
177	snprintf(name, sizeof(name), "%s receive queue", device->name);
178
179	if (init_fifo(&interface->receive_queue, name, 16 * 1024 * 1024) < B_OK)
180		goto error1;
181
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;
188
189	snprintf(name, sizeof(name), "%s consumer", device->name);
190
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);
197
198	// TODO: proper interface index allocation
199	device->index = ++sDeviceIndex;
200	device->module = module;
201
202	sInterfaces.Add(interface);
203	return interface;
204
205error2:
206	uninit_fifo(&interface->receive_queue);
207error1:
208	recursive_lock_destroy(&interface->receive_lock);
209	mutex_destroy(&interface->monitor_lock);
210	delete interface;
211
212	return NULL;
213}
214
215
216static void
217notify_device_monitors(net_device_interface* interface, int32 event)
218{
219	MutexLocker locker(interface->monitor_lock);
220
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);
226	}
227}
228
229
230#if ENABLE_DEBUGGER_COMMANDS
231
232
233static int
234dump_device_interface(int argc, char** argv)
235{
236	if (argc != 2) {
237		kprintf("usage: %s [address]\n", argv[0]);
238		return 0;
239	}
240
241	net_device_interface* interface
242		= (net_device_interface*)parse_expression(argv[1]);
243
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);
251
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());
259
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());
267
268	return 0;
269}
270
271
272static int
273dump_device_interfaces(int argc, char** argv)
274{
275	DeviceInterfaceList::Iterator iterator = sInterfaces.GetIterator();
276	while (net_device_interface* interface = iterator.Next()) {
277		kprintf("  %p  %s\n", interface, interface->device->name);
278	}
279
280	return 0;
281}
282
283
284#endif	// ENABLE_DEBUGGER_COMMANDS
285
286
287//	#pragma mark - device interfaces
288
289
290net_device_interface*
291acquire_device_interface(net_device_interface* interface)
292{
293	if (interface == NULL || atomic_add(&interface->ref_count, 1) == 0)
294		return NULL;
295
296	return interface;
297}
298
299
300void
301get_device_interface_address(net_device_interface* interface,
302	sockaddr* _address)
303{
304	sockaddr_dl &address = *(sockaddr_dl*)_address;
305
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);
312
313	address.sdl_alen = interface->device->address.length;
314	memcpy(LLADDR(&address), interface->device->address.data, address.sdl_alen);
315
316	address.sdl_len = sizeof(sockaddr_dl) - sizeof(address.sdl_data)
317		+ address.sdl_nlen + address.sdl_alen;
318}
319
320
321uint32
322count_device_interfaces()
323{
324	MutexLocker locker(sLock);
325
326	DeviceInterfaceList::Iterator iterator = sInterfaces.GetIterator();
327	uint32 count = 0;
328
329	while (iterator.HasNext()) {
330		iterator.Next();
331		count++;
332	}
333
334	return count;
335}
336
337
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.
341*/
342status_t
343list_device_interfaces(void* _buffer, size_t* bufferSize)
344{
345	MutexLocker locker(sLock);
346
347	DeviceInterfaceList::Iterator iterator = sInterfaces.GetIterator();
348	UserBuffer buffer(_buffer, *bufferSize);
349
350	while (net_device_interface* interface = iterator.Next()) {
351		buffer.Push(interface->device->name, IF_NAMESIZE);
352
353		sockaddr_storage address;
354		get_device_interface_address(interface, (sockaddr*)&address);
355
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);
359
360		if (buffer.Status() != B_OK)
361			return buffer.Status();
362	}
363
364	*bufferSize = buffer.BytesConsumed();
365	return B_OK;
366}
367
368
369/*!	Releases the reference for the interface. When all references are
370	released, the interface is removed.
371*/
372void
373put_device_interface(struct net_device_interface* interface)
374{
375	if (interface == NULL)
376		return;
377
378	if (atomic_add(&interface->ref_count, -1) != 1)
379		return;
380
381	MutexLocker locker(sLock);
382	sInterfaces.Remove(interface);
383	locker.Unlock();
384
385	uninit_fifo(&interface->receive_queue);
386	status_t status;
387	wait_for_thread(interface->consumer_thread, &status);
388
389	net_device* device = interface->device;
390	const char* moduleName = device->module->info.name;
391
392	device->module->uninit_device(device);
393	put_module(moduleName);
394
395	mutex_destroy(&interface->monitor_lock);
396	recursive_lock_destroy(&interface->receive_lock);
397	delete interface;
398}
399
400
401/*!	Finds an interface by the specified index and acquires a reference to it.
402*/
403struct net_device_interface*
404get_device_interface(uint32 index)
405{
406	MutexLocker locker(sLock);
407
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;
414		}
415	}
416
417	return NULL;
418}
419
420
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.
423*/
424struct net_device_interface*
425get_device_interface(const char* name, bool create)
426{
427	MutexLocker locker(sLock);
428
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;
433
434		// try to recreate interface - it just got removed
435	}
436
437	if (!create)
438		return NULL;
439
440	void* cookie = open_module_list("network/devices");
441	if (cookie == NULL)
442		return NULL;
443
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;
449
450		TRACE(("get_device_interface: ask \"%s\" for %s\n", moduleName, name));
451
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;
460
461				module->uninit_device(device);
462			}
463			put_module(moduleName);
464		}
465	}
466
467	close_module_list(cookie);
468
469	return NULL;
470}
471
472
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.
476*/
477void
478device_interface_monitor_receive(net_device_interface* interface,
479	net_buffer* buffer)
480{
481	MutexLocker locker(interface->monitor_lock);
482
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);
488	}
489}
490
491
492status_t
493up_device_interface(net_device_interface* interface)
494{
495	net_device* device = interface->device;
496
497	RecursiveLocker locker(interface->receive_lock);
498
499	if (interface->up_count != 0) {
500		interface->up_count++;
501		return B_OK;
502	}
503
504	status_t status = device->module->up(device);
505	if (status != B_OK)
506		return status;
507
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);
512
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;
517	}
518
519	device->flags |= IFF_UP;
520
521	if (device->module->receive_data != NULL)
522		resume_thread(interface->reader_thread);
523
524	interface->up_count = 1;
525	return B_OK;
526}
527
528
529void
530down_device_interface(net_device_interface* interface)
531{
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:
535	//
536	// - domain_interface_control() [rx lock held, domain lock held]
537	//    interface_set_down()
538	//     interface_protocol_down()
539	//
540	// - domain_interface_control() [rx lock held, domain lock held]
541	//    remove_interface_from_domain()
542	//     delete_interface()
543	//      interface_set_down()
544
545	net_device* device = interface->device;
546
547	device->flags &= ~IFF_UP;
548	device->module->down(device);
549
550	notify_device_monitors(interface, B_DEVICE_GOING_DOWN);
551
552	if (device->module->receive_data != NULL) {
553		thread_id readerThread = interface->reader_thread;
554
555		// make sure the reader thread is gone before shutting down the interface
556		status_t status;
557		wait_for_thread(readerThread, &status);
558	}
559}
560
561
562//	#pragma mark - devices stack API
563
564
565/*!	Unregisters a previously registered deframer function. */
566status_t
567unregister_device_deframer(net_device* device)
568{
569	MutexLocker locker(sLock);
570
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;
575
576	RecursiveLocker _(interface->receive_lock);
577
578	if (--interface->deframe_ref_count == 0)
579		interface->deframe_func = NULL;
580
581	return B_OK;
582}
583
584
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.
588
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).
591*/
592status_t
593register_device_deframer(net_device* device, net_deframe_func deframeFunc)
594{
595	MutexLocker locker(sLock);
596
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;
601
602	RecursiveLocker _(interface->receive_lock);
603
604	if (interface->deframe_func != NULL
605		&& interface->deframe_func != deframeFunc)
606		return B_ERROR;
607
608	interface->deframe_func = deframeFunc;
609	interface->deframe_ref_count++;
610	return B_OK;
611}
612
613
614/*!	Registers a domain to receive net_buffers from the specified \a device. */
615status_t
616register_domain_device_handler(struct net_device* device, int32 type,
617	struct net_domain* _domain)
618{
619	net_domain_private* domain = (net_domain_private*)_domain;
620	if (domain->module == NULL || domain->module->receive_data == NULL)
621		return B_BAD_VALUE;
622
623	return register_device_handler(device, type, &domain_receive_adapter,
624		domain);
625}
626
627
628/*!	Registers a receiving function callback for the specified \a device. */
629status_t
630register_device_handler(struct net_device* device, int32 type,
631	net_receive_func receiveFunc, void* cookie)
632{
633	MutexLocker locker(sLock);
634
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;
639
640	RecursiveLocker _(interface->receive_lock);
641
642	// see if such a handler already for this device
643
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;
649	}
650
651	// Add new handler
652
653	net_device_handler* handler = new(std::nothrow) net_device_handler;
654	if (handler == NULL)
655		return B_NO_MEMORY;
656
657	handler->func = receiveFunc;
658	handler->type = type;
659	handler->cookie = cookie;
660	interface->receive_funcs.Add(handler);
661	return B_OK;
662}
663
664
665/*!	Unregisters a previously registered device handler. */
666status_t
667unregister_device_handler(struct net_device* device, int32 type)
668{
669	MutexLocker locker(sLock);
670
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;
675
676	RecursiveLocker _(interface->receive_lock);
677
678	// search for the handler
679
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;
688		}
689	}
690
691	return B_BAD_VALUE;
692}
693
694
695/*!	Registers a device monitor for the specified device. */
696status_t
697register_device_monitor(net_device* device, net_device_monitor* monitor)
698{
699	if (monitor->receive == NULL || monitor->event == NULL)
700		return B_BAD_VALUE;
701
702	MutexLocker locker(sLock);
703
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;
708
709	MutexLocker monitorLocker(interface->monitor_lock);
710	interface->monitor_funcs.Add(monitor);
711	atomic_add(&interface->monitor_count, 1);
712
713	return B_OK;
714}
715
716
717/*!	Unregisters a previously registered device monitor. */
718status_t
719unregister_device_monitor(net_device* device, net_device_monitor* monitor)
720{
721	MutexLocker locker(sLock);
722
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;
727
728	MutexLocker monitorLocker(interface->monitor_lock);
729
730	// search for the monitor
731
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;
739		}
740	}
741
742	return B_BAD_VALUE;
743}
744
745
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.
749*/
750status_t
751device_link_changed(net_device* device)
752{
753	notify_link_changed(device);
754	return B_OK;
755}
756
757
758/*!	This function is called by device modules once their device got
759	physically removed, ie. a USB networking card is unplugged.
760*/
761status_t
762device_removed(net_device* device)
763{
764	MutexLocker locker(sLock);
765
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;
771
772	// Propagate the loss of the device throughout the stack.
773
774	interface_removed_device_interface(interface);
775	notify_device_monitors(interface, B_DEVICE_BEING_REMOVED);
776
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	mutex_lock(&interface->monitor_lock);
780	interface->monitor_funcs.RemoveAll();
781
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().
785
786	put_device_interface(interface);
787
788	return B_OK;
789}
790
791
792status_t
793device_enqueue_buffer(net_device* device, net_buffer* buffer)
794{
795	net_device_interface* interface = get_device_interface(device->index);
796	if (interface == NULL)
797		return B_DEVICE_NOT_FOUND;
798
799	status_t status = fifo_enqueue_buffer(&interface->receive_queue, buffer);
800
801	put_device_interface(interface);
802	return status;
803}
804
805
806//	#pragma mark -
807
808
809status_t
810init_device_interfaces()
811{
812	mutex_init(&sLock, "net device interfaces");
813
814	new (&sInterfaces) DeviceInterfaceList;
815		// static C++ objects are not initialized in the module startup
816
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;
824}
825
826
827status_t
828uninit_device_interfaces()
829{
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
834
835	mutex_destroy(&sLock);
836	return B_OK;
837}
838
839