diff options
Diffstat (limited to 'proto')
-rw-r--r-- | proto/bfd/bfd.c | 1 | ||||
-rw-r--r-- | proto/bgp/attrs.c | 70 | ||||
-rw-r--r-- | proto/bgp/bgp.c | 6 | ||||
-rw-r--r-- | proto/bgp/bgp.h | 2 | ||||
-rw-r--r-- | proto/mrt/mrt.c | 39 | ||||
-rw-r--r-- | proto/mrt/mrt.h | 6 | ||||
-rw-r--r-- | proto/perf/perf.c | 4 | ||||
-rw-r--r-- | proto/rip/rip.c | 18 | ||||
-rw-r--r-- | proto/static/static.c | 4 |
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)) |