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