aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Nayshtut <qca_antonn@qca.qualcomm.com>2015-03-04 10:12:36 (GMT)
committerJouni Malinen <j@w1.fi>2015-07-16 09:33:29 (GMT)
commitcb05808c46539922cf02e9e8527a062e90637ff9 (patch)
tree8e576c69ead8b3a54cda6fc428dbfcace4f0d0ce
parentdca95e692416ab732a43ff937d893c64feffada1 (diff)
downloadhostap-cb05808c46539922cf02e9e8527a062e90637ff9.zip
hostap-cb05808c46539922cf02e9e8527a062e90637ff9.tar.gz
hostap-cb05808c46539922cf02e9e8527a062e90637ff9.tar.bz2
nl80211: Generic Linux master interface support for hostapd
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>
-rw-r--r--src/drivers/driver_nl80211.c24
-rw-r--r--src/drivers/linux_ioctl.c23
-rw-r--r--src/drivers/linux_ioctl.h1
3 files changed, 39 insertions, 9 deletions
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index da03e50..b775bb6 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -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;
}
diff --git a/src/drivers/linux_ioctl.c b/src/drivers/linux_ioctl.c
index 837971d..e21147a 100644
--- a/src/drivers/linux_ioctl.c
+++ b/src/drivers/linux_ioctl.c
@@ -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;
+}
diff --git a/src/drivers/linux_ioctl.h b/src/drivers/linux_ioctl.h
index c03fe6e..6de4d9b 100644
--- a/src/drivers/linux_ioctl.h
+++ b/src/drivers/linux_ioctl.h
@@ -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 */