wired: Wait for the link to become active before sending packets

Interfaces that take one or two seconds to reconfigure the link after we
set IFF_ALLMULTI or after we bring the interface up were dropping the
initial TX EAPOL packet which caused excessive delays in authentication.
This change applies to FreeBSD/DragonFly only.

Signed-hostap: Rui Paulo <rpaulo@FreeBSD.org>
This commit is contained in:
Rui Paulo 2013-08-25 11:40:19 +03:00 committed by Jouni Malinen
parent d393de1d27
commit ba873bdf86

View file

@ -17,6 +17,7 @@
#endif /* __linux__ */
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
#include <net/if_dl.h>
#include <net/if_media.h>
#endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) */
#ifdef __sun__
#include <sys/sockio.h>
@ -454,6 +455,34 @@ static int wpa_driver_wired_set_ifflags(const char *ifname, int flags)
}
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
static int wpa_driver_wired_get_ifstatus(const char *ifname, int *status)
{
struct ifmediareq ifmr;
int s;
s = socket(PF_INET, SOCK_DGRAM, 0);
if (s < 0) {
perror("socket");
return -1;
}
os_memset(&ifmr, 0, sizeof(ifmr));
os_strlcpy(ifmr.ifm_name, ifname, IFNAMSIZ);
if (ioctl(s, SIOCGIFMEDIA, (caddr_t) &ifmr) < 0) {
perror("ioctl[SIOCGIFMEDIA]");
close(s);
return -1;
}
close(s);
*status = (ifmr.ifm_status & (IFM_ACTIVE | IFM_AVALID)) ==
(IFM_ACTIVE | IFM_AVALID);
return 0;
}
#endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(FreeBSD_kernel__) */
static int wpa_driver_wired_multi(const char *ifname, const u8 *addr, int add)
{
struct ifreq ifr;
@ -562,6 +591,16 @@ static void * wpa_driver_wired_init(void *ctx, const char *ifname)
__func__);
drv->iff_allmulti = 1;
}
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
{
int status;
wpa_printf(MSG_DEBUG, "%s: waiting for link to become active",
__func__);
while (wpa_driver_wired_get_ifstatus(ifname, &status) == 0 &&
status == 0)
sleep(1);
}
#endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(FreeBSD_kernel__) */
return drv;
}