aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Drake <dsd@gentoo.org>2006-06-01 10:37:22 -0400
committerJohn W. Linville <linville@tuxdriver.com>2006-06-05 15:51:30 -0400
commit6ae15df16ef3dc3f5f043e94bb2cd4aa6c7f2aa8 (patch)
tree4aaf3f6dd60df4dd712679e8594796dfd8322194
parent76ea4c7f4cd319dee35934ecab57745feae58fa5 (diff)
[PATCH] softmac: Fix handling of authentication failure
My router blew up earlier, but exhibited some interesting behaviour during its dying moments. It was broadcasting beacons but wouldn't respond to any authentication requests. I noticed that softmac wasn't playing nice with this, as I couldn't make it try to connect to other networks after it had timed out authenticating to my ill router. To resolve this, I modified the softmac event/notify API to pass the event code to the callback, so that callbacks being notified from IEEE80211SOFTMAC_EVENT_ANY masks can make some judgement. In this case, the ieee80211softmac_assoc callback needs to make a decision based upon whether the association passed or failed. Signed-off-by: Daniel Drake <dsd@gentoo.org> Acked-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--include/net/ieee80211softmac.h2
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_assoc.c22
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_event.c5
3 files changed, 24 insertions, 5 deletions
diff --git a/include/net/ieee80211softmac.h b/include/net/ieee80211softmac.h
index 703463a8828b..7a483ab4022f 100644
--- a/include/net/ieee80211softmac.h
+++ b/include/net/ieee80211softmac.h
@@ -310,7 +310,7 @@ extern void ieee80211softmac_stop(struct net_device *dev);
310 * - context set to the context data you want passed 310 * - context set to the context data you want passed
311 * The return value is 0, or an error. 311 * The return value is 0, or an error.
312 */ 312 */
313typedef void (*notify_function_ptr)(struct net_device *dev, void *context); 313typedef void (*notify_function_ptr)(struct net_device *dev, int event_type, void *context);
314 314
315#define ieee80211softmac_notify(dev, event, fun, context) ieee80211softmac_notify_gfp(dev, event, fun, context, GFP_KERNEL); 315#define ieee80211softmac_notify(dev, event, fun, context) ieee80211softmac_notify_gfp(dev, event, fun, context, GFP_KERNEL);
316#define ieee80211softmac_notify_atomic(dev, event, fun, context) ieee80211softmac_notify_gfp(dev, event, fun, context, GFP_ATOMIC); 316#define ieee80211softmac_notify_atomic(dev, event, fun, context) ieee80211softmac_notify_gfp(dev, event, fun, context, GFP_ATOMIC);
diff --git a/net/ieee80211/softmac/ieee80211softmac_assoc.c b/net/ieee80211/softmac/ieee80211softmac_assoc.c
index 5d90b9a6ee50..5e9a90651d04 100644
--- a/net/ieee80211/softmac/ieee80211softmac_assoc.c
+++ b/net/ieee80211/softmac/ieee80211softmac_assoc.c
@@ -164,12 +164,28 @@ network_matches_request(struct ieee80211softmac_device *mac, struct ieee80211_ne
164} 164}
165 165
166static void 166static void
167ieee80211softmac_assoc_notify(struct net_device *dev, void *context) 167ieee80211softmac_assoc_notify_scan(struct net_device *dev, int event_type, void *context)
168{ 168{
169 struct ieee80211softmac_device *mac = ieee80211_priv(dev); 169 struct ieee80211softmac_device *mac = ieee80211_priv(dev);
170 ieee80211softmac_assoc_work((void*)mac); 170 ieee80211softmac_assoc_work((void*)mac);
171} 171}
172 172
173static void
174ieee80211softmac_assoc_notify_auth(struct net_device *dev, int event_type, void *context)
175{
176 struct ieee80211softmac_device *mac = ieee80211_priv(dev);
177
178 switch (event_type) {
179 case IEEE80211SOFTMAC_EVENT_AUTHENTICATED:
180 ieee80211softmac_assoc_work((void*)mac);
181 break;
182 case IEEE80211SOFTMAC_EVENT_AUTH_FAILED:
183 case IEEE80211SOFTMAC_EVENT_AUTH_TIMEOUT:
184 ieee80211softmac_disassoc(mac);
185 break;
186 }
187}
188
173/* This function is called to handle userspace requests (asynchronously) */ 189/* This function is called to handle userspace requests (asynchronously) */
174void 190void
175ieee80211softmac_assoc_work(void *d) 191ieee80211softmac_assoc_work(void *d)
@@ -249,7 +265,7 @@ ieee80211softmac_assoc_work(void *d)
249 * Maybe we can hope to have more memory after scanning finishes ;) 265 * Maybe we can hope to have more memory after scanning finishes ;)
250 */ 266 */
251 dprintk(KERN_INFO PFX "Associate: Scanning for networks first.\n"); 267 dprintk(KERN_INFO PFX "Associate: Scanning for networks first.\n");
252 ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, ieee80211softmac_assoc_notify, NULL); 268 ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, ieee80211softmac_assoc_notify_scan, NULL);
253 if (ieee80211softmac_start_scan(mac)) 269 if (ieee80211softmac_start_scan(mac))
254 dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n"); 270 dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n");
255 return; 271 return;
@@ -284,7 +300,7 @@ ieee80211softmac_assoc_work(void *d)
284 * otherwise adding the notification would be racy. */ 300 * otherwise adding the notification would be racy. */
285 if (!ieee80211softmac_auth_req(mac, found)) { 301 if (!ieee80211softmac_auth_req(mac, found)) {
286 dprintk(KERN_INFO PFX "cannot associate without being authenticated, requested authentication\n"); 302 dprintk(KERN_INFO PFX "cannot associate without being authenticated, requested authentication\n");
287 ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify, NULL, GFP_KERNEL); 303 ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify_auth, NULL, GFP_KERNEL);
288 } else { 304 } else {
289 printkl(KERN_WARNING PFX "Not authenticated, but requesting authentication failed. Giving up to associate\n"); 305 printkl(KERN_WARNING PFX "Not authenticated, but requesting authentication failed. Giving up to associate\n");
290 ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, found); 306 ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, found);
diff --git a/net/ieee80211/softmac/ieee80211softmac_event.c b/net/ieee80211/softmac/ieee80211softmac_event.c
index 4b153f7cc96c..f34fa2ef666b 100644
--- a/net/ieee80211/softmac/ieee80211softmac_event.c
+++ b/net/ieee80211/softmac/ieee80211softmac_event.c
@@ -78,7 +78,7 @@ ieee80211softmac_notify_callback(void *d)
78 struct ieee80211softmac_event event = *(struct ieee80211softmac_event*) d; 78 struct ieee80211softmac_event event = *(struct ieee80211softmac_event*) d;
79 kfree(d); 79 kfree(d);
80 80
81 event.fun(event.mac->dev, event.context); 81 event.fun(event.mac->dev, event.event_type, event.context);
82} 82}
83 83
84int 84int
@@ -167,6 +167,9 @@ ieee80211softmac_call_events_locked(struct ieee80211softmac_device *mac, int eve
167 if ((eventptr->event_type == event || eventptr->event_type == -1) 167 if ((eventptr->event_type == event || eventptr->event_type == -1)
168 && (eventptr->event_context == NULL || eventptr->event_context == event_ctx)) { 168 && (eventptr->event_context == NULL || eventptr->event_context == event_ctx)) {
169 list_del(&eventptr->list); 169 list_del(&eventptr->list);
170 /* User may have subscribed to ANY event, so
171 * we tell them which event triggered it. */
172 eventptr->event_type = event;
170 schedule_work(&eventptr->work); 173 schedule_work(&eventptr->work);
171 } 174 }
172 } 175 }