kernel-netlink: Respect kernel routing priorities for IKE routes

If a system uses routing metrics, we should honor them when doing (manual)
routing lookups for IKE. When enumerating routes, the kernel reports priorities
with the RTA_PRIORITY attribute, not RTA_METRICS. We prefer routes with a
lower priority value, and fall back to longest prefix match priorities if
the priority value is equal.
This commit is contained in:
Martin Willi
2015-03-03 13:42:41 +01:00
parent 4dc72f5e57
commit 6b57790270
@@ -1538,6 +1538,7 @@ typedef struct {
u_int8_t dst_len;
u_int32_t table;
u_int32_t oif;
u_int32_t priority;
} rt_entry_t;
/**
@@ -1573,6 +1574,7 @@ static rt_entry_t *parse_route(struct nlmsghdr *hdr, rt_entry_t *route)
route->dst_len = msg->rtm_dst_len;
route->table = msg->rtm_table;
route->oif = 0;
route->priority = 0;
}
else
{
@@ -1601,6 +1603,12 @@ static rt_entry_t *parse_route(struct nlmsghdr *hdr, rt_entry_t *route)
route->oif = *(u_int32_t*)RTA_DATA(rta);
}
break;
case RTA_PRIORITY:
if (RTA_PAYLOAD(rta) == sizeof(route->priority))
{
route->priority = *(u_int32_t*)RTA_DATA(rta);
}
break;
#ifdef HAVE_RTA_TABLE
case RTA_TABLE:
if (RTA_PAYLOAD(rta) == sizeof(route->table))
@@ -1724,11 +1732,16 @@ static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest,
}
route->src_host = src;
}
/* insert route, sorted by decreasing network prefix */
/* insert route, sorted by priority and network prefix */
enumerator = routes->create_enumerator(routes);
while (enumerator->enumerate(enumerator, &other))
{
if (route->dst_len > other->dst_len)
if (route->priority < other->priority)
{
break;
}
if (route->priority == other->priority &&
route->dst_len > other->dst_len)
{
break;
}