diff options
-rw-r--r-- | ffd/announce.c | 11 | ||||
-rw-r--r-- | ffd/ffd.h | 1 | ||||
-rw-r--r-- | ffd/send.c | 11 |
3 files changed, 18 insertions, 5 deletions
diff --git a/ffd/announce.c b/ffd/announce.c index ae0a406..0d7b1bc 100644 --- a/ffd/announce.c +++ b/ffd/announce.c @@ -115,6 +115,15 @@ void ffd_announce_update(ffd_announce_t *announce) { announce->selected = select_nexthop(announce); announce->metric = get_metric(announce); + + /* triggered updates */ + int diff = announce->metric.metric - announce->last_metric; + + if (((announce->last_metric == 0xffff) != (announce->metric.metric == 0xffff)) + || diff <= -1024 || diff >= 384) { + fprintf(stderr, "info: announce metric has changed significantly, sending updates\n"); + ffd_send_update(NULL, NULL, announce, false); + } } void ffd_announce_update_nexthop(ffd_announce_t *announce, ffd_nexthop_t *nexthop, ffd_metric_seqno_t ms, uint16_t interval) { @@ -131,7 +140,7 @@ void ffd_announce_update_nexthop(ffd_announce_t *announce, ffd_nexthop_t *nextho ffd_announce_t* ffd_announce_new(void) { ffd_announce_t *a = calloc(1, sizeof(ffd_announce_t)); - a->metric.metric = a->feasibility_distance.metric = 0xffff; + a->metric.metric = a->feasibility_distance.metric = a->last_metric = 0xffff; a->next = announce_list; announce_list = a; @@ -81,6 +81,7 @@ typedef struct _ffd_announce_t { uint16_t key; ffd_metric_seqno_t metric; + uint16_t last_metric; ffd_metric_seqno_t feasibility_distance; ffd_nexthop_t *selected; @@ -176,7 +176,7 @@ static bool add_node_id(ffd_packet_t *packet, size_t max_len, ffd_node_id_t node return true; } -static bool add_update(ffd_packet_t *packet, size_t max_len, ffd_node_id_t *node_id, ffd_announce_t *announce, bool with_data) { +static bool add_update(ffd_packet_t *packet, size_t max_len, ffd_node_id_t *node_id, ffd_announce_t *announce, bool with_data, bool targetted) { if (announce->len && !announce->data) { /* incomplete announce, handle like non-existant announce */ return true; @@ -217,6 +217,9 @@ static bool add_update(ffd_packet_t *packet, size_t max_len, ffd_node_id_t *node if (ffd_is_metric_better(announce->metric, announce->feasibility_distance)) announce->feasibility_distance = announce->metric; + if (!targetted) + announce->last_metric = announce->metric.metric; + return true; } @@ -227,20 +230,20 @@ void ffd_send_update(ffd_iface_t *iface, ffd_neigh_t *neigh, ffd_announce_t *ann packet->len = 0; if (announce) { - add_update(packet, FFD_PACKET_MAX, NULL, announce, with_data); + add_update(packet, FFD_PACKET_MAX, NULL, announce, with_data, iface || neigh); } else { ffd_node_id_t node_id = FFD_NODE_ID_UNSPEC; ffd_announce_t *a; for (a = announce_list; a; a = a->next) { - if (!add_update(packet, FFD_PACKET_MAX, &node_id, a, with_data)) { + if (!add_update(packet, FFD_PACKET_MAX, &node_id, a, with_data, iface || neigh)) { send_any(iface, neigh, packet); node_id = FFD_NODE_ID_UNSPEC; packet->len = 0; - if (!add_update(packet, FFD_PACKET_MAX, &node_id, a, with_data)) { + if (!add_update(packet, FFD_PACKET_MAX, &node_id, a, with_data, iface || neigh)) { fprintf(stderr, "error: add_update failed\n"); return; } |