return -1;
}
-static struct ipv6_addr *
+struct ipv6_addr *
dhcp6_iffindaddr(struct interface *ifp, const struct in6_addr *addr,
short flags)
{
#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 *);
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) {}
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;
}
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;
*(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
}
/* 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
}
/* 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;
return NULL;
}
+ if (!had_block)
+ ifo->options &= ~DHCPCD_WAITOPTS;
finish_config(ifo);
return ifo;
}
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;
}
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
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;
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
#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
}
}
+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)
{
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)
#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) {}
}
}
+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)
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);
#define ipv6nd_hasra(a) (0)
#define ipv6nd_dadcompleted(a) (0)
#define ipv6nd_drop(a) {}
+#define ipv6nd_expire(a, b) {}
#endif
#endif