From 0af36311e10c0dd480bcfca5774db738e165066d Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 24 Mar 2013 02:54:17 +0100 Subject: Add nexthop data structure and receive updates --- src/tlv_types.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) (limited to 'src/tlv_types.c') diff --git a/src/tlv_types.c b/src/tlv_types.c index 3ff8bf9..b860784 100644 --- a/src/tlv_types.c +++ b/src/tlv_types.c @@ -145,6 +145,76 @@ static void handle_tlv_node_id(gmrf_t *gmrf, gmrf_context_t *ctx, const gp_babel arg->node_id = tlv_node_id->id; } +static void handle_tlv_update(gmrf_t *gmrf, gmrf_context_t *ctx, const gp_babel_tlv_update_t *tlv_update, size_t len, handle_tlv_arg_t *arg) { + if (len < sizeof(gp_babel_tlv_update_t)) { + gmrf_logf(gmrf, LOG_WARNING, "received short update TLV."); + return; + } + + if (gp_babel_node_id_is_unspec(&arg->node_id)) { + gmrf_logf(gmrf, LOG_WARNING, "received update TLV without node id TLV."); + return; + } + + if (gp_babel_node_id_equal(&arg->node_id, &ctx->self)) { + gmrf_logf(gmrf, LOG_DEBUG, "update source is myself."); + return; + } + + gp_babel_announce_t *announce = gp_babel_announce_get(gmrf, ctx, &arg->node_id, ntohs(tlv_update->type), ntohs(tlv_update->key)); + gp_babel_metric_seqno_t ms = { ntohs(tlv_update->metric), ntohs(tlv_update->seqno) }; + bool feasible = gp_babel_is_feasible(announce, ms); + + gp_babel_neigh_t *neigh = get_tlv_neigh(arg); + gp_babel_nexthop_t *nexthop = gp_babel_announce_nexthop_find(announce, neigh); + + gmrf_logf(gmrf, LOG_DEBUG, "update received from %04x%04x, metric %u, seqno %04x.", + ntohl(*(uint32_t*)arg->node_id.id), ntohl(*(uint32_t*)(arg->node_id.id+4)), + ms.metric, ms.seqno); + gmrf_logf(gmrf, LOG_DEBUG, "the update is %sfeasible and there is %s nexthop.", feasible ? "" : "not ", nexthop ? "a" : "no"); + + if (!nexthop) { + if (feasible && tlv_update->metric != GP_BABEL_INFINITY /* no need to ntohs */) + nexthop = gp_babel_announce_nexthop_new(announce, neigh); + } + else { + if (!feasible && nexthop == announce->selected) { + gmrf_logf(gmrf, LOG_DEBUG, "need new seqno"); + // gp_babel_send_seqno_request_for(neigh, announce); + nexthop = NULL; + } + } + + if (!feasible && nexthop && nexthop != announce->selected) { + if (ms.metric + gp_babel_neigh_get_cost(gmrf, neigh) < announce->metric.metric) { + gmrf_logf(gmrf, LOG_DEBUG, "need new seqno"); + // gp_babel_send_seqno_request_for(neigh, announce); + } + } + + if (!announce->data) { + if (len > sizeof(gp_babel_tlv_update_t)) { + announce->len = len - sizeof(gp_babel_tlv_update_t); + announce->data = malloc(announce->len); + memcpy(announce->data, tlv_update->data, announce->len); + } + else { + announce->len = 0xff; + + /* request data */ + //if (nexthop) + // gp_babel_send_announce_request(arg->iface, neigh, announce->node, announce->type, announce->key, true); + } + } + + if (!nexthop) + return; + + gmrf_logf(gmrf, LOG_DEBUG, "the update was accepted."); + + //gp_babel_announce_update_nexthop(announce, nexthop, ms, ntohs(tlv_update->interval)); +} + static void handle_tlv(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_tlv_type_t type, const void *data, size_t len, void *arg) { handle_tlv_arg_t *tlv_arg = arg; @@ -169,6 +239,10 @@ static void handle_tlv(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_tlv_type_t ty handle_tlv_node_id(gmrf, ctx, data, len, tlv_arg); return; + case TLV_UPDATE: + handle_tlv_update(gmrf, ctx, data, len, tlv_arg); + return; + default: gmrf_logf(gmrf, LOG_DEBUG, "received unknown TLV %u on %s.", type, gmrf_iface_get_name(gmrf, tlv_arg->iface->gmrf_iface)); return; -- cgit v1.2.3