/* * IP software interrupt routine */ void ipintr(void) { int s; struct mbuf *m; struct ifqueue lcl_intrq; memset(&lcl_intrq, 0, sizeof(lcl_intrq)); mutex_enter(softnet_lock); KERNEL_LOCK(1, NULL); if (!IF_IS_EMPTY(&ipintrq)) { s = splnet(); /* Take existing queue onto stack */ lcl_intrq = ipintrq; /* Zero out global queue, preserving maxlen and drops */ ipintrq.ifq_head = NULL; ipintrq.ifq_tail = NULL; ipintrq.ifq_len = 0; ipintrq.ifq_maxlen = lcl_intrq.ifq_maxlen; ipintrq.ifq_drops = lcl_intrq.ifq_drops; splx(s); } KERNEL_UNLOCK_ONE(NULL); while (!IF_IS_EMPTY(&lcl_intrq)) { IF_DEQUEUE(&lcl_intrq, m); if (m == NULL) break; ip_input(m); } mutex_exit(softnet_lock); }
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 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 */ }
/* * This function shall be called by drivers immediately after every DTIM. * Transmit all group addressed MSDUs buffered at the AP. */ void ieee80211_notify_dtim(struct ieee80211com *ic) { /* NB: group addressed MSDUs are buffered in ic_bss */ struct ieee80211_node *ni = ic->ic_bss; struct ifnet *ifp = &ic->ic_if; struct ieee80211_frame *wh; struct mbuf *m; KASSERT(ic->ic_opmode == IEEE80211_M_HOSTAP); for (;;) { IF_DEQUEUE(&ni->ni_savedq, m); if (m == NULL) break; if (!IF_IS_EMPTY(&ni->ni_savedq)) { /* more queued frames, set the more data bit */ wh = mtod(m, struct ieee80211_frame *); wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA; } IF_ENQUEUE(&ic->ic_pwrsaveq, m); (*ifp->if_start)(ifp); }
void mplsintr(void) { struct mbuf *m; int s; while (!IF_IS_EMPTY(&mplsintrq)) { s = splnet(); IF_DEQUEUE(&mplsintrq, m); splx(s); if (!m) return; if (((m->m_flags & M_PKTHDR) == 0) || (m->m_pkthdr.rcvif == 0)) panic("mplsintr(): no pkthdr or rcvif"); #ifdef MBUFTRACE m_claimm(m, &mpls_owner); #endif mpls_input(m->m_pkthdr.rcvif, m); } }