]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
routes: allow a head clear with a context
authorRoy Marples <roy@marples.name>
Wed, 28 Mar 2018 18:25:16 +0000 (18:25 +0000)
committerRoy Marples <roy@marples.name>
Wed, 28 Mar 2018 18:25:16 +0000 (18:25 +0000)
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.

src/dhcpcd.c
src/if-options.c
src/if-options.h
src/if.c
src/route.c
src/route.h

index 23ca18701182409fa5f122c9639807da1da427a4..291b9b5d3c8c368543e11ec3a84e83e6c4c62c56 100644 (file)
@@ -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);
index bd051b3bc76c7c819f0815b32513406a6c4f78e4..d0feadddfd969d735e66465e79675cf3e08aa5e4 100644 (file)
@@ -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);
index 4852d4b761c7df23b85ad6c4b981515701c842ca..8dfe3486e94689f50d334390c2a13f638985ac4b 100644 (file)
@@ -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
index 208da245e8af19b361b6ca65fdc8e4b550038e3c..eaebefa5a4e34e363fc2a582cec5df21e1c9c736 100644 (file)
--- 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);
 }
 
index 4ce073fca3b819670a28d7a2fe1a9ae33e2b2b1f..dc43a8c0f973661bfb55de8186ee6587ca525eef 100644 (file)
@@ -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)
 {
index db316e2e5669acf58cd1acb81a32a1e76c654093..204b20c0b2d21f5a9778211270aa9af1b952b564 100644 (file)
@@ -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 *);