summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2018-03-28 18:25:16 +0000
committerRoy Marples <roy@marples.name>2018-03-28 18:25:16 +0000
commit667df0b3ef9bf3313b4e151c8127e444ce5a093e (patch)
treed37043cdbdddd0b924464463329b7730fe2525e2
parent17644e6823711d25d6fa381f9930ef63f2df104d (diff)
downloaddhcpcd-667df0b3ef9bf3313b4e151c8127e444ce5a093e.tar.xz
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.
-rw-r--r--src/dhcpcd.c14
-rw-r--r--src/if-options.c10
-rw-r--r--src/if-options.h2
-rw-r--r--src/if.c2
-rw-r--r--src/route.c18
-rw-r--r--src/route.h1
6 files changed, 27 insertions, 20 deletions
diff --git a/src/dhcpcd.c b/src/dhcpcd.c
index 23ca1870..291b9b5d 100644
--- a/src/dhcpcd.c
+++ b/src/dhcpcd.c
@@ -577,7 +577,7 @@ dhcpcd_selectprofile(struct interface *ifp, const char *profile)
} 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 @@ reload_config(struct dhcpcd_ctx *ctx)
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 @@ main(int argc, char **argv)
#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 @@ main(int argc, char **argv)
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 @@ printpidfile:
}
}
- rt_init(&ctx);
-
TAILQ_FOREACH(ifp, ctx.ifaces, next) {
if (ifp->active)
dhcpcd_initstate1(ifp, argc, argv, 0);
@@ -1985,7 +1985,7 @@ printpidfile:
handle_exit_timeout, &ctx);
}
}
- free_options(ifo);
+ free_options(&ctx, ifo);
ifo = NULL;
if_sortinterfaces(&ctx);
@@ -2029,7 +2029,7 @@ exit1:
close(ctx.link_fd);
}
if_closesockets(&ctx);
- free_options(ifo);
+ free_options(&ctx, ifo);
free_globals(&ctx);
ipv6_ctxfree(&ctx);
dev_stop(&ctx);
diff --git a/src/if-options.c b/src/if-options.c
index bd051b3b..d0feaddd 100644
--- a/src/if-options.c
+++ b/src/if-options.c
@@ -2354,7 +2354,7 @@ read_config(struct dhcpcd_ctx *ctx,
buf = malloc(buflen);
if (buf == NULL) {
logerr(__func__);
- free_options(ifo);
+ free_options(ctx, ifo);
return NULL;
}
ldop = edop = NULL;
@@ -2368,7 +2368,7 @@ read_config(struct dhcpcd_ctx *ctx,
if (nbuf == NULL) {
logerr(__func__);
free(buf);
- free_options(ifo);
+ free_options(ctx, ifo);
return NULL;
}
buf = nbuf;
@@ -2532,7 +2532,7 @@ read_config(struct dhcpcd_ctx *ctx,
free(buf);
if (profile && !have_profile) {
- free_options(ifo);
+ free_options(ctx, ifo);
errno = ENOENT;
return NULL;
}
@@ -2577,7 +2577,7 @@ add_options(struct dhcpcd_ctx *ctx, const char *ifname,
}
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_options(struct if_options *ifo)
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);
diff --git a/src/if-options.h b/src/if-options.h
index 4852d4b7..8dfe3486 100644
--- a/src/if-options.h
+++ b/src/if-options.h
@@ -230,6 +230,6 @@ struct if_options *read_config(struct dhcpcd_ctx *,
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
diff --git a/src/if.c b/src/if.c
index 208da245..eaebefa5 100644
--- a/src/if.c
+++ b/src/if.c
@@ -85,7 +85,7 @@ if_free(struct interface *ifp)
ipv6nd_free(ifp);
ipv6_free(ifp);
rt_freeif(ifp);
- free_options(ifp->options);
+ free_options(ifp->ctx, ifp->options);
free(ifp);
}
diff --git a/src/route.c b/src/route.c
index 4ce073fc..dc43a8c0 100644
--- a/src/route.c
+++ b/src/route.c
@@ -101,17 +101,13 @@ rt_desc(const char *cmd, const struct rt *rt)
}
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 @@ rt_headclear(struct rt_head *rts, int af)
}
}
+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)
{
diff --git a/src/route.h b/src/route.h
index db316e2e..204b20c0 100644
--- a/src/route.h
+++ b/src/route.h
@@ -86,6 +86,7 @@ void rt_dispose(struct dhcpcd_ctx *);
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 *);