From: Roy Marples Date: Wed, 20 May 2015 10:25:10 +0000 (+0000) Subject: Fix waiting for ip address, [1972d664c2]. X-Git-Tag: v6.9.1~79 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=edb0ed379d7d4e1cb40aa6f81a68f58a84b17b03;p=thirdparty%2Fdhcpcd.git Fix waiting for ip address, [1972d664c2]. --- diff --git a/dhcp6.c b/dhcp6.c index c1b7bfdb..2bb2dcf2 100644 --- 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 41b2213c..90f60fc0 100644 --- 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) {} diff --git a/dhcpcd.c b/dhcpcd.c index 78cd22e2..fa940c75 100644 --- 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; } diff --git a/if-options.c b/if-options.c index c2d232bf..e32a0c84 100644 --- a/if-options.c +++ b/if-options.c @@ -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 b86e710a..ee994337 100644 --- 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 76c32c66..53d27950 100644 --- 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 c351ac74..67f9a174 100644 --- 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 7fedd111..f7f2e110 100644 --- 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) {} diff --git a/ipv6nd.c b/ipv6nd.c index 5580bdfa..e8e981b6 100644 --- 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) diff --git a/ipv6nd.h b/ipv6nd.h index a8e20544..ef01c554 100644 --- 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