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