]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Proto: deferring start from proto_enable
authorMaria Matejka <mq@ucw.cz>
Thu, 18 Sep 2025 10:43:44 +0000 (12:43 +0200)
committerMaria Matejka <mq@ucw.cz>
Mon, 22 Sep 2025 11:35:02 +0000 (13:35 +0200)
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.

nest/proto.c

index eb556b9789ead0cbb6a1e8e3d3183a5d11a124ed..7c0186de37f075c7cfb822c3f34a3969a83c71fe 100644 (file)
@@ -1938,6 +1938,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)
 {
@@ -1963,7 +1975,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;
 }
 
@@ -2826,7 +2842,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);
 }