summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO3
-rw-r--r--nest/protocol.h2
-rw-r--r--nest/rt-table.c19
3 files changed, 21 insertions, 3 deletions
diff --git a/TODO b/TODO
index 7f478f2..ae0d53d 100644
--- a/TODO
+++ b/TODO
@@ -9,9 +9,6 @@ Core
- tagging of external routes?
-- when an identical route is received, don't trigger updates
-
-- configure: --enable-ipv6
- configure: IPv6 on glibc 2.0?
- Makefile: install target?
diff --git a/nest/protocol.h b/nest/protocol.h
index 2e64112..768792f 100644
--- a/nest/protocol.h
+++ b/nest/protocol.h
@@ -135,11 +135,13 @@ struct proto {
* Routing entry hooks (called only for rte's belonging to this protocol):
*
* rte_better Compare two rte's and decide which one is better (1=first, 0=second).
+ * rte_same Compare two rte's and decide whether they are identical (1=yes, 0=no).
* rte_insert Called whenever a rte is inserted to a routing table.
* rte_remove Called whenever a rte is removed from the routing table.
*/
int (*rte_better)(struct rte *, struct rte *);
+ int (*rte_same)(struct rte *, struct rte *);
void (*rte_insert)(struct network *, struct rte *);
void (*rte_remove)(struct network *, struct rte *);
diff --git a/nest/rt-table.c b/nest/rt-table.c
index 832e9ef..4214d07 100644
--- a/nest/rt-table.c
+++ b/nest/rt-table.c
@@ -272,6 +272,17 @@ rte_free_quick(rte *e)
sl_free(rte_slab, e);
}
+static int
+rte_same(rte *x, rte *y)
+{
+ return
+ x->attrs == y->attrs &&
+ x->flags == y->flags &&
+ x->pflags == y->pflags &&
+ x->pref == y->pref &&
+ (!x->attrs->proto->rte_same || x->attrs->proto->rte_same(x, y));
+}
+
static void
rte_recalculate(rtable *table, net *net, struct proto *p, rte *new, ea_list *tmpa)
{
@@ -284,6 +295,14 @@ rte_recalculate(rtable *table, net *net, struct proto *p, rte *new, ea_list *tmp
{
if (old->attrs->proto == p)
{
+ if (rte_same(old, new))
+ {
+ /* No changes, ignore the new route */
+ rte_trace_in(D_ROUTES, p, new, "ignored");
+ rte_free_quick(new);
+ old->lastmod = now;
+ return;
+ }
*k = old->next;
break;
}