kernel-pfroute: Retry route lookup without source address on failure

The known source address might be gone resulting in an error, making
learning a new source address impossible.
This commit is contained in:
Tobias Brunner
2013-07-17 17:45:17 +02:00
parent bbd9df25a9
commit dc8b083d9f
@@ -1118,8 +1118,10 @@ static host_t *get_route(private_kernel_pfroute_net_t *this, bool nexthop,
host_t *host = NULL; host_t *host = NULL;
enumerator_t *enumerator; enumerator_t *enumerator;
struct sockaddr *addr; struct sockaddr *addr;
bool failed = FALSE;
int type; int type;
retry:
msg.hdr.rtm_msglen = sizeof(struct rt_msghdr); msg.hdr.rtm_msglen = sizeof(struct rt_msghdr);
for (type = 0; type < RTAX_MAX; type++) for (type = 0; type < RTAX_MAX; type++)
{ {
@@ -1196,13 +1198,26 @@ static host_t *get_route(private_kernel_pfroute_net_t *this, bool nexthop,
} }
else else
{ {
DBG1(DBG_KNL, "PF_ROUTE lookup failed: %s", strerror(errno)); failed = TRUE;
} }
/* signal completion of query to a waiting thread */ /* signal completion of query to a waiting thread */
this->waiting_seq = 0; this->waiting_seq = 0;
this->condvar->signal(this->condvar); this->condvar->signal(this->condvar);
this->mutex->unlock(this->mutex); this->mutex->unlock(this->mutex);
if (failed)
{
if (src)
{ /* the given source address might be gone, try again without */
src = NULL;
msg.hdr.rtm_seq = ++this->seq;
msg.hdr.rtm_addrs = 0;
memset(msg.buf, sizeof(msg.buf), 0);
goto retry;
}
DBG1(DBG_KNL, "PF_ROUTE lookup failed: %s", strerror(errno));
}
if (host) if (host)
{ {
DBG2(DBG_KNL, "using %H as %s to reach %H", host, DBG2(DBG_KNL, "using %H as %s to reach %H", host,