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>
master
Anton Nayshtut 9 years ago committed by Jouni Malinen
parent dca95e6924
commit cb05808c46

@ -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;
}

@ -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;
}

@ -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 */

Loading…
Cancel
Save