kernel-pfroute: Retry route lookup without source address on failure
authorTobias Brunner <tobias@strongswan.org>
Wed, 10 Jul 2013 09:22:57 +0000 (11:22 +0200)
committerTobias Brunner <tobias@strongswan.org>
Wed, 17 Jul 2013 15:45:17 +0000 (17:45 +0200)
The known source address might be gone resulting in an error, making
learning a new source address impossible.

src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c

index c05ca56..2d0e252 100644 (file)
@@ -1118,8 +1118,10 @@ static host_t *get_route(private_kernel_pfroute_net_t *this, bool nexthop,
        host_t *host = NULL;
        enumerator_t *enumerator;
        struct sockaddr *addr;
+       bool failed = FALSE;
        int type;
 
+retry:
        msg.hdr.rtm_msglen = sizeof(struct rt_msghdr);
        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
        {
-               DBG1(DBG_KNL, "PF_ROUTE lookup failed: %s", strerror(errno));
+               failed = TRUE;
        }
        /* signal completion of query to a waiting thread */
        this->waiting_seq = 0;
        this->condvar->signal(this->condvar);
        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)
        {
                DBG2(DBG_KNL, "using %H as %s to reach %H", host,