diff options
-rw-r--r-- | ffd/ffd.c | 37 | ||||
-rw-r--r-- | ffd/ffd.h | 9 | ||||
-rw-r--r-- | ffd/neigh.c | 11 | ||||
-rw-r--r-- | ffd/neigh.h | 1 | ||||
-rw-r--r-- | ffd/util.h | 4 |
5 files changed, 50 insertions, 12 deletions
@@ -215,7 +215,7 @@ static void handle_tlv_hello(const ffd_tlv_hello_t *tlv_hello, size_t len, handl uint16_t seqno = ntohs(tlv_hello->seqno); if (neigh->last_hello.tv_sec) { - int timediff = timespec_diff(&now, &neigh->last_hello)/10; + int timediff = timespec_diff(&now, &neigh->last_hello); uint16_t seqexp = neigh->last_seqno + (timediff - neigh->hello_interval/2)/neigh->hello_interval; /* cast to int16_t to ensure correct handling of seqno wrapping */ @@ -268,10 +268,11 @@ static void handle_tlv_ihu(const ffd_tlv_ihu_t *tlv_ihu, size_t len, handle_tlv_ } ffd_neigh_t *neigh = get_tlv_neigh(arg); + neigh->ihu_interval = ntohs(tlv_ihu->interval); neigh->last_ihu = now; neigh->txcost = ntohs(tlv_ihu->rxcost); - fprintf(stderr, "debug: accepted IHU, txcost is %u, cost is %u now.\n", neigh->txcost, ffd_neigh_get_cost(neigh)); + fprintf(stderr, "debug: accepted IHU, txcost is %u, cost is %u now.\n", ffd_neigh_get_txcost(neigh), ffd_neigh_get_cost(neigh)); } static void handle_tlv_node_id(const ffd_tlv_node_id_t *tlv_node_id, size_t len, handle_tlv_arg_t *arg) { @@ -470,6 +471,19 @@ static void send_updates(void) { } } +static void maintenance(void) { + ffd_iface_t *iface; + for (iface = iface_list; iface; iface = iface->next) { + ffd_neigh_t *neigh; + for (neigh = iface->neigh_list; neigh; neigh = neigh->next) { + fprintf(stderr, "debug: maintenance: %02x:%02x:%02x:%02x:%02x:%02x[%s]: %u (rx %u/tx %u)\n", + neigh->addr.d[0], neigh->addr.d[1], neigh->addr.d[2], + neigh->addr.d[3], neigh->addr.d[4], neigh->addr.d[5], + iface->name, ffd_neigh_get_cost(neigh), ffd_neigh_get_rxcost(neigh), ffd_neigh_get_txcost(neigh)); + } + } +} + int main() { if (!check_config()) return 1; @@ -484,34 +498,43 @@ int main() { struct timespec next_hello = now; struct timespec next_update = now; + struct timespec next_maintenance = now; while (true) { update_netifs(); int hello_timeout = timespec_diff(&next_hello, &now); - int update_timeout = timespec_diff(&next_update, &now); - if (hello_timeout <= 0) { ffd_send_hellos(); add_interval(&next_hello, FFD_HELLO_INTERVAL); - continue; } + int update_timeout = timespec_diff(&next_update, &now); if (update_timeout <= 0) { fprintf(stderr, "Sending periodic update.\n"); send_updates(); add_interval(&next_update, FFD_UPDATE_INTERVAL); - continue; } + int maintenance_timeout = timespec_diff(&next_maintenance, &now); + if (maintenance_timeout <= 0) { + maintenance(); + + add_interval(&next_maintenance, FFD_MAINTENANCE_INTERVAL); + } + + int timeout = min(min(hello_timeout, update_timeout), maintenance_timeout); + if (timeout <= 0) + continue; + struct pollfd fds[1]; fds[0].fd = sockfd; fds[0].events = POLLIN; - poll(fds, 1, min(hello_timeout, update_timeout)); + poll(fds, 1, 10*timeout); update_time(); @@ -39,9 +39,14 @@ #define FFD_HELLO_INTERVAL 400 #define FFD_IHU_INTERVAL (3*FFD_HELLO_INTERVAL) - #define FFD_UPDATE_INTERVAL 6000 +#define FFD_HELLO_TIMEOUT(interval) (16*(interval)) +#define FFD_IHU_TIMEOUT(interval) ((interval)*7/2) +#define FFD_UPDATE_TIMEOUT(interval) ((interval)*7/2) + +#define FFD_MAINTENANCE_INTERVAL FFD_HELLO_INTERVAL + #define FFD_UPDATE_WITH_DATA 0x01 @@ -94,6 +99,8 @@ typedef struct _ffd_neigh_t { uint16_t hello_interval; uint16_t last_seqno; struct timespec last_hello; + + uint16_t ihu_interval; struct timespec last_ihu; uint16_t txcost; diff --git a/ffd/neigh.c b/ffd/neigh.c index 02a3318..74ff1b5 100644 --- a/ffd/neigh.c +++ b/ffd/neigh.c @@ -53,7 +53,7 @@ uint16_t ffd_neigh_get_rxcost(const ffd_neigh_t *neigh) { if (!neigh->hello_log || !neigh->hello_interval) return 0xffff; - int timediff = timespec_diff(&now, &neigh->last_hello)/10; + int timediff = timespec_diff(&now, &neigh->last_hello); int shift = (timediff - neigh->hello_interval/2)/neigh->hello_interval; int received = __builtin_popcount(neigh->hello_log << shift); @@ -63,11 +63,18 @@ uint16_t ffd_neigh_get_rxcost(const ffd_neigh_t *neigh) { return (0x1000/received); } +uint16_t ffd_neigh_get_txcost(const ffd_neigh_t *neigh) { + if (timespec_diff(&now, &neigh->last_ihu) > FFD_IHU_TIMEOUT(neigh->ihu_interval)) + return 0xffff; + else + return neigh->txcost; +} + uint16_t ffd_neigh_get_cost(const ffd_neigh_t *neigh) { if (!neigh) /* self */ return 0; - uint16_t txcost = neigh->txcost; + uint16_t txcost = ffd_neigh_get_txcost(neigh); if (txcost < 256) txcost = 256; diff --git a/ffd/neigh.h b/ffd/neigh.h index 6874dbe..d82025c 100644 --- a/ffd/neigh.h +++ b/ffd/neigh.h @@ -44,6 +44,7 @@ ffd_neigh_t* ffd_neigh_get(ffd_iface_t *iface, const eth_addr_t *addr); void ffd_neigh_free_list(ffd_neigh_t *neigh); uint16_t ffd_neigh_get_rxcost(const ffd_neigh_t *neigh); +uint16_t ffd_neigh_get_txcost(const ffd_neigh_t *neigh); uint16_t ffd_neigh_get_cost(const ffd_neigh_t *neigh); void ffd_neigh_reset(ffd_iface_t *iface, ffd_neigh_t *neigh); @@ -53,9 +53,9 @@ static inline bool are_eth_addrs_equal(const eth_addr_t *address1, const eth_add return (a[0]==b[0] && a[1]==b[1] && a[2]==b[2] && a[3]==b[3] && a[4]==b[4] && a[5]==b[5]); } -/* returns (tp1 - tp2) in milliseconds */ +/* returns (tp1 - tp2) in centiseconds */ static inline int timespec_diff(const struct timespec *tp1, const struct timespec *tp2) { - return ((tp1->tv_sec - tp2->tv_sec))*1000 + (tp1->tv_nsec - tp2->tv_nsec)/1e6; + return ((tp1->tv_sec - tp2->tv_sec))*100 + (tp1->tv_nsec - tp2->tv_nsec)/1e7; } static inline int max(int a, int b) { |