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 &&

Reply via email to