nl80211: Generic Linux master interface support for hostapd
authorAnton Nayshtut <qca_antonn@qca.qualcomm.com>
Wed, 4 Mar 2015 10:12:36 +0000 (12:12 +0200)
committerJouni Malinen <j@w1.fi>
Thu, 16 Jul 2015 09:33:29 +0000 (12:33 +0300)
Previously, hostapd only supported the case of EAPOL frames receiving
from interfaces enslaved into bridge. This commit adds support for any
Linux master (teaming, openvswitch, bonding, etc.) to be detected.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
src/drivers/driver_nl80211.c
src/drivers/linux_ioctl.c
src/drivers/linux_ioctl.h

index da03e50..b775bb6 100644 (file)
@@ -5675,8 +5675,8 @@ static void *i802_init(struct hostapd_data *hapd,
        struct wpa_driver_nl80211_data *drv;
        struct i802_bss *bss;
        size_t i;
-       char brname[IFNAMSIZ];
-       int ifindex, br_ifindex;
+       char master_ifname[IFNAMSIZ];
+       int ifindex, br_ifindex = 0;
        int br_added = 0;
 
        bss = wpa_driver_nl80211_drv_init(hapd, params->ifname,
@@ -5687,15 +5687,21 @@ static void *i802_init(struct hostapd_data *hapd,
 
        drv = bss->drv;
 
-       if (linux_br_get(brname, params->ifname) == 0) {
+       if (linux_br_get(master_ifname, params->ifname) == 0) {
                wpa_printf(MSG_DEBUG, "nl80211: Interface %s is in bridge %s",
-                          params->ifname, brname);
-               br_ifindex = if_nametoindex(brname);
-               os_strlcpy(bss->brname, brname, IFNAMSIZ);
+                          params->ifname, master_ifname);
+               br_ifindex = if_nametoindex(master_ifname);
+               os_strlcpy(bss->brname, master_ifname, IFNAMSIZ);
+       } else if ((params->num_bridge == 0 || !params->bridge[0]) &&
+                  linux_master_get(master_ifname, params->ifname) == 0) {
+               wpa_printf(MSG_DEBUG, "nl80211: Interface %s is in master %s",
+                       params->ifname, master_ifname);
+               /* start listening for EAPOL on the master interface */
+               add_ifidx(drv, if_nametoindex(master_ifname));
        } else {
-               brname[0] = '\0';
-               br_ifindex = 0;
+               master_ifname[0] = '\0';
        }
+
        bss->br_ifindex = br_ifindex;
 
        for (i = 0; i < params->num_bridge; i++) {
@@ -5715,7 +5721,7 @@ static void *i802_init(struct hostapd_data *hapd,
                if (i802_check_bridge(drv, bss, params->bridge[0],
                                      params->ifname) < 0)
                        goto failed;
-               if (os_strcmp(params->bridge[0], brname) != 0)
+               if (os_strcmp(params->bridge[0], master_ifname) != 0)
                        br_added = 1;
        }
 
index 837971d..e21147a 100644 (file)
@@ -219,3 +219,26 @@ int linux_br_get(char *brname, const char *ifname)
        os_strlcpy(brname, pos, IFNAMSIZ);
        return 0;
 }
+
+
+int linux_master_get(char *master_ifname, const char *ifname)
+{
+       char buf[128], masterlink[128], *pos;
+       ssize_t res;
+
+       /* check whether there is a master */
+       os_snprintf(buf, sizeof(buf), "/sys/class/net/%s/master", ifname);
+
+       res = readlink(buf, masterlink, sizeof(masterlink));
+       if (res < 0 || (size_t) res >= sizeof(masterlink))
+               return -1;
+
+       masterlink[res] = '\0';
+
+       pos = os_strrchr(masterlink, '/');
+       if (pos == NULL)
+               return -1;
+       pos++;
+       os_strlcpy(master_ifname, pos, IFNAMSIZ);
+       return 0;
+}
index c03fe6e..6de4d9b 100644 (file)
@@ -18,5 +18,6 @@ int linux_br_del(int sock, const char *brname);
 int linux_br_add_if(int sock, const char *brname, const char *ifname);
 int linux_br_del_if(int sock, const char *brname, const char *ifname);
 int linux_br_get(char *brname, const char *ifname);
+int linux_master_get(char *master_ifname, const char *ifname);
 
 #endif /* LINUX_IOCTL_H */