Cleanup nexthop maintenance logic

This commit is contained in:
Matthias Schiffer 2013-08-04 00:48:53 +02:00
parent dc9ac724cb
commit a8873733dc
2 changed files with 54 additions and 45 deletions

View file

@ -103,6 +103,8 @@ struct gp_babel_route {
gp_babel_nexthop_t *selected; gp_babel_nexthop_t *selected;
gp_babel_nexthop_t *nexthops; gp_babel_nexthop_t *nexthops;
gmrf_time_t last_nexthop;
}; };
struct gp_babel_nexthop { struct gp_babel_nexthop {

View file

@ -27,6 +27,7 @@
#include "babel.h" #include "babel.h"
#include "neigh.h" #include "neigh.h"
#include <assert.h>
#include <stdlib.h> #include <stdlib.h>
@ -88,51 +89,52 @@ gp_babel_nexthop_t* gp_babel_route_nexthop_new(gp_babel_route_t *route, gp_babel
return nexthop; return nexthop;
} }
static inline bool nexthop_has_expired(gmrf_context_t *ctx, gp_babel_nexthop_t *nexthop) {
return (gp_babel_since(ctx, nexthop->last_update) > GP_BABEL_UPDATE_TIMEOUT(nexthop->interval));
}
static void nexthop_delete(gmrf_context_t *ctx, gp_babel_route_t *route, gp_babel_nexthop_t *nexthop) {
gp_babel_nexthop_t **nexthopp;
for (nexthopp = &route->nexthops; *nexthopp; nexthopp = &(*nexthopp)->next) {
if (*nexthopp == nexthop)
break;
}
assert(*nexthopp == nexthop);
*nexthopp = nexthop->next;
if (route->selected == nexthop)
route->selected = NULL;
gp_babel_neigh_unref(nexthop->neigh);
free(nexthop);
route->last_nexthop = gmrf_now(ctx->gmrf);
}
static void maintain_nexthop(gmrf_context_t *ctx, gp_babel_route_t *route, gp_babel_nexthop_t *nexthop) {
if (!nexthop->neigh) /* local */
return;
if (nexthop_has_expired(ctx, nexthop)) {
nexthop_delete(ctx, route, nexthop);
return;
}
if (gp_babel_since(ctx, nexthop->last_update) > GP_BABEL_UPDATE_REQUEST_TIMEOUT(nexthop->interval)
&& route->selected == nexthop && !nexthop->requested_update) {
gmrf_logf(ctx->gmrf, LOG_INFO, "route about to expire, requesting update");
gp_babel_send_route_request(ctx, NULL, nexthop->neigh, &route->node);
nexthop->requested_update = true;
}
}
static void maintain_nexthops(gmrf_context_t *ctx, gp_babel_route_t *route) { static void maintain_nexthops(gmrf_context_t *ctx, gp_babel_route_t *route) {
gp_babel_nexthop_t **cur, **next; gp_babel_nexthop_t *nexthop, *next;
for (cur = &route->nexthops; *cur; cur = next) { for (nexthop = route->nexthops; nexthop; nexthop = next) {
gp_babel_nexthop_t *nexthop = *cur; next = nexthop->next;
next = &nexthop->next;
if (!nexthop->neigh) /* local */ maintain_nexthop(ctx, route, nexthop);
continue;
if (!nexthop->neigh->iface) {
// TODO find out what this is supposed to to
if (nexthop->metric_seqno.metric != GP_BABEL_INFINITY) {
nexthop->metric_seqno.metric = GP_BABEL_INFINITY;
nexthop->last_update = gmrf_now(ctx->gmrf);
nexthop->last_update += GP_BABEL_UPDATE_TIMEOUT(nexthop->interval)*10;
}
continue;
}
if (gp_babel_since(ctx, nexthop->last_update) > GP_BABEL_UPDATE_TIMEOUT(nexthop->interval)) {
if (nexthop->metric_seqno.metric == GP_BABEL_INFINITY) {
*cur = *next;
next = cur;
if (route->selected == nexthop)
route->selected = NULL;
gp_babel_neigh_unref(nexthop->neigh);
free(nexthop);
}
else {
nexthop->metric_seqno.metric = GP_BABEL_INFINITY;
nexthop->last_update += GP_BABEL_UPDATE_TIMEOUT(nexthop->interval)*10;
}
}
else if (gp_babel_since(ctx, nexthop->last_update) > GP_BABEL_UPDATE_REQUEST_TIMEOUT(nexthop->interval) && route->selected == nexthop) {
if (!nexthop->requested_update) {
gmrf_logf(ctx->gmrf, LOG_INFO, "route about to expire, requesting update");
gp_babel_send_route_request(ctx, NULL, nexthop->neigh, &route->node);
nexthop->requested_update = true;
}
}
} }
} }
@ -190,12 +192,17 @@ void gp_babel_route_update(gmrf_context_t *ctx, gp_babel_route_t *route) {
} }
void gp_babel_route_update_nexthop(gmrf_context_t *ctx, gp_babel_route_t *route, gp_babel_nexthop_t *nexthop, gp_babel_metric_seqno_t ms, uint16_t interval) { void gp_babel_route_update_nexthop(gmrf_context_t *ctx, gp_babel_route_t *route, gp_babel_nexthop_t *nexthop, gp_babel_metric_seqno_t ms, uint16_t interval) {
if (ms.metric != GP_BABEL_INFINITY || nexthop->metric_seqno.metric != GP_BABEL_INFINITY) if (ms.metric == GP_BABEL_INFINITY) {
nexthop->last_update = gmrf_now(ctx->gmrf); gmrf_logf(ctx->gmrf, LOG_DEBUG, "retract received, deleting nexthop");
nexthop_delete(ctx, route, nexthop);
gp_babel_route_update(ctx, route);
return;
}
nexthop->metric_seqno = ms; nexthop->metric_seqno = ms;
nexthop->interval = interval; nexthop->interval = interval;
nexthop->requested_update = false; nexthop->requested_update = false;
nexthop->last_update = gmrf_now(ctx->gmrf);
gp_babel_route_update(ctx, route); gp_babel_route_update(ctx, route);
} }