]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Fix waiting for ip address, [1972d664c2].
authorRoy Marples <roy@marples.name>
Wed, 20 May 2015 10:25:10 +0000 (10:25 +0000)
committerRoy Marples <roy@marples.name>
Wed, 20 May 2015 10:25:10 +0000 (10:25 +0000)
dhcp6.c
dhcp6.h
dhcpcd.c
if-options.c
ipv4.c
ipv4.h
ipv6.c
ipv6.h
ipv6nd.c
ipv6nd.h

diff --git a/dhcp6.c b/dhcp6.c
index c1b7bfdb36883cc5cce2c441421dedb7fdfd5fa9..2bb2dcf2bbe73f7feaef65ce37dc81f723423059 100644 (file)
--- a/dhcp6.c
+++ b/dhcp6.c
@@ -1693,7 +1693,7 @@ dhcp6_checkstatusok(const struct interface *ifp,
        return -1;
 }
 
-static struct ipv6_addr *
+struct ipv6_addr *
 dhcp6_iffindaddr(struct interface *ifp, const struct in6_addr *addr,
     short flags)
 {
diff --git a/dhcp6.h b/dhcp6.h
index 41b2213c106f13f69f12bb026275322b21ec1b44..90f60fc089c6148e564504552b2bac07dee383b5 100644 (file)
--- a/dhcp6.h
+++ b/dhcp6.h
@@ -232,6 +232,8 @@ struct dhcp6_state {
 #ifdef INET6
 void dhcp6_printoptions(const struct dhcpcd_ctx *,
     const struct dhcp_opt *, size_t);
+struct ipv6_addr *dhcp6_iffindaddr(struct interface *ifp,
+    const struct in6_addr *addr, short flags);
 struct ipv6_addr *dhcp6_findaddr(struct dhcpcd_ctx *, const struct in6_addr *,
     short);
 size_t dhcp6_find_delegates(struct interface *);
@@ -247,7 +249,6 @@ int dhcp6_dadcompleted(const struct interface *);
 void dhcp6_drop(struct interface *, const char *);
 int dhcp6_dump(struct interface *);
 #else
-#define dhcp6_findaddr(a, b, c) (0)
 #define dhcp6_find_delegates(a) {}
 #define dhcp6_start(a, b) (0)
 #define dhcp6_reboot(a) {}
index 78cd22e2ee8407f2b0581463cafa535c97930e4a..fa940c75d7b5d7b27b956e8047a66e84d7a563a0 100644 (file)
--- a/dhcpcd.c
+++ b/dhcpcd.c
@@ -224,14 +224,14 @@ static int
 dhcpcd_ifipwaited(struct interface *ifp, unsigned long long opts)
 {
 
-       if (opts & DHCPCD_WAITIP4 && !ipv4_ifaddrexists(ifp))
+       if (opts & DHCPCD_WAITIP4 && !ipv4_hasaddr(ifp))
                return 0;
-       if (opts & DHCPCD_WAITIP6 && !ipv6_iffindaddr(ifp, NULL))
+       if (opts & DHCPCD_WAITIP6 && !ipv6_hasaddr(ifp))
                return 0;
        if (opts & DHCPCD_WAITIP &&
            !(opts & (DHCPCD_WAITIP4 | DHCPCD_WAITIP6)) &&
-           !ipv4_ifaddrexists(ifp) &&
-           !ipv6_iffindaddr(ifp, NULL))
+           !ipv4_hasaddr(ifp) &&
+           !ipv6_hasaddr(ifp))
                return 0;
        return 1;
 }
index c2d232bf28914d1e8ca37287988ffda57275a791..e32a0c84c31df43acefa2229178498e5aa8f6ea9 100644 (file)
@@ -2096,7 +2096,7 @@ read_config(struct dhcpcd_ctx *ctx,
        char *line, *buf, *option, *p;
        size_t buflen;
        ssize_t vlen;
-       int skip = 0, have_profile = 0;
+       int skip = 0, have_profile = 0, new_block, had_block;
 #ifndef EMBEDDED_CONFIG
        const char * const *e;
        size_t ol;
@@ -2282,10 +2282,16 @@ read_config(struct dhcpcd_ctx *ctx,
                            *(p - 1) != '\\')
                                *p-- = '\0';
                }
+               if (new_block) {
+                       had_block = 1;
+                       new_block = 0;
+                       ifo->options &= ~DHCPCD_WAITOPTS;
+               }
                /* Start of an interface block, skip if not ours */
                if (strcmp(option, "interface") == 0) {
                        char **n;
 
+                       new_block = 1;
                        if (ifname && line && strcmp(line, ifname) == 0)
                                skip = 0;
                        else
@@ -2312,6 +2318,7 @@ read_config(struct dhcpcd_ctx *ctx,
                }
                /* Start of an ssid block, skip if not ours */
                if (strcmp(option, "ssid") == 0) {
+                       new_block = 1;
                        if (ssid && line && strcmp(line, ssid) == 0)
                                skip = 0;
                        else
@@ -2320,6 +2327,7 @@ read_config(struct dhcpcd_ctx *ctx,
                }
                /* Start of a profile block, skip if not ours */
                if (strcmp(option, "profile") == 0) {
+                       new_block = 1;
                        if (profile && line && strcmp(line, profile) == 0) {
                                skip = 0;
                                have_profile = 1;
@@ -2344,6 +2352,8 @@ read_config(struct dhcpcd_ctx *ctx,
                return NULL;
        }
 
+       if (!had_block)
+               ifo->options &= ~DHCPCD_WAITOPTS;
        finish_config(ifo);
        return ifo;
 }
@@ -2353,18 +2363,27 @@ add_options(struct dhcpcd_ctx *ctx, const char *ifname,
     struct if_options *ifo, int argc, char **argv)
 {
        int oi, opt, r;
+       unsigned long long wait_opts;
 
        if (argc == 0)
                return 1;
 
        optind = 0;
        r = 1;
+       /* Don't apply the command line wait options to each interface,
+        * only use the dhcpcd.conf entry for that. */
+       if (ifname != NULL)
+               wait_opts = ifo->options & DHCPCD_WAITOPTS;
        while ((opt = getopt_long(argc, argv, IF_OPTS, cf_options, &oi)) != -1)
        {
                r = parse_option(ctx, ifname, ifo, opt, optarg, NULL, NULL);
                if (r != 1)
                        break;
        }
+       if (ifname != NULL) {
+               ifo->options &= ~DHCPCD_WAITOPTS;
+               ifo->options |= wait_opts;
+       }
 
        finish_config(ifo);
        return r;
diff --git a/ipv4.c b/ipv4.c
index b86e710a5ff1823ca249f0d9f6db484e688bf5f5..ee994337e827139251452ee9ca1e0618ce01d76c 100644 (file)
--- a/ipv4.c
+++ b/ipv4.c
@@ -157,33 +157,14 @@ ipv4_findaddr(struct dhcpcd_ctx *ctx, const struct in_addr *addr)
 }
 
 int
-ipv4_ifaddrexists(const struct interface *ifp)
+ipv4_hasaddr(const struct interface *ifp)
 {
        const struct dhcp_state *state;
 
        state = D_CSTATE(ifp);
-       return (state && state->addr.s_addr != INADDR_ANY);
-}
-
-int
-ipv4_addrexists(struct dhcpcd_ctx *ctx, const struct in_addr *addr)
-{
-       struct interface *ifp;
-       struct dhcp_state *state;
-
-       TAILQ_FOREACH(ifp, ctx->ifaces, next) {
-               state = D_STATE(ifp);
-               if (state) {
-                       if (addr == NULL) {
-                               if (state->addr.s_addr != INADDR_ANY)
-                                       return 1;
-                       } else if (addr->s_addr == state->addr.s_addr)
-                               return 1;
-               }
-               if (addr != NULL && ipv4_iffindaddr(ifp, addr, NULL))
-                       return 1;
-       }
-       return 0;
+       return (state &&
+           state->added == STATE_ADDED &&
+           state->addr.s_addr != INADDR_ANY);
 }
 
 void
@@ -716,7 +697,7 @@ ipv4_buildroutes(struct dhcpcd_ctx *ctx)
                                        or = ipv4_findrt(ctx, rt, 1);
                                        if (or == NULL ||
                                            or->gate.s_addr != rt->gate.s_addr)
-                                               continue;
+                                               continue;
                                } else {
                                        if (n_route(rt) != 0)
                                                continue;
diff --git a/ipv4.h b/ipv4.h
index 76c32c660675a479293eac648ef661631a6054dd..53d279509622ecf2d140bb8f988c52eb16e8eaa0 100644 (file)
--- a/ipv4.h
+++ b/ipv4.h
@@ -75,8 +75,7 @@ int ipv4_ifcmp(const struct interface *, const struct interface *);
 uint8_t inet_ntocidr(struct in_addr);
 int inet_cidrtoaddr(int, struct in_addr *);
 uint32_t ipv4_getnetmask(uint32_t);
-int ipv4_ifaddrexists(const struct interface *);
-int ipv4_addrexists(struct dhcpcd_ctx *, const struct in_addr *);
+int ipv4_hasaddr(const struct interface *);
 
 #define STATE_ADDED            0x01
 #define STATE_FAKE             0x02
@@ -110,7 +109,8 @@ void ipv4_ctxfree(struct dhcpcd_ctx *);
 #define ipv4_freeroutes(a) {}
 #define ipv4_free(a) {}
 #define ipv4_ctxfree(a) {}
-#define ipv4_ifaddrexists(a) (0)
+#define ipv4_hasaddr(a) (0)
+#define ipv4_preferanother(a) (0)
 #endif
 
 #endif
diff --git a/ipv6.c b/ipv6.c
index c351ac742c5c45858a929e0aefc2260012db1e15..67f9a1746e0f223394f66866e3c290b6f403fae5 100644 (file)
--- a/ipv6.c
+++ b/ipv6.c
@@ -1036,6 +1036,17 @@ ipv6_handleifa(struct dhcpcd_ctx *ctx,
        }
 }
 
+int
+ipv6_hasaddr(struct interface *ifp)
+{
+
+       if (ipv6nd_iffindaddr(ifp, NULL, 0) != NULL)
+               return 1;
+       if (dhcp6_iffindaddr(ifp, NULL, 0) != NULL)
+               return 1;
+       return 0;
+}
+
 const struct ipv6_addr *
 ipv6_iffindaddr(const struct interface *ifp, const struct in6_addr *addr)
 {
diff --git a/ipv6.h b/ipv6.h
index 7fedd11129228225eb51009fb607bf52cdd30d0c..f7f2e1106dfdaeea856f707cfc0f8620ec0d9204 100644 (file)
--- a/ipv6.h
+++ b/ipv6.h
@@ -249,6 +249,7 @@ int ipv6_handleifa_addrs(int, struct ipv6_addrhead *,
 int ipv6_publicaddr(const struct ipv6_addr *);
 const struct ipv6_addr *ipv6_iffindaddr(const struct interface *,
     const struct in6_addr *);
+int ipv6_hasaddr(struct interface *);
 struct ipv6_addr *ipv6_findaddr(struct dhcpcd_ctx *,
     const struct in6_addr *, short);
 #define ipv6_linklocal(ifp) ipv6_iffindaddr((ifp), NULL)
@@ -279,7 +280,7 @@ void ipv6_buildroutes(struct dhcpcd_ctx *);
 #else
 #define ipv6_init(a) (NULL)
 #define ipv6_start(a) (-1)
-#define ipv6_iffindaddr(a, b) (NULL)
+#define ipv6_hasaddr(a) (0)
 #define ipv6_free_ll_callbacks(a) {}
 #define ipv6_free(a) {}
 #define ipv6_drop(a) {}
index 5580bdfaa8bb273b02b6109520a721d3ff45507e..e8e981b6a3d53c1d838a9451b5a50cecb8e3a26d 100644 (file)
--- a/ipv6nd.c
+++ b/ipv6nd.c
@@ -418,6 +418,33 @@ ipv6nd_neighbour(struct dhcpcd_ctx *ctx, struct in6_addr *addr, int flags)
        }
 }
 
+const struct ipv6_addr *
+ipv6nd_iffindaddr(const struct interface *ifp, const struct in6_addr *addr,
+    short flags)
+{
+       struct ra *rap;
+       struct ipv6_addr *ap;
+
+       if (ifp->ctx->ipv6 == NULL)
+               return NULL;
+
+       TAILQ_FOREACH(rap, ifp->ctx->ipv6->ra_routers, next) {
+               if (rap->iface != ifp)
+                       continue;
+               TAILQ_FOREACH(ap, &rap->addrs, next) {
+                       if (addr == NULL) {
+                               if ((ap->flags &
+                                   (IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED)) ==
+                                   (IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED))
+                                       return ap;
+                       } else if (ap->prefix_vltime &&
+                           IN6_ARE_ADDR_EQUAL(&ap->addr, addr) &&
+                           (!flags || ap->flags & flags))
+                               return ap;
+               }
+       }
+       return NULL;
+}
 struct ipv6_addr *
 ipv6nd_findaddr(struct dhcpcd_ctx *ctx, const struct in6_addr *addr,
     short flags)
index a8e20544aba6eca9b0d59aa43052b1806f56a661..ef01c554c2342b2c8499b4798227cb73a2bd4ec0 100644 (file)
--- a/ipv6nd.h
+++ b/ipv6nd.h
@@ -99,6 +99,8 @@ void ipv6nd_printoptions(const struct dhcpcd_ctx *,
     const struct dhcp_opt *, size_t);
 void ipv6nd_startrs(struct interface *);
 ssize_t ipv6nd_env(char **, const char *, const struct interface *);
+const struct ipv6_addr *ipv6nd_iffindaddr(const struct interface *ifp,
+    const struct in6_addr *addr, short flags);
 struct ipv6_addr *ipv6nd_findaddr(struct dhcpcd_ctx *,
     const struct in6_addr *, short);
 void ipv6nd_freedrop_ra(struct ra *, int);
@@ -121,6 +123,7 @@ void ipv6nd_neighbour(struct dhcpcd_ctx *, struct in6_addr *, int);
 #define ipv6nd_hasra(a) (0)
 #define ipv6nd_dadcompleted(a) (0)
 #define ipv6nd_drop(a) {}
+#define ipv6nd_expire(a, b) {}
 #endif
 
 #endif