[bgpd] Bug #533: Fix crash with copy/pasted commands, inc 'no bgp ...'
* bgpd.c: Removal of (struct bgp *) from the master list was being left to
bgp_free time. This meant there was a window of time between bgp_delete
and refcounts hitting 0 (e.g. routes to be processed) where bgp_lookup's
could return a deleted (struct bgp *).
(bgp_delete) This is the logical place where a (struct bgp *) should lose
its visibility, so move the deletion from the bgp-master list to here,
from bgp_free.
Many thanks to Fritz Reichmann for his thorough debugging of the problem
and testing of fixes and Chris Caputo for his further analysis.
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 1fefbd3..86bf60e 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -2073,9 +2073,14 @@
peer_delete(bgp->peer_self);
bgp->peer_self = NULL;
}
-
+
+ /* Remove visibility via the master list - there may however still be
+ * routes to be processed still referencing the struct bgp.
+ */
+ listnode_delete (bm->bgp, bgp);
+
bgp_unlock(bgp); /* initial reference */
-
+
return 0;
}
@@ -2104,8 +2109,6 @@
list_delete (bgp->peer);
list_delete (bgp->rsclient);
- listnode_delete (bm->bgp, bgp);
-
if (bgp->name)
free (bgp->name);