summaryrefslogtreecommitdiff
path: root/proto
diff options
context:
space:
mode:
authorMaria Matejka <mq@ucw.cz>2021-09-29 16:15:13 +0200
committerMaria Matejka <mq@ucw.cz>2021-11-22 19:05:44 +0100
commit878eeec12bf020c9e7460040d225a929bbbd2bd2 (patch)
treee60ffcdbcf26972912271aba2353c572f02c679f /proto
parentc7d0c5b2523a8cbfcaee9a235955dd5e58fab671 (diff)
Routing tables now have their own loops.
This basically means that: * there are some more levels of indirection and asynchronicity, mostly in cleanup procedures, requiring correct lock ordering * all the internal table operations (prune, next hop update) are done without blocking the other parts of BIRD * the protocols may get their own loops very soon
Diffstat (limited to 'proto')
-rw-r--r--proto/bgp/attrs.c2
-rw-r--r--proto/bgp/bgp.c12
-rw-r--r--proto/bgp/bgp.h2
-rw-r--r--proto/mrt/mrt.c59
-rw-r--r--proto/mrt/mrt.h6
-rw-r--r--proto/perf/perf.c4
-rw-r--r--proto/radv/radv.c5
-rw-r--r--proto/static/static.c12
8 files changed, 75 insertions, 27 deletions
diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c
index 9b9013f9..1080db77 100644
--- a/proto/bgp/attrs.c
+++ b/proto/bgp/attrs.c
@@ -2140,7 +2140,7 @@ use_deterministic_med(struct rte_storage *r)
}
int
-bgp_rte_recalculate(rtable *table, net *net, rte *new, rte *old, rte *old_best)
+bgp_rte_recalculate(rtable_private *table, net *net, rte *new, rte *old, rte *old_best)
{
rte *key = new ? new : old;
u32 lpref = key->attrs->pref;
diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c
index dc845550..aac1f45c 100644
--- a/proto/bgp/bgp.c
+++ b/proto/bgp/bgp.c
@@ -1800,10 +1800,12 @@ bgp_channel_start(struct channel *C)
ip_addr src = p->local_ip;
if (c->igp_table_ip4)
- rt_lock_table(c->igp_table_ip4);
+ RT_LOCKED(c->igp_table_ip4, t)
+ rt_lock_table(t);
if (c->igp_table_ip6)
- rt_lock_table(c->igp_table_ip6);
+ RT_LOCKED(c->igp_table_ip6, t)
+ rt_lock_table(t);
c->pool = p->p.pool; // XXXX
bgp_init_bucket_table(c);
@@ -1884,10 +1886,12 @@ bgp_channel_cleanup(struct channel *C)
struct bgp_channel *c = (void *) C;
if (c->igp_table_ip4)
- rt_unlock_table(c->igp_table_ip4);
+ RT_LOCKED(c->igp_table_ip4, t)
+ rt_unlock_table(t);
if (c->igp_table_ip6)
- rt_unlock_table(c->igp_table_ip6);
+ RT_LOCKED(c->igp_table_ip6, t)
+ rt_unlock_table(t);
c->index = 0;
diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h
index 7cb4df1f..60f93bce 100644
--- a/proto/bgp/bgp.h
+++ b/proto/bgp/bgp.h
@@ -586,7 +586,7 @@ void bgp_free_prefix(struct bgp_channel *c, struct bgp_prefix *bp);
int bgp_rte_better(struct rte *, struct rte *);
int bgp_rte_mergable(rte *pri, rte *sec);
-int bgp_rte_recalculate(rtable *table, net *net, rte *new, rte *old, rte *old_best);
+int bgp_rte_recalculate(rtable_private *table, net *net, rte *new, rte *old, rte *old_best);
void bgp_rte_modify_stale(struct rt_export_request *, const net_addr *, struct rt_pending_export *, rte **, uint);
u32 bgp_rte_igp_metric(struct rte *);
void bgp_rt_notify(struct proto *P, struct channel *C, const net_addr *n, rte *new, const rte *old);
diff --git a/proto/mrt/mrt.c b/proto/mrt/mrt.c
index 9d78438d..b40592d2 100644
--- a/proto/mrt/mrt.c
+++ b/proto/mrt/mrt.c
@@ -228,7 +228,7 @@ mrt_next_table_(rtable *tab, rtable *tab_ptr, const char *pattern)
NODE_VALID(tn);
tn = tn->next)
{
- tab = SKIP_BACK(struct rtable, n, tn);
+ tab = SKIP_BACK(rtable, n, tn);
if (patmatch(pattern, tab->name) &&
((tab->addr_type == NET_IP4) || (tab->addr_type == NET_IP6)))
return tab;
@@ -243,13 +243,21 @@ mrt_next_table(struct mrt_table_dump_state *s)
rtable *tab = mrt_next_table_(s->table, s->table_ptr, s->table_expr);
if (s->table)
- rt_unlock_table(s->table);
+ {
+ RT_LOCK(s->table);
+ rt_unlock_table(RT_PRIV(s->table));
+ RT_UNLOCK(s->table);
+ }
s->table = tab;
s->ipv4 = tab ? (tab->addr_type == NET_IP4) : 0;
if (s->table)
- rt_lock_table(s->table);
+ {
+ RT_LOCK(s->table);
+ rt_lock_table(RT_PRIV(s->table));
+ RT_UNLOCK(s->table);
+ }
return s->table;
}
@@ -573,14 +581,23 @@ mrt_table_dump_init(pool *pp)
static void
mrt_table_dump_free(struct mrt_table_dump_state *s)
{
- if (s->table_open)
- FIB_ITERATE_UNLINK(&s->fit, &s->table->fib);
-
if (s->table)
- rt_unlock_table(s->table);
+ {
+ RT_LOCK(s->table);
+
+ if (s->table_open)
+ FIB_ITERATE_UNLINK(&s->fit, &RT_PRIV(s->table)->fib);
+
+ rt_unlock_table(RT_PRIV(s->table));
+ RT_UNLOCK(s->table);
+ }
if (s->table_ptr)
- rt_unlock_table(s->table_ptr);
+ {
+ RT_LOCK(s->table_ptr);
+ rt_unlock_table(RT_PRIV(s->table_ptr));
+ RT_UNLOCK(s->table_ptr);
+ }
config_del_obstacle(s->config);
@@ -596,8 +613,14 @@ mrt_table_dump_step(struct mrt_table_dump_state *s)
s->max = 2048;
s->bws = &bws;
+ rtable_private *tab;
+
if (s->table_open)
+ {
+ RT_LOCK(s->table);
+ tab = RT_PRIV(s->table);
goto step;
+ }
while (mrt_next_table(s))
{
@@ -606,15 +629,18 @@ mrt_table_dump_step(struct mrt_table_dump_state *s)
mrt_peer_table_dump(s);
- FIB_ITERATE_INIT(&s->fit, &s->table->fib);
+ RT_LOCK(s->table);
+ tab = RT_PRIV(s->table);
+ FIB_ITERATE_INIT(&s->fit, &tab->fib);
s->table_open = 1;
step:
- FIB_ITERATE_START(&s->table->fib, &s->fit, net, n)
+ FIB_ITERATE_START(&tab->fib, &s->fit, net, n)
{
if (s->max < 0)
{
FIB_ITERATE_PUT(&s->fit);
+ RT_UNLOCK(s->table);
return 0;
}
@@ -634,6 +660,7 @@ mrt_table_dump_step(struct mrt_table_dump_state *s)
mrt_peer_table_flush(s);
}
+ RT_UNLOCK(s->table);
return 1;
}
@@ -661,7 +688,11 @@ mrt_timer(timer *t)
s->always_add_path = cf->always_add_path;
if (s->table_ptr)
- rt_lock_table(s->table_ptr);
+ {
+ RT_LOCK(s->table_ptr);
+ rt_lock_table(RT_PRIV(s->table_ptr));
+ RT_UNLOCK(s->table_ptr);
+ }
p->table_dump = s;
ev_schedule(p->event);
@@ -734,7 +765,11 @@ mrt_dump_cmd(struct mrt_dump_data *d)
s->filename = d->filename;
if (s->table_ptr)
- rt_lock_table(s->table_ptr);
+ {
+ RT_LOCK(s->table_ptr);
+ rt_lock_table(RT_PRIV(s->table_ptr));
+ RT_UNLOCK(s->table_ptr);
+ }
this_cli->cont = mrt_dump_cont;
this_cli->cleanup = mrt_dump_cleanup;
diff --git a/proto/mrt/mrt.h b/proto/mrt/mrt.h
index 4ff94c12..04865089 100644
--- a/proto/mrt/mrt.h
+++ b/proto/mrt/mrt.h
@@ -40,7 +40,7 @@ struct mrt_proto {
struct mrt_dump_data {
const char *table_expr;
- struct rtable *table_ptr;
+ rtable *table_ptr;
const struct filter *filter;
const char *filename;
};
@@ -60,7 +60,7 @@ struct mrt_table_dump_state {
/* Configuration information */
const char *table_expr; /* Wildcard for table name (or NULL) */
- struct rtable *table_ptr; /* Explicit table (or NULL) */
+ rtable *table_ptr; /* Explicit table (or NULL) */
const struct filter *filter; /* Optional filter */
const char *filename; /* Filename pattern */
int always_add_path; /* Always use *_ADDPATH message subtypes */
@@ -73,7 +73,7 @@ struct mrt_table_dump_state {
HASH(struct mrt_peer_entry) peer_hash; /* Hash for peers to find the index */
- struct rtable *table; /* Processed table, NULL initially */
+ rtable *table; /* Processed table, NULL initially */
struct fib_iterator fit; /* Iterator in processed table */
int table_open; /* Whether iterator is linked */
diff --git a/proto/perf/perf.c b/proto/perf/perf.c
index 8b2cb69f..aa688d88 100644
--- a/proto/perf/perf.c
+++ b/proto/perf/perf.c
@@ -198,7 +198,9 @@ perf_loop(void *data)
p->exp++;
}
- rt_schedule_prune(P->main_channel->table);
+ RT_LOCK(P->main_channel->table);
+ rt_schedule_prune(RT_PRIV(P->main_channel->table));
+ RT_UNLOCK(P->main_channel->table);
ev_schedule(p->loop);
}
diff --git a/proto/radv/radv.c b/proto/radv/radv.c
index fa228c69..d572c1b7 100644
--- a/proto/radv/radv.c
+++ b/proto/radv/radv.c
@@ -555,7 +555,10 @@ radv_check_active(struct radv_proto *p)
return 1;
struct channel *c = p->p.main_channel;
- return rt_examine(c->table, &cf->trigger, c, c->out_filter);
+ RT_LOCK(c->table);
+ int active = rt_examine(RT_PRIV(c->table), &cf->trigger, c, c->out_filter);
+ RT_UNLOCK(c->table);
+ return active;
}
static void
diff --git a/proto/static/static.c b/proto/static/static.c
index 45791e8e..bd7f3f5b 100644
--- a/proto/static/static.c
+++ b/proto/static/static.c
@@ -491,10 +491,12 @@ static_start(struct proto *P)
static_lp = lp_new(&root_pool, LP_GOOD_SIZE(1024));
if (p->igp_table_ip4)
- rt_lock_table(p->igp_table_ip4);
+ RT_LOCKED(p->igp_table_ip4, t)
+ rt_lock_table(t);
if (p->igp_table_ip6)
- rt_lock_table(p->igp_table_ip6);
+ RT_LOCKED(p->igp_table_ip6, t)
+ rt_lock_table(t);
p->event = ev_new_init(p->p.pool, static_announce_marked, p);
@@ -521,10 +523,12 @@ static_shutdown(struct proto *P)
static_reset_rte(p, r);
if (p->igp_table_ip4)
- rt_unlock_table(p->igp_table_ip4);
+ RT_LOCKED(p->igp_table_ip4, t)
+ rt_unlock_table(t);
if (p->igp_table_ip6)
- rt_unlock_table(p->igp_table_ip6);
+ RT_LOCKED(p->igp_table_ip6, t)
+ rt_unlock_table(t);
return PS_DOWN;
}