We've got lots of RF noise in the g2k12 hackroom. Edd's soekris
sometimes failed to allow new nodes to associate and we found
that this was due to ieee80211_node_alloc_helper() failing to
add a new node to the cache. 'netstat -W ral0' showed the
'input packets dropped' counter, which corresponds to
ic->ic_stats.is_rx_nodealloc, was increasing well beyond 2000 and rising.

The diff below fixes this by tweaking cache eviction rules used when
the node cache is full. It additionally kicks off new nodes in AUTH
state which weren't active during the last chache wait interval
(currently 5 seconds). Without this diff such nodes can occupy cache
slots for an entire cache timeout interval (5 minutes), preventing
legitimate users from associating. With this diff the soekris hasn't
reported a single 'dropped' input packet yet within a couple of hours.
# netstat -W ral0 | grep drop 
        0 input packets dropped

ok?

Index: ieee80211_node.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_node.c,v
retrieving revision 1.68
diff -u -p -r1.68 ieee80211_node.c
--- ieee80211_node.c    25 Jan 2012 17:04:02 -0000      1.68
+++ ieee80211_node.c    13 Jul 2012 07:23:34 -0000
@@ -1141,8 +1141,8 @@ ieee80211_free_allnodes(struct ieee80211
  * Else, this function is called because a new node must be allocated but the
  * node cache is full. In this case, return as soon as a free slot was made
  * available. If acting as hostap, clean cached nodes regardless of their
- * recent activity and also allow de-authing inactive authenticated or
- * associated nodes.
+ * recent activity and also allow de-authing of authenticated nodes older
+ * than one cache wait interval, and de-authing of inactive associated nodes.
  */
 void
 ieee80211_clean_nodes(struct ieee80211com *ic, int cache_timeout)
@@ -1172,7 +1172,15 @@ ieee80211_clean_nodes(struct ieee80211co
                                    ni->ni_inact < IEEE80211_INACT_MAX))
                                        continue;
                        } else {
-                               if (ni->ni_state != IEEE80211_STA_COLLECT &&
+                               if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
+                                   ((ni->ni_state == IEEE80211_STA_ASSOC &&
+                                   ni->ni_inact < IEEE80211_INACT_MAX) ||
+                                   (ni->ni_state == IEEE80211_STA_AUTH &&
+                                    ni->ni_inact == 0)))
+                                       continue;
+
+                               if (ic->ic_opmode == IEEE80211_M_IBSS &&
+                                   ni->ni_state != IEEE80211_STA_COLLECT &&
                                    ni->ni_state != IEEE80211_STA_CACHE &&
                                    ni->ni_inact < IEEE80211_INACT_MAX)
                                        continue;

Reply via email to