diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/babel.h | 2 | ||||
-rw-r--r-- | src/route.c | 85 |
2 files changed, 48 insertions, 39 deletions
diff --git a/src/babel.h b/src/babel.h index 625b570..0e1ebb9 100644 --- a/src/babel.h +++ b/src/babel.h @@ -103,6 +103,8 @@ struct gp_babel_route { gp_babel_nexthop_t *selected; gp_babel_nexthop_t *nexthops; + + gmrf_time_t last_nexthop; }; struct gp_babel_nexthop { diff --git a/src/route.c b/src/route.c index db89896..ccb2d84 100644 --- a/src/route.c +++ b/src/route.c @@ -27,6 +27,7 @@ #include "babel.h" #include "neigh.h" +#include <assert.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; } -static void maintain_nexthops(gmrf_context_t *ctx, gp_babel_route_t *route) { - gp_babel_nexthop_t **cur, **next; - for (cur = &route->nexthops; *cur; cur = next) { - gp_babel_nexthop_t *nexthop = *cur; - next = &nexthop->next; +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)); +} - if (!nexthop->neigh) /* local */ - continue; +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); - if (!nexthop->neigh->iface) { - // TODO find out what this is supposed to to + *nexthopp = nexthop->next; - 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; - } + if (route->selected == nexthop) + route->selected = NULL; - continue; - } + gp_babel_neigh_unref(nexthop->neigh); + free(nexthop); - 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; + route->last_nexthop = gmrf_now(ctx->gmrf); +} - if (route->selected == nexthop) - route->selected = NULL; +static void maintain_nexthop(gmrf_context_t *ctx, gp_babel_route_t *route, gp_babel_nexthop_t *nexthop) { + if (!nexthop->neigh) /* local */ + return; - gp_babel_neigh_unref(nexthop->neigh); + if (nexthop_has_expired(ctx, nexthop)) { + nexthop_delete(ctx, route, nexthop); + return; + } - 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; - } - } + 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) { + gp_babel_nexthop_t *nexthop, *next; + for (nexthop = route->nexthops; nexthop; nexthop = next) { + next = nexthop->next; + + maintain_nexthop(ctx, route, nexthop); } } @@ -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) { - if (ms.metric != GP_BABEL_INFINITY || nexthop->metric_seqno.metric != GP_BABEL_INFINITY) - nexthop->last_update = gmrf_now(ctx->gmrf); + if (ms.metric == GP_BABEL_INFINITY) { + 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->interval = interval; nexthop->requested_update = false; + nexthop->last_update = gmrf_now(ctx->gmrf); gp_babel_route_update(ctx, route); } |