1 /* 2 * Copyright 2009, Colin Günther, coling@gmx.de. 3 * Copyright 2007-2009, Axel Dörfler, axeld@pinc-software.de. 4 * Copyright 2007, Hugo Santos. All Rights Reserved. 5 * Copyright 2004, Marcus Overhagen. All Rights Reserved. 6 * 7 * Distributed under the terms of the MIT License. 8 */ 9 10 11 #include "device.h" 12 13 #include <stdio.h> 14 #include <net/if_types.h> 15 #include <sys/sockio.h> 16 17 #include <compat/sys/bus.h> 18 #include <compat/sys/kernel.h> 19 #include <compat/sys/taskqueue.h> 20 21 #include <compat/net/bpf.h> 22 #include <compat/net/ethernet.h> 23 #include <compat/net/if.h> 24 #include <compat/net/if_arp.h> 25 #include <compat/net/if_media.h> 26 #include <compat/net/if_var.h> 27 #include <compat/net/if_vlan_var.h> 28 #include <compat/sys/malloc.h> 29 30 31 32 int ifqmaxlen = IFQ_MAXLEN; 33 34 static void if_input_default(struct ifnet *, struct mbuf *); 35 static int if_requestencap_default(struct ifnet *, struct if_encap_req *); 36 37 38 39 #define IFNET_HOLD (void *)(uintptr_t)(-1) 40 41 42 static void 43 insert_into_device_name_list(struct ifnet * ifp) 44 { 45 int i; 46 for (i = 0; i < MAX_DEVICES; i++) { 47 if (gDeviceNameList[i] == NULL) { 48 gDeviceNameList[i] = ifp->device_name; 49 return; 50 } 51 } 52 53 panic("too many devices"); 54 } 55 56 57 static void 58 remove_from_device_name_list(struct ifnet * ifp) 59 { 60 int i; 61 for (i = 0; i < MAX_DEVICES; i++) { 62 if (ifp->device_name == gDeviceNameList[i]) { 63 int last; 64 for (last = i + 1; last < MAX_DEVICES; last++) { 65 if (gDeviceNameList[last] == NULL) 66 break; 67 } 68 last--; 69 70 if (i == last) 71 gDeviceNameList[i] = NULL; 72 else { 73 // switch positions with the last entry 74 gDeviceNameList[i] = gDeviceNameList[last]; 75 gDeviceNameList[last] = NULL; 76 } 77 break; 78 } 79 } 80 } 81 82 83 static struct ifnet * 84 ifnet_byindex_locked(u_int idx) 85 { 86 struct ifnet *ifp; 87 88 ifp = gDevices[idx]; 89 90 return (ifp); 91 } 92 93 94 if_t 95 ifnet_byindex(u_int idx) 96 { 97 struct ifnet *ifp; 98 99 IFNET_RLOCK_NOSLEEP(); 100 ifp = ifnet_byindex_locked(idx); 101 IFNET_RUNLOCK_NOSLEEP(); 102 103 return (ifp); 104 } 105 106 107 static void 108 ifnet_setbyindex_locked(u_short idx, struct ifnet *ifp) 109 { 110 gDevices[idx] = ifp; 111 } 112 113 114 static void 115 ifnet_setbyindex(u_short idx, struct ifnet *ifp) 116 { 117 IFNET_WLOCK(); 118 ifnet_setbyindex_locked(idx, ifp); 119 IFNET_WUNLOCK(); 120 } 121 122 123 static int 124 ifindex_alloc_locked(u_short *idxp) 125 { 126 u_short index; 127 128 for (index = 0; index < MAX_DEVICES; index++) { 129 if (gDevices[index] == NULL) { 130 break; 131 } 132 } 133 134 if (index == MAX_DEVICES) 135 return ENOSPC; 136 137 gDeviceCount++; 138 *idxp = index; 139 140 return ENOERR; 141 } 142 143 144 static void 145 ifindex_free_locked(u_short idx) 146 { 147 gDevices[idx] = NULL; 148 gDeviceCount--; 149 } 150 151 152 int 153 if_alloc_inplace(struct ifnet *ifp, u_char type) 154 { 155 char semName[64]; 156 u_short index; 157 158 snprintf(semName, sizeof(semName), "%s receive", gDriverName); 159 160 ifp->receive_sem = create_sem(0, semName); 161 if (ifp->receive_sem < B_OK) 162 return ifp->receive_sem; 163 164 ifp->link_state_sem = -1; 165 ifp->open_count = 0; 166 ifp->flags = 0; 167 ifp->if_type = type; 168 ifq_init(&ifp->receive_queue, semName); 169 170 ifp->scan_done_sem = -1; 171 // WLAN specific, doesn't hurt when initialized for other devices 172 173 // Search for the first free device slot, and use that one 174 IFNET_WLOCK(); 175 if (ifindex_alloc_locked(&index) != ENOERR) { 176 IFNET_WUNLOCK(); 177 panic("too many devices"); 178 goto err2; 179 } 180 ifnet_setbyindex_locked(index, IFNET_HOLD); 181 IFNET_WUNLOCK(); 182 183 ifp->if_index = index; 184 ifnet_setbyindex(ifp->if_index, ifp); 185 186 IF_ADDR_LOCK_INIT(ifp); 187 return 0; 188 189 err2: 190 delete_sem(ifp->receive_sem); 191 192 return -1; 193 } 194 195 196 struct ifnet * 197 if_alloc(u_char type) 198 { 199 struct ifnet *ifp = _kernel_malloc(sizeof(struct ifnet), M_ZERO); 200 if (ifp == NULL) 201 return NULL; 202 203 if (if_alloc_inplace(ifp, type) != 0) { 204 _kernel_free(ifp); 205 return NULL; 206 } 207 208 return ifp; 209 } 210 211 212 void 213 if_free_inplace(struct ifnet *ifp) 214 { 215 // IEEE80211 devices won't be in this list, 216 // so don't try to remove them. 217 if (ifp->if_type == IFT_ETHER) 218 remove_from_device_name_list(ifp); 219 220 IFNET_WLOCK(); 221 ifindex_free_locked(ifp->if_index); 222 IFNET_WUNLOCK(); 223 224 IF_ADDR_LOCK_DESTROY(ifp); 225 226 delete_sem(ifp->receive_sem); 227 ifq_uninit(&ifp->receive_queue); 228 } 229 230 231 void 232 if_free(struct ifnet *ifp) 233 { 234 if_free_inplace(ifp); 235 236 _kernel_free(ifp); 237 } 238 239 240 void 241 if_initname(struct ifnet *ifp, const char *name, int unit) 242 { 243 dprintf("if_initname(%p, %s, %d)\n", ifp, name, unit); 244 245 if (name == NULL || name[0] == '\0') 246 panic("interface goes unnamed"); 247 248 ifp->if_dname = name; 249 ifp->if_dunit = unit; 250 251 strlcpy(ifp->if_xname, name, sizeof(ifp->if_xname)); 252 253 snprintf(ifp->device_name, sizeof(ifp->device_name), "net/%s/%i", 254 gDriverName, ifp->if_index); 255 256 driver_printf("%s: /dev/%s\n", gDriverName, ifp->device_name); 257 insert_into_device_name_list(ifp); 258 259 ifp->root_device = find_root_device(unit); 260 } 261 262 263 void 264 ifq_init(struct ifqueue *ifq, const char *name) 265 { 266 ifq->ifq_head = NULL; 267 ifq->ifq_tail = NULL; 268 ifq->ifq_len = 0; 269 ifq->ifq_maxlen = IFQ_MAXLEN; 270 ifq->ifq_drops = 0; 271 272 mtx_init(&ifq->ifq_mtx, name, NULL, MTX_DEF); 273 } 274 275 276 void 277 ifq_uninit(struct ifqueue *ifq) 278 { 279 mtx_destroy(&ifq->ifq_mtx); 280 } 281 282 283 static int 284 if_transmit_default(struct ifnet *ifp, struct mbuf *m) 285 { 286 int error; 287 288 IFQ_HANDOFF(ifp, m, error); 289 return (error); 290 } 291 292 293 static void 294 if_input_default(struct ifnet *ifp __unused, struct mbuf *m) 295 { 296 297 m_freem(m); 298 } 299 300 301 /* 302 * Flush an interface queue. 303 */ 304 void 305 if_qflush(struct ifnet *ifp) 306 { 307 struct mbuf *m, *n; 308 struct ifaltq *ifq; 309 310 ifq = &ifp->if_snd; 311 IFQ_LOCK(ifq); 312 #ifdef ALTQ 313 if (ALTQ_IS_ENABLED(ifq)) 314 ALTQ_PURGE(ifq); 315 #endif 316 n = ifq->ifq_head; 317 while ((m = n) != NULL) { 318 n = m->m_nextpkt; 319 m_freem(m); 320 } 321 ifq->ifq_head = 0; 322 ifq->ifq_tail = 0; 323 ifq->ifq_len = 0; 324 IFQ_UNLOCK(ifq); 325 } 326 327 328 void 329 if_attach(struct ifnet *ifp) 330 { 331 unsigned socksize, ifasize; 332 int namelen, masklen; 333 struct sockaddr_dl *sdl; 334 struct ifaddr *ifa; 335 336 TAILQ_INIT(&ifp->if_addrhead); 337 TAILQ_INIT(&ifp->if_prefixhead); 338 TAILQ_INIT(&ifp->if_multiaddrs); 339 340 IF_ADDR_LOCK_INIT(ifp); 341 342 ifp->if_lladdr.sdl_family = AF_LINK; 343 344 ifq_init((struct ifqueue *) &ifp->if_snd, ifp->if_xname); 345 346 if (ifp->if_transmit == NULL) { 347 ifp->if_transmit = if_transmit_default; 348 ifp->if_qflush = if_qflush; 349 } 350 if (ifp->if_input == NULL) 351 ifp->if_input = if_input_default; 352 353 if (ifp->if_requestencap == NULL) 354 ifp->if_requestencap = if_requestencap_default; 355 356 /* 357 * Create a Link Level name for this device. 358 */ 359 namelen = strlen(ifp->if_xname); 360 /* 361 * Always save enough space for any possiable name so we 362 * can do a rename in place later. 363 */ 364 masklen = offsetof(struct sockaddr_dl, sdl_data[0]) + IFNAMSIZ; 365 socksize = masklen + ifp->if_addrlen; 366 if (socksize < sizeof(*sdl)) 367 socksize = sizeof(*sdl); 368 socksize = roundup2(socksize, sizeof(long)); 369 ifasize = sizeof(*ifa) + 2 * socksize; 370 ifa = ifa_alloc(ifasize, M_WAITOK); 371 sdl = (struct sockaddr_dl *)(ifa + 1); 372 sdl->sdl_len = socksize; 373 sdl->sdl_family = AF_LINK; 374 bcopy(ifp->if_xname, sdl->sdl_data, namelen); 375 sdl->sdl_nlen = namelen; 376 sdl->sdl_index = ifp->if_index; 377 sdl->sdl_type = ifp->if_type; 378 ifp->if_addr = ifa; 379 ifa->ifa_ifp = ifp; 380 //ifa->ifa_rtrequest = link_rtrequest; 381 ifa->ifa_addr = (struct sockaddr *)sdl; 382 sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl); 383 ifa->ifa_netmask = (struct sockaddr *)sdl; 384 sdl->sdl_len = masklen; 385 while (namelen != 0) 386 sdl->sdl_data[--namelen] = 0xff; 387 dprintf("if_attach %p\n", ifa->ifa_addr); 388 } 389 390 391 void 392 if_detach(struct ifnet *ifp) 393 { 394 if (HAIKU_DRIVER_REQUIRES(FBSD_SWI_TASKQUEUE)) 395 taskqueue_drain(taskqueue_swi, &ifp->if_linktask); 396 397 IF_ADDR_LOCK_DESTROY(ifp); 398 ifq_uninit((struct ifqueue *) &ifp->if_snd); 399 } 400 401 402 void 403 if_start(struct ifnet *ifp) 404 { 405 ifp->if_start(ifp); 406 } 407 408 409 int 410 if_printf(struct ifnet *ifp, const char *format, ...) 411 { 412 char buf[256]; 413 va_list vl; 414 va_start(vl, format); 415 vsnprintf(buf, sizeof(buf), format, vl); 416 va_end(vl); 417 418 dprintf("[%s] %s", ifp->device_name, buf); 419 return 0; 420 } 421 422 423 /* 424 * Compat function for handling basic encapsulation requests. 425 * Not converted stacks (FDDI, IB, ..) supports traditional 426 * output model: ARP (and other similar L2 protocols) are handled 427 * inside output routine, arpresolve/nd6_resolve() returns MAC 428 * address instead of full prepend. 429 * 430 * This function creates calculated header==MAC for IPv4/IPv6 and 431 * returns EAFNOSUPPORT (which is then handled in ARP code) for other 432 * address families. 433 */ 434 static int 435 if_requestencap_default(struct ifnet *ifp, struct if_encap_req *req) 436 { 437 438 if (req->rtype != IFENCAP_LL) 439 return (EOPNOTSUPP); 440 441 if (req->bufsize < req->lladdr_len) 442 return (ENOMEM); 443 444 switch (req->family) { 445 case AF_INET: 446 case AF_INET6: 447 break; 448 default: 449 return (EAFNOSUPPORT); 450 } 451 452 /* Copy lladdr to storage as is */ 453 memmove(req->buf, req->lladdr, req->lladdr_len); 454 req->bufsize = req->lladdr_len; 455 req->lladdr_off = 0; 456 457 return (0); 458 } 459 460 461 void 462 if_link_state_change(struct ifnet *ifp, int linkState) 463 { 464 if (ifp->if_link_state == linkState) 465 return; 466 467 ifp->if_link_state = linkState; 468 release_sem_etc(ifp->link_state_sem, 1, B_DO_NOT_RESCHEDULE); 469 } 470 471 static struct ifmultiaddr * 472 if_findmulti(struct ifnet *ifp, struct sockaddr *_address) 473 { 474 struct sockaddr_dl *address = (struct sockaddr_dl *) _address; 475 struct ifmultiaddr *ifma; 476 477 TAILQ_FOREACH (ifma, &ifp->if_multiaddrs, ifma_link) { 478 if (memcmp(LLADDR(address), 479 LLADDR((struct sockaddr_dl *)ifma->ifma_addr), ETHER_ADDR_LEN) == 0) 480 return ifma; 481 } 482 483 return NULL; 484 } 485 486 487 /* 488 * if_freemulti: free ifmultiaddr structure and possibly attached related 489 * addresses. The caller is responsible for implementing reference 490 * counting, notifying the driver, handling routing messages, and releasing 491 * any dependent link layer state. 492 */ 493 static void 494 if_freemulti(struct ifmultiaddr *ifma) 495 { 496 497 KASSERT(ifma->ifma_refcount == 0, ("if_freemulti: refcount %d", 498 ifma->ifma_refcount)); 499 KASSERT(ifma->ifma_protospec == NULL, 500 ("if_freemulti: protospec not NULL")); 501 502 if (ifma->ifma_lladdr != NULL) 503 free(ifma->ifma_lladdr); 504 505 // Haiku note: We use a field in the ifmultiaddr struct (ifma_addr_storage) 506 // to store the address and let ifma_addr point to that. We therefore do not 507 // free it here, as it will be freed as part of freeing the if_multiaddr. 508 //free(ifma->ifma_addr); 509 510 free(ifma); 511 } 512 513 514 static struct ifmultiaddr * 515 _if_addmulti(struct ifnet *ifp, struct sockaddr *address) 516 { 517 struct ifmultiaddr *addr = if_findmulti(ifp, address); 518 519 if (addr != NULL) { 520 addr->ifma_refcount++; 521 return addr; 522 } 523 524 addr = (struct ifmultiaddr *) malloc(sizeof(struct ifmultiaddr)); 525 if (addr == NULL) 526 return NULL; 527 528 addr->ifma_lladdr = NULL; 529 addr->ifma_ifp = ifp; 530 addr->ifma_protospec = NULL; 531 532 memcpy(&addr->ifma_addr_storage, address, sizeof(struct sockaddr_dl)); 533 addr->ifma_addr = (struct sockaddr *) &addr->ifma_addr_storage; 534 535 addr->ifma_refcount = 1; 536 537 TAILQ_INSERT_HEAD(&ifp->if_multiaddrs, addr, ifma_link); 538 539 return addr; 540 } 541 542 543 int 544 if_addmulti(struct ifnet *ifp, struct sockaddr *address, 545 struct ifmultiaddr **out) 546 { 547 struct ifmultiaddr *result; 548 int refcount = 0; 549 550 IF_ADDR_LOCK(ifp); 551 result = _if_addmulti(ifp, address); 552 if (result) 553 refcount = result->ifma_refcount; 554 IF_ADDR_UNLOCK(ifp); 555 556 if (result == NULL) 557 return ENOBUFS; 558 559 if (refcount == 1 && ifp->if_ioctl != NULL) 560 ifp->if_ioctl(ifp, SIOCADDMULTI, NULL); 561 562 if (out) 563 (*out) = result; 564 565 return 0; 566 } 567 568 569 static int 570 if_delmulti_locked(struct ifnet *ifp, struct ifmultiaddr *ifma, int detaching) 571 { 572 struct ifmultiaddr *ll_ifma; 573 574 if (ifp != NULL && ifma->ifma_ifp != NULL) { 575 KASSERT(ifma->ifma_ifp == ifp, 576 ("%s: inconsistent ifp %p", __func__, ifp)); 577 IF_ADDR_LOCK_ASSERT(ifp); 578 } 579 580 ifp = ifma->ifma_ifp; 581 582 /* 583 * If the ifnet is detaching, null out references to ifnet, 584 * so that upper protocol layers will notice, and not attempt 585 * to obtain locks for an ifnet which no longer exists. The 586 * routing socket announcement must happen before the ifnet 587 * instance is detached from the system. 588 */ 589 if (detaching) { 590 #ifdef DIAGNOSTIC 591 printf("%s: detaching ifnet instance %p\n", __func__, ifp); 592 #endif 593 /* 594 * ifp may already be nulled out if we are being reentered 595 * to delete the ll_ifma. 596 */ 597 if (ifp != NULL) { 598 #ifndef __HAIKU__ 599 rt_newmaddrmsg(RTM_DELMADDR, ifma); 600 #endif 601 ifma->ifma_ifp = NULL; 602 } 603 } 604 605 if (--ifma->ifma_refcount > 0) 606 return 0; 607 608 #ifndef __HAIKU__ 609 /* 610 * If this ifma is a network-layer ifma, a link-layer ifma may 611 * have been associated with it. Release it first if so. 612 */ 613 ll_ifma = ifma->ifma_llifma; 614 if (ll_ifma != NULL) { 615 KASSERT(ifma->ifma_lladdr != NULL, 616 ("%s: llifma w/o lladdr", __func__)); 617 if (detaching) 618 ll_ifma->ifma_ifp = NULL; /* XXX */ 619 if (--ll_ifma->ifma_refcount == 0) { 620 if (ifp != NULL) { 621 TAILQ_REMOVE(&ifp->if_multiaddrs, ll_ifma, 622 ifma_link); 623 } 624 if_freemulti(ll_ifma); 625 } 626 } 627 #endif 628 629 if (ifp != NULL) 630 TAILQ_REMOVE(&ifp->if_multiaddrs, ifma, ifma_link); 631 632 if_freemulti(ifma); 633 634 /* 635 * The last reference to this instance of struct ifmultiaddr 636 * was released; the hardware should be notified of this change. 637 */ 638 return 1; 639 } 640 641 642 /* 643 * Delete all multicast group membership for an interface. 644 * Should be used to quickly flush all multicast filters. 645 */ 646 void 647 if_delallmulti(struct ifnet *ifp) 648 { 649 struct ifmultiaddr *ifma; 650 struct ifmultiaddr *next; 651 652 IF_ADDR_LOCK(ifp); 653 TAILQ_FOREACH_SAFE(ifma, &ifp->if_multiaddrs, ifma_link, next) 654 if_delmulti_locked(ifp, ifma, 0); 655 IF_ADDR_UNLOCK(ifp); 656 } 657 658 659 static void 660 if_delete_multiaddr(struct ifnet *ifp, struct ifmultiaddr *ifma) 661 { 662 TAILQ_REMOVE(&ifp->if_multiaddrs, ifma, ifma_link); 663 free(ifma); 664 } 665 666 667 int 668 if_delmulti(struct ifnet *ifp, struct sockaddr *sa) 669 { 670 struct ifmultiaddr *ifma; 671 int lastref; 672 #if 0 /* def INVARIANTS */ 673 struct ifnet *oifp; 674 675 IFNET_RLOCK_NOSLEEP(); 676 TAILQ_FOREACH(oifp, &V_ifnet, if_link) 677 if (ifp == oifp) 678 break; 679 if (ifp != oifp) 680 ifp = NULL; 681 IFNET_RUNLOCK_NOSLEEP(); 682 683 KASSERT(ifp != NULL, ("%s: ifnet went away", __func__)); 684 #endif 685 if (ifp == NULL) 686 return (ENOENT); 687 688 IF_ADDR_LOCK(ifp); 689 lastref = 0; 690 ifma = if_findmulti(ifp, sa); 691 if (ifma != NULL) 692 lastref = if_delmulti_locked(ifp, ifma, 0); 693 IF_ADDR_UNLOCK(ifp); 694 695 if (ifma == NULL) 696 return (ENOENT); 697 698 if (lastref && ifp->if_ioctl != NULL) { 699 (void)(*ifp->if_ioctl)(ifp, SIOCDELMULTI, 0); 700 } 701 702 return (0); 703 } 704 705 706 /* 707 * Return counter values from counter(9)s stored in ifnet. 708 */ 709 uint64_t 710 if_get_counter_default(struct ifnet *ifp, ift_counter cnt) 711 { 712 713 KASSERT(cnt < IFCOUNTERS, ("%s: invalid cnt %d", __func__, cnt)); 714 715 switch (cnt) { 716 case IFCOUNTER_IPACKETS: 717 return atomic_get64((int64 *)&ifp->if_ipackets); 718 case IFCOUNTER_IERRORS: 719 return atomic_get64((int64 *)&ifp->if_ierrors); 720 case IFCOUNTER_OPACKETS: 721 return atomic_get64((int64 *)&ifp->if_opackets); 722 case IFCOUNTER_OERRORS: 723 return atomic_get64((int64 *)&ifp->if_oerrors); 724 case IFCOUNTER_COLLISIONS: 725 return atomic_get64((int64 *)&ifp->if_collisions); 726 case IFCOUNTER_IBYTES: 727 return atomic_get64((int64 *)&ifp->if_ibytes); 728 case IFCOUNTER_OBYTES: 729 return atomic_get64((int64 *)&ifp->if_obytes); 730 case IFCOUNTER_IMCASTS: 731 return atomic_get64((int64 *)&ifp->if_imcasts); 732 case IFCOUNTER_OMCASTS: 733 return atomic_get64((int64 *)&ifp->if_omcasts); 734 case IFCOUNTER_IQDROPS: 735 return atomic_get64((int64 *)&ifp->if_iqdrops); 736 case IFCOUNTER_OQDROPS: 737 return atomic_get64((int64 *)&ifp->if_oqdrops); 738 case IFCOUNTER_NOPROTO: 739 return atomic_get64((int64 *)&ifp->if_noproto); 740 case IFCOUNTERS: 741 KASSERT(cnt < IFCOUNTERS, ("%s: invalid cnt %d", __func__, cnt)); 742 } 743 return 0; 744 } 745 746 void 747 if_addr_rlock(struct ifnet *ifp) 748 { 749 IF_ADDR_LOCK(ifp); 750 } 751 752 753 void 754 if_addr_runlock(struct ifnet *ifp) 755 { 756 IF_ADDR_UNLOCK(ifp); 757 } 758 759 760 void 761 if_maddr_rlock(struct ifnet *ifp) 762 { 763 IF_ADDR_LOCK(ifp); 764 } 765 766 767 void 768 if_maddr_runlock(struct ifnet *ifp) 769 { 770 IF_ADDR_UNLOCK(ifp); 771 } 772 773 774 int 775 ether_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, 776 struct route *ro) 777 { 778 int error = 0; 779 IFQ_HANDOFF(ifp, m, error); 780 return error; 781 } 782 783 784 static void 785 ether_input(struct ifnet *ifp, struct mbuf *m) 786 { 787 int32 count = 0; 788 789 IF_LOCK(&ifp->receive_queue); 790 while (m != NULL) { 791 struct mbuf *mn = m->m_nextpkt; 792 m->m_nextpkt = NULL; 793 794 _IF_ENQUEUE(&ifp->receive_queue, m); 795 count++; 796 797 m = mn; 798 } 799 IF_UNLOCK(&ifp->receive_queue); 800 801 release_sem_etc(ifp->receive_sem, count, B_DO_NOT_RESCHEDULE); 802 } 803 804 805 void 806 ether_ifattach(struct ifnet *ifp, const uint8_t *lla) 807 { 808 struct ifaddr *ifa; 809 struct sockaddr_dl *sdl; 810 811 ifp->if_addrlen = ETHER_ADDR_LEN; 812 ifp->if_hdrlen = ETHER_HDR_LEN; 813 if_attach(ifp); 814 ifp->if_mtu = ETHERMTU; 815 ifp->if_output = ether_output; 816 ifp->if_input = ether_input; 817 ifp->if_resolvemulti = NULL; // done in the stack 818 ifp->if_get_counter = NULL; 819 ifp->if_broadcastaddr = etherbroadcastaddr; 820 821 ifa = ifp->if_addr; 822 sdl = (struct sockaddr_dl *)ifa->ifa_addr; 823 sdl->sdl_type = IFT_ETHER; 824 sdl->sdl_alen = ifp->if_addrlen; 825 bcopy(lla, LLADDR(sdl), ifp->if_addrlen); 826 } 827 828 829 void 830 ether_ifdetach(struct ifnet *ifp) 831 { 832 if_detach(ifp); 833 } 834 835 836 int 837 ether_ioctl(struct ifnet *ifp, u_long command, caddr_t data) 838 { 839 struct ifreq *ifr = (struct ifreq *) data; 840 841 //dprintf("ether_ioctl: received %d\n", command); 842 843 switch (command) { 844 case SIOCSIFMTU: 845 if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ETHERMTU) 846 return EINVAL; 847 ifp->if_mtu = ifr->ifr_mtu; 848 break; 849 850 default: 851 return EINVAL; 852 } 853 854 return 0; 855 } 856 857 858 /* 859 * Initialization, destruction and refcounting functions for ifaddrs. 860 */ 861 struct ifaddr * 862 ifa_alloc(size_t size, int flags) 863 { 864 struct ifaddr *ifa; 865 866 KASSERT(size >= sizeof(struct ifaddr), 867 ("%s: invalid size %zu", __func__, size)); 868 869 ifa = _kernel_malloc(size, M_ZERO | flags); 870 if (ifa == NULL) 871 return (NULL); 872 873 //refcount_init(&ifa->ifa_refcnt, 1); 874 875 return (ifa); 876 877 fail: 878 /* free(NULL) is okay */ 879 free(ifa); 880 881 return (NULL); 882 } 883 884 void 885 if_inc_counter(struct ifnet *ifp, ift_counter cnt, int64_t inc) 886 { 887 switch (cnt) { 888 case IFCOUNTER_IPACKETS: 889 atomic_add64((int64 *)&ifp->if_ipackets, inc); 890 break; 891 case IFCOUNTER_IERRORS: 892 atomic_add64((int64 *)&ifp->if_ierrors, inc); 893 break; 894 case IFCOUNTER_OPACKETS: 895 atomic_add64((int64 *)&ifp->if_opackets, inc); 896 break; 897 case IFCOUNTER_OERRORS: 898 atomic_add64((int64 *)&ifp->if_oerrors, inc); 899 break; 900 case IFCOUNTER_COLLISIONS: 901 atomic_add64((int64 *)&ifp->if_collisions, inc); 902 break; 903 case IFCOUNTER_IBYTES: 904 atomic_add64((int64 *)&ifp->if_ibytes, inc); 905 break; 906 case IFCOUNTER_OBYTES: 907 atomic_add64((int64 *)&ifp->if_obytes, inc); 908 break; 909 case IFCOUNTER_IMCASTS: 910 atomic_add64((int64 *)&ifp->if_imcasts, inc); 911 break; 912 case IFCOUNTER_OMCASTS: 913 atomic_add64((int64 *)&ifp->if_omcasts, inc); 914 break; 915 case IFCOUNTER_IQDROPS: 916 atomic_add64((int64 *)&ifp->if_iqdrops, inc); 917 break; 918 case IFCOUNTER_OQDROPS: 919 atomic_add64((int64 *)&ifp->if_oqdrops, inc); 920 break; 921 case IFCOUNTER_NOPROTO: 922 atomic_add64((int64 *)&ifp->if_noproto, inc); 923 break; 924 case IFCOUNTERS: 925 KASSERT(cnt < IFCOUNTERS, ("%s: invalid cnt %d", __func__, cnt)); 926 } 927 } 928 929 void 930 if_bpfmtap(if_t ifh, struct mbuf *m) 931 { 932 struct ifnet *ifp = (struct ifnet *)ifh; 933 934 BPF_MTAP(ifp, m); 935 } 936 937 void 938 if_etherbpfmtap(if_t ifh, struct mbuf *m) 939 { 940 struct ifnet *ifp = (struct ifnet *)ifh; 941 942 ETHER_BPF_MTAP(ifp, m); 943 } 944