summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_main.c')
-rw-r--r--bgpd/bgp_main.c84
1 files changed, 62 insertions, 22 deletions
diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c
index 0de28b9b..60b66533 100644
--- a/bgpd/bgp_main.c
+++ b/bgpd/bgp_main.c
@@ -75,20 +75,23 @@ static const struct option longopts[] =
{ "ignore_warnings", no_argument, NULL, 'I'},
{ 0 }
};
-/* Configuration file and directory. */
+/* Configuration file and directory. */
char config_default[] = SYSCONFDIR BGP_DEFAULT_CONFIG;
-/* Route retain mode flag. */
-static int retain_mode = 0;
+/* Route retain mode flag. */
+static bool retain_mode = false;
+
+/* Have started terminating the program */
+static bool program_terminating = false ;
/* whether to ignore warnings in configuration file */
static bool config_ignore_warnings = false;
/* whether configured to run with qpthreads */
-static bool config_threaded = 0;
+static bool config_threaded = false ;
/* whether configured to run as an AS2 speaker */
-static bool config_as2_speaker = 0;
+static bool config_as2_speaker = false ;
/* Master of threads. */
struct thread_master *master;
@@ -483,11 +486,11 @@ int
main (int argc, char **argv)
{
char *p;
- int opt;
- int daemon_mode = 0;
- int dryrun = 0;
+ int opt;
+ bool daemon_mode = false ;
+ bool dryrun = false ;
char *progname;
- int tmp_port;
+ int tmp_port;
/* Set umask before anything for security */
umask (0027);
@@ -520,7 +523,7 @@ main (int argc, char **argv)
case 0:
break;
case 'd':
- daemon_mode = 1;
+ daemon_mode = true ;
break;
case 'f':
config_file = optarg;
@@ -551,7 +554,7 @@ main (int argc, char **argv)
vty_port = BGP_VTY_PORT;
break;
case 'r':
- retain_mode = 1;
+ retain_mode = true ;
break;
case 'l':
bm->address = optarg;
@@ -570,19 +573,19 @@ main (int argc, char **argv)
exit (0);
break;
case 'C':
- dryrun = 1;
+ dryrun = true ;
break;
case 'h':
usage (progname, 0);
break;
case 't':
- config_threaded = 1;
+ config_threaded = true ;
break;
case 'I':
- config_ignore_warnings = 1;
+ config_ignore_warnings = true ;
break ;
case '2':
- config_as2_speaker = 1;
+ config_as2_speaker = true ;
break ;
default:
usage (progname, 1);
@@ -716,6 +719,10 @@ routing_background(void)
return thread_dispatch_background(master) ;
}
+/*==============================================================================
+ * SIGHUP and SIGTERM
+ */
+
/*------------------------------------------------------------------------------
* SIGHUP: message sent to Routeing engine and the action it then takes.
*
@@ -726,14 +733,14 @@ sighup_enqueue(void)
{
mqueue_block mqb = mqb_init_new(NULL, sighup_action, NULL) ;
- mqueue_enqueue(routing_nexus->queue, mqb, 1) ;
+ mqueue_enqueue(routing_nexus->queue, mqb, mqb_priority) ;
}
/* dispatch a command from the message queue block */
static void
sighup_action(mqueue_block mqb, mqb_flag_t flag)
{
- if (flag == mqb_action)
+ if ((flag == mqb_action) && !program_terminating)
{
zlog_info ("bgpd restarting!");
@@ -753,6 +760,32 @@ sighup_action(mqueue_block mqb, mqb_flag_t flag)
}
/*------------------------------------------------------------------------------
+ * Foreground task to see if all peers have been deleted yet.
+ */
+static int
+program_terminate_if_all_peers_deleted(void)
+{
+ if (bm->peer_linger_count == 0)
+ {
+ /* ask remaining pthreads to die
+ *
+ * Note that qpn_terminate does nothing if it has been called once
+ * already.
+ */
+ if (qpthreads_enabled && routing_nexus != NULL)
+ qpn_terminate(routing_nexus);
+
+ if (qpthreads_enabled && bgp_nexus != NULL)
+ qpn_terminate(bgp_nexus);
+
+ if (cli_nexus != NULL)
+ qpn_terminate(cli_nexus) ;
+ } ;
+
+ return 0 ; /* nothing to do, really. */
+} ;
+
+/*------------------------------------------------------------------------------
* SIGTERM: message sent to Routeing engine and the action it then takes.
*/
static void
@@ -760,19 +793,26 @@ sigterm_enqueue(void)
{
mqueue_block mqb = mqb_init_new(NULL, sigterm_action, NULL) ;
- mqueue_enqueue(routing_nexus->queue, mqb, 1) ;
-}
+ mqueue_enqueue(routing_nexus->queue, mqb, mqb_priority) ;
+} ;
/* dispatch a command from the message queue block */
static void
sigterm_action(mqueue_block mqb, mqb_flag_t flag)
{
- if (flag == mqb_action)
+ if ((flag == mqb_action) && !program_terminating)
{
/* send notify to all peers, wait for all sessions to be disables
- * then terminate all pthreads */
+ * then terminate all pthreads
+ */
+ program_terminating = true ;
+
bgp_terminate(1, retain_mode);
+
+ qpn_add_hook_function(&routing_nexus->foreground,
+ program_terminate_if_all_peers_deleted) ;
}
mqb_free(mqb);
-}
+} ;
+