diff options
author | Daniel Drake <dsd@gentoo.org> | 2006-06-01 10:37:22 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2006-06-05 15:51:30 -0400 |
commit | 6ae15df16ef3dc3f5f043e94bb2cd4aa6c7f2aa8 (patch) | |
tree | 4aaf3f6dd60df4dd712679e8594796dfd8322194 | |
parent | 76ea4c7f4cd319dee35934ecab57745feae58fa5 (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.h | 2 | ||||
-rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_assoc.c | 22 | ||||
-rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_event.c | 5 |
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 | */ |
313 | typedef void (*notify_function_ptr)(struct net_device *dev, void *context); | 313 | typedef 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 | ||
166 | static void | 166 | static void |
167 | ieee80211softmac_assoc_notify(struct net_device *dev, void *context) | 167 | ieee80211softmac_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 | ||
173 | static void | ||
174 | ieee80211softmac_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) */ |
174 | void | 190 | void |
175 | ieee80211softmac_assoc_work(void *d) | 191 | ieee80211softmac_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 | ||
84 | int | 84 | int |
@@ -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 | } |