diff --git a/sys/net80211/ieee80211_ddb.c b/sys/net80211/ieee80211_ddb.c index b3dd4d4c1d02..8334d772bc72 100644 --- a/sys/net80211/ieee80211_ddb.c +++ b/sys/net80211/ieee80211_ddb.c @@ -92,7 +92,8 @@ __FBSDID("$FreeBSD$"); #define IEEE80211_NODE_BITS \ "\20\1AUTH\2QOS\3ERP\5PWR_MGT\6AREF\7HT\10HTCOMPAT\11WPS\12TSN" \ - "\13AMPDU_RX\14AMPDU_TX\15MIMO_PS\16MIMO_RTS\17RIFS\20SGI20\21SGI40" + "\13AMPDU_RX\14AMPDU_TX\15MIMO_PS\16MIMO_RTS\17RIFS\20SGI20\21SGI40" \ + "\22ASSOCID" #define IEEE80211_ERP_BITS \ "\20\1NON_ERP_PRESENT\2USE_PROTECTION\3LONG_PREAMBLE" diff --git a/sys/net80211/ieee80211_hostap.c b/sys/net80211/ieee80211_hostap.c index 60cbe4be19ee..4ff89039ea19 100644 --- a/sys/net80211/ieee80211_hostap.c +++ b/sys/net80211/ieee80211_hostap.c @@ -928,6 +928,11 @@ hostap_auth_open(struct ieee80211_node *ni, struct ieee80211_frame *wh, * after the transaction completes. */ ni->ni_flags |= IEEE80211_NODE_AREF; + /* + * Mark the node as requiring a valid associatio id + * before outbound traffic is permitted. + */ + ni->ni_flags |= IEEE80211_NODE_ASSOCID; if (vap->iv_acl != NULL && vap->iv_acl->iac_getpolicy(vap) == IEEE80211_MACCMD_POLICY_RADIUS) { @@ -1054,6 +1059,11 @@ hostap_auth_shared(struct ieee80211_node *ni, struct ieee80211_frame *wh, * after the transaction completes. */ ni->ni_flags |= IEEE80211_NODE_AREF; + /* + * Mark the node as requiring a valid associatio id + * before outbound traffic is permitted. + */ + ni->ni_flags |= IEEE80211_NODE_ASSOCID; IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); ni->ni_noise = noise; ni->ni_rstamp = rstamp; diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c index 8e9d91f0e519..1d1e5d78c980 100644 --- a/sys/net80211/ieee80211_node.c +++ b/sys/net80211/ieee80211_node.c @@ -732,6 +732,7 @@ ieee80211_sta_join(struct ieee80211vap *vap, struct ieee80211_channel *chan, ni->ni_erp = se->se_erp; IEEE80211_RSSI_LPF(ni->ni_avgrssi, se->se_rssi); ni->ni_noise = se->se_noise; + ni->ni_flags |= IEEE80211_NODE_ASSOCID; if (ieee80211_ies_init(&ni->ni_ies, se->se_ies.data, se->se_ies.len)) { ieee80211_ies_expand(&ni->ni_ies); @@ -898,8 +899,10 @@ node_cleanup(struct ieee80211_node *ni) * has happened. This is probably not needed as the node * should always be removed from the table so not found but * do it just in case. + * Likewise clear the ASSOCID flag as these flags are intended + * to be managed in tandem. */ - ni->ni_flags &= ~IEEE80211_NODE_AREF; + ni->ni_flags &= ~(IEEE80211_NODE_AREF | IEEE80211_NODE_ASSOCID); /* * Drain power save queue and, if needed, clear TIM. @@ -1511,19 +1514,8 @@ ieee80211_find_txnode(struct ieee80211vap *vap, vap->iv_opmode == IEEE80211_M_WDS || IEEE80211_IS_MULTICAST(macaddr)) ni = ieee80211_ref_node(vap->iv_bss); - else { + else ni = ieee80211_find_node_locked(nt, macaddr); - if (vap->iv_opmode == IEEE80211_M_HOSTAP && - (ni != NULL && ni->ni_associd == 0)) { - /* - * Station is not associated; don't permit the - * data frame to be sent by returning NULL. This - * is kinda a kludge but the least intrusive way - * to add this check into all drivers. - */ - ieee80211_unref_node(&ni); /* NB: null's ni */ - } - } IEEE80211_NODE_UNLOCK(nt); if (ni == NULL) { diff --git a/sys/net80211/ieee80211_node.h b/sys/net80211/ieee80211_node.h index b8a30ad9ced5..bd304d5d737b 100644 --- a/sys/net80211/ieee80211_node.h +++ b/sys/net80211/ieee80211_node.h @@ -117,6 +117,7 @@ struct ieee80211_node { #define IEEE80211_NODE_RIFS 0x004000 /* RIFS enabled */ #define IEEE80211_NODE_SGI20 0x008000 /* Short GI in HT20 enabled */ #define IEEE80211_NODE_SGI40 0x010000 /* Short GI in HT40 enabled */ +#define IEEE80211_NODE_ASSOCID 0x020000 /* xmit requires associd */ uint16_t ni_associd; /* association ID */ uint16_t ni_vlan; /* vlan tag */ uint16_t ni_txpower; /* current transmit power */ diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c index e5c688946953..050d892315b1 100644 --- a/sys/net80211/ieee80211_output.c +++ b/sys/net80211/ieee80211_output.c @@ -203,10 +203,8 @@ ieee80211_start(struct ifnet *ifp) continue; } /* XXX AUTH'd */ - /* XXX mark vap to identify if associd is required */ if (ni->ni_associd == 0 && - (vap->iv_opmode == IEEE80211_M_STA || - vap->iv_opmode == IEEE80211_M_HOSTAP || IS_DWDS(vap))) { + (ni->ni_flags & IEEE80211_NODE_ASSOCID)) { IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_OUTPUT, eh->ether_dhost, NULL, "sta not associated (type 0x%04x)",