HASH_REMOVE(p->session_hash_id, HASH_ID, s);
HASH_REMOVE(p->session_hash_ip, HASH_IP, s);
- sl_free(s);
-
- TRACE(D_EVENTS, "Session to %I removed", ip);
+ TRACE(D_EVENTS, "Session to %I removed", s->addr);
- birdloop_leave(p->loop);
+ sl_free(s);
}
+struct bfd_reconfigure_sessions_deferred_call {
+ struct deferred_call dc;
+ struct bfd_proto *p;
+ config_ref old_config;
+};
+
static void
-bfd_reconfigure_session(struct bfd_proto *p, struct bfd_session *s)
+bfd_reconfigure_sessions(struct deferred_call *dc)
{
- if (EMPTY_LIST(s->request_list))
- return;
+ SKIP_BACK_DECLARE(struct bfd_reconfigure_sessions_deferred_call,
+ brsdc, dc, dc);
- birdloop_enter(p->loop);
+ struct bfd_proto *p = brsdc->p;
+ birdloop_enter(p->p.loop);
+ birdloop_enter(p->eloop);
+
+ /* Very much hoping that this is not too slow to cause significant delays. */
- struct bfd_request *req = SKIP_BACK(struct bfd_request, n, HEAD(s->request_list));
- s->cf = bfd_merge_options(s->ifa->cf, &req->opts);
+ HASH_WALK(p->session_hash_id, next_id, s)
+ {
+ if (!EMPTY_TLIST(bfd_request, &s->request_list))
+ {
+ struct bfd_request *req = THEAD(bfd_request, &s->request_list);
+ struct bfd_options opts = bfd_merge_options(&s->ifa->cf->opts, &req->opts);
+
+#define CHK(x) (opts.x != s->cf.x) ||
+ bool reload = MACRO_FOREACH(CHK,
+ min_rx_int,
+ min_tx_int,
+ idle_tx_int,
+ multiplier,
++ auth_type,
++ passwords,
+ passive) false; /* terminating the || chain */
+#undef CHK
+
+ s->cf = opts;
+
+ if (reload)
+ {
+ struct bfd_state_pair sp = atomic_load_explicit(&s->state, memory_order_relaxed);
+ u32 tx = (sp.loc.state == BFD_STATE_UP) ? s->cf.min_tx_int : s->cf.idle_tx_int;
+ bfd_session_set_min_tx(s, tx);
+ bfd_session_set_min_rx(s, s->cf.min_rx_int);
+ s->detect_mult = s->cf.multiplier;
+ s->passive = s->cf.passive;
- u32 tx = (s->loc_state == BFD_STATE_UP) ? s->cf.min_tx_int : s->cf.idle_tx_int;
- bfd_session_set_min_tx(s, tx);
- bfd_session_set_min_rx(s, s->cf.min_rx_int);
- s->detect_mult = s->cf.multiplier;
- s->passive = s->cf.passive;
+ bfd_session_control_tx_timer(s, 0);
- bfd_session_control_tx_timer(s, 0);
+ TRACE(D_EVENTS, "Session to %I reconfigured", s->addr);
+ }
+ }
+ }
+ HASH_WALK_END;
- birdloop_leave(p->loop);
+ birdloop_leave(p->eloop);
+ birdloop_leave(p->p.loop);
- TRACE(D_EVENTS, "Session to %I reconfigured", s->addr);
+ /* Now the config is clean */
+ OBSREF_CLEAR(brsdc->old_config);
}