summaryrefslogtreecommitdiffstats
path: root/src/send.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/send.c')
-rw-r--r--src/send.c135
1 files changed, 64 insertions, 71 deletions
diff --git a/src/send.c b/src/send.c
index 9f53510..55adb21 100644
--- a/src/send.c
+++ b/src/send.c
@@ -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);