[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