+ thread_t thread = THREAD_NULL;
+
+ /*
+ * The following fields must be 64-bit aligned for atomic operations.
+ */
+ IF_DATA_REQUIRE_ALIGNED_64(ifi_ipackets);
+ IF_DATA_REQUIRE_ALIGNED_64(ifi_ierrors)
+ IF_DATA_REQUIRE_ALIGNED_64(ifi_opackets);
+ IF_DATA_REQUIRE_ALIGNED_64(ifi_oerrors);
+ IF_DATA_REQUIRE_ALIGNED_64(ifi_collisions);
+ IF_DATA_REQUIRE_ALIGNED_64(ifi_ibytes);
+ IF_DATA_REQUIRE_ALIGNED_64(ifi_obytes);
+ IF_DATA_REQUIRE_ALIGNED_64(ifi_imcasts);
+ IF_DATA_REQUIRE_ALIGNED_64(ifi_omcasts);
+ IF_DATA_REQUIRE_ALIGNED_64(ifi_iqdrops);
+ IF_DATA_REQUIRE_ALIGNED_64(ifi_noproto);
+
+ IFNET_IF_DATA_REQUIRE_ALIGNED_64(ifi_ipackets);
+ IFNET_IF_DATA_REQUIRE_ALIGNED_64(ifi_ierrors)
+ IFNET_IF_DATA_REQUIRE_ALIGNED_64(ifi_opackets);
+ IFNET_IF_DATA_REQUIRE_ALIGNED_64(ifi_oerrors);
+ IFNET_IF_DATA_REQUIRE_ALIGNED_64(ifi_collisions);
+ IFNET_IF_DATA_REQUIRE_ALIGNED_64(ifi_ibytes);
+ IFNET_IF_DATA_REQUIRE_ALIGNED_64(ifi_obytes);
+ IFNET_IF_DATA_REQUIRE_ALIGNED_64(ifi_imcasts);
+ IFNET_IF_DATA_REQUIRE_ALIGNED_64(ifi_omcasts);
+ IFNET_IF_DATA_REQUIRE_ALIGNED_64(ifi_iqdrops);
+ IFNET_IF_DATA_REQUIRE_ALIGNED_64(ifi_noproto);
+
+ IFNET_IF_TC_REQUIRE_ALIGNED_64(ifi_ibkpackets);
+ IFNET_IF_TC_REQUIRE_ALIGNED_64(ifi_ibkbytes);
+ IFNET_IF_TC_REQUIRE_ALIGNED_64(ifi_obkpackets);
+ IFNET_IF_TC_REQUIRE_ALIGNED_64(ifi_obkbytes);
+ IFNET_IF_TC_REQUIRE_ALIGNED_64(ifi_ivipackets);
+ IFNET_IF_TC_REQUIRE_ALIGNED_64(ifi_ivibytes);
+ IFNET_IF_TC_REQUIRE_ALIGNED_64(ifi_ovipackets);
+ IFNET_IF_TC_REQUIRE_ALIGNED_64(ifi_ovibytes);
+ IFNET_IF_TC_REQUIRE_ALIGNED_64(ifi_ivopackets);
+ IFNET_IF_TC_REQUIRE_ALIGNED_64(ifi_ivobytes);
+ IFNET_IF_TC_REQUIRE_ALIGNED_64(ifi_ovopackets);
+ IFNET_IF_TC_REQUIRE_ALIGNED_64(ifi_ovobytes);
+
+ /*
+ * These IF_HWASSIST_ flags must be equal to their IFNET_* counterparts.
+ */
+ _CASSERT(IF_HWASSIST_CSUM_IP == IFNET_CSUM_IP);
+ _CASSERT(IF_HWASSIST_CSUM_TCP == IFNET_CSUM_TCP);
+ _CASSERT(IF_HWASSIST_CSUM_UDP == IFNET_CSUM_UDP);
+ _CASSERT(IF_HWASSIST_CSUM_IP_FRAGS == IFNET_CSUM_FRAGMENT);
+ _CASSERT(IF_HWASSIST_CSUM_FRAGMENT == IFNET_IP_FRAGMENT);
+ _CASSERT(IF_HWASSIST_CSUM_TCP_SUM16 == IFNET_CSUM_SUM16);
+ _CASSERT(IF_HWASSIST_VLAN_TAGGING == IFNET_VLAN_TAGGING);
+ _CASSERT(IF_HWASSIST_VLAN_MTU == IFNET_VLAN_MTU);
+ _CASSERT(IF_HWASSIST_TSO_V4 == IFNET_TSO_IPV4);
+ _CASSERT(IF_HWASSIST_TSO_V6 == IFNET_TSO_IPV6);
+
+ /*
+ * Make sure we have at least IF_LLREACH_MAXLEN in the llreach info.
+ */
+ _CASSERT(IF_LLREACH_MAXLEN <= IF_LLREACHINFO_ADDRLEN);
+
+ PE_parse_boot_argn("net_affinity", &net_affinity,
+ sizeof (net_affinity));
+
+ PE_parse_boot_argn("net_rtref", &net_rtref, sizeof (net_rtref));
+
+ PE_parse_boot_argn("ifnet_debug", &ifnet_debug, sizeof (ifnet_debug));
+
+ dlif_size = (ifnet_debug == 0) ? sizeof (struct dlil_ifnet) :
+ sizeof (struct dlil_ifnet_dbg);
+ /* Enforce 64-bit alignment for dlil_ifnet structure */
+ dlif_bufsize = dlif_size + sizeof (void *) + sizeof (u_int64_t);
+ dlif_bufsize = P2ROUNDUP(dlif_bufsize, sizeof (u_int64_t));
+ dlif_zone = zinit(dlif_bufsize, DLIF_ZONE_MAX * dlif_bufsize,
+ 0, DLIF_ZONE_NAME);
+ if (dlif_zone == NULL) {
+ panic("%s: failed allocating %s", __func__, DLIF_ZONE_NAME);
+ /* NOTREACHED */
+ }
+ zone_change(dlif_zone, Z_EXPAND, TRUE);
+ zone_change(dlif_zone, Z_CALLERACCT, FALSE);
+
+ dlif_filt_size = sizeof (struct ifnet_filter);
+ dlif_filt_zone = zinit(dlif_filt_size,
+ DLIF_FILT_ZONE_MAX * dlif_filt_size, 0, DLIF_FILT_ZONE_NAME);
+ if (dlif_filt_zone == NULL) {
+ panic("%s: failed allocating %s", __func__,
+ DLIF_FILT_ZONE_NAME);
+ /* NOTREACHED */
+ }
+ zone_change(dlif_filt_zone, Z_EXPAND, TRUE);
+ zone_change(dlif_filt_zone, Z_CALLERACCT, FALSE);
+
+ dlif_inp_size = sizeof (struct dlil_threading_info);
+ dlif_inp_zone = zinit(dlif_inp_size,
+ DLIF_INP_ZONE_MAX * dlif_inp_size, 0, DLIF_INP_ZONE_NAME);
+ if (dlif_inp_zone == NULL) {
+ panic("%s: failed allocating %s", __func__, DLIF_INP_ZONE_NAME);
+ /* NOTREACHED */
+ }
+ zone_change(dlif_inp_zone, Z_EXPAND, TRUE);
+ zone_change(dlif_inp_zone, Z_CALLERACCT, FALSE);
+
+ dlif_phash_size = sizeof (struct proto_hash_entry) * PROTO_HASH_SLOTS;
+ dlif_phash_zone = zinit(dlif_phash_size,
+ DLIF_PHASH_ZONE_MAX * dlif_phash_size, 0, DLIF_PHASH_ZONE_NAME);
+ if (dlif_phash_zone == NULL) {
+ panic("%s: failed allocating %s", __func__,
+ DLIF_PHASH_ZONE_NAME);
+ /* NOTREACHED */
+ }
+ zone_change(dlif_phash_zone, Z_EXPAND, TRUE);
+ zone_change(dlif_phash_zone, Z_CALLERACCT, FALSE);
+
+ dlif_proto_size = sizeof (struct if_proto);
+ dlif_proto_zone = zinit(dlif_proto_size,
+ DLIF_PROTO_ZONE_MAX * dlif_proto_size, 0, DLIF_PROTO_ZONE_NAME);
+ if (dlif_proto_zone == NULL) {
+ panic("%s: failed allocating %s", __func__,
+ DLIF_PROTO_ZONE_NAME);
+ /* NOTREACHED */
+ }
+ zone_change(dlif_proto_zone, Z_EXPAND, TRUE);
+ zone_change(dlif_proto_zone, Z_CALLERACCT, FALSE);
+
+ ifnet_llreach_init();
+