On Mon, Apr 30, 2018 at 10:55:22AM +0200, Stefan Sperling wrote:
> I've ran into what seems to be a fairly modern dual-band AP (issued
> by a French ISP). This AP camps on channel 112. This channel requires
> radar detection which may explain the behaviour described below.
> 
> The AP sends 5GHz beacons with a ridicously low RSSI while no client
> is connected, and OpenBSD prefers the 2GHz band...
> 
>   + b8:ee:0e:cb:b3:08    1   +58 54M   ess  privacy   rsn  "ESSID"
>   + b8:ee:0e:cb:b3:09  112    +6 54M   ess  privacy   rsn  "ESSID"
> 
> ... unless we get lucky and the most recently measured RSSI is obtained
> from a probe response instead of a beacon:
> 
>   + b8:ee:0e:cb:b3:08    1   +58 54M   ess  privacy   rsn  "ESSID"
>   + b8:ee:0e:cb:b3:09  112   +61 54M   ess  privacy   rsn  "ESSID"
> 
> tcpdump confirms that beacons are received with a low RSSI of -10dBm
> as long as no other client is connected (nevermind that the positive
> dBm values shown here are bogus; that is a separate issue):
> 
> 10:18:59.773885 802.11 flags=0<>: beacon, timestamp 974393344059, interval 
> 100,
> caps=2421<ESS,PRIVACY,SPECTRUM_MGMT,SHORT_SLOTTIME>, ssid (ESSID), rates 6M* 
> 9M
> 12M* 18M 24M* 36M 48M 54M, ds (chan 112), tim 0x00030000, country 'FR ',
> channel 36 limit 23dB, channel 40 limit 23dB, channel 44 limit 23dB, channel 
> 48
> limit 23dB, channel 52 limit 23dB, channel 56 limit 23dB, channel 60 limit
> 23dB, channel 64 limit 23dB, channel 100 limit 23dB, channel 104 limit 23dB,
> channel 108 limit 23dB, channel 112 limit 23dB, channel 116 limit 23dB, 
> channel
> 132 limit 23dB, channel 136 limit 23dB, channel 140 limit 23dB, power
> constraint 0dB, <radiotap v0, tsf 13340545, 6Mbit/s, chan 144, 11a, sig 10dBm,
> noise -127dBm>
> 
> Whereas probe responses consistently arrive with much more promising
> RSSI values of about -60dBm:
> 
> 10:18:58.889338 802.11 flags=8<RETRY>: probe response, timestamp 974392459305,
> interval 100, caps=2421<ESS,PRIVACY,SPECTRUM_MGMT,SHORT_SLOTTIME>, ssid
> (ESSID), rates 6M* 9M 12M* 18M 24M* 36M 48M 54M, ds (chan 112), country 'FR ',
> channel 36 limit 23dB, channel 40 limit 23dB, channel 44 limit 23dB, channel 
> 48
> limit 23dB, channel 52 limit 23dB, channel 56 limit 23dB, channel 60 limit
> 23dB, channel 64 limit 23dB, channel 100 limit 23dB, channel 104 limit 23dB,
> channel 108 limit 23dB, channel 112 limit 23dB, channel 116 limit 23dB, 
> channel
> 132 limit 23dB, channel 136 limit 23dB, channel 140 limit 23dB, power
> constraint 0dB, <radiotap v0, tsf 12455791, 6Mbit/s, chan 112, 11a, sig 60dBm,
> noise -127dBm>
> 
> I have no idea if and where the 802.11 standard describes this behaviour.
> Maybe there is a way to tell the real RSSI even from beacon frames?
> Does anyone know more about this?
> 
> Setting aside concerns about my lack of understanding of the underlying
> reason for this behaviour, the hack below is sufficient to make this AP
> show up as a strong contender in the candidate list and be preferred
> over 2GHz as it should be.
> 
> Should I commit this hack? I don't see any downsides.
> 
> Index: ieee80211_input.c
> ===================================================================
> RCS file: /cvs/src/sys/net80211/ieee80211_input.c,v
> retrieving revision 1.200
> diff -u -p -r1.200 ieee80211_input.c
> --- ieee80211_input.c 29 Apr 2018 12:11:48 -0000      1.200
> +++ ieee80211_input.c 30 Apr 2018 08:32:58 -0000
> @@ -1689,13 +1689,26 @@ ieee80211_recv_probe_resp(struct ieee802
>               memcpy(ni->ni_essid, &ssid[2], ssid[1]);
>       }
>       IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3);
> -     ni->ni_rssi = rxi->rxi_rssi;
> +     /* XXX validate channel # */
> +     ni->ni_chan = &ic->ic_channels[chan];
> +     if (ic->ic_state == IEEE80211_S_SCAN &&
> +         IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) {
> +             /*
> +              * During a scan on 5Ghz, prefer RSSI measured for probe
> +              * response frames. i.e. don't allow beacons to lower the
> +              * measured RSSI. Some 5GHz APs send beacons with much
> +              * less Tx power than they use for probe responses.
> +              */
> +              if (isprobe)

Properly indent the if clause here

> +                     ni->ni_rssi = rxi->rxi_rssi;
> +             else if (ni->ni_rssi < rxi->rxi_rssi)

Can't this be an OR in the former if clause?

> +                     ni->ni_rssi = rxi->rxi_rssi;
> +     } else
> +             ni->ni_rssi = rxi->rxi_rssi;

And actually, can't all of this be turned into a single if clause? :)
Maybe I am reading this wrong, but aren't you setting everywhere
ni->ni_rssi to rxi->rxi_rssi?

I am a bit confused why this did not work before (when you were setting
the value to rxi_rssi no matter what) and why this extra checking fixed
it.

Maybe I need another cup of coffee to understand this...

>       ni->ni_rstamp = rxi->rxi_tstamp;
>       memcpy(ni->ni_tstamp, tstamp, sizeof(ni->ni_tstamp));
>       ni->ni_intval = bintval;
>       ni->ni_capinfo = capinfo;
> -     /* XXX validate channel # */
> -     ni->ni_chan = &ic->ic_channels[chan];
>       ni->ni_erp = erp;
>       /* NB: must be after ni_chan is setup */
>       ieee80211_setup_rates(ic, ni, rates, xrates, IEEE80211_F_DOSORT);

Reply via email to