On Mon, Jan 10, 2022 at 11:00:52AM +0100, Stefan Sperling wrote: > Ping. I have had zero feedback on this so far. Anyone?
Makes sense, I remember that part of the code making problems before. ok tobhe. > > On Tue, Jan 04, 2022 at 02:35:52PM +0100, Stefan Sperling wrote: > > The function ieee80211_find_node_for_beacon() was added by reyk on 2005. > > At the time, net80211 nodes were stored in a hash table keyed on hashes > > the node's source MAC addresses. > > The purpose of ieee80211_find_node_for_beacon() was to avoid storing > > duplicate nodes with the same source MAC address in a given hash bucket. > > Hash collisions on differing MAC addresses were valid, but collisions > > on the same address had to be avoided. > > > > Later on, the node table data structure was changed from a hash table > > to an RB tree which is still in use today. The RB tree can only store a > > single node per MAC address. However, find_node_for_beacon() was kept > > regardless, now documented to serve a different purpose. > > Its new purpose is to tell apart different nodes which happen to use > > the same MAC address and hence cannot both be stored in the RB tree. > > The idea is to help the net80211 stack to pick the "better" one of two > > such APs while it is scanning for access points. The comment also claims > > this function would avoid "bloat" of the nodes tree, which is obviously > > related to the function's original purpose. > > > > There are several problems with this: > > > > The code which decides which node is "better" can erroneously match > > an AP against itself, in case the AP uses a hidden SSID. > > This prevents state updates for such APs. > > Just a bit further down, the code looks up the same node again > > and performs all of the intended updates. Simply skipping the > > ieee80211_find_node_for_beacon() check makes state updates work. > > (I have received a patch submission which fixes probe responses > > for iwm/iwx in order to interop with hidden SSID APs. And that > > patch contains a workaround for this problem, which prompted me > > to look into it.) > > > > The intention of avoiding "bloat" makes no sense. > > There cannot be "bloat" of the node tree. Worst case we could end up > > leaking memory when we replace an existing node in the tree with a > > new node which has the same address (we would lose track of the pointer > > to memory which stores the original node, and would never be able to > > free this memory). There is no code in place which would prevent such > > a leak. Simply always updating the existing node we have allocated is > > the safer choice in the absence of proper collision handling. > > > > My opinion is that this function should simply be removed. > > It is an incomplete attempt at dealing with an edge case (MAC address > > collisions), which is not a problem this function alone could ever > > hope to solve completely. > > > > ok? > > > > diff d32c3633e170510dd593f1e288e78acfddaff882 > > 32e6a77a0992dc0014e72c20005dfd9631b2055b > > blob - bb6367fd1d5dd9f4641fedd96491069a8f0878dc > > blob + 51d05f49c8b1ea58ea891f7b0f817e3bf94bed08 > > --- sys/net80211/ieee80211_input.c > > +++ sys/net80211/ieee80211_input.c > > @@ -1751,37 +1751,7 @@ ieee80211_recv_probe_resp(struct ieee80211com *ic, > > str > > ic->ic_stats.is_rx_chanmismatch++; > > return; > > } > > - /* > > - * Use mac, channel and rssi so we collect only the > > - * best potential AP with the equal bssid while scanning. > > - * Collecting all potential APs may result in bloat of > > - * the node tree. This call will return NULL if the node > > - * for this APs does not exist or if the new node is the > > - * potential better one. > > - */ > > - ni = ieee80211_find_node_for_beacon(ic, wh->i_addr2, > > - &ic->ic_channels[chan], ssid, rxi->rxi_rssi); > > - if (ni != NULL) { > > - /* > > - * If we are doing a directed scan for an AP with a hidden SSID > > - * we must collect the SSID from a probe response to override > > - * a non-zero-length SSID filled with zeroes that we may have > > - * received earlier in a beacon. > > - */ > > - if (isprobe && ssid[1] != 0 && ni->ni_essid[0] == '\0') { > > - ni->ni_esslen = ssid[1]; > > - memset(ni->ni_essid, 0, sizeof(ni->ni_essid)); > > - /* we know that ssid[1] <= IEEE80211_NWID_LEN */ > > - memcpy(ni->ni_essid, &ssid[2], ssid[1]); > > - } > > > > - /* Update channel in case AP has switched */ > > - if (ic->ic_opmode == IEEE80211_M_STA) > > - ni->ni_chan = rni->ni_chan; > > - > > - return; > > - } > > - > > #ifdef IEEE80211_DEBUG > > if (ieee80211_debug > 1 && > > (ni == NULL || ic->ic_state == IEEE80211_S_SCAN || > > @@ -1977,6 +1947,13 @@ ieee80211_recv_probe_resp(struct ieee80211com *ic, > > str > > } > > } > > > > + /* > > + * Set our SSID if we do not know it yet. > > + * If we are doing a directed scan for an AP with a hidden SSID > > + * we must collect the SSID from a probe response to override > > + * a non-zero-length SSID filled with zeroes that we may have > > + * received earlier in a beacon. > > + */ > > if (ssid[1] != 0 && ni->ni_essid[0] == '\0') { > > ni->ni_esslen = ssid[1]; > > memset(ni->ni_essid, 0, sizeof(ni->ni_essid)); > > blob - 98cac0edbe5d0a070244293819042423b33e1e68 > > blob + 691dbc4f48afcdec88f15856c97fc3ebe123db70 > > --- sys/net80211/ieee80211_node.c > > +++ sys/net80211/ieee80211_node.c > > @@ -2025,30 +2025,6 @@ ieee80211_find_rxnode(struct ieee80211com *ic, > > return ieee80211_ref_node(ni); > > } > > > > -struct ieee80211_node * > > -ieee80211_find_node_for_beacon(struct ieee80211com *ic, > > - const u_int8_t *macaddr, const struct ieee80211_channel *chan, > > - const char *ssid, u_int8_t rssi) > > -{ > > - struct ieee80211_node *ni, *keep = NULL; > > - int s, score = 0; > > - > > - if ((ni = ieee80211_find_node(ic, macaddr)) != NULL) { > > - s = splnet(); > > - > > - if (ni->ni_chan != chan && ni->ni_rssi >= rssi) > > - score++; > > - if (ssid[1] == 0 && ni->ni_esslen != 0) > > - score++; > > - if (score > 0) > > - keep = ni; > > - > > - splx(s); > > - } > > - > > - return (keep); > > -} > > - > > void > > ieee80211_node_tx_ba_clear(struct ieee80211_node *ni, int tid) > > { > > blob - ca7f9cd59bbc04c36318d64eaf8ef2036a07644e > > blob + 4edf341acf6ae1ed4e6c3361bcc19a585dab636e > > --- sys/net80211/ieee80211_node.h > > +++ sys/net80211/ieee80211_node.h > > @@ -524,10 +524,6 @@ struct ieee80211_node *ieee80211_find_rxnode(struct ie > > const struct ieee80211_frame *); > > struct ieee80211_node *ieee80211_find_txnode(struct ieee80211com *, > > const u_int8_t *); > > -struct ieee80211_node * > > - ieee80211_find_node_for_beacon(struct ieee80211com *, > > - const u_int8_t *, const struct ieee80211_channel *, > > - const char *, u_int8_t); > > void ieee80211_release_node(struct ieee80211com *, > > struct ieee80211_node *); > > void ieee80211_node_cleanup(struct ieee80211com *, struct ieee80211_node > > *); > > > > >