Index: dhclient.c =================================================================== RCS file: /usr/cvs/src/sbin/dhclient/dhclient.c,v retrieving revision 1.21 diff -u -r1.21 dhclient.c --- dhclient.c 9 Feb 2007 17:50:26 -0000 1.21 +++ dhclient.c 7 Mar 2008 18:40:03 -0000 @@ -178,6 +178,30 @@ } struct iaddr defaddr = { 4 }; +static int disassoc_pending; + +void +wifi_disassoc(void *arg) +{ + + disassoc_pending = 0; + /* + * Clear existing state; transition to the init + * state and then wait for either a link down + * notification or an associate event. + */ + if (ifi->client->active != NULL) { + script_init("EXPIRE", NULL); + script_write_params("old_", + ifi->client->active); + if (ifi->client->alias) + script_write_params("alias_", + ifi->client->alias); + script_go(); + } + ifi->client->state = S_INIT; +} + /* ARGSUSED */ void routehandler(struct protocol *p) @@ -255,24 +279,19 @@ switch (ifan->ifan_what) { case RTM_IEEE80211_ASSOC: case RTM_IEEE80211_REASSOC: - state_reboot(ifi); - break; - case RTM_IEEE80211_DISASSOC: /* - * Clear existing state; transition to the init - * state and then wait for either a link down - * notification or an associate event. + * If we have a pending disassociate event, just + * ignore the disassociate/associate cycle. */ - if (ifi->client->active != NULL) { - script_init("EXPIRE", NULL); - script_write_params("old_", - ifi->client->active); - if (ifi->client->alias) - script_write_params("alias_", - ifi->client->alias); - script_go(); + if (disassoc_pending) { + cancel_timeout(wifi_disassoc, NULL); + disassoc_pending = 0; + break; } - ifi->client->state = S_INIT; + state_reboot(ifi); + break; + case RTM_IEEE80211_DISASSOC: + add_timeout(cur_time + 2, wifi_disassoc, NULL); break; } break;