summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2012-10-08 00:01:10 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2012-10-08 00:01:10 +0200
commita934dcc3ce78b22a0ff4db5d353a3d8dcc2b5f1d (patch)
treecba93f8f90b56a47d5537238198ea68476bbfe3e
parent5d538bb78e1820a807a8670cd3075757f2e115f0 (diff)
downloadffd-a934dcc3ce78b22a0ff4db5d353a3d8dcc2b5f1d.tar
ffd-a934dcc3ce78b22a0ff4db5d353a3d8dcc2b5f1d.zip
Purge old neigh and announce entries
-rw-r--r--ffd/announce.c31
-rw-r--r--ffd/ffd.c56
-rw-r--r--ffd/ffd.h2
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;