mirror of
https://gitlab.labs.nic.cz/labs/bird.git
synced 2024-05-11 16:54:54 +00:00
Nest: Route generations and explicit tracking route propagion through pipes
This commit is contained in:
@@ -111,7 +111,7 @@ proto_postconfig(void)
|
||||
|
||||
CF_DECLS
|
||||
|
||||
CF_KEYWORDS(ROUTER, ID, HOSTNAME, PROTOCOL, TEMPLATE, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT)
|
||||
CF_KEYWORDS(ROUTER, ID, HOSTNAME, PROTOCOL, TEMPLATE, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT, PIPE)
|
||||
CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, VRF, DEFAULT, TABLE, STATES, ROUTES, FILTERS)
|
||||
CF_KEYWORDS(IPV4, IPV6, VPN4, VPN6, ROA4, ROA6, FLOW4, FLOW6, SADR, MPLS)
|
||||
CF_KEYWORDS(RECEIVE, LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE, KEEP, FILTERED, RPKI)
|
||||
@@ -348,6 +348,7 @@ debug_default:
|
||||
DEBUG PROTOCOLS debug_mask { new_config->proto_default_debug = $3; }
|
||||
| DEBUG CHANNELS debug_mask { new_config->channel_default_debug = $3; }
|
||||
| DEBUG COMMANDS expr { new_config->cli_debug = $3; }
|
||||
| DEBUG PIPE bool { new_config->pipe_debug = $3; }
|
||||
;
|
||||
|
||||
/* MRTDUMP PROTOCOLS is in systep/unix/config.Y */
|
||||
|
||||
@@ -162,7 +162,6 @@ typedef struct rtable {
|
||||
char *name; /* Name of this table */
|
||||
list channels; /* List of attached channels (struct channel) */
|
||||
uint addr_type; /* Type of address data stored in table (NET_*) */
|
||||
int pipe_busy; /* Pipe loop detection */
|
||||
int use_count; /* Number of protocols using this table */
|
||||
u32 rt_count; /* Number of routes in the table */
|
||||
|
||||
@@ -185,6 +184,7 @@ typedef struct rtable {
|
||||
byte nhu_state; /* Next Hop Update state */
|
||||
struct fib_iterator prune_fit; /* Rtable prune FIB iterator */
|
||||
struct fib_iterator nhu_fit; /* Next Hop Update FIB iterator */
|
||||
struct tbf rl_pipe; /* Rate limiting token buffer for pipe collisions */
|
||||
|
||||
list subscribers; /* Subscribers for notifications */
|
||||
struct timer *settle_timer; /* Settle time for notifications */
|
||||
@@ -243,6 +243,9 @@ typedef struct rte {
|
||||
u32 id; /* Table specific route id */
|
||||
byte flags; /* Table-specific flags */
|
||||
byte pflags; /* Protocol-specific flags */
|
||||
u8 generation; /* If this route import is based on other previously exported route,
|
||||
this value should be 1 + MAX(generation of the parent routes).
|
||||
Otherwise the route is independent and this value is zero. */
|
||||
} rte;
|
||||
|
||||
struct rte_storage {
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user