Commit 480c78c9 authored by Matthieu Boutier's avatar Matthieu Boutier Committed by Juliusz Chroboczek

Optimization, by allowing traversing (installed) specific routes only.

Two main modifications:
  - source-specific routes are putted in front of the RIB,
  - route_stream now allows traversing all routes, all installed routes,
    or source-specific installed routes.
parent bb1fd470
......@@ -1123,7 +1123,7 @@ dump_tables(FILE *out)
xroute_stream_done(xroutes);
}
routes = route_stream(0);
routes = route_stream(ROUTE_ALL);
if(routes) {
while(1) {
struct babel_route *route = route_stream_next(routes);
......
......@@ -145,7 +145,7 @@ min_conflict(const struct zone *zone, const struct babel_route *rt)
const struct babel_route *min = NULL;
struct route_stream *stream = NULL;
struct zone curr_zone;
stream = route_stream(1);
stream = route_stream(ROUTE_INSTALLED);
if(!stream) {
fprintf(stderr, "Couldn't allocate route stream.\n");
return NULL;
......@@ -171,7 +171,8 @@ conflict_solution(const struct babel_route *rt)
const struct babel_route *min = NULL; /* == solution */
struct zone zone;
struct zone tmp;
stream1 = route_stream(1);
/* Having a conflict requires at least one specific route. */
stream1 = route_stream(ROUTE_SS_INSTALLED);
if(!stream1) {
return NULL;
}
......@@ -179,7 +180,7 @@ conflict_solution(const struct babel_route *rt)
rt1 = route_stream_next(stream1);
if(rt1 == NULL) break;
stream2 = route_stream(1);
stream2 = route_stream(ROUTE_INSTALLED);
if(!stream2) {
route_stream_done(stream1);
fprintf(stderr, "Couldn't allocate route stream.\n");
......@@ -281,7 +282,7 @@ kinstall_route(const struct babel_route *route)
goto end;
}
stream = route_stream(1);
stream = route_stream(ROUTE_INSTALLED);
if(!stream) {
fprintf(stderr, "Couldn't allocate route stream.\n");
return -1;
......@@ -350,7 +351,7 @@ kuninstall_route(const struct babel_route *route)
perror("kernel_route(FLUSH)");
/* Remove source-specific conflicting routes */
stream = route_stream(1);
stream = route_stream(ROUTE_INSTALLED);
if(!stream) {
fprintf(stderr, "Couldn't allocate route stream.\n");
return -1;
......@@ -395,7 +396,7 @@ kswitch_routes(const struct babel_route *old, const struct babel_route *new)
/* Remove source-specific conflicting routes */
if(!kernel_disambiguate(v4mapped(old->nexthop))) {
stream = route_stream(1);
stream = route_stream(ROUTE_INSTALLED);
if(!stream) {
fprintf(stderr, "Couldn't allocate route stream.\n");
return -1;
......@@ -442,7 +443,7 @@ kchange_route_metric(const struct babel_route *route,
}
if(!kernel_disambiguate(v4mapped(route->nexthop))) {
stream = route_stream(1);
stream = route_stream(ROUTE_INSTALLED);
if(!stream) {
fprintf(stderr, "Couldn't allocate route stream.\n");
return -1;
......
......@@ -289,7 +289,7 @@ local_notify_all_1(int s)
xroute_stream_done(xroutes);
}
routes = route_stream(0);
routes = route_stream(ROUTE_ALL);
if(routes) {
while(1) {
struct babel_route *route = route_stream_next(routes);
......
......@@ -1525,7 +1525,7 @@ send_update(struct interface *ifp, int urgent,
struct route_stream *routes;
send_self_update(ifp);
debugf("Sending update to %s for any.\n", ifp->name);
routes = route_stream(1);
routes = route_stream(ROUTE_INSTALLED);
if(routes) {
while(1) {
struct babel_route *route = route_stream_next(routes);
......
......@@ -52,6 +52,22 @@ int keep_unfeasible = 0;
static int smoothing_half_life = 0;
static int two_to_the_one_over_hl = 0; /* 2^(1/hl) * 0x10000 */
static int
check_specific_first(void)
{
/* All source-specific routes are in front of the list */
int specific = 1;
int i;
for(i = 0; i < route_slots; i++) {
if(routes[i]->src->src_plen == 0) {
specific = 0;
} else if(!specific) {
return 0;
}
}
return 1;
}
/* We maintain a list of "slots", ordered by prefix. Every slot
contains a linked list of the routes to this prefix, with the
installed route, if any, at the head of the list. */
......@@ -61,7 +77,16 @@ route_compare(const unsigned char *prefix, unsigned char plen,
const unsigned char *src_prefix, unsigned char src_plen,
struct babel_route *route)
{
int i = memcmp(prefix, route->src->prefix, 16);
int i;
/* Put all source-specific routes in the front of the list. */
if(src_plen == 0 && route->src->src_plen > 0) {
return 1;
} else if(src_plen > 0 && route->src->src_plen == 0) {
return -1;
}
i = memcmp(prefix, route->src->prefix, 16);
if(i != 0)
return i;
......@@ -344,16 +369,19 @@ struct route_stream {
struct route_stream *
route_stream(int installed)
route_stream(int which)
{
struct route_stream *stream;
if(!check_specific_first())
fprintf(stderr, "Invariant failed: specific routes first in RIB.\n");
stream = malloc(sizeof(struct route_stream));
if(stream == NULL)
return NULL;
stream->installed = installed;
stream->index = installed ? 0 : -1;
stream->installed = which;
stream->index = which == ROUTE_ALL ? -1 : 0;
stream->next = NULL;
return stream;
......@@ -363,8 +391,14 @@ struct babel_route *
route_stream_next(struct route_stream *stream)
{
if(stream->installed) {
while(stream->index < route_slots && !routes[stream->index]->installed)
stream->index++;
while(stream->index < route_slots)
if(stream->installed == ROUTE_SS_INSTALLED &&
routes[stream->index]->src->src_plen == 0)
return NULL;
else if(routes[stream->index]->installed)
break;
else
stream->index++;
if(stream->index < route_slots)
return routes[stream->index++];
......
......@@ -44,6 +44,9 @@ struct babel_route {
struct babel_route *next;
};
#define ROUTE_ALL 0
#define ROUTE_INSTALLED 1
#define ROUTE_SS_INSTALLED 2
struct route_stream;
extern struct babel_route **routes;
......@@ -80,7 +83,7 @@ void flush_route(struct babel_route *route);
void flush_all_routes(void);
void flush_neighbour_routes(struct neighbour *neigh);
void flush_interface_routes(struct interface *ifp, int v4only);
struct route_stream *route_stream(int installed);
struct route_stream *route_stream(int which);
struct babel_route *route_stream_next(struct route_stream *stream);
void route_stream_done(struct route_stream *stream);
int 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