Commit c12137a7 authored by Matthieu Boutier's avatar Matthieu Boutier

Add API function to research some routes, or approximations.

parent df472327
...@@ -389,6 +389,107 @@ route_stream_done(struct route_stream *stream) ...@@ -389,6 +389,107 @@ route_stream_done(struct route_stream *stream)
free(stream); free(stream);
} }
/* Search for a route having dst_prefix/dst_len as destination prefix and
src_prefix/src_plen as source prefix. However, if is_min_dst is specified,
the route returns has just as constraint to contains the given destination
prefix. As multiple routes can matched this one, the minimum among the
possibles routes is returned. If exclusive_min is specified, it will be
requier for the destination to be different than the one in argument. The
same behaviour holds for the source prefix with is_min_src. */
struct babel_route *
find_min_iroute(const unsigned char *dst_prefix, unsigned char dst_plen,
const unsigned char *src_prefix, unsigned char src_plen,
int is_min_dst, int is_min_src, int exclusive_min)
{
enum prefix_status st;
struct babel_route *result = NULL;
int i;
if(!is_min_dst && !is_min_src) {
i = find_route_slot(dst_prefix, dst_plen, src_prefix, src_plen, NULL);
result = (i < 0 || !routes[i]->installed) ? NULL : routes[i];
} else if(is_min_src) { /* only dst is exactly specified */
for(i = 0; i < route_slots; i++) {
if(!routes[i]->installed)
continue;
st = prefix_cmp(dst_prefix, dst_plen,
routes[i]->src->prefix, routes[i]->src->plen);
if(st != PST_EQUALS)
continue;
st = prefix_cmp(src_prefix, src_plen,
routes[i]->src->src_prefix,
routes[i]->src->src_plen);
if(!(st & (exclusive_min ? PST_MORE_SPECIFIC :
PST_MORE_SPECIFIC | PST_EQUALS)))
continue;
if(result &&
(prefix_cmp(result->src->src_prefix,
result->src->src_plen,
routes[i]->src->src_prefix,
routes[i]->src->src_plen)
== PST_MORE_SPECIFIC))
continue;
result = routes[i];
}
} else if(is_min_dst) { /* only src is exactly specified */
for(i = 0; i < route_slots; i++) {
if(!routes[i]->installed)
continue;
st = prefix_cmp(src_prefix, src_plen,
routes[i]->src->src_prefix,
routes[i]->src->src_plen);
if(st != PST_EQUALS)
continue;
st = prefix_cmp(dst_prefix, dst_plen,
routes[i]->src->prefix, routes[i]->src->plen);
if(!(st & (exclusive_min ? PST_MORE_SPECIFIC :
PST_MORE_SPECIFIC | PST_EQUALS)))
continue;
if(result &&
(prefix_cmp(result->src->prefix,
result->src->plen,
routes[i]->src->prefix,
routes[i]->src->plen)
== PST_MORE_SPECIFIC))
continue;
result = routes[i];
}
} else {
for(i = 0; i < route_slots; i++) {
if(!routes[i]->installed)
continue;
st = prefix_cmp(dst_prefix, dst_plen,
routes[i]->src->prefix, routes[i]->src->plen);
if(!(st & (exclusive_min ? PST_MORE_SPECIFIC :
PST_MORE_SPECIFIC | PST_EQUALS)))
continue;
st = prefix_cmp(src_prefix, src_plen,
routes[i]->src->src_prefix,
routes[i]->src->src_plen);
if(!(st & (exclusive_min ? PST_MORE_SPECIFIC :
PST_MORE_SPECIFIC | PST_EQUALS)))
continue;
if(result &&
(prefix_cmp(result->src->src_prefix,
result->src->src_plen,
routes[i]->src->src_prefix,
routes[i]->src->src_plen)
== PST_MORE_SPECIFIC))
continue;
result = routes[i];
}
}
if(result)
assert(v4mapped(dst_prefix) == v4mapped(result->src->prefix));
return result;
}
static int static int
metric_to_kernel(int metric) metric_to_kernel(int metric)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment