From c32eba04f311d2bd4d249b2d84a3b496b0f4d302 Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Thu, 11 Jul 2019 19:36:06 -0700 Subject: [PATCH] ospfd: no router ospf crash fix no router ospf triggers to cancel all threads including read/write (receive/send packets) threads, cleans up resources fd, message queue and data. Last job of write (packet) thread invoked where the ospf instance is referenced is not running nor the socket fd valid. Write thread callback should check if fd is valid and ospf instance is running before proceeding to send a message over socket. Ticket:CM-20095 Testing Done: Performed the multiple 'no router ospf' with the fix in topology where the crash was seen. Post fix the crash is not observed. Signed-off-by: Chirag Shah --- ospfd/ospf_packet.c | 8 ++++++++ ospfd/ospfd.c | 17 +++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 6bc8c25153..50c30a6fa0 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -660,6 +660,14 @@ static int ospf_write(struct thread *thread) struct in_pktinfo *pi; #endif + if (ospf->fd < 0 || ospf->oi_running == 0) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_write failed to send, fd %d, instance %u" + ,ospf->fd, ospf->oi_running); + return -1; + } + ospf->t_write = NULL; node = listhead(ospf->oi_write_q); diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index aa38a42714..a64ddbc3b7 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -656,6 +656,7 @@ static void ospf_finish_final(struct ospf *ospf) for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) ospf_if_free(oi); list_delete(&ospf->oiflist); + ospf->oi_running = 0; /* De-Register VRF */ ospf_zebra_vrf_deregister(ospf); @@ -699,6 +700,8 @@ static void ospf_finish_final(struct ospf *ospf) } /* Cancel all timers. */ + OSPF_TIMER_OFF(ospf->t_read); + OSPF_TIMER_OFF(ospf->t_write); OSPF_TIMER_OFF(ospf->t_external_lsa); OSPF_TIMER_OFF(ospf->t_spf_calc); OSPF_TIMER_OFF(ospf->t_ase_calc); @@ -708,14 +711,9 @@ static void ospf_finish_final(struct ospf *ospf) OSPF_TIMER_OFF(ospf->t_asbr_check); OSPF_TIMER_OFF(ospf->t_distribute_update); OSPF_TIMER_OFF(ospf->t_lsa_refresher); - OSPF_TIMER_OFF(ospf->t_read); - OSPF_TIMER_OFF(ospf->t_write); OSPF_TIMER_OFF(ospf->t_opaque_lsa_self); OSPF_TIMER_OFF(ospf->t_sr_update); - close(ospf->fd); - stream_free(ospf->ibuf); - LSDB_LOOP (OPAQUE_AS_LSDB(ospf), rn, lsa) ospf_discard_from_db(ospf, ospf->lsdb, lsa); LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa) @@ -755,9 +753,6 @@ static void ospf_finish_final(struct ospf *ospf) ospf_ase_external_lsas_finish(ospf->external_lsas); } - list_delete(&ospf->areas); - list_delete(&ospf->oi_write_q); - for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++) { struct list *ext_list; struct ospf_external *ext; @@ -789,6 +784,12 @@ static void ospf_finish_final(struct ospf *ospf) if (!CHECK_FLAG(om->options, OSPF_MASTER_SHUTDOWN)) instance = ospf->instance; + list_delete(&ospf->areas); + list_delete(&ospf->oi_write_q); + + close(ospf->fd); + stream_free(ospf->ibuf); + ospf->fd = -1; ospf_delete(ospf); if (ospf->name) {