When a HT node leaves or reassociates as a non-HT node,
clear HT capabilities stored in its node cache object.

A node may switch from 11n mode to 11a/b/g mode.
If we don't clear HT capabilities from the cache the node will
be mistaken as 11n-capable after reassociation.

Index: ieee80211_input.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_input.c,v
retrieving revision 1.181
diff -u -p -r1.181 ieee80211_input.c
--- ieee80211_input.c   9 Jan 2017 12:40:00 -0000       1.181
+++ ieee80211_input.c   9 Jan 2017 19:13:00 -0000
@@ -1802,6 +1802,8 @@ ieee80211_recv_probe_req(struct ieee8021
        }
        if (htcaps)
                ieee80211_setup_htcaps(ni, htcaps + 2, htcaps[1]);
+       else
+               ieee80211_clear_htcaps(ni);
        IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_PROBE_RESP, 0);
 }
 #endif /* IEEE80211_STA_ONLY */
@@ -2141,6 +2143,8 @@ ieee80211_recv_assoc_req(struct ieee8021
        ni->ni_chan = ic->ic_bss->ni_chan;
        if (htcaps)
                ieee80211_setup_htcaps(ni, htcaps + 2, htcaps[1]);
+       else
+               ieee80211_clear_htcaps(ni);
  end:
        if (status != 0) {
                IEEE80211_SEND_MGMT(ic, ni, resp, status);
Index: ieee80211_node.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_node.c,v
retrieving revision 1.110
diff -u -p -r1.110 ieee80211_node.c
--- ieee80211_node.c    9 Jan 2017 16:24:20 -0000       1.110
+++ ieee80211_node.c    9 Jan 2017 19:16:17 -0000
@@ -1350,6 +1350,27 @@ ieee80211_setup_htcaps(struct ieee80211_
        ni->ni_aselcaps = data[25];
 }
 
+#ifndef IEEE80211_STA_ONLY
+/* 
+ * Handle nodes switching from 11n into legacy modes.
+ */
+void
+ieee80211_clear_htcaps(struct ieee80211_node *ni)
+{
+       ni->ni_htcaps = 0;
+       ni->ni_ampdu_param = 0;
+       memset(ni->ni_rxmcs, 0, sizeof(ni->ni_rxmcs));
+       ni->ni_max_rxrate = 0;
+       ni->ni_tx_mcs_set = 0;
+       ni->ni_htxcaps = 0;
+       ni->ni_txbfcaps = 0;
+       ni->ni_aselcaps = 0;
+
+       ni->ni_flags &= ~IEEE80211_NODE_HT;
+
+}
+#endif
+
 /*
  * Install received HT op information in the node's state block.
  */
@@ -1626,6 +1647,8 @@ ieee80211_node_leave_ht(struct ieee80211
                        ba->ba_buf = NULL;
                }
        }
+
+       ieee80211_clear_htcaps(ni);
 }
 
 /*
Index: ieee80211_node.h
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_node.h,v
retrieving revision 1.63
diff -u -p -r1.63 ieee80211_node.h
--- ieee80211_node.h    21 Sep 2016 12:21:27 -0000      1.63
+++ ieee80211_node.h    9 Jan 2017 19:12:50 -0000
@@ -363,6 +363,7 @@ extern      void ieee80211_clean_cached(struc
 extern void ieee80211_clean_nodes(struct ieee80211com *, int);
 void ieee80211_setup_htcaps(struct ieee80211_node *, const uint8_t *,
     uint8_t);
+void ieee80211_clear_htcaps(struct ieee80211_node *);
 int ieee80211_setup_htop(struct ieee80211_node *, const uint8_t *,
     uint8_t);
 extern int ieee80211_setup_rates(struct ieee80211com *,

Reply via email to