* Allocate a struct ifnet and an index for an interface. A layer 2 * common structure will also be allocated if an allocation routine is * registered for the passed type. */
| 590 | * registered for the passed type. |
| 591 | */ |
| 592 | struct ifnet * |
| 593 | if_alloc_domain(u_char type, int numa_domain) |
| 594 | { |
| 595 | struct ifnet *ifp; |
| 596 | u_short idx; |
| 597 | void *old = NULL; |
| 598 | |
| 599 | KASSERT(numa_domain <= IF_NODOM, ("numa_domain too large")); |
| 600 | if (numa_domain == IF_NODOM) |
| 601 | ifp = malloc(sizeof(struct ifnet), M_IFNET, |
| 602 | M_WAITOK | M_ZERO); |
| 603 | else |
| 604 | ifp = malloc_domainset(sizeof(struct ifnet), M_IFNET, |
| 605 | DOMAINSET_PREF(numa_domain), M_WAITOK | M_ZERO); |
| 606 | restart: |
| 607 | IFNET_WLOCK(); |
| 608 | idx = ifindex_alloc(&old); |
| 609 | if (__predict_false(idx == USHRT_MAX)) { |
| 610 | IFNET_WUNLOCK(); |
| 611 | epoch_wait_preempt(net_epoch_preempt); |
| 612 | free(old, M_IFNET); |
| 613 | goto restart; |
| 614 | } |
| 615 | ifnet_setbyindex(idx, IFNET_HOLD); |
| 616 | IFNET_WUNLOCK(); |
| 617 | ifp->if_index = idx; |
| 618 | ifp->if_type = type; |
| 619 | ifp->if_alloctype = type; |
| 620 | ifp->if_numa_domain = numa_domain; |
| 621 | #ifdef VIMAGE |
| 622 | ifp->if_vnet = curvnet; |
| 623 | #endif |
| 624 | if (if_com_alloc[type] != NULL) { |
| 625 | ifp->if_l2com = if_com_alloc[type](type, ifp); |
| 626 | if (ifp->if_l2com == NULL) { |
| 627 | free(ifp, M_IFNET); |
| 628 | ifindex_free(idx); |
| 629 | return (NULL); |
| 630 | } |
| 631 | } |
| 632 | |
| 633 | IF_ADDR_LOCK_INIT(ifp); |
| 634 | TASK_INIT(&ifp->if_linktask, 0, do_link_state_change, ifp); |
| 635 | TASK_INIT(&ifp->if_addmultitask, 0, if_siocaddmulti, ifp); |
| 636 | ifp->if_afdata_initialized = 0; |
| 637 | IF_AFDATA_LOCK_INIT(ifp); |
| 638 | CK_STAILQ_INIT(&ifp->if_addrhead); |
| 639 | CK_STAILQ_INIT(&ifp->if_multiaddrs); |
| 640 | CK_STAILQ_INIT(&ifp->if_groups); |
| 641 | #ifdef MAC |
| 642 | mac_ifnet_init(ifp); |
| 643 | #endif |
| 644 | ifq_init(&ifp->if_snd, ifp); |
| 645 | |
| 646 | refcount_init(&ifp->if_refcount, 1); /* Index reference. */ |
| 647 | for (int i = 0; i < IFCOUNTERS; i++) |
| 648 | ifp->if_counters[i] = counter_u64_alloc(M_WAITOK); |
| 649 | ifp->if_get_counter = if_get_counter_default; |
no test coverage detected