I'd like to add some 802.11n-related counters to netstat -W output.

The first diff below is for the kernel, the second for netstat.

ok?

Index: ieee80211_input.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_input.c,v
retrieving revision 1.171
diff -u -p -r1.171 ieee80211_input.c
--- ieee80211_input.c   15 Apr 2016 03:04:27 -0000      1.171
+++ ieee80211_input.c   27 Apr 2016 11:30:08 -0000
@@ -707,7 +707,7 @@ ieee80211_input_ba(struct ieee80211com *
                timeout_add_usec(&ba->ba_to, ba->ba_timeout_val);
 
        if (SEQ_LT(sn, ba->ba_winstart)) {      /* SN < WinStartB */
-               ic->ic_stats.is_rx_dup++;
+               ic->ic_stats.is_ht_rx_frame_below_ba_winstart++;
                m_freem(m);     /* discard the MPDU */
                return;
        }
@@ -730,6 +730,7 @@ ieee80211_input_ba(struct ieee80211com *
                            "%d, expecting %d:%d\n", __func__,
                            sn, ba->ba_winstart, ba->ba_winend);
 #endif
+               ic->ic_stats.is_ht_rx_frame_above_ba_winend++;
                if (count > ba->ba_winsize) {
                        if (ba->ba_winmiss < IEEE80211_BA_MAX_WINMISS) { 
                                if (ba->ba_missedsn == sn - 1)
@@ -743,6 +744,7 @@ ieee80211_input_ba(struct ieee80211com *
                        }
 
                        /* It appears the window has moved for real. */
+                       ic->ic_stats.is_ht_rx_ba_window_jump++;
                        ba->ba_winmiss = 0;
                        ba->ba_missedsn = 0;
 
@@ -754,7 +756,8 @@ ieee80211_input_ba(struct ieee80211com *
                                ieee80211_input(ifp, ba->ba_buf[ba->ba_head].m,
                                    ni, &ba->ba_buf[ba->ba_head].rxi);
                                ba->ba_buf[ba->ba_head].m = NULL;
-                       }
+                       } else
+                               ic->ic_stats.is_ht_rx_ba_frame_lost++;
                        ba->ba_head = (ba->ba_head + 1) %
                            IEEE80211_BA_MAX_WINSZ;
                }
@@ -769,6 +772,7 @@ ieee80211_input_ba(struct ieee80211com *
        /* store the received MPDU in the buffer */
        if (ba->ba_buf[idx].m != NULL) {
                ifp->if_ierrors++;
+               ic->ic_stats.is_ht_rx_ba_no_buf++;
                m_freem(m);
                return;
        }
@@ -820,6 +824,8 @@ ieee80211_input_ba_gap_timeout(void *arg
        struct ieee80211com *ic = ni->ni_ic;
        int s, skipped;
 
+       ic->ic_stats.is_ht_rx_ba_window_gap_timeout++;
+
        s = splnet();
 
        skipped = 0;
@@ -828,6 +834,7 @@ ieee80211_input_ba_gap_timeout(void *arg
                ba->ba_head = (ba->ba_head + 1) % IEEE80211_BA_MAX_WINSZ;
                ba->ba_winstart = (ba->ba_winstart + 1) & 0xfff;
                skipped++;
+               ic->ic_stats.is_ht_rx_ba_frame_lost++;
        }
        if (skipped > 0)
                ba->ba_winend = (ba->ba_winstart + ba->ba_winsize - 1) & 0xfff;
@@ -861,7 +868,8 @@ ieee80211_ba_move_window(struct ieee8021
                        ieee80211_input(ifp, ba->ba_buf[ba->ba_head].m, ni,
                            &ba->ba_buf[ba->ba_head].rxi);
                        ba->ba_buf[ba->ba_head].m = NULL;
-               }
+               } else
+                       ic->ic_stats.is_ht_rx_ba_frame_lost++;
                ba->ba_head = (ba->ba_head + 1) % IEEE80211_BA_MAX_WINSZ;
        }
        /* move window forward */
@@ -1580,6 +1588,7 @@ ieee80211_recv_probe_resp(struct ieee802
                                DPRINTF(("[%s] htprot change: was %d, now %d\n",
                                    ether_sprintf((u_int8_t *)wh->i_addr2),
                                    htprot_last, htprot));
+                               ic->ic_stats.is_ht_prot_change++;
                                ic->ic_bss->ni_htop1 = ni->ni_htop1;
                                ic->ic_update_htprot(ic, ic->ic_bss);
                        }
@@ -2491,6 +2500,7 @@ ieee80211_recv_addba_req(struct ieee8021
                goto resp;
        }
        ba->ba_state = IEEE80211_BA_AGREED;
+       ic->ic_stats.is_ht_rx_ba_agreements++;
        /* start Block Ack inactivity timer */
        if (ba->ba_timeout_val != 0)
                timeout_add_usec(&ba->ba_to, ba->ba_timeout_val);
@@ -2561,6 +2571,7 @@ ieee80211_recv_addba_resp(struct ieee802
        }
        /* MLME-ADDBA.confirm(Success) */
        ba->ba_state = IEEE80211_BA_AGREED;
+       ic->ic_stats.is_ht_tx_ba_agreements++;
 
        /* notify drivers of this new Block Ack agreement */
        if (ic->ic_ampdu_tx_start != NULL)
Index: ieee80211_ioctl.h
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_ioctl.h,v
retrieving revision 1.23
diff -u -p -r1.23 ieee80211_ioctl.h
--- ieee80211_ioctl.h   12 Jan 2016 09:28:09 -0000      1.23
+++ ieee80211_ioctl.h   27 Apr 2016 11:19:38 -0000
@@ -95,6 +95,20 @@ struct ieee80211_stats {
        u_int32_t       is_cmac_replays;
        u_int32_t       is_cmac_icv_errs;
        u_int32_t       is_pbac_errs;
+       u_int32_t       is_ht_nego_no_mandatory_mcs;
+       u_int32_t       is_ht_nego_no_basic_mcs;
+       u_int32_t       is_ht_nego_bad_crypto;
+       u_int32_t       is_ht_prot_change;
+       u_int32_t       is_ht_rx_ba_agreements;
+       u_int32_t       is_ht_tx_ba_agreements;
+       u_int32_t       is_ht_rx_frame_below_ba_winstart;
+       u_int32_t       is_ht_rx_frame_above_ba_winend;
+       u_int32_t       is_ht_rx_ba_window_jump;
+       u_int32_t       is_ht_rx_ba_no_buf;
+       u_int32_t       is_ht_rx_ba_frame_lost;
+       u_int32_t       is_ht_rx_ba_window_gap_timeout;
+       u_int32_t       is_ht_rx_ba_timeout;
+       u_int32_t       is_ht_tx_ba_timeout;
 };
 
 #define        SIOCG80211STATS         _IOWR('i', 242, struct ifreq)
Index: ieee80211_proto.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_proto.c,v
retrieving revision 1.65
diff -u -p -r1.65 ieee80211_proto.c
--- ieee80211_proto.c   12 Apr 2016 14:33:27 -0000      1.65
+++ ieee80211_proto.c   27 Apr 2016 10:42:05 -0000
@@ -560,15 +560,19 @@ ieee80211_ht_negotiate(struct ieee80211c
                return;
 
        /* Check if the peer supports HT. MCS 0-7 are mandatory. */
-       if (ni->ni_rxmcs[0] != 0xff)
+       if (ni->ni_rxmcs[0] != 0xff) {
+               ic->ic_stats.is_ht_nego_no_mandatory_mcs++;
                return;
+       }
 
        if (ic->ic_opmode == IEEE80211_M_STA) {
                /* We must support the AP's basic MCS set. */
                for (i = 0; i < IEEE80211_HT_NUM_MCS; i++) {
                        if (isset(ni->ni_basic_mcs, i) &&
-                           !isset(ic->ic_sup_mcs, i))
+                           !isset(ic->ic_sup_mcs, i)) {
+                               ic->ic_stats.is_ht_nego_no_basic_mcs++;
                                return;
+                       }
                }
        }
 
@@ -576,12 +580,16 @@ ieee80211_ht_negotiate(struct ieee80211c
         * Don't allow group cipher (includes WEP) or TKIP
         * for pairwise encryption (see 802.11-2012 11.1.6).
         */
-       if (ic->ic_flags & IEEE80211_F_WEPON)
+       if (ic->ic_flags & IEEE80211_F_WEPON) {
+               ic->ic_stats.is_ht_nego_bad_crypto++;
                return;
+       }
        if ((ic->ic_flags & IEEE80211_F_RSNON) &&
            (ni->ni_rsnciphers & IEEE80211_CIPHER_USEGROUP ||
-           ni->ni_rsnciphers & IEEE80211_CIPHER_TKIP))
+           ni->ni_rsnciphers & IEEE80211_CIPHER_TKIP)) {
+               ic->ic_stats.is_ht_nego_bad_crypto++;
                return;
+       }
 
        ni->ni_flags |= IEEE80211_NODE_HT; 
 }
@@ -595,6 +603,8 @@ ieee80211_tx_ba_timeout(void *arg)
        u_int8_t tid;
        int s;
 
+       ic->ic_stats.is_ht_tx_ba_timeout++;
+
        s = splnet();
        if (ba->ba_state == IEEE80211_BA_REQUESTED) {
                /* MLME-ADDBA.confirm(TIMEOUT) */
@@ -618,6 +628,8 @@ ieee80211_rx_ba_timeout(void *arg)
        u_int8_t tid;
        int s;
 
+       ic->ic_stats.is_ht_rx_ba_timeout++;
+
        s = splnet();
 
        /* Block Ack inactivity timeout */




Index: net80211.c
===================================================================
RCS file: /cvs/src/usr.bin/netstat/net80211.c,v
retrieving revision 1.13
diff -u -p -r1.13 net80211.c
--- net80211.c  16 Jan 2015 06:40:10 -0000      1.13
+++ net80211.c  27 Apr 2016 11:29:11 -0000
@@ -114,6 +114,30 @@ net80211_ifstats(char *ifname)
        p(is_cmac_replays, "\t%lu cmac replayed frame%s\n");
        p(is_tkip_icv_errs, "\t%lu tkip icv error%s\n");
        p(is_tkip_replays, "\t%lu tkip replay%s\n");
+       p(is_pbac_errs, "\t%lu pbac error%s\n");
+       p(is_ht_nego_no_mandatory_mcs, "\t%lu HT negotiation failure%s because "
+           "peer does not support MCS 0-7\n");
+       p(is_ht_nego_no_mandatory_mcs, "\t%lu HT negotiation failure%s because "
+           "we do not support basic MCS set\n");
+       p(is_ht_nego_bad_crypto,
+           "\t%lu HT negotiation failure%s because peer uses bad crypto\n");
+       p(is_ht_prot_change, "\t%lu HT protection change%s\n");
+       p(is_ht_rx_ba_agreements, "\t%lu new input block ack agreement%s\n");
+       p(is_ht_tx_ba_agreements, "\t%lu new output block ack agreement%s\n");
+       p(is_ht_rx_frame_below_ba_winstart,
+           "\t%lu input frame%s below block ack window start\n");
+       p(is_ht_rx_frame_above_ba_winend,
+           "\t%lu input frame%s above block ack window end\n");
+       p(is_ht_rx_ba_window_jump, "\t%lu input block ack window jump%s\n");
+       p(is_ht_rx_ba_no_buf, "\t%lu duplicate input block ack frame%s\n");
+       p(is_ht_rx_ba_frame_lost,
+           "\t%lu expected input block ack frame%s never arrived\n");
+       p(is_ht_rx_ba_window_gap_timeout,
+           "\t%lu input block ack window gap%s timed out\n");
+       p(is_ht_rx_ba_timeout,
+           "\t%lu input block ack agreement%s timed out\n");
+       p(is_ht_tx_ba_timeout,
+           "\t%lu output block ack agreement%s timed out\n");
 
        close(s);
 

Reply via email to