diff options
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r-- | net/mac80211/cfg.c | 79 |
1 files changed, 65 insertions, 14 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index c981604b71e6..ecf9b7166ed1 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -68,14 +68,42 @@ static int ieee80211_change_iface(struct wiphy *wiphy, | |||
68 | params && params->use_4addr >= 0) | 68 | params && params->use_4addr >= 0) |
69 | sdata->u.mgd.use_4addr = params->use_4addr; | 69 | sdata->u.mgd.use_4addr = params->use_4addr; |
70 | 70 | ||
71 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) | 71 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) { |
72 | sdata->u.mntr_flags = *flags; | 72 | struct ieee80211_local *local = sdata->local; |
73 | |||
74 | if (ieee80211_sdata_running(sdata)) { | ||
75 | /* | ||
76 | * Prohibit MONITOR_FLAG_COOK_FRAMES to be | ||
77 | * changed while the interface is up. | ||
78 | * Else we would need to add a lot of cruft | ||
79 | * to update everything: | ||
80 | * cooked_mntrs, monitor and all fif_* counters | ||
81 | * reconfigure hardware | ||
82 | */ | ||
83 | if ((*flags & MONITOR_FLAG_COOK_FRAMES) != | ||
84 | (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES)) | ||
85 | return -EBUSY; | ||
86 | |||
87 | ieee80211_adjust_monitor_flags(sdata, -1); | ||
88 | sdata->u.mntr_flags = *flags; | ||
89 | ieee80211_adjust_monitor_flags(sdata, 1); | ||
90 | |||
91 | ieee80211_configure_filter(local); | ||
92 | } else { | ||
93 | /* | ||
94 | * Because the interface is down, ieee80211_do_stop | ||
95 | * and ieee80211_do_open take care of "everything" | ||
96 | * mentioned in the comment above. | ||
97 | */ | ||
98 | sdata->u.mntr_flags = *flags; | ||
99 | } | ||
100 | } | ||
73 | 101 | ||
74 | return 0; | 102 | return 0; |
75 | } | 103 | } |
76 | 104 | ||
77 | static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, | 105 | static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, |
78 | u8 key_idx, const u8 *mac_addr, | 106 | u8 key_idx, bool pairwise, const u8 *mac_addr, |
79 | struct key_params *params) | 107 | struct key_params *params) |
80 | { | 108 | { |
81 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 109 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
@@ -103,6 +131,9 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, | |||
103 | if (IS_ERR(key)) | 131 | if (IS_ERR(key)) |
104 | return PTR_ERR(key); | 132 | return PTR_ERR(key); |
105 | 133 | ||
134 | if (pairwise) | ||
135 | key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE; | ||
136 | |||
106 | mutex_lock(&sdata->local->sta_mtx); | 137 | mutex_lock(&sdata->local->sta_mtx); |
107 | 138 | ||
108 | if (mac_addr) { | 139 | if (mac_addr) { |
@@ -125,7 +156,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, | |||
125 | } | 156 | } |
126 | 157 | ||
127 | static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, | 158 | static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, |
128 | u8 key_idx, const u8 *mac_addr) | 159 | u8 key_idx, bool pairwise, const u8 *mac_addr) |
129 | { | 160 | { |
130 | struct ieee80211_sub_if_data *sdata; | 161 | struct ieee80211_sub_if_data *sdata; |
131 | struct sta_info *sta; | 162 | struct sta_info *sta; |
@@ -142,10 +173,17 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, | |||
142 | if (!sta) | 173 | if (!sta) |
143 | goto out_unlock; | 174 | goto out_unlock; |
144 | 175 | ||
145 | if (sta->key) { | 176 | if (pairwise) { |
146 | ieee80211_key_free(sdata->local, sta->key); | 177 | if (sta->ptk) { |
147 | WARN_ON(sta->key); | 178 | ieee80211_key_free(sdata->local, sta->ptk); |
148 | ret = 0; | 179 | ret = 0; |
180 | } | ||
181 | } else { | ||
182 | if (sta->gtk[key_idx]) { | ||
183 | ieee80211_key_free(sdata->local, | ||
184 | sta->gtk[key_idx]); | ||
185 | ret = 0; | ||
186 | } | ||
149 | } | 187 | } |
150 | 188 | ||
151 | goto out_unlock; | 189 | goto out_unlock; |
@@ -167,7 +205,8 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, | |||
167 | } | 205 | } |
168 | 206 | ||
169 | static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, | 207 | static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, |
170 | u8 key_idx, const u8 *mac_addr, void *cookie, | 208 | u8 key_idx, bool pairwise, const u8 *mac_addr, |
209 | void *cookie, | ||
171 | void (*callback)(void *cookie, | 210 | void (*callback)(void *cookie, |
172 | struct key_params *params)) | 211 | struct key_params *params)) |
173 | { | 212 | { |
@@ -175,7 +214,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, | |||
175 | struct sta_info *sta = NULL; | 214 | struct sta_info *sta = NULL; |
176 | u8 seq[6] = {0}; | 215 | u8 seq[6] = {0}; |
177 | struct key_params params; | 216 | struct key_params params; |
178 | struct ieee80211_key *key; | 217 | struct ieee80211_key *key = NULL; |
179 | u32 iv32; | 218 | u32 iv32; |
180 | u16 iv16; | 219 | u16 iv16; |
181 | int err = -ENOENT; | 220 | int err = -ENOENT; |
@@ -189,7 +228,10 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, | |||
189 | if (!sta) | 228 | if (!sta) |
190 | goto out; | 229 | goto out; |
191 | 230 | ||
192 | key = sta->key; | 231 | if (pairwise) |
232 | key = sta->ptk; | ||
233 | else if (key_idx < NUM_DEFAULT_KEYS) | ||
234 | key = sta->gtk[key_idx]; | ||
193 | } else | 235 | } else |
194 | key = sdata->keys[key_idx]; | 236 | key = sdata->keys[key_idx]; |
195 | 237 | ||
@@ -285,6 +327,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
285 | STATION_INFO_TX_BYTES | | 327 | STATION_INFO_TX_BYTES | |
286 | STATION_INFO_RX_PACKETS | | 328 | STATION_INFO_RX_PACKETS | |
287 | STATION_INFO_TX_PACKETS | | 329 | STATION_INFO_TX_PACKETS | |
330 | STATION_INFO_TX_RETRIES | | ||
331 | STATION_INFO_TX_FAILED | | ||
288 | STATION_INFO_TX_BITRATE; | 332 | STATION_INFO_TX_BITRATE; |
289 | 333 | ||
290 | sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); | 334 | sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); |
@@ -292,6 +336,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
292 | sinfo->tx_bytes = sta->tx_bytes; | 336 | sinfo->tx_bytes = sta->tx_bytes; |
293 | sinfo->rx_packets = sta->rx_packets; | 337 | sinfo->rx_packets = sta->rx_packets; |
294 | sinfo->tx_packets = sta->tx_packets; | 338 | sinfo->tx_packets = sta->tx_packets; |
339 | sinfo->tx_retries = sta->tx_retry_count; | ||
340 | sinfo->tx_failed = sta->tx_retry_failed; | ||
295 | 341 | ||
296 | if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || | 342 | if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || |
297 | (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { | 343 | (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { |
@@ -1317,7 +1363,7 @@ static int ieee80211_get_tx_power(struct wiphy *wiphy, int *dbm) | |||
1317 | } | 1363 | } |
1318 | 1364 | ||
1319 | static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev, | 1365 | static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev, |
1320 | u8 *addr) | 1366 | const u8 *addr) |
1321 | { | 1367 | { |
1322 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1368 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1323 | 1369 | ||
@@ -1366,7 +1412,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata, | |||
1366 | if (!sdata->u.mgd.associated || | 1412 | if (!sdata->u.mgd.associated || |
1367 | sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) { | 1413 | sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) { |
1368 | mutex_lock(&sdata->local->iflist_mtx); | 1414 | mutex_lock(&sdata->local->iflist_mtx); |
1369 | ieee80211_recalc_smps(sdata->local, sdata); | 1415 | ieee80211_recalc_smps(sdata->local); |
1370 | mutex_unlock(&sdata->local->iflist_mtx); | 1416 | mutex_unlock(&sdata->local->iflist_mtx); |
1371 | return 0; | 1417 | return 0; |
1372 | } | 1418 | } |
@@ -1521,7 +1567,11 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, | |||
1521 | 1567 | ||
1522 | switch (sdata->vif.type) { | 1568 | switch (sdata->vif.type) { |
1523 | case NL80211_IFTYPE_ADHOC: | 1569 | case NL80211_IFTYPE_ADHOC: |
1524 | if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) | 1570 | case NL80211_IFTYPE_AP: |
1571 | case NL80211_IFTYPE_AP_VLAN: | ||
1572 | case NL80211_IFTYPE_P2P_GO: | ||
1573 | if (!ieee80211_is_action(mgmt->frame_control) || | ||
1574 | mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) | ||
1525 | break; | 1575 | break; |
1526 | rcu_read_lock(); | 1576 | rcu_read_lock(); |
1527 | sta = sta_info_get(sdata, mgmt->da); | 1577 | sta = sta_info_get(sdata, mgmt->da); |
@@ -1530,6 +1580,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, | |||
1530 | return -ENOLINK; | 1580 | return -ENOLINK; |
1531 | break; | 1581 | break; |
1532 | case NL80211_IFTYPE_STATION: | 1582 | case NL80211_IFTYPE_STATION: |
1583 | case NL80211_IFTYPE_P2P_CLIENT: | ||
1533 | break; | 1584 | break; |
1534 | default: | 1585 | default: |
1535 | return -EOPNOTSUPP; | 1586 | return -EOPNOTSUPP; |