The branch main has been updated by bz:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=eb4722614a933c331afe02f6a6870303d7f7bb22

commit eb4722614a933c331afe02f6a6870303d7f7bb22
Author:     Bjoern A. Zeeb <b...@freebsd.org>
AuthorDate: 2025-08-27 07:25:55 +0000
Commit:     Bjoern A. Zeeb <b...@freebsd.org>
CommitDate: 2025-08-29 13:18:42 +0000

    LinuxKPI: 802.11: improve scan/beacon tracing in RX path
    
    In one of my setups I am sometimes seeing "ghost beacons" (beacons from a
    BSSID on a 2nd channel where it is not sending beacons; also checked with
    a monitor node to be sure).
    In order to rule out later processing errors I added debugging early on
    in the LinuxKPI 802.11 RX path.  This will at least help us (users) to
    debug possible problems more easily by turning on scan debugging (either
    here, or using wlandebug +scan to get the net80211 view on it, or both).
    
    Sponsored by:   The FreeBSD Foundation
    MFC after:      3 days
---
 sys/compat/linuxkpi/common/src/linux_80211.c | 74 +++++++++++++++++++++++++---
 1 file changed, 67 insertions(+), 7 deletions(-)

diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c 
b/sys/compat/linuxkpi/common/src/linux_80211.c
index 4ac2482e4138..55d84789e05a 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211.c
+++ b/sys/compat/linuxkpi/common/src/linux_80211.c
@@ -7243,6 +7243,63 @@ lkpi_convert_rx_status(struct ieee80211_hw *hw, struct 
lkpi_sta *lsta,
        }
 }
 
+#ifdef LINUXKPI_DEBUG_80211
+static void
+lkpi_rx_log_beacon(struct mbuf *m, struct lkpi_hw *lhw,
+    struct ieee80211_rx_status *rx_status)
+{
+       struct ieee80211_mgmt *f;
+       uint8_t *e;
+       char ssid[IEEE80211_NWID_LEN * 4 + 1];
+
+       memset(ssid, '\0', sizeof(ssid));
+
+       f = mtod(m, struct ieee80211_mgmt *);
+       e = f->u.beacon.variable;
+       /*
+        * Usually SSID is right after the fixed part and for debugging we will
+        * be fine should we miss it if it is not.
+        */
+       while ((e - (uint8_t *)f) < m->m_len) {
+               if (*e == IEEE80211_ELEMID_SSID)
+                       break;
+               e += (2 + *(e + 1));
+       }
+       if (*e == IEEE80211_ELEMID_SSID) {
+               int i, len;
+               char *p;
+
+               p = ssid;
+               len = m->m_len - ((e + 2) - (uint8_t *)f);
+               if (len > *(e + 1))
+                       len = *(e + 1);
+               e += 2;
+               for (i = 0; i < len; i++) {
+                       /* Printable character? */
+                       if (*e >= 0x20 && *e < 0x7f) {
+                               *p++ = *e++;
+                       } else {
+                               snprintf(p, 5, "%#04x", *e++);
+                               p += 4;
+                       }
+               }
+               *p = '\0';
+       }
+
+       /* We print skb, skb->data, m as we are seeing 'ghost beacons'. */
+       TRACE_SCAN(lhw->ic, "Beacon: scan_flags %b, band %s freq %u chan %-4d "
+           "len %d { %#06x %#06x %6D %6D %6D %#06x %ju %u %#06x SSID '%s' }",
+           lhw->scan_flags, LKPI_LHW_SCAN_BITS,
+           lkpi_nl80211_band_name(rx_status->band), rx_status->freq,
+           linuxkpi_ieee80211_frequency_to_channel(rx_status->freq, 0),
+           m->m_pkthdr.len, f->frame_control, f->duration_id,
+           f->da, ":", f->sa, ":", f->bssid, ":", f->seq_ctrl,
+           (uintmax_t)le64_to_cpu(f->u.beacon.timestamp),
+           le16_to_cpu(f->u.beacon.beacon_int),
+           le16_to_cpu(f->u.beacon.capab_info), ssid);
+}
+#endif
+
 /* For %list see comment towards the end of the function. */
 void
 linuxkpi_ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
@@ -7299,13 +7356,15 @@ linuxkpi_ieee80211_rx(struct ieee80211_hw *hw, struct 
sk_buff *skb,
        is_beacon = ieee80211_is_beacon(hdr->frame_control);
 
 #ifdef LINUXKPI_DEBUG_80211
-       if (is_beacon)
-               TRACE_SCAN(ic, "Beacon: scan_flags %b, band %s freq %u chan %d",
-                   lhw->scan_flags, LKPI_LHW_SCAN_BITS,
-                   lkpi_nl80211_band_name(rx_status->band), rx_status->freq,
-                   linuxkpi_ieee80211_frequency_to_channel(rx_status->freq, 
0));
+       /*
+        * We use the mbuf here as otherwise the variable part might
+        * be in skb frags.
+        */
+       if (is_beacon && ((linuxkpi_debug_80211 & D80211_SCAN) != 0))
+               lkpi_rx_log_beacon(m, lhw, rx_status);
 
-       if (is_beacon && (linuxkpi_debug_80211 & D80211_TRACE_RX_BEACONS) == 0)
+       if (is_beacon && (linuxkpi_debug_80211 & D80211_TRACE_RX_BEACONS) == 0 
&&
+          (linuxkpi_debug_80211 & D80211_SCAN) == 0)
                goto no_trace_beacons;
 
        if (linuxkpi_debug_80211 & D80211_TRACE_RX)
@@ -7320,7 +7379,8 @@ linuxkpi_ieee80211_rx(struct ieee80211_hw *hw, struct 
sk_buff *skb,
                hexdump(mtod(m, const void *), m->m_len, "RX (raw) ", 0);
 
        /* Implement a dump_rxcb() !!! */
-       if (linuxkpi_debug_80211 & D80211_TRACE_RX)
+       if ((linuxkpi_debug_80211 & D80211_TRACE_RX) != 0 ||
+           (linuxkpi_debug_80211 & D80211_SCAN) != 0)
                printf("TRACE-RX: %s: RXCB: %ju %ju %u, %b, %u, %#0x, %#0x, "
                    "%u band %u, %u { %d %d %d %d }, %d, %#x %#x %#x %#x %u %u 
%u\n",
                        __func__,

Reply via email to