kernel-netlink: Order routes by prefix before comparing priority/metric

Metrics are basically defined to order routes with equal prefix, so ordering
routes by metric first makes not much sense as that could prefer totally
unspecific routes over very specific ones.

For instance, the previous code did break installation of routes for
passthrough policies with two routes like these in the main routing table:

  default via 192.168.2.1 dev eth0 proto static
  192.168.2.0/24 dev eth0 proto kernel scope link src 192.168.2.10 metric 1

Because the default route has no metric set (0) it was used, instead of the
more specific other one, to determine src and next hop when installing a route
for a passthrough policy for 192.168.2.0/24.  Therefore, the installed route
in table 220 did then incorrectly redirect all local traffic to "next hop"
192.168.2.1.

The same issue occurred when determining the source address while
installing trap policies.

Fixes 6b57790270 ("kernel-netlink: Respect kernel routing priorities for IKE routes").
Fixes #1416.
This commit is contained in:
Tobias Brunner 2016-04-18 18:39:35 +02:00
parent 612fe5410b
commit 3f4cc30b19
1 changed files with 4 additions and 4 deletions

View File

@ -1774,16 +1774,16 @@ static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest,
}
route->src_host = src;
}
/* insert route, sorted by priority and network prefix */
/* insert route, sorted by network prefix and priority */
enumerator = routes->create_enumerator(routes);
while (enumerator->enumerate(enumerator, &other))
{
if (route->priority < other->priority)
if (route->dst_len > other->dst_len)
{
break;
}
if (route->priority == other->priority &&
route->dst_len > other->dst_len)
if (route->dst_len == other->dst_len &&
route->priority < other->priority)
{
break;
}