Index: net80211/ieee80211_node.c =================================================================== --- net80211/ieee80211_node.c (revision 3345) +++ net80211/ieee80211_node.c (working copy) @@ -599,6 +599,22 @@ memcmp(a->ni_essid, b->ni_essid, a->ni_esslen) == 0); } +static void +ieee80211_iter_node_leave(void *data, struct ieee80211_node *ni) +{ + if (IEEE80211_ADDR_EQ(data, ni->ni_bssid)) { + ieee80211_notify_node_leave(ni); + } +} + +static void +ieee80211_iter_node_join(void *data, struct ieee80211_node *ni) +{ + if (IEEE80211_ADDR_EQ(data, ni->ni_bssid)) { + ieee80211_notify_node_join(ni, 1); + } +} + /* * Join the specified IBSS/BSS network. The node is assumed to * be passed in with a reference already held for use in assigning @@ -618,6 +634,9 @@ * that the negotiated rate set is acceptable. */ ieee80211_fix_rate(selbs, IEEE80211_F_DODEL); + + + ieee80211_iterate_nodes(&ic->ic_sta, ieee80211_iter_node_leave, vap->iv_bssid); } /* @@ -666,6 +685,10 @@ vap->iv_nsparams.arg = -1; IEEE80211_SCHEDULE_TQUEUE(&vap->iv_stajoin1tq); } + + if (vap->iv_opmode == IEEE80211_M_IBSS) { + ieee80211_iterate_nodes(&ic->ic_sta, ieee80211_iter_node_join, vap->iv_bssid); + } return 1; } @@ -1505,8 +1530,13 @@ if (ic->ic_newassoc != NULL) ic->ic_newassoc(ni, 1); + /* XXX not right for 802.1x/WPA */ ieee80211_node_authorize(ni); + /* notify user space if BSSID matches */ + if (IEEE80211_ADDR_EQ(vap->iv_bssid, ni->ni_bssid)) { + ieee80211_notify_node_join(ni, 1); + } if (vap->iv_opmode == IEEE80211_M_AHDEMO) { /* * Blindly propagate capabilities based on the @@ -2309,8 +2339,8 @@ * is reused before the reference count goes to zero * (and memory is reclaimed). */ +done: ieee80211_sta_leave(ni); -done: /* Run a cleanup */ #ifdef IEEE80211_DEBUG_REFCNT ic->ic_node_cleanup_debug(ni, __func__, __LINE__); Index: net80211/ieee80211_input.c =================================================================== --- net80211/ieee80211_input.c (revision 3345) +++ net80211/ieee80211_input.c (working copy) @@ -3442,7 +3442,23 @@ */ ni->ni_esslen = scan.ssid[1]; memcpy(ni->ni_essid, scan.ssid + 2, scan.ssid[1]); - IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3); + /* notify user space when they join/leave our BSS: + * ni_bssid = old BSSID + * i_addr3 = new BSSID + * iv_bssid = our current BSSID + */ + if (!IEEE80211_ADDR_EQ(ni->ni_bssid, wh->i_addr3)) { + /* the BSSID of the node has changed */ + if (IEEE80211_ADDR_EQ(vap->iv_bssid, wh->i_addr3)) { + /* the node joins our BSS */ + ieee80211_notify_node_join(ni, 1); + + } else if (IEEE80211_ADDR_EQ(vap->iv_bssid, ni->ni_bssid)) { + /* the node leaves our BSS */ + ieee80211_notify_node_leave(ni); + } + IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3); + } memcpy(ni->ni_tstamp.data, scan.tstamp, sizeof(ni->ni_tstamp)); ni->ni_intval =