nl80211: Support AP mode probe/action frame TX/RX without monitor iface
This allows non-mac80211 drivers to report received Probe Request frames to user space and Probe Response and Action frames to be sent from user space when using AP/P2P GO mode.
This commit is contained in:
parent
4dc03726de
commit
86957e6298
1 changed files with 21 additions and 13 deletions
|
@ -169,6 +169,7 @@ struct wpa_driver_nl80211_data {
|
||||||
u64 send_action_cookie;
|
u64 send_action_cookie;
|
||||||
|
|
||||||
unsigned int last_mgmt_freq;
|
unsigned int last_mgmt_freq;
|
||||||
|
unsigned int ap_oper_freq;
|
||||||
|
|
||||||
struct wpa_driver_scan_filter *filter_ssids;
|
struct wpa_driver_scan_filter *filter_ssids;
|
||||||
size_t num_filter_ssids;
|
size_t num_filter_ssids;
|
||||||
|
@ -1356,8 +1357,7 @@ static void nl80211_new_station_event(struct wpa_driver_nl80211_data *drv,
|
||||||
addr = nla_data(tb[NL80211_ATTR_MAC]);
|
addr = nla_data(tb[NL80211_ATTR_MAC]);
|
||||||
wpa_printf(MSG_DEBUG, "nl80211: New station " MACSTR, MAC2STR(addr));
|
wpa_printf(MSG_DEBUG, "nl80211: New station " MACSTR, MAC2STR(addr));
|
||||||
|
|
||||||
if (drv->nlmode == NL80211_IFTYPE_AP &&
|
if (is_ap_interface(drv->nlmode) && drv->no_monitor_iface_capab) {
|
||||||
drv->no_monitor_iface_capab) {
|
|
||||||
u8 *ies = NULL;
|
u8 *ies = NULL;
|
||||||
size_t ies_len = 0;
|
size_t ies_len = 0;
|
||||||
if (tb[NL80211_ATTR_IE]) {
|
if (tb[NL80211_ATTR_IE]) {
|
||||||
|
@ -1390,8 +1390,7 @@ static void nl80211_del_station_event(struct wpa_driver_nl80211_data *drv,
|
||||||
wpa_printf(MSG_DEBUG, "nl80211: Delete station " MACSTR,
|
wpa_printf(MSG_DEBUG, "nl80211: Delete station " MACSTR,
|
||||||
MAC2STR(addr));
|
MAC2STR(addr));
|
||||||
|
|
||||||
if (drv->nlmode == NL80211_IFTYPE_AP &&
|
if (is_ap_interface(drv->nlmode) && drv->no_monitor_iface_capab) {
|
||||||
drv->no_monitor_iface_capab) {
|
|
||||||
drv_event_disassoc(drv->ctx, addr);
|
drv_event_disassoc(drv->ctx, addr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3801,6 +3800,11 @@ static int wpa_driver_nl80211_send_mlme(void *priv, const u8 *data,
|
||||||
data, data_len, NULL);
|
data, data_len, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (drv->no_monitor_iface_capab && is_ap_interface(drv->nlmode)) {
|
||||||
|
return nl80211_send_frame_cmd(drv, drv->ap_oper_freq, 0,
|
||||||
|
data, data_len, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
|
if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
|
||||||
WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_AUTH) {
|
WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_AUTH) {
|
||||||
/*
|
/*
|
||||||
|
@ -4764,8 +4768,16 @@ static int wpa_driver_nl80211_ap(struct wpa_driver_nl80211_data *drv,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: setup monitor interface (and add code somewhere to remove this
|
if (drv->no_monitor_iface_capab) {
|
||||||
* when AP mode is stopped; associate with mode != 2 or drv_deinit) */
|
if (wpa_driver_nl80211_probe_req_report(&drv->first_bss, 1) < 0)
|
||||||
|
{
|
||||||
|
wpa_printf(MSG_DEBUG, "nl80211: Failed to enable "
|
||||||
|
"Probe Request frame reporting in AP mode");
|
||||||
|
/* Try to survive without this */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drv->ap_oper_freq = params->freq;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -5211,6 +5223,7 @@ static int wpa_driver_nl80211_set_mode(struct i802_bss *bss,
|
||||||
struct wpa_driver_nl80211_data *drv = bss->drv;
|
struct wpa_driver_nl80211_data *drv = bss->drv;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
int i;
|
int i;
|
||||||
|
int was_ap = is_ap_interface(drv->nlmode);
|
||||||
|
|
||||||
if (nl80211_set_mode(drv, drv->ifindex, nlmode) == 0) {
|
if (nl80211_set_mode(drv, drv->ifindex, nlmode) == 0) {
|
||||||
drv->nlmode = nlmode;
|
drv->nlmode = nlmode;
|
||||||
|
@ -5264,6 +5277,8 @@ done:
|
||||||
return -1;
|
return -1;
|
||||||
} else if (!ret && !is_ap_interface(nlmode)) {
|
} else if (!ret && !is_ap_interface(nlmode)) {
|
||||||
/* Remove additional AP mode functionality */
|
/* Remove additional AP mode functionality */
|
||||||
|
if (was_ap && drv->no_monitor_iface_capab)
|
||||||
|
wpa_driver_nl80211_probe_req_report(bss, 0);
|
||||||
nl80211_remove_monitor_interface(drv);
|
nl80211_remove_monitor_interface(drv);
|
||||||
bss->beacon_set = 0;
|
bss->beacon_set = 0;
|
||||||
}
|
}
|
||||||
|
@ -6503,13 +6518,6 @@ static int wpa_driver_nl80211_probe_req_report(void *priv, int report)
|
||||||
struct i802_bss *bss = priv;
|
struct i802_bss *bss = priv;
|
||||||
struct wpa_driver_nl80211_data *drv = bss->drv;
|
struct wpa_driver_nl80211_data *drv = bss->drv;
|
||||||
|
|
||||||
if (!is_sta_interface(drv->nlmode)) {
|
|
||||||
wpa_printf(MSG_DEBUG, "nl80211: probe_req_report control only "
|
|
||||||
"allowed in station mode (iftype=%d)",
|
|
||||||
drv->nlmode);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!report) {
|
if (!report) {
|
||||||
if (drv->nl_handle_preq) {
|
if (drv->nl_handle_preq) {
|
||||||
eloop_unregister_read_sock(
|
eloop_unregister_read_sock(
|
||||||
|
|
Loading…
Reference in a new issue