121 lines
2.7 KiB
Diff
121 lines
2.7 KiB
Diff
|
Subject: mac80211: support adding/removing keys via cfg80211
|
||
|
|
||
|
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>
|
||
|
|
||
|
---
|
||
|
net/mac80211/cfg.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
1 file changed, 91 insertions(+)
|
||
|
|
||
|
--- everything.orig/net/mac80211/cfg.c 2007-11-07 13:19:29.441515732 +0100
|
||
|
+++ everything/net/mac80211/cfg.c 2007-11-07 13:19:39.531517685 +0100
|
||
|
@@ -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>
|
||
|
@@ -105,8 +106,98 @@ static int ieee80211_change_iface(struct
|
||
|
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,
|
||
|
};
|