summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2008-03-22 16:24:02 +0000
committersam <sam@FreeBSD.org>2008-03-22 16:24:02 +0000
commit92ad9709eb4cc7193927c79c168c9138e3b77964 (patch)
treec66592f3b794f24561c2605cf36b5dfc51562f8d
parentba857311dd69b8ea1169af902785b27a86119890 (diff)
downloadFreeBSD-src-92ad9709eb4cc7193927c79c168c9138e3b77964.zip
FreeBSD-src-92ad9709eb4cc7193927c79c168c9138e3b77964.tar.gz
Defer state change on disassociate to avoid unnecessarily dropping the
lease: track the current bssid and if it changes (as reported in an assoc/reassoc) event only then kick the state machine. This gives us immediate response when roaming but otherwise causes us to fallback on the normal state machine. Reviewed by: brooks, jhb MFC after: 3 weeks
-rw-r--r--sbin/dhclient/dhclient.c46
1 files changed, 31 insertions, 15 deletions
diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c
index 949e12e..aa6ce55 100644
--- a/sbin/dhclient/dhclient.c
+++ b/sbin/dhclient/dhclient.c
@@ -176,7 +176,29 @@ get_ifa(char *cp, int n)
return (NULL);
}
+
struct iaddr defaddr = { 4 };
+uint8_t curbssid[6];
+
+static void
+disassoc(void *arg)
+{
+ struct interface_info *ifi = arg;
+
+ /*
+ * Clear existing state.
+ */
+ 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
@@ -187,6 +209,7 @@ routehandler(struct protocol *p)
struct if_msghdr *ifm;
struct ifa_msghdr *ifam;
struct if_announcemsghdr *ifan;
+ struct ieee80211_join_event *jev;
struct client_lease *l;
time_t t = time(NULL);
struct sockaddr *sa;
@@ -255,24 +278,17 @@ routehandler(struct protocol *p)
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.
+ * Use assoc/reassoc event to kick state machine
+ * in case we roam. Otherwise fall back to the
+ * normal state machine just like a wired network.
*/
- 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();
+ jev = (struct ieee80211_join_event *) &ifan[1];
+ if (memcmp(curbssid, jev->iev_addr, 6)) {
+ disassoc(ifi);
+ state_reboot(ifi);
}
- ifi->client->state = S_INIT;
+ memcpy(curbssid, jev->iev_addr, 6);
break;
}
break;
OpenPOWER on IntegriCloud