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
HashKeyChainHash109 size_t HashKey(KeyType key) const
110 {
111 return HASH(&key);
112 }
113
HashChainHash114 size_t Hash(ValueType* value) const
115 {
116 return HASH(value);
117 }
118
119 #undef HASH
120
CompareChainHash121 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
GetLinkChainHash131 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
HashKeyFamilyHash141 size_t HashKey(KeyType key) const
142 {
143 return key;
144 }
145
HashFamilyHash146 size_t Hash(ValueType* value) const
147 {
148 return value->type;
149 }
150
CompareFamilyHash151 bool Compare(KeyType key, ValueType* family) const
152 {
153 return family->type == key;
154 }
155
GetLinkFamilyHash156 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
family(int _type)177 family::family(int _type)
178 :
179 type(_type),
180 ref_count(0)
181 {
182 }
183
184
185 void
Acquire()186 family::Acquire()
187 {
188 atomic_add(&ref_count, 1);
189 }
190
191
192 void
Release()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*
Lookup(int type)209 family::Lookup(int type)
210 {
211 return sFamilies->Lookup(type);
212 }
213
214
215 /*static*/ struct family*
Add(int type)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
chain(int _family,int _type,int _protocol)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
~chain()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
Acquire()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
Release()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
Uninitialize()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*
Lookup(ChainTable * chains,int family,int type,int protocol)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*
Add(ChainTable * chains,int family,int type,int protocol,va_list modules)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*
Add(ChainTable * chains,int family,int type,int protocol,...)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
DeleteChains(ChainTable * chains)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
uninit_domain_protocols(net_socket * socket)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
get_domain_protocols(net_socket * socket)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
put_domain_protocols(net_socket * socket)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
uninit_domain_datalink_protocols(domain_datalink * datalink)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
get_domain_datalink_protocols(Interface * interface,net_domain * domain)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
put_domain_datalink_protocols(Interface * interface,net_domain * domain)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
get_domain_receiving_protocol(net_domain * _domain,uint32 type,net_protocol_module_info ** _module)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
put_domain_receiving_protocol(net_domain * _domain,uint32 type)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
register_domain_protocols(int family,int type,int protocol,...)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
register_domain_datalink_protocols(int family,int type,...)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
register_domain_receiving_protocol(int family,int type,const char * moduleName)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
scan_modules(const char * path)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
init_stack()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
uninit_stack()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
stack_std_ops(int32 op,...)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