summaryrefslogtreecommitdiff
path: root/proto/mrt/mrt.c
diff options
context:
space:
mode:
Diffstat (limited to 'proto/mrt/mrt.c')
-rw-r--r--proto/mrt/mrt.c93
1 files changed, 62 insertions, 31 deletions
diff --git a/proto/mrt/mrt.c b/proto/mrt/mrt.c
index 8d97c860..e12f7743 100644
--- a/proto/mrt/mrt.c
+++ b/proto/mrt/mrt.c
@@ -113,13 +113,13 @@ mrt_buffer_flush(buffer *b)
}
#define MRT_DEFINE_TYPE(S, T) \
- static inline void mrt_put_##S##_(buffer *b, T x) \
+ UNUSED static inline void mrt_put_##S##_(buffer *b, T x) \
{ \
put_##S(b->pos, x); \
b->pos += sizeof(T); \
} \
\
- static inline void mrt_put_##S(buffer *b, T x) \
+ UNUSED static inline void mrt_put_##S(buffer *b, T x) \
{ \
mrt_buffer_need(b, sizeof(T)); \
put_##S(b->pos, x); \
@@ -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;
}
@@ -460,7 +468,7 @@ mrt_rib_table_entry_bgp_attrs(struct mrt_table_dump_state *s, rte *r)
return;
fail:
- mrt_log(s, "Attribute list too long for %N", r->net->n.addr);
+ mrt_log(s, "Attribute list too long for %N", r->net);
}
#endif
@@ -472,9 +480,9 @@ mrt_rib_table_entry(struct mrt_table_dump_state *s, rte *r)
#ifdef CONFIG_BGP
/* Find peer index */
- if (r->attrs->src->proto->proto == &proto_bgp)
+ struct bgp_proto *p = bgp_rte_proto(r);
+ if (p)
{
- struct bgp_proto *p = (void *) r->attrs->src->proto;
struct mrt_peer_entry *n =
HASH_FIND(s->peer_hash, PEER, p->remote_id, p->remote_as, p->remote_ip);
@@ -488,7 +496,7 @@ mrt_rib_table_entry(struct mrt_table_dump_state *s, rte *r)
/* Path Identifier */
if (s->add_path)
- mrt_put_u32(b, r->attrs->src->private_id);
+ mrt_put_u32(b, r->src->private_id);
/* Route Attributes */
mrt_put_u16(b, 0);
@@ -512,26 +520,21 @@ mrt_rib_table_dump(struct mrt_table_dump_state *s, net *n, int add_path)
mrt_init_message(&s->buf, MRT_TABLE_DUMP_V2, subtype);
mrt_rib_table_header(s, n->n.addr);
- rte *rt, *rt0;
- for (rt0 = n->routes; rt = rt0; rt0 = rt0->next)
+ for (struct rte_storage *rt, *rt0 = n->routes; rt = rt0; rt0 = rt0->next)
{
- if (rte_is_filtered(rt))
+ if (rte_is_filtered(&rt->rte))
continue;
/* Skip routes that should be reported in the other phase */
- if (!s->always_add_path && (!rt->attrs->src->private_id != !s->add_path))
+ if (!s->always_add_path && (!rt->rte.src->private_id != !s->add_path))
{
s->want_add_path = 1;
continue;
}
- rte_make_tmp_attrs(&rt, s->linpool, NULL);
-
- if (f_run(s->filter, &rt, s->linpool, 0) <= F_ACCEPT)
- mrt_rib_table_entry(s, rt);
-
- if (rt != rt0)
- rte_free(rt);
+ rte e = rt->rte;
+ if (f_run(s->filter, &e, s->linpool, 0) <= F_ACCEPT)
+ mrt_rib_table_entry(s, &e);
lp_flush(s->linpool);
}
@@ -558,10 +561,11 @@ mrt_rib_table_dump(struct mrt_table_dump_state *s, net *n, int add_path)
static struct mrt_table_dump_state *
mrt_table_dump_init(pool *pp)
{
- pool *pool = rp_new(pp, "MRT Table Dump");
+ pool *pool = rp_new(pp, &main_birdloop, "MRT Table Dump");
struct mrt_table_dump_state *s = mb_allocz(pool, sizeof(struct mrt_table_dump_state));
s->pool = pool;
+ s->parent = pp;
s->linpool = lp_new(pool, 4080);
s->peer_lp = lp_new(pool, 4080);
mrt_buffer_init(&s->buf, pool, 2 * MRT_ATTR_BUFFER_SIZE);
@@ -578,18 +582,27 @@ 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);
- rfree(s->pool);
+ rp_free(s->pool, s->parent);
}
@@ -601,8 +614,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))
{
@@ -611,15 +630,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;
}
@@ -639,6 +661,7 @@ mrt_table_dump_step(struct mrt_table_dump_state *s)
mrt_peer_table_flush(s);
}
+ RT_UNLOCK(s->table);
return 1;
}
@@ -666,7 +689,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);
@@ -739,7 +766,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;