xref: /haiku/src/add-ons/kernel/network/stack/stack.cpp (revision 13581b3d2a71545960b98fefebc5225b5bf29072)
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 "ancillary_data.h"
11 #include "device_interfaces.h"
12 #include "domains.h"
13 #include "interfaces.h"
14 #include "link.h"
15 #include "stack_private.h"
16 #include "utility.h"
17 
18 #include <net_datalink_protocol.h>
19 #include <net_device.h>
20 #include <net_protocol.h>
21 #include <net_stack.h>
22 
23 #include <lock.h>
24 #include <util/AutoLock.h>
25 #include <util/Vector.h>
26 
27 #include <KernelExport.h>
28 
29 #include <net/if_types.h>
30 #include <new>
31 #include <stdarg.h>
32 #include <stdlib.h>
33 #include <string.h>
34 
35 
36 //#define TRACE_STACK
37 #ifdef TRACE_STACK
38 #	define TRACE(x) dprintf x
39 #else
40 #	define TRACE(x) ;
41 #endif
42 
43 #define MAX_CHAIN_MODULES 5
44 
45 struct chain;
46 typedef DoublyLinkedList<chain> ChainList;
47 
48 struct chain_key {
49 	int		family;
50 	int		type;
51 	int		protocol;
52 };
53 
54 struct family {
55 	family(int type);
56 
57 	void Acquire();
58 	void Release();
59 
60 	static int Compare(void* _family, const void* _key);
61 	static uint32 Hash(void* _family, const void* _key, uint32 range);
62 	static struct family* Lookup(int type);
63 	static struct family* Add(int type);
64 
65 	struct family*	next;
66 	int				type;
67 	int32			ref_count;
68 	ChainList		chains;
69 };
70 
71 struct ChainHash;
72 
73 struct chain : DoublyLinkedListLinkImpl<chain> {
74 	chain(int family, int type, int protocol);
75 	~chain();
76 
77 	status_t Acquire();
78 	void Release();
79 	void Uninitialize();
80 
81 	static struct chain* Lookup(BOpenHashTable<ChainHash>* chains,
82 		int family, int type, int protocol);
83 	static struct chain* Add(BOpenHashTable<ChainHash>* chains,
84 		int family, int type, int protocol, va_list modules);
85 	static struct chain* Add(BOpenHashTable<ChainHash>* chains,
86 		int family, int type, int protocol, ...);
87 	static void DeleteChains(BOpenHashTable<ChainHash>* chains);
88 
89 	chain*			next;
90 	struct family*	parent;
91 
92 	int 			family;
93 	int				type;
94 	int				protocol;
95 
96 	int32			ref_count;
97 	uint32			flags;
98 	const char*		modules[MAX_CHAIN_MODULES + 1];
99 	module_info*	infos[MAX_CHAIN_MODULES + 1];
100 };
101 
102 struct ChainHash {
103 	typedef chain_key	KeyType;
104 	typedef	chain		ValueType;
105 
106 // TODO: check if this makes a good hash...
107 #define HASH(o) ((uint32)(((o)->family) ^ ((o)->type) ^ ((o)->protocol)))
108 
109 	size_t HashKey(KeyType key) const
110 	{
111 		return HASH(&key);
112 	}
113 
114 	size_t Hash(ValueType* value) const
115 	{
116 		return HASH(value);
117 	}
118 
119 #undef HASH
120 
121 	bool Compare(KeyType key, ValueType* chain) const
122 	{
123 		if (chain->family == key.family
124 			&& chain->type == key.type
125 			&& chain->protocol == key.protocol)
126 			return true;
127 
128 		return false;
129 	}
130 
131 	ValueType*& GetLink(ValueType* value) const
132 	{
133 		return value->next;
134 	}
135 };
136 
137 struct FamilyHash {
138 	typedef int			KeyType;
139 	typedef	family		ValueType;
140 
141 	size_t HashKey(KeyType key) const
142 	{
143 		return key;
144 	}
145 
146 	size_t Hash(ValueType* value) const
147 	{
148 		return value->type;
149 	}
150 
151 	bool Compare(KeyType key, ValueType* family) const
152 	{
153 		return family->type == key;
154 	}
155 
156 	ValueType*& GetLink(ValueType* value) const
157 	{
158 		return value->next;
159 	}
160 };
161 
162 typedef BOpenHashTable<ChainHash> ChainTable;
163 typedef BOpenHashTable<FamilyHash> FamilyTable;
164 
165 #define CHAIN_MISSING_MODULE	0x02
166 #define CHAIN_INITIALIZED		0x01
167 
168 static mutex sChainLock;
169 static mutex sInitializeChainLock;
170 static ChainTable* sProtocolChains;
171 static ChainTable* sDatalinkProtocolChains;
172 static ChainTable* sReceivingProtocolChains;
173 static FamilyTable* sFamilies;
174 static bool sInitialized;
175 
176 
177 family::family(int _type)
178 	:
179 	type(_type),
180 	ref_count(0)
181 {
182 }
183 
184 
185 void
186 family::Acquire()
187 {
188 	atomic_add(&ref_count, 1);
189 }
190 
191 
192 void
193 family::Release()
194 {
195 	if (atomic_add(&ref_count, -1) > 1)
196 		return;
197 
198 	TRACE(("family %d unused, uninit chains\n", type));
199 	MutexLocker _(sChainLock);
200 
201 	ChainList::Iterator iterator = chains.GetIterator();
202 	while (struct chain* chain = iterator.Next()) {
203 		chain->Uninitialize();
204 	}
205 }
206 
207 
208 /*static*/ struct family*
209 family::Lookup(int type)
210 {
211 	return sFamilies->Lookup(type);
212 }
213 
214 
215 /*static*/ struct family*
216 family::Add(int type)
217 {
218 	struct family* family = new (std::nothrow) ::family(type);
219 	if (family == NULL)
220 		return NULL;
221 
222 	if (sFamilies->Insert(family) != B_OK) {
223 		delete family;
224 		return NULL;
225 	}
226 
227 	return family;
228 }
229 
230 
231 //	#pragma mark -
232 
233 
234 chain::chain(int _family, int _type, int _protocol)
235 	:
236 	family(_family),
237 	type(_type),
238 	protocol(_protocol),
239 	ref_count(0),
240 	flags(0)
241 {
242 	parent = ::family::Lookup(family);
243 	if (parent == NULL)
244 		parent = ::family::Add(family);
245 
246 	//parent->chains.Add(this);
247 
248 	for (int32 i = 0; i < MAX_CHAIN_MODULES; i++) {
249 		modules[i] = NULL;
250 		infos[i] = NULL;
251 	}
252 }
253 
254 
255 chain::~chain()
256 {
257 	for (int32 i = 0; i < MAX_CHAIN_MODULES; i++) {
258 		free((char*)modules[i]);
259 	}
260 
261 	//parent->chains.Remove(this);
262 }
263 
264 
265 status_t
266 chain::Acquire()
267 {
268 	if (atomic_add(&ref_count, 1) > 0) {
269 		if ((flags & CHAIN_MISSING_MODULE) != 0) {
270 			atomic_add(&ref_count, -1);
271 			return EAFNOSUPPORT;
272 		}
273 
274 		while ((flags & CHAIN_INITIALIZED) == 0) {
275 			mutex_lock(&sInitializeChainLock);
276 			mutex_unlock(&sInitializeChainLock);
277 		}
278 		return B_OK;
279 	}
280 
281 	parent->Acquire();
282 
283 	if ((flags & CHAIN_INITIALIZED) != 0)
284 		return B_OK;
285 
286 	TRACE(("initializing chain %d.%d.%d\n", family, type, protocol));
287 	MutexLocker locker(&sInitializeChainLock);
288 
289 	for (int32 i = 0; modules[i] != NULL; i++) {
290 		if (get_module(modules[i], &infos[i]) < B_OK) {
291 			flags |= CHAIN_MISSING_MODULE;
292 
293 			// put already opened modules
294 			while (i-- > 0) {
295 				put_module(modules[i]);
296 			}
297 			return EAFNOSUPPORT;
298 		}
299 	}
300 
301 	flags |= CHAIN_INITIALIZED;
302 	return B_OK;
303 }
304 
305 
306 void
307 chain::Release()
308 {
309 	if (atomic_add(&ref_count, -1) > 1)
310 		return;
311 
312 	TRACE(("chain %d.%d.%d unused\n", family, type, protocol));
313 	parent->Release();
314 }
315 
316 
317 void
318 chain::Uninitialize()
319 {
320 	if ((flags & CHAIN_INITIALIZED) == 0)
321 		return;
322 
323 	TRACE(("uninit chain %d.%d.%d\n", family, type, protocol));
324 	MutexLocker _(sInitializeChainLock);
325 
326 	for (int32 i = 0; modules[i] != NULL; i++) {
327 		put_module(modules[i]);
328 	}
329 
330 	flags &= ~CHAIN_INITIALIZED;
331 }
332 
333 
334 /*static*/ struct chain*
335 chain::Lookup(ChainTable* chains, int family, int type, int protocol)
336 {
337 	struct chain_key key = { family, type, protocol };
338 	return chains->Lookup(key);
339 }
340 
341 
342 /*static*/ struct chain*
343 chain::Add(ChainTable* chains, int family, int type, int protocol,
344 	va_list modules)
345 {
346 	struct chain* chain = new (std::nothrow) ::chain(family, type, protocol);
347 	if (chain == NULL)
348 		return NULL;
349 
350 	if (chain->parent == NULL || chains->Insert(chain) != B_OK) {
351 		delete chain;
352 		return NULL;
353 	}
354 
355 	TRACE(("Add chain %d.%d.%d:\n", family, type, protocol));
356 	const char* module;
357 	int32 count = 0;
358 
359 	while (true) {
360 		module = va_arg(modules, const char*);
361 		if (module == NULL)
362 			break;
363 
364 		TRACE(("  [%" B_PRId32 "] %s\n", count, module));
365 		chain->modules[count] = strdup(module);
366 		if (chain->modules[count] == NULL
367 			|| ++count >= MAX_CHAIN_MODULES) {
368 			chains->Remove(chain);
369 			delete chain;
370 			return NULL;
371 		}
372 	}
373 
374 	if (chains == sProtocolChains && count == 0) {
375 		chains->Remove(chain);
376 		delete chain;
377 		return NULL;
378 	}
379 
380 	return chain;
381 }
382 
383 
384 /*static*/ struct chain*
385 chain::Add(ChainTable* chains, int family, int type, int protocol, ...)
386 {
387 	va_list modules;
388 	va_start(modules, protocol);
389 
390 	struct chain* chain = Add(chains, family, type, 0, modules);
391 
392 	va_end(modules);
393 	return chain;
394 }
395 
396 
397 /*static*/ void
398 chain::DeleteChains(ChainTable* chains)
399 {
400 	struct chain* current;
401 	current = chains->Clear(true);
402 	while (current) {
403 		struct chain* next = current->next;
404 
405 		current->Uninitialize();
406 		delete current;
407 		current = next;
408 	}
409 }
410 
411 
412 //	#pragma mark -
413 
414 
415 static void
416 uninit_domain_protocols(net_socket* socket)
417 {
418 	net_protocol* protocol = socket->first_protocol;
419 	while (protocol != NULL) {
420 		net_protocol* next = protocol->next;
421 		protocol->module->uninit_protocol(protocol);
422 
423 		protocol = next;
424 	}
425 
426 	socket->first_protocol = NULL;
427 	socket->first_info = NULL;
428 }
429 
430 
431 status_t
432 get_domain_protocols(net_socket* socket)
433 {
434 	struct chain* chain;
435 
436 	{
437 		MutexLocker _(sChainLock);
438 
439 		chain = chain::Lookup(sProtocolChains, socket->family, socket->type,
440 			socket->type == SOCK_RAW ? 0 : socket->protocol);
441 			// in SOCK_RAW mode, we ignore the protocol information
442 		if (chain == NULL) {
443 			// TODO: if we want to be POSIX compatible, we should also support
444 			//	the error codes EPROTONOSUPPORT and EPROTOTYPE.
445 			return EAFNOSUPPORT;
446 		}
447 	}
448 
449 	// create net_protocol objects for the protocols in the chain
450 
451 	status_t status = chain->Acquire();
452 	if (status != B_OK)
453 		return status;
454 
455 	net_protocol* last = NULL;
456 
457 	for (int32 i = 0; chain->infos[i] != NULL; i++) {
458 		net_protocol* protocol =
459 			((net_protocol_module_info*)chain->infos[i])->init_protocol(socket);
460 		if (protocol == NULL) {
461 			// free protocols we already initialized
462 			uninit_domain_protocols(socket);
463 			chain->Release();
464 			return B_NO_MEMORY;
465 		}
466 
467 		protocol->module = (net_protocol_module_info*)chain->infos[i];
468 		protocol->socket = socket;
469 		protocol->next = NULL;
470 
471 		if (last == NULL) {
472 			socket->first_protocol = protocol;
473 			socket->first_info = protocol->module;
474 		} else
475 			last->next = protocol;
476 
477 		last = protocol;
478 	}
479 
480 	return B_OK;
481 }
482 
483 
484 status_t
485 put_domain_protocols(net_socket* socket)
486 {
487 	struct chain* chain;
488 
489 	{
490 		MutexLocker _(sChainLock);
491 
492 		chain = chain::Lookup(sProtocolChains, socket->family, socket->type,
493 			socket->protocol);
494 		if (chain == NULL)
495 			return B_ERROR;
496 	}
497 
498 	uninit_domain_protocols(socket);
499 	chain->Release();
500 	return B_OK;
501 }
502 
503 
504 static void
505 uninit_domain_datalink_protocols(domain_datalink* datalink)
506 {
507 	TRACE(("%s(datalink %p)\n", __FUNCTION__, datalink));
508 
509 	if (datalink == NULL)
510 		return;
511 
512 	net_datalink_protocol* protocol = datalink->first_protocol;
513 	while (protocol != NULL) {
514 		net_datalink_protocol* next = protocol->next;
515 		protocol->module->uninit_protocol(protocol);
516 
517 		protocol = next;
518 	}
519 
520 	datalink->first_protocol = NULL;
521 	datalink->first_info = NULL;
522 }
523 
524 
525 status_t
526 get_domain_datalink_protocols(Interface* interface, net_domain* domain)
527 {
528 	TRACE(("%s(interface %p, domain %d)\n", __FUNCTION__, interface,
529 		domain->family));
530 
531 	struct chain* chain;
532 
533 	{
534 		MutexLocker _(sChainLock);
535 
536 		chain = chain::Lookup(sDatalinkProtocolChains, domain->family,
537 			interface->DeviceInterface()->device->type, 0);
538 		if (chain == NULL)
539 			return EAFNOSUPPORT;
540 	}
541 
542 	domain_datalink* datalink = interface->DomainDatalink(domain->family);
543 	if (datalink == NULL)
544 		return B_BAD_VALUE;
545 	if (datalink->first_protocol != NULL)
546 		return B_NAME_IN_USE;
547 
548 	// create net_protocol objects for the protocols in the chain
549 
550 	status_t status = chain->Acquire();
551 	if (status != B_OK)
552 		return status;
553 
554 	net_datalink_protocol* last = NULL;
555 
556 	for (int32 i = 0; chain->infos[i] != NULL; i++) {
557 		net_datalink_protocol* protocol;
558 		status_t status = ((net_datalink_protocol_module_info*)
559 			chain->infos[i])->init_protocol(interface, domain, &protocol);
560 		if (status != B_OK) {
561 			// free protocols we already initialized
562 			uninit_domain_datalink_protocols(datalink);
563 			chain->Release();
564 			return status;
565 		}
566 
567 		protocol->module = (net_datalink_protocol_module_info*)chain->infos[i];
568 		protocol->interface = interface;
569 		protocol->domain = domain;
570 		protocol->next = NULL;
571 
572 		if (last == NULL) {
573 			datalink->first_protocol = protocol;
574 			datalink->first_info = protocol->module;
575 		} else
576 			last->next = protocol;
577 
578 		last = protocol;
579 	}
580 
581 	return B_OK;
582 }
583 
584 
585 status_t
586 put_domain_datalink_protocols(Interface* interface, net_domain* domain)
587 {
588 	TRACE(("%s(interface %p, domain %d)\n", __FUNCTION__, interface,
589 		domain->family));
590 
591 	struct chain* chain;
592 
593 	{
594 		MutexLocker _(sChainLock);
595 
596 		chain = chain::Lookup(sDatalinkProtocolChains, domain->family,
597 			interface->DeviceInterface()->device->type, 0);
598 		if (chain == NULL)
599 			return B_ERROR;
600 	}
601 
602 	uninit_domain_datalink_protocols(interface->DomainDatalink(domain->family));
603 	chain->Release();
604 	return B_OK;
605 }
606 
607 
608 status_t
609 get_domain_receiving_protocol(net_domain* _domain, uint32 type,
610 	net_protocol_module_info** _module)
611 {
612 	struct net_domain_private* domain = (net_domain_private*)_domain;
613 	struct chain* chain;
614 
615 	TRACE(("get_domain_receiving_protocol(family %d, type %" B_PRIu32 ")\n",
616 		domain->family, type));
617 
618 	{
619 		MutexLocker _(sChainLock);
620 
621 		chain = chain::Lookup(sReceivingProtocolChains, domain->family,
622 			type, 0);
623 		if (chain == NULL)
624 			return EAFNOSUPPORT;
625 	}
626 
627 	status_t status = chain->Acquire();
628 	if (status != B_OK)
629 		return status;
630 
631 	*_module = (net_protocol_module_info*)chain->infos[0];
632 	return B_OK;
633 }
634 
635 
636 status_t
637 put_domain_receiving_protocol(net_domain* _domain, uint32 type)
638 {
639 	struct net_domain_private* domain = (net_domain_private*)_domain;
640 	struct chain* chain;
641 
642 	{
643 		MutexLocker _(sChainLock);
644 
645 		chain = chain::Lookup(sReceivingProtocolChains, domain->family,
646 			type, 0);
647 		if (chain == NULL)
648 			return B_ERROR;
649 	}
650 
651 	chain->Release();
652 	return B_OK;
653 }
654 
655 
656 status_t
657 register_domain_protocols(int family, int type, int protocol, ...)
658 {
659 	if (type == SOCK_RAW) {
660 		// in SOCK_RAW mode, we ignore the protocol information
661 		protocol = 0;
662 	}
663 
664 	MutexLocker locker(&sChainLock);
665 
666 	struct chain* chain = chain::Lookup(sProtocolChains, family, type, protocol);
667 	if (chain != NULL)
668 		return B_OK;
669 
670 	va_list modules;
671 	va_start(modules, protocol);
672 
673 	chain = chain::Add(sProtocolChains, family, type, protocol, modules);
674 
675 	va_end(modules);
676 
677 	if (chain == NULL)
678 		return B_NO_MEMORY;
679 
680 	return B_OK;
681 }
682 
683 
684 status_t
685 register_domain_datalink_protocols(int family, int type, ...)
686 {
687 	TRACE(("register_domain_datalink_protocol(%d.%d)\n", family, type));
688 	MutexLocker locker(&sChainLock);
689 
690 	struct chain* chain
691 		= chain::Lookup(sDatalinkProtocolChains, family, type, 0);
692 	if (chain != NULL)
693 		return B_OK;
694 
695 	va_list modules;
696 	va_start(modules, type);
697 
698 	chain = chain::Add(sDatalinkProtocolChains, family, type, 0, modules);
699 
700 	va_end(modules);
701 
702 	if (chain == NULL)
703 		return B_NO_MEMORY;
704 
705 	// Add datalink interface protocol as the last protocol in the chain; it's
706 	// name stays unset, so that it won't be part of the release/acquire process.
707 
708 	uint32 count = 0;
709 	while (chain->modules[count] != NULL) {
710 		count++;
711 	}
712 
713 	chain->infos[count] = (module_info*)&gDatalinkInterfaceProtocolModule;
714 	return B_OK;
715 }
716 
717 
718 static status_t
719 register_domain_receiving_protocol(int family, int type, const char* moduleName)
720 {
721 	TRACE(("register_domain_receiving_protocol(%d.%d, %s)\n", family, type,
722 		moduleName));
723 
724 	MutexLocker _(sChainLock);
725 
726 	struct chain* chain
727 		= chain::Lookup(sReceivingProtocolChains, family, type, 0);
728 	if (chain != NULL)
729 		return B_OK;
730 
731 	chain = chain::Add(sReceivingProtocolChains, family, type, 0, moduleName,
732 		NULL);
733 	if (chain == NULL)
734 		return B_NO_MEMORY;
735 
736 	return B_OK;
737 }
738 
739 
740 static void
741 scan_modules(const char* path)
742 {
743 	void* cookie = open_module_list(path);
744 	if (cookie == NULL)
745 		return;
746 
747 	Vector<module_info*> modules;
748 	while (true) {
749 		char name[B_FILE_NAME_LENGTH];
750 		size_t length = sizeof(name);
751 		if (read_next_module_name(cookie, name, &length) != B_OK)
752 			break;
753 
754 		TRACE(("scan %s\n", name));
755 
756 		// we don't need the module right now, but we give it a chance
757 		// to register itself
758 		module_info* module;
759 		if (get_module(name, &module) == B_OK)
760 			modules.Add(module);
761 	}
762 
763 	close_module_list(cookie);
764 
765 	// We don't need the modules right now, so put them all.
766 	// (This is done at the end to avoid repeated loading/unloading of dependencies.)
767 	for (int32 i = 0; i < modules.Count(); i++)
768 		put_module(modules[i]->name);
769 }
770 
771 
772 status_t
773 init_stack()
774 {
775 	status_t status = init_domains();
776 	if (status != B_OK)
777 		return status;
778 
779 	status = init_interfaces();
780 	if (status != B_OK)
781 		goto err1;
782 
783 	status = init_device_interfaces();
784 	if (status != B_OK)
785 		goto err2;
786 
787 	status = init_timers();
788 	if (status != B_OK)
789 		goto err3;
790 
791 	status = init_notifications();
792 	if (status < B_OK) {
793 		// If this fails, it just means there won't be any notifications,
794 		// it's not a fatal error.
795 		dprintf("networking stack notifications could not be initialized: %s\n",
796 			strerror(status));
797 	}
798 
799 	module_info* dummy;
800 	status = get_module(NET_SOCKET_MODULE_NAME, &dummy);
801 	if (status != B_OK)
802 		goto err4;
803 
804 	mutex_init(&sChainLock, "net chains");
805 	mutex_init(&sInitializeChainLock, "net intialize chains");
806 
807 	sFamilies = new(std::nothrow) FamilyTable();
808 	if (sFamilies == NULL || sFamilies->Init(10) != B_OK) {
809 		status = B_NO_MEMORY;
810 		goto err5;
811 	}
812 
813 	sProtocolChains = new(std::nothrow) ChainTable();
814 	if (sProtocolChains == NULL || sProtocolChains->Init(10) != B_OK) {
815 		status = B_NO_MEMORY;
816 		goto err6;
817 	}
818 
819 	sDatalinkProtocolChains = new(std::nothrow) ChainTable();
820 	if (sDatalinkProtocolChains == NULL
821 			|| sDatalinkProtocolChains->Init(10) != B_OK) {
822 		status = B_NO_MEMORY;
823 		goto err7;
824 	}
825 
826 	sReceivingProtocolChains = new(std::nothrow) ChainTable();
827 	if (sReceivingProtocolChains == NULL
828 			|| sReceivingProtocolChains->Init(10) != B_OK) {
829 		status = B_NO_MEMORY;
830 		goto err8;
831 	}
832 
833 	sInitialized = true;
834 
835 	link_init();
836 	scan_modules("network/protocols");
837 	scan_modules("network/datalink_protocols");
838 
839 	// TODO: for now!
840 	register_domain_datalink_protocols(AF_INET, IFT_LOOP,
841 		"network/datalink_protocols/loopback_frame/v1", NULL);
842 	register_domain_datalink_protocols(AF_INET, IFT_TUNNEL,
843 		"network/datalink_protocols/loopback_frame/v1", NULL);
844 #if 0 // PPP is not (currently) included in the build
845 	register_domain_datalink_protocols(AF_INET, IFT_PPP,
846 		"network/datalink_protocols/ppp_frame/v1", NULL);
847 #endif
848 	register_domain_datalink_protocols(AF_INET6, IFT_LOOP,
849 		"network/datalink_protocols/loopback_frame/v1", NULL);
850 	register_domain_datalink_protocols(AF_INET, IFT_ETHER,
851 		"network/datalink_protocols/arp/v1",
852 		"network/datalink_protocols/ethernet_frame/v1",
853 		NULL);
854 	register_domain_datalink_protocols(AF_INET6, IFT_ETHER,
855 		"network/datalink_protocols/ipv6_datagram/v1",
856 		"network/datalink_protocols/ethernet_frame/v1",
857 		NULL);
858 
859 	return B_OK;
860 
861 err8:
862 	delete sDatalinkProtocolChains;
863 err7:
864 	delete sProtocolChains;
865 err6:
866 	delete sFamilies;
867 err5:
868 	mutex_destroy(&sInitializeChainLock);
869 	mutex_destroy(&sChainLock);
870 err4:
871 	uninit_timers();
872 err3:
873 	uninit_device_interfaces();
874 err2:
875 	uninit_interfaces();
876 err1:
877 	uninit_domains();
878 	return status;
879 }
880 
881 
882 status_t
883 uninit_stack()
884 {
885 	TRACE(("Unloading network stack\n"));
886 
887 	put_module(NET_SOCKET_MODULE_NAME);
888 	uninit_notifications();
889 
890 	// remove chains and families
891 
892 	chain::DeleteChains(sProtocolChains);
893 	chain::DeleteChains(sDatalinkProtocolChains);
894 	chain::DeleteChains(sReceivingProtocolChains);
895 
896 	mutex_destroy(&sChainLock);
897 	mutex_destroy(&sInitializeChainLock);
898 
899 	uninit_timers();
900 	uninit_device_interfaces();
901 	uninit_interfaces();
902 	uninit_domains();
903 
904 	struct family* current;
905 	current = sFamilies->Clear(true);
906 	while (current) {
907 		struct family* next = current->next;
908 
909 		delete current;
910 		current = next;
911 	}
912 
913 	delete sProtocolChains;
914 	delete sDatalinkProtocolChains;
915 	delete sReceivingProtocolChains;
916 	delete sFamilies;
917 
918 	return B_OK;
919 }
920 
921 
922 static status_t
923 stack_std_ops(int32 op, ...)
924 {
925 	switch (op) {
926 		case B_MODULE_INIT:
927 			return sInitialized ? B_OK : B_BUSY;
928 		case B_MODULE_UNINIT:
929 			return B_OK;
930 
931 		default:
932 			return B_ERROR;
933 	}
934 }
935 
936 
937 net_stack_module_info gNetStackModule = {
938 	{
939 		NET_STACK_MODULE_NAME,
940 		0,
941 		stack_std_ops
942 	},
943 
944 	register_domain,
945 	unregister_domain,
946 	get_domain,
947 
948 	register_domain_protocols,
949 	register_domain_datalink_protocols,
950 	register_domain_receiving_protocol,
951 
952 	get_domain_receiving_protocol,
953 	put_domain_receiving_protocol,
954 
955 	register_device_deframer,
956 	unregister_device_deframer,
957 	register_domain_device_handler,
958 	register_device_handler,
959 	unregister_device_handler,
960 	register_device_monitor,
961 	unregister_device_monitor,
962 	device_link_changed,
963 	device_removed,
964 	device_enqueue_buffer,
965 
966 	notify_socket,
967 
968 	checksum,
969 
970 	init_fifo,
971 	uninit_fifo,
972 	fifo_enqueue_buffer,
973 	fifo_dequeue_buffer,
974 	clear_fifo,
975 	fifo_socket_enqueue_buffer,
976 
977 	init_timer,
978 	set_timer,
979 	cancel_timer,
980 	wait_for_timer,
981 	is_timer_active,
982 	is_timer_running,
983 
984 	is_syscall,
985 	is_restarted_syscall,
986 	store_syscall_restart_timeout,
987 	restore_syscall_restart_timeout,
988 
989 	create_ancillary_data_container,
990 	delete_ancillary_data_container,
991 	add_ancillary_data,
992 	remove_ancillary_data,
993 	move_ancillary_data,
994 	next_ancillary_data
995 };
996 
997 module_info* modules[] = {
998 	(module_info*)&gNetStackModule,
999 	(module_info*)&gNetBufferModule,
1000 	(module_info*)&gNetSocketModule,
1001 	(module_info*)&gNetDatalinkModule,
1002 	(module_info*)&gLinkModule,
1003 	(module_info*)&gNetStackInterfaceModule,
1004 	NULL
1005 };
1006