aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2007-12-18 20:03:30 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 17:59:49 -0500
commite8cbb4cbeb7642d179b01c35adf036ddb65f3dd0 (patch)
tree8eefc93ad8262d4b487e752c7db5dea2e2780a08
parent41ade00f21a72d30911c6351a93823a491fffa39 (diff)
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> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/mac80211/cfg.c91
1 files changed, 91 insertions, 0 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 9e2bc1fd0237..d49f7b58b05c 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -6,6 +6,7 @@
6 * This file is GPLv2 as found in COPYING. 6 * This file is GPLv2 as found in COPYING.
7 */ 7 */
8 8
9#include <linux/ieee80211.h>
9#include <linux/nl80211.h> 10#include <linux/nl80211.h>
10#include <linux/rtnetlink.h> 11#include <linux/rtnetlink.h>
11#include <net/net_namespace.h> 12#include <net/net_namespace.h>
@@ -99,8 +100,98 @@ static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
99 return 0; 100 return 0;
100} 101}
101 102
103static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
104 u8 key_idx, u8 *mac_addr,
105 struct key_params *params)
106{
107 struct ieee80211_sub_if_data *sdata;
108 struct sta_info *sta = NULL;
109 enum ieee80211_key_alg alg;
110 int ret;
111
112 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
113
114 switch (params->cipher) {
115 case WLAN_CIPHER_SUITE_WEP40:
116 case WLAN_CIPHER_SUITE_WEP104:
117 alg = ALG_WEP;
118 break;
119 case WLAN_CIPHER_SUITE_TKIP:
120 alg = ALG_TKIP;
121 break;
122 case WLAN_CIPHER_SUITE_CCMP:
123 alg = ALG_CCMP;
124 break;
125 default:
126 return -EINVAL;
127 }
128
129 if (mac_addr) {
130 sta = sta_info_get(sdata->local, mac_addr);
131 if (!sta)
132 return -ENOENT;
133 }
134
135 ret = 0;
136 if (!ieee80211_key_alloc(sdata, sta, alg, key_idx,
137 params->key_len, params->key))
138 ret = -ENOMEM;
139
140 if (sta)
141 sta_info_put(sta);
142
143 return ret;
144}
145
146static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
147 u8 key_idx, u8 *mac_addr)
148{
149 struct ieee80211_sub_if_data *sdata;
150 struct sta_info *sta;
151 int ret;
152
153 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
154
155 if (mac_addr) {
156 sta = sta_info_get(sdata->local, mac_addr);
157 if (!sta)
158 return -ENOENT;
159
160 ret = 0;
161 if (sta->key)
162 ieee80211_key_free(sta->key);
163 else
164 ret = -ENOENT;
165
166 sta_info_put(sta);
167 return ret;
168 }
169
170 if (!sdata->keys[key_idx])
171 return -ENOENT;
172
173 ieee80211_key_free(sdata->keys[key_idx]);
174
175 return 0;
176}
177
178static int ieee80211_config_default_key(struct wiphy *wiphy,
179 struct net_device *dev,
180 u8 key_idx)
181{
182 struct ieee80211_sub_if_data *sdata;
183
184 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
185 ieee80211_set_default_key(sdata, key_idx);
186
187 return 0;
188}
189
102struct cfg80211_ops mac80211_config_ops = { 190struct cfg80211_ops mac80211_config_ops = {
103 .add_virtual_intf = ieee80211_add_iface, 191 .add_virtual_intf = ieee80211_add_iface,
104 .del_virtual_intf = ieee80211_del_iface, 192 .del_virtual_intf = ieee80211_del_iface,
105 .change_virtual_intf = ieee80211_change_iface, 193 .change_virtual_intf = ieee80211_change_iface,
194 .add_key = ieee80211_add_key,
195 .del_key = ieee80211_del_key,
196 .set_default_key = ieee80211_config_default_key,
106}; 197};