If present, they will show the address family waiting for.
return -1;
}
-struct ipv6_addr *
-dhcp6_iffindaddr(struct interface *ifp, const struct in6_addr *addr,
+const struct ipv6_addr *
+dhcp6_iffindaddr(const struct interface *ifp, const struct in6_addr *addr,
short flags)
{
- struct dhcp6_state *state;
- struct ipv6_addr *ap;
+ const struct dhcp6_state *state;
+ const struct ipv6_addr *ap;
- state = D6_STATE(ifp);
- if (state) {
+ if ((state = D6_STATE(ifp)) != NULL) {
TAILQ_FOREACH(ap, &state->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))
+ if (ipv6_findaddrmatch(ap, addr, flags))
return ap;
}
}
{
struct interface *ifp;
struct ipv6_addr *ap;
+ struct dhcp6_state *state;
TAILQ_FOREACH(ifp, ctx->ifaces, next) {
- ap = dhcp6_iffindaddr(ifp, addr, flags);
- if (ap)
- return ap;
+ if ((state = D6_STATE(ifp)) != NULL) {
+ TAILQ_FOREACH(ap, &state->addrs, next) {
+ if (ipv6_findaddrmatch(ap, addr, flags))
+ return ap;
+ }
+ }
}
return NULL;
}
continue;
}
iap = (const struct dhcp6_ia_addr *)D6_COPTION_DATA(o);
- a = dhcp6_iffindaddr(ifp, &iap->addr, 0);
+ TAILQ_FOREACH(a, &state->addrs, next) {
+ if (ipv6_findaddrmatch(a, &iap->addr, 0))
+ break;
+ }
if (a == NULL) {
a = calloc(1, sizeof(*a));
if (a == NULL) {
#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 ipv6_addr *dhcp6_iffindaddr(const struct interface *ifp,
const struct in6_addr *addr, short flags);
struct ipv6_addr *dhcp6_findaddr(struct dhcpcd_ctx *, const struct in6_addr *,
short);
dhcpcd_daemonise(ctx);
}
-int
-dhcpcd_oneup(struct dhcpcd_ctx *ctx)
-{
- const struct interface *ifp;
-
- TAILQ_FOREACH(ifp, ctx->ifaces, next) {
- if (D_STATE_RUNNING(ifp) ||
- RS_STATE_RUNNING(ifp) ||
- D6_STATE_RUNNING(ifp))
- return 1;
- }
- return 0;
-}
-
static const char *
dhcpcd_af(int af)
{
}
}
-static int
-dhcpcd_ifafwaiting(struct interface *ifp, unsigned long long opts)
+int
+dhcpcd_ifafwaiting(const struct interface *ifp)
{
+ unsigned long long opts;
+ opts = ifp->options->options;
if (opts & DHCPCD_WAITIP4 && !ipv4_hasaddr(ifp))
return AF_INET;
if (opts & DHCPCD_WAITIP6 && !ipv6_hasaddr(ifp))
return AF_MAX;
}
-static int
-dhcpcd_ipwaited(struct dhcpcd_ctx *ctx)
+int
+dhcpcd_afwaiting(const struct dhcpcd_ctx *ctx)
{
- struct interface *ifp;
- int af;
unsigned long long opts;
-
- TAILQ_FOREACH(ifp, ctx->ifaces, next) {
- if (ifp->options->options & DHCPCD_WAITOPTS) {
- af = dhcpcd_ifafwaiting(ifp, ifp->options->options);
- if (af != AF_MAX) {
- logger(ctx, LOG_DEBUG,
- "%s: waiting for an %s address",
- ifp->name, dhcpcd_af(af));
- return 0;
- }
- }
- }
+ const struct interface *ifp;
+ int af;
if (!(ctx->options & DHCPCD_WAITOPTS))
- return 1;
+ return AF_MAX;
opts = ctx->options;
TAILQ_FOREACH(ifp, ctx->ifaces, next) {
else if (opts & DHCPCD_WAITIP6)
af = AF_INET6;
else
- return 1;
+ return AF_MAX;
+ return af;
+}
- logger(ctx, LOG_DEBUG, "waiting for an %s address", dhcpcd_af(af));
- return 0;
+static int
+dhcpcd_ipwaited(struct dhcpcd_ctx *ctx)
+{
+ struct interface *ifp;
+ int af;
+
+ TAILQ_FOREACH(ifp, ctx->ifaces, next) {
+ if ((af = dhcpcd_ifafwaiting(ifp)) != AF_MAX) {
+ logger(ctx, LOG_DEBUG,
+ "%s: waiting for an %s address",
+ ifp->name, dhcpcd_af(af));
+ return 0;
+ }
+ }
+
+ if ((af = dhcpcd_afwaiting(ctx)) != AF_MAX) {
+ logger(ctx, LOG_DEBUG,
+ "waiting for an %s address",
+ dhcpcd_af(af));
+ return 0;
+ }
+
+ return 1;
}
/* Returns the pid of the child, otherwise 0. */
extern const size_t dhcpcd_signals_len;
#endif
-int dhcpcd_oneup(struct dhcpcd_ctx *);
+int dhcpcd_ifafwaiting(const struct interface *);
+int dhcpcd_afwaiting(const struct dhcpcd_ctx *);
pid_t dhcpcd_daemonise(struct dhcpcd_ctx *);
int dhcpcd_handleargs(struct dhcpcd_ctx *, struct fd_list *, int, char **);
!(ia->addr_flags & IN6_IFF_NOTUSEABLE));
}
+int
+ipv6_findaddrmatch(const struct ipv6_addr *addr, const struct in6_addr *match,
+ short flags)
+{
+
+ if (match == NULL) {
+ if ((addr->flags &
+ (IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED)) ==
+ (IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED))
+ return 1;
+ } else if (addr->prefix_vltime &&
+ IN6_ARE_ADDR_EQUAL(&addr->addr, match) &&
+ (!flags || addr->flags & flags))
+ return 1;
+
+ return 0;
+}
+
struct ipv6_addr *
ipv6_findaddr(struct dhcpcd_ctx *ctx, const struct in6_addr *addr, short flags)
{
}
int
-ipv6_hasaddr(struct interface *ifp)
+ipv6_hasaddr(const struct interface *ifp)
{
if (ipv6nd_iffindaddr(ifp, NULL, 0) != NULL)
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 *);
+int ipv6_hasaddr(const struct interface *);
+int ipv6_findaddrmatch(const struct ipv6_addr *, const struct in6_addr *,
+ short);
struct ipv6_addr *ipv6_findaddr(struct dhcpcd_ctx *,
const struct in6_addr *, short);
#define ipv6_linklocal(ifp) ipv6_iffindaddr((ifp), NULL)
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))
+ if (ipv6_findaddrmatch(ap, addr, flags))
return ap;
}
}
return NULL;
}
+
struct ipv6_addr *
ipv6nd_findaddr(struct dhcpcd_ctx *ctx, const struct in6_addr *addr,
short flags)
TAILQ_FOREACH(rap, ctx->ipv6->ra_routers, next) {
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))
+ if (ipv6_findaddrmatch(ap, addr, flags))
return ap;
}
}
#endif
const struct if_options *ifo = ifp->options;
const struct interface *ifp2;
+ int af;
#ifdef INET
int dhcp;
const struct dhcp_state *state;
if (ifp->ctx->options & DHCPCD_DUMPLEASE)
elen = 2;
else
- elen = 12;
+ elen = 11;
#define EMALLOC(i, l) if ((env[(i)] = malloc((l))) == NULL) goto eexit;
/* Make our env + space for profile, wireless and debug */
- env = calloc(1, sizeof(char *) * (elen + 3 + 1));
+ env = calloc(1, sizeof(char *) * (elen + 4 + 1));
if (env == NULL)
goto eexit;
e = strlen("interface") + strlen(ifp->name) + 2;
}
if (env[9] == NULL || env[10] == NULL)
goto eexit;
- if (dhcpcd_oneup(ifp->ctx))
- env[11] = strdup("if_oneup=true");
- else
- env[11] = strdup("if_oneup=false");
- if (env[11] == NULL)
- goto eexit;
+ if ((af = dhcpcd_ifafwaiting(ifp)) != AF_MAX) {
+ e = 20;
+ EMALLOC(elen, e);
+ snprintf(env[elen++], e, "if_afwaiting=%d", af);
+ }
+ if ((af = dhcpcd_afwaiting(ifp->ctx)) != AF_MAX) {
+ e = 20;
+ EMALLOC(elen, e);
+ snprintf(env[elen++], e, "af_waiting=%d", af);
+ }
if (ifo->options & DHCPCD_DEBUG) {
e = strlen("syslog_debug=true") + 1;
EMALLOC(elen, e);