Implement proper handling of route requests

This commit is contained in:
Matthias Schiffer 2013-08-03 02:25:37 +02:00
parent f29e37138a
commit 707c703e4f
2 changed files with 40 additions and 21 deletions

View file

@ -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->flags = 0;
update->reserved = 0; update->reserved = 0;
update->interval = htons(GP_BABEL_UPDATE_INTERVAL); 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->metric = htons(ms.metric);
update->node = *node; 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}); 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); gp_babel_tlv_update_t *update = add_update_tlv(buf, &route->node, route->metric);
if (!update) if (!update)
return false; 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)) if (gp_babel_is_metric_better(route->metric, route->feasibility_distance))
route->feasibility_distance = route->metric; route->feasibility_distance = route->metric;
if (!targetted) if (!targeted)
route->last_metric = route->metric.metric; route->last_metric = route->metric.metric;
return true; 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) { 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); gp_babel_packet_buf_t *buf = gp_babel_packet_alloca(GP_BABEL_PACKET_MAX);
bool targeted = neigh;
gp_babel_route_t *a; gp_babel_route_t *route;
for (a = ctx->routes; a; a = a->next) { for (route = ctx->routes; route; route = route->next) {
if (!add_update(buf, a, neigh)) { 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) if (neigh)
send_neigh(ctx, neigh, &buf->packet); send_neigh(ctx, neigh, &buf->packet);
else 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; buf->packet.len = 0;
assert(add_update(buf, a, neigh)); assert(add_update(buf, route, targeted));
} }
} }

View file

@ -159,8 +159,22 @@ static void handle_tlv_update(gmrf_context_t *ctx, const gp_babel_tlv_update_t *
return; 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_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); bool feasible = gp_babel_is_feasible(route, ms);
gp_babel_neigh_t *neigh = get_tlv_neigh(arg); 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; 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); gp_babel_neigh_t *neigh = get_tlv_neigh(arg);
if (gp_babel_node_id_is_unspec(node)) if (gp_babel_node_id_is_unspec(&tlv->node)) {
node = NULL; gmrf_logf(ctx->gmrf, LOG_DEBUG, "received wildcard route request, dumping table.");
gp_babel_send_update(ctx, arg->iface, neigh);
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; 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) { 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) {