From: Roy Marples Date: Wed, 28 Mar 2018 18:25:16 +0000 (+0000) Subject: routes: allow a head clear with a context X-Git-Tag: v7.0.3~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=30425c9bcb37b59b0b1cf9bda94bd730405f0ed6;p=thirdparty%2Fdhcpcd.git 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. --- 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 *);