]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
wired: Wait for the link to become active before sending packets
authorRui Paulo <rpaulo@FreeBSD.org>
Sun, 25 Aug 2013 08:40:19 +0000 (11:40 +0300)
committerJouni Malinen <j@w1.fi>
Sun, 25 Aug 2013 08:40:19 +0000 (11:40 +0300)
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>

src/drivers/driver_wired.c

index e0f0f2289bce9e583601abe95e7eb3b4ac4eb2dc..21f5e4248f21d25e428e51a7d9b3c036b5ba479d 100644 (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;
 }