diff options
-rw-r--r-- | bgpd/bgp_main.c | 71 | ||||
-rw-r--r-- | bgpd/bgp_peer.c | 3 | ||||
-rw-r--r-- | bgpd/bgp_session.c | 3 | ||||
-rw-r--r-- | bgpd/bgpd.c | 5 | ||||
-rw-r--r-- | lib/command.c | 3 | ||||
-rw-r--r-- | lib/qpnexus.c | 3 | ||||
-rw-r--r-- | lib/vty.c | 20 |
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); } @@ -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 |