summaryrefslogtreecommitdiff
path: root/nest/rt-table.c
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2013-06-13 11:27:14 +0200
committerOndrej Zajicek <santiago@crfreenet.org>2013-06-13 11:27:14 +0200
commitfad04c750ca6906fb095f1b45958dec0ac8e210c (patch)
tree7825e1113596653689591ce20ce69f4a01415c6d /nest/rt-table.c
parentf623ab9875cad2d129f708e95021d3a252930000 (diff)
Fixes problems with kernel routes multiple routing tables.
Temporary dummy routes created by a kernel protocol during routing table scan get mixed with real routes propagated from another kernel protocol through a pipe.
Diffstat (limited to 'nest/rt-table.c')
-rw-r--r--nest/rt-table.c31
1 files changed, 28 insertions, 3 deletions
diff --git a/nest/rt-table.c b/nest/rt-table.c
index e3fd985c..ebdac833 100644
--- a/nest/rt-table.c
+++ b/nest/rt-table.c
@@ -906,6 +906,26 @@ rte_update_unlock(void)
lp_flush(rte_update_pool);
}
+static inline void
+rte_hide_dummy_routes(net *net, rte **dummy)
+{
+ if (net->routes && net->routes->attrs->source == RTS_DUMMY)
+ {
+ *dummy = net->routes;
+ net->routes = (*dummy)->next;
+ }
+}
+
+static inline void
+rte_unhide_dummy_routes(net *net, rte **dummy)
+{
+ if (*dummy)
+ {
+ (*dummy)->next = net->routes;
+ net->routes = *dummy;
+ }
+}
+
/**
* rte_update - enter a new update to a routing table
* @table: table to be updated
@@ -955,6 +975,7 @@ rte_update2(struct announce_hook *ah, net *net, rte *new, struct proto *src)
struct proto_stats *stats = ah->stats;
struct filter *filter = ah->in_filter;
ea_list *tmpa = NULL;
+ rte *dummy = NULL;
rte_update_lock();
if (new)
@@ -1010,14 +1031,18 @@ rte_update2(struct announce_hook *ah, net *net, rte *new, struct proto *src)
else
stats->imp_withdraws_received++;
+ recalc:
+ rte_hide_dummy_routes(net, &dummy);
rte_recalculate(ah, net, new, tmpa, src);
+ rte_unhide_dummy_routes(net, &dummy);
rte_update_unlock();
return;
-drop:
+ drop:
rte_free(new);
- rte_recalculate(ah, net, NULL, NULL, src);
- rte_update_unlock();
+ new = NULL;
+ tmpa = NULL;
+ goto recalc;
}
/* Independent call to rte_announce(), used from next hop