kernel-netlink: Ensure address changes are not missed in roam events

If multiple roam events are triggered within ROAM_DELAY, only one job is
created.  The old code set the address flag to the value of the last
triggering call.  So if a route change followed an address change within
ROAM_DELAY the address change was missed by the upper layers, e.g. causing
it not to update the list of addresses via MOBIKE.

The new code now keeps the state of the address flag until the job is
actually executed, which still has some issues.  For instance, if an
address disappears and reappears within ROAM_RELAY, the flag would not
have to be set to TRUE.  So address updates might occasionally get
triggered where none would actually be required.

Fixes #374.
This commit is contained in:
Tobias Brunner 2013-08-12 11:23:34 +02:00
parent a24515c515
commit 77d4a0281a
1 changed files with 15 additions and 4 deletions

View File

@ -393,6 +393,11 @@ struct private_kernel_netlink_net_t {
*/
timeval_t next_roam;
/**
* roam event due to address change
*/
bool roam_address;
/**
* lock to check and update roam event time
*/
@ -696,9 +701,15 @@ static host_t *get_interface_address(private_kernel_netlink_net_t *this,
/**
* callback function that raises the delayed roam event
*/
static job_requeue_t roam_event(uintptr_t address)
static job_requeue_t roam_event(private_kernel_netlink_net_t *this)
{
hydra->kernel_interface->roam(hydra->kernel_interface, address != 0);
bool address;
this->roam_lock->lock(this->roam_lock);
address = this->roam_address;
this->roam_address = FALSE;
this->roam_lock->unlock(this->roam_lock);
hydra->kernel_interface->roam(hydra->kernel_interface, address);
return JOB_REQUEUE_NONE;
}
@ -725,11 +736,11 @@ static void fire_roam_event(private_kernel_netlink_net_t *this, bool address)
}
timeval_add_ms(&now, ROAM_DELAY);
this->next_roam = now;
this->roam_address |= address;
this->roam_lock->unlock(this->roam_lock);
job = (job_t*)callback_job_create((callback_job_cb_t)roam_event,
(void*)(uintptr_t)(address ? 1 : 0),
NULL, NULL);
this, NULL, NULL);
lib->scheduler->schedule_job_ms(lib->scheduler, job, ROAM_DELAY);
}