]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
dhcp6: don't listen on IPv6 addresses when not using DHCP6
authorRoy Marples <roy@marples.name>
Thu, 7 Dec 2017 17:01:39 +0000 (17:01 +0000)
committerRoy Marples <roy@marples.name>
Thu, 7 Dec 2017 17:01:39 +0000 (17:01 +0000)
To achieve this we need to learn the addresses AFTER the interface
configuration has been loaded.

src/dhcp6.c
src/dhcpcd.c
src/if.c
src/if.h

index 7e85a455c4f889209254e28e7bae12e637101e38..ba732d218cc7ea80fdf4f88828764025db6ae504 100644 (file)
@@ -3879,16 +3879,18 @@ void
 dhcp6_handleifa(int cmd, struct ipv6_addr *ia)
 {
        struct dhcp6_state *state;
+       struct interface *ifp = ia->iface;
 
        /* If not running in master mode, listen to this address */
        if (cmd == RTM_NEWADDR &&
            !(ia->addr_flags & IN6_IFF_NOTUSEABLE) &&
-           ia->iface->active == IF_ACTIVE_USER &&
-           !(ia->iface->ctx->options & DHCPCD_MASTER) &&
+           ifp->active == IF_ACTIVE_USER &&
+           !(ifp->ctx->options & DHCPCD_MASTER) &&
+           ifp->options->options & DHCPCD_DHCP6 &&
            ia->dhcp6_fd == -1)
                dhcp6_listen(ia->iface->ctx, ia);
 
-       if ((state = D6_STATE(ia->iface)) != NULL)
+       if ((state = D6_STATE(ifp)) != NULL)
                ipv6_handleifa_addrs(cmd, &state->addrs, ia);
 }
 
index a82cc44974a9c9cdbbaa7fd4838a254eeeec6b94..6ce077f7e9780dbdfa529b1621a9b285ed5c883f 100644 (file)
@@ -975,6 +975,7 @@ int
 dhcpcd_handleinterface(void *arg, int action, const char *ifname)
 {
        struct dhcpcd_ctx *ctx;
+       struct ifaddrs *ifaddrs;
        struct if_head *ifs;
        struct interface *ifp, *iff, *ifn;
        const char * const argv[] = { ifname };
@@ -998,7 +999,7 @@ dhcpcd_handleinterface(void *arg, int action, const char *ifname)
        }
 
        i = -1;
-       ifs = if_discover(ctx, -1, UNCONST(argv));
+       ifs = if_discover(ctx, &ifaddrs, -1, UNCONST(argv));
        if (ifs == NULL) {
                logerr(__func__);
                return -1;
@@ -1043,6 +1044,17 @@ dhcpcd_handleinterface(void *arg, int action, const char *ifname)
                        dhcpcd_prestartinterface(iff);
        }
 
+       if_learnaddrs(ctx, ifs, &ifaddrs);
+
+       /* Now we have learned addresses, start the interface */
+       TAILQ_FOREACH_SAFE(ifp, ifs, next, ifn) {
+               if (strcmp(ifp->name, ifname) != 0)
+                       continue;
+               iff = if_find(ctx->ifaces, ifp->name);
+               if (action > 0 && iff->active)
+                       dhcpcd_prestartinterface(iff);
+       }
+
        /* Free our discovered list */
        while ((ifp = TAILQ_FIRST(ifs))) {
                TAILQ_REMOVE(ifs, ifp, next);
@@ -1403,6 +1415,7 @@ int
 main(int argc, char **argv)
 {
        struct dhcpcd_ctx ctx;
+       struct ifaddrs *ifaddrs = NULL;
        struct if_options *ifo;
        struct interface *ifp;
        uint16_t family = 0;
@@ -1678,7 +1691,7 @@ printpidfile:
                if (optind != argc) {
                        /* We need to try and find the interface so we can load
                         * the hardware address to compare automated IAID */
-                       ctx.ifaces = if_discover(&ctx,
+                       ctx.ifaces = if_discover(&ctx, &ifaddrs,
                            argc - optind, argv + optind);
                } else {
                        if ((ctx.ifaces = malloc(sizeof(*ctx.ifaces))) != NULL)
@@ -1842,7 +1855,7 @@ printpidfile:
            (DHCPCD_MASTER | DHCPCD_DEV))
                dev_start(&ctx);
 
-       ctx.ifaces = if_discover(&ctx, ctx.ifc, ctx.ifv);
+       ctx.ifaces = if_discover(&ctx, &ifaddrs, ctx.ifc, ctx.ifv);
        if (ctx.ifaces == NULL) {
                logerr("%s: if_discover", __func__);
                goto exit_failure;
@@ -1878,6 +1891,7 @@ printpidfile:
                if (ifp->active)
                        dhcpcd_initstate1(ifp, argc, argv, 0);
        }
+       if_learnaddrs(&ctx, ctx.ifaces, &ifaddrs);
 
        if (ctx.options & DHCPCD_BACKGROUND && dhcpcd_daemonise(&ctx))
                goto exit_success;
@@ -1948,6 +1962,8 @@ exit_failure:
        i = EXIT_FAILURE;
 
 exit1:
+       if (ifaddrs != NULL)
+               freeifaddrs(ifaddrs);
        if (control_stop(&ctx) == -1)
                logerr("%s: control_stop", __func__);
        /* Free memory and close fd's */
index 2ae5079359c06b07c5a423de1cc70a4e7e0ce10c..828dc4acdec9d684f311effcf79f8fd36c2355b6 100644 (file)
--- a/src/if.c
+++ b/src/if.c
@@ -190,8 +190,9 @@ if_hasconf(struct dhcpcd_ctx *ctx, const char *ifname)
        return 0;
 }
 
-static void if_learnaddrs(struct dhcpcd_ctx *ctx, struct if_head *ifs,
-    struct ifaddrs *ifaddrs)
+void
+if_learnaddrs(struct dhcpcd_ctx *ctx, struct if_head *ifs,
+    struct ifaddrs **ifaddrs)
 {
        struct ifaddrs *ifa;
        struct interface *ifp;
@@ -203,7 +204,7 @@ static void if_learnaddrs(struct dhcpcd_ctx *ctx, struct if_head *ifs,
 #endif
        int addrflags;
 
-       for (ifa = ifaddrs; ifa; ifa = ifa->ifa_next) {
+       for (ifa = *ifaddrs; ifa; ifa = ifa->ifa_next) {
                if (ifa->ifa_addr == NULL)
                        continue;
                if ((ifp = if_find(ifs, ifa->ifa_name)) == NULL)
@@ -262,6 +263,9 @@ static void if_learnaddrs(struct dhcpcd_ctx *ctx, struct if_head *ifs,
 #endif
                }
        }
+
+       freeifaddrs(*ifaddrs);
+       *ifaddrs = NULL;
 }
 
 bool
@@ -283,9 +287,10 @@ if_valid_hwaddr(const uint8_t *hwaddr, size_t hwlen)
 }
 
 struct if_head *
-if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
+if_discover(struct dhcpcd_ctx *ctx, struct ifaddrs **ifaddrs,
+    int argc, char * const *argv)
 {
-       struct ifaddrs *ifaddrs, *ifa;
+       struct ifaddrs *ifa;
        int i;
        unsigned int active;
        struct if_head *ifs;
@@ -307,14 +312,17 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
        const struct sockaddr_ll *sll;
 #endif
 
-       if (getifaddrs(&ifaddrs) == -1)
+       if ((ifs = malloc(sizeof(*ifs))) == NULL) {
+               logerr(__func__);
                return NULL;
-
-       if ((ifs = malloc(sizeof(*ifs))) == NULL)
-               goto failed;
+       }
        TAILQ_INIT(ifs);
+       if (getifaddrs(ifaddrs) == -1) {
+               logerr(__func__);
+               goto out;
+       }
 
-       for (ifa = ifaddrs; ifa; ifa = ifa->ifa_next) {
+       for (ifa = *ifaddrs; ifa; ifa = ifa->ifa_next) {
                if (ifa->ifa_addr != NULL) {
 #ifdef AF_LINK
                        if (ifa->ifa_addr->sa_family != AF_LINK)
@@ -565,9 +573,7 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
                TAILQ_INSERT_TAIL(ifs, ifp, next);
        }
 
-       if_learnaddrs(ctx, ifs, ifaddrs);
-failed:
-       freeifaddrs(ifaddrs);
+out:
        return ifs;
 }
 
index b3544f5bda29f3b416ab0e0fbb9ea3dbb8b13cf0..a71afd43c8f773eefc3c9aa2c6497a0eebf2d00e 100644 (file)
--- a/src/if.h
+++ b/src/if.h
@@ -35,6 +35,8 @@
 #include <netinet/in_var.h>    /* for IN_IFF_TENTATIVE et all */
 #endif
 
+#include <ifaddrs.h>
+
 /* Some systems have in-built IPv4 DAD.
  * However, we need them to do DAD at carrier up as well. */
 #ifdef IN_IFF_TENTATIVE
@@ -112,7 +114,9 @@ int if_getifaddrs(struct ifaddrs **);
 int if_setflag(struct interface *ifp, short flag);
 #define if_up(ifp) if_setflag((ifp), (IFF_UP | IFF_RUNNING))
 bool if_valid_hwaddr(const uint8_t *, size_t);
-struct if_head *if_discover(struct dhcpcd_ctx *, int, char * const *);
+struct if_head *if_discover(struct dhcpcd_ctx *, struct ifaddrs **,
+    int, char * const *);
+void if_learnaddrs(struct dhcpcd_ctx *, struct if_head *, struct ifaddrs **);
 struct interface *if_find(struct if_head *, const char *);
 struct interface *if_findindex(struct if_head *, unsigned int);
 struct interface *if_loopback(struct dhcpcd_ctx *);