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);
|
||||
};
|
||||
|
||||
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) {
|
||||
if (ms1.metric == GP_BABEL_INFINITY)
|
||||
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->hop_count = hop_count;
|
||||
req->reserved = 0;
|
||||
req->node = announce->node;
|
||||
req->type = htons(announce->type);
|
||||
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));
|
||||
}
|
||||
|
||||
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) {
|
||||
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);
|
||||
return;
|
||||
|
||||
case TLV_SEQNO_REQ:
|
||||
handle_tlv_seqno_req(ctx, data, len, tlv_arg);
|
||||
return;
|
||||
|
||||
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));
|
||||
return;
|
||||
|
|
Reference in a new issue