From a934dcc3ce78b22a0ff4db5d353a3d8dcc2b5f1d Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 8 Oct 2012 00:01:10 +0200 Subject: Purge old neigh and announce entries --- ffd/announce.c | 31 +++++++++++++++++++++++++++++++ ffd/ffd.c | 56 ++++++++++++++++++++++++++++++++++++++++---------------- ffd/ffd.h | 2 ++ 3 files changed, 73 insertions(+), 16 deletions(-) diff --git a/ffd/announce.c b/ffd/announce.c index 99bf1aa..6b30ec6 100644 --- a/ffd/announce.c +++ b/ffd/announce.c @@ -28,6 +28,35 @@ #include "neigh.h" +static void maintain_nexthops(ffd_announce_t *announce) { + ffd_nexthop_t **cur, **next; + for (cur = &announce->nexthop_list; *cur; cur = next) { + ffd_nexthop_t *nexthop = *cur; + next = &nexthop->next; + + if (!nexthop->neigh) /* local */ + continue; + + if (timespec_diff(&now, &nexthop->last_update) > FFD_UPDATE_TIMEOUT(nexthop->interval)) { + if (nexthop->metric_seqno.metric == 0xffff) { + *cur = *next; + next = cur; + + if (announce->selected == nexthop) + announce->selected = NULL; + + nexthop->neigh->nexthop_refs--; + + free(nexthop); + } + else { + nexthop->metric_seqno.metric = 0xffff; + add_interval(&nexthop->last_update, FFD_UPDATE_TIMEOUT(nexthop->interval)); + } + } + } +} + static ffd_nexthop_t* select_nexthop(const ffd_announce_t *announce) { uint16_t ret_metric = 0xffff; ffd_nexthop_t *ret = NULL; @@ -63,6 +92,8 @@ ffd_metric_seqno_t get_metric(const ffd_announce_t *announce) { } void ffd_announce_update(ffd_announce_t *announce) { + maintain_nexthops(announce); + announce->selected = select_nexthop(announce); announce->metric = get_metric(announce); } diff --git a/ffd/ffd.c b/ffd/ffd.c index ee1e3ea..7cc3d3f 100644 --- a/ffd/ffd.c +++ b/ffd/ffd.c @@ -320,6 +320,8 @@ static ffd_nexthop_t* new_nexthop(ffd_announce_t *announce, ffd_neigh_t *neigh) nexthop->next = announce->nexthop_list; announce->nexthop_list = nexthop; + neigh->nexthop_refs++; + return nexthop; } @@ -475,8 +477,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) { + ffd_neigh_t **cur, **next; + for (cur = &iface->neigh_list; *cur; cur = next) { + ffd_neigh_t *neigh = *cur; + next = &neigh->next; + + if (ffd_neigh_get_rxcost(neigh) == 0xffff && ffd_neigh_get_txcost(neigh) == 0xffff && !neigh->nexthop_refs) { + *cur = *next; + next = cur; + free(neigh); + + continue; + } + 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], @@ -484,28 +497,39 @@ static void maintenance(void) { } } - ffd_announce_t *announce; - for (announce = announce_list; announce; announce = announce->next) { + ffd_announce_t **cur, **next; + for (cur = &announce_list; *cur; cur = next) { + ffd_announce_t *announce = *cur; + next = &announce->next; + ffd_announce_update(announce); - fprintf(stderr, "debug: maintenance: node %04x%04x, type %04x, announce %04x: ", ntohl(*(uint32_t*)announce->node.id), ntohl(*(uint32_t*)(announce->node.id+4)), announce->type, announce->key); + if (!announce->nexthop_list) { + *cur = *next; + next = cur; + free(announce); - if (!announce->selected) { - fprintf(stderr, "nexthop: none\n"); continue; } - ffd_neigh_t *neigh = announce->selected->neigh; + fprintf(stderr, "debug: node %04x%04x, type %04x, announce %04x (%u, seqno=%04x):\n", + ntohl(*(uint32_t*)announce->node.id), ntohl(*(uint32_t*)(announce->node.id+4)), announce->type, announce->key, announce->metric.metric, announce->metric.seqno); - if (!neigh) { - fprintf(stderr, "local\n"); - continue; - } + ffd_nexthop_t *nexthop; + for (nexthop = announce->nexthop_list; nexthop; nexthop = nexthop->next) { + ffd_neigh_t *neigh = nexthop->neigh; + + if (!neigh) { + fprintf(stderr, "\tlocal\n"); + continue; + } - fprintf(stderr, "nexthop: %02x:%02x:%02x:%02x:%02x:%02x (%u, seqno=%04x)\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], - announce->metric.metric, announce->metric.seqno); + fprintf(stderr, "\tnexthop: %02x:%02x:%02x:%02x:%02x:%02x (%u, seqno=%04x, cost=%u%s)\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], + nexthop->metric_seqno.metric, nexthop->metric_seqno.seqno, ffd_neigh_get_cost(neigh), + (nexthop == announce->selected) ? ", selected" : ""); + } } } diff --git a/ffd/ffd.h b/ffd/ffd.h index fa2c378..9bd0d2c 100644 --- a/ffd/ffd.h +++ b/ffd/ffd.h @@ -91,6 +91,8 @@ typedef struct _ffd_announce_t { typedef struct _ffd_neigh_t { struct _ffd_neigh_t *next; + unsigned nexthop_refs; + /* for actual routing, we'd also have to link back to the iface this neighbour belongs to */ eth_addr_t addr; -- cgit v1.2.3