do not use a route if outgoing interface is down

other cleanups
This commit is contained in:
Martin Willi
2008-11-14 13:04:22 +00:00
parent a65e1c5c3a
commit fb6c8591a3
2 changed files with 82 additions and 55 deletions
+1 -1
View File
@@ -256,7 +256,7 @@ static status_t get_address_by_ts(private_kernel_interface_t *this,
} }
host->destroy(host); host->destroy(host);
addrs = this->public.create_address_enumerator(&this->public, TRUE, TRUE); addrs = create_address_enumerator(this, TRUE, TRUE);
while (addrs->enumerate(addrs, (void**)&host)) while (addrs->enumerate(addrs, (void**)&host))
{ {
if (ts->includes(ts, host)) if (ts->includes(ts, host))
@@ -700,6 +700,28 @@ static int get_interface_index(private_kernel_netlink_net_t *this, char* name)
return ifindex; return ifindex;
} }
/**
* Check if an interface with a given index is up
*/
static bool is_interface_up(private_kernel_netlink_net_t *this, int index)
{
enumerator_t *ifaces;
iface_entry_t *iface;
bool up = FALSE;
ifaces = this->ifaces->create_enumerator(this->ifaces);
while (ifaces->enumerate(ifaces, &iface))
{
if (iface->ifindex == index)
{
up = iface->flags & IFF_UP;
break;
}
}
ifaces->destroy(ifaces);
return up;
}
/** /**
* check if an address (chunk) addr is in subnet (net with net_len net bits) * check if an address (chunk) addr is in subnet (net with net_len net bits)
*/ */
@@ -786,6 +808,9 @@ static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest,
size_t rtasize; size_t rtasize;
chunk_t rta_gtw, rta_src, rta_dst; chunk_t rta_gtw, rta_src, rta_dst;
u_int32_t rta_oif = 0; u_int32_t rta_oif = 0;
enumerator_t *ifaces, *addrs;
iface_entry_t *iface;
addr_entry_t *addr;
rta_gtw = rta_src = rta_dst = chunk_empty; rta_gtw = rta_src = rta_dst = chunk_empty;
msg = (struct rtmsg*)(NLMSG_DATA(current)); msg = (struct rtmsg*)(NLMSG_DATA(current));
@@ -813,29 +838,34 @@ static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest,
} }
rta = RTA_NEXT(rta, rtasize); rta = RTA_NEXT(rta, rtasize);
} }
if (rta_oif && !is_interface_up(this, rta_oif))
/* apply the route if: { /* interface is down */
* - it is not from our own ipsec routing table goto next;
* - is better than a previous one }
* - is the default route or if (this->routing_table != 0 &&
* - its destination net contains our destination msg->rtm_table == this->routing_table)
*/ { /* route is from our own ipsec routing table */
if ((this->routing_table == 0 ||msg->rtm_table != this->routing_table) goto next;
&& msg->rtm_dst_len > best }
&& (msg->rtm_dst_len == 0 || /* default route */ if (msg->rtm_dst_len <= best)
(rta_dst.ptr && addr_in_subnet(chunk, rta_dst, msg->rtm_dst_len)))) { /* not better than a previous one */
{ goto next;
enumerator_t *ifaces, *addrs; }
iface_entry_t *iface; if (msg->rtm_dst_len != 0 &&
addr_entry_t *addr; (!rta_dst.ptr ||
!addr_in_subnet(chunk, rta_dst, msg->rtm_dst_len)))
{ /* is not the default route and not contained in our dst */
goto next;
}
best = msg->rtm_dst_len; best = msg->rtm_dst_len;
if (nexthop) if (nexthop)
{ {
DESTROY_IF(gtw); DESTROY_IF(gtw);
gtw = host_create_from_chunk(msg->rtm_family, rta_gtw, 0); gtw = host_create_from_chunk(msg->rtm_family, rta_gtw, 0);
goto next;
} }
else if (rta_src.ptr) if (rta_src.ptr)
{ {
DESTROY_IF(src); DESTROY_IF(src);
src = host_create_from_chunk(msg->rtm_family, rta_src, 0); src = host_create_from_chunk(msg->rtm_family, rta_src, 0);
@@ -843,17 +873,15 @@ static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest,
{ /* skip source address if it is installed by us */ { /* skip source address if it is installed by us */
DESTROY_IF(src); DESTROY_IF(src);
src = NULL; src = NULL;
current = NLMSG_NEXT(current, len);
continue;
} }
goto next;
} }
else
{
/* no source addr, get one from the interfaces */ /* no source addr, get one from the interfaces */
ifaces = this->ifaces->create_enumerator(this->ifaces); ifaces = this->ifaces->create_enumerator(this->ifaces);
while (ifaces->enumerate(ifaces, &iface)) while (ifaces->enumerate(ifaces, &iface))
{ {
if (iface->ifindex == rta_oif) if (iface->ifindex == rta_oif &&
iface->flags & IFF_UP)
{ {
addrs = iface->addrs->create_enumerator(iface->addrs); addrs = iface->addrs->create_enumerator(iface->addrs);
while (addrs->enumerate(addrs, &addr)) while (addrs->enumerate(addrs, &addr))
@@ -873,11 +901,10 @@ static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest,
} }
} }
ifaces->destroy(ifaces); ifaces->destroy(ifaces);
} goto next;
}
/* FALL through */
} }
default: default:
next:
current = NLMSG_NEXT(current, len); current = NLMSG_NEXT(current, len);
continue; continue;
} }