diff options
author | Daniel Drake <dsd@gentoo.org> | 2007-07-10 13:32:11 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2007-07-12 16:07:26 -0400 |
commit | 63fc33ceb0ccc08b3f62d7bfe56a33eb33ca9427 (patch) | |
tree | 6fb60af08616b2f4065cdd74b83f43c819f1853c /net/mac80211 | |
parent | 5628221caf88e2a052782b042e12da7cd34111b0 (diff) |
[PATCH] mac80211: improved 802.11g CTS protection
Currently, CTS protection is partially implemented twice:
1. via prism2 ioctls, only used by hostapd
2. via STA beacon parsing, recorded in sta.use_protection but never used
(other than printed in debugfs)
Protection control should be implemented on a per-subif basis. For example,
a single physical device may be running a soft AP on one channel, and a STA
on another. The AP interface should use protection based on what hostapd told
it, and the STA interface should use protection based on beacon parsing.
These should operate independantly: one subif using protection should not
influence the other.
To implement this, I moved the use_protection flag into ieee80211_sub_if_data
and removed the device-global cts_protect_erp_frames flag.
I also made the PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES write operation only
available for AP interfaces, to avoid any possibility of the user messing with
the behaviour of a STA.
Signed-off-by: Daniel Drake <dsd@gentoo.org>
Signed-off-by: Jiri Benc <jbenc@suse.cz>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/debugfs_netdev.c | 2 | ||||
-rw-r--r-- | net/mac80211/ieee80211.c | 5 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 3 | ||||
-rw-r--r-- | net/mac80211/ieee80211_ioctl.c | 7 | ||||
-rw-r--r-- | net/mac80211/ieee80211_sta.c | 8 |
5 files changed, 13 insertions, 12 deletions
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 9e3964638bad..a3e01d76d503 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c | |||
@@ -118,7 +118,7 @@ static ssize_t ieee80211_if_fmt_flags( | |||
118 | sdata->u.sta.authenticated ? "AUTH\n" : "", | 118 | sdata->u.sta.authenticated ? "AUTH\n" : "", |
119 | sdata->u.sta.associated ? "ASSOC\n" : "", | 119 | sdata->u.sta.associated ? "ASSOC\n" : "", |
120 | sdata->u.sta.probereq_poll ? "PROBEREQ POLL\n" : "", | 120 | sdata->u.sta.probereq_poll ? "PROBEREQ POLL\n" : "", |
121 | sdata->u.sta.use_protection ? "CTS prot\n" : ""); | 121 | sdata->use_protection ? "CTS prot\n" : ""); |
122 | } | 122 | } |
123 | __IEEE80211_IF_FILE(flags); | 123 | __IEEE80211_IF_FILE(flags); |
124 | 124 | ||
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index fe32a2d16053..2ddf4ef4065e 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c | |||
@@ -442,7 +442,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_txrx_data *tx) | |||
442 | if (!tx->u.tx.rate) | 442 | if (!tx->u.tx.rate) |
443 | return TXRX_DROP; | 443 | return TXRX_DROP; |
444 | if (tx->u.tx.mode->mode == MODE_IEEE80211G && | 444 | if (tx->u.tx.mode->mode == MODE_IEEE80211G && |
445 | tx->local->cts_protect_erp_frames && tx->fragmented && | 445 | tx->sdata->use_protection && tx->fragmented && |
446 | extra.nonerp) { | 446 | extra.nonerp) { |
447 | tx->u.tx.last_frag_rate = tx->u.tx.rate; | 447 | tx->u.tx.last_frag_rate = tx->u.tx.rate; |
448 | tx->u.tx.probe_last_frag = extra.probe ? 1 : 0; | 448 | tx->u.tx.probe_last_frag = extra.probe ? 1 : 0; |
@@ -868,8 +868,7 @@ ieee80211_tx_h_misc(struct ieee80211_txrx_data *tx) | |||
868 | * for the frame. */ | 868 | * for the frame. */ |
869 | if (mode->mode == MODE_IEEE80211G && | 869 | if (mode->mode == MODE_IEEE80211G && |
870 | (tx->u.tx.rate->flags & IEEE80211_RATE_ERP) && | 870 | (tx->u.tx.rate->flags & IEEE80211_RATE_ERP) && |
871 | tx->u.tx.unicast && | 871 | tx->u.tx.unicast && tx->sdata->use_protection && |
872 | tx->local->cts_protect_erp_frames && | ||
873 | !(control->flags & IEEE80211_TXCTL_USE_RTS_CTS)) | 872 | !(control->flags & IEEE80211_TXCTL_USE_RTS_CTS)) |
874 | control->flags |= IEEE80211_TXCTL_USE_CTS_PROTECT; | 873 | control->flags |= IEEE80211_TXCTL_USE_CTS_PROTECT; |
875 | 874 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 99ff7c5e9204..055a2a912185 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -241,7 +241,6 @@ struct ieee80211_if_sta { | |||
241 | unsigned int authenticated:1; | 241 | unsigned int authenticated:1; |
242 | unsigned int associated:1; | 242 | unsigned int associated:1; |
243 | unsigned int probereq_poll:1; | 243 | unsigned int probereq_poll:1; |
244 | unsigned int use_protection:1; | ||
245 | unsigned int create_ibss:1; | 244 | unsigned int create_ibss:1; |
246 | unsigned int mixed_cell:1; | 245 | unsigned int mixed_cell:1; |
247 | unsigned int wmm_enabled:1; | 246 | unsigned int wmm_enabled:1; |
@@ -284,6 +283,7 @@ struct ieee80211_sub_if_data { | |||
284 | int mc_count; | 283 | int mc_count; |
285 | unsigned int allmulti:1; | 284 | unsigned int allmulti:1; |
286 | unsigned int promisc:1; | 285 | unsigned int promisc:1; |
286 | unsigned int use_protection:1; /* CTS protect ERP frames */ | ||
287 | 287 | ||
288 | struct net_device_stats stats; | 288 | struct net_device_stats stats; |
289 | int drop_unencrypted; | 289 | int drop_unencrypted; |
@@ -444,7 +444,6 @@ struct ieee80211_local { | |||
444 | int *basic_rates[NUM_IEEE80211_MODES]; | 444 | int *basic_rates[NUM_IEEE80211_MODES]; |
445 | 445 | ||
446 | int rts_threshold; | 446 | int rts_threshold; |
447 | int cts_protect_erp_frames; | ||
448 | int fragmentation_threshold; | 447 | int fragmentation_threshold; |
449 | int short_retry_limit; /* dot11ShortRetryLimit */ | 448 | int short_retry_limit; /* dot11ShortRetryLimit */ |
450 | int long_retry_limit; /* dot11LongRetryLimit */ | 449 | int long_retry_limit; /* dot11LongRetryLimit */ |
diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c index 9bc209b72d41..5918dd079e12 100644 --- a/net/mac80211/ieee80211_ioctl.c +++ b/net/mac80211/ieee80211_ioctl.c | |||
@@ -1180,7 +1180,10 @@ static int ieee80211_ioctl_prism2_param(struct net_device *dev, | |||
1180 | break; | 1180 | break; |
1181 | 1181 | ||
1182 | case PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES: | 1182 | case PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES: |
1183 | local->cts_protect_erp_frames = value; | 1183 | if (sdata->type != IEEE80211_IF_TYPE_AP) |
1184 | ret = -ENOENT; | ||
1185 | else | ||
1186 | sdata->use_protection = value; | ||
1184 | break; | 1187 | break; |
1185 | 1188 | ||
1186 | case PRISM2_PARAM_PREAMBLE: | 1189 | case PRISM2_PARAM_PREAMBLE: |
@@ -1303,7 +1306,7 @@ static int ieee80211_ioctl_get_prism2_param(struct net_device *dev, | |||
1303 | break; | 1306 | break; |
1304 | 1307 | ||
1305 | case PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES: | 1308 | case PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES: |
1306 | *param = local->cts_protect_erp_frames; | 1309 | *param = sdata->use_protection; |
1307 | break; | 1310 | break; |
1308 | 1311 | ||
1309 | case PRISM2_PARAM_PREAMBLE: | 1312 | case PRISM2_PARAM_PREAMBLE: |
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c index df6c410de161..ba2bf8f0a347 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c | |||
@@ -316,12 +316,11 @@ static void ieee80211_sta_wmm_params(struct net_device *dev, | |||
316 | 316 | ||
317 | static void ieee80211_handle_erp_ie(struct net_device *dev, u8 erp_value) | 317 | static void ieee80211_handle_erp_ie(struct net_device *dev, u8 erp_value) |
318 | { | 318 | { |
319 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
320 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 319 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
321 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | 320 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; |
322 | int use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0; | 321 | int use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0; |
323 | 322 | ||
324 | if (use_protection != !!ifsta->use_protection) { | 323 | if (use_protection != sdata->use_protection) { |
325 | if (net_ratelimit()) { | 324 | if (net_ratelimit()) { |
326 | printk(KERN_DEBUG "%s: CTS protection %s (BSSID=" | 325 | printk(KERN_DEBUG "%s: CTS protection %s (BSSID=" |
327 | MAC_FMT ")\n", | 326 | MAC_FMT ")\n", |
@@ -329,8 +328,7 @@ static void ieee80211_handle_erp_ie(struct net_device *dev, u8 erp_value) | |||
329 | use_protection ? "enabled" : "disabled", | 328 | use_protection ? "enabled" : "disabled", |
330 | MAC_ARG(ifsta->bssid)); | 329 | MAC_ARG(ifsta->bssid)); |
331 | } | 330 | } |
332 | ifsta->use_protection = use_protection ? 1 : 0; | 331 | sdata->use_protection = use_protection; |
333 | local->cts_protect_erp_frames = use_protection; | ||
334 | } | 332 | } |
335 | } | 333 | } |
336 | 334 | ||
@@ -390,6 +388,7 @@ static void ieee80211_set_associated(struct net_device *dev, | |||
390 | struct ieee80211_if_sta *ifsta, int assoc) | 388 | struct ieee80211_if_sta *ifsta, int assoc) |
391 | { | 389 | { |
392 | union iwreq_data wrqu; | 390 | union iwreq_data wrqu; |
391 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
393 | 392 | ||
394 | if (ifsta->associated == assoc) | 393 | if (ifsta->associated == assoc) |
395 | return; | 394 | return; |
@@ -417,6 +416,7 @@ static void ieee80211_set_associated(struct net_device *dev, | |||
417 | ieee80211_sta_send_associnfo(dev, ifsta); | 416 | ieee80211_sta_send_associnfo(dev, ifsta); |
418 | } else { | 417 | } else { |
419 | netif_carrier_off(dev); | 418 | netif_carrier_off(dev); |
419 | sdata->use_protection = 0; | ||
420 | memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); | 420 | memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); |
421 | } | 421 | } |
422 | wrqu.ap_addr.sa_family = ARPHRD_ETHER; | 422 | wrqu.ap_addr.sa_family = ARPHRD_ETHER; |