From 48bf1322aa141ca6259b26b37551402758cff0cc Mon Sep 17 00:00:00 2001 From: Maria Matejka Date: Wed, 2 Mar 2022 10:35:21 +0100 Subject: Introducing an universal temporary linpool flushed after every task --- proto/bfd/io.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'proto/bfd') diff --git a/proto/bfd/io.c b/proto/bfd/io.c index 1cd9365a..e696cc89 100644 --- a/proto/bfd/io.c +++ b/proto/bfd/io.c @@ -482,6 +482,8 @@ birdloop_main(void *arg) birdloop_set_current(loop); + tmp_init(loop->pool); + pthread_mutex_lock(&loop->mutex); while (1) { -- cgit v1.2.3 From ebd807c0b8eb0b7a3dc3371cd4c87ae886c00885 Mon Sep 17 00:00:00 2001 From: Maria Matejka Date: Mon, 4 Apr 2022 20:31:14 +0200 Subject: Slab allocator can free the blocks without knowing the parent structure --- lib/resource.h | 2 +- lib/slab.c | 44 ++++++++------ lib/slab_test.c | 158 ++++++++++++++++++++++++-------------------------- nest/neighbor.c | 2 +- nest/rt-attr.c | 6 +- nest/rt-fib.c | 2 +- nest/rt-table.c | 6 +- proto/babel/babel.c | 12 ++-- proto/babel/packets.c | 9 ++- proto/bfd/bfd.c | 2 +- proto/bgp/attrs.c | 2 +- proto/ospf/topology.c | 2 +- proto/rip/rip.c | 4 +- 13 files changed, 127 insertions(+), 124 deletions(-) (limited to 'proto/bfd') diff --git a/lib/resource.h b/lib/resource.h index ed9e109d..8b180603 100644 --- a/lib/resource.h +++ b/lib/resource.h @@ -100,7 +100,7 @@ typedef struct slab slab; slab *sl_new(pool *, unsigned size); void *sl_alloc(slab *); void *sl_allocz(slab *); -void sl_free(slab *, void *); +void sl_free(void *); /* * Low-level memory allocation functions, please don't use diff --git a/lib/slab.c b/lib/slab.c index 9e0f7798..6da602f8 100644 --- a/lib/slab.c +++ b/lib/slab.c @@ -98,7 +98,7 @@ sl_allocz(slab *s) } void -sl_free(slab *s, void *oo) +sl_free(void *oo) { struct sl_obj *o = SKIP_BACK(struct sl_obj, data, oo); @@ -170,6 +170,7 @@ static struct resclass sl_class = { }; struct sl_head { + struct slab *slab; node n; u32 num_full; u32 used_bits[0]; @@ -236,7 +237,7 @@ sl_alloc(slab *s) struct sl_head *h; redo: - h = HEAD(s->partial_heads); + h = SKIP_BACK(struct sl_head, n, HEAD(s->partial_heads)); if (!h->n.next) goto no_partial; okay: @@ -262,7 +263,7 @@ okay: goto redo; no_partial: - h = HEAD(s->empty_heads); + h = SKIP_BACK(struct sl_head, n, HEAD(s->empty_heads)); if (h->n.next) { rem_node(&h->n); @@ -270,12 +271,16 @@ no_partial: s->num_empty_heads--; goto okay; } + h = alloc_page(); + ASSERT_DIE(SL_GET_HEAD(h) == h); + #ifdef POISON memset(h, 0xba, page_size); #endif - ASSERT_DIE(SL_GET_HEAD(h) == h); + memset(h, 0, s->head_size); + h->slab = s; add_head(&s->partial_heads, &h->n); goto okay; } @@ -305,9 +310,10 @@ sl_allocz(slab *s) * and returns it back to the Slab @s. */ void -sl_free(slab *s, void *oo) +sl_free(void *oo) { struct sl_head *h = SL_GET_HEAD(oo); + struct slab *s = h->slab; #ifdef POISON memset(oo, 0xdb, s->data_size); @@ -347,13 +353,14 @@ static void slab_free(resource *r) { slab *s = (slab *) r; - struct sl_head *h, *g; + struct sl_head *h; + node *nn, *nxt; - WALK_LIST_DELSAFE(h, g, s->empty_heads) + WALK_LIST2_DELSAFE(h, nn, nxt, s->empty_heads, n) free_page(h); - WALK_LIST_DELSAFE(h, g, s->partial_heads) + WALK_LIST2_DELSAFE(h, nn, nxt, s->partial_heads, n) free_page(h); - WALK_LIST_DELSAFE(h, g, s->full_heads) + WALK_LIST2_DELSAFE(h, nn, nxt, s->full_heads, n) free_page(h); } @@ -363,12 +370,13 @@ slab_dump(resource *r) slab *s = (slab *) r; int ec=0, pc=0, fc=0; struct sl_head *h; + node *nn; - WALK_LIST(h, s->empty_heads) + WALK_LIST2(h, nn, s->empty_heads, n) ec++; - WALK_LIST(h, s->partial_heads) + WALK_LIST2(h, nn, s->partial_heads, n) pc++; - WALK_LIST(h, s->full_heads) + WALK_LIST2(h, nn, s->full_heads, n) fc++; debug("(%de+%dp+%df blocks per %d objs per %d bytes)\n", ec, pc, fc, s->objs_per_slab, s->obj_size); } @@ -379,19 +387,20 @@ slab_memsize(resource *r) slab *s = (slab *) r; size_t heads = 0; struct sl_head *h; + node *nn; - WALK_LIST(h, s->full_heads) + WALK_LIST2(h, nn, s->full_heads, n) heads++; size_t items = heads * s->objs_per_slab; - WALK_LIST(h, s->partial_heads) + WALK_LIST2(h, nn, s->partial_heads, n) { heads++; items += h->num_full; } - WALK_LIST(h, s->empty_heads) + WALK_LIST2(h, nn, s->empty_heads, n) heads++; size_t eff = items * s->data_size; @@ -407,11 +416,12 @@ slab_lookup(resource *r, unsigned long a) { slab *s = (slab *) r; struct sl_head *h; + node *nn; - WALK_LIST(h, s->partial_heads) + WALK_LIST2(h, nn, s->partial_heads, n) if ((unsigned long) h < a && (unsigned long) h + page_size < a) return r; - WALK_LIST(h, s->full_heads) + WALK_LIST2(h, nn, s->full_heads, n) if ((unsigned long) h < a && (unsigned long) h + page_size < a) return r; return NULL; diff --git a/lib/slab_test.c b/lib/slab_test.c index e3ed0d58..803d0215 100644 --- a/lib/slab_test.c +++ b/lib/slab_test.c @@ -17,6 +17,25 @@ static const int sizes[] = { #define TEST_SIZE 1024 * 128 #define ITEMS(sz) TEST_SIZE / ( (sz) >> u32_log2((sz))/2 ) +struct test_request { + int size; + enum strategy { + TEST_NONE, + TEST_FORWARDS, + TEST_BACKWARDS, + TEST_RANDOM, + TEST_MIXED, + TEST__MAX, + } strategy; +}; + +const char * const strategy_name[TEST__MAX] = { + [TEST_FORWARDS] = "forwards", + [TEST_BACKWARDS] = "backwards", + [TEST_RANDOM] = "random", + [TEST_MIXED] = "mixed", +}; + static inline byte *test_alloc(slab *s, int sz, struct resmem *sliz) { byte *out = sl_alloc(s); @@ -42,7 +61,7 @@ static inline void test_free(slab *s, byte *block, int sz, struct resmem *sliz) block[p]++; } - sl_free(s, block); + sl_free(block); struct resmem ns = rmemsize((resource *) s); @@ -60,118 +79,93 @@ static inline struct resmem get_memsize(slab *s) } static int -t_slab_forwards(const void *data) +t_slab(const void *data) { - int sz = (intptr_t) data; - slab *s = sl_new(&root_pool, sz); - - struct resmem sliz = get_memsize(s); - - int n = ITEMS(sz); - byte **block = mb_alloc(&root_pool, n * sizeof(*block)); - - for (int i = 0; i < n; i++) - block[i] = test_alloc(s, sz, &sliz); - - for (int i = 0; i < n; i++) - test_free(s, block[i], sz, &sliz); + const struct test_request *tr = data; + int sz = tr->size; - mb_free(block); - - return 1; -} - -static int -t_slab_backwards(const void *data) -{ - int sz = (intptr_t) data; slab *s = sl_new(&root_pool, sz); - struct resmem sliz = get_memsize(s); int n = ITEMS(sz); byte **block = mb_alloc(&root_pool, n * sizeof(*block)); - for (int i = 0; i < n; i++) - block[i] = test_alloc(s, sz, &sliz); + switch (tr->strategy) { + case TEST_FORWARDS: + for (int i = 0; i < n; i++) + block[i] = test_alloc(s, sz, &sliz); - for (int i = n - 1; i >= 0; i--) - test_free(s, block[i], sz, &sliz); + for (int i = 0; i < n; i++) + test_free(s, block[i], sz, &sliz); - mb_free(block); + break; - return 1; -} + case TEST_BACKWARDS: + for (int i = 0; i < n; i++) + block[i] = test_alloc(s, sz, &sliz); -static int -t_slab_random(const void *data) -{ - int sz = (intptr_t) data; - slab *s = sl_new(&root_pool, sz); + for (int i = n - 1; i >= 0; i--) + test_free(s, block[i], sz, &sliz); - struct resmem sliz = get_memsize(s); + break; - int n = ITEMS(sz); - byte **block = mb_alloc(&root_pool, n * sizeof(*block)); + case TEST_RANDOM: + for (int i = 0; i < n; i++) + block[i] = test_alloc(s, sz, &sliz); - for (int i = 0; i < n; i++) - block[i] = test_alloc(s, sz, &sliz); + for (int i = 0; i < n; i++) + { + int pos = bt_random() % (n - i); + test_free(s, block[pos], sz, &sliz); + if (pos != n - i - 1) + block[pos] = block[n - i - 1]; + } - for (int i = 0; i < n; i++) - { - int pos = bt_random() % (n - i); - test_free(s, block[pos], sz, &sliz); - if (pos != n - i - 1) - block[pos] = block[n - i - 1]; - } + break; - mb_free(block); + case TEST_MIXED: + { + int cur = 0; + int pending = n; - return 1; -} + while (cur + pending > 0) { + int action = bt_random() % (cur + pending); -static int -t_slab_mixed(const void *data) -{ - int sz = (intptr_t) data; - slab *s = sl_new(&root_pool, sz); - - struct resmem sliz = get_memsize(s); - - int n = ITEMS(sz); - byte **block = mb_alloc(&root_pool, n * sizeof(*block)); + if (action < cur) { + test_free(s, block[action], sz, &sliz); + if (action != --cur) + block[action] = block[cur]; + } else { + block[cur++] = test_alloc(s, sz, &sliz); + pending--; + } + } - int cur = 0; - int pending = n; + break; + } - while (cur + pending > 0) { - int action = bt_random() % (cur + pending); - - if (action < cur) { - test_free(s, block[action], sz, &sliz); - if (action != --cur) - block[action] = block[cur]; - } else { - block[cur++] = test_alloc(s, sz, &sliz); - pending--; - } + default: bug("This shouldn't happen"); } mb_free(block); - return 1; } int main(int argc, char *argv[]) { bt_init(argc, argv); + struct test_request tr; + for (uint i = 0; i < sizeof(sizes) / sizeof(*sizes); i++) - { - bt_test_suite_arg(t_slab_forwards, (void *) (intptr_t) sizes[i], "Slab deallocation from beginning to end, size=%d", sizes[i]); - bt_test_suite_arg(t_slab_backwards, (void *) (intptr_t) sizes[i], "Slab deallocation from end to beginning, size=%d", sizes[i]); - bt_test_suite_arg(t_slab_random, (void *) (intptr_t) sizes[i], "Slab deallocation in random order, size=%d", sizes[i]); - bt_test_suite_arg(t_slab_mixed, (void *) (intptr_t) sizes[i], "Slab deallocation in mixed order, size=%d", sizes[i]); - } + for (uint strategy = TEST_FORWARDS; strategy < TEST__MAX; strategy++) + { + tr = (struct test_request) { + .size = sizes[i], + .strategy = strategy, + }; + bt_test_suite_arg(t_slab, &tr, "Slab allocator test, size=%d, strategy=%s", + tr.size, strategy_name[strategy]); + } return bt_exit_value(); } diff --git a/nest/neighbor.c b/nest/neighbor.c index 1a31fb79..7cf9c85d 100644 --- a/nest/neighbor.c +++ b/nest/neighbor.c @@ -345,7 +345,7 @@ neigh_free(neighbor *n) { rem_node(&n->n); rem_node(&n->if_n); - sl_free(neigh_slab, n); + sl_free(n); } /** diff --git a/nest/rt-attr.c b/nest/rt-attr.c index 1bece201..863d411b 100644 --- a/nest/rt-attr.c +++ b/nest/rt-attr.c @@ -154,7 +154,7 @@ rt_prune_sources(void) { HASH_DO_REMOVE(src_hash, RSH, sp); idm_free(&src_ids, src->global_id); - sl_free(rte_src_slab, src); + sl_free(src); } } HASH_WALK_FILTER_END; @@ -391,7 +391,7 @@ nexthop_free(struct nexthop *o) while (o) { n = o->next; - sl_free(nexthop_slab(o), o); + sl_free(o); o = n; } } @@ -1231,7 +1231,7 @@ rta__free(rta *a) nexthop_free(a->nh.next); ea_free(a->eattrs); a->cached = 0; - sl_free(rta_slab(a), a); + sl_free(a); } rta * diff --git a/nest/rt-fib.c b/nest/rt-fib.c index 1690a8f6..43e3039d 100644 --- a/nest/rt-fib.c +++ b/nest/rt-fib.c @@ -475,7 +475,7 @@ fib_delete(struct fib *f, void *E) } if (f->fib_slab) - sl_free(f->fib_slab, E); + sl_free(E); else mb_free(E); diff --git a/nest/rt-table.c b/nest/rt-table.c index a1e49c21..1885e602 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -631,7 +631,7 @@ rte_free(rte *e) rt_unlock_source(e->src); if (rta_is_cached(e->attrs)) rta_free(e->attrs); - sl_free(rte_slab, e); + sl_free(e); } static inline void @@ -639,7 +639,7 @@ rte_free_quick(rte *e) { rt_unlock_source(e->src); rta_free(e->attrs); - sl_free(rte_slab, e); + sl_free(e); } static int /* Actually better or at least as good as */ @@ -3393,7 +3393,7 @@ hc_delete_hostentry(struct hostcache *hc, pool *p, struct hostentry *he) rem_node(&he->ln); hc_remove(hc, he); - sl_free(hc->slab, he); + sl_free(he); hc->hash_items--; if (hc->hash_items < hc->hash_min) diff --git a/proto/babel/babel.c b/proto/babel/babel.c index 30809000..b3411fc2 100644 --- a/proto/babel/babel.c +++ b/proto/babel/babel.c @@ -119,7 +119,7 @@ babel_get_source(struct babel_proto *p, struct babel_entry *e, u64 router_id) } static void -babel_expire_sources(struct babel_proto *p, struct babel_entry *e) +babel_expire_sources(struct babel_proto *p UNUSED, struct babel_entry *e) { struct babel_source *n, *nx; btime now_ = current_time(); @@ -129,7 +129,7 @@ babel_expire_sources(struct babel_proto *p, struct babel_entry *e) if (n->expires && n->expires <= now_) { rem_node(NODE n); - sl_free(p->source_slab, n); + sl_free(n); } } } @@ -174,7 +174,7 @@ babel_retract_route(struct babel_proto *p, struct babel_route *r) } static void -babel_flush_route(struct babel_proto *p, struct babel_route *r) +babel_flush_route(struct babel_proto *p UNUSED, struct babel_route *r) { DBG("Babel: Flush route %N router_id %lR neigh %I\n", r->e->n.addr, r->router_id, r->neigh->addr); @@ -185,7 +185,7 @@ babel_flush_route(struct babel_proto *p, struct babel_route *r) if (r->e->selected == r) r->e->selected = NULL; - sl_free(p->route_slab, r); + sl_free(r); } static void @@ -336,13 +336,13 @@ found: } static void -babel_remove_seqno_request(struct babel_proto *p, struct babel_seqno_request *sr) +babel_remove_seqno_request(struct babel_proto *p UNUSED, struct babel_seqno_request *sr) { if (sr->nbr) rem_node(&sr->nbr_node); rem_node(NODE sr); - sl_free(p->seqno_slab, sr); + sl_free(sr); } static int diff --git a/proto/babel/packets.c b/proto/babel/packets.c index f13410e2..2a6d443d 100644 --- a/proto/babel/packets.c +++ b/proto/babel/packets.c @@ -1318,7 +1318,6 @@ babel_send_to(struct babel_iface *ifa, ip_addr dest) static uint babel_write_queue(struct babel_iface *ifa, list *queue) { - struct babel_proto *p = ifa->proto; struct babel_write_state state = { .next_hop_ip6 = ifa->addr }; if (EMPTY_LIST(*queue)) @@ -1346,7 +1345,7 @@ babel_write_queue(struct babel_iface *ifa, list *queue) pos += len; rem_node(NODE msg); - sl_free(p->msg_slab, msg); + sl_free(msg); } pos += babel_auth_add_tlvs(ifa, (struct babel_tlv *) pos, end - pos); @@ -1507,13 +1506,13 @@ babel_process_packet(struct babel_iface *ifa, else if (res == PARSE_IGNORE) { DBG("Babel: Ignoring TLV of type %d\n", tlv->type); - sl_free(p->msg_slab, msg); + sl_free(msg); } else /* PARSE_ERROR */ { LOG_PKT("Bad TLV from %I via %s type %d pos %d - parse error", saddr, ifa->iface->name, tlv->type, (int) ((byte *)tlv - (byte *)pkt)); - sl_free(p->msg_slab, msg); + sl_free(msg); break; } } @@ -1525,7 +1524,7 @@ babel_process_packet(struct babel_iface *ifa, if (tlv_data[msg->msg.type].handle_tlv) tlv_data[msg->msg.type].handle_tlv(&msg->msg, ifa); rem_node(NODE msg); - sl_free(p->msg_slab, msg); + sl_free(msg); } } diff --git a/proto/bfd/bfd.c b/proto/bfd/bfd.c index dac184c5..277f38bf 100644 --- a/proto/bfd/bfd.c +++ b/proto/bfd/bfd.c @@ -508,7 +508,7 @@ bfd_remove_session(struct bfd_proto *p, struct bfd_session *s) HASH_REMOVE(p->session_hash_id, HASH_ID, s); HASH_REMOVE(p->session_hash_ip, HASH_IP, s); - sl_free(p->session_slab, s); + sl_free(s); TRACE(D_EVENTS, "Session to %I removed", ip); diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c index 65e87c96..76b99c41 100644 --- a/proto/bgp/attrs.c +++ b/proto/bgp/attrs.c @@ -1664,7 +1664,7 @@ bgp_free_prefix(struct bgp_channel *c, struct bgp_prefix *px) HASH_REMOVE2(c->prefix_hash, PXH, c->pool, px); if (c->prefix_slab) - sl_free(c->prefix_slab, px); + sl_free(px); else mb_free(px); } diff --git a/proto/ospf/topology.c b/proto/ospf/topology.c index 52c2a0ce..9fe68264 100644 --- a/proto/ospf/topology.c +++ b/proto/ospf/topology.c @@ -2135,7 +2135,7 @@ ospf_hash_delete(struct top_graph *f, struct top_hash_entry *e) if (*ee == e) { *ee = e->next; - sl_free(f->hash_slab, e); + sl_free(e); if (f->hash_entries-- < f->hash_entries_min) ospf_top_rehash(f, -HASH_LO_STEP); return; diff --git a/proto/rip/rip.c b/proto/rip/rip.c index a501a784..eb232316 100644 --- a/proto/rip/rip.c +++ b/proto/rip/rip.c @@ -108,14 +108,14 @@ rip_add_rte(struct rip_proto *p, struct rip_rte **rp, struct rip_rte *src) } static inline void -rip_remove_rte(struct rip_proto *p, struct rip_rte **rp) +rip_remove_rte(struct rip_proto *p UNUSED, struct rip_rte **rp) { struct rip_rte *rt = *rp; rip_unlock_neighbor(rt->from); *rp = rt->next; - sl_free(p->rte_slab, rt); + sl_free(rt); } static inline int rip_same_rte(struct rip_rte *a, struct rip_rte *b) -- cgit v1.2.3 From 4a23ede2b056a41456790cc20a0c3d92a7137693 Mon Sep 17 00:00:00 2001 From: Maria Matejka Date: Fri, 18 Mar 2022 22:05:50 +0100 Subject: Protocols have their own explicit init routines --- Makefile.in | 10 ++++++++++ nest/Makefile | 7 ++++++- nest/proto.c | 45 +++++---------------------------------------- nest/protocol.h | 4 ++-- nest/rt-dev.c | 6 ++++++ proto/babel/Makefile | 1 + proto/babel/babel.c | 6 ++++++ proto/bfd/Makefile | 3 ++- proto/bfd/bfd.c | 17 ++++++++--------- proto/bgp/Makefile | 3 ++- proto/bgp/bgp.c | 5 +++++ proto/mrt/Makefile | 3 ++- proto/mrt/mrt.c | 6 ++++++ proto/ospf/Makefile | 3 ++- proto/ospf/ospf.c | 6 ++++++ proto/perf/Makefile | 1 + proto/perf/perf.c | 6 ++++++ proto/pipe/Makefile | 3 ++- proto/pipe/pipe.c | 6 ++++++ proto/radv/Makefile | 3 ++- proto/radv/radv.c | 6 ++++++ proto/rip/Makefile | 3 ++- proto/rip/rip.c | 6 ++++++ proto/rpki/Makefile | 3 ++- proto/rpki/rpki.c | 6 ++++++ proto/static/Makefile | 3 ++- proto/static/static.c | 6 ++++++ sysdep/unix/Makefile | 2 ++ sysdep/unix/krt.c | 13 +++++++++++++ sysdep/unix/main.c | 2 -- test/bt-utils.c | 2 -- 31 files changed, 131 insertions(+), 65 deletions(-) (limited to 'proto/bfd') diff --git a/Makefile.in b/Makefile.in index e0ff4a1d..0d55807b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -82,6 +82,9 @@ conf-lex-targets := $(addprefix $(objdir)/conf/,cf-lex.o) conf-y-targets := $(addprefix $(objdir)/conf/,cf-parse.y keywords.h commands.h) cf-local = $(conf-y-targets): $(s)config.Y +# nest/Makefile declarations needed for all other modules +proto-build-c := $(addprefix $(objdir)/nest/,proto-build.c) + src-o-files = $(patsubst %.c,$(o)%.o,$(src)) tests-target-files = $(patsubst %.c,$(o)%,$(tests_src)) @@ -95,6 +98,13 @@ else o = $(patsubst $(srcdir)%,$(objdir)%,$(s)) endif +define proto-build_in = +PROTO_BUILD += $(1) +$(proto-build-c): $(lastword $(MAKEFILE_LIST)) +endef + +proto-build = $(eval $(call proto-build_in,$(1))) + define clean_in = clean:: rm -f $(addprefix $(o),$(1)) diff --git a/nest/Makefile b/nest/Makefile index 884d3950..7d451ba4 100644 --- a/nest/Makefile +++ b/nest/Makefile @@ -1,7 +1,12 @@ -src := a-path.c a-set.c cli.c cmds.c iface.c locks.c neighbor.c password.c proto.c rt-attr.c rt-dev.c rt-fib.c rt-show.c rt-table.c +src := a-path.c a-set.c cli.c cmds.c iface.c locks.c neighbor.c password.c proto.c proto-build.c rt-attr.c rt-dev.c rt-fib.c rt-show.c rt-table.c obj := $(src-o-files) $(all-daemon) $(cf-local) +$(call proto-build,dev_build) + +$(proto-build-c): $(lastword $(MAKEFILE_LIST)) + $(E)echo GEN $@ + $(Q)echo "$(patsubst %,void %(void); ,$(PROTO_BUILD)) void protos_build_gen(void) { $(patsubst %, %(); ,$(PROTO_BUILD))}" > $@ tests_src := a-set_test.c a-path_test.c tests_targets := $(tests_targets) $(tests-target-files) diff --git a/nest/proto.c b/nest/proto.c index 7cfb1555..7074f73a 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -23,9 +23,9 @@ #include "filter/f-inst.h" pool *proto_pool; -list proto_list; +list STATIC_LIST_INIT(proto_list); -static list protocol_list; +static list STATIC_LIST_INIT(protocol_list); struct protocol *class_to_protocol[PROTOCOL__MAX]; #define CD(c, msg, args...) ({ if (c->debug & D_STATES) log(L_TRACE "%s.%s: " msg, c->proto->name, c->name ?: "?", ## args); }) @@ -1651,6 +1651,8 @@ proto_build(struct protocol *p) /* FIXME: convert this call to some protocol hook */ extern void bfd_init_all(void); +void protos_build_gen(void); + /** * protos_build - build a protocol list * @@ -1663,44 +1665,7 @@ extern void bfd_init_all(void); void protos_build(void) { - init_list(&proto_list); - init_list(&protocol_list); - - proto_build(&proto_device); -#ifdef CONFIG_RADV - proto_build(&proto_radv); -#endif -#ifdef CONFIG_RIP - proto_build(&proto_rip); -#endif -#ifdef CONFIG_STATIC - proto_build(&proto_static); -#endif -#ifdef CONFIG_MRT - proto_build(&proto_mrt); -#endif -#ifdef CONFIG_OSPF - proto_build(&proto_ospf); -#endif -#ifdef CONFIG_PIPE - proto_build(&proto_pipe); -#endif -#ifdef CONFIG_BGP - proto_build(&proto_bgp); -#endif -#ifdef CONFIG_BFD - proto_build(&proto_bfd); - bfd_init_all(); -#endif -#ifdef CONFIG_BABEL - proto_build(&proto_babel); -#endif -#ifdef CONFIG_RPKI - proto_build(&proto_rpki); -#endif -#ifdef CONFIG_PERF - proto_build(&proto_perf); -#endif + protos_build_gen(); proto_pool = rp_new(&root_pool, "Protocols"); proto_shutdown_timer = tm_new(proto_pool); diff --git a/nest/protocol.h b/nest/protocol.h index e05dd7ec..d0810a8f 100644 --- a/nest/protocol.h +++ b/nest/protocol.h @@ -84,8 +84,8 @@ struct protocol { void (*copy_config)(struct proto_config *, struct proto_config *); /* Copy config from given protocol instance */ }; -void protos_build(void); -void proto_build(struct protocol *); +void protos_build(void); /* Called from sysdep to initialize protocols */ +void proto_build(struct protocol *); /* Called from protocol to register itself */ void protos_preconfig(struct config *); void protos_commit(struct config *new, struct config *old, int force_restart, int type); struct proto * proto_spawn(struct proto_config *cf, uint disabled); diff --git a/nest/rt-dev.c b/nest/rt-dev.c index e2e65926..05e64fc3 100644 --- a/nest/rt-dev.c +++ b/nest/rt-dev.c @@ -195,3 +195,9 @@ struct protocol proto_device = { .reconfigure = dev_reconfigure, .copy_config = dev_copy_config }; + +void +dev_build(void) +{ + proto_build(&proto_device); +} diff --git a/proto/babel/Makefile b/proto/babel/Makefile index 06b58e95..ae6aeaf2 100644 --- a/proto/babel/Makefile +++ b/proto/babel/Makefile @@ -2,5 +2,6 @@ src := babel.c packets.c obj := $(src-o-files) $(all-daemon) $(cf-local) +$(call proto-build,babel_build) tests_objs := $(tests_objs) $(src-o-files) diff --git a/proto/babel/babel.c b/proto/babel/babel.c index b3411fc2..8040345f 100644 --- a/proto/babel/babel.c +++ b/proto/babel/babel.c @@ -2494,3 +2494,9 @@ struct protocol proto_babel = { .get_route_info = babel_get_route_info, .get_attr = babel_get_attr }; + +void +babel_build(void) +{ + proto_build(&proto_babel); +} diff --git a/proto/bfd/Makefile b/proto/bfd/Makefile index 402122fc..dbdc0a09 100644 --- a/proto/bfd/Makefile +++ b/proto/bfd/Makefile @@ -2,5 +2,6 @@ src := bfd.c io.c packets.c obj := $(src-o-files) $(all-daemon) $(cf-local) +$(call proto-build,bfd_build) -tests_objs := $(tests_objs) $(src-o-files) \ No newline at end of file +tests_objs := $(tests_objs) $(src-o-files) diff --git a/proto/bfd/bfd.c b/proto/bfd/bfd.c index 277f38bf..d1e97cd5 100644 --- a/proto/bfd/bfd.c +++ b/proto/bfd/bfd.c @@ -113,8 +113,8 @@ #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) -static list bfd_proto_list; -static list bfd_wait_list; +static list STATIC_LIST_INIT(bfd_proto_list); +static list STATIC_LIST_INIT(bfd_wait_list); const char *bfd_state_names[] = { "AdminDown", "Down", "Init", "Up" }; @@ -998,13 +998,6 @@ bfd_notify_init(struct bfd_proto *p) * BFD protocol glue */ -void -bfd_init_all(void) -{ - init_list(&bfd_proto_list); - init_list(&bfd_wait_list); -} - static struct proto * bfd_init(struct proto_config *c) { @@ -1186,3 +1179,9 @@ struct protocol proto_bfd = { .reconfigure = bfd_reconfigure, .copy_config = bfd_copy_config, }; + +void +bfd_build(void) +{ + proto_build(&proto_bfd); +} diff --git a/proto/bgp/Makefile b/proto/bgp/Makefile index 00aaef5e..2a4cc99c 100644 --- a/proto/bgp/Makefile +++ b/proto/bgp/Makefile @@ -2,5 +2,6 @@ src := attrs.c bgp.c packets.c obj := $(src-o-files) $(all-daemon) $(cf-local) +$(call proto-build,bgp_build) -tests_objs := $(tests_objs) $(src-o-files) \ No newline at end of file +tests_objs := $(tests_objs) $(src-o-files) diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index 52400762..8c97f7b3 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -2592,3 +2592,8 @@ struct protocol proto_bgp = { .get_route_info = bgp_get_route_info, .show_proto_info = bgp_show_proto_info }; + +void bgp_build(void) +{ + proto_build(&proto_bgp); +} diff --git a/proto/mrt/Makefile b/proto/mrt/Makefile index 925fb102..000e1c1c 100644 --- a/proto/mrt/Makefile +++ b/proto/mrt/Makefile @@ -2,5 +2,6 @@ src := mrt.c obj := $(src-o-files) $(all-daemon) $(cf-local) +$(call proto-build,mrt_build) -tests_objs := $(tests_objs) $(src-o-files) \ No newline at end of file +tests_objs := $(tests_objs) $(src-o-files) diff --git a/proto/mrt/mrt.c b/proto/mrt/mrt.c index e885611a..70b2aeff 100644 --- a/proto/mrt/mrt.c +++ b/proto/mrt/mrt.c @@ -916,3 +916,9 @@ struct protocol proto_mrt = { .reconfigure = mrt_reconfigure, .copy_config = mrt_copy_config, }; + +void +mrt_build(void) +{ + proto_build(&proto_mrt); +} diff --git a/proto/ospf/Makefile b/proto/ospf/Makefile index 39e74f71..85664543 100644 --- a/proto/ospf/Makefile +++ b/proto/ospf/Makefile @@ -2,5 +2,6 @@ src := dbdes.c hello.c iface.c lsack.c lsalib.c lsreq.c lsupd.c neighbor.c ospf. obj := $(src-o-files) $(all-daemon) $(cf-local) +$(call proto-build,ospf_build) -tests_objs := $(tests_objs) $(src-o-files) \ No newline at end of file +tests_objs := $(tests_objs) $(src-o-files) diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index f9aa6cd1..4ea53942 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -1534,3 +1534,9 @@ struct protocol proto_ospf = { .get_attr = ospf_get_attr, .get_route_info = ospf_get_route_info }; + +void +ospf_build(void) +{ + proto_build(&proto_ospf); +} diff --git a/proto/perf/Makefile b/proto/perf/Makefile index 7877fb19..42051f43 100644 --- a/proto/perf/Makefile +++ b/proto/perf/Makefile @@ -2,5 +2,6 @@ src := perf.c obj := $(src-o-files) $(all-daemon) $(cf-local) +$(call proto-build,perf_build) tests_objs := $(tests_objs) $(src-o-files) diff --git a/proto/perf/perf.c b/proto/perf/perf.c index 52784c14..5d228045 100644 --- a/proto/perf/perf.c +++ b/proto/perf/perf.c @@ -315,3 +315,9 @@ struct protocol proto_perf = { .reconfigure = perf_reconfigure, .copy_config = perf_copy_config, }; + +void +perf_build(void) +{ + proto_build(&proto_perf); +} diff --git a/proto/pipe/Makefile b/proto/pipe/Makefile index 5093da98..ba66027f 100644 --- a/proto/pipe/Makefile +++ b/proto/pipe/Makefile @@ -2,5 +2,6 @@ src := pipe.c obj := $(src-o-files) $(all-daemon) $(cf-local) +$(call proto-build,pipe_build) -tests_objs := $(tests_objs) $(src-o-files) \ No newline at end of file +tests_objs := $(tests_objs) $(src-o-files) diff --git a/proto/pipe/pipe.c b/proto/pipe/pipe.c index 97862780..c3457135 100644 --- a/proto/pipe/pipe.c +++ b/proto/pipe/pipe.c @@ -303,3 +303,9 @@ struct protocol proto_pipe = { .get_status = pipe_get_status, .show_proto_info = pipe_show_proto_info }; + +void +pipe_build(void) +{ + proto_build(&proto_pipe); +} diff --git a/proto/radv/Makefile b/proto/radv/Makefile index 05317eff..4780bee3 100644 --- a/proto/radv/Makefile +++ b/proto/radv/Makefile @@ -2,5 +2,6 @@ src := packets.c radv.c obj := $(src-o-files) $(all-daemon) $(cf-local) +$(call proto-build,radv_build) -tests_objs := $(tests_objs) $(src-o-files) \ No newline at end of file +tests_objs := $(tests_objs) $(src-o-files) diff --git a/proto/radv/radv.c b/proto/radv/radv.c index 540ff2a7..7985997a 100644 --- a/proto/radv/radv.c +++ b/proto/radv/radv.c @@ -771,3 +771,9 @@ struct protocol proto_radv = { .get_status = radv_get_status, .get_attr = radv_get_attr }; + +void +radv_build(void) +{ + proto_build(&proto_radv); +} diff --git a/proto/rip/Makefile b/proto/rip/Makefile index 7feabcd8..b9ff62d6 100644 --- a/proto/rip/Makefile +++ b/proto/rip/Makefile @@ -2,5 +2,6 @@ src := packets.c rip.c obj := $(src-o-files) $(all-daemon) $(cf-local) +$(call proto-build,rip_build) -tests_objs := $(tests_objs) $(src-o-files) \ No newline at end of file +tests_objs := $(tests_objs) $(src-o-files) diff --git a/proto/rip/rip.c b/proto/rip/rip.c index eb232316..9d8b9849 100644 --- a/proto/rip/rip.c +++ b/proto/rip/rip.c @@ -1342,3 +1342,9 @@ struct protocol proto_rip = { .get_route_info = rip_get_route_info, .get_attr = rip_get_attr }; + +void +rip_build(void) +{ + proto_build(&proto_rip); +} diff --git a/proto/rpki/Makefile b/proto/rpki/Makefile index eb09b7df..8e3a2761 100644 --- a/proto/rpki/Makefile +++ b/proto/rpki/Makefile @@ -2,5 +2,6 @@ src := rpki.c packets.c tcp_transport.c ssh_transport.c transport.c obj := $(src-o-files) $(all-daemon) $(cf-local) +$(call proto-build,rpki_build) -tests_objs := $(tests_objs) $(src-o-files) \ No newline at end of file +tests_objs := $(tests_objs) $(src-o-files) diff --git a/proto/rpki/rpki.c b/proto/rpki/rpki.c index be3d19ab..6e111a81 100644 --- a/proto/rpki/rpki.c +++ b/proto/rpki/rpki.c @@ -949,3 +949,9 @@ struct protocol proto_rpki = { .reconfigure = rpki_reconfigure, .get_status = rpki_get_status, }; + +void +rpki_build(void) +{ + proto_build(&proto_rpki); +} diff --git a/proto/static/Makefile b/proto/static/Makefile index e38f9b74..26aed31f 100644 --- a/proto/static/Makefile +++ b/proto/static/Makefile @@ -2,5 +2,6 @@ src := static.c obj := $(src-o-files) $(all-daemon) $(cf-local) +$(call proto-build,static_build) -tests_objs := $(tests_objs) $(src-o-files) \ No newline at end of file +tests_objs := $(tests_objs) $(src-o-files) diff --git a/proto/static/static.c b/proto/static/static.c index 6d3871cc..cf2e4585 100644 --- a/proto/static/static.c +++ b/proto/static/static.c @@ -793,3 +793,9 @@ struct protocol proto_static = { .copy_config = static_copy_config, .get_route_info = static_get_route_info, }; + +void +static_build(void) +{ + proto_build(&proto_static); +} diff --git a/sysdep/unix/Makefile b/sysdep/unix/Makefile index d0d36b5f..51ab98a9 100644 --- a/sysdep/unix/Makefile +++ b/sysdep/unix/Makefile @@ -2,6 +2,8 @@ src := alloc.c io.c krt.c log.c main.c random.c obj := $(src-o-files) $(all-daemon) $(cf-local) +$(call proto-build,kif_build) +$(call proto-build,krt_build) $(conf-y-targets): $(s)krt.Y src := $(filter-out main.c, $(src)) diff --git a/sysdep/unix/krt.c b/sysdep/unix/krt.c index 7d7ec7e6..bfd69b73 100644 --- a/sysdep/unix/krt.c +++ b/sysdep/unix/krt.c @@ -243,6 +243,13 @@ struct protocol proto_unix_iface = { .copy_config = kif_copy_config }; +void +kif_build(void) +{ + proto_build(&proto_unix_iface); +} + + /* * Tracing of routes */ @@ -1177,3 +1184,9 @@ struct protocol proto_unix_kernel = { .dump = krt_dump, #endif }; + +void +krt_build(void) +{ + proto_build(&proto_unix_kernel); +} diff --git a/sysdep/unix/main.c b/sysdep/unix/main.c index cdf0a310..71749324 100644 --- a/sysdep/unix/main.c +++ b/sysdep/unix/main.c @@ -906,8 +906,6 @@ main(int argc, char **argv) open_pid_file(); protos_build(); - proto_build(&proto_unix_kernel); - proto_build(&proto_unix_iface); struct config *conf = read_config(); diff --git a/test/bt-utils.c b/test/bt-utils.c index 2a7799c3..8496e185 100644 --- a/test/bt-utils.c +++ b/test/bt-utils.c @@ -68,8 +68,6 @@ bt_bird_init(void) config_init(); protos_build(); - proto_build(&proto_unix_kernel); - proto_build(&proto_unix_iface); } void bt_bird_cleanup(void) -- cgit v1.2.3 From 692055e3df6cc9f0d428d3b0dd8cdd8e825eb6f4 Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Thu, 7 Apr 2022 19:33:40 +0200 Subject: BFD: Add 'strict bind' option Add BFD protocol option 'strict bind' to use separate listening socket for each BFD interface bound to its address instead of using shared listening sockets. --- doc/bird.sgml | 7 +++++++ proto/bfd/bfd.c | 31 ++++++++++++++++++++++--------- proto/bfd/bfd.h | 3 +++ proto/bfd/config.Y | 4 +++- proto/bfd/packets.c | 36 +++++++++++++++++++++++++++++++++++- 5 files changed, 70 insertions(+), 11 deletions(-) (limited to 'proto/bfd') diff --git a/doc/bird.sgml b/doc/bird.sgml index 1d5ae056..9c4a6f68 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -2153,6 +2153,13 @@ protocol bfd [<name>] { to configure separate BFD protocol instances for IPv4 and for IPv6 sessions. +