summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRenato Westphal <renato@cvs.openbsd.org>2016-04-15 13:24:53 +0000
committerRenato Westphal <renato@cvs.openbsd.org>2016-04-15 13:24:53 +0000
commit936627c2c4cee12a29bbbf006db6731528ac43ea (patch)
tree5ad3e19ca556e6675886a1925c37ebcec03a39e1
parent0857e73657c069d6e5e62f51076de7d30ad50c9a (diff)
Properly implement the clear_config() function.
We need to free the internal pointers of the eigrpd_conf struct, not only the main struct. This avoids memory leaks when a config reload happens to fail (e.g. due to a syntax error).
-rw-r--r--usr.sbin/eigrpd/parse.y36
1 files changed, 35 insertions, 1 deletions
diff --git a/usr.sbin/eigrpd/parse.y b/usr.sbin/eigrpd/parse.y
index 5fa2ea58ba6..72d155bd76a 100644
--- a/usr.sbin/eigrpd/parse.y
+++ b/usr.sbin/eigrpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.12 2016/04/15 13:21:45 renato Exp $ */
+/* $OpenBSD: parse.y,v 1.13 2016/04/15 13:24:52 renato Exp $ */
/*
* Copyright (c) 2015 Renato Westphal <renato@openbsd.org>
@@ -1129,9 +1129,43 @@ conf_get_if(struct kif *kif)
return (e);
}
+extern struct iface_id_head ifaces_by_id;
+RB_PROTOTYPE(iface_id_head, eigrp_iface, id_tree, iface_id_compare)
+
void
clear_config(struct eigrpd_conf *xconf)
{
+ struct eigrp *e;
+ struct redistribute *r;
+ struct eigrp_iface *i;
+ struct summary_addr *s;
+
+ while ((e = TAILQ_FIRST(&xconf->instances)) != NULL) {
+ while (!SIMPLEQ_EMPTY(&e->redist_list)) {
+ r = SIMPLEQ_FIRST(&e->redist_list);
+ SIMPLEQ_REMOVE_HEAD(&e->redist_list, entry);
+ free(r);
+ }
+
+ while ((i = TAILQ_FIRST(&e->ei_list)) != NULL) {
+ RB_REMOVE(iface_id_head, &ifaces_by_id, i);
+ TAILQ_REMOVE(&e->ei_list, i, e_entry);
+ TAILQ_REMOVE(&e->ei_list, i, i_entry);
+ while ((s = TAILQ_FIRST(&i->summary_list)) != NULL) {
+ TAILQ_REMOVE(&i->summary_list, s, entry);
+ free(s);
+ }
+ if (TAILQ_EMPTY(&i->iface->ei_list)) {
+ TAILQ_REMOVE(&xconf->iface_list, i->iface, entry);
+ free(i->iface);
+ }
+ free(i);
+ }
+
+ TAILQ_REMOVE(&xconf->instances, e, entry);
+ free(e);
+ }
+
free(xconf);
}