[PATCH]: wait_for_interface poll on driver interface initialization
Kel Modderman
kel
Sun Jan 13 01:41:21 PST 2008
The attached patch attempts to fix the wait_for_interface option by
reorganizing wpa_supplicant_driver_init() and wpa_supplicant_init_iface2() so
that polling is done before the driver interface is prepared for work.
Currently, the driver interface is prepared before wait_for_interface is
considered, resulting in broken -w command line option, and ignoring any driver
parameters. See the following debug output that was captured with an atheros
cardbus card using madwifi driver:
# wext driver interface - not correctly setup for scanning when network
# interface exists after waiting.
#
# /sbin/wpa_supplicant -w -dd -P /var/run/wpa_supplicant.ath0.pid -i ath0 -D wext -c /etc/wpa_supplicant/conf.ath0
<snip>
Initializing interface (2) 'ath0'
EAPOL: SUPP_PAE entering state DISCONNECTED
EAPOL: KEY_RX entering state NO_KEY_RECEIVE
EAPOL: SUPP_BE entering state INITIALIZE
EAP: EAP entering state DISABLED
EAPOL: External notification - portEnabled=0
EAPOL: External notification - portValid=0
ioctl[SIOCGIFFLAGS]: No such device
Could not get interface 'ath0' flags
ioctl[SIOCSIWPMKSA]: No such device
ioctl[SIOCSIWMODE]: No such device
Could not configure driver to use managed mode
ioctl[SIOCGIWRANGE]: No such device
WEXT: Operstate: linkmode=1, operstate=5
ioctl[SIOCGIFINDEX]: No such device
Waiting for interface..
ioctl[SIOCGIFINDEX]: No such device
Waiting for interface..
ioctl[SIOCGIFINDEX]: No such device
Waiting for interface..
Own MAC address: 00:0f:b5:a4:8d:01
wpa_driver_wext_set_wpa
wpa_driver_wext_set_key: alg=0 key_idx=0 set_tx=0 seq_len=0 key_len=0
wpa_driver_wext_set_key: alg=0 key_idx=1 set_tx=0 seq_len=0 key_len=0
wpa_driver_wext_set_key: alg=0 key_idx=2 set_tx=0 seq_len=0 key_len=0
wpa_driver_wext_set_key: alg=0 key_idx=3 set_tx=0 seq_len=0 key_len=0
wpa_driver_wext_set_countermeasures
wpa_driver_wext_set_drop_unencrypted
RSN: flushing PMKID list in the driver
Setting scan request: 0 sec 100000 usec
Using existing control interface directory.
ctrl_interface_group=108 (from group name 'netdev')
Added interface ath0
EAPOL: disable timer tick
Ignore event for foreign ifindex 6
Ignore event for foreign ifindex 7
l2_packet_receive - recvfrom: Network is down
State: DISCONNECTED -> SCANNING
Starting AP scan (broadcast SSID)
Trying to get current scan results first without requesting a new scan to speed up initial association
Received 0 bytes of scan results (0 BSSes)
Selecting BSS from priority group 0
Try to find WPA-enabled AP
Try to find non-WPA AP
No suitable AP found.
Setting scan request: 0 sec 0 usec
Starting AP scan (broadcast SSID)
ioctl[SIOCSIWSCAN]: Network is down
Scan requested (ret=-1) - scan timeout 5 seconds
Failed to initiate AP scan.
Setting scan request: 10 sec 0 usec
Scan timeout - try to get results
Received 0 bytes of scan results (0 BSSes)
Selecting BSS from priority group 0
Try to find WPA-enabled AP
Try to find non-WPA AP
No suitable AP found.
Setting scan request: 5 sec 0 usec
Starting AP scan (broadcast SSID)
ioctl[SIOCSIWSCAN]: Network is down
Scan requested (ret=-1) - scan timeout 5 seconds
Failed to initiate AP scan.
Setting scan request: 10 sec 0 usec
Scan timeout - try to get results
Received 0 bytes of scan results (0 BSSes)
Selecting BSS from priority group 0
Try to find WPA-enabled AP
Try to find non-WPA AP
No suitable AP found.
Setting scan request: 5 sec 0 usec
Starting AP scan (broadcast SSID)
ioctl[SIOCSIWSCAN]: Network is down
Scan requested (ret=-1) - scan timeout 5 seconds
Failed to initiate AP scan.
Setting scan request: 10 sec 0 usec
Scan timeout - try to get results
Received 0 bytes of scan results (0 BSSes)
Selecting BSS from priority group 0
Try to find WPA-enabled AP
Try to find non-WPA AP
No suitable AP found.
Setting scan request: 5 sec 0 usec
CTRL-EVENT-TERMINATING - signal 2 received
Removing interface ath0
State: SCANNING -> DISCONNECTED
wpa_driver_wext_set_operstate: operstate 0->0 (DORMANT)
WEXT: Operstate: linkmode=-1, operstate=5
No keys have been configured - skip key clearing
EAPOL: External notification - portEnabled=0
EAPOL: External notification - portValid=0
wpa_driver_wext_set_wpa
wpa_driver_wext_set_drop_unencrypted
wpa_driver_wext_set_countermeasures
No keys have been configured - skip key clearing
Control interface directory not empty - leaving it behind
Cancelling scan request
Cancelling authentication timeout
WEXT: Operstate: linkmode=0, operstate=6
# madwifi driver interface fails to initialize, no polling occurs
#
# /sbin/wpa_supplicant -w -dd -P /var/run/wpa_supplicant.ath0.pid -i ath0 -D madwifi -c /etc/wpa_supplicant/conf.ath0
<snip>
Initializing interface (2) 'ath0'
EAPOL: SUPP_PAE entering state DISCONNECTED
EAPOL: KEY_RX entering state NO_KEY_RECEIVE
EAPOL: SUPP_BE entering state INITIALIZE
EAP: EAP entering state DISABLED
EAPOL: External notification - portEnabled=0
EAPOL: External notification - portValid=0
ioctl[SIOCGIFFLAGS]: No such device
Could not get interface 'ath0' flags
ioctl[SIOCSIWPMKSA]: No such device
ioctl[SIOCSIWMODE]: No such device
Could not configure driver to use managed mode
ioctl[SIOCGIWRANGE]: No such device
WEXT: Operstate: linkmode=1, operstate=5
ioctl[IEEE80211_IOCTL_SETPARAM]: No such device
wpa_driver_madwifi_init: failed to set wpa_supplicant-based roaming
ioctl[SIOCSIWAP]: No such device
WEXT: Operstate: linkmode=0, operstate=6
ioctl[SIOCGIFFLAGS]: No such device
Failed to initialize driver interface
Failed to add interface ath0
Cancelling scan request
Cancelling authentication timeout
Most drivers either use wpa_driver_wext_init() or fail when interface
properties cannot be determined in their init function. If polling on driver
initialization is to succeed, the wpa_driver_*_init() function must return
NULL when no interface exists. This patch modifies wpa_driver_wext_init()
to return NULL when interface flags cannot be determined.
I'd be just as happy to see the wait_for_interface stuff completely removed,
as any distro should have some hotplug agent or similar support in their
networking toolset. Therefore, I see no need for this option to exist at all,
but while it does exist and does not work, I'll have a go at fixing it ;-)
Signed-off-by: Kel Modderman <kel at otaku42.de>
---
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -1469,38 +1469,104 @@
/**
- * wpa_supplicant_driver_init - Initialize driver interface parameters
+ * wpa_supplicant_driver_init - Initialize driver interface
* @wpa_s: Pointer to wpa_supplicant data
* @wait_for_interface: 0 = do not wait for the interface (reports a failure if
* the interface is not present), 1 = wait until the interface is available
* Returns: 0 on success, -1 on failure
*
- * This function is called to initialize driver interface parameters.
- * wpa_drv_init() must have been called before this function to initialize the
- * driver interface.
+ * This function is called to initialize driver interface and driver interface
+ * parameters.
*/
int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s,
int wait_for_interface)
{
+ const char *ifname;
static int interface_count = 0;
+ /* Initialize driver interface and register driver event handler before
+ * L2 receive handler so that association events are processed before
+ * EAPOL-Key packets if both become available for the same select()
+ * call. */
for (;;) {
- if (wpa_s->driver->send_eapol) {
- const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
- if (addr)
- os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
- break;
+ wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname);
+ if (wpa_s->drv_priv == NULL) {
+ if (wait_for_interface) {
+ wpa_printf(MSG_DEBUG, "Waiting for interface "
+ "'%s'...", wpa_s->ifname);
+ os_sleep(5, 0);
+ } else {
+ wpa_printf(MSG_ERROR, "Failed to initialize "
+ "driver interface for '%s'",
+ wpa_s->ifname);
+ return -1;
+ }
}
+ else
+ break;
+ }
+
+ if (wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param) < 0) {
+ wpa_printf(MSG_ERROR, "Driver interface rejected "
+ "driver_param '%s'", wpa_s->conf->driver_param);
+ return -1;
+ }
+
+ ifname = wpa_drv_get_ifname(wpa_s);
+ if (ifname && os_strcmp(ifname, wpa_s->ifname) != 0) {
+ wpa_printf(MSG_DEBUG, "Driver interface replaced interface "
+ "name with '%s'", ifname);
+ os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname));
+ }
+
+ if (wpa_supplicant_init_wpa(wpa_s) < 0)
+ return -1;
+
+ wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname,
+ wpa_s->bridge_ifname[0] ? wpa_s->bridge_ifname :
+ NULL);
+ wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
+ wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
+
+ if (wpa_s->conf->dot11RSNAConfigPMKLifetime &&
+ wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
+ wpa_s->conf->dot11RSNAConfigPMKLifetime)) {
+ wpa_printf(MSG_ERROR, "Invalid WPA parameter value for "
+ "dot11RSNAConfigPMKLifetime");
+ return -1;
+ }
+
+ if (wpa_s->conf->dot11RSNAConfigPMKReauthThreshold &&
+ wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
+ wpa_s->conf->dot11RSNAConfigPMKReauthThreshold)) {
+ wpa_printf(MSG_ERROR, "Invalid WPA parameter value for "
+ "dot11RSNAConfigPMKReauthThreshold");
+ return -1;
+ }
+
+ if (wpa_s->conf->dot11RSNAConfigSATimeout &&
+ wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT,
+ wpa_s->conf->dot11RSNAConfigSATimeout)) {
+ wpa_printf(MSG_ERROR, "Invalid WPA parameter value for "
+ "dot11RSNAConfigSATimeout");
+ return -1;
+ }
+
+ if (wpa_s->driver->send_eapol) {
+ const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
+ if (addr)
+ os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
+ } else {
wpa_s->l2 = l2_packet_init(wpa_s->ifname,
wpa_drv_get_mac_addr(wpa_s),
ETH_P_EAPOL,
wpa_supplicant_rx_eapol, wpa_s, 0);
- if (wpa_s->l2)
- break;
- else if (!wait_for_interface)
+ if (wpa_s->l2 == NULL) {
+ wpa_printf(MSG_ERROR, "Failed to open l2_packet "
+ "connection for interface '%s'",
+ wpa_s->ifname);
return -1;
- wpa_printf(MSG_DEBUG, "Waiting for interface..");
- os_sleep(5, 0);
+ }
}
if (wpa_s->l2 && l2_packet_get_own_addr(wpa_s->l2, wpa_s->own_addr)) {
@@ -1671,7 +1737,6 @@
static int wpa_supplicant_init_iface2(struct wpa_supplicant *wpa_s,
int wait_for_interface)
{
- const char *ifname;
struct wpa_driver_capa capa;
wpa_printf(MSG_DEBUG, "Initializing interface (2) '%s'",
@@ -1684,61 +1749,6 @@
eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
- /* Initialize driver interface and register driver event handler before
- * L2 receive handler so that association events are processed before
- * EAPOL-Key packets if both become available for the same select()
- * call. */
- wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname);
- if (wpa_s->drv_priv == NULL) {
- wpa_printf(MSG_ERROR, "Failed to initialize driver interface");
- return -1;
- }
- if (wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param) < 0) {
- wpa_printf(MSG_ERROR, "Driver interface rejected "
- "driver_param '%s'", wpa_s->conf->driver_param);
- return -1;
- }
-
- ifname = wpa_drv_get_ifname(wpa_s);
- if (ifname && os_strcmp(ifname, wpa_s->ifname) != 0) {
- wpa_printf(MSG_DEBUG, "Driver interface replaced interface "
- "name with '%s'", ifname);
- os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname));
- }
-
- if (wpa_supplicant_init_wpa(wpa_s) < 0)
- return -1;
-
- wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname,
- wpa_s->bridge_ifname[0] ? wpa_s->bridge_ifname :
- NULL);
- wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
- wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
-
- if (wpa_s->conf->dot11RSNAConfigPMKLifetime &&
- wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
- wpa_s->conf->dot11RSNAConfigPMKLifetime)) {
- wpa_printf(MSG_ERROR, "Invalid WPA parameter value for "
- "dot11RSNAConfigPMKLifetime");
- return -1;
- }
-
- if (wpa_s->conf->dot11RSNAConfigPMKReauthThreshold &&
- wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
- wpa_s->conf->dot11RSNAConfigPMKReauthThreshold)) {
- wpa_printf(MSG_ERROR, "Invalid WPA parameter value for "
- "dot11RSNAConfigPMKReauthThreshold");
- return -1;
- }
-
- if (wpa_s->conf->dot11RSNAConfigSATimeout &&
- wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT,
- wpa_s->conf->dot11RSNAConfigSATimeout)) {
- wpa_printf(MSG_ERROR, "Invalid WPA parameter value for "
- "dot11RSNAConfigSATimeout");
- return -1;
- }
-
if (wpa_supplicant_driver_init(wpa_s, wait_for_interface) < 0) {
return -1;
}
--- a/src/drivers/driver_wext.c
+++ b/src/drivers/driver_wext.c
@@ -924,9 +924,7 @@
s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if (s < 0) {
perror("socket(PF_NETLINK,SOCK_RAW,NETLINK_ROUTE)");
- close(drv->ioctl_sock);
- os_free(drv);
- return NULL;
+ goto fail;
}
os_memset(&local, 0, sizeof(local));
@@ -934,10 +932,7 @@
local.nl_groups = RTMGRP_LINK;
if (bind(s, (struct sockaddr *) &local, sizeof(local)) < 0) {
perror("bind(netlink)");
- close(s);
- close(drv->ioctl_sock);
- os_free(drv);
- return NULL;
+ goto fail2;
}
eloop_register_read_sock(s, wpa_driver_wext_event_receive, drv, ctx);
@@ -945,9 +940,10 @@
drv->mlme_sock = -1;
- if (wpa_driver_wext_get_ifflags(drv, &flags) != 0)
+ if (wpa_driver_wext_get_ifflags(drv, &flags) != 0) {
printf("Could not get interface '%s' flags\n", drv->ifname);
- else if (!(flags & IFF_UP)) {
+ goto fail3;
+ } else if (!(flags & IFF_UP)) {
if (wpa_driver_wext_set_ifflags(drv, flags | IFF_UP) != 0) {
printf("Could not set interface '%s' UP\n",
drv->ifname);
@@ -996,6 +992,16 @@
wpa_driver_wext_send_oper_ifla(drv, 1, IF_OPER_DORMANT);
return drv;
+
+fail3:
+ close(drv->event_sock);
+ eloop_unregister_read_sock(s);
+fail2:
+ close(s);
+fail:
+ close(drv->ioctl_sock);
+ os_free(drv);
+ return NULL;
}
---
More information about the Hostap
mailing list