From 878eeec12bf020c9e7460040d225a929bbbd2bd2 Mon Sep 17 00:00:00 2001 From: Maria Matejka Date: Wed, 29 Sep 2021 16:15:13 +0200 Subject: 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 --- nest/proto.c | 75 +++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 28 deletions(-) (limited to 'nest/proto.c') diff --git a/nest/proto.c b/nest/proto.c index 35af3c6c..4ae0cbfd 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -172,7 +172,7 @@ proto_cf_find_channel(struct proto_config *pc, uint net_type) * Returns pointer to channel or NULL */ struct channel * -proto_find_channel_by_table(struct proto *p, struct rtable *t) +proto_find_channel_by_table(struct proto *p, rtable *t) { struct channel *c; @@ -236,7 +236,9 @@ proto_add_channel(struct proto *p, struct channel_config *cf) c->channel = cf->channel; c->proto = p; c->table = cf->table->table; - rt_lock_table(c->table); + + RT_LOCKED(c->table, t) + rt_lock_table(t); c->in_filter = cf->in_filter; c->out_filter = cf->out_filter; @@ -277,7 +279,9 @@ proto_remove_channel(struct proto *p UNUSED, struct channel *c) CD(c, "Removed", c->name); - rt_unlock_table(c->table); + RT_LOCKED(c->table, t) + rt_unlock_table(t); + rem_node(&c->n); mb_free(c); } @@ -391,7 +395,7 @@ static void channel_roa_subscribe_filter(struct channel *c, int dir) { const struct filter *f = dir ? c->in_filter : c->out_filter; - struct rtable *tab; + rtable *tab; int valid = 1, found = 0; if ((f == FILTER_ACCEPT) || (f == FILTER_REJECT)) @@ -560,11 +564,11 @@ channel_check_stopped(struct channel *c) } void -channel_import_stopped(struct rt_import_request *req) +channel_import_stopped(void *_c) { - struct channel *c = SKIP_BACK(struct channel, in_req, req); + struct channel *c = _c; - req->hook = NULL; + c->in_req.hook = NULL; mb_free(c->in_req.name); c->in_req.name = NULL; @@ -661,17 +665,16 @@ channel_aux_stopped(void *data) else c->in_table = NULL; - rfree(cat->tab->rp); - + rfree(cat->tab->priv.rp); mb_free(cat); - return channel_check_stopped(c); + channel_check_stopped(c); } static void -channel_aux_import_stopped(struct rt_import_request *req) +channel_aux_import_stopped(void *_cat) { - struct channel_aux_table *cat = SKIP_BACK(struct channel_aux_table, push, req); - ASSERT_DIE(cat->tab->delete_event); + struct channel_aux_table *cat = _cat; + cat->push.hook = NULL; } static void @@ -680,24 +683,35 @@ channel_aux_export_stopped(struct rt_export_request *req) struct channel_aux_table *cat = SKIP_BACK(struct channel_aux_table, get, req); req->hook = NULL; - if (cat->refeed_pending && !cat->tab->delete_event) - { - cat->refeed_pending = 0; - rt_request_export(cat->tab, req); - } - else - ASSERT_DIE(cat->tab->delete_event); + int del; + RT_LOCKED(cat->tab, t) + del = !!t->delete_event; + + if (del) + return; + + ASSERT_DIE(cat->refeed_pending); + cat->refeed_pending = 0; + rt_request_export(cat->tab, req); } static void channel_aux_stop(struct channel_aux_table *cat) { - rt_stop_import(&cat->push, channel_aux_import_stopped); - rt_stop_export(&cat->get, channel_aux_export_stopped); + RT_LOCKED(cat->tab, t) + { + t->delete_event = ev_new_init(t->rp, channel_aux_stopped, cat); + t->delete_event->list = proto_event_list(cat->c->proto); + } - cat->tab->delete_event = ev_new_init(cat->tab->rp, channel_aux_stopped, cat); + cat->push_stopped = (event) { + .hook = channel_aux_import_stopped, + .data = cat, + .list = proto_event_list(cat->c->proto), + }; - rt_unlock_table(cat->tab); + rt_stop_import(&cat->push, &cat->push_stopped); + rt_stop_export(&cat->get, channel_aux_export_stopped); } static void @@ -889,7 +903,6 @@ channel_setup_in_table(struct channel *c, int best) c->in_table->c = c; c->in_table->tab = rt_setup(c->proto->pool, &cat->tab_cf); - rt_lock_table(c->in_table->tab); rt_request_import(c->in_table->tab, &c->in_table->push); rt_request_export(c->in_table->tab, &c->in_table->get); @@ -931,7 +944,6 @@ channel_setup_out_table(struct channel *c) c->out_table->c = c; c->out_table->tab = rt_setup(c->proto->pool, &cat->tab_cf); - rt_lock_table(c->out_table->tab); rt_request_import(c->out_table->tab, &c->out_table->push); rt_request_export(c->out_table->tab, &c->out_table->get); @@ -993,7 +1005,14 @@ channel_do_stop(struct channel *c) /* Stop import */ if (c->in_req.hook) - rt_stop_import(&c->in_req, channel_import_stopped); + { + c->in_stopped = (event) { + .hook = channel_import_stopped, + .data = c, + .list = proto_event_list(c->proto), + }; + rt_stop_import(&c->in_req, &c->in_stopped); + } c->gr_wait = 0; if (c->gr_lock) @@ -2339,7 +2358,7 @@ proto_do_start(struct proto *p) { p->active = 1; - rt_init_sources(&p->sources, p->name, proto_event_list(p)); + rt_init_sources(&p->sources, p->name, proto_work_list(p)); if (!p->sources.class) p->sources.class = &default_rte_owner_class; -- cgit v1.2.3 From dc160e11e1a9e4344bbee6fd0bc8aee229d7c540 Mon Sep 17 00:00:00 2001 From: Maria Matejka Date: Fri, 12 Nov 2021 15:53:33 +0000 Subject: Route table import-to-export announcement indirection to reduce pipe traffic --- nest/proto.c | 3 +++ nest/route.h | 7 ++++--- nest/rt-table.c | 53 +++++++++++++++++++++++++++++++++++++---------------- 3 files changed, 44 insertions(+), 19 deletions(-) (limited to 'nest/proto.c') diff --git a/nest/proto.c b/nest/proto.c index 623585f1..b7dbae5e 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -468,6 +468,7 @@ channel_start_import(struct channel *c) c->in_req = (struct rt_import_request) { .name = rn, + .list = proto_work_list(c->proto), .trace_routes = c->debug | c->proto->debug, .dump_req = channel_dump_import_req, .log_state_change = channel_import_log_state_change, @@ -886,6 +887,7 @@ channel_setup_in_table(struct channel *c, int best) c->in_table = &cat->cat; c->in_table->push = (struct rt_import_request) { .name = cat->name, + .list = proto_work_list(c->proto), .trace_routes = c->debug | c->proto->debug, .dump_req = channel_in_push_dump_req, .log_state_change = channel_push_log_state_change, @@ -928,6 +930,7 @@ channel_setup_out_table(struct channel *c) c->out_table = &cat->cat; c->out_table->push = (struct rt_import_request) { .name = cat->name, + .list = proto_work_list(c->proto), .trace_routes = c->debug | c->proto->debug, .dump_req = channel_out_push_dump_req, .log_state_change = channel_push_log_state_change, diff --git a/nest/route.h b/nest/route.h index 9417d97d..3f8bf433 100644 --- a/nest/route.h +++ b/nest/route.h @@ -170,6 +170,7 @@ typedef struct rtable_private { struct hmap id_map; struct hostcache *hostcache; struct event *prune_event; /* Event to prune abandoned routes */ + struct event *announce_event; /* Event to announce pending exports */ struct event *ec_event; /* Event to prune finished exports */ struct event *hcu_event; /* Event to update host cache */ struct event *delete_event; /* Event to delete the table */ @@ -191,8 +192,6 @@ typedef struct rtable_private { struct timer *settle_timer; /* Settle time for notifications */ list pending_exports; /* List of packed struct rt_pending_export */ - btime base_export_time; /* When first pending export was announced */ - struct timer *export_timer; struct rt_pending_export *first_export; /* First export to announce */ u64 next_export_seq; /* The next export will have this ID */ @@ -221,7 +220,6 @@ struct rtable_config { byte sorted; /* Routes of network are sorted according to rte_better() */ btime min_settle_time; /* Minimum settle time for notifications */ btime max_settle_time; /* Maximum settle time for notifications */ - btime export_settle_time; /* Delay before exports are announced */ uint cork_limit; /* Amount of routes to be pending on export to cork imports */ }; @@ -309,6 +307,8 @@ struct rt_import_request { char *name; u8 trace_routes; + event_list *list; /* Where to schedule import events */ + void (*dump_req)(struct rt_import_request *req); void (*log_state_change)(struct rt_import_request *req, u8 state); /* Preimport is called when the @new route is just-to-be inserted, replacing @old. @@ -339,6 +339,7 @@ struct rt_import_hook { u8 stale_pruned; /* Last prune finished when this value was set at stale_valid */ u8 stale_pruning; /* Last prune started when this value was set at stale_valid */ + struct event *export_announce_event; /* Event to run to announce new exports */ struct event *stopped; /* Event to run when import is stopped */ }; diff --git a/nest/rt-table.c b/nest/rt-table.c index f304372f..f33b9153 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -1023,8 +1023,6 @@ rte_announce(rtable_private *tab, net *net, struct rte_storage *new, struct rte_ rt_notify_hostcache(tab, net); } - rt_schedule_notify(tab); - if (EMPTY_LIST(tab->exports) && EMPTY_LIST(tab->pending_exports)) { /* No export hook and no pending exports to cleanup. We may free the route immediately. */ @@ -1105,10 +1103,7 @@ rte_announce(rtable_private *tab, net *net, struct rte_storage *new, struct rte_ { ev_cork(&rt_cork); tab->cork_active = 1; - tm_start_in(tab->export_timer, 0, tab->loop); } - else if (!tm_active(tab->export_timer)) - tm_start_in(tab->export_timer, tab->config->export_settle_time, tab->loop); } static struct rt_pending_export * @@ -1158,11 +1153,13 @@ rt_send_export_event(struct rt_export_hook *hook) } static void -rt_announce_exports(timer *tm) +rt_announce_exports(void *data) { - rtable_private *tab = tm->data; + rtable_private *tab = data; ASSERT_DIE(birdloop_inside(tab->loop)); + rt_schedule_notify(tab); + struct rt_export_hook *c; node *n; WALK_LIST2(c, n, tab->exports, n) { @@ -1173,6 +1170,26 @@ rt_announce_exports(timer *tm) } } +static void +rt_import_announce_exports(void *data) +{ + struct rt_import_hook *hook = data; + RT_LOCKED(hook->table, tab) + { + if (hook->import_state == TIS_CLEARED) + { + rfree(hook->export_announce_event); + + ev_send(hook->stopped->list, hook->stopped); + rem_node(&hook->n); + mb_free(hook); + rt_unlock_table(tab); + } + else + ev_send_loop(tab->loop, tab->announce_event); + } +} + static struct rt_pending_export * rt_last_export(rtable_private *tab) { @@ -1471,6 +1488,8 @@ rte_recalculate(rtable_private *table, struct rt_import_hook *c, net *net, rte * rte_announce(table, net, new_stored, old_stored, net->routes, old_best_stored); + ev_send(req->list, c->export_announce_event); + if (!net->routes && (table->gc_counter++ >= table->config->gc_max_ops) && (table->gc_time + table->config->gc_min_time <= current_time())) @@ -1709,6 +1728,8 @@ rt_request_import(rtable *t, struct rt_import_request *req) hook->req = req; hook->table = t; + hook->export_announce_event = ev_new_init(tab->rp, rt_import_announce_exports, hook); + if (!hook->stale_set) hook->stale_set = hook->stale_valid = hook->stale_pruning = hook->stale_pruned = 1; @@ -1727,11 +1748,12 @@ rt_stop_import(struct rt_import_request *req, event *stopped) struct rt_import_hook *hook = req->hook; RT_LOCK(hook->table); + rt_schedule_prune(RT_PRIV(hook->table)); rt_set_import_state(hook, TIS_STOP); - hook->stopped = stopped; + RT_UNLOCK(hook->table); } @@ -2158,6 +2180,7 @@ rt_setup(pool *pp, struct rtable_config *cf) t->loop = birdloop_new(p, DOMAIN_ORDER(rtable), nb); + t->announce_event = ev_new_init(p, rt_announce_exports, t); t->ec_event = ev_new_init(p, rt_export_cleanup, t); t->prune_event = ev_new_init(p, rt_prune_table, t); t->hcu_event = ev_new_init(p, rt_update_hostcache, t); @@ -2166,7 +2189,6 @@ rt_setup(pool *pp, struct rtable_config *cf) t->nhu_event->cork = &rt_cork; t->prune_event->cork = &rt_cork; - t->export_timer = tm_new_init(p, rt_announce_exports, t, 0, 0); t->last_rt_change = t->gc_time = current_time(); t->next_export_seq = 1; @@ -2472,15 +2494,11 @@ done:; if (!first_export || (first_export->seq >= ih->flush_seq)) { ih->import_state = TIS_CLEARED; - ev_send(ih->stopped->list, ih->stopped); - rem_node(&ih->n); - mb_free(ih); - rt_unlock_table(tab); + ev_send(ih->req->list, ih->export_announce_event); } - - if (EMPTY_LIST(tab->pending_exports) && tm_active(tab->export_timer)) - tm_stop(tab->export_timer); + if (EMPTY_LIST(tab->pending_exports) && ev_active(tab->announce_event)) + ev_postpone(tab->announce_event); /* If reduced to at most one export block pending */ if (tab->cork_active && @@ -2753,6 +2771,8 @@ rt_next_hop_update(void *data) if (atomic_fetch_and_explicit(&tab->nhu_state, NHU_SCHEDULED, memory_order_acq_rel) != NHU_RUNNING) ev_send_loop(tab->loop, tab->nhu_event); + ev_send_loop(tab->loop, tab->announce_event); + rt_unlock_table(tab); } @@ -2809,6 +2829,7 @@ rt_loop_stopped(void *data) r->loop = NULL; r->prune_event->list = r->ec_event->list = NULL; r->nhu_event->list = r->hcu_event->list = NULL; + r->announce_event->list = NULL; ev_send(r->delete_event->list, r->delete_event); } -- cgit v1.2.3 From 4f3fa1623f66acd24c227cf0cc5a4af2f5133b6c Mon Sep 17 00:00:00 2001 From: Maria Matejka Date: Mon, 18 Oct 2021 21:22:58 +0200 Subject: Pipe runs in parallel. --- nest/proto.c | 1 + proto/pipe/config.Y | 1 + 2 files changed, 2 insertions(+) (limited to 'nest/proto.c') diff --git a/nest/proto.c b/nest/proto.c index 4ae0cbfd..623585f1 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -1413,6 +1413,7 @@ proto_event(void *ptr) { if (p->proto == &proto_unix_iface) if_flush_ifaces(p); + p->do_stop = 0; } diff --git a/proto/pipe/config.Y b/proto/pipe/config.Y index c869de9f..fc08445f 100644 --- a/proto/pipe/config.Y +++ b/proto/pipe/config.Y @@ -25,6 +25,7 @@ proto: pipe_proto '}' { this_channel = NULL; } ; pipe_proto_start: proto_start PIPE { this_proto = proto_config_new(&proto_pipe, $1); + this_proto->loop_order = DOMAIN_ORDER(proto); PIPE_CFG->max_generation = 16; } proto_name -- cgit v1.2.3 From adf37d8eff8f281871295c402a51ae1dd654851c Mon Sep 17 00:00:00 2001 From: Maria Matejka Date: Mon, 15 Nov 2021 10:53:58 +0100 Subject: VRF setting reduced to one argument, using default dummy iface for default vrf --- nest/config.Y | 4 ++-- nest/iface.c | 13 +++++++++---- nest/iface.h | 2 ++ nest/neighbor.c | 10 +++++----- nest/proto.c | 8 +++----- nest/protocol.h | 2 -- proto/bfd/bfd.c | 2 +- 7 files changed, 22 insertions(+), 19 deletions(-) (limited to 'nest/proto.c') diff --git a/nest/config.Y b/nest/config.Y index 6e7689ed..0914048b 100644 --- a/nest/config.Y +++ b/nest/config.Y @@ -266,8 +266,8 @@ proto_item: | MRTDUMP mrtdump_mask { this_proto->mrtdump = $2; } | ROUTER ID idval { this_proto->router_id = $3; } | DESCRIPTION text { this_proto->dsc = $2; } - | VRF text { this_proto->vrf = if_get_by_name($2); this_proto->vrf_set = 1; } - | VRF DEFAULT { this_proto->vrf = NULL; this_proto->vrf_set = 1; } + | VRF text { this_proto->vrf = if_get_by_name($2); } + | VRF DEFAULT { this_proto->vrf = &default_vrf; } ; diff --git a/nest/iface.c b/nest/iface.c index 83a633a3..5cb9e814 100644 --- a/nest/iface.c +++ b/nest/iface.c @@ -37,6 +37,7 @@ static pool *if_pool; list iface_list; +struct iface default_vrf; static void if_recalc_preferred(struct iface *i); @@ -147,7 +148,7 @@ ifa_send_notify(struct proto *p, unsigned c, struct ifa *a) { if (p->ifa_notify && (p->proto_state != PS_DOWN) && - (!p->vrf_set || p->vrf == a->iface->master)) + (!p->vrf || p->vrf == a->iface->master)) { if (p->debug & D_IFACES) log(L_TRACE "%s < address %N on interface %s %s", @@ -185,7 +186,7 @@ if_send_notify(struct proto *p, unsigned c, struct iface *i) { if (p->if_notify && (p->proto_state != PS_DOWN) && - (!p->vrf_set || p->vrf == i->master)) + (!p->vrf || p->vrf == i->master)) { if (p->debug & D_IFACES) log(L_TRACE "%s < interface %s %s", p->name, i->name, @@ -243,7 +244,7 @@ if_recalc_flags(struct iface *i UNUSED, uint flags) { if ((flags & IF_ADMIN_UP) && !(flags & (IF_SHUTDOWN | IF_TMP_DOWN)) && - !(i->master_index && !i->master)) + !(i->master_index && i->master == &default_vrf)) flags |= IF_UP; else flags &= ~IF_UP; @@ -301,6 +302,9 @@ if_update(struct iface *new) struct iface *i; unsigned c; + if (!new->master) + new->master = &default_vrf; + WALK_LIST(i, iface_list) if (!strcmp(new->name, i->name)) { @@ -711,6 +715,7 @@ if_init(void) { if_pool = rp_new(&root_pool, "Interfaces"); init_list(&iface_list); + strcpy(default_vrf.name, "default"); neigh_init(if_pool); } @@ -843,7 +848,7 @@ if_show(void) continue; char mbuf[16 + sizeof(i->name)] = {}; - if (i->master) + if (i->master != &default_vrf) bsprintf(mbuf, " master=%s", i->master->name); else if (i->master_index) bsprintf(mbuf, " master=#%u", i->master_index); diff --git a/nest/iface.h b/nest/iface.h index 1189cdd4..13f3bd12 100644 --- a/nest/iface.h +++ b/nest/iface.h @@ -28,6 +28,8 @@ struct ifa { /* Interface address */ unsigned flags; /* Analogous to iface->flags */ }; +extern struct iface default_vrf; + struct iface { node n; char name[16]; diff --git a/nest/neighbor.c b/nest/neighbor.c index 1a31fb79..cb2d1b2b 100644 --- a/nest/neighbor.c +++ b/nest/neighbor.c @@ -142,7 +142,7 @@ if_connected(ip_addr a, struct iface *i, struct ifa **ap, uint flags) } static inline int -if_connected_any(ip_addr a, struct iface *vrf, uint vrf_set, struct iface **iface, struct ifa **addr, uint flags) +if_connected_any(ip_addr a, struct iface *vrf, struct iface **iface, struct ifa **addr, uint flags) { struct iface *i; struct ifa *b; @@ -153,7 +153,7 @@ if_connected_any(ip_addr a, struct iface *vrf, uint vrf_set, struct iface **ifac /* Prefer SCOPE_HOST or longer prefix */ WALK_LIST(i, iface_list) - if ((!vrf_set || vrf == i->master) && ((s = if_connected(a, i, &b, flags)) >= 0)) + if ((!vrf || vrf == i->master) && ((s = if_connected(a, i, &b, flags)) >= 0)) if (scope_better(s, scope) || (scope_remote(s, scope) && ifa_better(b, *addr))) { *iface = i; @@ -245,7 +245,7 @@ neigh_find(struct proto *p, ip_addr a, struct iface *iface, uint flags) iface = (scope < 0) ? NULL : iface; } else - scope = if_connected_any(a, p->vrf, p->vrf_set, &iface, &addr, flags); + scope = if_connected_any(a, p->vrf, &iface, &addr, flags); /* scope < 0 means i don't know neighbor */ /* scope >= 0 <=> iface != NULL */ @@ -369,7 +369,7 @@ neigh_update(neighbor *n, struct iface *iface) return; /* VRF-bound neighbors ignore changes in other VRFs */ - if (p->vrf_set && (p->vrf != iface->master)) + if (p->vrf && (p->vrf != iface->master)) return; scope = if_connected(n->addr, iface, &ifa, n->flags); @@ -379,7 +379,7 @@ neigh_update(neighbor *n, struct iface *iface) { /* When neighbor is going down, try to respawn it on other ifaces */ if ((scope < 0) && (n->scope >= 0) && !n->ifreq && (n->flags & NEF_STICKY)) - scope = if_connected_any(n->addr, p->vrf, p->vrf_set, &iface, &ifa, n->flags); + scope = if_connected_any(n->addr, p->vrf, &iface, &ifa, n->flags); } else { diff --git a/nest/proto.c b/nest/proto.c index b7dbae5e..8babedee 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -1469,7 +1469,6 @@ proto_init(struct proto_config *c, node *n) p->proto_state = PS_DOWN; p->last_state_change = current_time(); p->vrf = c->vrf; - p->vrf_set = c->vrf_set; insert_node(&p->n, n); p->event = ev_new_init(proto_pool, proto_event, p); @@ -1654,8 +1653,7 @@ proto_reconfigure(struct proto *p, struct proto_config *oc, struct proto_config if ((nc->protocol != oc->protocol) || (nc->net_type != oc->net_type) || (nc->disabled != p->disabled) || - (nc->vrf != oc->vrf) || - (nc->vrf_set != oc->vrf_set)) + (nc->vrf != oc->vrf)) return 0; p->name = nc->name; @@ -2626,8 +2624,8 @@ proto_cmd_show(struct proto *p, uintptr_t verbose, int cnt) cli_msg(-1006, " Message: %s", p->message); if (p->cf->router_id) cli_msg(-1006, " Router ID: %R", p->cf->router_id); - if (p->vrf_set) - cli_msg(-1006, " VRF: %s", p->vrf ? p->vrf->name : "default"); + if (p->vrf) + cli_msg(-1006, " VRF: %s", p->vrf->name); if (p->proto->show_proto_info) p->proto->show_proto_info(p); diff --git a/nest/protocol.h b/nest/protocol.h index 8d077e44..1d4f2059 100644 --- a/nest/protocol.h +++ b/nest/protocol.h @@ -117,7 +117,6 @@ struct proto_config { int class; /* SYM_PROTO or SYM_TEMPLATE */ u8 net_type; /* Protocol network type (NET_*), 0 for undefined */ u8 disabled; /* Protocol enabled/disabled by default */ - u8 vrf_set; /* Related VRF instance (below) is defined */ u8 late_if_feed; /* Delay interface feed after channels are up */ u32 debug, mrtdump; /* Debugging bitfields, both use D_* constants */ u32 router_id; /* Protocol specific router ID */ @@ -154,7 +153,6 @@ struct proto { uint active_coroutines; /* Number of active coroutines */ byte net_type; /* Protocol network type (NET_*), 0 for undefined */ byte disabled; /* Manually disabled */ - byte vrf_set; /* Related VRF instance (above) is defined */ byte proto_state; /* Protocol state machine (PS_*, see below) */ byte active; /* From PS_START to cleanup after PS_STOP */ byte do_stop; /* Stop actions are scheduled */ diff --git a/proto/bfd/bfd.c b/proto/bfd/bfd.c index 3964c267..dd3488d4 100644 --- a/proto/bfd/bfd.c +++ b/proto/bfd/bfd.c @@ -658,7 +658,7 @@ bfd_add_request(struct bfd_proto *p, struct bfd_request *req) { struct bfd_config *cf = (struct bfd_config *) (p->p.cf); - if (p->p.vrf_set && (p->p.vrf != req->vrf)) + if (p->p.vrf && (p->p.vrf != req->vrf)) return 0; if (ipa_is_ip4(req->addr) ? !cf->accept_ipv4 : !cf->accept_ipv6) -- cgit v1.2.3 From 974f16b1f70ae8b7fa4efa6a217988e1811069e7 Mon Sep 17 00:00:00 2001 From: Maria Matejka Date: Fri, 9 Sep 2022 15:04:36 +0200 Subject: Created a dedicated settle timer structure --- conf/confbase.Y | 10 +++++++++ doc/bird.sgml | 17 +++++++-------- lib/settle.h | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ nest/config.Y | 6 ++---- nest/proto.c | 53 ++++++++++++++++++++--------------------------- nest/protocol.h | 7 +++---- 6 files changed, 110 insertions(+), 47 deletions(-) create mode 100644 lib/settle.h (limited to 'nest/proto.c') diff --git a/conf/confbase.Y b/conf/confbase.Y index 241c332d..8e5da9e3 100644 --- a/conf/confbase.Y +++ b/conf/confbase.Y @@ -14,6 +14,7 @@ CF_HDR #include "conf/conf.h" #include "lib/resource.h" #include "lib/socket.h" +#include "lib/settle.h" #include "lib/timer.h" #include "lib/string.h" #include "nest/protocol.h" @@ -93,6 +94,7 @@ CF_DECLS struct proto_spec ps; struct channel_limit cl; struct timeformat *tf; + struct settle_config settle; struct adata *ad; struct bytestring *bs; } @@ -111,6 +113,7 @@ CF_DECLS %type expr bool pxlen4 %type