route compare function doesn't consider prefixlen
Brett Ciphery
brett.ciphery at windriver.com
Wed Jan 11 10:01:52 EST 2012
I've been playing around with a route cache in libnl and using an
nl_cache_foreach_filter to return specific routes based on a
destination, something like:
...
rtnl_route_set_family(filter, AF_INET);
rtnl_route_set_table(filter, RT_TABLE_MAIN);
nl_addr_parse( "10.0.0.0/16", AF_INET, &addrfilter);
rtnl_route_set_dst(filter, addrfilter);
nl_cache_foreach_filter(route_cache, (struct nl_object *)
filter, route_process, NULL);
...
But noticed it doesn't use the prefixlen in the route_compare function.
As an example, the above addrfilter will match a route of 10.0.0.0/8 as
well as 10.0.0.0/16 (why they're both set is another issue).
The problem is the call to nl_addr_cmp from route_compare
(route_obj.c:306):
diff |= ROUTE_DIFF(DST, nl_addr_cmp(a->rt_dst, b->rt_dst));
doesn't consider prefixlen. The below patch fixes it, but I see there
is also an nl_addr_cmp_prefix() maybe meant to be used, but it wasn't
giving me correct behaviour either when used inside route_compare.
--- a/lib/addr.c
+++ b/lib/addr.c
@@ -497,7 +497,10 @@ int nl_addr_cmp(struct nl_addr *a, struct nl_addr
*b)
d = a->a_len - b->a_len;
if (a->a_len && d == 0)
- return memcmp(a->a_addr, b->a_addr, a->a_len);
+ d = memcmp(a->a_addr, b->a_addr, a->a_len);
+
+ if (d == 0)
+ return (a->a_prefixlen -
b->a_prefixlen);
}
return d;
Thoughts?
Brett
More information about the libnl
mailing list