wifi: cfg80211: Add link_id parameter to various key operations for MLO

Add support for various key operations on MLD by adding new parameter
link_id. Pass the link_id received from userspace to driver for add_key,
get_key, del_key, set_default_key, set_default_mgmt_key and
set_default_beacon_key to support configuring keys specific to each MLO
link. Userspace must not specify link ID for MLO pairwise key since it
is common for all the MLO links.

Signed-off-by: Veerendranath Jakkam <quic_vjakkam@quicinc.com>
Link: https://lore.kernel.org/r/20220730052643.1959111-4-quic_vjakkam@quicinc.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Veerendranath Jakkam 2022-07-30 10:56:43 +05:30 committed by Johannes Berg
parent aa129bcd34
commit e7a7b84e33
20 changed files with 312 additions and 178 deletions

View File

@ -1124,7 +1124,7 @@ void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq,
} }
static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
u8 key_index, bool pairwise, int link_id, u8 key_index, bool pairwise,
const u8 *mac_addr, const u8 *mac_addr,
struct key_params *params) struct key_params *params)
{ {
@ -1249,7 +1249,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
} }
static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
u8 key_index, bool pairwise, int link_id, u8 key_index, bool pairwise,
const u8 *mac_addr) const u8 *mac_addr)
{ {
struct ath6kl *ar = ath6kl_priv(ndev); struct ath6kl *ar = ath6kl_priv(ndev);
@ -1279,7 +1279,7 @@ static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
} }
static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
u8 key_index, bool pairwise, int link_id, u8 key_index, bool pairwise,
const u8 *mac_addr, void *cookie, const u8 *mac_addr, void *cookie,
void (*callback) (void *cookie, void (*callback) (void *cookie,
struct key_params *)) struct key_params *))
@ -1314,7 +1314,7 @@ static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
} }
static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy, static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
struct net_device *ndev, struct net_device *ndev, int link_id,
u8 key_index, bool unicast, u8 key_index, bool unicast,
bool multicast) bool multicast)
{ {

View File

@ -1620,7 +1620,7 @@ static void wil_del_rx_key(u8 key_index, enum wmi_key_usage key_usage,
} }
static int wil_cfg80211_add_key(struct wiphy *wiphy, static int wil_cfg80211_add_key(struct wiphy *wiphy,
struct net_device *ndev, struct net_device *ndev, int link_id,
u8 key_index, bool pairwise, u8 key_index, bool pairwise,
const u8 *mac_addr, const u8 *mac_addr,
struct key_params *params) struct key_params *params)
@ -1696,7 +1696,7 @@ static int wil_cfg80211_add_key(struct wiphy *wiphy,
} }
static int wil_cfg80211_del_key(struct wiphy *wiphy, static int wil_cfg80211_del_key(struct wiphy *wiphy,
struct net_device *ndev, struct net_device *ndev, int link_id,
u8 key_index, bool pairwise, u8 key_index, bool pairwise,
const u8 *mac_addr) const u8 *mac_addr)
{ {
@ -1723,7 +1723,7 @@ static int wil_cfg80211_del_key(struct wiphy *wiphy,
/* Need to be present or wiphy_new() will WARN */ /* Need to be present or wiphy_new() will WARN */
static int wil_cfg80211_set_default_key(struct wiphy *wiphy, static int wil_cfg80211_set_default_key(struct wiphy *wiphy,
struct net_device *ndev, struct net_device *ndev, int link_id,
u8 key_index, bool unicast, u8 key_index, bool unicast,
bool multicast) bool multicast)
{ {
@ -2072,8 +2072,8 @@ void wil_cfg80211_ap_recovery(struct wil6210_priv *wil)
key_params.key = vif->gtk; key_params.key = vif->gtk;
key_params.key_len = vif->gtk_len; key_params.key_len = vif->gtk_len;
key_params.seq_len = IEEE80211_GCMP_PN_LEN; key_params.seq_len = IEEE80211_GCMP_PN_LEN;
rc = wil_cfg80211_add_key(wiphy, ndev, vif->gtk_index, false, rc = wil_cfg80211_add_key(wiphy, ndev, -1, vif->gtk_index,
NULL, &key_params); false, NULL, &key_params);
if (rc) if (rc)
wil_err(wil, "vif %d recovery add key failed (%d)\n", wil_err(wil, "vif %d recovery add key failed (%d)\n",
i, rc); i, rc);

View File

@ -2361,7 +2361,8 @@ done:
static s32 static s32
brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev, brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
u8 key_idx, bool unicast, bool multicast) int link_id, u8 key_idx, bool unicast,
bool multicast)
{ {
struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_pub *drvr = ifp->drvr; struct brcmf_pub *drvr = ifp->drvr;
@ -2395,7 +2396,8 @@ done:
static s32 static s32
brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
u8 key_idx, bool pairwise, const u8 *mac_addr) int link_id, u8 key_idx, bool pairwise,
const u8 *mac_addr)
{ {
struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_wsec_key *key; struct brcmf_wsec_key *key;
@ -2432,8 +2434,8 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
static s32 static s32
brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
u8 key_idx, bool pairwise, const u8 *mac_addr, int link_id, u8 key_idx, bool pairwise,
struct key_params *params) const u8 *mac_addr, struct key_params *params)
{ {
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_if *ifp = netdev_priv(ndev);
@ -2457,8 +2459,8 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
} }
if (params->key_len == 0) if (params->key_len == 0)
return brcmf_cfg80211_del_key(wiphy, ndev, key_idx, pairwise, return brcmf_cfg80211_del_key(wiphy, ndev, -1, key_idx,
mac_addr); pairwise, mac_addr);
if (params->key_len > sizeof(key->data)) { if (params->key_len > sizeof(key->data)) {
bphy_err(drvr, "Too long key length (%u)\n", params->key_len); bphy_err(drvr, "Too long key length (%u)\n", params->key_len);
@ -2553,8 +2555,9 @@ done:
} }
static s32 static s32
brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_idx, brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
bool pairwise, const u8 *mac_addr, void *cookie, int link_id, u8 key_idx, bool pairwise,
const u8 *mac_addr, void *cookie,
void (*callback)(void *cookie, void (*callback)(void *cookie,
struct key_params *params)) struct key_params *params))
{ {
@ -2610,7 +2613,8 @@ done:
static s32 static s32
brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy, brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
struct net_device *ndev, u8 key_idx) struct net_device *ndev, int link_id,
u8 key_idx)
{ {
struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_if *ifp = netdev_priv(ndev);

View File

@ -1435,7 +1435,7 @@ static int lbs_cfg_disconnect(struct wiphy *wiphy, struct net_device *dev,
} }
static int lbs_cfg_set_default_key(struct wiphy *wiphy, static int lbs_cfg_set_default_key(struct wiphy *wiphy,
struct net_device *netdev, struct net_device *netdev, int link_id,
u8 key_index, bool unicast, u8 key_index, bool unicast,
bool multicast) bool multicast)
{ {
@ -1455,8 +1455,8 @@ static int lbs_cfg_set_default_key(struct wiphy *wiphy,
static int lbs_cfg_add_key(struct wiphy *wiphy, struct net_device *netdev, static int lbs_cfg_add_key(struct wiphy *wiphy, struct net_device *netdev,
u8 idx, bool pairwise, const u8 *mac_addr, int link_id, u8 idx, bool pairwise,
struct key_params *params) const u8 *mac_addr, struct key_params *params)
{ {
struct lbs_private *priv = wiphy_priv(wiphy); struct lbs_private *priv = wiphy_priv(wiphy);
u16 key_info; u16 key_info;
@ -1516,7 +1516,8 @@ static int lbs_cfg_add_key(struct wiphy *wiphy, struct net_device *netdev,
static int lbs_cfg_del_key(struct wiphy *wiphy, struct net_device *netdev, static int lbs_cfg_del_key(struct wiphy *wiphy, struct net_device *netdev,
u8 key_index, bool pairwise, const u8 *mac_addr) int link_id, u8 key_index, bool pairwise,
const u8 *mac_addr)
{ {
lbs_deb_assoc("del_key: key_idx %d, mac_addr %pM\n", lbs_deb_assoc("del_key: key_idx %d, mac_addr %pM\n",

View File

@ -154,7 +154,8 @@ static void *mwifiex_cfg80211_get_adapter(struct wiphy *wiphy)
*/ */
static int static int
mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev, mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev,
u8 key_index, bool pairwise, const u8 *mac_addr) int link_id, u8 key_index, bool pairwise,
const u8 *mac_addr)
{ {
struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
static const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; static const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
@ -443,7 +444,7 @@ mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy,
*/ */
static int static int
mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev, mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
u8 key_index, bool unicast, int link_id, u8 key_index, bool unicast,
bool multicast) bool multicast)
{ {
struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
@ -468,8 +469,8 @@ mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
*/ */
static int static int
mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev, mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
u8 key_index, bool pairwise, const u8 *mac_addr, int link_id, u8 key_index, bool pairwise,
struct key_params *params) const u8 *mac_addr, struct key_params *params)
{ {
struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
struct mwifiex_wep_key *wep_key; struct mwifiex_wep_key *wep_key;
@ -506,6 +507,7 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
static int static int
mwifiex_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, mwifiex_cfg80211_set_default_mgmt_key(struct wiphy *wiphy,
struct net_device *netdev, struct net_device *netdev,
int link_id,
u8 key_index) u8 key_index)
{ {
struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);

View File

@ -540,8 +540,9 @@ static int wilc_wfi_cfg_copy_wpa_info(struct wilc_wfi_key *key_info,
return 0; return 0;
} }
static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, static int add_key(struct wiphy *wiphy, struct net_device *netdev, int link_id,
bool pairwise, const u8 *mac_addr, struct key_params *params) u8 key_index, bool pairwise, const u8 *mac_addr,
struct key_params *params)
{ {
int ret = 0, keylen = params->key_len; int ret = 0, keylen = params->key_len;
@ -644,7 +645,7 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
return ret; return ret;
} }
static int del_key(struct wiphy *wiphy, struct net_device *netdev, static int del_key(struct wiphy *wiphy, struct net_device *netdev, int link_id,
u8 key_index, u8 key_index,
bool pairwise, bool pairwise,
const u8 *mac_addr) const u8 *mac_addr)
@ -685,8 +686,9 @@ static int del_key(struct wiphy *wiphy, struct net_device *netdev,
return 0; return 0;
} }
static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, static int get_key(struct wiphy *wiphy, struct net_device *netdev, int link_id,
bool pairwise, const u8 *mac_addr, void *cookie, u8 key_index, bool pairwise, const u8 *mac_addr,
void *cookie,
void (*callback)(void *cookie, struct key_params *)) void (*callback)(void *cookie, struct key_params *))
{ {
struct wilc_vif *vif = netdev_priv(netdev); struct wilc_vif *vif = netdev_priv(netdev);
@ -723,13 +725,14 @@ static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
/* wiphy_new_nm() will WARNON if not present */ /* wiphy_new_nm() will WARNON if not present */
static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, static int set_default_key(struct wiphy *wiphy, struct net_device *netdev,
u8 key_index, bool unicast, bool multicast) int link_id, u8 key_index, bool unicast,
bool multicast)
{ {
return 0; return 0;
} }
static int set_default_mgmt_key(struct wiphy *wiphy, struct net_device *netdev, static int set_default_mgmt_key(struct wiphy *wiphy, struct net_device *netdev,
u8 key_index) int link_id, u8 key_index)
{ {
struct wilc_vif *vif = netdev_priv(netdev); struct wilc_vif *vif = netdev_priv(netdev);

View File

@ -532,8 +532,8 @@ qtnf_dump_station(struct wiphy *wiphy, struct net_device *dev,
} }
static int qtnf_add_key(struct wiphy *wiphy, struct net_device *dev, static int qtnf_add_key(struct wiphy *wiphy, struct net_device *dev,
u8 key_index, bool pairwise, const u8 *mac_addr, int link_id, u8 key_index, bool pairwise,
struct key_params *params) const u8 *mac_addr, struct key_params *params)
{ {
struct qtnf_vif *vif = qtnf_netdev_get_priv(dev); struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
int ret; int ret;
@ -548,7 +548,8 @@ static int qtnf_add_key(struct wiphy *wiphy, struct net_device *dev,
} }
static int qtnf_del_key(struct wiphy *wiphy, struct net_device *dev, static int qtnf_del_key(struct wiphy *wiphy, struct net_device *dev,
u8 key_index, bool pairwise, const u8 *mac_addr) int link_id, u8 key_index, bool pairwise,
const u8 *mac_addr)
{ {
struct qtnf_vif *vif = qtnf_netdev_get_priv(dev); struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
int ret; int ret;
@ -569,7 +570,8 @@ static int qtnf_del_key(struct wiphy *wiphy, struct net_device *dev,
} }
static int qtnf_set_default_key(struct wiphy *wiphy, struct net_device *dev, static int qtnf_set_default_key(struct wiphy *wiphy, struct net_device *dev,
u8 key_index, bool unicast, bool multicast) int link_id, u8 key_index, bool unicast,
bool multicast)
{ {
struct qtnf_vif *vif = qtnf_netdev_get_priv(dev); struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
int ret; int ret;
@ -585,7 +587,7 @@ static int qtnf_set_default_key(struct wiphy *wiphy, struct net_device *dev,
static int static int
qtnf_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *dev, qtnf_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *dev,
u8 key_index) int link_id, u8 key_index)
{ {
struct qtnf_vif *vif = qtnf_netdev_get_priv(dev); struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
int ret; int ret;

View File

@ -489,14 +489,16 @@ static int rndis_join_ibss(struct wiphy *wiphy, struct net_device *dev,
static int rndis_leave_ibss(struct wiphy *wiphy, struct net_device *dev); static int rndis_leave_ibss(struct wiphy *wiphy, struct net_device *dev);
static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev, static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev,
u8 key_index, bool pairwise, const u8 *mac_addr, int link_id, u8 key_index, bool pairwise,
struct key_params *params); const u8 *mac_addr, struct key_params *params);
static int rndis_del_key(struct wiphy *wiphy, struct net_device *netdev, static int rndis_del_key(struct wiphy *wiphy, struct net_device *netdev,
u8 key_index, bool pairwise, const u8 *mac_addr); int link_id, u8 key_index, bool pairwise,
const u8 *mac_addr);
static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev, static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
u8 key_index, bool unicast, bool multicast); int link_id, u8 key_index, bool unicast,
bool multicast);
static int rndis_get_station(struct wiphy *wiphy, struct net_device *dev, static int rndis_get_station(struct wiphy *wiphy, struct net_device *dev,
const u8 *mac, struct station_info *sinfo); const u8 *mac, struct station_info *sinfo);
@ -2377,8 +2379,8 @@ static int rndis_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
} }
static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev, static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev,
u8 key_index, bool pairwise, const u8 *mac_addr, int link_id, u8 key_index, bool pairwise,
struct key_params *params) const u8 *mac_addr, struct key_params *params)
{ {
struct rndis_wlan_private *priv = wiphy_priv(wiphy); struct rndis_wlan_private *priv = wiphy_priv(wiphy);
struct usbnet *usbdev = priv->usbdev; struct usbnet *usbdev = priv->usbdev;
@ -2413,7 +2415,8 @@ static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev,
} }
static int rndis_del_key(struct wiphy *wiphy, struct net_device *netdev, static int rndis_del_key(struct wiphy *wiphy, struct net_device *netdev,
u8 key_index, bool pairwise, const u8 *mac_addr) int link_id, u8 key_index, bool pairwise,
const u8 *mac_addr)
{ {
struct rndis_wlan_private *priv = wiphy_priv(wiphy); struct rndis_wlan_private *priv = wiphy_priv(wiphy);
struct usbnet *usbdev = priv->usbdev; struct usbnet *usbdev = priv->usbdev;
@ -2424,7 +2427,8 @@ static int rndis_del_key(struct wiphy *wiphy, struct net_device *netdev,
} }
static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev, static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
u8 key_index, bool unicast, bool multicast) int link_id, u8 key_index, bool unicast,
bool multicast)
{ {
struct rndis_wlan_private *priv = wiphy_priv(wiphy); struct rndis_wlan_private *priv = wiphy_priv(wiphy);
struct usbnet *usbdev = priv->usbdev; struct usbnet *usbdev = priv->usbdev;

View File

@ -901,8 +901,8 @@ exit:
} }
static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev, static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev,
u8 key_index, bool pairwise, const u8 *mac_addr, int link_id, u8 key_index, bool pairwise,
struct key_params *params) const u8 *mac_addr, struct key_params *params)
{ {
char *alg_name; char *alg_name;
u32 param_len; u32 param_len;
@ -993,8 +993,8 @@ addkey_end:
} }
static int cfg80211_rtw_get_key(struct wiphy *wiphy, struct net_device *ndev, static int cfg80211_rtw_get_key(struct wiphy *wiphy, struct net_device *ndev,
u8 key_index, bool pairwise, const u8 *mac_addr, int link_id, u8 key_index, bool pairwise,
void *cookie, const u8 *mac_addr, void *cookie,
void (*callback)(void *cookie, void (*callback)(void *cookie,
struct key_params*)) struct key_params*))
{ {
@ -1002,7 +1002,8 @@ static int cfg80211_rtw_get_key(struct wiphy *wiphy, struct net_device *ndev,
} }
static int cfg80211_rtw_del_key(struct wiphy *wiphy, struct net_device *ndev, static int cfg80211_rtw_del_key(struct wiphy *wiphy, struct net_device *ndev,
u8 key_index, bool pairwise, const u8 *mac_addr) int link_id, u8 key_index, bool pairwise,
const u8 *mac_addr)
{ {
struct adapter *padapter = rtw_netdev_priv(ndev); struct adapter *padapter = rtw_netdev_priv(ndev);
struct security_priv *psecuritypriv = &padapter->securitypriv; struct security_priv *psecuritypriv = &padapter->securitypriv;
@ -1017,7 +1018,7 @@ static int cfg80211_rtw_del_key(struct wiphy *wiphy, struct net_device *ndev,
} }
static int cfg80211_rtw_set_default_key(struct wiphy *wiphy, static int cfg80211_rtw_set_default_key(struct wiphy *wiphy,
struct net_device *ndev, u8 key_index struct net_device *ndev, int link_id, u8 key_index
, bool unicast, bool multicast , bool unicast, bool multicast
) )
{ {

View File

@ -143,8 +143,8 @@ exit:
} }
static int prism2_add_key(struct wiphy *wiphy, struct net_device *dev, static int prism2_add_key(struct wiphy *wiphy, struct net_device *dev,
u8 key_index, bool pairwise, const u8 *mac_addr, int link_id, u8 key_index, bool pairwise,
struct key_params *params) const u8 *mac_addr, struct key_params *params)
{ {
struct wlandevice *wlandev = dev->ml_priv; struct wlandevice *wlandev = dev->ml_priv;
u32 did; u32 did;
@ -172,7 +172,7 @@ static int prism2_add_key(struct wiphy *wiphy, struct net_device *dev,
} }
static int prism2_get_key(struct wiphy *wiphy, struct net_device *dev, static int prism2_get_key(struct wiphy *wiphy, struct net_device *dev,
u8 key_index, bool pairwise, int link_id, u8 key_index, bool pairwise,
const u8 *mac_addr, void *cookie, const u8 *mac_addr, void *cookie,
void (*callback)(void *cookie, struct key_params*)) void (*callback)(void *cookie, struct key_params*))
{ {
@ -202,7 +202,8 @@ static int prism2_get_key(struct wiphy *wiphy, struct net_device *dev,
} }
static int prism2_del_key(struct wiphy *wiphy, struct net_device *dev, static int prism2_del_key(struct wiphy *wiphy, struct net_device *dev,
u8 key_index, bool pairwise, const u8 *mac_addr) int link_id, u8 key_index, bool pairwise,
const u8 *mac_addr)
{ {
struct wlandevice *wlandev = dev->ml_priv; struct wlandevice *wlandev = dev->ml_priv;
u32 did; u32 did;
@ -227,7 +228,8 @@ static int prism2_del_key(struct wiphy *wiphy, struct net_device *dev,
} }
static int prism2_set_default_key(struct wiphy *wiphy, struct net_device *dev, static int prism2_set_default_key(struct wiphy *wiphy, struct net_device *dev,
u8 key_index, bool unicast, bool multicast) int link_id, u8 key_index, bool unicast,
bool multicast)
{ {
struct wlandevice *wlandev = dev->ml_priv; struct wlandevice *wlandev = dev->ml_priv;

View File

@ -3931,22 +3931,33 @@ struct mgmt_frame_regs {
* @del_intf_link: Remove an MLO link from the given interface. * @del_intf_link: Remove an MLO link from the given interface.
* *
* @add_key: add a key with the given parameters. @mac_addr will be %NULL * @add_key: add a key with the given parameters. @mac_addr will be %NULL
* when adding a group key. * when adding a group key. @link_id will be -1 for non-MLO connection.
* For MLO connection, @link_id will be >= 0 for group key and -1 for
* pairwise key, @mac_addr will be peer's MLD address for MLO pairwise key.
* *
* @get_key: get information about the key with the given parameters. * @get_key: get information about the key with the given parameters.
* @mac_addr will be %NULL when requesting information for a group * @mac_addr will be %NULL when requesting information for a group
* key. All pointers given to the @callback function need not be valid * key. All pointers given to the @callback function need not be valid
* after it returns. This function should return an error if it is * after it returns. This function should return an error if it is
* not possible to retrieve the key, -ENOENT if it doesn't exist. * not possible to retrieve the key, -ENOENT if it doesn't exist.
* @link_id will be -1 for non-MLO connection. For MLO connection,
* @link_id will be >= 0 for group key and -1 for pairwise key, @mac_addr
* will be peer's MLD address for MLO pairwise key.
* *
* @del_key: remove a key given the @mac_addr (%NULL for a group key) * @del_key: remove a key given the @mac_addr (%NULL for a group key)
* and @key_index, return -ENOENT if the key doesn't exist. * and @key_index, return -ENOENT if the key doesn't exist. @link_id will
* be -1 for non-MLO connection. For MLO connection, @link_id will be >= 0
* for group key and -1 for pairwise key, @mac_addr will be peer's MLD
* address for MLO pairwise key.
* *
* @set_default_key: set the default key on an interface * @set_default_key: set the default key on an interface. @link_id will be >= 0
* for MLO connection and -1 for non-MLO connection.
* *
* @set_default_mgmt_key: set the default management frame key on an interface * @set_default_mgmt_key: set the default management frame key on an interface.
* @link_id will be >= 0 for MLO connection and -1 for non-MLO connection.
* *
* @set_default_beacon_key: set the default Beacon frame key on an interface * @set_default_beacon_key: set the default Beacon frame key on an interface.
* @link_id will be >= 0 for MLO connection and -1 for non-MLO connection.
* *
* @set_rekey_data: give the data necessary for GTK rekeying to the driver * @set_rekey_data: give the data necessary for GTK rekeying to the driver
* *
@ -4295,22 +4306,24 @@ struct cfg80211_ops {
unsigned int link_id); unsigned int link_id);
int (*add_key)(struct wiphy *wiphy, struct net_device *netdev, int (*add_key)(struct wiphy *wiphy, struct net_device *netdev,
u8 key_index, bool pairwise, const u8 *mac_addr, int link_id, u8 key_index, bool pairwise,
struct key_params *params); const u8 *mac_addr, struct key_params *params);
int (*get_key)(struct wiphy *wiphy, struct net_device *netdev, int (*get_key)(struct wiphy *wiphy, struct net_device *netdev,
u8 key_index, bool pairwise, const u8 *mac_addr, int link_id, u8 key_index, bool pairwise,
void *cookie, const u8 *mac_addr, void *cookie,
void (*callback)(void *cookie, struct key_params*)); void (*callback)(void *cookie, struct key_params*));
int (*del_key)(struct wiphy *wiphy, struct net_device *netdev, int (*del_key)(struct wiphy *wiphy, struct net_device *netdev,
u8 key_index, bool pairwise, const u8 *mac_addr); int link_id, u8 key_index, bool pairwise,
const u8 *mac_addr);
int (*set_default_key)(struct wiphy *wiphy, int (*set_default_key)(struct wiphy *wiphy,
struct net_device *netdev, struct net_device *netdev, int link_id,
u8 key_index, bool unicast, bool multicast); u8 key_index, bool unicast, bool multicast);
int (*set_default_mgmt_key)(struct wiphy *wiphy, int (*set_default_mgmt_key)(struct wiphy *wiphy,
struct net_device *netdev, struct net_device *netdev, int link_id,
u8 key_index); u8 key_index);
int (*set_default_beacon_key)(struct wiphy *wiphy, int (*set_default_beacon_key)(struct wiphy *wiphy,
struct net_device *netdev, struct net_device *netdev,
int link_id,
u8 key_index); u8 key_index);
int (*start_ap)(struct wiphy *wiphy, struct net_device *dev, int (*start_ap)(struct wiphy *wiphy, struct net_device *dev,

View File

@ -377,14 +377,22 @@
* the non-transmitting interfaces are deleted as well. * the non-transmitting interfaces are deleted as well.
* *
* @NL80211_CMD_GET_KEY: Get sequence counter information for a key specified * @NL80211_CMD_GET_KEY: Get sequence counter information for a key specified
* by %NL80211_ATTR_KEY_IDX and/or %NL80211_ATTR_MAC. * by %NL80211_ATTR_KEY_IDX and/or %NL80211_ATTR_MAC. %NL80211_ATTR_MAC
* represents peer's MLD address for MLO pairwise key. For MLO group key,
* the link is identified by %NL80211_ATTR_MLO_LINK_ID.
* @NL80211_CMD_SET_KEY: Set key attributes %NL80211_ATTR_KEY_DEFAULT, * @NL80211_CMD_SET_KEY: Set key attributes %NL80211_ATTR_KEY_DEFAULT,
* %NL80211_ATTR_KEY_DEFAULT_MGMT, or %NL80211_ATTR_KEY_THRESHOLD. * %NL80211_ATTR_KEY_DEFAULT_MGMT, or %NL80211_ATTR_KEY_THRESHOLD.
* For MLO connection, the link to set default key is identified by
* %NL80211_ATTR_MLO_LINK_ID.
* @NL80211_CMD_NEW_KEY: add a key with given %NL80211_ATTR_KEY_DATA, * @NL80211_CMD_NEW_KEY: add a key with given %NL80211_ATTR_KEY_DATA,
* %NL80211_ATTR_KEY_IDX, %NL80211_ATTR_MAC, %NL80211_ATTR_KEY_CIPHER, * %NL80211_ATTR_KEY_IDX, %NL80211_ATTR_MAC, %NL80211_ATTR_KEY_CIPHER,
* and %NL80211_ATTR_KEY_SEQ attributes. * and %NL80211_ATTR_KEY_SEQ attributes. %NL80211_ATTR_MAC represents
* peer's MLD address for MLO pairwise key. The link to add MLO
* group key is identified by %NL80211_ATTR_MLO_LINK_ID.
* @NL80211_CMD_DEL_KEY: delete a key identified by %NL80211_ATTR_KEY_IDX * @NL80211_CMD_DEL_KEY: delete a key identified by %NL80211_ATTR_KEY_IDX
* or %NL80211_ATTR_MAC. * or %NL80211_ATTR_MAC. %NL80211_ATTR_MAC represents peer's MLD address
* for MLO pairwise key. The link to delete group key is identified by
* %NL80211_ATTR_MLO_LINK_ID.
* *
* @NL80211_CMD_GET_BEACON: (not used) * @NL80211_CMD_GET_BEACON: (not used)
* @NL80211_CMD_SET_BEACON: change the beacon on an access point interface * @NL80211_CMD_SET_BEACON: change the beacon on an access point interface

View File

@ -452,8 +452,8 @@ static int ieee80211_set_tx(struct ieee80211_sub_if_data *sdata,
} }
static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
u8 key_idx, bool pairwise, const u8 *mac_addr, int link_id, u8 key_idx, bool pairwise,
struct key_params *params) const u8 *mac_addr, struct key_params *params)
{ {
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_local *local = sdata->local; struct ieee80211_local *local = sdata->local;
@ -596,7 +596,8 @@ ieee80211_lookup_key(struct ieee80211_sub_if_data *sdata,
} }
static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
u8 key_idx, bool pairwise, const u8 *mac_addr) int link_id, u8 key_idx, bool pairwise,
const u8 *mac_addr)
{ {
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_local *local = sdata->local; struct ieee80211_local *local = sdata->local;
@ -623,8 +624,8 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
} }
static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
u8 key_idx, bool pairwise, const u8 *mac_addr, int link_id, u8 key_idx, bool pairwise,
void *cookie, const u8 *mac_addr, void *cookie,
void (*callback)(void *cookie, void (*callback)(void *cookie,
struct key_params *params)) struct key_params *params))
{ {
@ -729,7 +730,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
static int ieee80211_config_default_key(struct wiphy *wiphy, static int ieee80211_config_default_key(struct wiphy *wiphy,
struct net_device *dev, struct net_device *dev,
u8 key_idx, bool uni, int link_id, u8 key_idx, bool uni,
bool multi) bool multi)
{ {
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@ -741,7 +742,7 @@ static int ieee80211_config_default_key(struct wiphy *wiphy,
static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy, static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy,
struct net_device *dev, struct net_device *dev,
u8 key_idx) int link_id, u8 key_idx)
{ {
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@ -752,7 +753,7 @@ static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy,
static int ieee80211_config_default_beacon_key(struct wiphy *wiphy, static int ieee80211_config_default_beacon_key(struct wiphy *wiphy,
struct net_device *dev, struct net_device *dev,
u8 key_idx) int link_id, u8 key_idx)
{ {
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);

View File

@ -171,7 +171,7 @@ static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext)
*/ */
if (rdev->ops->del_key) if (rdev->ops->del_key)
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
rdev_del_key(rdev, dev, i, false, NULL); rdev_del_key(rdev, dev, -1, i, false, NULL);
if (wdev->u.ibss.current_bss) { if (wdev->u.ibss.current_bss) {
cfg80211_unhold_bss(wdev->u.ibss.current_bss); cfg80211_unhold_bss(wdev->u.ibss.current_bss);

View File

@ -1545,7 +1545,6 @@ static int nl80211_key_allowed(struct wireless_dev *wdev)
return -ENOLINK; return -ENOLINK;
case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_P2P_CLIENT:
/* for MLO, require driver validation of the link ID */
if (wdev->connected) if (wdev->connected)
return 0; return 0;
return -ENOLINK; return -ENOLINK;
@ -4333,6 +4332,38 @@ static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info)
return rdev_set_noack_map(rdev, dev, noack_map); return rdev_set_noack_map(rdev, dev, noack_map);
} }
static int nl80211_validate_key_link_id(struct genl_info *info,
struct wireless_dev *wdev,
int link_id, bool pairwise)
{
if (pairwise) {
if (link_id != -1) {
GENL_SET_ERR_MSG(info,
"link ID not allowed for pairwise key");
return -EINVAL;
}
return 0;
}
if (wdev->valid_links) {
if (link_id == -1) {
GENL_SET_ERR_MSG(info,
"link ID must for MLO group key");
return -EINVAL;
}
if (!(wdev->valid_links & BIT(link_id))) {
GENL_SET_ERR_MSG(info, "invalid link ID for MLO group key");
return -EINVAL;
}
} else if (link_id != -1) {
GENL_SET_ERR_MSG(info, "link ID not allowed for non-MLO group key");
return -EINVAL;
}
return 0;
}
struct get_key_cookie { struct get_key_cookie {
struct sk_buff *msg; struct sk_buff *msg;
int error; int error;
@ -4394,13 +4425,15 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
void *hdr; void *hdr;
struct sk_buff *msg; struct sk_buff *msg;
bool bigtk_support = false; bool bigtk_support = false;
int link_id = nl80211_link_id_or_invalid(info->attrs);
struct wireless_dev *wdev = dev->ieee80211_ptr;
if (wiphy_ext_feature_isset(&rdev->wiphy, if (wiphy_ext_feature_isset(&rdev->wiphy,
NL80211_EXT_FEATURE_BEACON_PROTECTION)) NL80211_EXT_FEATURE_BEACON_PROTECTION))
bigtk_support = true; bigtk_support = true;
if ((dev->ieee80211_ptr->iftype == NL80211_IFTYPE_STATION || if ((wdev->iftype == NL80211_IFTYPE_STATION ||
dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_CLIENT) && wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) &&
wiphy_ext_feature_isset(&rdev->wiphy, wiphy_ext_feature_isset(&rdev->wiphy,
NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT)) NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT))
bigtk_support = true; bigtk_support = true;
@ -4452,8 +4485,12 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr)) nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr))
goto nla_put_failure; goto nla_put_failure;
err = rdev_get_key(rdev, dev, key_idx, pairwise, mac_addr, &cookie, err = nl80211_validate_key_link_id(info, wdev, link_id, pairwise);
get_key_callback); if (err)
goto free_msg;
err = rdev_get_key(rdev, dev, link_id, key_idx, pairwise, mac_addr,
&cookie, get_key_callback);
if (err) if (err)
goto free_msg; goto free_msg;
@ -4477,6 +4514,8 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
struct key_parse key; struct key_parse key;
int err; int err;
struct net_device *dev = info->user_ptr[1]; struct net_device *dev = info->user_ptr[1];
int link_id = nl80211_link_id_or_invalid(info->attrs);
struct wireless_dev *wdev = dev->ieee80211_ptr;
err = nl80211_parse_key(info, &key); err = nl80211_parse_key(info, &key);
if (err) if (err)
@ -4492,7 +4531,7 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
!(key.p.mode == NL80211_KEY_SET_TX)) !(key.p.mode == NL80211_KEY_SET_TX))
return -EINVAL; return -EINVAL;
wdev_lock(dev->ieee80211_ptr); wdev_lock(wdev);
if (key.def) { if (key.def) {
if (!rdev->ops->set_default_key) { if (!rdev->ops->set_default_key) {
@ -4500,18 +4539,22 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
goto out; goto out;
} }
err = nl80211_key_allowed(dev->ieee80211_ptr); err = nl80211_key_allowed(wdev);
if (err) if (err)
goto out; goto out;
err = rdev_set_default_key(rdev, dev, key.idx, err = nl80211_validate_key_link_id(info, wdev, link_id, false);
key.def_uni, key.def_multi); if (err)
goto out;
err = rdev_set_default_key(rdev, dev, link_id, key.idx,
key.def_uni, key.def_multi);
if (err) if (err)
goto out; goto out;
#ifdef CONFIG_CFG80211_WEXT #ifdef CONFIG_CFG80211_WEXT
dev->ieee80211_ptr->wext.default_key = key.idx; wdev->wext.default_key = key.idx;
#endif #endif
} else if (key.defmgmt) { } else if (key.defmgmt) {
if (key.def_uni || !key.def_multi) { if (key.def_uni || !key.def_multi) {
@ -4524,16 +4567,20 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
goto out; goto out;
} }
err = nl80211_key_allowed(dev->ieee80211_ptr); err = nl80211_key_allowed(wdev);
if (err) if (err)
goto out; goto out;
err = rdev_set_default_mgmt_key(rdev, dev, key.idx); err = nl80211_validate_key_link_id(info, wdev, link_id, false);
if (err)
goto out;
err = rdev_set_default_mgmt_key(rdev, dev, link_id, key.idx);
if (err) if (err)
goto out; goto out;
#ifdef CONFIG_CFG80211_WEXT #ifdef CONFIG_CFG80211_WEXT
dev->ieee80211_ptr->wext.default_mgmt_key = key.idx; wdev->wext.default_mgmt_key = key.idx;
#endif #endif
} else if (key.defbeacon) { } else if (key.defbeacon) {
if (key.def_uni || !key.def_multi) { if (key.def_uni || !key.def_multi) {
@ -4546,11 +4593,15 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
goto out; goto out;
} }
err = nl80211_key_allowed(dev->ieee80211_ptr); err = nl80211_key_allowed(wdev);
if (err) if (err)
goto out; goto out;
err = rdev_set_default_beacon_key(rdev, dev, key.idx); err = nl80211_validate_key_link_id(info, wdev, link_id, false);
if (err)
goto out;
err = rdev_set_default_beacon_key(rdev, dev, link_id, key.idx);
if (err) if (err)
goto out; goto out;
} else if (key.p.mode == NL80211_KEY_SET_TX && } else if (key.p.mode == NL80211_KEY_SET_TX &&
@ -4566,14 +4617,18 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
goto out; goto out;
} }
err = rdev_add_key(rdev, dev, key.idx, err = nl80211_validate_key_link_id(info, wdev, link_id, true);
if (err)
goto out;
err = rdev_add_key(rdev, dev, link_id, key.idx,
NL80211_KEYTYPE_PAIRWISE, NL80211_KEYTYPE_PAIRWISE,
mac_addr, &key.p); mac_addr, &key.p);
} else { } else {
err = -EINVAL; err = -EINVAL;
} }
out: out:
wdev_unlock(dev->ieee80211_ptr); wdev_unlock(wdev);
return err; return err;
} }
@ -4585,6 +4640,8 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
struct net_device *dev = info->user_ptr[1]; struct net_device *dev = info->user_ptr[1];
struct key_parse key; struct key_parse key;
const u8 *mac_addr = NULL; const u8 *mac_addr = NULL;
int link_id = nl80211_link_id_or_invalid(info->attrs);
struct wireless_dev *wdev = dev->ieee80211_ptr;
err = nl80211_parse_key(info, &key); err = nl80211_parse_key(info, &key);
if (err) if (err)
@ -4626,18 +4683,23 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
return -EINVAL; return -EINVAL;
} }
wdev_lock(dev->ieee80211_ptr); wdev_lock(wdev);
err = nl80211_key_allowed(dev->ieee80211_ptr); err = nl80211_key_allowed(wdev);
if (err) if (err)
GENL_SET_ERR_MSG(info, "key not allowed"); GENL_SET_ERR_MSG(info, "key not allowed");
if (!err)
err = nl80211_validate_key_link_id(info, wdev, link_id,
key.type == NL80211_KEYTYPE_PAIRWISE);
if (!err) { if (!err) {
err = rdev_add_key(rdev, dev, key.idx, err = rdev_add_key(rdev, dev, link_id, key.idx,
key.type == NL80211_KEYTYPE_PAIRWISE, key.type == NL80211_KEYTYPE_PAIRWISE,
mac_addr, &key.p); mac_addr, &key.p);
if (err) if (err)
GENL_SET_ERR_MSG(info, "key addition failed"); GENL_SET_ERR_MSG(info, "key addition failed");
} }
wdev_unlock(dev->ieee80211_ptr); wdev_unlock(wdev);
return err; return err;
} }
@ -4649,6 +4711,8 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
struct net_device *dev = info->user_ptr[1]; struct net_device *dev = info->user_ptr[1];
u8 *mac_addr = NULL; u8 *mac_addr = NULL;
struct key_parse key; struct key_parse key;
int link_id = nl80211_link_id_or_invalid(info->attrs);
struct wireless_dev *wdev = dev->ieee80211_ptr;
err = nl80211_parse_key(info, &key); err = nl80211_parse_key(info, &key);
if (err) if (err)
@ -4676,27 +4740,31 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
if (!rdev->ops->del_key) if (!rdev->ops->del_key)
return -EOPNOTSUPP; return -EOPNOTSUPP;
wdev_lock(dev->ieee80211_ptr); wdev_lock(wdev);
err = nl80211_key_allowed(dev->ieee80211_ptr); err = nl80211_key_allowed(wdev);
if (key.type == NL80211_KEYTYPE_GROUP && mac_addr && if (key.type == NL80211_KEYTYPE_GROUP && mac_addr &&
!(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
err = -ENOENT; err = -ENOENT;
if (!err) if (!err)
err = rdev_del_key(rdev, dev, key.idx, err = nl80211_validate_key_link_id(info, wdev, link_id,
key.type == NL80211_KEYTYPE_PAIRWISE);
if (!err)
err = rdev_del_key(rdev, dev, link_id, key.idx,
key.type == NL80211_KEYTYPE_PAIRWISE, key.type == NL80211_KEYTYPE_PAIRWISE,
mac_addr); mac_addr);
#ifdef CONFIG_CFG80211_WEXT #ifdef CONFIG_CFG80211_WEXT
if (!err) { if (!err) {
if (key.idx == dev->ieee80211_ptr->wext.default_key) if (key.idx == wdev->wext.default_key)
dev->ieee80211_ptr->wext.default_key = -1; wdev->wext.default_key = -1;
else if (key.idx == dev->ieee80211_ptr->wext.default_mgmt_key) else if (key.idx == wdev->wext.default_mgmt_key)
dev->ieee80211_ptr->wext.default_mgmt_key = -1; wdev->wext.default_mgmt_key = -1;
} }
#endif #endif
wdev_unlock(dev->ieee80211_ptr); wdev_unlock(wdev);
return err; return err;
} }

View File

@ -77,65 +77,69 @@ rdev_change_virtual_intf(struct cfg80211_registered_device *rdev,
} }
static inline int rdev_add_key(struct cfg80211_registered_device *rdev, static inline int rdev_add_key(struct cfg80211_registered_device *rdev,
struct net_device *netdev, u8 key_index, struct net_device *netdev, int link_id,
bool pairwise, const u8 *mac_addr, u8 key_index, bool pairwise, const u8 *mac_addr,
struct key_params *params) struct key_params *params)
{ {
int ret; int ret;
trace_rdev_add_key(&rdev->wiphy, netdev, key_index, pairwise, trace_rdev_add_key(&rdev->wiphy, netdev, link_id, key_index, pairwise,
mac_addr, params->mode); mac_addr, params->mode);
ret = rdev->ops->add_key(&rdev->wiphy, netdev, key_index, pairwise, ret = rdev->ops->add_key(&rdev->wiphy, netdev, link_id, key_index,
mac_addr, params); pairwise, mac_addr, params);
trace_rdev_return_int(&rdev->wiphy, ret); trace_rdev_return_int(&rdev->wiphy, ret);
return ret; return ret;
} }
static inline int static inline int
rdev_get_key(struct cfg80211_registered_device *rdev, struct net_device *netdev, rdev_get_key(struct cfg80211_registered_device *rdev, struct net_device *netdev,
u8 key_index, bool pairwise, const u8 *mac_addr, void *cookie, int link_id, u8 key_index, bool pairwise, const u8 *mac_addr,
void *cookie,
void (*callback)(void *cookie, struct key_params*)) void (*callback)(void *cookie, struct key_params*))
{ {
int ret; int ret;
trace_rdev_get_key(&rdev->wiphy, netdev, key_index, pairwise, mac_addr); trace_rdev_get_key(&rdev->wiphy, netdev, link_id, key_index, pairwise,
ret = rdev->ops->get_key(&rdev->wiphy, netdev, key_index, pairwise, mac_addr);
mac_addr, cookie, callback); ret = rdev->ops->get_key(&rdev->wiphy, netdev, link_id, key_index,
pairwise, mac_addr, cookie, callback);
trace_rdev_return_int(&rdev->wiphy, ret); trace_rdev_return_int(&rdev->wiphy, ret);
return ret; return ret;
} }
static inline int rdev_del_key(struct cfg80211_registered_device *rdev, static inline int rdev_del_key(struct cfg80211_registered_device *rdev,
struct net_device *netdev, u8 key_index, struct net_device *netdev, int link_id,
bool pairwise, const u8 *mac_addr) u8 key_index, bool pairwise, const u8 *mac_addr)
{ {
int ret; int ret;
trace_rdev_del_key(&rdev->wiphy, netdev, key_index, pairwise, mac_addr); trace_rdev_del_key(&rdev->wiphy, netdev, link_id, key_index, pairwise,
ret = rdev->ops->del_key(&rdev->wiphy, netdev, key_index, pairwise, mac_addr);
mac_addr); ret = rdev->ops->del_key(&rdev->wiphy, netdev, link_id, key_index,
pairwise, mac_addr);
trace_rdev_return_int(&rdev->wiphy, ret); trace_rdev_return_int(&rdev->wiphy, ret);
return ret; return ret;
} }
static inline int static inline int
rdev_set_default_key(struct cfg80211_registered_device *rdev, rdev_set_default_key(struct cfg80211_registered_device *rdev,
struct net_device *netdev, u8 key_index, bool unicast, struct net_device *netdev, int link_id, u8 key_index,
bool multicast) bool unicast, bool multicast)
{ {
int ret; int ret;
trace_rdev_set_default_key(&rdev->wiphy, netdev, key_index, trace_rdev_set_default_key(&rdev->wiphy, netdev, link_id, key_index,
unicast, multicast); unicast, multicast);
ret = rdev->ops->set_default_key(&rdev->wiphy, netdev, key_index, ret = rdev->ops->set_default_key(&rdev->wiphy, netdev, link_id,
unicast, multicast); key_index, unicast, multicast);
trace_rdev_return_int(&rdev->wiphy, ret); trace_rdev_return_int(&rdev->wiphy, ret);
return ret; return ret;
} }
static inline int static inline int
rdev_set_default_mgmt_key(struct cfg80211_registered_device *rdev, rdev_set_default_mgmt_key(struct cfg80211_registered_device *rdev,
struct net_device *netdev, u8 key_index) struct net_device *netdev, int link_id, u8 key_index)
{ {
int ret; int ret;
trace_rdev_set_default_mgmt_key(&rdev->wiphy, netdev, key_index); trace_rdev_set_default_mgmt_key(&rdev->wiphy, netdev, link_id,
ret = rdev->ops->set_default_mgmt_key(&rdev->wiphy, netdev, key_index);
ret = rdev->ops->set_default_mgmt_key(&rdev->wiphy, netdev, link_id,
key_index); key_index);
trace_rdev_return_int(&rdev->wiphy, ret); trace_rdev_return_int(&rdev->wiphy, ret);
return ret; return ret;
@ -143,13 +147,15 @@ rdev_set_default_mgmt_key(struct cfg80211_registered_device *rdev,
static inline int static inline int
rdev_set_default_beacon_key(struct cfg80211_registered_device *rdev, rdev_set_default_beacon_key(struct cfg80211_registered_device *rdev,
struct net_device *netdev, u8 key_index) struct net_device *netdev, int link_id,
u8 key_index)
{ {
int ret; int ret;
trace_rdev_set_default_beacon_key(&rdev->wiphy, netdev, key_index); trace_rdev_set_default_beacon_key(&rdev->wiphy, netdev, link_id,
ret = rdev->ops->set_default_beacon_key(&rdev->wiphy, netdev, key_index);
key_index); ret = rdev->ops->set_default_beacon_key(&rdev->wiphy, netdev, link_id,
key_index);
trace_rdev_return_int(&rdev->wiphy, ret); trace_rdev_return_int(&rdev->wiphy, ret);
return ret; return ret;
} }

View File

@ -1326,7 +1326,7 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT)) NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT))
max_key_idx = 7; max_key_idx = 7;
for (i = 0; i <= max_key_idx; i++) for (i = 0; i <= max_key_idx; i++)
rdev_del_key(rdev, dev, i, false, NULL); rdev_del_key(rdev, dev, -1, i, false, NULL);
} }
rdev_set_qos_map(rdev, dev, NULL); rdev_set_qos_map(rdev, dev, NULL);

View File

@ -434,13 +434,14 @@ TRACE_EVENT(rdev_change_virtual_intf,
); );
DECLARE_EVENT_CLASS(key_handle, DECLARE_EVENT_CLASS(key_handle,
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int link_id,
bool pairwise, const u8 *mac_addr), u8 key_index, bool pairwise, const u8 *mac_addr),
TP_ARGS(wiphy, netdev, key_index, pairwise, mac_addr), TP_ARGS(wiphy, netdev, link_id, key_index, pairwise, mac_addr),
TP_STRUCT__entry( TP_STRUCT__entry(
WIPHY_ENTRY WIPHY_ENTRY
NETDEV_ENTRY NETDEV_ENTRY
MAC_ENTRY(mac_addr) MAC_ENTRY(mac_addr)
__field(int, link_id)
__field(u8, key_index) __field(u8, key_index)
__field(bool, pairwise) __field(bool, pairwise)
), ),
@ -448,34 +449,38 @@ DECLARE_EVENT_CLASS(key_handle,
WIPHY_ASSIGN; WIPHY_ASSIGN;
NETDEV_ASSIGN; NETDEV_ASSIGN;
MAC_ASSIGN(mac_addr, mac_addr); MAC_ASSIGN(mac_addr, mac_addr);
__entry->link_id = link_id;
__entry->key_index = key_index; __entry->key_index = key_index;
__entry->pairwise = pairwise; __entry->pairwise = pairwise;
), ),
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", key_index: %u, pairwise: %s, mac addr: " MAC_PR_FMT, TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", link_id: %d, "
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index, "key_index: %u, pairwise: %s, mac addr: " MAC_PR_FMT,
BOOL_TO_STR(__entry->pairwise), MAC_PR_ARG(mac_addr)) WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->link_id,
__entry->key_index, BOOL_TO_STR(__entry->pairwise),
MAC_PR_ARG(mac_addr))
); );
DEFINE_EVENT(key_handle, rdev_get_key, DEFINE_EVENT(key_handle, rdev_get_key,
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int link_id,
bool pairwise, const u8 *mac_addr), u8 key_index, bool pairwise, const u8 *mac_addr),
TP_ARGS(wiphy, netdev, key_index, pairwise, mac_addr) TP_ARGS(wiphy, netdev, link_id, key_index, pairwise, mac_addr)
); );
DEFINE_EVENT(key_handle, rdev_del_key, DEFINE_EVENT(key_handle, rdev_del_key,
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int link_id,
bool pairwise, const u8 *mac_addr), u8 key_index, bool pairwise, const u8 *mac_addr),
TP_ARGS(wiphy, netdev, key_index, pairwise, mac_addr) TP_ARGS(wiphy, netdev, link_id, key_index, pairwise, mac_addr)
); );
TRACE_EVENT(rdev_add_key, TRACE_EVENT(rdev_add_key,
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int link_id,
bool pairwise, const u8 *mac_addr, u8 mode), u8 key_index, bool pairwise, const u8 *mac_addr, u8 mode),
TP_ARGS(wiphy, netdev, key_index, pairwise, mac_addr, mode), TP_ARGS(wiphy, netdev, link_id, key_index, pairwise, mac_addr, mode),
TP_STRUCT__entry( TP_STRUCT__entry(
WIPHY_ENTRY WIPHY_ENTRY
NETDEV_ENTRY NETDEV_ENTRY
MAC_ENTRY(mac_addr) MAC_ENTRY(mac_addr)
__field(int, link_id)
__field(u8, key_index) __field(u8, key_index)
__field(bool, pairwise) __field(bool, pairwise)
__field(u8, mode) __field(u8, mode)
@ -484,24 +489,27 @@ TRACE_EVENT(rdev_add_key,
WIPHY_ASSIGN; WIPHY_ASSIGN;
NETDEV_ASSIGN; NETDEV_ASSIGN;
MAC_ASSIGN(mac_addr, mac_addr); MAC_ASSIGN(mac_addr, mac_addr);
__entry->link_id = link_id;
__entry->key_index = key_index; __entry->key_index = key_index;
__entry->pairwise = pairwise; __entry->pairwise = pairwise;
__entry->mode = mode; __entry->mode = mode;
), ),
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", key_index: %u, " TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", link_id: %d, "
"mode: %u, pairwise: %s, mac addr: " MAC_PR_FMT, "key_index: %u, mode: %u, pairwise: %s, "
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index, "mac addr: " MAC_PR_FMT,
__entry->mode, BOOL_TO_STR(__entry->pairwise), WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->link_id,
MAC_PR_ARG(mac_addr)) __entry->key_index, __entry->mode,
BOOL_TO_STR(__entry->pairwise), MAC_PR_ARG(mac_addr))
); );
TRACE_EVENT(rdev_set_default_key, TRACE_EVENT(rdev_set_default_key,
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int link_id,
bool unicast, bool multicast), u8 key_index, bool unicast, bool multicast),
TP_ARGS(wiphy, netdev, key_index, unicast, multicast), TP_ARGS(wiphy, netdev, link_id, key_index, unicast, multicast),
TP_STRUCT__entry( TP_STRUCT__entry(
WIPHY_ENTRY WIPHY_ENTRY
NETDEV_ENTRY NETDEV_ENTRY
__field(int, link_id)
__field(u8, key_index) __field(u8, key_index)
__field(bool, unicast) __field(bool, unicast)
__field(bool, multicast) __field(bool, multicast)
@ -509,48 +517,58 @@ TRACE_EVENT(rdev_set_default_key,
TP_fast_assign( TP_fast_assign(
WIPHY_ASSIGN; WIPHY_ASSIGN;
NETDEV_ASSIGN; NETDEV_ASSIGN;
__entry->link_id = link_id;
__entry->key_index = key_index; __entry->key_index = key_index;
__entry->unicast = unicast; __entry->unicast = unicast;
__entry->multicast = multicast; __entry->multicast = multicast;
), ),
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", key index: %u, unicast: %s, multicast: %s", TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", link_id: %d, "
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index, "key index: %u, unicast: %s, multicast: %s",
BOOL_TO_STR(__entry->unicast), WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->link_id,
__entry->key_index, BOOL_TO_STR(__entry->unicast),
BOOL_TO_STR(__entry->multicast)) BOOL_TO_STR(__entry->multicast))
); );
TRACE_EVENT(rdev_set_default_mgmt_key, TRACE_EVENT(rdev_set_default_mgmt_key,
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 key_index), TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int link_id,
TP_ARGS(wiphy, netdev, key_index), u8 key_index),
TP_ARGS(wiphy, netdev, link_id, key_index),
TP_STRUCT__entry( TP_STRUCT__entry(
WIPHY_ENTRY WIPHY_ENTRY
NETDEV_ENTRY NETDEV_ENTRY
__field(int, link_id)
__field(u8, key_index) __field(u8, key_index)
), ),
TP_fast_assign( TP_fast_assign(
WIPHY_ASSIGN; WIPHY_ASSIGN;
NETDEV_ASSIGN; NETDEV_ASSIGN;
__entry->link_id = link_id;
__entry->key_index = key_index; __entry->key_index = key_index;
), ),
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", key index: %u", TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", link_id: %d, "
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index) "key index: %u", WIPHY_PR_ARG, NETDEV_PR_ARG,
__entry->link_id, __entry->key_index)
); );
TRACE_EVENT(rdev_set_default_beacon_key, TRACE_EVENT(rdev_set_default_beacon_key,
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 key_index), TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int link_id,
TP_ARGS(wiphy, netdev, key_index), u8 key_index),
TP_ARGS(wiphy, netdev, link_id, key_index),
TP_STRUCT__entry( TP_STRUCT__entry(
WIPHY_ENTRY WIPHY_ENTRY
NETDEV_ENTRY NETDEV_ENTRY
__field(int, link_id)
__field(u8, key_index) __field(u8, key_index)
), ),
TP_fast_assign( TP_fast_assign(
WIPHY_ASSIGN; WIPHY_ASSIGN;
NETDEV_ASSIGN; NETDEV_ASSIGN;
__entry->link_id = link_id;
__entry->key_index = key_index; __entry->key_index = key_index;
), ),
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", key index: %u", TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", link_id: %d, "
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index) "key index: %u", WIPHY_PR_ARG, NETDEV_PR_ARG,
__entry->link_id, __entry->key_index)
); );
TRACE_EVENT(rdev_start_ap, TRACE_EVENT(rdev_start_ap,

View File

@ -935,13 +935,13 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev)
for (i = 0; i < CFG80211_MAX_WEP_KEYS; i++) { for (i = 0; i < CFG80211_MAX_WEP_KEYS; i++) {
if (!wdev->connect_keys->params[i].cipher) if (!wdev->connect_keys->params[i].cipher)
continue; continue;
if (rdev_add_key(rdev, dev, i, false, NULL, if (rdev_add_key(rdev, dev, -1, i, false, NULL,
&wdev->connect_keys->params[i])) { &wdev->connect_keys->params[i])) {
netdev_err(dev, "failed to set key %d\n", i); netdev_err(dev, "failed to set key %d\n", i);
continue; continue;
} }
if (wdev->connect_keys->def == i && if (wdev->connect_keys->def == i &&
rdev_set_default_key(rdev, dev, i, true, true)) { rdev_set_default_key(rdev, dev, -1, i, true, true)) {
netdev_err(dev, "failed to set defkey %d\n", i); netdev_err(dev, "failed to set defkey %d\n", i);
continue; continue;
} }

View File

@ -470,7 +470,7 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
!(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
err = -ENOENT; err = -ENOENT;
else else
err = rdev_del_key(rdev, dev, idx, pairwise, err = rdev_del_key(rdev, dev, -1, idx, pairwise,
addr); addr);
} }
wdev->wext.connect.privacy = false; wdev->wext.connect.privacy = false;
@ -509,7 +509,7 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
if (wdev->connected || if (wdev->connected ||
(wdev->iftype == NL80211_IFTYPE_ADHOC && (wdev->iftype == NL80211_IFTYPE_ADHOC &&
wdev->u.ibss.current_bss)) wdev->u.ibss.current_bss))
err = rdev_add_key(rdev, dev, idx, pairwise, addr, params); err = rdev_add_key(rdev, dev, -1, idx, pairwise, addr, params);
else if (params->cipher != WLAN_CIPHER_SUITE_WEP40 && else if (params->cipher != WLAN_CIPHER_SUITE_WEP40 &&
params->cipher != WLAN_CIPHER_SUITE_WEP104) params->cipher != WLAN_CIPHER_SUITE_WEP104)
return -EINVAL; return -EINVAL;
@ -546,7 +546,8 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
__cfg80211_leave_ibss(rdev, wdev->netdev, true); __cfg80211_leave_ibss(rdev, wdev->netdev, true);
rejoin = true; rejoin = true;
} }
err = rdev_set_default_key(rdev, dev, idx, true, true); err = rdev_set_default_key(rdev, dev, -1, idx, true,
true);
} }
if (!err) { if (!err) {
wdev->wext.default_key = idx; wdev->wext.default_key = idx;
@ -561,7 +562,7 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
if (wdev->connected || if (wdev->connected ||
(wdev->iftype == NL80211_IFTYPE_ADHOC && (wdev->iftype == NL80211_IFTYPE_ADHOC &&
wdev->u.ibss.current_bss)) wdev->u.ibss.current_bss))
err = rdev_set_default_mgmt_key(rdev, dev, idx); err = rdev_set_default_mgmt_key(rdev, dev, -1, idx);
if (!err) if (!err)
wdev->wext.default_mgmt_key = idx; wdev->wext.default_mgmt_key = idx;
return err; return err;
@ -632,7 +633,7 @@ static int cfg80211_wext_siwencode(struct net_device *dev,
if (wdev->connected || if (wdev->connected ||
(wdev->iftype == NL80211_IFTYPE_ADHOC && (wdev->iftype == NL80211_IFTYPE_ADHOC &&
wdev->u.ibss.current_bss)) wdev->u.ibss.current_bss))
err = rdev_set_default_key(rdev, dev, idx, true, err = rdev_set_default_key(rdev, dev, -1, idx, true,
true); true);
if (!err) if (!err)
wdev->wext.default_key = idx; wdev->wext.default_key = idx;