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