]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Channels now can have external obstacles temporarily blocking their shutdown
authorMaria Matejka <mq@ucw.cz>
Fri, 24 Nov 2023 11:19:44 +0000 (12:19 +0100)
committerMaria Matejka <mq@ucw.cz>
Mon, 8 Jan 2024 12:03:25 +0000 (13:03 +0100)
nest/proto.c
nest/protocol.h

index 72d94a282646a4bc6879633bfc477b1bcfb4b082..6427afcd266ce369e259b99c1212a8a7597aee4f 100644 (file)
@@ -745,7 +745,7 @@ channel_check_stopped(struct channel *c)
   switch (c->channel_state)
   {
     case CS_STOP:
-      if (!EMPTY_LIST(c->roa_subscriptions) || c->out_req.hook || c->refeed_req.hook || c->in_req.hook || c->reload_req.hook)
+      if (c->obstacles || !EMPTY_LIST(c->roa_subscriptions) || c->out_req.hook || c->refeed_req.hook || c->in_req.hook || c->reload_req.hook)
        return;
 
       channel_set_state(c, CS_DOWN);
@@ -753,7 +753,7 @@ channel_check_stopped(struct channel *c)
 
       break;
     case CS_PAUSE:
-      if (!EMPTY_LIST(c->roa_subscriptions) || c->out_req.hook || c->refeed_req.hook || c->reload_req.hook)
+      if (c->obstacles || !EMPTY_LIST(c->roa_subscriptions) || c->out_req.hook || c->refeed_req.hook || c->reload_req.hook)
        return;
 
       channel_set_state(c, CS_START);
@@ -763,6 +763,19 @@ channel_check_stopped(struct channel *c)
   DBG("%s.%s: Channel requests/hooks stopped (in state %s)\n", c->proto->name, c->name, c_states[c->channel_state]);
 }
 
+void
+channel_add_obstacle(struct channel *c)
+{
+  c->obstacles++;
+}
+
+void
+channel_del_obstacle(struct channel *c)
+{
+  if (!--c->obstacles)
+    channel_check_stopped(c);
+}
+
 void
 channel_import_stopped(struct rt_import_request *req)
 {
index 9b8b837d1fd6180d698d73a9dd582bf28e2b9580..4c983ffc903b3ab37a9d366cc95efeca8e84465c 100644 (file)
@@ -605,6 +605,8 @@ struct channel {
   u8 gr_lock;                          /* Graceful restart mechanism should wait for this channel */
   u8 gr_wait;                          /* Route export to channel is postponed until graceful restart */
 
+  u32 obstacles;                       /* External obstacles remaining before cleanup */
+
   btime last_state_change;             /* Time of last state transition */
 
   struct rt_export_request reload_req; /* Feeder for import reload */
@@ -692,6 +694,9 @@ void channel_set_state(struct channel *c, uint state);
 void channel_schedule_reload(struct channel *c, struct channel_import_request *cir);
 int channel_import_request_prefilter(struct channel_import_request *cir_head, const net_addr *n);
 
+void channel_add_obstacle(struct channel *c);
+void channel_del_obstacle(struct channel *c);
+
 static inline void channel_init(struct channel *c) { channel_set_state(c, CS_START); }
 static inline void channel_open(struct channel *c) { channel_set_state(c, CS_UP); }
 static inline void channel_close(struct channel *c) { channel_set_state(c, CS_STOP); }