Skip to content

Commit

Permalink
mac80211: support adding/removing keys via cfg80211
Browse files Browse the repository at this point in the history
This adds the necessary hooks to mac80211 to allow userspace
to edit keys with cfg80211 (through nl80211.)

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Johannes Berg authored and David S. Miller committed Jan 28, 2008
1 parent 41ade00 commit e8cbb4c
Showing 1 changed file with 91 additions and 0 deletions.
91 changes: 91 additions & 0 deletions net/mac80211/cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* This file is GPLv2 as found in COPYING.
*/

#include <linux/ieee80211.h>
#include <linux/nl80211.h>
#include <linux/rtnetlink.h>
#include <net/net_namespace.h>
Expand Down Expand Up @@ -99,8 +100,98 @@ static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
return 0;
}

static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
u8 key_idx, u8 *mac_addr,
struct key_params *params)
{
struct ieee80211_sub_if_data *sdata;
struct sta_info *sta = NULL;
enum ieee80211_key_alg alg;
int ret;

sdata = IEEE80211_DEV_TO_SUB_IF(dev);

switch (params->cipher) {
case WLAN_CIPHER_SUITE_WEP40:
case WLAN_CIPHER_SUITE_WEP104:
alg = ALG_WEP;
break;
case WLAN_CIPHER_SUITE_TKIP:
alg = ALG_TKIP;
break;
case WLAN_CIPHER_SUITE_CCMP:
alg = ALG_CCMP;
break;
default:
return -EINVAL;
}

if (mac_addr) {
sta = sta_info_get(sdata->local, mac_addr);
if (!sta)
return -ENOENT;
}

ret = 0;
if (!ieee80211_key_alloc(sdata, sta, alg, key_idx,
params->key_len, params->key))
ret = -ENOMEM;

if (sta)
sta_info_put(sta);

return ret;
}

static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
u8 key_idx, u8 *mac_addr)
{
struct ieee80211_sub_if_data *sdata;
struct sta_info *sta;
int ret;

sdata = IEEE80211_DEV_TO_SUB_IF(dev);

if (mac_addr) {
sta = sta_info_get(sdata->local, mac_addr);
if (!sta)
return -ENOENT;

ret = 0;
if (sta->key)
ieee80211_key_free(sta->key);
else
ret = -ENOENT;

sta_info_put(sta);
return ret;
}

if (!sdata->keys[key_idx])
return -ENOENT;

ieee80211_key_free(sdata->keys[key_idx]);

return 0;
}

static int ieee80211_config_default_key(struct wiphy *wiphy,
struct net_device *dev,
u8 key_idx)
{
struct ieee80211_sub_if_data *sdata;

sdata = IEEE80211_DEV_TO_SUB_IF(dev);
ieee80211_set_default_key(sdata, key_idx);

return 0;
}

struct cfg80211_ops mac80211_config_ops = {
.add_virtual_intf = ieee80211_add_iface,
.del_virtual_intf = ieee80211_del_iface,
.change_virtual_intf = ieee80211_change_iface,
.add_key = ieee80211_add_key,
.del_key = ieee80211_del_key,
.set_default_key = ieee80211_config_default_key,
};

0 comments on commit e8cbb4c

Please sign in to comment.