summaryrefslogtreecommitdiff
path: root/proto
diff options
context:
space:
mode:
Diffstat (limited to 'proto')
-rw-r--r--proto/bfd/bfd.c1
-rw-r--r--proto/bgp/attrs.c70
-rw-r--r--proto/bgp/bgp.c6
-rw-r--r--proto/bgp/bgp.h2
-rw-r--r--proto/mrt/mrt.c39
-rw-r--r--proto/mrt/mrt.h6
-rw-r--r--proto/perf/perf.c4
-rw-r--r--proto/rip/rip.c18
-rw-r--r--proto/static/static.c4
9 files changed, 89 insertions, 61 deletions
diff --git a/proto/bfd/bfd.c b/proto/bfd/bfd.c
index e7d27f74..331ba730 100644
--- a/proto/bfd/bfd.c
+++ b/proto/bfd/bfd.c
@@ -113,7 +113,6 @@
#define HASH_IP_EQ(a1,n1,a2,n2) ipa_equal(a1, a2) && n1 == n2
#define HASH_IP_FN(a,n) ipa_hash(a) ^ u32_hash(n)
-DEFINE_DOMAIN(rtable);
#define BFD_LOCK LOCK_DOMAIN(rtable, bfd_global.lock)
#define BFD_UNLOCK UNLOCK_DOMAIN(rtable, bfd_global.lock)
diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c
index 2543ee73..bfdd9ac5 100644
--- a/proto/bgp/attrs.c
+++ b/proto/bgp/attrs.c
@@ -1867,25 +1867,30 @@ bgp_free_pending_tx(struct bgp_channel *c)
* Prefix hash table exporter
*/
+struct bgp_out_export_hook {
+ struct rt_export_hook h;
+ u32 hash_iter; /* Iterator over hash */
+};
+
static void
bgp_out_table_feed(void *data)
{
- struct rt_export_hook *hook = data;
- struct bgp_channel *bc = SKIP_BACK(struct bgp_channel, prefix_exporter, hook->table);
+ struct bgp_out_export_hook *hook = data;
+ struct bgp_channel *bc = SKIP_BACK(struct bgp_channel, prefix_exporter, hook->h.table);
struct bgp_pending_tx *c = bc->ptx;
int max = 512;
- const net_addr *neq = (hook->req->addr_mode == TE_ADDR_EQUAL) ? hook->req->addr : NULL;
+ const net_addr *neq = (hook->h.req->addr_mode == TE_ADDR_EQUAL) ? hook->h.req->addr : NULL;
const net_addr *cand = NULL;
do {
HASH_WALK_ITER(c->prefix_hash, PXH, n, hook->hash_iter)
{
- switch (hook->req->addr_mode)
+ switch (hook->h.req->addr_mode)
{
case TE_ADDR_IN:
- if (!net_in_netX(n->net, hook->req->addr))
+ if (!net_in_netX(n->net, hook->h.req->addr))
continue;
/* fall through */
case TE_ADDR_NONE:
@@ -1897,7 +1902,7 @@ bgp_out_table_feed(void *data)
case TE_ADDR_FOR:
if (!neq)
{
- if (net_in_netX(hook->req->addr, n->net) && (!cand || (n->net->length > cand->length)))
+ if (net_in_netX(hook->h.req->addr, n->net) && (!cand || (n->net->length > cand->length)))
cand = n->net;
continue;
}
@@ -1942,13 +1947,13 @@ bgp_out_table_feed(void *data)
.new = &es, .new_best = &es,
};
- if (hook->req->export_bulk)
+ if (hook->h.req->export_bulk)
{
rte *feed = &es.rte;
- hook->req->export_bulk(hook->req, n->net, &rpe, &feed, 1);
+ hook->h.req->export_bulk(hook->h.req, n->net, &rpe, &feed, 1);
}
- else if (hook->req->export_one)
- hook->req->export_one(hook->req, n->net, &rpe);
+ else if (hook->h.req->export_one)
+ hook->h.req->export_one(hook->h.req, n->net, &rpe);
else
bug("No export method in export request");
}
@@ -1959,36 +1964,51 @@ bgp_out_table_feed(void *data)
} while (neq);
if (hook->hash_iter)
- ev_schedule_work(hook->event);
+ ev_schedule_work(&hook->h.event);
else
- rt_set_export_state(hook, TES_READY);
+ rt_set_export_state(&hook->h, TES_READY);
}
-static struct rt_export_hook *
-bgp_out_table_export_start(struct rt_exporter *re, struct rt_export_request *req UNUSED)
+static void
+bgp_out_table_export_start(struct rt_exporter *re, struct rt_export_request *req)
{
- struct bgp_channel *bc = SKIP_BACK(struct bgp_channel, prefix_exporter, re);
- pool *p = rp_new(bc->c.proto->pool, "Export hook");
- struct rt_export_hook *hook = mb_allocz(p, sizeof(struct rt_export_hook));
- hook->pool = p;
- hook->event = ev_new_init(p, bgp_out_table_feed, hook);
- hook->feed_type = TFT_HASH;
+ req->hook = rt_alloc_export(re, sizeof(struct bgp_out_export_hook));
+ req->hook->req = req;
- return hook;
+ struct bgp_out_export_hook *hook = SKIP_BACK(struct bgp_out_export_hook, h, req->hook);
+
+ hook->h.event.hook = bgp_out_table_feed;
+ rt_init_export(re, req->hook);
}
+static void
+bgp_out_table_export_done(void *data)
+{
+ struct bgp_out_export_hook *hook = data;
+ struct rt_export_request *req = hook->h.req;
+ void (*stopped)(struct rt_export_request *) = hook->h.stopped;
+
+ rt_export_stopped(&hook->h);
+ CALL(stopped, req);
+}
+
+static const struct rt_exporter_class bgp_out_table_export_class = {
+ .start = bgp_out_table_export_start,
+ .done = bgp_out_table_export_done,
+};
+
void
bgp_setup_out_table(struct bgp_channel *c)
{
ASSERT_DIE(c->c.out_table == NULL);
c->prefix_exporter = (struct rt_exporter) {
+ .class = &bgp_out_table_export_class,
.addr_type = c->c.table->addr_type,
- .start = bgp_out_table_export_start,
+ .rp = c->c.proto->pool,
};
- init_list(&c->prefix_exporter.hooks);
- init_list(&c->prefix_exporter.pending);
+ rt_exporter_init(&c->prefix_exporter);
c->c.out_table = &c->prefix_exporter;
}
@@ -2510,7 +2530,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(struct rtable_private *table, net *net, rte *new, rte *old, rte *old_best)
{
rte *key = new ? new : old;
u32 lpref = rt_get_preference(key);
diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c
index 68c788ea..573e3d25 100644
--- a/proto/bgp/bgp.c
+++ b/proto/bgp/bgp.c
@@ -847,7 +847,7 @@ bgp_graceful_restart_feed(struct bgp_channel *c)
.export_one = bgp_graceful_restart_drop_export,
};
- rt_request_export(&c->c.table->exporter, &c->stale_feed);
+ rt_request_export(c->c.table, &c->stale_feed);
}
@@ -1934,7 +1934,7 @@ bgp_default_igp_table(struct bgp_config *cf, struct bgp_channel_config *cc, u32
return cc2->c.table;
/* Last, try default table of given type */
- if (tab = cf->c.global->def_tables[type])
+ if (tab = rt_get_default_table(cf->c.global, type))
return tab;
cf_error("Undefined IGP table");
@@ -1953,7 +1953,7 @@ bgp_default_base_table(struct bgp_config *cf, struct bgp_channel_config *cc)
return cc2->c.table;
/* Last, try default table of given type */
- struct rtable_config *tab = cf->c.global->def_tables[type];
+ struct rtable_config *tab = rt_get_default_table(cf->c.global, type);
if (tab)
return tab;
diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h
index 0cd327a2..1bcfb915 100644
--- a/proto/bgp/bgp.h
+++ b/proto/bgp/bgp.h
@@ -599,7 +599,7 @@ void bgp_done_prefix(struct bgp_channel *c, struct bgp_prefix *px, struct bgp_bu
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(struct rtable_private *table, net *net, rte *new, rte *old, rte *old_best);
void bgp_rte_modify_stale(struct rt_export_request *req, const net_addr *n, struct rt_pending_export *rpe UNUSED, rte **feed, uint count);
u32 bgp_rte_igp_metric(const 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 f4c09ab1..f07f9ca2 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,15 @@ 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_LOCKED(s->table, tab)
+ rt_unlock_table(tab);
s->table = tab;
s->ipv4 = tab ? (tab->addr_type == NET_IP4) : 0;
if (s->table)
- rt_lock_table(s->table);
+ RT_LOCKED(s->table, tab)
+ rt_lock_table(tab);
return s->table;
}
@@ -573,14 +575,18 @@ 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_LOCKED(s->table, tab)
+ {
+ if (s->table_open)
+ FIB_ITERATE_UNLINK(&s->fit, &tab->fib);
+
+ rt_unlock_table(tab);
+ }
if (s->table_ptr)
- rt_unlock_table(s->table_ptr);
+ RT_LOCKED(s->table_ptr, tab)
+ rt_unlock_table(tab);
config_del_obstacle(s->config);
@@ -606,16 +612,19 @@ mrt_table_dump_step(struct mrt_table_dump_state *s)
mrt_peer_table_dump(s);
- FIB_ITERATE_INIT(&s->fit, &s->table->fib);
+ RT_LOCKED(s->table, tab)
+ {
+
+ 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);
- return 0;
+ RT_RETURN(tab, 0);
}
/* With Always ADD_PATH option, we jump directly to second phase */
@@ -630,6 +639,8 @@ mrt_table_dump_step(struct mrt_table_dump_state *s)
FIB_ITERATE_END;
s->table_open = 0;
+ }
+
mrt_close_file(s);
mrt_peer_table_flush(s);
}
@@ -661,7 +672,8 @@ mrt_timer(timer *t)
s->always_add_path = cf->always_add_path;
if (s->table_ptr)
- rt_lock_table(s->table_ptr);
+ RT_LOCKED(s->table_ptr, tab)
+ rt_lock_table(tab);
p->table_dump = s;
ev_schedule(p->event);
@@ -737,7 +749,8 @@ mrt_dump_cmd(struct mrt_dump_data *d)
s->filename = d->filename;
if (s->table_ptr)
- rt_lock_table(s->table_ptr);
+ RT_LOCKED(s->table_ptr, tab)
+ rt_lock_table(tab);
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 3b83aa39..f535a391 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 d82ac8aa..9adafe5a 100644
--- a/proto/perf/perf.c
+++ b/proto/perf/perf.c
@@ -202,7 +202,9 @@ perf_loop(void *data)
p->exp++;
}
- rt_schedule_prune(P->main_channel->table);
+ RT_LOCKED(P->main_channel->table, tab)
+ rt_schedule_prune(tab);
+
ev_schedule(p->loop);
}
diff --git a/proto/rip/rip.c b/proto/rip/rip.c
index ab0e3f4b..183fc265 100644
--- a/proto/rip/rip.c
+++ b/proto/rip/rip.c
@@ -1121,24 +1121,18 @@ rip_rte_proto(struct rte *rte)
SKIP_BACK(struct rip_proto, p.sources, rte->src->owner) : NULL;
}
-static int
-rip_rte_better(struct rte *new, struct rte *old)
-{
- ASSERT_DIE(new->src == old->src);
- struct rip_proto *p = rip_rte_proto(new);
-
- u32 new_metric = ea_get_int(new->attrs, &ea_rip_metric, p->infinity);
- u32 old_metric = ea_get_int(old->attrs, &ea_rip_metric, p->infinity);
-
- return new_metric < old_metric;
-}
-
static u32
rip_rte_igp_metric(const rte *rt)
{
return ea_get_int(rt->attrs, &ea_rip_metric, IGP_METRIC_UNKNOWN);
}
+static int
+rip_rte_better(struct rte *new, struct rte *old)
+{
+ return rip_rte_igp_metric(new) < rip_rte_igp_metric(old);
+}
+
static void
rip_postconfig(struct proto_config *CF)
{
diff --git a/proto/static/static.c b/proto/static/static.c
index 65f3eccc..cb764a1c 100644
--- a/proto/static/static.c
+++ b/proto/static/static.c
@@ -436,11 +436,11 @@ static_postconfig(struct proto_config *CF)
if (!cf->igp_table_ip4)
cf->igp_table_ip4 = (cc->table->addr_type == NET_IP4) ?
- cc->table : cf->c.global->def_tables[NET_IP4];
+ cc->table : rt_get_default_table(cf->c.global, NET_IP4);
if (!cf->igp_table_ip6)
cf->igp_table_ip6 = (cc->table->addr_type == NET_IP6) ?
- cc->table : cf->c.global->def_tables[NET_IP6];
+ cc->table : rt_get_default_table(cf->c.global, NET_IP6);
WALK_LIST(r, cf->routes)
if (r->net && (r->net->type != CF->net_type))