Implement handling of seqno requests
This commit is contained in:
parent
94e334a1fe
commit
45a3ff5a4f
3 changed files with 60 additions and 0 deletions
|
@ -154,6 +154,12 @@ static inline bool gp_babel_node_id_is_unspec(const gp_babel_node_id_t *id) {
|
||||||
return gp_babel_node_id_equal(id, &gp_babel_node_id_unspec);
|
return gp_babel_node_id_equal(id, &gp_babel_node_id_unspec);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline bool gp_babel_less(uint16_t a, uint16_t b) {
|
||||||
|
int16_t diff = a - b;
|
||||||
|
|
||||||
|
return (diff < 0);
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool gp_babel_is_metric_better(gp_babel_metric_seqno_t ms1, gp_babel_metric_seqno_t ms2) {
|
static inline bool gp_babel_is_metric_better(gp_babel_metric_seqno_t ms1, gp_babel_metric_seqno_t ms2) {
|
||||||
if (ms1.metric == GP_BABEL_INFINITY)
|
if (ms1.metric == GP_BABEL_INFINITY)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -236,6 +236,7 @@ void gp_babel_send_seqno_request(gmrf_context_t *ctx, gp_babel_neigh_t *neigh, g
|
||||||
|
|
||||||
req->seqno = htons(seqno);
|
req->seqno = htons(seqno);
|
||||||
req->hop_count = hop_count;
|
req->hop_count = hop_count;
|
||||||
|
req->reserved = 0;
|
||||||
req->node = announce->node;
|
req->node = announce->node;
|
||||||
req->type = htons(announce->type);
|
req->type = htons(announce->type);
|
||||||
req->key = htons(announce->key);
|
req->key = htons(announce->key);
|
||||||
|
|
|
@ -218,6 +218,55 @@ static void handle_tlv_update(gmrf_context_t *ctx, const gp_babel_tlv_update_t *
|
||||||
gp_babel_announce_update_nexthop(ctx, announce, nexthop, ms, ntohs(tlv_update->interval));
|
gp_babel_announce_update_nexthop(ctx, announce, nexthop, ms, ntohs(tlv_update->interval));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_tlv_seqno_req(gmrf_context_t *ctx, const gp_babel_tlv_seqno_req_t *tlv_seqno_req, size_t len, handle_tlv_arg_t *arg) {
|
||||||
|
if (len < sizeof(gp_babel_tlv_seqno_req_t)) {
|
||||||
|
gmrf_logf(ctx->gmrf, LOG_WARNING, "received short seqno request TLV.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gp_babel_announce_t *announce = gp_babel_announce_get(ctx, &tlv_seqno_req->node, ntohs(tlv_seqno_req->type), ntohs(tlv_seqno_req->key));
|
||||||
|
if (!announce || !announce->selected) {
|
||||||
|
gmrf_logf(ctx->gmrf, LOG_DEBUG, "received seqno request for unknown/unreachable announce.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gmrf_logf(ctx->gmrf, LOG_DEBUG, "seqno request received for %04x%04x, seqno %04x.",
|
||||||
|
ntohl(*(uint32_t*)tlv_seqno_req->node.id), ntohl(*(uint32_t*)(tlv_seqno_req->node.id+4)),
|
||||||
|
ntohs(tlv_seqno_req->seqno));
|
||||||
|
|
||||||
|
gp_babel_neigh_t *neigh = get_tlv_neigh(arg);
|
||||||
|
|
||||||
|
if (!gp_babel_less(announce->metric.seqno, ntohs(tlv_seqno_req->seqno))) {
|
||||||
|
/* local seqno is high enough */
|
||||||
|
gmrf_logf(ctx->gmrf, LOG_DEBUG, "sending update.");
|
||||||
|
gp_babel_send_update(ctx, arg->iface, neigh, announce, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!announce->selected->neigh) {
|
||||||
|
/* announce is local, increment seqno */
|
||||||
|
gmrf_logf(ctx->gmrf, LOG_DEBUG, "incrementing seqno.");
|
||||||
|
announce->selected->metric_seqno.seqno++;
|
||||||
|
|
||||||
|
gp_babel_send_update(ctx, arg->iface, neigh, announce, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tlv_seqno_req->hop_count < 2) {
|
||||||
|
gmrf_logf(ctx->gmrf, LOG_DEBUG, "hopcount too low, discarding.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (announce->selected->neigh == neigh) {
|
||||||
|
gmrf_logf(ctx->gmrf, LOG_DEBUG, "not forwarding backwards.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* forward request */
|
||||||
|
gmrf_logf(ctx->gmrf, LOG_DEBUG, "forwarding request.");
|
||||||
|
gp_babel_send_seqno_request(ctx, announce->selected->neigh, announce, ntohs(tlv_seqno_req->seqno), tlv_seqno_req->hop_count-1);
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_tlv(gmrf_context_t *ctx, gp_babel_tlv_type_t type, const void *data, size_t len, void *arg) {
|
static void handle_tlv(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;
|
handle_tlv_arg_t *tlv_arg = arg;
|
||||||
|
|
||||||
|
@ -246,6 +295,10 @@ static void handle_tlv(gmrf_context_t *ctx, gp_babel_tlv_type_t type, const void
|
||||||
handle_tlv_update(ctx, data, len, tlv_arg);
|
handle_tlv_update(ctx, data, len, tlv_arg);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case TLV_SEQNO_REQ:
|
||||||
|
handle_tlv_seqno_req(ctx, data, len, tlv_arg);
|
||||||
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
gmrf_logf(ctx->gmrf, LOG_DEBUG, "received unknown TLV %u on %s.", type, gmrf_iface_get_name(ctx->gmrf, tlv_arg->iface->gmrf_iface));
|
gmrf_logf(ctx->gmrf, LOG_DEBUG, "received unknown TLV %u on %s.", type, gmrf_iface_get_name(ctx->gmrf, tlv_arg->iface->gmrf_iface));
|
||||||
return;
|
return;
|
||||||
|
|
Reference in a new issue