[PATCH 1/2] nl80211: consider p2p when changing vif type
Eliad Peller
eliad at wizery.com
Thu May 26 04:52:36 EDT 2011
(ping)
On Mon, Feb 28, 2011 at 1:10 PM, Eliad Peller <eliad at wizery.com> wrote:
> Commit 9f51b11 ("nl80211: use P2P interface types") added
> support for p2p interfaces when adding a new interface.
> however, it didn't handle the case in which the same
> interface is being used and its type is being changed.
> Add support for this case.
>
> Consequently, when doing "ap_scan_as_station" we now need
> to save the actual ap interface type (normal/p2p) in order
> to restore it properly. for that, change ap_scan_as_station
> type from int to nl80211_iftype, and set it to
> NL80211_IFTYPE_UNSPECIFED when not used.
>
> Signed-off-by: Eliad Peller <eliad at wizery.com>
> ---
> src/drivers/driver_nl80211.c | 99 ++++++++++++++++++++++--------------------
> 1 files changed, 52 insertions(+), 47 deletions(-)
>
> diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
> index a64b091..52a656d 100644
> --- a/src/drivers/driver_nl80211.c
> +++ b/src/drivers/driver_nl80211.c
> @@ -150,7 +150,7 @@ struct wpa_driver_nl80211_data {
> u8 ssid[32];
> size_t ssid_len;
> int nlmode;
> - int ap_scan_as_station;
> + enum nl80211_iftype ap_scan_as_station;
> unsigned int assoc_freq;
>
> int monitor_sock;
> @@ -186,7 +186,8 @@ struct wpa_driver_nl80211_data {
>
> static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx,
> void *timeout_ctx);
> -static int wpa_driver_nl80211_set_mode(void *priv, int mode);
> +static int wpa_driver_nl80211_set_mode(void *priv,
> + enum nl80211_iftype nlmode);
> static int
> wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv);
> static int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
> @@ -1111,6 +1112,17 @@ static int get_link_signal(struct nl_msg *msg, void *arg)
> return NL_SKIP;
> }
>
> +static int is_ap_interface(enum nl80211_iftype nlmode)
> +{
> + return (nlmode == NL80211_IFTYPE_AP ||
> + nlmode == NL80211_IFTYPE_P2P_GO);
> +}
> +
> +static int is_sta_interface(enum nl80211_iftype nlmode)
> +{
> + return (nlmode == NL80211_IFTYPE_STATION ||
> + nlmode == NL80211_IFTYPE_P2P_CLIENT);
> +}
>
> static int nl80211_get_link_signal(struct wpa_driver_nl80211_data *drv,
> struct signal_change *sig)
> @@ -1309,12 +1321,12 @@ static int process_event(struct nl_msg *msg, void *arg)
> }
> }
>
> - if (drv->ap_scan_as_station &&
> + if ((drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED) &&
> (gnlh->cmd == NL80211_CMD_NEW_SCAN_RESULTS ||
> gnlh->cmd == NL80211_CMD_SCAN_ABORTED)) {
> wpa_driver_nl80211_set_mode(&drv->first_bss,
> - IEEE80211_MODE_AP);
> - drv->ap_scan_as_station = 0;
> + drv->ap_scan_as_station);
> + drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED;
> }
>
> switch (gnlh->cmd) {
> @@ -1825,6 +1837,7 @@ static void * wpa_driver_nl80211_init(void *ctx, const char *ifname,
> drv->monitor_ifidx = -1;
> drv->monitor_sock = -1;
> drv->ioctl_sock = -1;
> + drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED;
>
> if (wpa_driver_nl80211_init_nl(drv)) {
> os_free(drv);
> @@ -1989,7 +2002,7 @@ wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv)
> drv->first_bss.ifindex = drv->ifindex;
>
> #ifndef HOSTAPD
> - if (wpa_driver_nl80211_set_mode(bss, IEEE80211_MODE_INFRA) < 0) {
> + if (wpa_driver_nl80211_set_mode(bss, NL80211_IFTYPE_STATION) < 0) {
> wpa_printf(MSG_DEBUG, "nl80211: Could not configure driver to "
> "use managed mode");
> }
> @@ -2085,7 +2098,7 @@ static void wpa_driver_nl80211_deinit(void *priv)
>
> nl80211_remove_monitor_interface(drv);
>
> - if (drv->nlmode == NL80211_IFTYPE_AP)
> + if (is_ap_interface(drv->nlmode))
> wpa_driver_nl80211_del_beacon(drv);
>
> #ifdef HOSTAPD
> @@ -2116,7 +2129,7 @@ static void wpa_driver_nl80211_deinit(void *priv)
> eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
>
> (void) linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 0);
> - wpa_driver_nl80211_set_mode(bss, IEEE80211_MODE_INFRA);
> + wpa_driver_nl80211_set_mode(bss, NL80211_IFTYPE_STATION);
>
> if (drv->ioctl_sock >= 0)
> close(drv->ioctl_sock);
> @@ -2149,10 +2162,10 @@ static void wpa_driver_nl80211_deinit(void *priv)
> static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, void *timeout_ctx)
> {
> struct wpa_driver_nl80211_data *drv = eloop_ctx;
> - if (drv->ap_scan_as_station) {
> + if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED) {
> wpa_driver_nl80211_set_mode(&drv->first_bss,
> - IEEE80211_MODE_AP);
> - drv->ap_scan_as_station = 0;
> + drv->ap_scan_as_station);
> + drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED;
> }
> wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
> wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
> @@ -2226,23 +2239,23 @@ static int wpa_driver_nl80211_scan(void *priv,
> wpa_printf(MSG_DEBUG, "nl80211: Scan trigger failed: ret=%d "
> "(%s)", ret, strerror(-ret));
> #ifdef HOSTAPD
> - if (drv->nlmode == NL80211_IFTYPE_AP) {
> + if (is_ap_interface(drv->nlmode)) {
> /*
> * mac80211 does not allow scan requests in AP mode, so
> * try to do this in station mode.
> */
> if (wpa_driver_nl80211_set_mode(bss,
> - IEEE80211_MODE_INFRA))
> + NL80211_IFTYPE_STATION))
> goto nla_put_failure;
>
> if (wpa_driver_nl80211_scan(drv, params)) {
> wpa_driver_nl80211_set_mode(bss,
> - IEEE80211_MODE_AP);
> + drv->nlmode);
> goto nla_put_failure;
> }
>
> /* Restore AP mode when processing scan results */
> - drv->ap_scan_as_station = 1;
> + drv->ap_scan_as_station = drv->nlmode;
> ret = 0;
> } else
> goto nla_put_failure;
> @@ -2468,7 +2481,7 @@ static void wpa_driver_nl80211_check_bss_status(
> "indicates BSS status with " MACSTR
> " as authenticated",
> MAC2STR(r->bssid));
> - if (drv->nlmode == NL80211_IFTYPE_STATION &&
> + if (is_sta_interface(drv->nlmode) &&
> os_memcmp(r->bssid, drv->bssid, ETH_ALEN) != 0 &&
> os_memcmp(r->bssid, drv->auth_bssid, ETH_ALEN) !=
> 0) {
> @@ -2486,13 +2499,13 @@ static void wpa_driver_nl80211_check_bss_status(
> "indicate BSS status with " MACSTR
> " as associated",
> MAC2STR(r->bssid));
> - if (drv->nlmode == NL80211_IFTYPE_STATION &&
> + if (is_sta_interface(drv->nlmode) &&
> !drv->associated) {
> wpa_printf(MSG_DEBUG, "nl80211: Local state "
> "(not associated) does not match "
> "with BSS state");
> clear_state_mismatch(drv, r->bssid);
> - } else if (drv->nlmode == NL80211_IFTYPE_STATION &&
> + } else if (is_sta_interface(drv->nlmode) &&
> os_memcmp(drv->bssid, r->bssid, ETH_ALEN) !=
> 0) {
> wpa_printf(MSG_DEBUG, "nl80211: Local state "
> @@ -2700,7 +2713,7 @@ static int wpa_driver_nl80211_set_key(const char *ifname, void *priv,
> */
> if (ret || !set_tx || alg == WPA_ALG_NONE)
> return ret;
> - if (drv->nlmode == NL80211_IFTYPE_AP && addr &&
> + if (is_ap_interface(drv->nlmode) && addr &&
> !is_broadcast_ether_addr(addr))
> return ret;
>
> @@ -2957,7 +2970,7 @@ static int wpa_driver_nl80211_authenticate(
> os_memset(drv->auth_bssid, 0, ETH_ALEN);
> /* FIX: IBSS mode */
> if (drv->nlmode != NL80211_IFTYPE_STATION &&
> - wpa_driver_nl80211_set_mode(priv, IEEE80211_MODE_INFRA) < 0)
> + wpa_driver_nl80211_set_mode(priv, NL80211_IFTYPE_STATION) < 0)
> return -1;
>
> retry:
> @@ -3545,7 +3558,7 @@ static int wpa_driver_nl80211_send_mlme(void *priv, const u8 *data,
> mgmt = (struct ieee80211_mgmt *) data;
> fc = le_to_host16(mgmt->frame_control);
>
> - if (drv->nlmode == NL80211_IFTYPE_STATION &&
> + if (is_sta_interface(drv->nlmode) &&
> WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
> WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_RESP) {
> /*
> @@ -4362,7 +4375,9 @@ static int wpa_driver_nl80211_ap(struct wpa_driver_nl80211_data *drv,
> if (params->p2p)
> wpa_printf(MSG_DEBUG, "nl80211: Setup AP operations for P2P "
> "group (GO)");
> - if (wpa_driver_nl80211_set_mode(&drv->first_bss, params->mode) ||
> + enum nl80211_iftype nlmode = params->p2p ?
> + NL80211_IFTYPE_P2P_GO : NL80211_IFTYPE_AP;
> + if (wpa_driver_nl80211_set_mode(&drv->first_bss, nlmode) ||
> wpa_driver_nl80211_set_freq(drv, params->freq, 0, 0)) {
> nl80211_remove_monitor_interface(drv);
> return -1;
> @@ -4413,7 +4428,8 @@ static int wpa_driver_nl80211_ibss(struct wpa_driver_nl80211_data *drv,
>
> wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex);
>
> - if (wpa_driver_nl80211_set_mode(&drv->first_bss, params->mode)) {
> + if (wpa_driver_nl80211_set_mode(&drv->first_bss,
> + NL80211_IFTYPE_ADHOC)) {
> wpa_printf(MSG_INFO, "nl80211: Failed to set interface into "
> "IBSS mode");
> return -1;
> @@ -4639,7 +4655,10 @@ static int wpa_driver_nl80211_associate(
> return wpa_driver_nl80211_ibss(drv, params);
>
> if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) {
> - if (wpa_driver_nl80211_set_mode(priv, params->mode) < 0)
> + enum nl80211_iftype nlmode = params->p2p ?
> + NL80211_IFTYPE_P2P_CLIENT : NL80211_IFTYPE_STATION;
> +
> + if (wpa_driver_nl80211_set_mode(priv, nlmode) < 0)
> return -1;
> return wpa_driver_nl80211_connect(drv, params);
> }
> @@ -4786,28 +4805,14 @@ nla_put_failure:
> }
>
>
> -static int wpa_driver_nl80211_set_mode(void *priv, int mode)
> +static int wpa_driver_nl80211_set_mode(void *priv,
> + enum nl80211_iftype nlmode)
> {
> struct i802_bss *bss = priv;
> struct wpa_driver_nl80211_data *drv = bss->drv;
> int ret = -1;
> - int nlmode;
> int i;
>
> - switch (mode) {
> - case 0:
> - nlmode = NL80211_IFTYPE_STATION;
> - break;
> - case 1:
> - nlmode = NL80211_IFTYPE_ADHOC;
> - break;
> - case 2:
> - nlmode = NL80211_IFTYPE_AP;
> - break;
> - default:
> - return -1;
> - }
> -
> if (nl80211_set_mode(drv, drv->ifindex, nlmode) == 0) {
> drv->nlmode = nlmode;
> ret = 0;
> @@ -4851,12 +4856,12 @@ static int wpa_driver_nl80211_set_mode(void *priv, int mode)
> }
>
> done:
> - if (!ret && nlmode == NL80211_IFTYPE_AP) {
> + if (!ret && is_ap_interface(nlmode)) {
> /* Setup additional AP mode functionality if needed */
> if (drv->monitor_ifidx < 0 &&
> nl80211_create_monitor_interface(drv))
> return -1;
> - } else if (!ret && nlmode != NL80211_IFTYPE_AP) {
> + } else if (!ret && !is_ap_interface(nlmode)) {
> /* Remove additional AP mode functionality */
> nl80211_remove_monitor_interface(drv);
> bss->beacon_set = 0;
> @@ -5621,7 +5626,7 @@ static void *i802_init(struct hostapd_data *hapd,
> goto failed;
> }
>
> - if (wpa_driver_nl80211_set_mode(bss, IEEE80211_MODE_AP)) {
> + 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;
> @@ -5946,7 +5951,7 @@ static int wpa_driver_nl80211_send_action(void *priv, unsigned int freq,
> os_memcpy(hdr->addr2, src, ETH_ALEN);
> os_memcpy(hdr->addr3, bssid, ETH_ALEN);
>
> - if (drv->nlmode == NL80211_IFTYPE_AP)
> + if (is_ap_interface(drv->nlmode))
> ret = wpa_driver_nl80211_send_mlme(priv, buf, 24 + data_len);
> else
> ret = nl80211_send_frame_cmd(drv, freq, wait_time, buf,
> @@ -6065,7 +6070,7 @@ static int wpa_driver_nl80211_probe_req_report(void *priv, int report)
> struct i802_bss *bss = priv;
> struct wpa_driver_nl80211_data *drv = bss->drv;
>
> - if (drv->nlmode != NL80211_IFTYPE_STATION) {
> + if (!is_sta_interface(drv->nlmode)) {
> wpa_printf(MSG_DEBUG, "nl80211: probe_req_report control only "
> "allowed in station mode (iftype=%d)",
> drv->nlmode);
> @@ -6203,10 +6208,10 @@ static int wpa_driver_nl80211_deinit_ap(void *priv)
> {
> struct i802_bss *bss = priv;
> struct wpa_driver_nl80211_data *drv = bss->drv;
> - if (drv->nlmode != NL80211_IFTYPE_AP)
> + if (!is_ap_interface(drv->nlmode))
> return -1;
> wpa_driver_nl80211_del_beacon(drv);
> - return wpa_driver_nl80211_set_mode(priv, IEEE80211_MODE_INFRA);
> + return wpa_driver_nl80211_set_mode(priv, NL80211_IFTYPE_STATION);
> }
>
>
> --
> 1.7.0.4
>
> _______________________________________________
> HostAP mailing list
> HostAP at lists.shmoo.com
> http://lists.shmoo.com/mailman/listinfo/hostap
>
More information about the HostAP
mailing list