From a8873733dcbca6f5f83dcdae1ccfefb95bcb18ab Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 4 Aug 2013 00:48:53 +0200 Subject: [PATCH 01/10] Cleanup nexthop maintenance logic --- src/babel.h | 2 ++ src/route.c | 97 ++++++++++++++++++++++++++++------------------------- 2 files changed, 54 insertions(+), 45 deletions(-) diff --git a/src/babel.h b/src/babel.h index 625b570..0e1ebb9 100644 --- a/src/babel.h +++ b/src/babel.h @@ -103,6 +103,8 @@ struct gp_babel_route { gp_babel_nexthop_t *selected; gp_babel_nexthop_t *nexthops; + + gmrf_time_t last_nexthop; }; struct gp_babel_nexthop { diff --git a/src/route.c b/src/route.c index db89896..ccb2d84 100644 --- a/src/route.c +++ b/src/route.c @@ -27,6 +27,7 @@ #include "babel.h" #include "neigh.h" +#include #include @@ -88,51 +89,52 @@ gp_babel_nexthop_t* gp_babel_route_nexthop_new(gp_babel_route_t *route, gp_babel return nexthop; } +static inline bool nexthop_has_expired(gmrf_context_t *ctx, gp_babel_nexthop_t *nexthop) { + return (gp_babel_since(ctx, nexthop->last_update) > GP_BABEL_UPDATE_TIMEOUT(nexthop->interval)); +} + +static void nexthop_delete(gmrf_context_t *ctx, gp_babel_route_t *route, gp_babel_nexthop_t *nexthop) { + gp_babel_nexthop_t **nexthopp; + for (nexthopp = &route->nexthops; *nexthopp; nexthopp = &(*nexthopp)->next) { + if (*nexthopp == nexthop) + break; + } + assert(*nexthopp == nexthop); + + *nexthopp = nexthop->next; + + if (route->selected == nexthop) + route->selected = NULL; + + gp_babel_neigh_unref(nexthop->neigh); + free(nexthop); + + route->last_nexthop = gmrf_now(ctx->gmrf); +} + +static void maintain_nexthop(gmrf_context_t *ctx, gp_babel_route_t *route, gp_babel_nexthop_t *nexthop) { + if (!nexthop->neigh) /* local */ + return; + + if (nexthop_has_expired(ctx, nexthop)) { + nexthop_delete(ctx, route, nexthop); + return; + } + + if (gp_babel_since(ctx, nexthop->last_update) > GP_BABEL_UPDATE_REQUEST_TIMEOUT(nexthop->interval) + && route->selected == nexthop && !nexthop->requested_update) { + gmrf_logf(ctx->gmrf, LOG_INFO, "route about to expire, requesting update"); + gp_babel_send_route_request(ctx, NULL, nexthop->neigh, &route->node); + nexthop->requested_update = true; + } +} + static void maintain_nexthops(gmrf_context_t *ctx, gp_babel_route_t *route) { - gp_babel_nexthop_t **cur, **next; - for (cur = &route->nexthops; *cur; cur = next) { - gp_babel_nexthop_t *nexthop = *cur; - next = &nexthop->next; + gp_babel_nexthop_t *nexthop, *next; + for (nexthop = route->nexthops; nexthop; nexthop = next) { + next = nexthop->next; - if (!nexthop->neigh) /* local */ - continue; - - if (!nexthop->neigh->iface) { - // TODO find out what this is supposed to to - - if (nexthop->metric_seqno.metric != GP_BABEL_INFINITY) { - nexthop->metric_seqno.metric = GP_BABEL_INFINITY; - nexthop->last_update = gmrf_now(ctx->gmrf); - nexthop->last_update += GP_BABEL_UPDATE_TIMEOUT(nexthop->interval)*10; - } - - continue; - } - - if (gp_babel_since(ctx, nexthop->last_update) > GP_BABEL_UPDATE_TIMEOUT(nexthop->interval)) { - if (nexthop->metric_seqno.metric == GP_BABEL_INFINITY) { - *cur = *next; - next = cur; - - if (route->selected == nexthop) - route->selected = NULL; - - gp_babel_neigh_unref(nexthop->neigh); - - free(nexthop); - } - else { - nexthop->metric_seqno.metric = GP_BABEL_INFINITY; - nexthop->last_update += GP_BABEL_UPDATE_TIMEOUT(nexthop->interval)*10; - } - } - else if (gp_babel_since(ctx, nexthop->last_update) > GP_BABEL_UPDATE_REQUEST_TIMEOUT(nexthop->interval) && route->selected == nexthop) { - if (!nexthop->requested_update) { - gmrf_logf(ctx->gmrf, LOG_INFO, "route about to expire, requesting update"); - gp_babel_send_route_request(ctx, NULL, nexthop->neigh, &route->node); - nexthop->requested_update = true; - } - } + maintain_nexthop(ctx, route, nexthop); } } @@ -190,12 +192,17 @@ void gp_babel_route_update(gmrf_context_t *ctx, gp_babel_route_t *route) { } void gp_babel_route_update_nexthop(gmrf_context_t *ctx, gp_babel_route_t *route, gp_babel_nexthop_t *nexthop, gp_babel_metric_seqno_t ms, uint16_t interval) { - if (ms.metric != GP_BABEL_INFINITY || nexthop->metric_seqno.metric != GP_BABEL_INFINITY) - nexthop->last_update = gmrf_now(ctx->gmrf); + if (ms.metric == GP_BABEL_INFINITY) { + gmrf_logf(ctx->gmrf, LOG_DEBUG, "retract received, deleting nexthop"); + nexthop_delete(ctx, route, nexthop); + gp_babel_route_update(ctx, route); + return; + } nexthop->metric_seqno = ms; nexthop->interval = interval; nexthop->requested_update = false; + nexthop->last_update = gmrf_now(ctx->gmrf); gp_babel_route_update(ctx, route); } From 8c439585116b30cbbdf405d2001e21bc4998c154 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 4 Aug 2013 01:20:18 +0200 Subject: [PATCH 02/10] Delete nexthop entries when a neighbour is reset --- src/babel.h | 1 + src/neigh.c | 13 +++++++++++++ src/route.c | 17 +++++++++-------- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/babel.h b/src/babel.h index 0e1ebb9..46c19e4 100644 --- a/src/babel.h +++ b/src/babel.h @@ -139,6 +139,7 @@ void gp_babel_route_free(gmrf_context_t *ctx, gp_babel_route_t *route); gp_babel_nexthop_t* gp_babel_route_nexthop_new(gp_babel_route_t *route, gp_babel_neigh_t *neigh); gp_babel_nexthop_t* gp_babel_route_nexthop_find(const gp_babel_route_t *route, gp_babel_neigh_t *neigh); +void gp_babel_route_nexthop_delete(gmrf_context_t *ctx, gp_babel_route_t *route, gp_babel_nexthop_t *nexthop); void gp_babel_route_update_nexthop(gmrf_context_t *ctx, gp_babel_route_t *route, gp_babel_nexthop_t *nexthop, gp_babel_metric_seqno_t ms, uint16_t interval); diff --git a/src/neigh.c b/src/neigh.c index b97540d..86f8189 100644 --- a/src/neigh.c +++ b/src/neigh.c @@ -107,5 +107,18 @@ uint16_t gp_babel_neigh_get_cost(gmrf_context_t *ctx, const gp_babel_neigh_t *ne } void gp_babel_neigh_reset(gmrf_context_t *ctx, gmrf_iface_state_t *iface, gp_babel_neigh_t *neigh) { + gmrf_logf(ctx->gmrf, LOG_DEBUG, "resetting neighbour %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x[%s].", + neigh->addr.d[0], neigh->addr.d[1], neigh->addr.d[2], neigh->addr.d[3], + neigh->addr.d[4], neigh->addr.d[5], neigh->addr.d[6], neigh->addr.d[7], + gmrf_iface_get_name(ctx->gmrf, neigh->iface->gmrf_iface)); + + gp_babel_route_t *route; + for (route = ctx->routes; route; route = route->next) { + gp_babel_nexthop_t *nexthop = gp_babel_route_nexthop_find(route, neigh); + + if (nexthop) + gp_babel_route_nexthop_delete(ctx, route, nexthop); + } + gp_babel_send_route_request(ctx, iface, neigh, NULL); } diff --git a/src/route.c b/src/route.c index ccb2d84..4daea64 100644 --- a/src/route.c +++ b/src/route.c @@ -32,14 +32,15 @@ gp_babel_route_t* gp_babel_route_new(gmrf_context_t *ctx) { - gp_babel_route_t *a = calloc(1, sizeof(gp_babel_route_t)); + gp_babel_route_t *route = calloc(1, sizeof(gp_babel_route_t)); - a->metric.metric = a->feasibility_distance.metric = a->last_metric = GP_BABEL_INFINITY; + route->metric.metric = route->feasibility_distance.metric = route->last_metric = GP_BABEL_INFINITY; + route->last_nexthop = gmrf_time_unspec; - a->next = ctx->routes; - ctx->routes = a; + route->next = ctx->routes; + ctx->routes = route; - return a; + return route; } gp_babel_route_t* gp_babel_route_find(gmrf_context_t *ctx, const gp_babel_node_id_t *node) { @@ -93,7 +94,7 @@ static inline bool nexthop_has_expired(gmrf_context_t *ctx, gp_babel_nexthop_t * return (gp_babel_since(ctx, nexthop->last_update) > GP_BABEL_UPDATE_TIMEOUT(nexthop->interval)); } -static void nexthop_delete(gmrf_context_t *ctx, gp_babel_route_t *route, gp_babel_nexthop_t *nexthop) { +void gp_babel_route_nexthop_delete(gmrf_context_t *ctx, gp_babel_route_t *route, gp_babel_nexthop_t *nexthop) { gp_babel_nexthop_t **nexthopp; for (nexthopp = &route->nexthops; *nexthopp; nexthopp = &(*nexthopp)->next) { if (*nexthopp == nexthop) @@ -117,7 +118,7 @@ static void maintain_nexthop(gmrf_context_t *ctx, gp_babel_route_t *route, gp_ba return; if (nexthop_has_expired(ctx, nexthop)) { - nexthop_delete(ctx, route, nexthop); + gp_babel_route_nexthop_delete(ctx, route, nexthop); return; } @@ -194,7 +195,7 @@ void gp_babel_route_update(gmrf_context_t *ctx, gp_babel_route_t *route) { void gp_babel_route_update_nexthop(gmrf_context_t *ctx, gp_babel_route_t *route, gp_babel_nexthop_t *nexthop, gp_babel_metric_seqno_t ms, uint16_t interval) { if (ms.metric == GP_BABEL_INFINITY) { gmrf_logf(ctx->gmrf, LOG_DEBUG, "retract received, deleting nexthop"); - nexthop_delete(ctx, route, nexthop); + gp_babel_route_nexthop_delete(ctx, route, nexthop); gp_babel_route_update(ctx, route); return; } From 4b79b85e4eb270dd2104c7fee4e5c9352f5703b7 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 4 Aug 2013 01:51:06 +0200 Subject: [PATCH 03/10] Don't purge route entries before the purge timeout has passed --- src/babel.c | 6 +++++- src/babel.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/babel.c b/src/babel.c index 3c0e219..7842428 100644 --- a/src/babel.c +++ b/src/babel.c @@ -93,7 +93,11 @@ static void maintain_routes(gmrf_context_t *ctx) { gp_babel_route_update(ctx, route); - if (!route->nexthops) { + if (!route->nexthops && gp_babel_since(ctx, route->last_nexthop) > GP_BABEL_PURGE_TIMEOUT) { + gmrf_logf(ctx->gmrf, LOG_DEBUG, "node %04x%04x (%u, seqno=%04x): purging.", + ntohl(*(uint32_t*)route->node.id), ntohl(*(uint32_t*)(route->node.id+4)), + route->metric.metric, route->metric.seqno); + *cur = *next; next = cur; gp_babel_route_free(ctx, route); diff --git a/src/babel.h b/src/babel.h index 46c19e4..c55a3a8 100644 --- a/src/babel.h +++ b/src/babel.h @@ -45,6 +45,7 @@ #define GP_BABEL_UPDATE_REQUEST_TIMEOUT(interval) ((interval)*13/4) /* 3.25 intervals */ #define GP_BABEL_MAINTENANCE_INTERVAL GP_BABEL_HELLO_INTERVAL +#define GP_BABEL_PURGE_TIMEOUT GP_BABEL_UPDATE_TIMEOUT(GP_BABEL_UPDATE_INTERVAL) #define GP_BABEL_NEIGH_PACKET_TIMEOUT 6000 From ef586cf976550dd7877180be0c3b3368db820031 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 4 Aug 2013 01:59:28 +0200 Subject: [PATCH 04/10] Send triggered updates --- src/route.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/route.c b/src/route.c index 4daea64..3d54d35 100644 --- a/src/route.c +++ b/src/route.c @@ -183,13 +183,16 @@ void gp_babel_route_update(gmrf_context_t *ctx, gp_babel_route_t *route) { gp_babel_send_seqno_request_for(ctx, NULL, route); /* triggered updates */ - /*int diff = route->metric.metric - route->last_metric; + int diff = route->metric.metric - route->last_metric; if (((route->last_metric == GP_BABEL_INFINITY) != (route->metric.metric == GP_BABEL_INFINITY)) || diff <= -1024 || diff >= 384) { - gmrf_logf(gmrf, LOG_INFO, "route metric has changed significantly, sending updates"); - gp_babel_update_enqueue(&route->node, route->type, route->key, NULL, route->metric.metric == GP_BABEL_INFINITY); - } */ + gmrf_logf(ctx->gmrf, LOG_INFO, "route metric has changed significantly, sending updates"); + + gmrf_iface_state_t *iface; + for (iface = ctx->interfaces; iface; iface = iface->next) + gp_babel_send_update_for_route(ctx, iface, NULL, route); + } } void gp_babel_route_update_nexthop(gmrf_context_t *ctx, gp_babel_route_t *route, gp_babel_nexthop_t *nexthop, gp_babel_metric_seqno_t ms, uint16_t interval) { From 7efd6c82cb359b5220134f5e65828a671f4e8b1c Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 4 Aug 2013 13:58:09 +0200 Subject: [PATCH 05/10] There is no reason to keep a hello seqno for each interface separately --- src/babel.h | 3 +-- src/send.c | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/babel.h b/src/babel.h index c55a3a8..334ee57 100644 --- a/src/babel.h +++ b/src/babel.h @@ -56,6 +56,7 @@ struct gmrf_context { gmrf_t *gmrf; gp_babel_node_id_t self; + uint16_t hello_seqno; gmrf_iface_state_t *interfaces; gp_babel_neigh_t *neighbours; @@ -68,8 +69,6 @@ struct gmrf_iface_state { gmrf_iface_t *gmrf_iface; - uint16_t seqno; - gp_babel_neigh_t *neighbours; }; diff --git a/src/send.c b/src/send.c index e1c582f..f649a34 100644 --- a/src/send.c +++ b/src/send.c @@ -104,13 +104,15 @@ void gp_babel_send_hellos(gmrf_context_t *ctx) { gmrf_iface_state_t *iface; for (iface = ctx->interfaces; iface; iface = iface->next) { - hello->seqno = htons(iface->seqno++); + hello->seqno = htons(ctx->hello_seqno); buf->packet.len = len; add_ihus(ctx, buf, iface); send_iface(ctx, iface, &buf->packet); } + + ctx->hello_seqno++; } /*static inline bool add_node_id_tlv(gp_babel_packet_buf_t *buf, const gp_babel_node_id_t *node_id) { From 0587bef25eb23f58aad1cd0b39d6bcb2dd074578 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 18 Mar 2014 16:56:06 +0100 Subject: [PATCH 06/10] Compile options, -Wextra fixes --- src/CMakeLists.txt | 3 ++- src/babel.c | 6 +++--- src/route.c | 2 +- src/tlv_types.c | 2 +- src/types.h | 3 +++ 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 64cda12..f8c0a8a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,5 @@ include_directories(${GMRF_INCLUDE_DIR}) +set_directory_properties(PROPERTIES COMPILE_DEFINITIONS _GNU_SOURCE) add_library(mmss_proto_babel MODULE babel.c @@ -9,4 +10,4 @@ add_library(mmss_proto_babel MODULE tlv_types.c ) target_link_libraries(mmss_proto_babel ${MMSS_PROTOCOL_LIB}) -set_target_properties(mmss_proto_babel PROPERTIES LINK_FLAGS "-Wl,--undefined=mmss_protocol_info") +set_target_properties(mmss_proto_babel PROPERTIES COMPILE_FLAGS "-std=c99 -Wall" LINK_FLAGS "-Wl,--undefined=mmss_protocol_info") diff --git a/src/babel.c b/src/babel.c index 7842428..4a2de19 100644 --- a/src/babel.c +++ b/src/babel.c @@ -35,13 +35,13 @@ const char *gmrf_protocol_name = "babel"; const char *gmrf_protocol_version = "experimental"; -static void send_hellos(gmrf_context_t *ctx, void *arg) { +static void send_hellos(gmrf_context_t *ctx, void *arg UNUSED) { gmrf_schedule(ctx->gmrf, send_hellos, NULL, GP_BABEL_HELLO_INTERVAL*10); gp_babel_send_hellos(ctx); } -static void send_updates(gmrf_context_t *ctx, void *arg) { +static void send_updates(gmrf_context_t *ctx, void *arg UNUSED) { gmrf_schedule(ctx->gmrf, send_updates, NULL, GP_BABEL_UPDATE_INTERVAL*10); gmrf_logf(ctx->gmrf, LOG_DEBUG, "sending periodic updates."); @@ -128,7 +128,7 @@ static void maintain_routes(gmrf_context_t *ctx) { } } -static void maintenance(gmrf_context_t *ctx, void *arg) { +static void maintenance(gmrf_context_t *ctx, void *arg UNUSED) { gmrf_schedule(ctx->gmrf, maintenance, NULL, GP_BABEL_MAINTENANCE_INTERVAL*10); maintain_neighbours(ctx); diff --git a/src/route.c b/src/route.c index 3d54d35..f8a16d5 100644 --- a/src/route.c +++ b/src/route.c @@ -64,7 +64,7 @@ gp_babel_route_t* gp_babel_route_get(gmrf_context_t *ctx, const gp_babel_node_id return route; } -void gp_babel_route_free(gmrf_context_t *ctx, gp_babel_route_t *route) { +void gp_babel_route_free(gmrf_context_t *ctx UNUSED, gp_babel_route_t *route) { free(route); } diff --git a/src/tlv_types.c b/src/tlv_types.c index fd96e98..850acfb 100644 --- a/src/tlv_types.c +++ b/src/tlv_types.c @@ -54,7 +54,7 @@ static void handle_tlv_ack_req(gmrf_context_t *ctx, const gp_babel_tlv_ack_req_t gp_babel_send_ack(ctx, get_tlv_neigh(ctx, arg), ntohs(tlv->nonce)); } -static void handle_tlv_ack(gmrf_context_t *ctx, const gp_babel_tlv_ack_t *tlv, size_t len, handle_tlv_arg_t *arg) { +static void handle_tlv_ack(gmrf_context_t *ctx, const gp_babel_tlv_ack_t *tlv UNUSED, size_t len, handle_tlv_arg_t *arg UNUSED) { if (len < sizeof(gp_babel_tlv_ack_t)) { gmrf_logf(ctx->gmrf, LOG_WARNING, "received short acknowledement TLV."); return; diff --git a/src/types.h b/src/types.h index 0907232..db4f573 100644 --- a/src/types.h +++ b/src/types.h @@ -30,6 +30,9 @@ #include +#define UNUSED __attribute__((unused)) + + #define GP_BABEL_NODE_ID_LENGTH 8 typedef struct __attribute__((packed)) gp_gabel_node_id { From 3af74a4b534186c966728785a05b0f72dc2b6048 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 18 Mar 2014 17:56:29 +0100 Subject: [PATCH 07/10] Add GMRF debug calls --- src/babel.c | 4 ++++ src/route.c | 10 +++++++++- src/tlv_types.c | 2 ++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/babel.c b/src/babel.c index 4a2de19..c8781f8 100644 --- a/src/babel.c +++ b/src/babel.c @@ -68,6 +68,7 @@ static void maintain_neighbours(gmrf_context_t *ctx) { neigh->addr.d[0], neigh->addr.d[1], neigh->addr.d[2], neigh->addr.d[3], neigh->addr.d[4], neigh->addr.d[5], neigh->addr.d[6], neigh->addr.d[7], gmrf_iface_get_name(ctx->gmrf, iface->gmrf_iface), (int)gp_babel_since(ctx, neigh->last_packet)*10); + gmrf_debug_neigh_lost(ctx->gmrf, iface->gmrf_iface, &neigh->addr); *cur = *next; next = cur; @@ -81,6 +82,7 @@ static void maintain_neighbours(gmrf_context_t *ctx) { neigh->addr.d[4], neigh->addr.d[5], neigh->addr.d[6], neigh->addr.d[7], gmrf_iface_get_name(ctx->gmrf, iface->gmrf_iface), gp_babel_neigh_get_cost(ctx, neigh), gp_babel_neigh_get_rxcost(ctx, neigh), gp_babel_neigh_get_txcost(ctx, neigh)); + gmrf_debug_neigh(ctx->gmrf, iface->gmrf_iface, &neigh->addr, gp_babel_neigh_get_rxcost(ctx, neigh), gp_babel_neigh_get_txcost(ctx, neigh)); } } } @@ -147,6 +149,8 @@ gmrf_context_t* gmrf_protocol_init(gmrf_t *gmrf) { ctx->gmrf = gmrf; gmrf_random_bytes(gmrf, &ctx->self, sizeof(gp_babel_node_id_t)); + gmrf_debug_init(gmrf, ctx->self.id, sizeof(gp_babel_node_id_t)); + gp_babel_route_t *route = gp_babel_route_new(ctx); route->node = ctx->self; diff --git a/src/route.c b/src/route.c index f8a16d5..e0cd588 100644 --- a/src/route.c +++ b/src/route.c @@ -179,9 +179,17 @@ void gp_babel_route_update(gmrf_context_t *ctx, gp_babel_route_t *route) { route->selected = select_nexthop(ctx, route); route->metric = get_metric(ctx, route); - if (!route->selected) + if (route->selected) { + if (route->selected->neigh) + gmrf_debug_route(ctx->gmrf, route->node.id, sizeof(gp_babel_node_id_t), route->selected->neigh->iface->gmrf_iface, + &route->selected->neigh->addr, route->metric.metric); + } + else { gp_babel_send_seqno_request_for(ctx, NULL, route); + gmrf_debug_route_lost(ctx->gmrf, route->node.id, sizeof(gp_babel_node_id_t)); + } + /* triggered updates */ int diff = route->metric.metric - route->last_metric; diff --git a/src/tlv_types.c b/src/tlv_types.c index 850acfb..279aaab 100644 --- a/src/tlv_types.c +++ b/src/tlv_types.c @@ -111,6 +111,7 @@ static void handle_tlv_hello(gmrf_context_t *ctx, const gp_babel_tlv_hello_t *tl gp_babel_neigh_reset(ctx, arg->iface, neigh); gmrf_logf(ctx->gmrf, LOG_DEBUG, "accepted hello, log %04x, rxcost is %u, cost is %u now.", neigh->hello_log, gp_babel_neigh_get_rxcost(ctx, neigh), gp_babel_neigh_get_cost(ctx, neigh)); + gmrf_debug_neigh(ctx->gmrf, arg->iface->gmrf_iface, &neigh->addr, gp_babel_neigh_get_rxcost(ctx, neigh), gp_babel_neigh_get_txcost(ctx, neigh)); } static void handle_tlv_ihu(gmrf_context_t *ctx, const gp_babel_tlv_ihu_t *tlv, size_t len, handle_tlv_arg_t *arg) { @@ -139,6 +140,7 @@ static void handle_tlv_ihu(gmrf_context_t *ctx, const gp_babel_tlv_ihu_t *tlv, s neigh->txcost = ntohs(tlv->rxcost); gmrf_logf(ctx->gmrf, LOG_DEBUG, "accepted IHU, txcost is %u, cost is %u now.", gp_babel_neigh_get_txcost(ctx, neigh), gp_babel_neigh_get_cost(ctx, neigh)); + gmrf_debug_neigh(ctx->gmrf, arg->iface->gmrf_iface, &neigh->addr, gp_babel_neigh_get_rxcost(ctx, neigh), gp_babel_neigh_get_txcost(ctx, neigh)); } static void handle_tlv_node_id(gmrf_context_t *ctx, const gp_babel_tlv_node_id_t *tlv, size_t len, handle_tlv_arg_t *arg) { From 2d6ec74c73f9d8404bf48998eed3cb9733c4095f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 18 Mar 2014 18:03:17 +0100 Subject: [PATCH 08/10] Update copyright years --- src/babel.c | 2 +- src/babel.h | 2 +- src/packet.h | 2 +- src/route.c | 2 +- src/send.c | 2 +- src/tlv.c | 2 +- src/tlv.h | 2 +- src/tlv_types.c | 2 +- src/tlv_types.h | 2 +- src/types.h | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/babel.c b/src/babel.c index c8781f8..fb2d165 100644 --- a/src/babel.c +++ b/src/babel.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2013, Matthias Schiffer + Copyright (c) 2013-2014, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/babel.h b/src/babel.h index 334ee57..3564cf8 100644 --- a/src/babel.h +++ b/src/babel.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2013, Matthias Schiffer + Copyright (c) 2013-2014, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/packet.h b/src/packet.h index 09b6dc0..0b89b56 100644 --- a/src/packet.h +++ b/src/packet.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2013, Matthias Schiffer + Copyright (c) 2013-2014, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/route.c b/src/route.c index e0cd588..e0ff127 100644 --- a/src/route.c +++ b/src/route.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2013, Matthias Schiffer + Copyright (c) 2013-2014, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/send.c b/src/send.c index f649a34..f5734b5 100644 --- a/src/send.c +++ b/src/send.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2013, Matthias Schiffer + Copyright (c) 2013-2014, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/tlv.c b/src/tlv.c index d8a5be5..94e6e04 100644 --- a/src/tlv.c +++ b/src/tlv.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2013, Matthias Schiffer + Copyright (c) 2013-2014, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/tlv.h b/src/tlv.h index 2cfd73d..6208ae2 100644 --- a/src/tlv.h +++ b/src/tlv.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2013, Matthias Schiffer + Copyright (c) 2013-2014, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/tlv_types.c b/src/tlv_types.c index 279aaab..2a20f5d 100644 --- a/src/tlv_types.c +++ b/src/tlv_types.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2013, Matthias Schiffer + Copyright (c) 2013-2014, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/tlv_types.h b/src/tlv_types.h index 08a23b6..c859873 100644 --- a/src/tlv_types.h +++ b/src/tlv_types.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2013, Matthias Schiffer + Copyright (c) 2013-2014, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/types.h b/src/types.h index db4f573..069e44a 100644 --- a/src/types.h +++ b/src/types.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2013, Matthias Schiffer + Copyright (c) 2013-2014, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without From 5a077ac88402ea4ec5f25211c14f85ad18aa0f2d Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 18 Mar 2014 18:33:25 +0100 Subject: [PATCH 09/10] Always update a route's nexthop as soon as the current nexthop is deleted (and clean up the route update code a bit) --- src/babel.c | 2 +- src/babel.h | 2 +- src/route.c | 128 ++++++++++++++++++++++++++++------------------------ 3 files changed, 71 insertions(+), 61 deletions(-) diff --git a/src/babel.c b/src/babel.c index fb2d165..0fab0a7 100644 --- a/src/babel.c +++ b/src/babel.c @@ -93,7 +93,7 @@ static void maintain_routes(gmrf_context_t *ctx) { gp_babel_route_t *route = *cur; next = &route->next; - gp_babel_route_update(ctx, route); + gp_babel_route_maintain(ctx, route); if (!route->nexthops && gp_babel_since(ctx, route->last_nexthop) > GP_BABEL_PURGE_TIMEOUT) { gmrf_logf(ctx->gmrf, LOG_DEBUG, "node %04x%04x (%u, seqno=%04x): purging.", diff --git a/src/babel.h b/src/babel.h index 3564cf8..27748a7 100644 --- a/src/babel.h +++ b/src/babel.h @@ -134,7 +134,7 @@ void gp_babel_send_seqno_request(gmrf_context_t *ctx, gp_babel_neigh_t *neigh, g gp_babel_route_t* gp_babel_route_new(gmrf_context_t *ctx); gp_babel_route_t* gp_babel_route_find(gmrf_context_t *ctx, const gp_babel_node_id_t *node); gp_babel_route_t* gp_babel_route_get(gmrf_context_t *ctx, const gp_babel_node_id_t *node); -void gp_babel_route_update(gmrf_context_t *ctx, gp_babel_route_t *route); +void gp_babel_route_maintain(gmrf_context_t *ctx, gp_babel_route_t *route); void gp_babel_route_free(gmrf_context_t *ctx, gp_babel_route_t *route); gp_babel_nexthop_t* gp_babel_route_nexthop_new(gp_babel_route_t *route, gp_babel_neigh_t *neigh); diff --git a/src/route.c b/src/route.c index e0ff127..fed699c 100644 --- a/src/route.c +++ b/src/route.c @@ -94,50 +94,6 @@ static inline bool nexthop_has_expired(gmrf_context_t *ctx, gp_babel_nexthop_t * return (gp_babel_since(ctx, nexthop->last_update) > GP_BABEL_UPDATE_TIMEOUT(nexthop->interval)); } -void gp_babel_route_nexthop_delete(gmrf_context_t *ctx, gp_babel_route_t *route, gp_babel_nexthop_t *nexthop) { - gp_babel_nexthop_t **nexthopp; - for (nexthopp = &route->nexthops; *nexthopp; nexthopp = &(*nexthopp)->next) { - if (*nexthopp == nexthop) - break; - } - assert(*nexthopp == nexthop); - - *nexthopp = nexthop->next; - - if (route->selected == nexthop) - route->selected = NULL; - - gp_babel_neigh_unref(nexthop->neigh); - free(nexthop); - - route->last_nexthop = gmrf_now(ctx->gmrf); -} - -static void maintain_nexthop(gmrf_context_t *ctx, gp_babel_route_t *route, gp_babel_nexthop_t *nexthop) { - if (!nexthop->neigh) /* local */ - return; - - if (nexthop_has_expired(ctx, nexthop)) { - gp_babel_route_nexthop_delete(ctx, route, nexthop); - return; - } - - if (gp_babel_since(ctx, nexthop->last_update) > GP_BABEL_UPDATE_REQUEST_TIMEOUT(nexthop->interval) - && route->selected == nexthop && !nexthop->requested_update) { - gmrf_logf(ctx->gmrf, LOG_INFO, "route about to expire, requesting update"); - gp_babel_send_route_request(ctx, NULL, nexthop->neigh, &route->node); - nexthop->requested_update = true; - } -} - -static void maintain_nexthops(gmrf_context_t *ctx, gp_babel_route_t *route) { - gp_babel_nexthop_t *nexthop, *next; - for (nexthop = route->nexthops; nexthop; nexthop = next) { - next = nexthop->next; - - maintain_nexthop(ctx, route, nexthop); - } -} static gp_babel_nexthop_t* select_nexthop(gmrf_context_t *ctx, const gp_babel_route_t *route) { uint16_t ret_metric = GP_BABEL_INFINITY; @@ -162,7 +118,7 @@ static gp_babel_nexthop_t* select_nexthop(gmrf_context_t *ctx, const gp_babel_ro return ret; } -gp_babel_metric_seqno_t get_metric(gmrf_context_t *ctx, const gp_babel_route_t *route) { +static gp_babel_metric_seqno_t get_metric(gmrf_context_t *ctx, const gp_babel_route_t *route) { if (route->selected) { uint32_t metric = route->selected->metric_seqno.metric + gp_babel_neigh_get_cost(ctx, route->selected->neigh); @@ -173,9 +129,7 @@ gp_babel_metric_seqno_t get_metric(gmrf_context_t *ctx, const gp_babel_route_t * return (gp_babel_metric_seqno_t){GP_BABEL_INFINITY, 0}; } -void gp_babel_route_update(gmrf_context_t *ctx, gp_babel_route_t *route) { - maintain_nexthops(ctx, route); - +static void update_nexthop(gmrf_context_t *ctx, gp_babel_route_t *route) { route->selected = select_nexthop(ctx, route); route->metric = get_metric(ctx, route); @@ -203,18 +157,74 @@ void gp_babel_route_update(gmrf_context_t *ctx, gp_babel_route_t *route) { } } -void gp_babel_route_update_nexthop(gmrf_context_t *ctx, gp_babel_route_t *route, gp_babel_nexthop_t *nexthop, gp_babel_metric_seqno_t ms, uint16_t interval) { - if (ms.metric == GP_BABEL_INFINITY) { - gmrf_logf(ctx->gmrf, LOG_DEBUG, "retract received, deleting nexthop"); - gp_babel_route_nexthop_delete(ctx, route, nexthop); - gp_babel_route_update(ctx, route); +static void delete_nexthop(gmrf_context_t *ctx, gp_babel_route_t *route, gp_babel_nexthop_t *nexthop) { + gp_babel_nexthop_t **nexthopp; + for (nexthopp = &route->nexthops; *nexthopp; nexthopp = &(*nexthopp)->next) { + if (*nexthopp == nexthop) + break; + } + assert(*nexthopp == nexthop); + + *nexthopp = nexthop->next; + + if (route->selected == nexthop) + route->selected = NULL; + + gp_babel_neigh_unref(nexthop->neigh); + free(nexthop); + + route->last_nexthop = gmrf_now(ctx->gmrf); +} + +void gp_babel_route_nexthop_delete(gmrf_context_t *ctx, gp_babel_route_t *route, gp_babel_nexthop_t *nexthop) { + delete_nexthop(ctx, route, nexthop); + + if (!route->selected) + gp_babel_route_maintain(ctx, route); +} + +static void maintain_nexthop(gmrf_context_t *ctx, gp_babel_route_t *route, gp_babel_nexthop_t *nexthop) { + if (!nexthop->neigh) /* local */ + return; + + if (nexthop_has_expired(ctx, nexthop)) { + delete_nexthop(ctx, route, nexthop); return; } - nexthop->metric_seqno = ms; - nexthop->interval = interval; - nexthop->requested_update = false; - nexthop->last_update = gmrf_now(ctx->gmrf); - - gp_babel_route_update(ctx, route); + if (gp_babel_since(ctx, nexthop->last_update) > GP_BABEL_UPDATE_REQUEST_TIMEOUT(nexthop->interval) + && route->selected == nexthop && !nexthop->requested_update) { + gmrf_logf(ctx->gmrf, LOG_INFO, "route about to expire, requesting update"); + gp_babel_send_route_request(ctx, NULL, nexthop->neigh, &route->node); + nexthop->requested_update = true; + } +} + +static void maintain_nexthops(gmrf_context_t *ctx, gp_babel_route_t *route) { + gp_babel_nexthop_t *nexthop, *next; + for (nexthop = route->nexthops; nexthop; nexthop = next) { + next = nexthop->next; + + maintain_nexthop(ctx, route, nexthop); + } +} + +void gp_babel_route_maintain(gmrf_context_t *ctx, gp_babel_route_t *route) { + maintain_nexthops(ctx, route); + update_nexthop(ctx, route); +} + +void gp_babel_route_update_nexthop(gmrf_context_t *ctx, gp_babel_route_t *route, gp_babel_nexthop_t *nexthop, gp_babel_metric_seqno_t ms, uint16_t interval) { + if (ms.metric == GP_BABEL_INFINITY) { + gmrf_logf(ctx->gmrf, LOG_DEBUG, "retract received, deleting nexthop"); + delete_nexthop(ctx, route, nexthop); + } + else { + nexthop->metric_seqno = ms; + nexthop->interval = interval; + nexthop->requested_update = false; + nexthop->last_update = gmrf_now(ctx->gmrf); + } + + gp_babel_route_maintain(ctx, route); } From b57074f83ea6163afe2525cd8b372cc8332635d7 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 23 Mar 2014 16:36:21 +0100 Subject: [PATCH 10/10] Don't handle "lost" routes when the route didn't have a selected nexthop before --- src/route.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/route.c b/src/route.c index fed699c..bffb4c7 100644 --- a/src/route.c +++ b/src/route.c @@ -130,6 +130,8 @@ static gp_babel_metric_seqno_t get_metric(gmrf_context_t *ctx, const gp_babel_ro } static void update_nexthop(gmrf_context_t *ctx, gp_babel_route_t *route) { + bool had_selected = route->selected; + route->selected = select_nexthop(ctx, route); route->metric = get_metric(ctx, route); @@ -139,9 +141,11 @@ static void update_nexthop(gmrf_context_t *ctx, gp_babel_route_t *route) { &route->selected->neigh->addr, route->metric.metric); } else { - gp_babel_send_seqno_request_for(ctx, NULL, route); + if (had_selected) { + gp_babel_send_seqno_request_for(ctx, NULL, route); - gmrf_debug_route_lost(ctx->gmrf, route->node.id, sizeof(gp_babel_node_id_t)); + gmrf_debug_route_lost(ctx->gmrf, route->node.id, sizeof(gp_babel_node_id_t)); + } } /* triggered updates */