void ieee80211_free_node(struct ieee80211com *ic, struct ieee80211_node *ni) { if (ni == ic->ic_bss) panic("freeing bss node"); splassert(IPL_NET); DPRINTF(("%s\n", ether_sprintf(ni->ni_macaddr))); #ifndef IEEE80211_STA_ONLY timeout_del(&ni->ni_eapol_to); timeout_del(&ni->ni_sa_query_to); IEEE80211_AID_CLR(ni->ni_associd, ic->ic_aid_bitmap); #endif RB_REMOVE(ieee80211_tree, &ic->ic_tree, ni); ic->ic_nnodes--; #ifndef IEEE80211_STA_ONLY if (!IF_IS_EMPTY(&ni->ni_savedq)) { IF_PURGE(&ni->ni_savedq); if (ic->ic_set_tim != NULL) (*ic->ic_set_tim)(ic, ni->ni_associd, 0); } #endif (*ic->ic_node_free)(ic, ni); /* TBD indicate to drivers that a new node can be allocated */ }
/* * Handle bookkeeping for station deauthentication/disassociation * when operating as an ap. */ void ieee80211_node_leave(struct ieee80211com *ic, struct ieee80211_node *ni) { if (ic->ic_opmode != IEEE80211_M_HOSTAP) panic("not in ap mode, mode %u", ic->ic_opmode); /* * If node wasn't previously associated all we need to do is * reclaim the reference. */ if (ni->ni_associd == 0) { ieee80211_node_newstate(ni, IEEE80211_STA_COLLECT); return; } if (ni->ni_pwrsave == IEEE80211_PS_DOZE) { ic->ic_pssta--; ni->ni_pwrsave = IEEE80211_PS_AWAKE; } if (!IF_IS_EMPTY(&ni->ni_savedq)) { IF_PURGE(&ni->ni_savedq); if (ic->ic_set_tim != NULL) (*ic->ic_set_tim)(ic, ni->ni_associd, 0); } if (ic->ic_flags & IEEE80211_F_RSNON) ieee80211_node_leave_rsn(ic, ni); if (ic->ic_curmode == IEEE80211_MODE_11G) ieee80211_node_leave_11g(ic, ni); #ifndef IEEE80211_NO_HT if (ni->ni_flags & IEEE80211_NODE_HT) ieee80211_node_leave_ht(ic, ni); #endif if (ic->ic_node_leave != NULL) (*ic->ic_node_leave)(ic, ni); IEEE80211_AID_CLR(ni->ni_associd, ic->ic_aid_bitmap); ni->ni_associd = 0; ieee80211_node_newstate(ni, IEEE80211_STA_COLLECT); #if NBRIDGE > 0 /* * If the parent interface is a bridgeport, delete * any dynamically learned address for this node. */ if (ic->ic_if.if_bridgeport != NULL) bridge_update(&ic->ic_if, (struct ether_addr *)ni->ni_macaddr, 1); #endif }
static int tun_clone_destroy(struct ifnet *ifp) { struct tun_softc *tp = (void *)ifp; int s, zombie = 0; IF_PURGE(&ifp->if_snd); ifp->if_flags &= ~IFF_RUNNING; s = splnet(); simple_lock(&tun_softc_lock); mutex_enter(&tp->tun_lock); LIST_REMOVE(tp, tun_list); if (tp->tun_flags & TUN_OPEN) { /* Hang on to storage until last close */ zombie = 1; tp->tun_flags &= ~TUN_INITED; LIST_INSERT_HEAD(&tunz_softc_list, tp, tun_list); } simple_unlock(&tun_softc_lock); if (tp->tun_flags & TUN_RWAIT) { tp->tun_flags &= ~TUN_RWAIT; wakeup((void *)tp); } selnotify(&tp->tun_rsel, 0, 0); mutex_exit(&tp->tun_lock); splx(s); if (tp->tun_flags & TUN_ASYNC && tp->tun_pgid) fownsignal(tp->tun_pgid, SIGIO, POLL_HUP, 0, NULL); bpf_detach(ifp); if_detach(ifp); if (!zombie) { seldestroy(&tp->tun_rsel); seldestroy(&tp->tun_wsel); softint_disestablish(tp->tun_osih); softint_disestablish(tp->tun_isih); mutex_destroy(&tp->tun_lock); free(tp, M_DEVBUF); } return (0); }
static void ieee80211_free_node(struct ieee80211com *ic, struct ieee80211_node *ni) { if (ni == ic->ic_bss) panic("freeing bss node"); IEEE80211_DPRINTF(("%s %s\n", __func__, ether_sprintf(ni->ni_macaddr))); IEEE80211_AID_CLR(ni->ni_associd, ic->ic_aid_bitmap); RB_REMOVE(ieee80211_tree, &ic->ic_tree, ni); ic->ic_nnodes--; if (!IF_IS_EMPTY(&ni->ni_savedq)) { IF_PURGE(&ni->ni_savedq); if (ic->ic_set_tim) (*ic->ic_set_tim)(ic, ni->ni_associd, 0); } if (RB_EMPTY(&ic->ic_tree)) ic->ic_inact_timer = 0; (*ic->ic_node_free)(ic, ni); /* TBD indicate to drivers that a new node can be allocated */ }