Subject: bin/33823: wpa_supplicant -w broken
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: None <nbgnats@anastigmatix.net>
List: netbsd-bugs
Date: 06/25/2006 20:50:00
>Number:         33823
>Category:       bin
>Synopsis:       wpa_supplicant -w broken
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Jun 25 20:50:00 +0000 2006
>Originator:     Chapman Flack
>Release:        3.99.21
>Organization:
>Environment:
>Description:
The -w option to wpa_supplicant directs it to lie in wait until the named
interface is attached.

On NetBSD it exits with "Failed to initialize driver interface".
If -d is added, the additional output includes "wpa_driver_bsd_init:
interface ath0 does not exist" and "Failed to add interface ath0."

In other words, it is not even trying to do -w right.

The problem is in src/usr.sbin/wpa/wpa_supplicant/driver_netbsd.c
which contains this comment:

/*
 * NB: We require the interface name be mappable to an index.
 *     This implies we do not support having wpa_supplicant
 *     wait for an interface to appear. This seems ok; that
 *     doesn't belong here; it's really the job of devd.
 *     XXXSCW: devd is FreeBSD-specific.
 */
>How-To-Repeat:
Use wpa_supplicant -w for an interface that is not yet attached.
Or read the code.
>Fix:
This is at the very least an embarrassing doc bug. Of the at least
two people who knew that driver_netbsd.c was going to break
wpa_supplicant -- the one who wrote that not implementing the
documented behavior "seems ok", and the one who noticed that
the suggested alternative was a FreeBSDism -- nobody bothered to say
so in the manual. In fact, the one sentence in the man page that
comes closest to saying so has been /commented out/!

But how hard would it be to implement the documented behavior?
Save the iface name in the wpa_driver_bsd_data struct and mark
the rest uninitialized, with a real_init() callback for first
use? If the cost of checking for first-call in every method would
be a concern, why not populate the struct at first with init-checking
methods, and have real_init() replace them?

I don't know the intricacies of the ieee80211 code to know how hard
that would be, but bin/31513 and bin/32537 are probably consequences
of the same issue: they deal with breakage when an already initialized
interface goes away.

Fundamentally, it looks as if the author of wpa_supplicant intended
a drv structure to be something that can be initialized and afterward
represent either an interface that is present and active or one that
isn't. We've plugged in a bsd driver implementation that doesn't follow
that design, and the reported bugs are the consequences of that,
either when a device isn't present at init time, or when it goes away
later. If our drv implementation had a not-here state, it should just
revert to that state on device disappearance; wpa_supplicant itself
seems designed for that possibility.