]> git.puffer.fish Git - matthieu/frr.git/commitdiff
ospfd: no router ospf crash fix
authorChirag Shah <chirag@cumulusnetworks.com>
Fri, 12 Jul 2019 02:36:06 +0000 (19:36 -0700)
committerChirag Shah <chirag@cumulusnetworks.com>
Mon, 15 Jul 2019 16:55:54 +0000 (09:55 -0700)
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 <chirag@cumulusnetworks.com>
ospfd/ospf_packet.c
ospfd/ospfd.c

index 6bc8c25153bf1d48e833eb564ea783f1c9187e13..50c30a6fa0c15171e5aebc612e7e270f2ba920cb 100644 (file)
@@ -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);
index aa38a4271442792ba358f4fac42a64203dbe9e4f..a64ddbc3b7df06426a2ca2caaeab9e5e804eba70 100644 (file)
@@ -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) {