Date: Tue, 11 Nov 2003 21:51:34 -0800 (PST) From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 42105 for review Message-ID: <200311120551.hAC5pYMS046795@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=42105 Change 42105 by sam@sam_ebb on 2003/11/11 21:50:53 Deal with a scan request prior to an interface being marked up. This may happen, for example, if someone isn't running devd, inserts a card, and then runs wicontrol -i ath0 -L (the wi driver handels this directly so is not impacted). In this case the scan request happens before ic_bss->ni_chan has been set to a valid value so the driver blows up. Always validate state prior to initiating a scan and, for now, disallow a scan if the device isn't marked IFF_UP. In the future it would be good to support this so that users can scan for AP's before marking an interface up. Affected files ... .. //depot/projects/netperf/sys/net80211/ieee80211_ioctl.c#7 edit Differences ... ==== //depot/projects/netperf/sys/net80211/ieee80211_ioctl.c#7 (text+ko) ==== @@ -376,6 +376,43 @@ #undef IEEERATE } +/* + * Prepare to do a user-initiated scan for AP's. If no + * current/default channel is setup or the current channel + * is invalid then pick the first available channel from + * the active list as the place to start the scan. + */ +static int +ieee80211_setupscan(struct ieee80211com *ic) +{ + u_char *chanlist = ic->ic_chan_active; + int i; + + if (ic->ic_ibss_chan == NULL || + isclr(chanlist, ieee80211_chan2ieee(ic, ic->ic_ibss_chan))) { + for (i = 0; i <= IEEE80211_CHAN_MAX; i++) + if (isset(chanlist, i)) { + ic->ic_ibss_chan = &ic->ic_channels[i]; + goto found; + } + return EINVAL; /* no active channels */ +found: + ; + } + if (ic->ic_bss->ni_chan == IEEE80211_CHAN_ANYC || + isclr(chanlist, ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan))) + ic->ic_bss->ni_chan = ic->ic_ibss_chan; + /* + * XXX don't permit a scan to be started unless we + * know the device is ready. For the moment this means + * the device is marked up as this is the required to + * initialize the hardware. It would be better to permit + * scanning prior to being up but that'll require some + * changes to the infrastructure. + */ + return (ic->ic_if.if_flags & IFF_UP) ? 0 : ENETRESET; +} + int ieee80211_cfgset(struct ifnet *ifp, u_long cmd, caddr_t data) { @@ -659,8 +696,9 @@ case WI_RID_SCAN_REQ: /* XXX wicontrol */ if (ic->ic_opmode == IEEE80211_M_HOSTAP) break; - /* NB: ignore channel list and tx rate parameters */ - error = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); + error = ieee80211_setupscan(ic); + if (error == 0) + error = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); break; case WI_RID_SCAN_APS: if (ic->ic_opmode == IEEE80211_M_HOSTAP) @@ -692,18 +730,11 @@ } memcpy(ic->ic_chan_active, chanlist, sizeof(ic->ic_chan_active)); - if (isclr(chanlist, ieee80211_chan2ieee(ic, ic->ic_ibss_chan))) { - for (i = 0; i <= IEEE80211_CHAN_MAX; i++) - if (isset(chanlist, i)) { - ic->ic_ibss_chan = &ic->ic_channels[i]; - break; - } - } - if (isclr(chanlist, ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan))) - ic->ic_bss->ni_chan = ic->ic_ibss_chan; - if (wreq.wi_type == WI_RID_CHANNEL_LIST) + error = ieee80211_setupscan(ic); + if (wreq.wi_type == WI_RID_CHANNEL_LIST) { + /* NB: ignore error from ieee80211_setupscan */ error = ENETRESET; - else + } else if (error == 0) error = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); break; default:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200311120551.hAC5pYMS046795>