diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f8c0a8a..64cda12 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,4 @@ include_directories(${GMRF_INCLUDE_DIR}) -set_directory_properties(PROPERTIES COMPILE_DEFINITIONS _GNU_SOURCE) add_library(mmss_proto_babel MODULE babel.c @@ -10,4 +9,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 COMPILE_FLAGS "-std=c99 -Wall" LINK_FLAGS "-Wl,--undefined=mmss_protocol_info") +set_target_properties(mmss_proto_babel PROPERTIES LINK_FLAGS "-Wl,--undefined=mmss_protocol_info") diff --git a/src/babel.c b/src/babel.c index 0fab0a7..3c0e219 100644 --- a/src/babel.c +++ b/src/babel.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2013-2014, Matthias Schiffer + Copyright (c) 2013, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without @@ -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 UNUSED) { +static void send_hellos(gmrf_context_t *ctx, void *arg) { 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 UNUSED) { +static void send_updates(gmrf_context_t *ctx, void *arg) { gmrf_schedule(ctx->gmrf, send_updates, NULL, GP_BABEL_UPDATE_INTERVAL*10); gmrf_logf(ctx->gmrf, LOG_DEBUG, "sending periodic updates."); @@ -68,7 +68,6 @@ 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; @@ -82,7 +81,6 @@ 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)); } } } @@ -93,13 +91,9 @@ static void maintain_routes(gmrf_context_t *ctx) { gp_babel_route_t *route = *cur; next = &route->next; - 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.", - ntohl(*(uint32_t*)route->node.id), ntohl(*(uint32_t*)(route->node.id+4)), - route->metric.metric, route->metric.seqno); + gp_babel_route_update(ctx, route); + if (!route->nexthops) { *cur = *next; next = cur; gp_babel_route_free(ctx, route); @@ -130,7 +124,7 @@ static void maintain_routes(gmrf_context_t *ctx) { } } -static void maintenance(gmrf_context_t *ctx, void *arg UNUSED) { +static void maintenance(gmrf_context_t *ctx, void *arg) { gmrf_schedule(ctx->gmrf, maintenance, NULL, GP_BABEL_MAINTENANCE_INTERVAL*10); maintain_neighbours(ctx); @@ -149,8 +143,6 @@ 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/babel.h b/src/babel.h index 27748a7..625b570 100644 --- a/src/babel.h +++ b/src/babel.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2013-2014, Matthias Schiffer + Copyright (c) 2013, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without @@ -45,7 +45,6 @@ #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 @@ -56,7 +55,6 @@ 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; @@ -69,6 +67,8 @@ struct gmrf_iface_state { gmrf_iface_t *gmrf_iface; + uint16_t seqno; + gp_babel_neigh_t *neighbours; }; @@ -103,8 +103,6 @@ struct gp_babel_route { gp_babel_nexthop_t *selected; gp_babel_nexthop_t *nexthops; - - gmrf_time_t last_nexthop; }; struct gp_babel_nexthop { @@ -134,12 +132,11 @@ 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_maintain(gmrf_context_t *ctx, gp_babel_route_t *route); +void gp_babel_route_update(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); 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 86f8189..b97540d 100644 --- a/src/neigh.c +++ b/src/neigh.c @@ -107,18 +107,5 @@ 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/packet.h b/src/packet.h index 0b89b56..09b6dc0 100644 --- a/src/packet.h +++ b/src/packet.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2013-2014, Matthias Schiffer + Copyright (c) 2013, 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 bffb4c7..db89896 100644 --- a/src/route.c +++ b/src/route.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2013-2014, Matthias Schiffer + Copyright (c) 2013, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without @@ -27,20 +27,18 @@ #include "babel.h" #include "neigh.h" -#include #include gp_babel_route_t* gp_babel_route_new(gmrf_context_t *ctx) { - gp_babel_route_t *route = calloc(1, sizeof(gp_babel_route_t)); + gp_babel_route_t *a = calloc(1, sizeof(gp_babel_route_t)); - route->metric.metric = route->feasibility_distance.metric = route->last_metric = GP_BABEL_INFINITY; - route->last_nexthop = gmrf_time_unspec; + a->metric.metric = a->feasibility_distance.metric = a->last_metric = GP_BABEL_INFINITY; - route->next = ctx->routes; - ctx->routes = route; + a->next = ctx->routes; + ctx->routes = a; - return route; + return a; } gp_babel_route_t* gp_babel_route_find(gmrf_context_t *ctx, const gp_babel_node_id_t *node) { @@ -64,7 +62,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 UNUSED, gp_babel_route_t *route) { +void gp_babel_route_free(gmrf_context_t *ctx, gp_babel_route_t *route) { free(route); } @@ -90,10 +88,53 @@ 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 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; + 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; + } + } + } +} static gp_babel_nexthop_t* select_nexthop(gmrf_context_t *ctx, const gp_babel_route_t *route) { uint16_t ret_metric = GP_BABEL_INFINITY; @@ -118,7 +159,7 @@ static gp_babel_nexthop_t* select_nexthop(gmrf_context_t *ctx, const gp_babel_ro return ret; } -static gp_babel_metric_seqno_t get_metric(gmrf_context_t *ctx, const gp_babel_route_t *route) { +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); @@ -129,106 +170,32 @@ static gp_babel_metric_seqno_t get_metric(gmrf_context_t *ctx, const gp_babel_ro return (gp_babel_metric_seqno_t){GP_BABEL_INFINITY, 0}; } -static void update_nexthop(gmrf_context_t *ctx, gp_babel_route_t *route) { - bool had_selected = route->selected; +void gp_babel_route_update(gmrf_context_t *ctx, gp_babel_route_t *route) { + maintain_nexthops(ctx, route); route->selected = select_nexthop(ctx, route); route->metric = get_metric(ctx, route); - 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 { - 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)); - } - } + if (!route->selected) + 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(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); - } -} - -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; - } - - 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); + 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); + } */ } 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; + if (ms.metric != GP_BABEL_INFINITY || nexthop->metric_seqno.metric != GP_BABEL_INFINITY) nexthop->last_update = gmrf_now(ctx->gmrf); - } - gp_babel_route_maintain(ctx, route); + nexthop->metric_seqno = ms; + nexthop->interval = interval; + nexthop->requested_update = false; + + gp_babel_route_update(ctx, route); } diff --git a/src/send.c b/src/send.c index f5734b5..e1c582f 100644 --- a/src/send.c +++ b/src/send.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2013-2014, Matthias Schiffer + Copyright (c) 2013, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without @@ -104,15 +104,13 @@ 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(ctx->hello_seqno); + hello->seqno = htons(iface->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) { diff --git a/src/tlv.c b/src/tlv.c index 94e6e04..d8a5be5 100644 --- a/src/tlv.c +++ b/src/tlv.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2013-2014, Matthias Schiffer + Copyright (c) 2013, 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 6208ae2..2cfd73d 100644 --- a/src/tlv.h +++ b/src/tlv.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2013-2014, Matthias Schiffer + Copyright (c) 2013, 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 2a20f5d..fd96e98 100644 --- a/src/tlv_types.c +++ b/src/tlv_types.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2013-2014, Matthias Schiffer + Copyright (c) 2013, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without @@ -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 UNUSED, size_t len, handle_tlv_arg_t *arg UNUSED) { +static void handle_tlv_ack(gmrf_context_t *ctx, const gp_babel_tlv_ack_t *tlv, size_t len, handle_tlv_arg_t *arg) { if (len < sizeof(gp_babel_tlv_ack_t)) { gmrf_logf(ctx->gmrf, LOG_WARNING, "received short acknowledement TLV."); return; @@ -111,7 +111,6 @@ 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) { @@ -140,7 +139,6 @@ 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) { diff --git a/src/tlv_types.h b/src/tlv_types.h index c859873..08a23b6 100644 --- a/src/tlv_types.h +++ b/src/tlv_types.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2013-2014, Matthias Schiffer + Copyright (c) 2013, 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 069e44a..0907232 100644 --- a/src/types.h +++ b/src/types.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2013-2014, Matthias Schiffer + Copyright (c) 2013, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without @@ -30,9 +30,6 @@ #include -#define UNUSED __attribute__((unused)) - - #define GP_BABEL_NODE_ID_LENGTH 8 typedef struct __attribute__((packed)) gp_gabel_node_id {