diff options
Diffstat (limited to 'src/send.c')
-rw-r--r-- | src/send.c | 135 |
1 files changed, 64 insertions, 71 deletions
@@ -30,6 +30,8 @@ #include "tlv.h" #include "tlv_types.h" +#include <assert.h> + static inline bool send_neigh(gmrf_context_t *ctx, const gp_babel_neigh_t *neigh, const gp_babel_packet_t *packet) { if (!neigh->iface) @@ -111,7 +113,7 @@ void gp_babel_send_hellos(gmrf_context_t *ctx) { } } -static inline bool add_node_id(gp_babel_packet_buf_t *buf, const gp_babel_node_id_t *node_id) { +/*static inline bool add_node_id_tlv(gp_babel_packet_buf_t *buf, const gp_babel_node_id_t *node_id) { gp_babel_tlv_node_id_t *tlv = gp_babel_tlv_add(buf, TLV_NODE_ID, sizeof(gp_babel_tlv_node_id_t)); if (!tlv) return false; @@ -119,81 +121,56 @@ static inline bool add_node_id(gp_babel_packet_buf_t *buf, const gp_babel_node_i tlv->id = *node_id; return true; -} - -static bool add_update(gp_babel_packet_buf_t *buf, gp_babel_node_id_t *node_id, gp_babel_announce_t *announce, bool with_payload, bool targetted) { - if (announce->len && !announce->payload) { - /* incomplete announce, handle like non-existent announce */ - return true; - } - - uint16_t len = buf->packet.len; - - if (!node_id || !gp_babel_node_id_equal(node_id, &announce->node)) { - if (!add_node_id(buf, &announce->node)) - return false; + }*/ - if (node_id) - *node_id = announce->node; - } +static gp_babel_tlv_update_t* add_update_tlv(gp_babel_packet_buf_t *buf, const gp_babel_node_id_t *node, gp_babel_metric_seqno_t ms) { + gp_babel_tlv_update_t *update = gp_babel_tlv_add(buf, TLV_UPDATE, sizeof(gp_babel_tlv_update_t)); - uint8_t payload_len = (with_payload && announce->metric.metric != GP_BABEL_INFINITY) ? announce->len : 0; - gp_babel_tlv_update_t *update = gp_babel_tlv_add(buf, TLV_UPDATE, sizeof(gp_babel_tlv_update_t)+payload_len); - if (!update) { - /* reset length to remove possibly added node ID record */ - buf->packet.len = len; - return false; - } + if (!update) + return NULL; update->flags = 0; update->reserved = 0; update->interval = htons(GP_BABEL_UPDATE_INTERVAL); - update->seqno = htons(announce->metric.seqno); - update->metric = htons(announce->metric.metric); - update->type = htons(announce->type); - update->key = htons(announce->key); + update->seqno = htons(ms.seqno); + update->metric = htons(ms.metric); + update->node = *node; - if (announce->metric.metric != GP_BABEL_INFINITY && announce->len) { - update->flags |= GP_BABEL_UPDATE_FLAG_HAS_PAYLOAD; + return update; +} - if (payload_len) - memcpy(update->payload, announce->payload, payload_len); - } +static gp_babel_tlv_update_t* add_retract_tlv(gp_babel_packet_buf_t *buf, const gp_babel_node_id_t *node) { + 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) { + gp_babel_tlv_update_t *update = add_update_tlv(buf, &route->node, route->metric); + if (!update) + return false; - if (gp_babel_is_metric_better(announce->metric, announce->feasibility_distance)) - announce->feasibility_distance = announce->metric; + if (gp_babel_is_metric_better(route->metric, route->feasibility_distance)) + route->feasibility_distance = route->metric; if (!targetted) - announce->last_metric = announce->metric.metric; + route->last_metric = route->metric.metric; return true; } -void gp_babel_send_update(gmrf_context_t *ctx, gmrf_iface_state_t *iface, gp_babel_neigh_t *neigh, gp_babel_announce_t *announce, bool with_payload) { +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); - if (announce) { - add_update(buf, NULL, announce, with_payload, neigh); - } - else { - gp_babel_node_id_t node_id = gp_babel_node_id_unspec; - - gp_babel_announce_t *a; - for (a = ctx->announces; a; a = a->next) { - if (!add_update(buf, &node_id, a, with_payload, neigh)) { - if (neigh) - send_neigh(ctx, neigh, &buf->packet); - else - send_iface(ctx, iface, &buf->packet); - - node_id = gp_babel_node_id_unspec; - buf->packet.len = 0; - - if (!add_update(buf, &node_id, a, with_payload, neigh)) { - gmrf_logf(ctx->gmrf, LOG_ERR, "add_update failed"); - return; - } - } + gp_babel_route_t *a; + for (a = ctx->routes; a; a = a->next) { + if (!add_update(buf, a, neigh)) { + if (neigh) + send_neigh(ctx, neigh, &buf->packet); + else + send_iface(ctx, iface, &buf->packet); + + buf->packet.len = 0; + + assert(add_update(buf, a, neigh)); } } @@ -205,21 +182,39 @@ void gp_babel_send_update(gmrf_context_t *ctx, gmrf_iface_state_t *iface, gp_bab } } -void gp_babel_send_announce_request(gmrf_context_t *ctx, gmrf_iface_state_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_update_for_route(gmrf_context_t *ctx, gmrf_iface_state_t *iface, gp_babel_neigh_t *neigh, gp_babel_route_t *route) { 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)); + assert(add_update(buf, route, neigh)); + + if (neigh) + send_neigh(ctx, neigh, &buf->packet); + else + send_iface(ctx, iface, &buf->packet); +} + +void gp_babel_send_retract(gmrf_context_t *ctx, gmrf_iface_state_t *iface, gp_babel_neigh_t *neigh, const gp_babel_node_id_t *node) { + gp_babel_packet_buf_t *buf = gp_babel_packet_alloca(GP_BABEL_PACKET_MAX); + + assert(add_retract_tlv(buf, node)); + + if (neigh) + send_neigh(ctx, neigh, &buf->packet); + else + send_iface(ctx, iface, &buf->packet); +} + +void gp_babel_send_route_request(gmrf_context_t *ctx, gmrf_iface_state_t *iface, gp_babel_neigh_t *neigh, const gp_babel_node_id_t *node) { + gp_babel_packet_buf_t *buf = gp_babel_packet_alloca(GP_BABEL_PACKET_MAX); + + gp_babel_tlv_route_req_t *req = gp_babel_tlv_add(buf, TLV_ROUTE_REQ, sizeof(gp_babel_tlv_route_req_t)); if (!req) return; - req->node = *node; + req->node = node ? (*node) : (gp_babel_node_id_t){}; + 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(ctx, neigh, &buf->packet); @@ -227,7 +222,7 @@ void gp_babel_send_announce_request(gmrf_context_t *ctx, gmrf_iface_state_t *ifa send_iface(ctx, iface, &buf->packet); } -void gp_babel_send_seqno_request(gmrf_context_t *ctx, gp_babel_neigh_t *neigh, gp_babel_announce_t *announce, uint16_t seqno, uint8_t hop_count) { +void gp_babel_send_seqno_request(gmrf_context_t *ctx, gp_babel_neigh_t *neigh, gp_babel_route_t *route, 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)); @@ -237,9 +232,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); + req->node = route->node; if (neigh) send_neigh(ctx, neigh, &buf->packet); |