From 707c703e4f18805829ad465c66efcdd7e89fca9a Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 3 Aug 2013 02:25:37 +0200 Subject: Implement proper handling of route requests --- src/send.c | 19 ++++++++++++------- src/tlv_types.c | 40 +++++++++++++++++++++++++++------------- 2 files changed, 39 insertions(+), 20 deletions(-) diff --git a/src/send.c b/src/send.c index 55adb21..e1c582f 100644 --- a/src/send.c +++ b/src/send.c @@ -132,7 +132,7 @@ static gp_babel_tlv_update_t* add_update_tlv(gp_babel_packet_buf_t *buf, const g update->flags = 0; update->reserved = 0; update->interval = htons(GP_BABEL_UPDATE_INTERVAL); - update->seqno = htons(ms.seqno); + update->seqno = (ms.metric != GP_BABEL_INFINITY) ? htons(ms.seqno) : 0; update->metric = htons(ms.metric); update->node = *node; @@ -143,7 +143,7 @@ static gp_babel_tlv_update_t* add_retract_tlv(gp_babel_packet_buf_t *buf, const return add_update_tlv(buf, node, (gp_babel_metric_seqno_t){GP_BABEL_INFINITY, 0}); } -static bool add_update(gp_babel_packet_buf_t *buf, gp_babel_route_t *route, bool targetted) { +static bool add_update(gp_babel_packet_buf_t *buf, gp_babel_route_t *route, bool targeted) { gp_babel_tlv_update_t *update = add_update_tlv(buf, &route->node, route->metric); if (!update) return false; @@ -151,7 +151,7 @@ static bool add_update(gp_babel_packet_buf_t *buf, gp_babel_route_t *route, bool if (gp_babel_is_metric_better(route->metric, route->feasibility_distance)) route->feasibility_distance = route->metric; - if (!targetted) + if (!targeted) route->last_metric = route->metric.metric; return true; @@ -159,10 +159,15 @@ static bool add_update(gp_babel_packet_buf_t *buf, gp_babel_route_t *route, bool void gp_babel_send_update(gmrf_context_t *ctx, gmrf_iface_state_t *iface, gp_babel_neigh_t *neigh) { gp_babel_packet_buf_t *buf = gp_babel_packet_alloca(GP_BABEL_PACKET_MAX); + bool targeted = neigh; - gp_babel_route_t *a; - for (a = ctx->routes; a; a = a->next) { - if (!add_update(buf, a, neigh)) { + gp_babel_route_t *route; + for (route = ctx->routes; route; route = route->next) { + if ((route->metric.metric == GP_BABEL_INFINITY) && targeted) + /* when targeted == true we are responding to a wildcard route request */ + continue; + + if (!add_update(buf, route, targeted)) { if (neigh) send_neigh(ctx, neigh, &buf->packet); else @@ -170,7 +175,7 @@ void gp_babel_send_update(gmrf_context_t *ctx, gmrf_iface_state_t *iface, gp_bab buf->packet.len = 0; - assert(add_update(buf, a, neigh)); + assert(add_update(buf, route, targeted)); } } diff --git a/src/tlv_types.c b/src/tlv_types.c index bd68642..ddf819f 100644 --- a/src/tlv_types.c +++ b/src/tlv_types.c @@ -159,8 +159,22 @@ static void handle_tlv_update(gmrf_context_t *ctx, const gp_babel_tlv_update_t * return; } - gp_babel_route_t *route = gp_babel_route_get(ctx, &tlv->node); gp_babel_metric_seqno_t ms = { ntohs(tlv->metric), ntohs(tlv->seqno) }; + + gp_babel_route_t *route; + + if (ms.metric == GP_BABEL_INFINITY) { + route = gp_babel_route_find(ctx, &tlv->node); + if (!route) { + gmrf_logf(ctx->gmrf, LOG_DEBUG, "retract received for unknown node %04x%04x.", + ntohl(*(uint32_t*)tlv->node.id), ntohl(*(uint32_t*)(tlv->node.id+4))); + return; + } + } + else { + route = gp_babel_route_get(ctx, &tlv->node); + } + bool feasible = gp_babel_is_feasible(route, ms); gp_babel_neigh_t *neigh = get_tlv_neigh(arg); @@ -204,23 +218,23 @@ static void handle_tlv_route_req(gmrf_context_t *ctx, const gp_babel_tlv_route_r return; } - const gp_babel_node_id_t *node = &tlv->node; - gp_babel_route_t *route = NULL; gp_babel_neigh_t *neigh = get_tlv_neigh(arg); - if (gp_babel_node_id_is_unspec(node)) - node = NULL; + if (gp_babel_node_id_is_unspec(&tlv->node)) { + gmrf_logf(ctx->gmrf, LOG_DEBUG, "received wildcard route request, dumping table."); + gp_babel_send_update(ctx, arg->iface, neigh); + return; + } - if (node) { - route = gp_babel_route_find(ctx, &tlv->node); - if (!route) { - gmrf_logf(ctx->gmrf, LOG_DEBUG, "received route request for unknown route, retracting."); - gp_babel_send_retract(ctx, arg->iface, neigh, node); - return; - } + gp_babel_route_t *route = gp_babel_route_find(ctx, &tlv->node); + if (!route) { + gmrf_logf(ctx->gmrf, LOG_DEBUG, "received route request for unknown route, retracting."); + gp_babel_send_retract(ctx, arg->iface, neigh, &tlv->node); + return; } - // TODO + gmrf_logf(ctx->gmrf, LOG_DEBUG, "received route request, responding."); + gp_babel_send_update_for_route(ctx, arg->iface, neigh, route); } static void handle_tlv_seqno_req(gmrf_context_t *ctx, const gp_babel_tlv_seqno_req_t *tlv, size_t len, handle_tlv_arg_t *arg) { -- cgit v1.2.3