From 167ad6f7a2b2ae58dfaa46620b9b3212594f38e6 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 21 May 2008 18:17:05 +0300 Subject: mac80211: fix ieee80211_rx_bss_put/get imbalance This patch fixes iee80211_rx_bss_put/get imbalance introduced by 'mac80211: enable IBSS merging' patch. Signed-off-by: Tomas Winkler Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'net/mac80211/mlme.c') diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 7cfd12e0d1e..0ef5993e785 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -2479,8 +2479,6 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, ifsta->state = IEEE80211_IBSS_JOINED; mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); - ieee80211_rx_bss_put(dev, bss); - return res; } @@ -3523,6 +3521,7 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, struct ieee80211_supported_band *sband; u8 bssid[ETH_ALEN], *pos; int i; + int ret; DECLARE_MAC_BUF(mac); #if 0 @@ -3567,7 +3566,9 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, *pos++ = (u8) (rate / 5); } - return ieee80211_sta_join_ibss(dev, ifsta, bss); + ret = ieee80211_sta_join_ibss(dev, ifsta, bss); + ieee80211_rx_bss_put(dev, bss); + return ret; } @@ -3615,10 +3616,13 @@ static int ieee80211_sta_find_ibss(struct net_device *dev, (bss = ieee80211_rx_bss_get(dev, bssid, local->hw.conf.channel->center_freq, ifsta->ssid, ifsta->ssid_len))) { + int ret; printk(KERN_DEBUG "%s: Selected IBSS BSSID %s" " based on configured SSID\n", dev->name, print_mac(mac, bssid)); - return ieee80211_sta_join_ibss(dev, ifsta, bss); + ret = ieee80211_sta_join_ibss(dev, ifsta, bss); + ieee80211_rx_bss_put(dev, bss); + return ret; } #ifdef CONFIG_MAC80211_IBSS_DEBUG printk(KERN_DEBUG " did not try to join ibss\n"); -- cgit v1.2.3-70-g09d2 From 9381be059bf5831d259e8735005cfa35b7488543 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Fri, 23 May 2008 01:36:36 +0300 Subject: mac80211: reorder channel and freq reporting in wext scan report This patch switch order of channel and freq (SIOCGIWFREQ) reports in scan results in order to overcome wpa_supplicant inability to handle channel numbers in 5.2Ghz band. Wext reporting channel number is ambiguous as channels 7-12 (802.11j) exist on both bands. Signed-off-by: Tomas Winkler Signed-off-by: Emmanuel Grumbach Acked-by: Dan Williams Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'net/mac80211/mlme.c') diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 0ef5993e785..c29927c4977 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -4099,18 +4099,17 @@ ieee80211_sta_scan_result(struct net_device *dev, memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWFREQ; - iwe.u.freq.m = bss->freq; - iwe.u.freq.e = 6; + iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq); + iwe.u.freq.e = 0; current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWFREQ; - iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq); - iwe.u.freq.e = 0; + iwe.u.freq.m = bss->freq; + iwe.u.freq.e = 6; current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); - memset(&iwe, 0, sizeof(iwe)); iwe.cmd = IWEVQUAL; iwe.u.qual.qual = bss->signal; -- cgit v1.2.3-70-g09d2 From 70d251b24c44ab2fcba1807a5206e844cf10eb38 Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Wed, 28 May 2008 20:08:12 +0530 Subject: mac80211: Fix for NULL pointer dereference in sta_info_get() This addresses a NULL pointer dereference in sta_info_get(). TID and sta_info are extracted in ADDBA Timer expiry function through the timer handler's argument. The problem is extracging the TID (which was stored in timer_to_tid[] array of type "u8") through "int *" typecast which may also yield unwanted bytes for the MSB of TID that results in incorrect sta_info and ieee80211_local pointers. ieee80211_local pointer is NULL as illustrated below, it crashes in sta_info_get(). The problem started when extracting ieee80211_local pointer out of sta_info iteself and eventually crashed in stat_info_get(). The proper way to fix is to change the data type of TID to u8 instead of u16. However changing all the occurences requires some prototype changes as well. We should fix this in upcoming patches. Signed-off-by: Senthil Balasubramanian Signed-off-by: Luis Rodriguez Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net/mac80211/mlme.c') diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index c29927c4977..33a356e7b66 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1614,7 +1614,7 @@ void sta_addba_resp_timer_expired(unsigned long data) * only one argument, and both sta_info and TID are needed, so init * flow in sta_info_create gives the TID as data, while the timer_to_id * array gives the sta through container_of */ - u16 tid = *(int *)data; + u16 tid = *(u8 *)data; struct sta_info *temp_sta = container_of((void *)data, struct sta_info, timer_to_tid[tid]); @@ -1662,7 +1662,7 @@ timer_expired_exit: void sta_rx_agg_session_timer_expired(unsigned long data) { /* not an elegant detour, but there is no choice as the timer passes - * only one argument, and verious sta_info are needed here, so init + * only one argument, and various sta_info are needed here, so init * flow in sta_info_create gives the TID as data, while the timer_to_id * array gives the sta through container_of */ u8 *ptid = (u8 *)data; -- cgit v1.2.3-70-g09d2 From c97c23e38625f59e3e9869664eeeb0cab1822948 Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Wed, 28 May 2008 23:15:32 +0530 Subject: mac80211: fix alignment issue with compare_ether_addr() This addresses an alignment issue with compare_ether_addr(). The addresses passed to compare_ether_addr should be two bytes aligned. It may function properly in x86 platform. However may not work properly on IA-64 or ARM processor. This also fixes a typo in mlme.c where the sk_buff struct name is incorect. Though sizeof() works for any incorrect structure pointer name as its just a pointer length that we want, lets just fix it. Signed-off-by: Senthil Balasubramanian Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 4 ++-- net/mac80211/rx.c | 4 ++-- net/mac80211/util.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'net/mac80211/mlme.c') diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 33a356e7b66..841278f1df8 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1325,7 +1325,7 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev, /* prepare reordering buffer */ tid_agg_rx->reorder_buf = - kmalloc(buf_size * sizeof(struct sk_buf *), GFP_ATOMIC); + kmalloc(buf_size * sizeof(struct sk_buff *), GFP_ATOMIC); if (!tid_agg_rx->reorder_buf) { if (net_ratelimit()) printk(KERN_ERR "can not allocate reordering buffer " @@ -1334,7 +1334,7 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev, goto end; } memset(tid_agg_rx->reorder_buf, 0, - buf_size * sizeof(struct sk_buf *)); + buf_size * sizeof(struct sk_buff *)); if (local->ops->ampdu_action) ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_START, diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 1958bfb361c..0941e5d6a52 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1091,7 +1091,7 @@ ieee80211_data_to_8023(struct ieee80211_rx_data *rx) u16 fc, hdrlen, ethertype; u8 *payload; u8 dst[ETH_ALEN]; - u8 src[ETH_ALEN]; + u8 src[ETH_ALEN] __aligned(2); struct sk_buff *skb = rx->skb; struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); DECLARE_MAC_BUF(mac); @@ -1234,7 +1234,7 @@ ieee80211_data_to_8023(struct ieee80211_rx_data *rx) */ static bool ieee80211_frame_allowed(struct ieee80211_rx_data *rx) { - static const u8 pae_group_addr[ETH_ALEN] + static const u8 pae_group_addr[ETH_ALEN] __aligned(2) = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x03 }; struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data; diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 131e9e6c8a3..4e97b266f90 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -34,11 +34,11 @@ void *mac80211_wiphy_privid = &mac80211_wiphy_privid; /* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */ /* Ethernet-II snap header (RFC1042 for most EtherTypes) */ -const unsigned char rfc1042_header[] = +const unsigned char rfc1042_header[] __aligned(2) = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; /* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */ -const unsigned char bridge_tunnel_header[] = +const unsigned char bridge_tunnel_header[] __aligned(2) = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; -- cgit v1.2.3-70-g09d2 From 507b06d0622480f8026d49a94f86068bb0fd6ed6 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 3 Jun 2008 23:39:55 -0400 Subject: mac80211: send association event on IBSS create Otherwise userspace has no idea the IBSS creation succeeded. Signed-off-by: Dan Williams Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'net/mac80211/mlme.c') diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 841278f1df8..af375da9df2 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -2336,6 +2336,7 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, u8 *pos; struct ieee80211_sub_if_data *sdata; struct ieee80211_supported_band *sband; + union iwreq_data wrqu; sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; @@ -2479,6 +2480,10 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, ifsta->state = IEEE80211_IBSS_JOINED; mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); + memset(&wrqu, 0, sizeof(wrqu)); + memcpy(wrqu.ap_addr.sa_data, bss->bssid, ETH_ALEN); + wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); + return res; } -- cgit v1.2.3-70-g09d2 From 872ba53395b2a8be08c3ea2d39e225e5b4a8cb40 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 4 Jun 2008 13:59:34 -0400 Subject: mac80211: decrease IBSS creation latency Sufficient scans (at least 2 or 3) should have been done within 7 seconds to find an existing IBSS to join. This should improve IBSS creation latency; and since IBSS merging is still in effect, shouldn't have detrimental effects on eventual IBSS convergence. Signed-off-by: Dan Williams Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/mac80211/mlme.c') diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index af375da9df2..affe42f8484 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -44,7 +44,7 @@ #define IEEE80211_RETRY_AUTH_INTERVAL (1 * HZ) #define IEEE80211_SCAN_INTERVAL (2 * HZ) #define IEEE80211_SCAN_INTERVAL_SLOW (15 * HZ) -#define IEEE80211_IBSS_JOIN_TIMEOUT (20 * HZ) +#define IEEE80211_IBSS_JOIN_TIMEOUT (7 * HZ) #define IEEE80211_PROBE_DELAY (HZ / 33) #define IEEE80211_CHANNEL_TIME (HZ / 33) -- cgit v1.2.3-70-g09d2 From be038b376465953c358d675cb38a611898a49dc2 Mon Sep 17 00:00:00 2001 From: Assaf Krauss Date: Thu, 5 Jun 2008 19:55:21 +0300 Subject: mac80211: Checking IBSS support while changing channel in ad-hoc mode This patch adds a check to the set_channel flow. When attempting to change the channel while in IBSS mode, and the new channel does not support IBSS mode, the flow return with an error value with no consequences on the mac80211 and driver state. Signed-off-by: Assaf Krauss Signed-off-by: Emmanuel Grumbach Signed-off-by: Tomas Winkler Signed-off-by: John W. Linville --- net/mac80211/ieee80211_i.h | 2 +- net/mac80211/mlme.c | 11 ++++------- net/mac80211/wext.c | 15 +++++++++++---- 3 files changed, 16 insertions(+), 12 deletions(-) (limited to 'net/mac80211/mlme.c') diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index c7314bf4bec..006486b2672 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -899,7 +899,7 @@ extern const struct iw_handler_def ieee80211_iw_handler_def; /* ieee80211_ioctl.c */ -int ieee80211_set_freq(struct ieee80211_local *local, int freq); +int ieee80211_set_freq(struct net_device *dev, int freq); /* ieee80211_sta.c */ void ieee80211_sta_timer(unsigned long data); void ieee80211_sta_work(struct work_struct *work); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index affe42f8484..4d2b582dd05 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -2359,13 +2359,10 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, sdata->drop_unencrypted = bss->capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; - res = ieee80211_set_freq(local, bss->freq); + res = ieee80211_set_freq(dev, bss->freq); - if (local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS) { - printk(KERN_DEBUG "%s: IBSS not allowed on frequency " - "%d MHz\n", dev->name, local->oper_channel->center_freq); - return -1; - } + if (res) + return res; /* Set beacon template */ skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); @@ -3491,7 +3488,7 @@ static int ieee80211_sta_config_auth(struct net_device *dev, spin_unlock_bh(&local->sta_bss_lock); if (selected) { - ieee80211_set_freq(local, selected->freq); + ieee80211_set_freq(dev, selected->freq); if (!(ifsta->flags & IEEE80211_STA_SSID_SET)) ieee80211_sta_set_ssid(dev, selected->ssid, selected->ssid_len); diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index 8311bb24f9f..a8bb8e31b1e 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c @@ -290,14 +290,22 @@ static int ieee80211_ioctl_giwmode(struct net_device *dev, return 0; } -int ieee80211_set_freq(struct ieee80211_local *local, int freqMHz) +int ieee80211_set_freq(struct net_device *dev, int freqMHz) { int ret = -EINVAL; struct ieee80211_channel *chan; + struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); chan = ieee80211_get_channel(local->hw.wiphy, freqMHz); if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) { + if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && + chan->flags & IEEE80211_CHAN_NO_IBSS) { + printk(KERN_DEBUG "%s: IBSS not allowed on frequency " + "%d MHz\n", dev->name, chan->center_freq); + return ret; + } local->oper_channel = chan; if (local->sta_sw_scanning || local->sta_hw_scanning) @@ -315,7 +323,6 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *freq, char *extra) { - struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); if (sdata->vif.type == IEEE80211_IF_TYPE_STA) @@ -329,14 +336,14 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev, IEEE80211_STA_AUTO_CHANNEL_SEL; return 0; } else - return ieee80211_set_freq(local, + return ieee80211_set_freq(dev, ieee80211_channel_to_frequency(freq->m)); } else { int i, div = 1000000; for (i = 0; i < freq->e; i++) div /= 10; if (div > 0) - return ieee80211_set_freq(local, freq->m / div); + return ieee80211_set_freq(dev, freq->m / div); else return -EINVAL; } -- cgit v1.2.3-70-g09d2