]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Nest: Add command to request graceful restart
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Tue, 18 Jun 2019 14:27:21 +0000 (16:27 +0200)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Sun, 30 Jun 2019 19:29:24 +0000 (21:29 +0200)
When 'graceful down' command is entered, protocols are shut down
with regard to graceful restart. Namely Kernel protocol does
not remove routes and BGP protocol does not send notification,
just closes the connection.

conf/conf.c
conf/conf.h
doc/reply_codes
nest/proto.c
nest/protocol.h
proto/bgp/bgp.c
proto/bgp/bgp.h
sysdep/unix/config.Y
sysdep/unix/krt.c
sysdep/unix/main.c
sysdep/unix/unix.h

index d6b3e8e8e6808b9459df562223e8c3453c7fcd98..0b797dec2c51caa59fb5bed4caee3ec108918989 100644 (file)
@@ -492,19 +492,24 @@ config_init(void)
  * for switching to an empty configuration.
  */
 void
-order_shutdown(void)
+order_shutdown(int gr)
 {
   struct config *c;
 
   if (shutting_down)
     return;
 
-  log(L_INFO "Shutting down");
+  if (!gr)
+    log(L_INFO "Shutting down");
+  else
+    log(L_INFO "Shutting down for graceful restart");
+
   c = lp_alloc(config->mem, sizeof(struct config));
   memcpy(c, config, sizeof(struct config));
   init_list(&c->protos);
   init_list(&c->tables);
   c->shutdown = 1;
+  c->gr_down = gr;
 
   config_commit(c, RECONFIG_HARD, 0);
   shutting_down = 1;
index 51dcb989a03539fb2fec51b69c2ed4c062eaa6ca..777a1fca7db616f06c47224051c045cefb419c57 100644 (file)
@@ -55,6 +55,7 @@ struct config {
   struct sym_scope *root_scope;                /* Scope for root symbols */
   int obstacle_count;                  /* Number of items blocking freeing of this config */
   int shutdown;                                /* This is a pseudo-config for daemon shutdown */
+  int gr_down;                         /* This is a pseudo-config for graceful restart */
   btime load_time;                     /* When we've got this configuration */
 };
 
@@ -75,7 +76,7 @@ void config_init(void);
 void cf_error(const char *msg, ...) NORET;
 void config_add_obstacle(struct config *);
 void config_del_obstacle(struct config *);
-void order_shutdown(void);
+void order_shutdown(int gr);
 
 #define RECONFIG_NONE  0
 #define RECONFIG_HARD  1
index 3a7f2c907b17c5926f477a1ed8f359be09997f22..02f4e656084891aa21e41cdaa8c02746f4d2a156 100644 (file)
@@ -33,6 +33,7 @@ Reply codes of BIRD command-line interface
 0022   Undo scheduled
 0023   Evaluation of expression
 0024   Graceful restart status report
+0025   Graceful restart ordered
 
 1000   BIRD version
 1001   Interface list
index 415471c4bc473f7b63384a7c3540b205de9fe289..beb3f393680ba6df4d8d6a2e61b659d34d13e604 100644 (file)
@@ -1048,6 +1048,11 @@ protos_commit(struct config *new, struct config *old, int force_reconfig, int ty
        p->down_code = PDC_CF_REMOVE;
        p->cf_new = NULL;
       }
+      else if (new->gr_down)
+      {
+       p->down_code = PDC_CMD_GR_DOWN;
+       p->cf_new = NULL;
+      }
       else /* global shutdown */
       {
        p->down_code = PDC_CMD_SHUTDOWN;
index b26d9cc1f652cc3b5aaa970d4358d77691bd3adc..53cccd5b63587dc59becf303ad730fa6189f8194 100644 (file)
@@ -257,6 +257,7 @@ struct proto_spec {
 #define PDC_CMD_DISABLE                0x11    /* Result of disable command */
 #define PDC_CMD_RESTART                0x12    /* Result of restart command */
 #define PDC_CMD_SHUTDOWN       0x13    /* Result of global shutdown */
+#define PDC_CMD_GR_DOWN                0x14    /* Result of global graceful restart */
 #define PDC_RX_LIMIT_HIT       0x21    /* Route receive limit reached */
 #define PDC_IN_LIMIT_HIT       0x22    /* Route import limit reached */
 #define PDC_OUT_LIMIT_HIT      0x23    /* Route export limit reached */
index 470c6ff52303484dcc95c41dd4d926683aba30d8..cfc31ed0093f1fc936299a0366aa6d32a0a4d027 100644 (file)
@@ -422,7 +422,7 @@ bgp_update_startup_delay(struct bgp_proto *p)
 }
 
 static void
-bgp_graceful_close_conn(struct bgp_conn *conn, uint subcode, byte *data, uint len)
+bgp_graceful_close_conn(struct bgp_conn *conn, int subcode, byte *data, uint len)
 {
   switch (conn->state)
   {
@@ -438,7 +438,13 @@ bgp_graceful_close_conn(struct bgp_conn *conn, uint subcode, byte *data, uint le
   case BS_OPENSENT:
   case BS_OPENCONFIRM:
   case BS_ESTABLISHED:
-    bgp_error(conn, 6, subcode, data, len);
+    if (subcode < 0)
+    {
+      bgp_conn_enter_close_state(conn);
+      bgp_schedule_packet(conn, NULL, PKT_SCHEDULE_CLOSE);
+    }
+    else
+      bgp_error(conn, 6, subcode, data, len);
     return;
 
   default:
@@ -501,7 +507,7 @@ bgp_spawn(struct bgp_proto *pp, ip_addr remote_ip)
 }
 
 void
-bgp_stop(struct bgp_proto *p, uint subcode, byte *data, uint len)
+bgp_stop(struct bgp_proto *p, int subcode, byte *data, uint len)
 {
   proto_notify_state(&p->p, PS_STOP);
   bgp_graceful_close_conn(&p->outgoing_conn, subcode, data, len);
@@ -1555,7 +1561,7 @@ static int
 bgp_shutdown(struct proto *P)
 {
   struct bgp_proto *p = (struct bgp_proto *) P;
-  uint subcode = 0;
+  int subcode = 0;
 
   char *message = NULL;
   byte *data = NULL;
@@ -1576,6 +1582,7 @@ bgp_shutdown(struct proto *P)
 
   case PDC_CMD_DISABLE:
   case PDC_CMD_SHUTDOWN:
+  shutdown:
     subcode = 2; // Errcode 6, 2 - administrative shutdown
     message = P->message;
     break;
@@ -1585,6 +1592,14 @@ bgp_shutdown(struct proto *P)
     message = P->message;
     break;
 
+  case PDC_CMD_GR_DOWN:
+    if ((p->cf->gr_mode != BGP_GR_ABLE) &&
+       (p->cf->llgr_mode != BGP_LLGR_ABLE))
+      goto shutdown;
+
+    subcode = -1; // Do not send NOTIFICATION, just close the connection
+    break;
+
   case PDC_RX_LIMIT_HIT:
   case PDC_IN_LIMIT_HIT:
     subcode = 1; // Errcode 6, 1 - max number of prefixes reached
index d8c9fe94ea76b492442435a5b466842e202c2a72..d7f7427f2b008c0f818f2c955cd936f97c2e25ab 100644 (file)
@@ -488,7 +488,7 @@ void bgp_graceful_restart_done(struct bgp_channel *c);
 void bgp_refresh_begin(struct bgp_channel *c);
 void bgp_refresh_end(struct bgp_channel *c);
 void bgp_store_error(struct bgp_proto *p, struct bgp_conn *c, u8 class, u32 code);
-void bgp_stop(struct bgp_proto *p, uint subcode, byte *data, uint len);
+void bgp_stop(struct bgp_proto *p, int subcode, byte *data, uint len);
 
 struct rte_source *bgp_find_source(struct bgp_proto *p, u32 path_id);
 struct rte_source *bgp_get_source(struct bgp_proto *p, u32 path_id);
index 2895a69e57ceae9c12e58a1eb73742018bb1cea0..b78e0e6c36855c064b40d95adf7ec1f8d45e01e2 100644 (file)
@@ -133,6 +133,10 @@ CF_CLI(CONFIGURE CHECK, cfg_name, [\"<file>\"], [[Parse configuration and check
 CF_CLI(DOWN,,, [[Shut the daemon down]])
 { cmd_shutdown(); } ;
 
+CF_CLI(GRACEFUL DOWN,,, [[Shut the daemon down for graceful restart]])
+{ cmd_graceful_restart(); } ;
+
+
 cfg_name:
    /* empty */ { $$ = NULL; }
  | TEXT
index 3aee3fe2cc3ea06f7653e41ad815e788083a2617..f0e78442a55b798d4f0839d62078067fe9dd7458 100644 (file)
@@ -1129,7 +1129,7 @@ krt_shutdown(struct proto *P)
   krt_scan_timer_stop(p);
 
   /* FIXME we should flush routes even when persist during reconfiguration */
-  if (p->initialized && !KRT_CF->persist)
+  if (p->initialized && !KRT_CF->persist && (P->down_code != PDC_CMD_GR_DOWN))
     krt_flush_routes(p);
 
   p->ready = 0;
index c381b44fc9cf55e3d3d15576d0bf97875b060e86..39465aa8821c5036f3bc444dbc86475e6143ae1c 100644 (file)
@@ -565,14 +565,14 @@ cmd_shutdown(void)
     return;
 
   cli_msg(7, "Shutdown requested");
-  order_shutdown();
+  order_shutdown(0);
 }
 
 void
 async_shutdown(void)
 {
   DBG("Shutting down...\n");
-  order_shutdown();
+  order_shutdown(0);
 }
 
 void
@@ -584,6 +584,17 @@ sysdep_shutdown_done(void)
   exit(0);
 }
 
+void
+cmd_graceful_restart(void)
+{
+  if (cli_access_restricted())
+    return;
+
+  cli_msg(25, "Graceful restart requested");
+  order_shutdown(1);
+}
+
+
 /*
  *     Signals
  */
index d5ce8ff99b6b3e09a34880731c53a3be6b9921be..bf0aedeba08218791c20537aac39965b55cee7c6 100644 (file)
@@ -28,6 +28,7 @@ void cmd_reconfig_confirm(void);
 void cmd_reconfig_undo(void);
 void cmd_reconfig_status(void);
 void cmd_shutdown(void);
+void cmd_graceful_restart(void);
 
 #define UNIX_DEFAULT_CONFIGURE_TIMEOUT 300