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