changeset 4249:c30233f8cca3 draft

routes: allow a head clear with a context This is because optionally defined routes may not have an interface at the global level. Also, init route lists earlier so they can be freed without error.
author Roy Marples <roy@marples.name>
date Wed, 28 Mar 2018 18:25:16 +0000
parents 2844dbb214b5
children c52f082bc674
files src/dhcpcd.c src/if-options.c src/if-options.h src/if.c src/route.c src/route.h
diffstat 6 files changed, 27 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/src/dhcpcd.c	Wed Mar 28 11:00:18 2018 +0100
+++ b/src/dhcpcd.c	Wed Mar 28 18:25:16 2018 +0000
@@ -577,7 +577,7 @@
 	} else
 		*ifp->profile = '\0';
 
-	free_options(ifp->options);
+	free_options(ifp->ctx, ifp->options);
 	ifp->options = ifo;
 	if (profile) {
 		add_options(ifp->ctx, ifp->name, ifp->options,
@@ -1165,7 +1165,7 @@
 	if (ctx->options & DHCPCD_DAEMONISED)
 		ifo->options |= DHCPCD_DAEMONISED;
 	ctx->options = ifo->options;
-	free_options(ifo);
+	free_options(ctx, ifo);
 }
 
 static void
@@ -1523,6 +1523,8 @@
 #ifdef INET
 	ctx.udp_fd = -1;
 #endif
+	rt_init(&ctx);
+
 	logopts = LOGERR_ERR|LOGERR_LOG|LOGERR_LOG_DATE|LOGERR_LOG_PID;
 	i = 0;
 	while ((opt = getopt_long(argc, argv,
@@ -1617,7 +1619,7 @@
 	if (i == 2) {
 		printf("Interface options:\n");
 		if (optind == argc - 1) {
-			free_options(ifo);
+			free_options(&ctx, ifo);
 			ifo = read_config(&ctx, argv[optind], NULL, NULL);
 			if (ifo == NULL)
 				goto exit_failure;
@@ -1933,8 +1935,6 @@
 		}
 	}
 
-	rt_init(&ctx);
-
 	TAILQ_FOREACH(ifp, ctx.ifaces, next) {
 		if (ifp->active)
 			dhcpcd_initstate1(ifp, argc, argv, 0);
@@ -1985,7 +1985,7 @@
 			    handle_exit_timeout, &ctx);
 		}
 	}
-	free_options(ifo);
+	free_options(&ctx, ifo);
 	ifo = NULL;
 
 	if_sortinterfaces(&ctx);
@@ -2029,7 +2029,7 @@
 		close(ctx.link_fd);
 	}
 	if_closesockets(&ctx);
-	free_options(ifo);
+	free_options(&ctx, ifo);
 	free_globals(&ctx);
 	ipv6_ctxfree(&ctx);
 	dev_stop(&ctx);
--- a/src/if-options.c	Wed Mar 28 11:00:18 2018 +0100
+++ b/src/if-options.c	Wed Mar 28 18:25:16 2018 +0000
@@ -2354,7 +2354,7 @@
 		buf = malloc(buflen);
 		if (buf == NULL) {
 			logerr(__func__);
-			free_options(ifo);
+			free_options(ctx, ifo);
 			return NULL;
 		}
 		ldop = edop = NULL;
@@ -2368,7 +2368,7 @@
 				if (nbuf == NULL) {
 					logerr(__func__);
 					free(buf);
-					free_options(ifo);
+					free_options(ctx, ifo);
 					return NULL;
 				}
 				buf = nbuf;
@@ -2532,7 +2532,7 @@
 	free(buf);
 
 	if (profile && !have_profile) {
-		free_options(ifo);
+		free_options(ctx, ifo);
 		errno = ENOENT;
 		return NULL;
 	}
@@ -2577,7 +2577,7 @@
 }
 
 void
-free_options(struct if_options *ifo)
+free_options(struct dhcpcd_ctx *ctx, struct if_options *ifo)
 {
 	size_t i;
 	struct dhcp_opt *opt;
@@ -2599,7 +2599,7 @@
 				free(ifo->config[i++]);
 			free(ifo->config);
 		}
-		rt_headclear(&ifo->routes, AF_UNSPEC);
+		rt_headclear0(ctx, &ifo->routes, AF_UNSPEC);
 		free(ifo->script);
 		free(ifo->arping);
 		free(ifo->blacklist);
--- a/src/if-options.h	Wed Mar 28 11:00:18 2018 +0100
+++ b/src/if-options.h	Wed Mar 28 18:25:16 2018 +0000
@@ -230,6 +230,6 @@
 int add_options(struct dhcpcd_ctx *, const char *,
     struct if_options *, int, char **);
 void free_dhcp_opt_embenc(struct dhcp_opt *);
-void free_options(struct if_options *);
+void free_options(struct dhcpcd_ctx *, struct if_options *);
 
 #endif
--- a/src/if.c	Wed Mar 28 11:00:18 2018 +0100
+++ b/src/if.c	Wed Mar 28 18:25:16 2018 +0000
@@ -85,7 +85,7 @@
 	ipv6nd_free(ifp);
 	ipv6_free(ifp);
 	rt_freeif(ifp);
-	free_options(ifp->options);
+	free_options(ifp->ctx, ifp->options);
 	free(ifp);
 }
 
--- a/src/route.c	Wed Mar 28 11:00:18 2018 +0100
+++ b/src/route.c	Wed Mar 28 18:25:16 2018 +0000
@@ -101,17 +101,13 @@
 }
 
 void
-rt_headclear(struct rt_head *rts, int af)
+rt_headclear0(struct dhcpcd_ctx *ctx, struct rt_head *rts, int af)
 {
 	struct rt *rt, *rtn;
-	struct dhcpcd_ctx *ctx;
 
 	if (rts == NULL)
 		return;
-
-	if ((rt = TAILQ_FIRST(rts)) == NULL)
-		return;
-	ctx = rt->rt_ifp->ctx;
+	assert(ctx != NULL);
 	assert(&ctx->froutes != rts);
 
 	TAILQ_FOREACH_SAFE(rt, rts, rt_next, rtn) {
@@ -124,6 +120,16 @@
 	}
 }
 
+void
+rt_headclear(struct rt_head *rts, int af)
+{
+	struct rt *rt;
+
+	if (rts == NULL || (rt = TAILQ_FIRST(rts)) == NULL)
+		return;
+	rt_headclear0(rt->rt_ifp->ctx, rts, af);
+}
+
 static void
 rt_headfree(struct rt_head *rts)
 {
--- a/src/route.h	Wed Mar 28 11:00:18 2018 +0100
+++ b/src/route.h	Wed Mar 28 18:25:16 2018 +0000
@@ -86,6 +86,7 @@
 struct rt * rt_find(struct rt_head *, const struct rt *);
 void rt_free(struct rt *);
 void rt_freeif(struct interface *);
+void rt_headclear0(struct dhcpcd_ctx *, struct rt_head *, int);
 void rt_headclear(struct rt_head *, int);
 void rt_headfreeif(struct rt_head *);
 struct rt * rt_new0(struct dhcpcd_ctx *);