Browse Source

ospf6d: clear lsa->refresh before clearing LSAs

This fixes a SEGV when we receive a higher-SeqNum copy of a LSA that we
originated ourselves, before a reboot of ospf6d.  We create a new
copy of the LSA to resync the SeqNum, but then half an hour later
the old refresh thread ends up trying to refresh the free()'d old LSA.

The SEGV is triggered by this chain:
  ospf6_lsdb_maxage_remover
  -> thread_execute(ospf6_lsa_refresh)
     -> old->refresh = NULL
Which assumes that old->refresh is no longer scheduled to run, as it is
being run right there.  But the thread_execute() doesn't know about
old->refresh and therefore didn't remove it.

(Found by ANVL OSPFV3-16.17)

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
David Lamparter 6 years ago
parent
commit
11b4f01355
2 changed files with 3 additions and 0 deletions
  1. 1 0
      ospf6d/ospf6_flood.c
  2. 2 0
      ospf6d/ospf6_lsdb.c

+ 1 - 0
ospf6d/ospf6_flood.c

@@ -220,6 +220,7 @@ ospf6_install_lsa (struct ospf6_lsa *lsa)
   if (old)
     {
       THREAD_OFF (old->expire);
+      THREAD_OFF (old->refresh);
       ospf6_flood_clear (old);
     }
 

+ 2 - 0
ospf6d/ospf6_lsdb.c

@@ -473,6 +473,8 @@ ospf6_lsdb_maxage_remover (struct ospf6_lsdb *lsdb)
          */
         lsa->header->seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER + 1);
         ospf6_lsa_checksum (lsa->header);
+
+	THREAD_OFF(lsa->refresh);
         thread_execute (master, ospf6_lsa_refresh, lsa, 0);
       } else {
         ospf6_lsdb_remove (lsa, lsdb);