nl80211: Share more code between hostapd and wpa_supplicant
This gets rid of some ifdef HOSTAPD constructs and shares more of the initialization code between hostapd and wpa_supplicant. Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
7b7de4cf94
commit
0d547d5ff8
1 changed files with 49 additions and 60 deletions
|
@ -297,6 +297,7 @@ struct wpa_driver_nl80211_data {
|
||||||
unsigned int use_monitor:1;
|
unsigned int use_monitor:1;
|
||||||
unsigned int ignore_next_local_disconnect:1;
|
unsigned int ignore_next_local_disconnect:1;
|
||||||
unsigned int allow_p2p_device:1;
|
unsigned int allow_p2p_device:1;
|
||||||
|
unsigned int hostapd:1;
|
||||||
|
|
||||||
u64 remain_on_chan_cookie;
|
u64 remain_on_chan_cookie;
|
||||||
u64 send_action_cookie;
|
u64 send_action_cookie;
|
||||||
|
@ -310,13 +311,11 @@ struct wpa_driver_nl80211_data {
|
||||||
|
|
||||||
int eapol_tx_sock;
|
int eapol_tx_sock;
|
||||||
|
|
||||||
#ifdef HOSTAPD
|
|
||||||
int eapol_sock; /* socket for EAPOL frames */
|
int eapol_sock; /* socket for EAPOL frames */
|
||||||
|
|
||||||
int default_if_indices[16];
|
int default_if_indices[16];
|
||||||
int *if_indices;
|
int *if_indices;
|
||||||
int num_if_indices;
|
int num_if_indices;
|
||||||
#endif /* HOSTAPD */
|
|
||||||
|
|
||||||
/* From failed authentication command */
|
/* From failed authentication command */
|
||||||
int auth_freq;
|
int auth_freq;
|
||||||
|
@ -340,7 +339,8 @@ static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx,
|
||||||
static int wpa_driver_nl80211_set_mode(struct i802_bss *bss,
|
static int wpa_driver_nl80211_set_mode(struct i802_bss *bss,
|
||||||
enum nl80211_iftype nlmode);
|
enum nl80211_iftype nlmode);
|
||||||
static int
|
static int
|
||||||
wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv);
|
wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
|
||||||
|
const u8 *set_addr);
|
||||||
static int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
|
static int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
|
||||||
const u8 *addr, int cmd, u16 reason_code,
|
const u8 *addr, int cmd, u16 reason_code,
|
||||||
int local_state_change);
|
int local_state_change);
|
||||||
|
@ -802,7 +802,6 @@ nla_put_failure:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef HOSTAPD
|
|
||||||
static int nl80211_get_macaddr(struct i802_bss *bss)
|
static int nl80211_get_macaddr(struct i802_bss *bss)
|
||||||
{
|
{
|
||||||
struct nl_msg *msg;
|
struct nl_msg *msg;
|
||||||
|
@ -824,7 +823,6 @@ nla_put_failure:
|
||||||
nlmsg_free(msg);
|
nlmsg_free(msg);
|
||||||
return NL80211_IFTYPE_UNSPECIFIED;
|
return NL80211_IFTYPE_UNSPECIFIED;
|
||||||
}
|
}
|
||||||
#endif /* HOSTAPD */
|
|
||||||
|
|
||||||
|
|
||||||
static int nl80211_register_beacons(struct wpa_driver_nl80211_data *drv,
|
static int nl80211_register_beacons(struct wpa_driver_nl80211_data *drv,
|
||||||
|
@ -1109,7 +1107,7 @@ static int wpa_driver_nl80211_own_ifindex(struct wpa_driver_nl80211_data *drv,
|
||||||
if (drv->if_removed && wpa_driver_nl80211_own_ifname(drv, buf, len)) {
|
if (drv->if_removed && wpa_driver_nl80211_own_ifname(drv, buf, len)) {
|
||||||
wpa_printf(MSG_DEBUG, "nl80211: Update ifindex for a removed "
|
wpa_printf(MSG_DEBUG, "nl80211: Update ifindex for a removed "
|
||||||
"interface");
|
"interface");
|
||||||
wpa_driver_nl80211_finish_drv_init(drv);
|
wpa_driver_nl80211_finish_drv_init(drv, NULL);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3716,16 +3714,9 @@ static void nl80211_destroy_bss(struct i802_bss *bss)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
static void * wpa_driver_nl80211_drv_init(void *ctx, const char *ifname,
|
||||||
* wpa_driver_nl80211_init - Initialize nl80211 driver interface
|
void *global_priv, int hostapd,
|
||||||
* @ctx: context to be used when calling wpa_supplicant functions,
|
const u8 *set_addr)
|
||||||
* e.g., wpa_supplicant_event()
|
|
||||||
* @ifname: interface name, e.g., wlan0
|
|
||||||
* @global_priv: private driver global data from global_init()
|
|
||||||
* Returns: Pointer to private data, %NULL on failure
|
|
||||||
*/
|
|
||||||
static void * wpa_driver_nl80211_init(void *ctx, const char *ifname,
|
|
||||||
void *global_priv)
|
|
||||||
{
|
{
|
||||||
struct wpa_driver_nl80211_data *drv;
|
struct wpa_driver_nl80211_data *drv;
|
||||||
struct rfkill_config *rcfg;
|
struct rfkill_config *rcfg;
|
||||||
|
@ -3738,6 +3729,10 @@ static void * wpa_driver_nl80211_init(void *ctx, const char *ifname,
|
||||||
return NULL;
|
return NULL;
|
||||||
drv->global = global_priv;
|
drv->global = global_priv;
|
||||||
drv->ctx = ctx;
|
drv->ctx = ctx;
|
||||||
|
drv->hostapd = !!hostapd;
|
||||||
|
drv->eapol_sock = -1;
|
||||||
|
drv->num_if_indices = sizeof(drv->default_if_indices) / sizeof(int);
|
||||||
|
drv->if_indices = drv->default_if_indices;
|
||||||
|
|
||||||
drv->first_bss = os_zalloc(sizeof(*drv->first_bss));
|
drv->first_bss = os_zalloc(sizeof(*drv->first_bss));
|
||||||
if (!drv->first_bss) {
|
if (!drv->first_bss) {
|
||||||
|
@ -3775,7 +3770,7 @@ static void * wpa_driver_nl80211_init(void *ctx, const char *ifname,
|
||||||
os_free(rcfg);
|
os_free(rcfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wpa_driver_nl80211_finish_drv_init(drv))
|
if (wpa_driver_nl80211_finish_drv_init(drv, set_addr))
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
drv->eapol_tx_sock = socket(PF_PACKET, SOCK_DGRAM, 0);
|
drv->eapol_tx_sock = socket(PF_PACKET, SOCK_DGRAM, 0);
|
||||||
|
@ -3813,6 +3808,21 @@ failed:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wpa_driver_nl80211_init - Initialize nl80211 driver interface
|
||||||
|
* @ctx: context to be used when calling wpa_supplicant functions,
|
||||||
|
* e.g., wpa_supplicant_event()
|
||||||
|
* @ifname: interface name, e.g., wlan0
|
||||||
|
* @global_priv: private driver global data from global_init()
|
||||||
|
* Returns: Pointer to private data, %NULL on failure
|
||||||
|
*/
|
||||||
|
static void * wpa_driver_nl80211_init(void *ctx, const char *ifname,
|
||||||
|
void *global_priv)
|
||||||
|
{
|
||||||
|
return wpa_driver_nl80211_drv_init(ctx, ifname, global_priv, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int nl80211_register_frame(struct i802_bss *bss,
|
static int nl80211_register_frame(struct i802_bss *bss,
|
||||||
struct nl_handle *nl_handle,
|
struct nl_handle *nl_handle,
|
||||||
u16 type, const u8 *match, size_t match_len)
|
u16 type, const u8 *match, size_t match_len)
|
||||||
|
@ -4160,13 +4170,12 @@ static int i802_set_iface_flags(struct i802_bss *bss, int up)
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv)
|
wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
|
||||||
|
const u8 *set_addr)
|
||||||
{
|
{
|
||||||
#ifndef HOSTAPD
|
|
||||||
enum nl80211_iftype nlmode = NL80211_IFTYPE_STATION;
|
|
||||||
#endif /* HOSTAPD */
|
|
||||||
struct i802_bss *bss = drv->first_bss;
|
struct i802_bss *bss = drv->first_bss;
|
||||||
int send_rfkill_event = 0;
|
int send_rfkill_event = 0;
|
||||||
|
enum nl80211_iftype nlmode;
|
||||||
|
|
||||||
drv->ifindex = if_nametoindex(bss->ifname);
|
drv->ifindex = if_nametoindex(bss->ifname);
|
||||||
bss->ifindex = drv->ifindex;
|
bss->ifindex = drv->ifindex;
|
||||||
|
@ -4183,20 +4192,23 @@ wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv)
|
||||||
wpa_printf(MSG_DEBUG, "nl80211: interface %s in phy %s",
|
wpa_printf(MSG_DEBUG, "nl80211: interface %s in phy %s",
|
||||||
bss->ifname, drv->phyname);
|
bss->ifname, drv->phyname);
|
||||||
|
|
||||||
#ifndef HOSTAPD
|
if (set_addr &&
|
||||||
if (bss->if_dynamic)
|
(linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 0) ||
|
||||||
nlmode = nl80211_get_ifmode(bss);
|
linux_set_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
|
||||||
|
set_addr)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (drv->hostapd)
|
||||||
|
nlmode = NL80211_IFTYPE_AP;
|
||||||
|
else if (bss->if_dynamic)
|
||||||
|
nlmode = nl80211_get_ifmode(bss);
|
||||||
|
else
|
||||||
|
nlmode = NL80211_IFTYPE_STATION;
|
||||||
|
|
||||||
/*
|
|
||||||
* Make sure the interface starts up in station mode unless this is a
|
|
||||||
* dynamically added interface (e.g., P2P) that was already configured
|
|
||||||
* with proper iftype.
|
|
||||||
*/
|
|
||||||
if (wpa_driver_nl80211_set_mode(bss, nlmode) < 0) {
|
if (wpa_driver_nl80211_set_mode(bss, nlmode) < 0) {
|
||||||
wpa_printf(MSG_ERROR, "nl80211: Could not configure driver to use managed mode");
|
wpa_printf(MSG_ERROR, "nl80211: Could not configure driver mode");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
drv->nlmode = nlmode;
|
|
||||||
|
|
||||||
if (nlmode == NL80211_IFTYPE_P2P_DEVICE) {
|
if (nlmode == NL80211_IFTYPE_P2P_DEVICE) {
|
||||||
int ret = nl80211_set_p2pdev(bss, 1);
|
int ret = nl80211_set_p2pdev(bss, 1);
|
||||||
|
@ -4220,9 +4232,9 @@ wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!drv->hostapd)
|
||||||
netlink_send_oper_ifla(drv->global->netlink, drv->ifindex,
|
netlink_send_oper_ifla(drv->global->netlink, drv->ifindex,
|
||||||
1, IF_OPER_DORMANT);
|
1, IF_OPER_DORMANT);
|
||||||
#endif /* HOSTAPD */
|
|
||||||
|
|
||||||
if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
|
if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
|
||||||
bss->addr))
|
bss->addr))
|
||||||
|
@ -4295,7 +4307,6 @@ static void wpa_driver_nl80211_deinit(struct i802_bss *bss)
|
||||||
if (is_ap_interface(drv->nlmode))
|
if (is_ap_interface(drv->nlmode))
|
||||||
wpa_driver_nl80211_del_beacon(drv);
|
wpa_driver_nl80211_del_beacon(drv);
|
||||||
|
|
||||||
#ifdef HOSTAPD
|
|
||||||
if (drv->eapol_sock >= 0) {
|
if (drv->eapol_sock >= 0) {
|
||||||
eloop_unregister_read_sock(drv->eapol_sock);
|
eloop_unregister_read_sock(drv->eapol_sock);
|
||||||
close(drv->eapol_sock);
|
close(drv->eapol_sock);
|
||||||
|
@ -4303,7 +4314,6 @@ static void wpa_driver_nl80211_deinit(struct i802_bss *bss)
|
||||||
|
|
||||||
if (drv->if_indices != drv->default_if_indices)
|
if (drv->if_indices != drv->default_if_indices)
|
||||||
os_free(drv->if_indices);
|
os_free(drv->if_indices);
|
||||||
#endif /* HOSTAPD */
|
|
||||||
|
|
||||||
if (drv->disabled_11b_rates)
|
if (drv->disabled_11b_rates)
|
||||||
nl80211_disable_11b_rates(drv, drv->ifindex, 0);
|
nl80211_disable_11b_rates(drv, drv->ifindex, 0);
|
||||||
|
@ -9135,14 +9145,13 @@ static void *i802_init(struct hostapd_data *hapd,
|
||||||
int ifindex, br_ifindex;
|
int ifindex, br_ifindex;
|
||||||
int br_added = 0;
|
int br_added = 0;
|
||||||
|
|
||||||
bss = wpa_driver_nl80211_init(hapd, params->ifname,
|
bss = wpa_driver_nl80211_drv_init(hapd, params->ifname,
|
||||||
params->global_priv);
|
params->global_priv, 1,
|
||||||
|
params->bssid);
|
||||||
if (bss == NULL)
|
if (bss == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
drv = bss->drv;
|
drv = bss->drv;
|
||||||
drv->nlmode = NL80211_IFTYPE_AP;
|
|
||||||
drv->eapol_sock = -1;
|
|
||||||
|
|
||||||
if (linux_br_get(brname, params->ifname) == 0) {
|
if (linux_br_get(brname, params->ifname) == 0) {
|
||||||
wpa_printf(MSG_DEBUG, "nl80211: Interface %s is in bridge %s",
|
wpa_printf(MSG_DEBUG, "nl80211: Interface %s is in bridge %s",
|
||||||
|
@ -9153,8 +9162,6 @@ static void *i802_init(struct hostapd_data *hapd,
|
||||||
br_ifindex = 0;
|
br_ifindex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
drv->num_if_indices = sizeof(drv->default_if_indices) / sizeof(int);
|
|
||||||
drv->if_indices = drv->default_if_indices;
|
|
||||||
for (i = 0; i < params->num_bridge; i++) {
|
for (i = 0; i < params->num_bridge; i++) {
|
||||||
if (params->bridge[i]) {
|
if (params->bridge[i]) {
|
||||||
ifindex = if_nametoindex(params->bridge[i]);
|
ifindex = if_nametoindex(params->bridge[i]);
|
||||||
|
@ -9171,28 +9178,10 @@ static void *i802_init(struct hostapd_data *hapd,
|
||||||
/* start listening for EAPOL on the default AP interface */
|
/* start listening for EAPOL on the default AP interface */
|
||||||
add_ifidx(drv, drv->ifindex);
|
add_ifidx(drv, drv->ifindex);
|
||||||
|
|
||||||
if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 0))
|
|
||||||
goto failed;
|
|
||||||
|
|
||||||
if (params->bssid) {
|
|
||||||
if (linux_set_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
|
|
||||||
params->bssid))
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wpa_driver_nl80211_set_mode(bss, drv->nlmode)) {
|
|
||||||
wpa_printf(MSG_ERROR, "nl80211: Failed to set interface %s "
|
|
||||||
"into AP mode", bss->ifname);
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (params->num_bridge && params->bridge[0] &&
|
if (params->num_bridge && params->bridge[0] &&
|
||||||
i802_check_bridge(drv, bss, params->bridge[0], params->ifname) < 0)
|
i802_check_bridge(drv, bss, params->bridge[0], params->ifname) < 0)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1))
|
|
||||||
goto failed;
|
|
||||||
|
|
||||||
drv->eapol_sock = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_PAE));
|
drv->eapol_sock = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_PAE));
|
||||||
if (drv->eapol_sock < 0) {
|
if (drv->eapol_sock < 0) {
|
||||||
wpa_printf(MSG_ERROR, "nl80211: socket(PF_PACKET, SOCK_DGRAM, ETH_P_PAE) failed: %s",
|
wpa_printf(MSG_ERROR, "nl80211: socket(PF_PACKET, SOCK_DGRAM, ETH_P_PAE) failed: %s",
|
||||||
|
|
Loading…
Reference in a new issue