1 /* 2 * Copyright 2006-2009, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Axel Dörfler, axeld@pinc-software.de 7 * Hugo Santos, hugosantos@gmail.com 8 */ 9 10 11 #include "datalink.h" 12 #include "domains.h" 13 #include "interfaces.h" 14 #include "routes.h" 15 #include "stack_private.h" 16 #include "utility.h" 17 18 #include <net_device.h> 19 #include <KernelExport.h> 20 #include <util/AutoLock.h> 21 22 #include <net/if.h> 23 #include <net/if_media.h> 24 #include <net/route.h> 25 #include <sys/sockio.h> 26 27 #include <new> 28 #include <stdlib.h> 29 #include <stdio.h> 30 #include <string.h> 31 32 33 struct datalink_protocol : net_protocol { 34 struct net_domain_private* domain; 35 }; 36 37 struct interface_protocol : net_datalink_protocol { 38 struct net_device_module_info* device_module; 39 struct net_device* device; 40 }; 41 42 43 /*! A service thread for each device interface. It just reads as many packets 44 as availabe, deframes them, and puts them into the receive queue of the 45 device interface. 46 */ 47 static status_t 48 device_reader_thread(void* _interface) 49 { 50 net_device_interface* interface = (net_device_interface*)_interface; 51 net_device* device = interface->device; 52 status_t status = B_OK; 53 54 RecursiveLocker locker(interface->receive_lock); 55 56 while ((device->flags & IFF_UP) != 0) { 57 locker.Unlock(); 58 59 net_buffer* buffer; 60 status = device->module->receive_data(device, &buffer); 61 62 locker.Lock(); 63 64 if (status == B_OK) { 65 // feed device monitors 66 DeviceMonitorList::Iterator iterator = 67 interface->monitor_funcs.GetIterator(); 68 while (net_device_monitor* monitor = iterator.Next()) { 69 monitor->receive(monitor, buffer); 70 } 71 72 buffer->interface = NULL; 73 buffer->type = interface->deframe_func(interface->device, buffer); 74 if (buffer->type < 0) { 75 gNetBufferModule.free(buffer); 76 continue; 77 } 78 79 fifo_enqueue_buffer(&interface->receive_queue, buffer); 80 } else { 81 // In case of error, give the other threads some 82 // time to run since this is a high priority time thread. 83 snooze(10000); 84 } 85 } 86 87 return status; 88 } 89 90 91 static struct sockaddr** 92 interface_address(net_interface* interface, int32 option) 93 { 94 switch (option) { 95 case SIOCSIFADDR: 96 case SIOCGIFADDR: 97 return &interface->address; 98 99 case SIOCSIFNETMASK: 100 case SIOCGIFNETMASK: 101 return &interface->mask; 102 103 case SIOCSIFBRDADDR: 104 case SIOCSIFDSTADDR: 105 case SIOCGIFBRDADDR: 106 case SIOCGIFDSTADDR: 107 return &interface->destination; 108 109 default: 110 return NULL; 111 } 112 } 113 114 115 /*! Removes the default routes as set by add_default_routes() again. */ 116 static void 117 remove_default_routes(net_interface_private* interface, int32 option) 118 { 119 net_route route; 120 route.destination = interface->address; 121 route.gateway = NULL; 122 route.interface = interface; 123 124 if (interface->mask != NULL 125 && (option == SIOCSIFNETMASK || option == SIOCSIFADDR)) { 126 route.mask = interface->mask; 127 route.flags = 0; 128 remove_route(interface->domain, &route); 129 } 130 131 if (option == SIOCSIFADDR) { 132 route.mask = NULL; 133 route.flags = RTF_LOCAL | RTF_HOST; 134 remove_route(interface->domain, &route); 135 } 136 } 137 138 139 /*! Adds the default routes that every interface needs, ie. the local host 140 route, and one for the subnet (if set). 141 */ 142 static void 143 add_default_routes(net_interface_private* interface, int32 option) 144 { 145 net_route route; 146 route.destination = interface->address; 147 route.gateway = NULL; 148 route.interface = interface; 149 150 if (interface->mask != NULL 151 && (option == SIOCSIFNETMASK || option == SIOCSIFADDR)) { 152 route.mask = interface->mask; 153 route.flags = 0; 154 add_route(interface->domain, &route); 155 } 156 157 if (option == SIOCSIFADDR) { 158 route.mask = NULL; 159 route.flags = RTF_LOCAL | RTF_HOST; 160 add_route(interface->domain, &route); 161 } 162 } 163 164 165 static sockaddr* 166 reallocate_address(sockaddr** _address, uint32 size) 167 { 168 sockaddr* address = *_address; 169 170 size = max_c(size, sizeof(struct sockaddr)); 171 if (address != NULL && address->sa_len >= size) 172 return address; 173 174 address = (sockaddr*)malloc(size); 175 if (address == NULL) 176 return NULL; 177 178 free(*_address); 179 *_address = address; 180 181 return address; 182 } 183 184 185 static status_t 186 datalink_control_interface(net_domain_private* domain, int32 option, 187 void* value, size_t* _length, size_t expected, bool getByName) 188 { 189 if (*_length < expected) 190 return B_BAD_VALUE; 191 192 ifreq request; 193 memset(&request, 0, sizeof(request)); 194 195 if (user_memcpy(&request, value, expected) < B_OK) 196 return B_BAD_ADDRESS; 197 198 RecursiveLocker _(domain->lock); 199 net_interface* interface = NULL; 200 201 if (getByName) 202 interface = find_interface(domain, request.ifr_name); 203 else 204 interface = find_interface(domain, request.ifr_index); 205 206 status_t status = interface == NULL ? ENODEV : B_OK; 207 208 switch (option) { 209 case SIOCGIFINDEX: 210 if (interface) 211 request.ifr_index = interface->index; 212 else 213 request.ifr_index = 0; 214 break; 215 216 case SIOCGIFNAME: 217 if (interface) 218 strlcpy(request.ifr_name, interface->name, IF_NAMESIZE); 219 else 220 status = B_BAD_VALUE; // TODO: should be ENXIO? 221 break; 222 } 223 224 if (status < B_OK) 225 return status; 226 227 return user_memcpy(value, &request, sizeof(ifreq)); 228 } 229 230 231 // #pragma mark - datalink module 232 233 234 status_t 235 datalink_control(net_domain* _domain, int32 option, void* value, 236 size_t* _length) 237 { 238 net_domain_private* domain = (net_domain_private*)_domain; 239 if (domain == NULL || domain->family == AF_LINK) { 240 // the AF_LINK family is already handled completely in the link protocol 241 return B_BAD_VALUE; 242 } 243 244 switch (option) { 245 case SIOCGIFINDEX: 246 return datalink_control_interface(domain, option, value, _length, 247 IF_NAMESIZE, true); 248 case SIOCGIFNAME: 249 return datalink_control_interface(domain, option, value, _length, 250 sizeof(ifreq), false); 251 252 case SIOCDIFADDR: 253 case SIOCSIFFLAGS: 254 { 255 struct ifreq request; 256 if (user_memcpy(&request, value, sizeof(struct ifreq)) < B_OK) 257 return B_BAD_ADDRESS; 258 259 return domain_interface_control(domain, option, &request); 260 } 261 262 case SIOCAIFADDR: 263 { 264 // add new interface address 265 struct ifreq request; 266 if (user_memcpy(&request, value, sizeof(struct ifreq)) < B_OK) 267 return B_BAD_ADDRESS; 268 269 return add_interface_to_domain(domain, request); 270 } 271 272 case SIOCGIFCOUNT: 273 { 274 // count number of interfaces 275 struct ifconf config; 276 config.ifc_value = count_domain_interfaces(); 277 278 return user_memcpy(value, &config, sizeof(struct ifconf)); 279 } 280 281 case SIOCGIFCONF: 282 { 283 // retrieve ifreqs for all interfaces 284 struct ifconf config; 285 if (user_memcpy(&config, value, sizeof(struct ifconf)) < B_OK) 286 return B_BAD_ADDRESS; 287 288 status_t result = list_domain_interfaces(config.ifc_buf, 289 (size_t*)&config.ifc_len); 290 if (result != B_OK) 291 return result; 292 293 return user_memcpy(value, &config, sizeof(struct ifconf)); 294 } 295 296 case SIOCGRTSIZE: 297 { 298 // determine size of buffer to hold the routing table 299 struct ifconf config; 300 config.ifc_value = route_table_size(domain); 301 302 return user_memcpy(value, &config, sizeof(struct ifconf)); 303 } 304 case SIOCGRTTABLE: 305 { 306 // retrieve all routes for this domain 307 struct ifconf config; 308 if (user_memcpy(&config, value, sizeof(struct ifconf)) < B_OK) 309 return B_BAD_ADDRESS; 310 311 return list_routes(domain, config.ifc_buf, config.ifc_len); 312 } 313 case SIOCGETRT: 314 return get_route_information(domain, value, *_length); 315 316 default: 317 { 318 // try to pass the request to an existing interface 319 struct ifreq request; 320 if (user_memcpy(&request, value, sizeof(struct ifreq)) < B_OK) 321 return B_BAD_ADDRESS; 322 323 RecursiveLocker _(domain->lock); 324 325 net_interface* interface = find_interface(domain, 326 request.ifr_name); 327 if (interface == NULL) 328 return B_BAD_VALUE; 329 330 // pass the request into the datalink protocol stack 331 return interface->first_info->control( 332 interface->first_protocol, option, value, *_length); 333 } 334 } 335 return B_BAD_VALUE; 336 } 337 338 339 status_t 340 datalink_send_data(struct net_route* route, net_buffer* buffer) 341 { 342 net_interface_private* interface = 343 (net_interface_private*)route->interface; 344 345 //dprintf("send buffer (%ld bytes) to interface %s (route flags %lx)\n", 346 // buffer->size, interface->name, route->flags); 347 348 if (route->flags & RTF_REJECT) 349 return ENETUNREACH; 350 351 if (route->flags & RTF_LOCAL) { 352 // we set the interface here so the buffer is delivered directly 353 // to the domain in interfaces.cpp:device_consumer_thread() 354 buffer->interface = interface; 355 // this one goes back to the domain directly 356 return fifo_enqueue_buffer( 357 &interface->device_interface->receive_queue, buffer); 358 } 359 360 if (route->flags & RTF_GATEWAY) { 361 // this route involves a gateway, we need to use the gateway address 362 // instead of the destination address: 363 if (route->gateway == NULL) 364 return B_MISMATCHED_VALUES; 365 memcpy(buffer->destination, route->gateway, route->gateway->sa_len); 366 } 367 368 // this goes out to the datalink protocols 369 return interface->first_info->send_data(interface->first_protocol, buffer); 370 } 371 372 373 status_t 374 datalink_send_datagram(net_protocol* protocol, net_domain* domain, 375 net_buffer* buffer) 376 { 377 if (protocol == NULL && domain == NULL) 378 return B_BAD_VALUE; 379 380 net_protocol_module_info* module = protocol ? protocol->module 381 : domain->module; 382 383 if (domain == NULL) 384 domain = protocol->module->get_domain(protocol); 385 386 net_route* route = NULL; 387 status_t status; 388 if (protocol != NULL && protocol->socket->bound_to_device > 0) { 389 status = get_device_route(domain, protocol->socket->bound_to_device, 390 &route); 391 } else 392 status = get_buffer_route(domain, buffer, &route); 393 if (status < B_OK) 394 return status; 395 396 status = module->send_routed_data(protocol, route, buffer); 397 put_route(domain, route); 398 return status; 399 } 400 401 402 /*! 403 Tests if \a address is a local address in the domain. 404 \param _interface will be set to the interface belonging to that address 405 if non-NULL. 406 \param _matchedType will be set to either zero or MSG_BCAST if non-NULL. 407 */ 408 bool 409 datalink_is_local_address(net_domain* _domain, const struct sockaddr* address, 410 net_interface** _interface, uint32* _matchedType) 411 { 412 net_domain_private* domain = (net_domain_private*)_domain; 413 if (domain == NULL || address == NULL) 414 return false; 415 416 RecursiveLocker locker(domain->lock); 417 418 net_interface* interface = NULL; 419 net_interface* fallback = NULL; 420 uint32 matchedType = 0; 421 422 while (true) { 423 interface = (net_interface*)list_get_next_item( 424 &domain->interfaces, interface); 425 if (interface == NULL) 426 break; 427 if (interface->address == NULL) { 428 fallback = interface; 429 continue; 430 } 431 432 // check for matching unicast address first 433 if (domain->address_module->equal_addresses(interface->address, address)) 434 break; 435 436 // check for matching broadcast address if interface supports 437 // broadcasting (IFF_BROADCAST is a link-level flag, so it is 438 // a property of the device) 439 if ((interface->device->flags & IFF_BROADCAST) 440 && domain->address_module->equal_addresses(interface->destination, 441 address)) { 442 matchedType = MSG_BCAST; 443 break; 444 } 445 } 446 447 if (interface == NULL) { 448 interface = fallback; 449 if (interface == NULL) 450 return false; 451 } 452 453 if (_interface != NULL) 454 *_interface = interface; 455 if (_matchedType != NULL) 456 *_matchedType = matchedType; 457 return true; 458 } 459 460 461 net_interface* 462 datalink_get_interface_with_address(net_domain* _domain, 463 const sockaddr* address) 464 { 465 net_domain_private* domain = (net_domain_private*)_domain; 466 if (domain == NULL) 467 return NULL; 468 469 RecursiveLocker _(domain->lock); 470 471 net_interface* interface = NULL; 472 473 while (true) { 474 interface = (net_interface*)list_get_next_item( 475 &domain->interfaces, interface); 476 if (interface == NULL) 477 break; 478 479 if (address == NULL) 480 return interface; 481 482 if (domain->address_module->equal_addresses(interface->address, 483 address)) 484 return interface; 485 } 486 487 return NULL; 488 } 489 490 491 net_interface* 492 datalink_get_interface(net_domain* domain, uint32 index) 493 { 494 if (index == 0) 495 return datalink_get_interface_with_address(domain, NULL); 496 497 return find_interface(domain, index); 498 } 499 500 501 static status_t 502 datalink_std_ops(int32 op, ...) 503 { 504 switch (op) { 505 case B_MODULE_INIT: 506 case B_MODULE_UNINIT: 507 return B_OK; 508 509 default: 510 return B_ERROR; 511 } 512 } 513 514 515 // #pragma mark - net_datalink_protocol 516 517 518 status_t 519 interface_protocol_init(struct net_interface* _interface, 520 net_datalink_protocol** _protocol) 521 { 522 net_interface_private* interface = (net_interface_private*)_interface; 523 524 interface_protocol* protocol = new (std::nothrow) interface_protocol; 525 if (protocol == NULL) 526 return B_NO_MEMORY; 527 528 protocol->device_module = interface->device->module; 529 protocol->device = interface->device; 530 531 *_protocol = protocol; 532 return B_OK; 533 } 534 535 536 status_t 537 interface_protocol_uninit(net_datalink_protocol* protocol) 538 { 539 delete protocol; 540 return B_OK; 541 } 542 543 544 status_t 545 interface_protocol_send_data(net_datalink_protocol* _protocol, 546 net_buffer* buffer) 547 { 548 interface_protocol* protocol = (interface_protocol*)_protocol; 549 net_interface_private* interface 550 = (net_interface_private*)protocol->interface; 551 552 // TODO: Need to think about this locking. We can't obtain the 553 // RX Lock here (nor would it make sense) as the ARP 554 // module calls send_data() with it's lock held (similiar 555 // to the domain lock, which would violate the locking 556 // protocol). 557 558 DeviceMonitorList::Iterator iterator = 559 interface->device_interface->monitor_funcs.GetIterator(); 560 while (iterator.HasNext()) { 561 net_device_monitor* monitor = iterator.Next(); 562 monitor->receive(monitor, buffer); 563 } 564 565 return protocol->device_module->send_data(protocol->device, buffer); 566 } 567 568 569 status_t 570 interface_protocol_up(net_datalink_protocol* _protocol) 571 { 572 interface_protocol* protocol = (interface_protocol*)_protocol; 573 net_device_interface* deviceInterface = 574 ((net_interface_private*)protocol->interface)->device_interface; 575 net_device* device = protocol->device; 576 577 // This function is called with the RX lock held. 578 579 if (deviceInterface->up_count != 0) { 580 deviceInterface->up_count++; 581 return B_OK; 582 } 583 584 status_t status = protocol->device_module->up(device); 585 if (status < B_OK) 586 return status; 587 588 if (device->module->receive_data != NULL) { 589 // give the thread a nice name 590 char name[B_OS_NAME_LENGTH]; 591 snprintf(name, sizeof(name), "%s reader", device->name); 592 593 deviceInterface->reader_thread = 594 spawn_kernel_thread(device_reader_thread, name, 595 B_REAL_TIME_DISPLAY_PRIORITY - 10, deviceInterface); 596 if (deviceInterface->reader_thread < B_OK) 597 return deviceInterface->reader_thread; 598 } 599 600 device->flags |= IFF_UP; 601 602 if (device->module->receive_data != NULL) 603 resume_thread(deviceInterface->reader_thread); 604 605 deviceInterface->up_count = 1; 606 return B_OK; 607 } 608 609 610 void 611 interface_protocol_down(net_datalink_protocol* _protocol) 612 { 613 interface_protocol* protocol = (interface_protocol*)_protocol; 614 net_device_interface* deviceInterface = 615 ((net_interface_private*)protocol->interface)->device_interface; 616 617 // This function is called with the RX lock held. 618 if (deviceInterface->up_count == 0) 619 return; 620 621 deviceInterface->up_count--; 622 623 domain_interface_went_down(protocol->interface); 624 625 if (deviceInterface->up_count > 0) 626 return; 627 628 down_device_interface(deviceInterface); 629 } 630 631 632 status_t 633 interface_protocol_control(net_datalink_protocol* _protocol, int32 option, 634 void* argument, size_t length) 635 { 636 interface_protocol* protocol = (interface_protocol*)_protocol; 637 net_interface_private* interface 638 = (net_interface_private*)protocol->interface; 639 640 switch (option) { 641 case SIOCSIFADDR: 642 case SIOCSIFNETMASK: 643 case SIOCSIFBRDADDR: 644 case SIOCSIFDSTADDR: 645 { 646 // set logical interface address 647 struct ifreq request; 648 if (user_memcpy(&request, argument, sizeof(struct ifreq)) < B_OK) 649 return B_BAD_ADDRESS; 650 651 sockaddr** _address = interface_address(interface, option); 652 if (_address == NULL) 653 return B_BAD_VALUE; 654 655 // allocate new address if needed 656 sockaddr* address = reallocate_address(_address, 657 request.ifr_addr.sa_len); 658 659 // copy new address over 660 if (address != NULL) { 661 remove_default_routes(interface, option); 662 memcpy(address, &request.ifr_addr, request.ifr_addr.sa_len); 663 664 if (option == SIOCSIFADDR || option == SIOCSIFNETMASK) { 665 // reset netmask and broadcast addresses to defaults 666 sockaddr* netmask = NULL; 667 sockaddr* oldNetmask = NULL; 668 if (option == SIOCSIFADDR) { 669 netmask = reallocate_address(&interface->mask, 670 request.ifr_addr.sa_len); 671 } else 672 oldNetmask = address; 673 674 sockaddr* broadcast = reallocate_address( 675 &interface->destination, request.ifr_addr.sa_len); 676 677 interface->domain->address_module->set_to_defaults( 678 netmask, broadcast, interface->address, oldNetmask); 679 } 680 681 add_default_routes(interface, option); 682 } 683 684 return address != NULL ? B_OK : B_NO_MEMORY; 685 } 686 687 case SIOCGIFADDR: 688 case SIOCGIFNETMASK: 689 case SIOCGIFBRDADDR: 690 case SIOCGIFDSTADDR: 691 { 692 // get logical interface address 693 sockaddr** _address = interface_address(interface, option); 694 if (_address == NULL) 695 return B_BAD_VALUE; 696 697 struct ifreq request; 698 699 sockaddr* address = *_address; 700 if (address != NULL) 701 memcpy(&request.ifr_addr, address, address->sa_len); 702 else { 703 request.ifr_addr.sa_len = 2; 704 request.ifr_addr.sa_family = AF_UNSPEC; 705 } 706 707 // copy address over 708 return user_memcpy(&((struct ifreq*)argument)->ifr_addr, 709 &request.ifr_addr, request.ifr_addr.sa_len); 710 } 711 712 case SIOCGIFFLAGS: 713 { 714 // get flags 715 struct ifreq request; 716 request.ifr_flags = interface->flags | interface->device->flags; 717 718 return user_memcpy(&((struct ifreq*)argument)->ifr_flags, 719 &request.ifr_flags, sizeof(request.ifr_flags)); 720 } 721 722 case SIOCGIFPARAM: 723 { 724 // get interface parameter 725 struct ifreq request; 726 strlcpy(request.ifr_parameter.base_name, interface->base_name, IF_NAMESIZE); 727 strlcpy(request.ifr_parameter.device, 728 interface->device_interface->device->name, IF_NAMESIZE); 729 request.ifr_parameter.sub_type = 0; 730 // TODO: for now, we ignore the sub type... 731 732 return user_memcpy(&((struct ifreq*)argument)->ifr_parameter, 733 &request.ifr_parameter, sizeof(request.ifr_parameter)); 734 } 735 736 case SIOCGIFSTATS: 737 { 738 // get stats 739 return user_memcpy(&((struct ifreq*)argument)->ifr_stats, 740 &interface->device_interface->device->stats, 741 sizeof(struct ifreq_stats)); 742 } 743 744 case SIOCGIFTYPE: 745 { 746 // get type 747 struct ifreq request; 748 request.ifr_type = interface->type; 749 750 return user_memcpy(&((struct ifreq*)argument)->ifr_type, 751 &request.ifr_type, sizeof(request.ifr_type)); 752 } 753 754 case SIOCGIFMTU: 755 { 756 // get MTU 757 struct ifreq request; 758 request.ifr_mtu = interface->mtu; 759 760 return user_memcpy(&((struct ifreq*)argument)->ifr_mtu, 761 &request.ifr_mtu, sizeof(request.ifr_mtu)); 762 } 763 case SIOCSIFMTU: 764 { 765 // set MTU 766 struct ifreq request; 767 if (user_memcpy(&request, argument, sizeof(struct ifreq)) < B_OK) 768 return B_BAD_ADDRESS; 769 770 // check for valid bounds 771 if (request.ifr_mtu < 100 772 || (uint32)request.ifr_mtu > interface->device->mtu) 773 return B_BAD_VALUE; 774 775 interface->mtu = request.ifr_mtu; 776 return B_OK; 777 } 778 779 case SIOCSIFMEDIA: 780 { 781 // set media 782 struct ifreq request; 783 if (user_memcpy(&request, argument, sizeof(struct ifreq)) < B_OK) 784 return B_BAD_ADDRESS; 785 786 return interface->device_interface->device->module->set_media( 787 interface->device, request.ifr_media); 788 } 789 case SIOCGIFMEDIA: 790 { 791 // get media 792 struct ifreq request; 793 request.ifr_media = interface->device->media; 794 795 return user_memcpy(&((struct ifreq*)argument)->ifr_media, 796 &request.ifr_media, sizeof(request.ifr_media)); 797 } 798 799 case SIOCGIFMETRIC: 800 { 801 // get metric 802 struct ifreq request; 803 request.ifr_metric = interface->metric; 804 805 return user_memcpy(&((struct ifreq*)argument)->ifr_metric, 806 &request.ifr_metric, sizeof(request.ifr_metric)); 807 } 808 case SIOCSIFMETRIC: 809 { 810 // set metric 811 struct ifreq request; 812 if (user_memcpy(&request, argument, sizeof(struct ifreq)) < B_OK) 813 return B_BAD_ADDRESS; 814 815 interface->metric = request.ifr_metric; 816 return B_OK; 817 } 818 819 case SIOCADDRT: 820 case SIOCDELRT: 821 // interface related route options 822 return control_routes(interface, option, argument, length); 823 } 824 825 return protocol->device_module->control(protocol->device, 826 option, argument, length); 827 } 828 829 830 static status_t 831 interface_protocol_join_multicast(net_datalink_protocol* _protocol, 832 const sockaddr* address) 833 { 834 interface_protocol* protocol = (interface_protocol*)_protocol; 835 836 return protocol->device_module->add_multicast(protocol->device, address); 837 } 838 839 840 static status_t 841 interface_protocol_leave_multicast(net_datalink_protocol* _protocol, 842 const sockaddr* address) 843 { 844 interface_protocol* protocol = (interface_protocol*)_protocol; 845 846 return protocol->device_module->remove_multicast(protocol->device, 847 address); 848 } 849 850 851 net_datalink_module_info gNetDatalinkModule = { 852 { 853 NET_DATALINK_MODULE_NAME, 854 0, 855 datalink_std_ops 856 }, 857 858 datalink_control, 859 datalink_send_data, 860 datalink_send_datagram, 861 datalink_is_local_address, 862 datalink_get_interface, 863 datalink_get_interface_with_address, 864 865 add_route, 866 remove_route, 867 get_route, 868 get_buffer_route, 869 put_route, 870 register_route_info, 871 unregister_route_info, 872 update_route_info 873 }; 874 875 net_datalink_protocol_module_info gDatalinkInterfaceProtocolModule = { 876 { 877 NULL, 878 0, 879 NULL 880 }, 881 interface_protocol_init, 882 interface_protocol_uninit, 883 interface_protocol_send_data, 884 interface_protocol_up, 885 interface_protocol_down, 886 interface_protocol_control, 887 interface_protocol_join_multicast, 888 interface_protocol_leave_multicast, 889 }; 890