diff options
Diffstat (limited to 'nest/rt-table.c')
-rw-r--r-- | nest/rt-table.c | 47 |
1 files changed, 24 insertions, 23 deletions
diff --git a/nest/rt-table.c b/nest/rt-table.c index b005f6f3..6851b4bc 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -837,7 +837,6 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src) struct proto *p = c->proto; struct rtable *table = c->table; struct proto_stats *stats = &c->stats; - static struct tbf rl_pipe = TBF_DEFAULT_LOG_LIMITS; struct rte_storage *old_best_stored = net->routes, *old_stored = NULL; rte *old_best = old_best_stored ? &old_best_stored->rte : NULL; rte *old = NULL; @@ -849,22 +848,22 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src) { old = &(old_stored = (*before_old))->rte; - /* If there is the same route in the routing table but from - * a different sender, then there are two paths from the - * source protocol to this routing table through transparent - * pipes, which is not allowed. - * - * We log that and ignore the route. If it is withdraw, we - * ignore it completely (there might be 'spurious withdraws', - * see FIXME in do_rte_announce()) - */ - if (old->sender->proto != p) - { - if (new) - log_rl(&rl_pipe, L_ERR "Pipe collision detected when sending %N to table %s", - net->n.addr, table->name); - return; - } + /* If there is the same route in the routing table but from + * a different sender, then there are two paths from the + * source protocol to this routing table through transparent + * pipes, which is not allowed. + * We log that and ignore the route. */ + if (old->sender->proto != p) + { + if (!old->generation && !new->generation) + bug("Two protocols claim to author a route with the same rte_src in table %s: %N %s/%u:%u", + c->table->name, net->n.addr, old->src->proto->name, old->src->private_id, old->src->global_id); + + log_rl(&table->rl_pipe, L_ERR "Route source collision in table %s: %N %s/%u:%u", + c->table->name, net->n.addr, old->src->proto->name, old->src->private_id, old->src->global_id); + + return; + } if (new && rte_same(old, new)) { @@ -875,14 +874,15 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src) if (!rte_is_filtered(new)) { stats->imp_updates_ignored++; - rte_trace_in(D_ROUTES, c, new, "ignored"); + rte_trace_in(D_ROUTES, c, new, "ignored"); } - return; - } + return; + } - *before_old = (*before_old)->next; - table->rt_count--; + + *before_old = (*before_old)->next; + table->rt_count--; } if (!old && !new) @@ -1128,7 +1128,6 @@ rte_update(struct channel *c, const net_addr *n, rte *new, struct rte_src *src) if (c->in_table && !rte_update_in(c, n, new, src)) return; - // struct proto *p = c->proto; struct proto_stats *stats = &c->stats; const struct filter *filter = c->in_filter; net *nn; @@ -1595,6 +1594,8 @@ rt_setup(pool *pp, struct rtable_config *cf) t->rt_event = ev_new_init(p, rt_event, t); t->last_rt_change = t->gc_time = current_time(); + + t->rl_pipe = (struct tbf) TBF_DEFAULT_LOG_LIMITS; } return t; |