From 178553b709e0143e2a67e453325b6983c0066ea1 Mon Sep 17 00:00:00 2001 From: Vamsi Krishna Date: Thu, 4 May 2017 12:54:49 +0530 Subject: [PATCH] MBO: Add support to set ignore assoc disallow to driver Add support to set ignore assoc disallow to the driver so that the driver ignores assoc disallowed bit set by APs while connecting. This is used by drivers that handle BSS selection and roaming internally. Signed-off-by: Jouni Malinen --- src/drivers/driver.h | 7 +++++ src/drivers/driver_nl80211.c | 51 ++++++++++++++++++++++++++++++++++++ wpa_supplicant/ctrl_iface.c | 2 ++ wpa_supplicant/driver_i.h | 8 ++++++ 4 files changed, 68 insertions(+) diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 6098329c5..014c7b712 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -3951,6 +3951,13 @@ struct wpa_driver_ops { struct wpa_bss_candidate_info * (*get_bss_transition_status)(void *priv, struct wpa_bss_trans_info *params); + /** + * ignore_assoc_disallow - Configure driver to ignore assoc_disallow + * @priv: Private driver interface data + * @ignore_disallow: 0 to not ignore, 1 to ignore + * Returns: 0 on success, -1 on failure + */ + int (*ignore_assoc_disallow)(void *priv, int ignore_disallow); }; /** diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 6ecb810d6..9f60504eb 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -9949,6 +9949,56 @@ fail: return NULL; } + +/** + * nl80211_ignore_assoc_disallow - Configure driver to ignore assoc_disallow + * @priv: Pointer to private driver data from wpa_driver_nl80211_init() + * @ignore_assoc_disallow: 0 to not ignore, 1 to ignore + * Returns: 0 on success, -1 on failure + */ +static int nl80211_ignore_assoc_disallow(void *priv, int ignore_disallow) +{ + struct i802_bss *bss = priv; + struct wpa_driver_nl80211_data *drv = bss->drv; + struct nl_msg *msg; + struct nlattr *attr; + int ret = -1; + + if (!drv->set_wifi_conf_vendor_cmd_avail) + return -1; + + if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) || + nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) || + nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, + QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION)) + goto fail; + + attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA); + if (!attr) + goto fail; + + wpa_printf(MSG_DEBUG, "nl80211: Set ignore_assoc_disallow %d", + ignore_disallow); + if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_IGNORE_ASSOC_DISALLOWED, + ignore_disallow)) + goto fail; + + nla_nest_end(msg, attr); + + ret = send_and_recv_msgs(drv, msg, NULL, NULL); + msg = NULL; + if (ret) { + wpa_printf(MSG_ERROR, + "nl80211: Set ignore_assoc_disallow failed: ret=%d (%s)", + ret, strerror(-ret)); + goto fail; + } + +fail: + nlmsg_free(msg); + return ret; +} + #endif /* CONFIG_MBO */ #endif /* CONFIG_DRIVER_NL80211_QCA */ @@ -10197,6 +10247,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = { .set_tdls_mode = nl80211_set_tdls_mode, #ifdef CONFIG_MBO .get_bss_transition_status = nl80211_get_bss_transition_status, + .ignore_assoc_disallow = nl80211_ignore_assoc_disallow, #endif /* CONFIG_MBO */ #endif /* CONFIG_DRIVER_NL80211_QCA */ .configure_data_frame_filters = nl80211_configure_data_frame_filters, diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index ad3701d39..a25d84abf 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -597,6 +597,8 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s, wpa_s->ignore_auth_resp = !!atoi(value); } else if (os_strcasecmp(cmd, "ignore_assoc_disallow") == 0) { wpa_s->ignore_assoc_disallow = !!atoi(value); + wpa_drv_ignore_assoc_disallow(wpa_s, + wpa_s->ignore_assoc_disallow); } else if (os_strcasecmp(cmd, "reject_btm_req_reason") == 0) { wpa_s->reject_btm_req_reason = atoi(value); } else if (os_strcasecmp(cmd, "get_pref_freq_list_override") == 0) { diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h index facceb900..39b08ac09 100644 --- a/wpa_supplicant/driver_i.h +++ b/wpa_supplicant/driver_i.h @@ -998,4 +998,12 @@ wpa_drv_get_bss_trans_status(struct wpa_supplicant *wpa_s, params); } +static inline int wpa_drv_ignore_assoc_disallow(struct wpa_supplicant *wpa_s, + int val) +{ + if (!wpa_s->driver->ignore_assoc_disallow) + return -1; + return wpa_s->driver->ignore_assoc_disallow(wpa_s->drv_priv, val); +} + #endif /* DRIVER_I_H */