aboutsummaryrefslogtreecommitdiffstats
path: root/src/libhydra
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2013-06-18 18:06:46 +0200
committerTobias Brunner <tobias@strongswan.org>2013-06-21 17:03:22 +0200
commit12488efa78bd42c41684236266d64631830012d0 (patch)
treebc68a6cb31f5be2a6e12548cc67cc342046025ee /src/libhydra
parent4b3fea3d54f884cc9e72bef630ffa9eb00f84b07 (diff)
downloadstrongswan-12488efa78bd42c41684236266d64631830012d0.tar.bz2
strongswan-12488efa78bd42c41684236266d64631830012d0.tar.xz
kernel-pfroute: Simplify route lookup after fixing sockaddr parsing
Diffstat (limited to 'src/libhydra')
-rw-r--r--src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c109
1 files changed, 19 insertions, 90 deletions
diff --git a/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c b/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c
index f8eed5775..c05ca56ec 100644
--- a/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c
+++ b/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c
@@ -1098,48 +1098,6 @@ METHOD(kernel_net_t, del_route, status_t,
}
/**
- * Get an address on the given interface, preferably src.
- */
-static host_t *get_address_on(private_kernel_pfroute_net_t *this, char *ifname,
- host_t *src)
-{
- enumerator_t *ifaces, *addrs;
- iface_entry_t *iface;
- addr_entry_t *addr, *found = NULL;
- host_t *host = NULL;
-
- this->lock->read_lock(this->lock);
- ifaces = this->ifaces->create_enumerator(this->ifaces);
- while (ifaces->enumerate(ifaces, &iface))
- {
- if (streq(ifname, iface->ifname))
- {
- addrs = iface->addrs->create_enumerator(iface->addrs);
- while (addrs->enumerate(addrs, &addr))
- {
- if (src->ip_equals(src, addr->ip))
- {
- found = addr;
- break;
- }
- else if (!found)
- { /* use the first address as fallback if we don't find src */
- found = addr;
- }
- }
- addrs->destroy(addrs);
- if (found)
- {
- host = found->ip->clone(found->ip);
- }
- break;
- }
- }
- ifaces->destroy(ifaces);
- this->lock->unlock(this->lock);
- return host;
-}
-/**
* Do a route lookup for dest and return either the nexthop or the source
* address.
*/
@@ -1157,10 +1115,9 @@ static host_t *get_route(private_kernel_pfroute_net_t *this, bool nexthop,
.rtm_seq = ++this->seq,
},
};
- host_t *host = NULL, *gtw = NULL, *dst = NULL, *ifa = NULL;
+ host_t *host = NULL;
enumerator_t *enumerator;
struct sockaddr *addr;
- char *ifname = NULL;
int type;
msg.hdr.rtm_msglen = sizeof(struct rt_msghdr);
@@ -1208,24 +1165,28 @@ static host_t *get_route(private_kernel_pfroute_net_t *this, bool nexthop,
sizeof(*this->reply));
while (enumerator->enumerate(enumerator, &type, &addr))
{
- if (type == RTAX_DST && this->reply->rtm_flags & RTF_HOST)
- { /* probably a cloned/cached direct route */
- dst = host_create_from_sockaddr(addr);
- }
- if (type == RTAX_GATEWAY)
- {
- gtw = host_create_from_sockaddr(addr);
- }
- if (type == RTAX_IFA)
+ if (nexthop)
{
- ifa = host_create_from_sockaddr(addr);
+ if (type == RTAX_DST && this->reply->rtm_flags & RTF_HOST)
+ { /* probably a cloned/cached direct route, only use that
+ * as fallback if no gateway is found */
+ host = host ?: host_create_from_sockaddr(addr);
+ }
+ if (type == RTAX_GATEWAY)
+ { /* could actually be a MAC address */
+ host_t *gtw = host_create_from_sockaddr(addr);
+ if (gtw)
+ {
+ DESTROY_IF(host);
+ host = gtw;
+ }
+ }
}
- if (type == RTAX_IFP)
+ else
{
- struct sockaddr_dl *sdl = (struct sockaddr_dl*)addr;
- if (addr->sa_family == AF_LINK && sdl->sdl_nlen)
+ if (type == RTAX_IFA)
{
- ifname = strndup(sdl->sdl_data, sdl->sdl_nlen);
+ host = host_create_from_sockaddr(addr);
}
}
}
@@ -1242,43 +1203,11 @@ static host_t *get_route(private_kernel_pfroute_net_t *this, bool nexthop,
this->condvar->signal(this->condvar);
this->mutex->unlock(this->mutex);
- DBG3(DBG_KNL, "route to %H: dst %H gw %H src %H if %s", dest, dst, gtw,
- ifa, ifname);
- if (nexthop)
- {
- if (gtw)
- {
- host = gtw->clone(gtw);
- }
- else if (dst)
- {
- host = dst->clone(dst);
- }
- }
- else
- {
- if (ifa)
- {
- host = ifa->clone(ifa);
- }
- else if (ifname)
- {
- host = get_address_on(this, ifname, src);
- }
- else if (gtw && !gtw->ip_equals(gtw, dest))
- {
- host = get_route(this, FALSE, gtw, src);
- }
- }
if (host)
{
DBG2(DBG_KNL, "using %H as %s to reach %H", host,
nexthop ? "nexthop" : "address", dest);
}
- DESTROY_IF(gtw);
- DESTROY_IF(dst);
- DESTROY_IF(ifa);
- free(ifname);
return host;
}