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>
This commit is contained in:
parent
dca95e6924
commit
cb05808c46
3 changed files with 39 additions and 9 deletions
|
@ -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…
Reference in a new issue