Anybody?
Did I write too much of a wall of text to explain the diff?
In that case, just read the diff. It should make sense.
On Sun, Dec 11, 2016 at 04:38:44PM +0100, Stefan Sperling wrote:
> This diff makes 'tcpdump -i iwn0 -y IEEE802_11_RADIO' show the
> correct mode for a channel in 11n mode.
> Before:
> <radiotap v0, chan 36, 11a, sig -46dBm, noise -91dBm>
> After:
> <radiotap v0, chan 36, 11n, sig -46dBm, noise -91dBm>
>
> Unfortunately this requires a kernel tweak because the kernel must
> be more careful about the channel flags it passes to userland.
>
> Channels exist in the 11b/g (2GHz) and 11a (5GHz) ranges.
> So net80211 has a "mode" concept, where a given mode is available
> if supported channels exist in a particular range. And there is the
> default "auto" mode which picks one of the other available modes.
> (This may not be the best design but it is how it was designed
> historically. Changing this is not in my radar.)
>
> The HT-channel flag is set to indicate whether a channel may be used
> in 11n mode. In practice this is just the superset of all channels
> supported by the device. When 11n support was introduced it was easier to
> fold the new 11n mode into the existing code with a flag like this, and
> avoid letting 11n mode be a special case which works against this design.
>
> And this HT-channel flag is set regardless of whether we're currently in
> 11n mode because we need this flag to enter 11n mode from another mode.
> A mode which has no channels available to it is not available.
> So the kernel needs this flag to be set on all channels at all times
> if the driver supports 11n.
>
> Now, we copy this flag out to userspace even in non-11n modes.
> If the kernel instead omits the HT-channel flag from the userspace copy if
> the current mode is not 11n, then tcpdump can inspect this flag to detect
> whether the channel is in fact an "11n" channel and print the mode correctly.
>
> In the end, this is just a cosmetic fix. If this is too much code
> churn and quirks for too little gain, I am happy to drop this diff.
>
> Index: sys/dev/pci/if_iwm.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/if_iwm.c,v
> retrieving revision 1.154
> diff -u -p -r1.154 if_iwm.c
> --- sys/dev/pci/if_iwm.c 10 Dec 2016 19:03:53 -0000 1.154
> +++ sys/dev/pci/if_iwm.c 11 Dec 2016 14:54:58 -0000
> @@ -3339,14 +3339,17 @@ iwm_rx_rx_mpdu(struct iwm_softc *sc, str
> if (sc->sc_drvbpf != NULL) {
> struct mbuf mb;
> struct iwm_rx_radiotap_header *tap = &sc->sc_rxtap;
> + uint16_t chan_flags;
>
> tap->wr_flags = 0;
> if (phy_info->phy_flags & htole16(IWM_PHY_INFO_FLAG_SHPREAMBLE))
> tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
> tap->wr_chan_freq =
> htole16(ic->ic_channels[phy_info->channel].ic_freq);
> - tap->wr_chan_flags =
> - htole16(ic->ic_channels[phy_info->channel].ic_flags);
> + chan_flags = ic->ic_channels[phy_info->channel].ic_flags;
> + if (ic->ic_curmode != IEEE80211_MODE_11N)
> + chan_flags &= ~IEEE80211_CHAN_HT;
> + tap->wr_chan_flags = htole16(chan_flags);
> tap->wr_dbm_antsignal = (int8_t)rssi;
> tap->wr_dbm_antnoise = (int8_t)sc->sc_noise;
> tap->wr_tsft = phy_info->system_timestamp;
> @@ -3991,10 +3994,14 @@ iwm_tx(struct iwm_softc *sc, struct mbuf
> if (sc->sc_drvbpf != NULL) {
> struct mbuf mb;
> struct iwm_tx_radiotap_header *tap = &sc->sc_txtap;
> + uint16_t chan_flags;
>
> tap->wt_flags = 0;
> tap->wt_chan_freq = htole16(ni->ni_chan->ic_freq);
> - tap->wt_chan_flags = htole16(ni->ni_chan->ic_flags);
> + chan_flags = ni->ni_chan->ic_flags;
> + if (ic->ic_curmode != IEEE80211_MODE_11N)
> + chan_flags &= ~IEEE80211_CHAN_HT;
> + tap->wt_chan_flags = htole16(chan_flags);
> if ((ni->ni_flags & IEEE80211_NODE_HT) &&
> !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
> type == IEEE80211_FC0_TYPE_DATA &&
> Index: sys/dev/pci/if_iwn.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/if_iwn.c,v
> retrieving revision 1.178
> diff -u -p -r1.178 if_iwn.c
> --- sys/dev/pci/if_iwn.c 10 Dec 2016 13:22:07 -0000 1.178
> +++ sys/dev/pci/if_iwn.c 11 Dec 2016 14:54:25 -0000
> @@ -2130,14 +2130,17 @@ iwn_rx_done(struct iwn_softc *sc, struct
> if (sc->sc_drvbpf != NULL) {
> struct mbuf mb;
> struct iwn_rx_radiotap_header *tap = &sc->sc_rxtap;
> + uint16_t chan_flags;
>
> tap->wr_flags = 0;
> if (stat->flags & htole16(IWN_STAT_FLAG_SHPREAMBLE))
> tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
> tap->wr_chan_freq =
> htole16(ic->ic_channels[stat->chan].ic_freq);
> - tap->wr_chan_flags =
> - htole16(ic->ic_channels[stat->chan].ic_flags);
> + chan_flags = ic->ic_channels[stat->chan].ic_flags;
> + if (ic->ic_curmode != IEEE80211_MODE_11N)
> + chan_flags &= ~IEEE80211_CHAN_HT;
> + tap->wr_chan_flags = htole16(chan_flags);
> tap->wr_dbm_antsignal = (int8_t)rssi;
> tap->wr_dbm_antnoise = (int8_t)sc->noise;
> tap->wr_tsft = stat->tstamp;
> @@ -2908,10 +2911,14 @@ iwn_tx(struct iwn_softc *sc, struct mbuf
> if (sc->sc_drvbpf != NULL) {
> struct mbuf mb;
> struct iwn_tx_radiotap_header *tap = &sc->sc_txtap;
> + uint16_t chan_flags;
>
> tap->wt_flags = 0;
> tap->wt_chan_freq = htole16(ni->ni_chan->ic_freq);
> - tap->wt_chan_flags = htole16(ni->ni_chan->ic_flags);
> + chan_flags = ni->ni_chan->ic_flags;
> + if (ic->ic_curmode != IEEE80211_MODE_11N)
> + chan_flags &= ~IEEE80211_CHAN_HT;
> + tap->wt_chan_flags = htole16(chan_flags);
> if ((ni->ni_flags & IEEE80211_NODE_HT) &&
> !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
> type == IEEE80211_FC0_TYPE_DATA) {
> Index: sys/net80211/ieee80211_ioctl.c
> ===================================================================
> RCS file: /cvs/src/sys/net80211/ieee80211_ioctl.c,v
> retrieving revision 1.44
> diff -u -p -r1.44 ieee80211_ioctl.c
> --- sys/net80211/ieee80211_ioctl.c 15 Sep 2016 03:32:48 -0000 1.44
> +++ sys/net80211/ieee80211_ioctl.c 11 Dec 2016 14:56:03 -0000
> @@ -71,6 +71,8 @@ ieee80211_node2req(struct ieee80211com *
> /* Channel and rates */
> nr->nr_channel = ieee80211_chan2ieee(ic, ni->ni_chan);
> nr->nr_chan_flags = ni->ni_chan->ic_flags;
> + if (ic->ic_curmode != IEEE80211_MODE_11N)
> + nr->nr_chan_flags &= ~IEEE80211_CHAN_HT;
> nr->nr_nrates = ni->ni_rates.rs_nrates;
> bcopy(ni->ni_rates.rs_rates, nr->nr_rates, IEEE80211_RATE_MAXSIZE);
>
> Index: usr.sbin/tcpdump/print-802_11.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/tcpdump/print-802_11.c,v
> retrieving revision 1.35
> diff -u -p -r1.35 print-802_11.c
> --- usr.sbin/tcpdump/print-802_11.c 19 Nov 2016 19:35:46 -0000 1.35
> +++ usr.sbin/tcpdump/print-802_11.c 11 Dec 2016 14:18:05 -0000
> @@ -1101,7 +1101,12 @@ ieee802_11_radio_if_print(u_char *user,
>
> printf(", chan %u", ieee80211_any2ieee(freq, flags));
>
> - if (flags & IEEE80211_CHAN_DYN &&
> + if (flags & IEEE80211_CHAN_HT)
> + printf(", 11n");
> + else if (flags & IEEE80211_CHAN_DYN &&
> + flags & IEEE80211_CHAN_2GHZ)
> + printf(", 11g");
> + else if (flags & IEEE80211_CHAN_DYN &&
> flags & IEEE80211_CHAN_2GHZ)
> printf(", 11g");
> else if (flags & IEEE80211_CHAN_CCK &&