summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_main.c71
-rw-r--r--bgpd/bgp_peer.c3
-rw-r--r--bgpd/bgp_session.c3
-rw-r--r--bgpd/bgpd.c5
-rw-r--r--lib/command.c3
-rw-r--r--lib/qpnexus.c3
-rw-r--r--lib/vty.c20
7 files changed, 83 insertions, 25 deletions
diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c
index 45ea0f59..88068017 100644
--- a/bgpd/bgp_main.c
+++ b/bgpd/bgp_main.c
@@ -85,6 +85,10 @@ static void init_second_stage(int pthreads);
static void bgp_in_thread_init(void);
static qtime_mono_t routing_event_hook(void);
static qtime_mono_t bgp_event_hook(void);
+static void sighup_action(mqueue_block mqb, mqb_flag_t flag);
+static void sighup_enqueue(void);
+static void sigterm_action(mqueue_block mqb, mqb_flag_t flag);
+static void sigterm_enqueue(void);
static struct quagga_signal_t bgp_signals[] =
{
@@ -189,9 +193,9 @@ sighup (void)
{
zlog (NULL, LOG_INFO, "SIGHUP received");
- /* Terminate all thread. */
- bgp_terminate ();
- bgp_reset ();
+ /* tell the routing engine */
+ sighup_enqueue();
+
zlog_info ("bgpd restarting!");
/* Reload config file. */
@@ -212,18 +216,18 @@ sigint (void)
#endif
zlog_notice ("Terminating on signal");
- if (!retain_mode)
- bgp_terminate ();
+ /* tell the routing engine */
+ sigterm_enqueue();
- if (qpthreads_enabled)
- {
- /* ask all threads to terminate */
- if (routing_nexus != NULL)
+ /* TODO: very temporary kludge to test if bgp engine does close */
+ sleep(20);
+
+ /* ask remaining pthreads to die */
+ if (qpthreads_enabled && routing_nexus != NULL)
qpn_terminate(routing_nexus);
- if (bgp_nexus != NULL)
+ if (qpthreads_enabled && bgp_nexus != NULL)
qpn_terminate(bgp_nexus);
- }
if (cli_nexus != NULL)
qpn_terminate(cli_nexus);
@@ -623,3 +627,48 @@ bgp_event_hook(void)
bgp_connection_queue_process();
return 0;
}
+
+/* SIGINT/TERM SIGHUP need to tell routing engine what to do */
+
+static void
+sighup_enqueue(void)
+{
+ mqueue_block mqb = mqb_init_new(NULL, sighup_action, NULL) ;
+
+ mqueue_enqueue(routing_nexus->queue, mqb, 0) ;
+}
+
+/* dispatch a command from the message queue block */
+static void
+sighup_action(mqueue_block mqb, mqb_flag_t flag)
+{
+ if (flag == mqb_action)
+ {
+ bgp_terminate ();
+ bgp_reset ();
+ }
+
+ mqb_free(mqb);
+}
+
+static void
+sigterm_enqueue(void)
+{
+ mqueue_block mqb = mqb_init_new(NULL, sigterm_action, NULL) ;
+
+ mqueue_enqueue(routing_nexus->queue, mqb, 0) ;
+}
+
+/* dispatch a command from the message queue block */
+static void
+sigterm_action(mqueue_block mqb, mqb_flag_t flag)
+{
+ if (flag == mqb_action)
+ {
+ /* send notify to all peers, unless retaining routes */
+ if (!retain_mode)
+ bgp_terminate();
+ }
+
+ mqb_free(mqb);
+}
diff --git a/bgpd/bgp_peer.c b/bgpd/bgp_peer.c
index 3d1c6a7c..10fedc86 100644
--- a/bgpd/bgp_peer.c
+++ b/bgpd/bgp_peer.c
@@ -904,7 +904,8 @@ peer_free (struct peer *peer)
BGP_EVENT_FLUSH (peer);
/* unregister */
- bgp_peer_index_deregister(peer, &peer->su);
+ if (peer->index_entry != NULL)
+ bgp_peer_index_deregister(peer, &peer->su);
if (peer->desc)
XFREE (MTYPE_PEER_DESC, peer->desc);
diff --git a/bgpd/bgp_session.c b/bgpd/bgp_session.c
index f7af093f..a863ecbe 100644
--- a/bgpd/bgp_session.c
+++ b/bgpd/bgp_session.c
@@ -306,6 +306,7 @@ bgp_session_do_enable(mqueue_block mqb, mqb_flag_t flag)
session->active = 1 ;
bgp_fsm_enable_session(session) ;
+ session->state = bgp_session_sEnabled;
BGP_SESSION_UNLOCK(session) ; /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
} ;
@@ -338,7 +339,7 @@ bgp_session_disable(bgp_peer peer, bgp_notify notification)
/* Do nothing if session is not active, or is already limping. */
if ( (session->state != bgp_session_sEnabled) &&
- (session->state != bgp_session_sEstablished) ) ;
+ (session->state != bgp_session_sEstablished) )
{
bgp_notify_free(notification) ; /* discard any bgp_notify */
return ;
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 8161868a..27a35cff 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -4702,9 +4702,8 @@ bgp_terminate (void)
for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
- if (peer->status == Established)
- bgp_notify_send (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_PEER_UNCONFIG);
+ bgp_peer_disable(peer, bgp_notify_new(BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN, 0));
bgp_cleanup_routes ();
diff --git a/lib/command.c b/lib/command.c
index 59cbbe52..2c9ca64a 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -536,6 +536,9 @@ zencrypt (const char *passwd)
static int
config_write_host (struct vty *vty)
{
+ if (qpthreads_enabled)
+ vty_out (vty, "threaded%s", VTY_NEWLINE);
+
if (host.name)
vty_out (vty, "hostname %s%s", host.name, VTY_NEWLINE);
diff --git a/lib/qpnexus.c b/lib/qpnexus.c
index 731190b6..5a243d0f 100644
--- a/lib/qpnexus.c
+++ b/lib/qpnexus.c
@@ -264,5 +264,6 @@ qpn_terminate(qpn_nexus qpn)
{
qpn->terminate = 1;
/* wake up any pselect */
- qpt_thread_signal(qpn->thread_id, SIGMQUEUE);
+ if (qpthreads_enabled)
+ qpt_thread_signal(qpn->thread_id, SIGMQUEUE);
}
diff --git a/lib/vty.c b/lib/vty.c
index e651e445..fdc36925 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -603,7 +603,8 @@ vty_queued_result(struct vty *vty, int result)
if (cli_nexus)
{
vty_event (VTY_WRITE, vty->fd, vty);
- qpt_thread_signal(cli_nexus->thread_id, SIGMQUEUE);
+ if (qpthreads_enabled)
+ qpt_thread_signal(cli_nexus->thread_id, SIGMQUEUE);
}
UNLOCK
@@ -2901,15 +2902,18 @@ vty_goodbye (void)
if (vtyvec)
{
for (i = 0; i < vector_active (vtyvec); i++)
- if (((vty = vector_slot (vtyvec, i)) != NULL) && vty->type == VTY_TERM)
- uty_out(vty, QUAGGA_PROGNAME " is shutting down%s", VTY_NEWLINE);
-
- /* Wake up */
- if (cli_nexus)
{
- vty_event (VTY_WRITE, vty->fd, vty);
- qpt_thread_signal(cli_nexus->thread_id, SIGMQUEUE);
+ if (((vty = vector_slot (vtyvec, i)) != NULL) && vty->type == VTY_TERM)
+ {
+ uty_out(vty, QUAGGA_PROGNAME " is shutting down%s", VTY_NEWLINE);
+
+ /* Wake up */
+ if (cli_nexus)
+ vty_event (VTY_WRITE, vty->fd, vty);
+ }
}
+ if (qpthreads_enabled)
+ qpt_thread_signal(cli_nexus->thread_id, SIGMQUEUE);
}
UNLOCK