A wifi driver's newassoc routine gets invoked excessively often in IBSS mode. It runs whenever a probe response is received. Showing output from a patched newassoc routine which prints "new node <address>":
Jan 10 02:01:09 jim /bsd: new node 00:24:fe:44:07:bb Jan 10 02:01:09 jim /bsd: new node 88:25:2c:bf:81:59 Jan 10 02:01:09 jim /bsd: new node 34:81:c4:ac:4e:f0 Jan 10 02:01:09 jim /bsd: new node bc:05:43:c9:8b:d3 Jan 10 02:01:09 jim /bsd: new node 00:0e:8e:24:52:7d Jan 10 02:01:09 jim /bsd: new node 00:0e:2e:5c:55:4f Jan 10 02:01:09 jim /bsd: new node 00:24:fe:44:07:bb Jan 10 02:01:09 jim /bsd: new node 34:81:c4:ac:4e:f0 Jan 10 02:01:09 jim /bsd: new node bc:05:43:c9:8b:d3 Jan 10 02:01:09 jim /bsd: new node 00:0e:8e:24:52:7d Jan 10 02:01:09 jim /bsd: new node 00:0e:2e:5c:55:4f Jan 10 02:01:09 jim /bsd: new node 34:81:c4:ac:4e:f0 Jan 10 02:01:09 jim /bsd: new node 00:0e:8e:24:52:7d It keeps being called for the same nodes, very often. Since drivers usually reset the node's tx rate in newassoc() this seems rather strange. Looking at the history of ieee80211_input.c I believe a mistake crept in several years ago in r1.4: - if (ic->ic_state == IEEE80211_S_SCAN) - ieee80211_unref_node(&ni); /* NB: do not free */ - else if (ic->ic_opmode == IEEE80211_M_IBSS && - allocbs && isprobe) { + if (ic->ic_opmode == IEEE80211_M_IBSS || (is_new && + ISPROBE(subtype))) { Note how && was changed to || in this revision and has since been kept. The original code in r1.1 in this if-block applied only to IBSS mode: else if (ic->ic_opmode == IEEE80211_M_IBSS && allocbs && isprobe) { /* * Fake an association so the driver can setup it's * private state. The rate set has been setup above; * there is no handshake as in ap/station operation. */ if (ic->ic_newassoc) (*ic->ic_newassoc)(ic, ni, 1); In AP and station modes newassoc is called via ieee80211_node_join() so there is no reason to call it for probe responses. Proposed fix restores the original behaviour and removes an outdated comment. Index: ieee80211_input.c =================================================================== RCS file: /cvs/src/sys/net80211/ieee80211_input.c,v retrieving revision 1.128 diff -u -p -r1.128 ieee80211_input.c --- ieee80211_input.c 23 Dec 2014 03:24:08 -0000 1.128 +++ ieee80211_input.c 10 Jan 2015 02:16:59 -0000 @@ -1633,18 +1633,8 @@ ieee80211_recv_probe_resp(struct ieee802 /* NB: must be after ni_chan is setup */ ieee80211_setup_rates(ic, ni, rates, xrates, IEEE80211_F_DOSORT); - /* - * When scanning we record results (nodes) with a zero - * refcnt. Otherwise we want to hold the reference for - * ibss neighbors so the nodes don't get released prematurely. - * Anything else can be discarded (XXX and should be handled - * above so we don't do so much work). - */ - if ( #ifndef IEEE80211_STA_ONLY - ic->ic_opmode == IEEE80211_M_IBSS || -#endif - (is_new && isprobe)) { + if (ic->ic_opmode == IEEE80211_M_IBSS && is_new && isprobe) { /* * Fake an association so the driver can setup it's * private state. The rate set has been setup above; @@ -1653,6 +1643,7 @@ ieee80211_recv_probe_resp(struct ieee802 if (ic->ic_newassoc) (*ic->ic_newassoc)(ic, ni, 1); } +#endif } #ifndef IEEE80211_STA_ONLY