nl80211: Fetch information on supported AKMs from the driver
The driver can advertise supported AKMs per wiphy and/or per interface. Populate per interface supported AKMs based on the driver advertisement in the following order of preference: 1. AKM suites advertised by NL80211_ATTR_IFTYPE_AKM_SUITES 2. AKM suites advertised by NL80211_ATTR_AKM_SUITES If neither of these is available: 3. AKMs support is assumed as per legacy behavior. In addition, extend other driver interface wrappers to set the per-interface values based on the global capability indication. Signed-off-by: Veerendranath Jakkam <vjakkam@codeaurora.org>
This commit is contained in:
parent
6fffb320fc
commit
b67bedf2e3
7 changed files with 311 additions and 79 deletions
|
@ -1658,6 +1658,73 @@ struct wpa_driver_set_key_params {
|
||||||
enum key_flag key_flag;
|
enum key_flag key_flag;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum wpa_driver_if_type {
|
||||||
|
/**
|
||||||
|
* WPA_IF_STATION - Station mode interface
|
||||||
|
*/
|
||||||
|
WPA_IF_STATION,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WPA_IF_AP_VLAN - AP mode VLAN interface
|
||||||
|
*
|
||||||
|
* This interface shares its address and Beacon frame with the main
|
||||||
|
* BSS.
|
||||||
|
*/
|
||||||
|
WPA_IF_AP_VLAN,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WPA_IF_AP_BSS - AP mode BSS interface
|
||||||
|
*
|
||||||
|
* This interface has its own address and Beacon frame.
|
||||||
|
*/
|
||||||
|
WPA_IF_AP_BSS,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WPA_IF_P2P_GO - P2P Group Owner
|
||||||
|
*/
|
||||||
|
WPA_IF_P2P_GO,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WPA_IF_P2P_CLIENT - P2P Client
|
||||||
|
*/
|
||||||
|
WPA_IF_P2P_CLIENT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WPA_IF_P2P_GROUP - P2P Group interface (will become either
|
||||||
|
* WPA_IF_P2P_GO or WPA_IF_P2P_CLIENT, but the role is not yet known)
|
||||||
|
*/
|
||||||
|
WPA_IF_P2P_GROUP,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WPA_IF_P2P_DEVICE - P2P Device interface is used to indentify the
|
||||||
|
* abstracted P2P Device function in the driver
|
||||||
|
*/
|
||||||
|
WPA_IF_P2P_DEVICE,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WPA_IF_MESH - Mesh interface
|
||||||
|
*/
|
||||||
|
WPA_IF_MESH,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WPA_IF_TDLS - TDLS offchannel interface (used for pref freq only)
|
||||||
|
*/
|
||||||
|
WPA_IF_TDLS,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WPA_IF_IBSS - IBSS interface (used for pref freq only)
|
||||||
|
*/
|
||||||
|
WPA_IF_IBSS,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WPA_IF_NAN - NAN Device
|
||||||
|
*/
|
||||||
|
WPA_IF_NAN,
|
||||||
|
|
||||||
|
/* keep last */
|
||||||
|
WPA_IF_MAX
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct wpa_driver_capa - Driver capability information
|
* struct wpa_driver_capa - Driver capability information
|
||||||
*/
|
*/
|
||||||
|
@ -1681,6 +1748,7 @@ struct wpa_driver_capa {
|
||||||
#define WPA_DRIVER_CAPA_KEY_MGMT_SAE 0x00010000
|
#define WPA_DRIVER_CAPA_KEY_MGMT_SAE 0x00010000
|
||||||
/** Bitfield of supported key management suites */
|
/** Bitfield of supported key management suites */
|
||||||
unsigned int key_mgmt;
|
unsigned int key_mgmt;
|
||||||
|
unsigned int key_mgmt_iftype[WPA_IF_MAX];
|
||||||
|
|
||||||
#define WPA_DRIVER_CAPA_ENC_WEP40 0x00000001
|
#define WPA_DRIVER_CAPA_ENC_WEP40 0x00000001
|
||||||
#define WPA_DRIVER_CAPA_ENC_WEP104 0x00000002
|
#define WPA_DRIVER_CAPA_ENC_WEP104 0x00000002
|
||||||
|
@ -2045,65 +2113,6 @@ struct hostapd_acl_params {
|
||||||
struct mac_address mac_acl[0];
|
struct mac_address mac_acl[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
enum wpa_driver_if_type {
|
|
||||||
/**
|
|
||||||
* WPA_IF_STATION - Station mode interface
|
|
||||||
*/
|
|
||||||
WPA_IF_STATION,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* WPA_IF_AP_VLAN - AP mode VLAN interface
|
|
||||||
*
|
|
||||||
* This interface shares its address and Beacon frame with the main
|
|
||||||
* BSS.
|
|
||||||
*/
|
|
||||||
WPA_IF_AP_VLAN,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* WPA_IF_AP_BSS - AP mode BSS interface
|
|
||||||
*
|
|
||||||
* This interface has its own address and Beacon frame.
|
|
||||||
*/
|
|
||||||
WPA_IF_AP_BSS,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* WPA_IF_P2P_GO - P2P Group Owner
|
|
||||||
*/
|
|
||||||
WPA_IF_P2P_GO,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* WPA_IF_P2P_CLIENT - P2P Client
|
|
||||||
*/
|
|
||||||
WPA_IF_P2P_CLIENT,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* WPA_IF_P2P_GROUP - P2P Group interface (will become either
|
|
||||||
* WPA_IF_P2P_GO or WPA_IF_P2P_CLIENT, but the role is not yet known)
|
|
||||||
*/
|
|
||||||
WPA_IF_P2P_GROUP,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* WPA_IF_P2P_DEVICE - P2P Device interface is used to indentify the
|
|
||||||
* abstracted P2P Device function in the driver
|
|
||||||
*/
|
|
||||||
WPA_IF_P2P_DEVICE,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* WPA_IF_MESH - Mesh interface
|
|
||||||
*/
|
|
||||||
WPA_IF_MESH,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* WPA_IF_TDLS - TDLS offchannel interface (used for pref freq only)
|
|
||||||
*/
|
|
||||||
WPA_IF_TDLS,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* WPA_IF_IBSS - IBSS interface (used for pref freq only)
|
|
||||||
*/
|
|
||||||
WPA_IF_IBSS,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct wpa_init_params {
|
struct wpa_init_params {
|
||||||
void *global_priv;
|
void *global_priv;
|
||||||
const u8 *bssid;
|
const u8 *bssid;
|
||||||
|
|
|
@ -1451,6 +1451,7 @@ wpa_driver_bsd_init(void *ctx, const char *ifname, void *priv)
|
||||||
#define GETPARAM(drv, param, v) \
|
#define GETPARAM(drv, param, v) \
|
||||||
(((v) = get80211param(drv, param)) != -1)
|
(((v) = get80211param(drv, param)) != -1)
|
||||||
struct bsd_driver_data *drv;
|
struct bsd_driver_data *drv;
|
||||||
|
int i;
|
||||||
|
|
||||||
drv = os_zalloc(sizeof(*drv));
|
drv = os_zalloc(sizeof(*drv));
|
||||||
if (drv == NULL)
|
if (drv == NULL)
|
||||||
|
@ -1486,6 +1487,10 @@ wpa_driver_bsd_init(void *ctx, const char *ifname, void *priv)
|
||||||
if (wpa_driver_bsd_capa(drv))
|
if (wpa_driver_bsd_capa(drv))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
/* Update per interface supported AKMs */
|
||||||
|
for (i = 0; i < WPA_IF_MAX; i++)
|
||||||
|
drv->capa.key_mgmt_iftype[i] = drv->capa.key_mgmt;
|
||||||
|
|
||||||
/* Down interface during setup. */
|
/* Down interface during setup. */
|
||||||
if (bsd_get_iface_flags(drv) < 0)
|
if (bsd_get_iface_flags(drv) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
|
@ -2809,6 +2809,7 @@ static void * wpa_driver_ndis_init(void *ctx, const char *ifname)
|
||||||
{
|
{
|
||||||
struct wpa_driver_ndis_data *drv;
|
struct wpa_driver_ndis_data *drv;
|
||||||
u32 mode;
|
u32 mode;
|
||||||
|
int i;
|
||||||
|
|
||||||
drv = os_zalloc(sizeof(*drv));
|
drv = os_zalloc(sizeof(*drv));
|
||||||
if (drv == NULL)
|
if (drv == NULL)
|
||||||
|
@ -2855,6 +2856,11 @@ static void * wpa_driver_ndis_init(void *ctx, const char *ifname)
|
||||||
}
|
}
|
||||||
wpa_driver_ndis_get_capability(drv);
|
wpa_driver_ndis_get_capability(drv);
|
||||||
|
|
||||||
|
/* Update per interface supported AKMs */
|
||||||
|
for (i = 0; i < WPA_IF_MAX; i++)
|
||||||
|
drv->capa.key_mgmt_iftype[i] = drv->capa.key_mgmt;
|
||||||
|
|
||||||
|
|
||||||
/* Make sure that the driver does not have any obsolete PMKID entries.
|
/* Make sure that the driver does not have any obsolete PMKID entries.
|
||||||
*/
|
*/
|
||||||
wpa_driver_ndis_flush_pmkid(drv);
|
wpa_driver_ndis_flush_pmkid(drv);
|
||||||
|
|
|
@ -2328,10 +2328,19 @@ static int nl80211_mgmt_subscribe_non_ap(struct i802_bss *bss)
|
||||||
/* FT Action frames */
|
/* FT Action frames */
|
||||||
if (nl80211_register_action_frame(bss, (u8 *) "\x06", 1) < 0)
|
if (nl80211_register_action_frame(bss, (u8 *) "\x06", 1) < 0)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
else
|
else if (!drv->has_driver_key_mgmt) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Update supported AKMs only if the driver doesn't advertize
|
||||||
|
* any AKM capabilities. */
|
||||||
drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT |
|
drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT |
|
||||||
WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK;
|
WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK;
|
||||||
|
|
||||||
|
/* Update per interface supported AKMs */
|
||||||
|
for (i = 0; i < WPA_IF_MAX; i++)
|
||||||
|
drv->capa.key_mgmt_iftype[i] = drv->capa.key_mgmt;
|
||||||
|
}
|
||||||
|
|
||||||
/* WNM - BSS Transition Management Request */
|
/* WNM - BSS Transition Management Request */
|
||||||
if (nl80211_register_action_frame(bss, (u8 *) "\x0a\x07", 2) < 0)
|
if (nl80211_register_action_frame(bss, (u8 *) "\x0a\x07", 2) < 0)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
@ -5056,6 +5065,10 @@ const char * nl80211_iftype_str(enum nl80211_iftype mode)
|
||||||
return "P2P_GO";
|
return "P2P_GO";
|
||||||
case NL80211_IFTYPE_P2P_DEVICE:
|
case NL80211_IFTYPE_P2P_DEVICE:
|
||||||
return "P2P_DEVICE";
|
return "P2P_DEVICE";
|
||||||
|
case NL80211_IFTYPE_OCB:
|
||||||
|
return "OCB";
|
||||||
|
case NL80211_IFTYPE_NAN:
|
||||||
|
return "NAN";
|
||||||
default:
|
default:
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,6 +111,7 @@ struct wpa_driver_nl80211_data {
|
||||||
unsigned int num_iface_ext_capa;
|
unsigned int num_iface_ext_capa;
|
||||||
|
|
||||||
int has_capability;
|
int has_capability;
|
||||||
|
int has_driver_key_mgmt;
|
||||||
|
|
||||||
int operstate;
|
int operstate;
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,8 @@ struct wiphy_info_data {
|
||||||
unsigned int mac_addr_rand_scan_supported:1;
|
unsigned int mac_addr_rand_scan_supported:1;
|
||||||
unsigned int mac_addr_rand_sched_scan_supported:1;
|
unsigned int mac_addr_rand_sched_scan_supported:1;
|
||||||
unsigned int update_ft_ies_supported:1;
|
unsigned int update_ft_ies_supported:1;
|
||||||
|
unsigned int has_key_mgmt:1;
|
||||||
|
unsigned int has_key_mgmt_iftype:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -252,6 +254,158 @@ static void wiphy_info_supp_cmds(struct wiphy_info_data *info,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned int get_akm_suites_info(struct nlattr *tb)
|
||||||
|
{
|
||||||
|
int i, num;
|
||||||
|
unsigned int key_mgmt = 0;
|
||||||
|
u32 *akms;
|
||||||
|
|
||||||
|
if (!tb)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
num = nla_len(tb) / sizeof(u32);
|
||||||
|
akms = nla_data(tb);
|
||||||
|
for (i = 0; i < num; i++) {
|
||||||
|
switch (akms[i]) {
|
||||||
|
case RSN_AUTH_KEY_MGMT_UNSPEC_802_1X:
|
||||||
|
key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA |
|
||||||
|
WPA_DRIVER_CAPA_KEY_MGMT_WPA2;
|
||||||
|
break;
|
||||||
|
case RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X:
|
||||||
|
key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
|
||||||
|
WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK;
|
||||||
|
break;
|
||||||
|
case RSN_AUTH_KEY_MGMT_FT_802_1X:
|
||||||
|
key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT;
|
||||||
|
break;
|
||||||
|
case RSN_AUTH_KEY_MGMT_FT_PSK:
|
||||||
|
key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK;
|
||||||
|
break;
|
||||||
|
case RSN_AUTH_KEY_MGMT_802_1X_SUITE_B:
|
||||||
|
key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B;
|
||||||
|
break;
|
||||||
|
case RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192:
|
||||||
|
key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B_192;
|
||||||
|
break;
|
||||||
|
case RSN_AUTH_KEY_MGMT_OWE:
|
||||||
|
key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_OWE;
|
||||||
|
break;
|
||||||
|
case RSN_AUTH_KEY_MGMT_DPP:
|
||||||
|
key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_DPP;
|
||||||
|
break;
|
||||||
|
case RSN_AUTH_KEY_MGMT_FILS_SHA256:
|
||||||
|
key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA256;
|
||||||
|
break;
|
||||||
|
case RSN_AUTH_KEY_MGMT_FILS_SHA384:
|
||||||
|
key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384;
|
||||||
|
break;
|
||||||
|
case RSN_AUTH_KEY_MGMT_FT_FILS_SHA256:
|
||||||
|
key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA256;
|
||||||
|
break;
|
||||||
|
case RSN_AUTH_KEY_MGMT_FT_FILS_SHA384:
|
||||||
|
key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA384;
|
||||||
|
break;
|
||||||
|
case RSN_AUTH_KEY_MGMT_SAE:
|
||||||
|
key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_SAE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return key_mgmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void get_iface_akm_suites_info(struct wiphy_info_data *info,
|
||||||
|
struct nlattr *nl_akms)
|
||||||
|
{
|
||||||
|
struct nlattr *tb[NL80211_IFTYPE_AKM_ATTR_MAX + 1];
|
||||||
|
struct nlattr *nl_iftype;
|
||||||
|
unsigned int key_mgmt;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!nl_akms)
|
||||||
|
return;
|
||||||
|
|
||||||
|
nla_parse(tb, NL80211_IFTYPE_AKM_ATTR_MAX,
|
||||||
|
nla_data(nl_akms), nla_len(nl_akms), NULL);
|
||||||
|
|
||||||
|
if (!tb[NL80211_IFTYPE_AKM_ATTR_IFTYPES] ||
|
||||||
|
!tb[NL80211_IFTYPE_AKM_ATTR_SUITES])
|
||||||
|
return;
|
||||||
|
|
||||||
|
info->has_key_mgmt_iftype = 1;
|
||||||
|
key_mgmt = get_akm_suites_info(tb[NL80211_IFTYPE_AKM_ATTR_SUITES]);
|
||||||
|
|
||||||
|
nla_for_each_nested(nl_iftype, tb[NL80211_IFTYPE_AKM_ATTR_IFTYPES], i) {
|
||||||
|
switch (nla_type(nl_iftype)) {
|
||||||
|
case NL80211_IFTYPE_ADHOC:
|
||||||
|
info->drv->capa.key_mgmt_iftype[WPA_IF_IBSS] = key_mgmt;
|
||||||
|
break;
|
||||||
|
case NL80211_IFTYPE_STATION:
|
||||||
|
info->drv->capa.key_mgmt_iftype[WPA_IF_STATION] =
|
||||||
|
key_mgmt;
|
||||||
|
break;
|
||||||
|
case NL80211_IFTYPE_AP:
|
||||||
|
info->drv->capa.key_mgmt_iftype[WPA_IF_AP_BSS] =
|
||||||
|
key_mgmt;
|
||||||
|
break;
|
||||||
|
case NL80211_IFTYPE_AP_VLAN:
|
||||||
|
info->drv->capa.key_mgmt_iftype[WPA_IF_AP_VLAN] =
|
||||||
|
key_mgmt;
|
||||||
|
break;
|
||||||
|
case NL80211_IFTYPE_MESH_POINT:
|
||||||
|
info->drv->capa.key_mgmt_iftype[WPA_IF_MESH] = key_mgmt;
|
||||||
|
break;
|
||||||
|
case NL80211_IFTYPE_P2P_CLIENT:
|
||||||
|
info->drv->capa.key_mgmt_iftype[WPA_IF_P2P_CLIENT] =
|
||||||
|
key_mgmt;
|
||||||
|
break;
|
||||||
|
case NL80211_IFTYPE_P2P_GO:
|
||||||
|
info->drv->capa.key_mgmt_iftype[WPA_IF_P2P_GO] =
|
||||||
|
key_mgmt;
|
||||||
|
break;
|
||||||
|
case NL80211_IFTYPE_P2P_DEVICE:
|
||||||
|
info->drv->capa.key_mgmt_iftype[WPA_IF_P2P_DEVICE] =
|
||||||
|
key_mgmt;
|
||||||
|
break;
|
||||||
|
case NL80211_IFTYPE_NAN:
|
||||||
|
info->drv->capa.key_mgmt_iftype[WPA_IF_NAN] = key_mgmt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
wpa_printf(MSG_DEBUG, "nl80211: %s supported key_mgmt 0x%x",
|
||||||
|
nl80211_iftype_str(nla_type(nl_iftype)),
|
||||||
|
key_mgmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void wiphy_info_iftype_akm_suites(struct wiphy_info_data *info,
|
||||||
|
struct nlattr *tb)
|
||||||
|
{
|
||||||
|
struct nlattr *nl_if;
|
||||||
|
int rem_if;
|
||||||
|
|
||||||
|
if (!tb)
|
||||||
|
return;
|
||||||
|
|
||||||
|
nla_for_each_nested(nl_if, tb, rem_if)
|
||||||
|
get_iface_akm_suites_info(info, nl_if);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void wiphy_info_akm_suites(struct wiphy_info_data *info,
|
||||||
|
struct nlattr *tb)
|
||||||
|
{
|
||||||
|
if (!tb)
|
||||||
|
return;
|
||||||
|
|
||||||
|
info->has_key_mgmt = 1;
|
||||||
|
info->capa->key_mgmt = get_akm_suites_info(tb);
|
||||||
|
wpa_printf(MSG_DEBUG, "nl80211: wiphy supported key_mgmt 0x%x",
|
||||||
|
info->capa->key_mgmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void wiphy_info_cipher_suites(struct wiphy_info_data *info,
|
static void wiphy_info_cipher_suites(struct wiphy_info_data *info,
|
||||||
struct nlattr *tb)
|
struct nlattr *tb)
|
||||||
{
|
{
|
||||||
|
@ -696,6 +850,8 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
|
||||||
wiphy_info_iface_comb(info, tb[NL80211_ATTR_INTERFACE_COMBINATIONS]);
|
wiphy_info_iface_comb(info, tb[NL80211_ATTR_INTERFACE_COMBINATIONS]);
|
||||||
wiphy_info_supp_cmds(info, tb[NL80211_ATTR_SUPPORTED_COMMANDS]);
|
wiphy_info_supp_cmds(info, tb[NL80211_ATTR_SUPPORTED_COMMANDS]);
|
||||||
wiphy_info_cipher_suites(info, tb[NL80211_ATTR_CIPHER_SUITES]);
|
wiphy_info_cipher_suites(info, tb[NL80211_ATTR_CIPHER_SUITES]);
|
||||||
|
wiphy_info_akm_suites(info, tb[NL80211_ATTR_AKM_SUITES]);
|
||||||
|
wiphy_info_iftype_akm_suites(info, tb[NL80211_ATTR_IFTYPE_AKM_SUITES]);
|
||||||
|
|
||||||
if (tb[NL80211_ATTR_OFFCHANNEL_TX_OK]) {
|
if (tb[NL80211_ATTR_OFFCHANNEL_TX_OK]) {
|
||||||
wpa_printf(MSG_DEBUG, "nl80211: Using driver-based "
|
wpa_printf(MSG_DEBUG, "nl80211: Using driver-based "
|
||||||
|
@ -1098,6 +1254,8 @@ static void qca_nl80211_get_features(struct wpa_driver_nl80211_data *drv)
|
||||||
int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
|
int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
|
||||||
{
|
{
|
||||||
struct wiphy_info_data info;
|
struct wiphy_info_data info;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (wpa_driver_nl80211_get_info(drv, &info))
|
if (wpa_driver_nl80211_get_info(drv, &info))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -1105,6 +1263,11 @@ int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
drv->has_capability = 1;
|
drv->has_capability = 1;
|
||||||
|
drv->has_driver_key_mgmt = info.has_key_mgmt | info.has_key_mgmt_iftype;
|
||||||
|
|
||||||
|
/* Fallback to hardcoded defaults if the driver does nott advertize any
|
||||||
|
* AKM capabilities. */
|
||||||
|
if (!drv->has_driver_key_mgmt) {
|
||||||
drv->capa.key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA |
|
drv->capa.key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA |
|
||||||
WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
|
WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
|
||||||
WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
|
WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
|
||||||
|
@ -1115,17 +1278,47 @@ int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
|
||||||
|
|
||||||
if (drv->capa.enc & (WPA_DRIVER_CAPA_ENC_CCMP_256 |
|
if (drv->capa.enc & (WPA_DRIVER_CAPA_ENC_CCMP_256 |
|
||||||
WPA_DRIVER_CAPA_ENC_GCMP_256))
|
WPA_DRIVER_CAPA_ENC_GCMP_256))
|
||||||
drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B_192;
|
drv->capa.key_mgmt |=
|
||||||
|
WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B_192;
|
||||||
|
|
||||||
if (drv->capa.flags & WPA_DRIVER_FLAGS_SME)
|
if (drv->capa.flags & WPA_DRIVER_FLAGS_SME)
|
||||||
drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA256 |
|
drv->capa.key_mgmt |=
|
||||||
|
WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA256 |
|
||||||
WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384 |
|
WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384 |
|
||||||
WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA256 |
|
WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA256 |
|
||||||
WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA384 |
|
WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA384 |
|
||||||
WPA_DRIVER_CAPA_KEY_MGMT_SAE;
|
WPA_DRIVER_CAPA_KEY_MGMT_SAE;
|
||||||
else if (drv->capa.flags & WPA_DRIVER_FLAGS_FILS_SK_OFFLOAD)
|
else if (drv->capa.flags & WPA_DRIVER_FLAGS_FILS_SK_OFFLOAD)
|
||||||
drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA256 |
|
drv->capa.key_mgmt |=
|
||||||
|
WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA256 |
|
||||||
WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384;
|
WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!info.has_key_mgmt_iftype) {
|
||||||
|
/* If the driver does not advertize per interface AKM
|
||||||
|
* capabilities, consider all interfaces to support default AKMs
|
||||||
|
* in key_mgmt. */
|
||||||
|
for (i = 0; i < WPA_IF_MAX; i++)
|
||||||
|
drv->capa.key_mgmt_iftype[i] = drv->capa.key_mgmt;
|
||||||
|
} else if (info.has_key_mgmt_iftype && !info.has_key_mgmt) {
|
||||||
|
/* If the driver advertizes only per interface supported AKMs
|
||||||
|
* but does not advertize per wiphy AKM capabilities, consider
|
||||||
|
* the default key_mgmt as a mask of per interface supported
|
||||||
|
* AKMs. */
|
||||||
|
drv->capa.key_mgmt = 0;
|
||||||
|
for (i = 0; i < WPA_IF_MAX; i++)
|
||||||
|
drv->capa.key_mgmt |= drv->capa.key_mgmt_iftype[i];
|
||||||
|
} else if (info.has_key_mgmt_iftype && info.has_key_mgmt) {
|
||||||
|
/* If the driver advertizes AKM capabilities both per wiphy and
|
||||||
|
* per interface, consider the interfaces for which per
|
||||||
|
* interface AKM capabilities were not received to support the
|
||||||
|
* default key_mgmt capabilities.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < WPA_IF_MAX; i++)
|
||||||
|
if (!drv->capa.key_mgmt_iftype[i])
|
||||||
|
drv->capa.key_mgmt_iftype[i] =
|
||||||
|
drv->capa.key_mgmt;
|
||||||
|
}
|
||||||
|
|
||||||
drv->capa.auth = WPA_DRIVER_AUTH_OPEN |
|
drv->capa.auth = WPA_DRIVER_AUTH_OPEN |
|
||||||
WPA_DRIVER_AUTH_SHARED |
|
WPA_DRIVER_AUTH_SHARED |
|
||||||
|
|
|
@ -968,6 +968,7 @@ static void wext_check_hostap(struct wpa_driver_wext_data *drv)
|
||||||
static int wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv)
|
static int wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv)
|
||||||
{
|
{
|
||||||
int send_rfkill_event = 0;
|
int send_rfkill_event = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1) < 0) {
|
if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1) < 0) {
|
||||||
if (rfkill_is_blocked(drv->rfkill)) {
|
if (rfkill_is_blocked(drv->rfkill)) {
|
||||||
|
@ -996,6 +997,10 @@ static int wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv)
|
||||||
|
|
||||||
wpa_driver_wext_get_range(drv);
|
wpa_driver_wext_get_range(drv);
|
||||||
|
|
||||||
|
/* Update per interface supported AKMs */
|
||||||
|
for (i = 0; i < WPA_IF_MAX; i++)
|
||||||
|
drv->capa.key_mgmt_iftype[i] = drv->capa.key_mgmt;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unlock the driver's BSSID and force to a random SSID to clear any
|
* Unlock the driver's BSSID and force to a random SSID to clear any
|
||||||
* previous association the driver might have when the supplicant
|
* previous association the driver might have when the supplicant
|
||||||
|
|
Loading…
Reference in a new issue