roam jobs for routing table changes not fired for virtual IP routes

This commit is contained in:
Martin Willi
2008-08-18 11:07:26 +00:00
parent 7cdf728586
commit 475814ce5f
+66 -36
View File
@@ -652,6 +652,40 @@ static void fire_roam_job(private_kernel_interface_t *this, bool address)
}
}
/**
* get the refcount of a virtual ip
*/
static int get_vip_refcount(private_kernel_interface_t *this, host_t* ip)
{
iterator_t *ifaces, *addrs;
iface_entry_t *iface;
addr_entry_t *addr;
int refcount = 0;
ifaces = this->ifaces->create_iterator(this->ifaces, TRUE);
while (ifaces->iterate(ifaces, (void**)&iface))
{
addrs = iface->addrs->create_iterator(iface->addrs, TRUE);
while (addrs->iterate(addrs, (void**)&addr))
{
if (addr->virtual && (iface->flags & IFF_UP) &&
ip->ip_equals(ip, addr->ip))
{
refcount = addr->refcount;
break;
}
}
addrs->destroy(addrs);
if (refcount)
{
break;
}
}
ifaces->destroy(ifaces);
return refcount;
}
/**
* process RTM_NEWLINK/RTM_DELLINK from kernel
*/
@@ -867,6 +901,37 @@ static void process_addr(private_kernel_interface_t *this,
}
}
/**
* process RTM_NEWROUTE from kernel
*/
static void process_route(private_kernel_interface_t *this, struct nlmsghdr *hdr)
{
struct rtmsg* msg = (struct rtmsg*)(NLMSG_DATA(hdr));
struct rtattr *rta = RTM_RTA(msg);
size_t rtasize = RTM_PAYLOAD(hdr);
host_t *host = NULL;
while(RTA_OK(rta, rtasize))
{
switch (rta->rta_type)
{
case RTA_PREFSRC:
host = host_create_from_chunk(msg->rtm_family,
chunk_create(RTA_DATA(rta), RTA_PAYLOAD(rta)), 0);
break;
}
rta = RTA_NEXT(rta, rtasize);
}
if (host)
{
if (!get_vip_refcount(this, host))
{ /* ignore routes added for virtual IPs */
fire_roam_job(this, FALSE);
}
host->destroy(host);
}
}
/**
* Receives events from kernel
*/
@@ -961,8 +1026,7 @@ static job_requeue_t receive_events(private_kernel_interface_t *this)
break;
case RTM_NEWROUTE:
case RTM_DELROUTE:
/* TODO: ignore route changes due to virtual IPs */
/* fire_roam_job(this, FALSE); */
process_route(this, hdr);
break;
default:
break;
@@ -1433,40 +1497,6 @@ static int get_interface_index(private_kernel_interface_t *this, host_t* ip)
return ifindex;
}
/**
* get the refcount of a virtual ip
*/
static int get_vip_refcount(private_kernel_interface_t *this, host_t* ip)
{
iterator_t *ifaces, *addrs;
iface_entry_t *iface;
addr_entry_t *addr;
int refcount = 0;
ifaces = this->ifaces->create_iterator(this->ifaces, TRUE);
while (ifaces->iterate(ifaces, (void**)&iface))
{
addrs = iface->addrs->create_iterator(iface->addrs, TRUE);
while (addrs->iterate(addrs, (void**)&addr))
{
if (addr->virtual && (iface->flags & IFF_UP) &&
ip->ip_equals(ip, addr->ip))
{
refcount = addr->refcount;
break;
}
}
addrs->destroy(addrs);
if (refcount)
{
break;
}
}
ifaces->destroy(ifaces);
return refcount;
}
/**
* Manages the creation and deletion of ip addresses on an interface.
* By setting the appropriate nlmsg_type, the ip will be set or unset.