From: Maria Matejka Date: Thu, 18 Sep 2025 10:43:44 +0000 (+0200) Subject: Proto: deferring start from proto_enable X-Git-Tag: v3.2.0~48 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ea44fd80a839da6398f4c90c604e111a8534dee6;p=thirdparty%2Fbird.git Proto: deferring start from proto_enable When the enable command is issued from CLI, we actually do not need to enable the protocol right away, it's enough to run the rethink goal function later from a deferred context. This allows us to change the protocol's loop safely. --- diff --git a/nest/proto.c b/nest/proto.c index be347ea3e..0b10666d8 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -1950,6 +1950,18 @@ done: ); } +struct proto_rethink_goal_deferred { + struct deferred_call dc; + struct proto *p; +}; + +static void +proto_rethink_goal_deferred(struct deferred_call *dc) +{ + SKIP_BACK_DECLARE(struct proto_rethink_goal_deferred, prgd, dc, dc); + proto_rethink_goal(prgd->p); +} + struct proto * proto_spawn(struct proto_config *cf, uint disabled) { @@ -1975,7 +1987,11 @@ proto_enable(struct proto *p) ASSERT_DIE(birdloop_inside(&main_birdloop)); bool changed = p->disabled; p->disabled = 0; - proto_rethink_goal(p); + struct proto_rethink_goal_deferred prgd = { + .dc.hook = proto_rethink_goal_deferred, + .p = p, + }; + defer_call(&prgd.dc, sizeof prgd); return changed; } @@ -2838,7 +2854,11 @@ proto_cmd_enable(struct proto *p, uintptr_t arg, int cnt UNUSED) log(L_INFO "Enabling protocol %s", p->name); p->disabled = 0; proto_set_message(p, (char *) arg, -1); - proto_rethink_goal(p); + struct proto_rethink_goal_deferred prgd = { + .dc.hook = proto_rethink_goal_deferred, + .p = p, + }; + defer_call(&prgd.dc, sizeof prgd); cli_msg(-11, "%s: enabled", p->name); }