From: Roy Marples Date: Tue, 8 Jul 2014 19:29:45 +0000 (+0000) Subject: Pseudo interfaces also have an address list, do loop through all of them. X-Git-Tag: v6.4.1~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=de8a6b2c8deab288e87c57b83ff593c2570dc21a;p=thirdparty%2Fdhcpcd.git Pseudo interfaces also have an address list, do loop through all of them. Describe reject routes better. --- diff --git a/ipv6.c b/ipv6.c index 98a4d454..44cca62c 100644 --- a/ipv6.c +++ b/ipv6.c @@ -755,72 +755,70 @@ ipv6_handleifa(struct dhcpcd_ctx *ctx, return; } TAILQ_FOREACH(ifp, ifs, next) { - if (strcmp(ifp->name, ifname) == 0) - break; - } - if (ifp == NULL) { - errno = ESRCH; - return; - } - state = ipv6_getstate(ifp); - if (state == NULL) { - errno = ENOENT; - return; - } - - if (!IN6_IS_ADDR_LINKLOCAL(addr)) { - ipv6nd_handleifa(ctx, cmd, ifname, addr, flags); - dhcp6_handleifa(ctx, cmd, ifname, addr, flags); - } - - TAILQ_FOREACH(ap, &state->addrs, next) { - if (IN6_ARE_ADDR_EQUAL(&ap->addr, addr)) - break; - } + /* Each psuedo interface also stores addresses */ + if (strcmp(ifp->name, ifname)) + continue; + state = ipv6_getstate(ifp); + if (state == NULL) + continue; - switch (cmd) { - case RTM_DELADDR: - if (ap) { - TAILQ_REMOVE(&state->addrs, ap, next); - free(ap); + if (!IN6_IS_ADDR_LINKLOCAL(addr)) { + ipv6nd_handleifa(ctx, cmd, ifname, addr, flags); + dhcp6_handleifa(ctx, cmd, ifname, addr, flags); } - break; - case RTM_NEWADDR: - if (ap == NULL) { - ap = calloc(1, sizeof(*ap)); - ap->iface = ifp; - memcpy(ap->addr.s6_addr, addr->s6_addr, - sizeof(ap->addr.s6_addr)); - TAILQ_INSERT_TAIL(&state->addrs, - ap, next); - } - ap->addr_flags = flags; - - if (IN6_IS_ADDR_LINKLOCAL(&ap->addr)) { -#ifdef IPV6_POLLADDRFLAG - if (ap->addr_flags & IN6_IFF_TENTATIVE) { - struct timeval tv; - ms_to_tv(&tv, RETRANS_TIMER / 2); - eloop_timeout_add_tv(ap->iface->ctx->eloop, - &tv, ipv6_checkaddrflags, ap); + TAILQ_FOREACH(ap, &state->addrs, next) { + if (IN6_ARE_ADDR_EQUAL(&ap->addr, addr)) break; + } + + switch (cmd) { + case RTM_DELADDR: + if (ap) { + TAILQ_REMOVE(&state->addrs, ap, next); + free(ap); + } + break; + case RTM_NEWADDR: + if (ap == NULL) { + ap = calloc(1, sizeof(*ap)); + ap->iface = ifp; + memcpy(ap->addr.s6_addr, addr->s6_addr, + sizeof(ap->addr.s6_addr)); + TAILQ_INSERT_TAIL(&state->addrs, + ap, next); } + ap->addr_flags = flags; + + if (IN6_IS_ADDR_LINKLOCAL(&ap->addr)) { +#ifdef IPV6_POLLADDRFLAG + if (ap->addr_flags & IN6_IFF_TENTATIVE) { + struct timeval tv; + + ms_to_tv(&tv, RETRANS_TIMER / 2); + eloop_timeout_add_tv( + ap->iface->ctx->eloop, + &tv, ipv6_checkaddrflags, ap); + break; + } #endif - if (!(ap->addr_flags & IN6_IFF_NOTUSEABLE)) { - /* Now run any callbacks. - * Typically IPv6RS or DHCPv6 */ - while ((cb = TAILQ_FIRST(&state->ll_callbacks))) - { - TAILQ_REMOVE(&state->ll_callbacks, - cb, next); - cb->callback(cb->arg); - free(cb); + if (!(ap->addr_flags & IN6_IFF_NOTUSEABLE)) { + /* Now run any callbacks. + * Typically IPv6RS or DHCPv6 */ + while ((cb = + TAILQ_FIRST(&state->ll_callbacks))) + { + TAILQ_REMOVE( + &state->ll_callbacks, + cb, next); + cb->callback(cb->arg); + free(cb); + } } } + break; } - break; } } @@ -1057,7 +1055,8 @@ ipv6_handleifa_addrs(int cmd, found = 0; TAILQ_FOREACH_SAFE(ap, addrs, next, apn) { if (!IN6_ARE_ADDR_EQUAL(addr, &ap->addr)) { - if ((ap->flags & IPV6_AF_DADCOMPLETED) == 0) + if (ap->flags & IPV6_AF_ADDED && + !(ap->flags & IPV6_AF_DADCOMPLETED)) alldadcompleted = 0; continue; } @@ -1126,7 +1125,8 @@ desc_route(const char *cmd, const struct rt6 *rt) syslog(LOG_INFO, "%s: %s default route via %s", ifname, cmd, gate); else - syslog(LOG_INFO, "%s: %s route to %s/%d via %s", ifname, cmd, + syslog(LOG_INFO, "%s: %s%s route to %s/%d via %s", ifname, cmd, + rt->flags & RTF_REJECT ? " reject" : "", dest, ipv6_prefixlen(&rt->net), gate); }