Send announce and seqno requests
This commit is contained in:
parent
79c6fd3f14
commit
a6fa92d1c8
5 changed files with 93 additions and 34 deletions
|
@ -92,7 +92,7 @@ gp_babel_nexthop_t* gp_babel_announce_nexthop_new(gp_babel_announce_t *announce,
|
||||||
return nexthop;
|
return nexthop;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void maintain_nexthops(gmrf_t *gmrf, gp_babel_announce_t *announce) {
|
static void maintain_nexthops(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_announce_t *announce) {
|
||||||
gp_babel_nexthop_t **cur, **next;
|
gp_babel_nexthop_t **cur, **next;
|
||||||
for (cur = &announce->nexthops; *cur; cur = next) {
|
for (cur = &announce->nexthops; *cur; cur = next) {
|
||||||
gp_babel_nexthop_t *nexthop = *cur;
|
gp_babel_nexthop_t *nexthop = *cur;
|
||||||
|
@ -131,7 +131,7 @@ static void maintain_nexthops(gmrf_t *gmrf, gp_babel_announce_t *announce) {
|
||||||
else if (gmrf_now(gmrf) > nexthop->last_update+GP_BABEL_UPDATE_REQUEST_TIMEOUT(nexthop->interval)*10 && announce->selected == nexthop) {
|
else if (gmrf_now(gmrf) > nexthop->last_update+GP_BABEL_UPDATE_REQUEST_TIMEOUT(nexthop->interval)*10 && announce->selected == nexthop) {
|
||||||
if (!nexthop->requested_update) {
|
if (!nexthop->requested_update) {
|
||||||
gmrf_logf(gmrf, LOG_INFO, "announce about to expire, requesting update");
|
gmrf_logf(gmrf, LOG_INFO, "announce about to expire, requesting update");
|
||||||
// gp_babel_send_announce_request(nexthop->neigh->iface, nexthop->neigh, announce->node, announce->type, announce->key, false);
|
gp_babel_send_announce_request(gmrf, ctx, NULL, nexthop->neigh, &announce->node, announce->type, announce->key, false);
|
||||||
nexthop->requested_update = true;
|
nexthop->requested_update = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -172,14 +172,14 @@ gp_babel_metric_seqno_t get_metric(gmrf_t *gmrf, const gp_babel_announce_t *anno
|
||||||
return (gp_babel_metric_seqno_t){GP_BABEL_INFINITY, 0};
|
return (gp_babel_metric_seqno_t){GP_BABEL_INFINITY, 0};
|
||||||
}
|
}
|
||||||
|
|
||||||
void gp_babel_announce_update(gmrf_t *gmrf, gp_babel_announce_t *announce) {
|
void gp_babel_announce_update(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_announce_t *announce) {
|
||||||
maintain_nexthops(gmrf, announce);
|
maintain_nexthops(gmrf, ctx, announce);
|
||||||
|
|
||||||
announce->selected = select_nexthop(gmrf, announce);
|
announce->selected = select_nexthop(gmrf, announce);
|
||||||
announce->metric = get_metric(gmrf, announce);
|
announce->metric = get_metric(gmrf, announce);
|
||||||
|
|
||||||
//if (!announce->selected)
|
if (!announce->selected)
|
||||||
// gp_babel_send_seqno_request_for(NULL, announce);
|
gp_babel_send_seqno_request_for(gmrf, ctx, NULL, announce);
|
||||||
|
|
||||||
/* triggered updates */
|
/* triggered updates */
|
||||||
/*int diff = announce->metric.metric - announce->last_metric;
|
/*int diff = announce->metric.metric - announce->last_metric;
|
||||||
|
@ -191,7 +191,7 @@ void gp_babel_announce_update(gmrf_t *gmrf, gp_babel_announce_t *announce) {
|
||||||
} */
|
} */
|
||||||
}
|
}
|
||||||
|
|
||||||
void gp_babel_announce_update_nexthop(gmrf_t *gmrf, gp_babel_announce_t *announce, gp_babel_nexthop_t *nexthop, gp_babel_metric_seqno_t ms, uint16_t interval) {
|
void gp_babel_announce_update_nexthop(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_announce_t *announce, gp_babel_nexthop_t *nexthop, gp_babel_metric_seqno_t ms, uint16_t interval) {
|
||||||
nexthop->metric_seqno = ms;
|
nexthop->metric_seqno = ms;
|
||||||
nexthop->interval = interval;
|
nexthop->interval = interval;
|
||||||
nexthop->requested_update = false;
|
nexthop->requested_update = false;
|
||||||
|
@ -199,5 +199,5 @@ void gp_babel_announce_update_nexthop(gmrf_t *gmrf, gp_babel_announce_t *announc
|
||||||
if (ms.metric != GP_BABEL_INFINITY)
|
if (ms.metric != GP_BABEL_INFINITY)
|
||||||
nexthop->last_update = gmrf_now(gmrf);
|
nexthop->last_update = gmrf_now(gmrf);
|
||||||
|
|
||||||
gp_babel_announce_update(gmrf, announce);
|
gp_babel_announce_update(gmrf, ctx, announce);
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ static void maintain_announces(gmrf_t *gmrf, gmrf_context_t *ctx) {
|
||||||
gp_babel_announce_t *announce = *cur;
|
gp_babel_announce_t *announce = *cur;
|
||||||
next = &announce->next;
|
next = &announce->next;
|
||||||
|
|
||||||
gp_babel_announce_update(gmrf, announce);
|
gp_babel_announce_update(gmrf, ctx, announce);
|
||||||
|
|
||||||
if (!announce->nexthops) {
|
if (!announce->nexthops) {
|
||||||
*cur = *next;
|
*cur = *next;
|
||||||
|
|
48
src/babel.h
48
src/babel.h
|
@ -47,7 +47,11 @@
|
||||||
#define GP_BABEL_MAINTENANCE_INTERVAL GP_BABEL_HELLO_INTERVAL
|
#define GP_BABEL_MAINTENANCE_INTERVAL GP_BABEL_HELLO_INTERVAL
|
||||||
|
|
||||||
|
|
||||||
|
#define GP_BABEL_SEQNO_REQ_HOP_LIMIT 127
|
||||||
|
|
||||||
|
|
||||||
#define GP_BABEL_UPDATE_FLAG_HAS_PAYLOAD 0x01
|
#define GP_BABEL_UPDATE_FLAG_HAS_PAYLOAD 0x01
|
||||||
|
#define GP_BABEL_ANNOUCE_REQ_FLAG_WITH_PAYLOAD 0x01
|
||||||
|
|
||||||
|
|
||||||
struct gmrf_context {
|
struct gmrf_context {
|
||||||
|
@ -119,6 +123,27 @@ struct gp_babel_nexthop {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void gp_babel_handle_packet(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_iface_t *iface, const gmrf_addr_t *source, const gp_babel_packet_t *packet);
|
||||||
|
|
||||||
|
void gp_babel_send_ack(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_neigh_t *neigh, uint16_t nonce);
|
||||||
|
void gp_babel_send_hellos(gmrf_t *gmrf, gmrf_context_t *ctx);
|
||||||
|
|
||||||
|
void gp_babel_send_update(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_iface_t *iface, gp_babel_neigh_t *neigh, gp_babel_announce_t *announce, bool with_payload);
|
||||||
|
|
||||||
|
void gp_babel_send_announce_request(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_iface_t *iface, gp_babel_neigh_t *neigh, const gp_babel_node_id_t *node, uint16_t type, uint16_t key, bool with_payload);
|
||||||
|
void gp_babel_send_seqno_request(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_neigh_t *neigh, gp_babel_announce_t *announce, uint16_t seqno, uint8_t hop_count);
|
||||||
|
|
||||||
|
gp_babel_announce_t* gp_babel_announce_new(gmrf_t *gmrf, gmrf_context_t *ctx);
|
||||||
|
gp_babel_announce_t* gp_babel_announce_find(gmrf_t *gmrf, gmrf_context_t *ctx, const gp_babel_node_id_t *node, uint16_t type, uint16_t key);
|
||||||
|
gp_babel_announce_t* gp_babel_announce_get(gmrf_t *gmrf, gmrf_context_t *ctx, const gp_babel_node_id_t *node, uint16_t type, uint16_t key);
|
||||||
|
void gp_babel_announce_update(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_announce_t *announce);
|
||||||
|
void gp_babel_announce_free(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_announce_t *announce);
|
||||||
|
|
||||||
|
gp_babel_nexthop_t* gp_babel_announce_nexthop_new(gp_babel_announce_t *announce, gp_babel_neigh_t *neigh);
|
||||||
|
gp_babel_nexthop_t* gp_babel_announce_nexthop_find(const gp_babel_announce_t *announce, gp_babel_neigh_t *neigh);
|
||||||
|
void gp_babel_announce_update_nexthop(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_announce_t *announce, gp_babel_nexthop_t *nexthop, gp_babel_metric_seqno_t ms, uint16_t interval);
|
||||||
|
|
||||||
|
|
||||||
static inline bool gp_babel_node_id_equal(const gp_babel_node_id_t *id1, const gp_babel_node_id_t *id2) {
|
static inline bool gp_babel_node_id_equal(const gp_babel_node_id_t *id1, const gp_babel_node_id_t *id2) {
|
||||||
return (memcmp(id1->id, id2->id, GP_BABEL_NODE_ID_LENGTH) == 0);
|
return (memcmp(id1->id, id2->id, GP_BABEL_NODE_ID_LENGTH) == 0);
|
||||||
}
|
}
|
||||||
|
@ -137,7 +162,6 @@ static inline gp_babel_iface_t* gp_babel_get_iface(gmrf_context_t *ctx, gmrf_ifa
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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;
|
||||||
|
@ -162,23 +186,11 @@ static inline bool gp_babel_is_feasible(const gp_babel_announce_t *announce, gp_
|
||||||
return gp_babel_is_metric_better(ms, announce->feasibility_distance);
|
return gp_babel_is_metric_better(ms, announce->feasibility_distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void gp_babel_send_seqno_request_for(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_neigh_t *neigh, gp_babel_announce_t *announce) {
|
||||||
|
if (announce->feasibility_distance.metric == GP_BABEL_INFINITY)
|
||||||
|
return;
|
||||||
|
|
||||||
void gp_babel_handle_packet(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_iface_t *iface, const gmrf_addr_t *source, const gp_babel_packet_t *packet);
|
gp_babel_send_seqno_request(gmrf, ctx, neigh, announce, announce->feasibility_distance.seqno+1, GP_BABEL_SEQNO_REQ_HOP_LIMIT);
|
||||||
|
}
|
||||||
void gp_babel_send_ack(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_neigh_t *neigh, uint16_t nonce);
|
|
||||||
void gp_babel_send_hellos(gmrf_t *gmrf, gmrf_context_t *ctx);
|
|
||||||
|
|
||||||
void gp_babel_send_update(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_iface_t *iface, gp_babel_neigh_t *neigh, gp_babel_announce_t *announce, bool with_payload);
|
|
||||||
|
|
||||||
|
|
||||||
gp_babel_announce_t* gp_babel_announce_new(gmrf_t *gmrf, gmrf_context_t *ctx);
|
|
||||||
gp_babel_announce_t* gp_babel_announce_find(gmrf_t *gmrf, gmrf_context_t *ctx, const gp_babel_node_id_t *node, uint16_t type, uint16_t key);
|
|
||||||
gp_babel_announce_t* gp_babel_announce_get(gmrf_t *gmrf, gmrf_context_t *ctx, const gp_babel_node_id_t *node, uint16_t type, uint16_t key);
|
|
||||||
void gp_babel_announce_update(gmrf_t *gmrf, gp_babel_announce_t *announce);
|
|
||||||
void gp_babel_announce_free(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_announce_t *announce);
|
|
||||||
|
|
||||||
gp_babel_nexthop_t* gp_babel_announce_nexthop_new(gp_babel_announce_t *announce, gp_babel_neigh_t *neigh);
|
|
||||||
gp_babel_nexthop_t* gp_babel_announce_nexthop_find(const gp_babel_announce_t *announce, gp_babel_neigh_t *neigh);
|
|
||||||
void gp_babel_announce_update_nexthop(gmrf_t *gmrf, gp_babel_announce_t *announce, gp_babel_nexthop_t *nexthop, gp_babel_metric_seqno_t ms, uint16_t interval);
|
|
||||||
|
|
||||||
#endif /* _GMRF_PROTO_BABEL_BABEL_H_ */
|
#endif /* _GMRF_PROTO_BABEL_BABEL_H_ */
|
||||||
|
|
47
src/send.c
47
src/send.c
|
@ -52,6 +52,12 @@ static inline bool send_iface(gmrf_t *gmrf, const gp_babel_iface_t *iface, const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void send_bc(gmrf_t *gmrf, gmrf_context_t *ctx, const gp_babel_packet_t *packet) {
|
||||||
|
gp_babel_iface_t *iface;
|
||||||
|
for (iface = ctx->interfaces; iface; iface = iface->next)
|
||||||
|
send_iface(gmrf, iface, packet);
|
||||||
|
}
|
||||||
|
|
||||||
void gp_babel_send_ack(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_neigh_t *neigh, uint16_t nonce) {
|
void gp_babel_send_ack(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_neigh_t *neigh, uint16_t nonce) {
|
||||||
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);
|
||||||
|
|
||||||
|
@ -198,3 +204,44 @@ void gp_babel_send_update(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_iface_t *i
|
||||||
send_iface(gmrf, iface, &buf->packet);
|
send_iface(gmrf, iface, &buf->packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gp_babel_send_announce_request(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_iface_t *iface, gp_babel_neigh_t *neigh, const gp_babel_node_id_t *node, uint16_t type, uint16_t key, bool with_payload) {
|
||||||
|
gp_babel_packet_buf_t *buf = gp_babel_packet_alloca(GP_BABEL_PACKET_MAX);
|
||||||
|
|
||||||
|
gp_babel_tlv_announce_req_t *req = gp_babel_tlv_add(buf, TLV_ANNOUNCE_REQ, sizeof(gp_babel_tlv_announce_req_t));
|
||||||
|
if (!req)
|
||||||
|
return;
|
||||||
|
|
||||||
|
req->node = *node;
|
||||||
|
req->flags = 0;
|
||||||
|
req->reserved = 0;
|
||||||
|
req->type = htons(type);
|
||||||
|
req->key = htons(key);
|
||||||
|
|
||||||
|
if (with_payload)
|
||||||
|
req->flags |= GP_BABEL_ANNOUCE_REQ_FLAG_WITH_PAYLOAD;
|
||||||
|
|
||||||
|
if (neigh)
|
||||||
|
send_neigh(gmrf, neigh, &buf->packet);
|
||||||
|
else
|
||||||
|
send_iface(gmrf, iface, &buf->packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gp_babel_send_seqno_request(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_neigh_t *neigh, gp_babel_announce_t *announce, uint16_t seqno, uint8_t hop_count) {
|
||||||
|
gp_babel_packet_buf_t *buf = gp_babel_packet_alloca(GP_BABEL_PACKET_MAX);
|
||||||
|
|
||||||
|
gp_babel_tlv_seqno_req_t *req = gp_babel_tlv_add(buf, TLV_SEQNO_REQ, sizeof(gp_babel_tlv_seqno_req_t));
|
||||||
|
if (!req)
|
||||||
|
return;
|
||||||
|
|
||||||
|
req->seqno = htons(seqno);
|
||||||
|
req->hop_count = hop_count;
|
||||||
|
req->node = announce->node;
|
||||||
|
req->type = htons(announce->type);
|
||||||
|
req->key = htons(announce->key);
|
||||||
|
|
||||||
|
if (neigh)
|
||||||
|
send_neigh(gmrf, neigh, &buf->packet);
|
||||||
|
else
|
||||||
|
send_bc(gmrf, ctx, &buf->packet);
|
||||||
|
}
|
||||||
|
|
|
@ -182,16 +182,16 @@ static void handle_tlv_update(gmrf_t *gmrf, gmrf_context_t *ctx, const gp_babel_
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!feasible && nexthop == announce->selected) {
|
if (!feasible && nexthop == announce->selected) {
|
||||||
gmrf_logf(gmrf, LOG_DEBUG, "need new seqno");
|
gmrf_logf(gmrf, LOG_DEBUG, "requesting new seqno");
|
||||||
// gp_babel_send_seqno_request_for(neigh, announce);
|
gp_babel_send_seqno_request_for(gmrf, ctx, neigh, announce);
|
||||||
nexthop = NULL;
|
nexthop = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!feasible && nexthop && nexthop != announce->selected) {
|
if (!feasible && nexthop && nexthop != announce->selected) {
|
||||||
if (ms.metric + gp_babel_neigh_get_cost(gmrf, neigh) < announce->metric.metric) {
|
if (ms.metric + gp_babel_neigh_get_cost(gmrf, neigh) < announce->metric.metric) {
|
||||||
gmrf_logf(gmrf, LOG_DEBUG, "need new seqno");
|
gmrf_logf(gmrf, LOG_DEBUG, "requesting new seqno");
|
||||||
// gp_babel_send_seqno_request_for(neigh, announce);
|
gp_babel_send_seqno_request_for(gmrf, ctx, neigh, announce);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,8 +205,8 @@ static void handle_tlv_update(gmrf_t *gmrf, gmrf_context_t *ctx, const gp_babel_
|
||||||
announce->len = 0xff;
|
announce->len = 0xff;
|
||||||
|
|
||||||
/* request payload */
|
/* request payload */
|
||||||
//if (nexthop)
|
if (nexthop)
|
||||||
// gp_babel_send_announce_request(arg->iface, neigh, announce->node, announce->type, announce->key, true);
|
gp_babel_send_announce_request(gmrf, ctx, NULL, neigh, &announce->node, announce->type, announce->key, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,7 +215,7 @@ static void handle_tlv_update(gmrf_t *gmrf, gmrf_context_t *ctx, const gp_babel_
|
||||||
|
|
||||||
gmrf_logf(gmrf, LOG_DEBUG, "the update was accepted.");
|
gmrf_logf(gmrf, LOG_DEBUG, "the update was accepted.");
|
||||||
|
|
||||||
gp_babel_announce_update_nexthop(gmrf, announce, nexthop, ms, ntohs(tlv_update->interval));
|
gp_babel_announce_update_nexthop(gmrf, ctx, 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) {
|
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) {
|
||||||
|
|
Reference in a new issue