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 | |
| 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>
| -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; |
