diff --git a/sys/net/if.c b/sys/net/if.c index 0e6c283..a72a534 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -582,19 +582,21 @@ skip: } /* - * Attach an interface to the list of "active" interfaces. + * Initialize an interface and assign an index for it. + * + * It must be called prior to a device specific attach routine + * (e.g., ether_ifattach and ieee80211_ifattach) or if_alloc_sadl, + * and be followed by if_register: + * + * if_initialize(ifp); + * ether_ifattach(ifp, enaddr); + * if_register(ifp); */ void -if_attach(ifnet_t *ifp) +if_initialize(ifnet_t *ifp) { KASSERT(if_indexlim > 0); TAILQ_INIT(&ifp->if_addrlist); - TAILQ_INSERT_TAIL(&ifnet_list, ifp, if_list); - - if (ifioctl_attach(ifp) != 0) - panic("%s: ifioctl_attach() failed", __func__); - - if_getindex(ifp); /* * Link level name is allocated later by a separate call to @@ -604,8 +606,6 @@ if_attach(ifnet_t *ifp) if (ifp->if_snd.ifq_maxlen == 0) ifp->if_snd.ifq_maxlen = ifqmaxlen; - sysctl_sndq_setup(&ifp->if_sysctl_log, ifp->if_xname, &ifp->if_snd); - ifp->if_broadcastaddr = 0; /* reliably crash if used uninitialized */ ifp->if_link_state = LINK_STATE_UNKNOWN; @@ -632,6 +632,20 @@ if_attach(ifnet_t *ifp) (void)pfil_run_hooks(if_pfil, (struct mbuf **)PFIL_IFNET_ATTACH, ifp, PFIL_IFNET); + if_getindex(ifp); +} + +/* + * Register an interface to the list of "active" interfaces. + */ +void +if_register(ifnet_t *ifp) +{ + if (ifioctl_attach(ifp) != 0) + panic("%s: ifioctl_attach() failed", __func__); + + sysctl_sndq_setup(&ifp->if_sysctl_log, ifp->if_xname, &ifp->if_snd); + if (!STAILQ_EMPTY(&domains)) if_attachdomain1(ifp); @@ -645,6 +659,19 @@ if_attach(ifnet_t *ifp) callout_setfunc(ifp->if_slowtimo_ch, if_slowtimo, ifp); if_slowtimo(ifp); } + + TAILQ_INSERT_TAIL(&ifnet_list, ifp, if_list); +} + +/* + * Deprecated. Use if_initialize and if_register instead. + * See the above comment of if_initialize. + */ +void +if_attach(ifnet_t *ifp) +{ + if_initialize(ifp); + if_register(ifp); } void @@ -744,6 +771,11 @@ if_detach(struct ifnet *ifp) s = splnet(); + ifindex2ifnet[ifp->if_index] = NULL; + TAILQ_REMOVE(&ifnet_list, ifp, if_list); + + sysctl_teardown(&ifp->if_sysctl_log); + if (ifp->if_slowtimo != NULL) { ifp->if_slowtimo = NULL; callout_halt(ifp->if_slowtimo_ch, NULL); @@ -766,8 +798,6 @@ if_detach(struct ifnet *ifp) if (ifp->if_snd.ifq_lock) mutex_obj_free(ifp->if_snd.ifq_lock); - sysctl_teardown(&ifp->if_sysctl_log); - #if NCARP > 0 /* Remove the interface from any carp group it is a part of. */ if (ifp->if_carp != NULL && ifp->if_type != IFT_CARP) @@ -878,10 +908,6 @@ again: /* Announce that the interface is gone. */ rt_ifannouncemsg(ifp, IFAN_DEPARTURE); - ifindex2ifnet[ifp->if_index] = NULL; - - TAILQ_REMOVE(&ifnet_list, ifp, if_list); - ifioctl_detach(ifp); /* diff --git a/sys/net/if.h b/sys/net/if.h index f3bdd30..e6e0b67 100644 --- a/sys/net/if.h +++ b/sys/net/if.h @@ -864,7 +864,9 @@ void if_activate_sadl(struct ifnet *, struct ifaddr *, const struct sockaddr_dl *); void if_set_sadl(struct ifnet *, const void *, u_char, bool); void if_alloc_sadl(struct ifnet *); -void if_attach(struct ifnet *); +void if_initialize(struct ifnet *); +void if_register(struct ifnet *); +void if_attach(struct ifnet *); /* Deprecated. Use if_initialize and if_register */ void if_attachdomain(void); void if_deactivate(struct ifnet *); void if_purgeaddrs(struct ifnet *, int, void (*)(struct ifaddr *));