summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Jakma <paul@quagga.net>2009-07-16 19:27:32 +0100
committerPaul Jakma <paul@quagga.net>2009-07-17 11:19:46 +0100
commitfd35b948dbb35674cd9ded431f94b59aeced40cc (patch)
treec236a99b492b19943916e0c117b0a2461333b422
parent3fa3f957e70f594cc2c1cac03644ddf48554c178 (diff)
[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.
-rw-r--r--bgpd/bgpd.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 1fefbd3f..86bf60ec 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -2073,9 +2073,14 @@ bgp_delete (struct bgp *bgp)
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 @@ bgp_free (struct bgp *bgp)
list_delete (bgp->peer);
list_delete (bgp->rsclient);
- listnode_delete (bm->bgp, bgp);
-
if (bgp->name)
free (bgp->name);