]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Simplify handling of IPv6 address from kernel messages, similar to IPv4.
authorRoy Marples <roy@marples.name>
Tue, 26 Jul 2016 20:52:31 +0000 (20:52 +0000)
committerRoy Marples <roy@marples.name>
Tue, 26 Jul 2016 20:52:31 +0000 (20:52 +0000)
While here, drop the flags argument from the ifa routines.
Instead, grab it in the main ifa handler - it was only for IPv6 addresses
in Linux anyway.

12 files changed:
dhcp6.c
dhcp6.h
if-bsd.c
if-linux.c
if.c
if.h
ipv4.c
ipv4.h
ipv6.c
ipv6.h
ipv6nd.c
ipv6nd.h

diff --git a/dhcp6.c b/dhcp6.c
index a743296ce1b5b129f4fcd4caa67f442ff779c556..7863a30a9676513d03209820b8b605f044886aa1 100644 (file)
--- a/dhcp6.c
+++ b/dhcp6.c
@@ -3467,22 +3467,12 @@ void dhcp6_dropnondelegates(struct interface *ifp)
 }
 
 void
-dhcp6_handleifa(struct dhcpcd_ctx *ctx, int cmd, const char *ifname,
-    const struct in6_addr *addr, int flags)
+dhcp6_handleifa(int cmd, struct ipv6_addr *ia)
 {
-       struct interface *ifp;
        struct dhcp6_state *state;
 
-       if (ctx->ifaces == NULL)
-               return;
-
-       TAILQ_FOREACH(ifp, ctx->ifaces, next) {
-               state = D6_STATE(ifp);
-               if (state == NULL || strcmp(ifp->name, ifname))
-                       continue;
-               ipv6_handleifa_addrs(cmd, &state->addrs, addr, flags);
-       }
-
+       if ((state = D6_STATE(ia->iface)) != NULL)
+               ipv6_handleifa_addrs(cmd, &state->addrs, ia);
 }
 
 ssize_t
diff --git a/dhcp6.h b/dhcp6.h
index 3287bbaf7193bd160a21a580738cda82d23d8453..d967caa2dcad0f5c051b7e32ed1c5ac1a210d18e 100644 (file)
--- a/dhcp6.h
+++ b/dhcp6.h
@@ -244,8 +244,7 @@ void dhcp6_renew(struct interface *);
 ssize_t dhcp6_env(char **, const char *, const struct interface *,
     const struct dhcp6_message *, size_t);
 void dhcp6_free(struct interface *);
-void dhcp6_handleifa(struct dhcpcd_ctx *, int, const char *,
-    const struct in6_addr *addr, int);
+void dhcp6_handleifa(int, struct ipv6_addr *);
 int dhcp6_dadcompleted(const struct interface *);
 void dhcp6_drop(struct interface *, const char *);
 void dhcp6_dropnondelegates(struct interface *ifp);
index d99bc306c74641e082c0116f68027abf17d6da62..08cb892c5f83e4abee8ed0f407de0d200474de3b 100644 (file)
--- a/if-bsd.c
+++ b/if-bsd.c
@@ -805,17 +805,17 @@ if_initrt(struct dhcpcd_ctx *ctx)
 }
 
 int
-if_addrflags(const struct in_addr *addr, const struct interface *ifp)
+if_addrflags(const struct ipv4_addr *ia)
 {
 #ifdef SIOCGIFAFLAG_IN
        struct ifreq ifr;
        struct sockaddr_in *sin;
 
        memset(&ifr, 0, sizeof(ifr));
-       strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
+       strlcpy(ifr.ifr_name, ia->iface->name, sizeof(ifr.ifr_name));
        sin = (void *)&ifr.ifr_addr;
        sin->sin_family = AF_INET;
-       sin->sin_addr = *addr;
+       sin->sin_addr = ia->addr;
        if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFAFLAG_IN, &ifr) == -1)
                return -1;
        return ifr.ifr_addrflags;
@@ -1164,16 +1164,16 @@ if_initrt6(struct dhcpcd_ctx *ctx)
 }
 
 int
-if_addrflags6(const struct in6_addr *addr, const struct interface *ifp)
+if_addrflags6(const struct ipv6_addr *ia)
 {
        int flags;
        struct in6_ifreq ifr6;
        struct priv *priv;
 
        memset(&ifr6, 0, sizeof(ifr6));
-       strlcpy(ifr6.ifr_name, ifp->name, sizeof(ifr6.ifr_name));
+       strlcpy(ifr6.ifr_name, ia->iface->name, sizeof(ifr6.ifr_name));
        ifr6.ifr_addr.sin6_family = AF_INET6;
-       ifr6.ifr_addr.sin6_addr = *addr;
+       ifr6.ifr_addr.sin6_addr = ia->addr;
        ifa_scope(&ifr6.ifr_addr, ifp->index);
        priv = (struct priv *)ifp->ctx->priv;
        if (ioctl(priv->pf_inet6_fd, SIOCGIFAFLAG_IN6, &ifr6) != -1)
@@ -1374,7 +1374,6 @@ if_ifa(struct dhcpcd_ctx *ctx, const struct ifa_msghdr *ifam)
        {
                const struct sockaddr_in *sin;
                struct in_addr addr, mask, bcast;
-               int flags;
 
                sin = (const void *)rti_info[RTAX_IFA];
                addr.s_addr = sin != NULL && sin->sin_family == AF_INET ?
@@ -1385,13 +1384,8 @@ if_ifa(struct dhcpcd_ctx *ctx, const struct ifa_msghdr *ifam)
                sin = (const void *)rti_info[RTAX_BRD];
                bcast.s_addr = sin != NULL && sin->sin_family == AF_INET ?
                    sin->sin_addr.s_addr : INADDR_ANY;
-               if (ifam->ifam_type == RTM_NEWADDR) {
-                       if ((flags = if_addrflags(&addr, ifp)) == -1)
-                               break;
-               } else
-                       flags = 0;
                ipv4_handleifa(ctx, ifam->ifam_type, NULL, ifp->name,
-                   &addr, &mask, &bcast, flags);
+                   &addr, &mask, &bcast);
                break;
        }
 #endif
@@ -1400,7 +1394,6 @@ if_ifa(struct dhcpcd_ctx *ctx, const struct ifa_msghdr *ifam)
        {
                struct in6_addr addr6, mask6;
                const struct sockaddr_in6 *sin6;
-               int flags;
 
                sin6 = (const void *)rti_info[RTAX_IFA];
                addr6 = sin6->sin6_addr;
@@ -1408,13 +1401,8 @@ if_ifa(struct dhcpcd_ctx *ctx, const struct ifa_msghdr *ifam)
                sin6 = (const void *)rti_info[RTAX_NETMASK];
                mask6 = sin6->sin6_addr;
                DESCOPE(&mask6);
-               if (ifam->ifam_type == RTM_NEWADDR) {
-                       if ((flags = if_addrflags6(&addr6, ifp)) == -1)
-                               break;
-               } else
-                       flags = 0;
                ipv6_handleifa(ctx, ifam->ifam_type, NULL,
-                   ifp->name, &addr6, ipv6_prefixlen(&mask6), flags);
+                   ifp->name, &addr6, ipv6_prefixlen(&mask6));
                break;
        }
 #endif
index bfaac490d263477c31da431647d05ed057632e0e..26018ba535b1551122e0bde786a3457ca55112ab 100644 (file)
@@ -683,7 +683,7 @@ link_addr(struct dhcpcd_ctx *ctx, struct interface *ifp, struct nlmsghdr *nlm)
                        rta = RTA_NEXT(rta, len);
                }
                ipv4_handleifa(ctx, nlm->nlmsg_type, NULL, ifp->name,
-                   &addr, &net, &brd, ifa->ifa_flags);
+                   &addr, &net, &brd);
                break;
 #endif
 #ifdef INET6
@@ -699,7 +699,7 @@ link_addr(struct dhcpcd_ctx *ctx, struct interface *ifp, struct nlmsghdr *nlm)
                        rta = RTA_NEXT(rta, len);
                }
                ipv6_handleifa(ctx, nlm->nlmsg_type, NULL, ifp->name,
-                   &addr6, ifa->ifa_prefixlen, ifa->ifa_flags);
+                   &addr6, ifa->ifa_prefixlen);
                break;
 #endif
        }
@@ -1494,8 +1494,7 @@ if_initrt(struct dhcpcd_ctx *ctx)
 }
 
 int
-if_addrflags(__unused const struct in_addr *addr,
-    __unused const struct interface *ifp)
+if_addrflags(__unused const struct ipv4_addr *addr)
 {
 
        /* Linux has no support for IPv4 address flags */
@@ -1677,7 +1676,7 @@ if_initrt6(struct dhcpcd_ctx *ctx)
 }
 
 int
-if_addrflags6(const struct in6_addr *addr, const struct interface *ifp)
+if_addrflags6(const struct ipv6_addr *ia)
 {
        FILE *fp;
        char *p, ifaddress[33], address[33], name[IF_NAMESIZE + 1];
@@ -1689,8 +1688,8 @@ if_addrflags6(const struct in6_addr *addr, const struct interface *ifp)
                return -1;
 
        p = ifaddress;
-       for (i = 0; i < (int)sizeof(addr->s6_addr); i++) {
-               p += snprintf(p, 3, "%.2x", addr->s6_addr[i]);
+       for (i = 0; i < (int)sizeof(ia->addr.s6_addr); i++) {
+               p += snprintf(p, 3, "%.2x", ia->addr.s6_addr[i]);
        }
        *p = '\0';
 
@@ -1699,10 +1698,10 @@ if_addrflags6(const struct in6_addr *addr, const struct interface *ifp)
        {
                if (strlen(address) != 32) {
                        fclose(fp);
-                       errno = ENOTSUP;
+                       errno = EINVAL;
                        return -1;
                }
-               if (strcmp(name, ifp->name) == 0 &&
+               if (strcmp(name, ia->iface->name) == 0 &&
                    strcmp(ifaddress, address) == 0)
                {
                        fclose(fp);
diff --git a/if.c b/if.c
index c4a095e55d21c5faa3f204f4503e0fac97375fc8..dad80ca2a2f14ba9e73d7fd3592bf6a393e59f4c 100644 (file)
--- a/if.c
+++ b/if.c
@@ -198,8 +198,6 @@ static void if_learnaddrs(struct dhcpcd_ctx *ctx, struct if_head *ifs,
 #ifdef INET6
        struct sockaddr_in6 *sin6, *net6;
 #endif
-       int ifa_flags;
-
 
        for (ifa = ifaddrs; ifa; ifa = ifa->ifa_next) {
                if (ifa->ifa_addr == NULL)
@@ -215,10 +213,9 @@ static void if_learnaddrs(struct dhcpcd_ctx *ctx, struct if_head *ifs,
                                brd = (void *)ifa->ifa_dstaddr;
                        else
                                brd = (void *)ifa->ifa_broadaddr;
-                       ifa_flags = if_addrflags(&addr->sin_addr, ifp);
                        ipv4_handleifa(ctx, RTM_NEWADDR, ifs, ifa->ifa_name,
                                &addr->sin_addr, &net->sin_addr,
-                               brd ? &brd->sin_addr : NULL, ifa_flags);
+                               brd ? &brd->sin_addr : NULL);
                        break;
 #endif
 #ifdef INET6
@@ -231,13 +228,9 @@ static void if_learnaddrs(struct dhcpcd_ctx *ctx, struct if_head *ifs,
                                sin6->sin6_addr.s6_addr[2] =
                                    sin6->sin6_addr.s6_addr[3] = '\0';
 #endif
-                       ifa_flags = if_addrflags6(&sin6->sin6_addr, ifp);
-                       if (ifa_flags != -1)
-                               ipv6_handleifa(ctx, RTM_NEWADDR, ifs,
-                                   ifa->ifa_name,
-                                   &sin6->sin6_addr,
-                                   ipv6_prefixlen(&net6->sin6_addr),
-                                   ifa_flags);
+                       ipv6_handleifa(ctx, RTM_NEWADDR, ifs,
+                           ifa->ifa_name, &sin6->sin6_addr,
+                           ipv6_prefixlen(&net6->sin6_addr));
                        break;
 #endif
                }
diff --git a/if.h b/if.h
index 5bf93b5ba93d229b90f584b1c22d3ff469827c66..55ae409365c5ebaa3b0336f09462ffa140d58f79 100644 (file)
--- a/if.h
+++ b/if.h
@@ -168,7 +168,7 @@ ssize_t if_readraw(struct interface *, int, void *, size_t, int *);
 void if_closeraw(struct interface *, int);
 
 int if_address(unsigned char, const struct ipv4_addr *);
-int if_addrflags(const struct in_addr *, const struct interface *);
+int if_addrflags(const struct ipv4_addr *);
 
 int if_route(unsigned char, const struct rt *rt);
 int if_initrt(struct dhcpcd_ctx *);
@@ -185,7 +185,7 @@ int ip6_temp_valid_lifetime(const char *ifname);
 #endif
 
 int if_address6(unsigned char, const struct ipv6_addr *);
-int if_addrflags6(const struct in6_addr *, const struct interface *);
+int if_addrflags6(const struct ipv6_addr *);
 int if_getlifetime6(struct ipv6_addr *);
 
 int if_route6(unsigned char, const struct rt6 *rt);
diff --git a/ipv4.c b/ipv4.c
index 33bb8a79ef6995e00165e1afe5b97a766adab074..7407a685c89dfdbb4b89d2279dc130ebb8c3905b 100644 (file)
--- a/ipv4.c
+++ b/ipv4.c
@@ -1227,7 +1227,7 @@ void
 ipv4_handleifa(struct dhcpcd_ctx *ctx,
     int cmd, struct if_head *ifs, const char *ifname,
     const struct in_addr *addr, const struct in_addr *mask,
-    const struct in_addr *brd, int flags)
+    const struct in_addr *brd)
 {
        struct interface *ifp;
        struct ipv4_state *state;
@@ -1269,7 +1269,7 @@ ipv4_handleifa(struct dhcpcd_ctx *ctx,
                        ia->brd = *brd;
                else
                        ia->brd.s_addr = INADDR_ANY;
-               ia->addr_flags = flags;
+               ia->addr_flags = if_addrflags(ia);
                break;
        case RTM_DELADDR:
                if (ia == NULL)
diff --git a/ipv4.h b/ipv4.h
index bb8adf4e2d605396a0f9eeec8a73c0deb35e8318..66425f88c61415bd412022c8545d688fb4b5ade0 100644 (file)
--- a/ipv4.h
+++ b/ipv4.h
@@ -142,8 +142,7 @@ struct ipv4_addr *ipv4_findaddr(struct dhcpcd_ctx *, const struct in_addr *);
 struct ipv4_addr *ipv4_findmaskaddr(struct dhcpcd_ctx *,
     const struct in_addr *);
 void ipv4_handleifa(struct dhcpcd_ctx *, int, struct if_head *, const char *,
-    const struct in_addr *, const struct in_addr *, const struct in_addr *,
-    int);
+    const struct in_addr *, const struct in_addr *, const struct in_addr *);
 
 void ipv4_freeroutes(struct rt_head *);
 
diff --git a/ipv6.c b/ipv6.c
index b4dacfde263885356e48a4ebb62fb314de949bbc..860605fb46176e508d0f1c4aa26be286c622d236 100644 (file)
--- a/ipv6.c
+++ b/ipv6.c
@@ -566,17 +566,15 @@ void
 ipv6_checkaddrflags(void *arg)
 {
        struct ipv6_addr *ap;
-       int ifa_flags;
 
        ap = arg;
-       ifa_flags = if_addrflags6(&ap->addr, ap->iface);
        if (ifa_flags == -1)
                logger(ap->iface->ctx, LOG_ERR,
                    "%s: if_addrflags6: %m", ap->iface->name);
        else if (!(ifa_flags & IN6_IFF_TENTATIVE)) {
                ipv6_handleifa(ap->iface->ctx, RTM_NEWADDR,
                    ap->iface->ctx->ifaces, ap->iface->name,
-                   &ap->addr, ap->prefix_len, ifa_flags);
+                   &ap->addr, ap->prefix_len);
        } else {
                struct timespec tv;
 
@@ -1012,11 +1010,11 @@ ipv6_getstate(struct interface *ifp)
 void
 ipv6_handleifa(struct dhcpcd_ctx *ctx,
     int cmd, struct if_head *ifs, const char *ifname,
-    const struct in6_addr *addr, uint8_t prefix_len, int flags)
+    const struct in6_addr *addr, uint8_t prefix_len)
 {
        struct interface *ifp;
        struct ipv6_state *state;
-       struct ipv6_addr *ap;
+       struct ipv6_addr *ia;
        struct ll_callback *cb;
 
 #if 0
@@ -1025,63 +1023,55 @@ ipv6_handleifa(struct dhcpcd_ctx *ctx,
 
        dbp = inet_ntop(AF_INET6, &addr->s6_addr,
            dbuf, INET6_ADDRSTRLEN);
-       logger(ctx, LOG_INFO, "%s: cmd %d addr %s flags %d",
-           ifname, cmd, dbp, flags);
+       logger(ctx, LOG_INFO, "%s: cmd %d addr %s",
+           ifname, cmd, dbp);
 #endif
 
        if (ifs == NULL)
                ifs = ctx->ifaces;
-       if (ifs == NULL) {
-               errno = ESRCH;
+       if (ifs == NULL)
                return;
-       }
        if ((ifp = if_find(ifs, ifname)) == NULL)
                return;
        if ((state = ipv6_getstate(ifp)) == NULL)
                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))
+       TAILQ_FOREACH(ia, &state->addrs, next) {
+               if (IN6_ARE_ADDR_EQUAL(&ia->addr, addr))
                        break;
        }
 
        switch (cmd) {
        case RTM_DELADDR:
-               if (ap) {
-                       TAILQ_REMOVE(&state->addrs, ap, next);
-                       ipv6_freeaddr(ap);
+               if (ia != NULL) {
+                       TAILQ_REMOVE(&state->addrs, ia, next);
+                       /* We'll free it at the end of the function. */
                }
                break;
        case RTM_NEWADDR:
-               if (ap == NULL) {
+               if (ia == NULL) {
                        char buf[INET6_ADDRSTRLEN];
                        const char *cbp;
 
-                       ap = calloc(1, sizeof(*ap));
-                       if (ap == NULL) {
+                       if ((ia = calloc(1, sizeof(*ia))) == NULL) {
                                logger(ctx, LOG_ERR,
                                    "%s: calloc: %m", __func__);
                                break;
                        }
 #ifdef ALIAS_ADDR
-                       strlcpy(ap->alias, ifname, sizeof(ap->alias));
+                       strlcpy(ia->alias, ifname, sizeof(ia->alias));
 #endif
-                       ap->iface = ifp;
-                       ap->addr = *addr;
-                       ap->prefix_len = prefix_len;
-                       ipv6_makeprefix(&ap->prefix, &ap->addr,
-                           ap->prefix_len);
+                       ia->iface = ifp;
+                       ia->addr = *addr;
+                       ia->prefix_len = prefix_len;
+                       ipv6_makeprefix(&ia->prefix, &ia->addr,
+                           ia->prefix_len);
                        cbp = inet_ntop(AF_INET6, &addr->s6_addr,
                            buf, sizeof(buf));
                        if (cbp)
-                               snprintf(ap->saddr, sizeof(ap->saddr),
+                               snprintf(ia->saddr, sizeof(ia->saddr),
                                    "%s/%d", cbp, prefix_len);
-                       if (if_getlifetime6(ap) == -1) {
+                       if (if_getlifetime6(ia) == -1) {
                                /* No support or address vanished.
                                 * Either way, just set a deprecated
                                 * infinite time lifetime and continue.
@@ -1090,8 +1080,8 @@ ipv6_handleifa(struct dhcpcd_ctx *ctx,
                                 * temporary addresses.
                                 * As we can't extend infinite, we'll
                                 * create a new temporary address. */
-                               ap->prefix_pltime = 0;
-                               ap->prefix_vltime =
+                               ia->prefix_pltime = 0;
+                               ia->prefix_vltime =
                                    ND6_INFINITE_LIFETIME;
                        }
                        /* This is a minor regression against RFC 4941
@@ -1104,33 +1094,32 @@ ipv6_handleifa(struct dhcpcd_ctx *ctx,
                         * pretend lifetimes are infinite and always
                         * generate a new temporary address on
                         * restart. */
-                       ap->acquired = ap->created;
-                       TAILQ_INSERT_TAIL(&state->addrs,
-                           ap, next);
+                       ia->acquired = ia->created;
+                       TAILQ_INSERT_TAIL(&state->addrs, ia, next);
                }
-               ap->addr_flags = flags;
+               ia->addr_flags = if_addrflags6(ia);
 #ifdef IPV6_MANAGETEMPADDR
-               if (ap->addr_flags & IN6_IFF_TEMPORARY)
-                       ap->flags |= IPV6_AF_TEMPORARY;
+               if (ia->addr_flags & IN6_IFF_TEMPORARY)
+                       ia->flags |= IPV6_AF_TEMPORARY;
 #endif
-               if (IN6_IS_ADDR_LINKLOCAL(&ap->addr) || ap->dadcallback) {
+               if (IN6_IS_ADDR_LINKLOCAL(&ia->addr) || ia->dadcallback) {
 #ifdef IPV6_POLLADDRFLAG
-                       if (ap->addr_flags & IN6_IFF_TENTATIVE) {
+                       if (ia->addr_flags & IN6_IFF_TENTATIVE) {
                                struct timespec tv;
 
                                ms_to_ts(&tv, RETRANS_TIMER / 2);
                                eloop_timeout_add_tv(
-                                   ap->iface->ctx->eloop,
-                                   &tv, ipv6_checkaddrflags, ap);
+                                   ia->iface->ctx->eloop,
+                                   &tv, ipv6_checkaddrflags, ia);
                                break;
                        }
 #endif
 
-                       if (ap->dadcallback)
-                               ap->dadcallback(ap);
+                       if (ia->dadcallback)
+                               ia->dadcallback(ia);
 
-                       if (IN6_IS_ADDR_LINKLOCAL(&ap->addr) &&
-                           !(ap->addr_flags & IN6_IFF_NOTUSEABLE))
+                       if (IN6_IS_ADDR_LINKLOCAL(&ia->addr) &&
+                           !(ia->addr_flags & IN6_IFF_NOTUSEABLE))
                        {
                                /* Now run any callbacks.
                                 * Typically IPv6RS or DHCPv6 */
@@ -1147,6 +1136,17 @@ ipv6_handleifa(struct dhcpcd_ctx *ctx,
                }
                break;
        }
+
+       if (ia != NULL) {
+               if (!IN6_IS_ADDR_LINKLOCAL(&ia->addr)) {
+                       ipv6nd_handleifa(cmd, ia);
+                       dhcp6_handleifa(cmd, ia);
+               }
+
+               /* Done with the ia now, so free it. */
+               if (cmd == RTM_DELADDR)
+                       ipv6_freeaddr(ia);
+       }
 }
 
 int
@@ -1604,44 +1604,45 @@ ipv6_ctxfree(struct dhcpcd_ctx *ctx)
 
 int
 ipv6_handleifa_addrs(int cmd,
-    struct ipv6_addrhead *addrs, const struct in6_addr *addr, int flags)
+    struct ipv6_addrhead *addrs, const struct ipv6_addr *addr)
 {
-       struct ipv6_addr *ap, *apn;
+       struct ipv6_addr *ia, *ian;
        uint8_t found, alldadcompleted;
 
        alldadcompleted = 1;
        found = 0;
-       TAILQ_FOREACH_SAFE(ap, addrs, next, apn) {
-               if (!IN6_ARE_ADDR_EQUAL(addr, &ap->addr)) {
-                       if (ap->flags & IPV6_AF_ADDED &&
-                           !(ap->flags & IPV6_AF_DADCOMPLETED))
+       TAILQ_FOREACH_SAFE(ia, addrs, next, ian) {
+               if (!IN6_ARE_ADDR_EQUAL(&addr->addr, &ia->addr)) {
+                       if (ia->flags & IPV6_AF_ADDED &&
+                           !(ia->flags & IPV6_AF_DADCOMPLETED))
                                alldadcompleted = 0;
                        continue;
                }
                switch (cmd) {
                case RTM_DELADDR:
-                       if (ap->flags & IPV6_AF_ADDED) {
-                               logger(ap->iface->ctx, LOG_INFO,
+                       if (ia->flags & IPV6_AF_ADDED) {
+                               logger(ia->iface->ctx, LOG_INFO,
                                    "%s: deleted address %s",
-                                   ap->iface->name, ap->saddr);
-                               ap->flags &= ~IPV6_AF_ADDED;
+                                   ia->iface->name, ia->saddr);
+                               ia->flags &= ~IPV6_AF_ADDED;
                        }
                        break;
                case RTM_NEWADDR:
                        /* Safety - ignore tentative announcements */
-                       if (flags & (IN6_IFF_DETACHED |IN6_IFF_TENTATIVE))
+                       if (addr->addr_flags &
+                           (IN6_IFF_DETACHED | IN6_IFF_TENTATIVE))
                                break;
-                       if ((ap->flags & IPV6_AF_DADCOMPLETED) == 0) {
+                       if ((ia->flags & IPV6_AF_DADCOMPLETED) == 0) {
                                found++;
-                               if (flags & IN6_IFF_DUPLICATED)
-                                       ap->flags |= IPV6_AF_DUPLICATED;
+                               if (addr->addr_flags & IN6_IFF_DUPLICATED)
+                                       ia->flags |= IPV6_AF_DUPLICATED;
                                else
-                                       ap->flags &= ~IPV6_AF_DUPLICATED;
-                               if (ap->dadcallback)
-                                       ap->dadcallback(ap);
+                                       ia->flags &= ~IPV6_AF_DUPLICATED;
+                               if (ia->dadcallback)
+                                       ia->dadcallback(ia);
                                /* We need to set this here in-case the
                                 * dadcallback function checks it */
-                               ap->flags |= IPV6_AF_DADCOMPLETED;
+                               ia->flags |= IPV6_AF_DADCOMPLETED;
                        }
                        break;
                }
diff --git a/ipv6.h b/ipv6.h
index 5171c1001748444a57ef0106e429f174aaada7d5..5d7285c3d14e7da26d937507173fcca46546b9a1 100644 (file)
--- a/ipv6.h
+++ b/ipv6.h
@@ -290,9 +290,8 @@ ssize_t ipv6_addaddrs(struct ipv6_addrhead *addrs);
 void ipv6_freedrop_addrs(struct ipv6_addrhead *, int,
     const struct interface *);
 void ipv6_handleifa(struct dhcpcd_ctx *ctx, int, struct if_head *,
-    const char *, const struct in6_addr *, uint8_t, int);
-int ipv6_handleifa_addrs(int, struct ipv6_addrhead *,
-    const struct in6_addr *, int);
+    const char *, const struct in6_addr *, uint8_t);
+int ipv6_handleifa_addrs(int, struct ipv6_addrhead *, const struct ipv6_addr *);
 struct ipv6_addr *ipv6_iffindaddr(struct interface *,
     const struct in6_addr *, int);
 int ipv6_hasaddr(const struct interface *);
index b0b65629abb075d1b831cc995f06b13c4018d439..95eda6b27ba6d93336f4027fa495117d466fd72a 100644 (file)
--- a/ipv6nd.c
+++ b/ipv6nd.c
@@ -1306,17 +1306,14 @@ ipv6nd_env(char **env, const char *prefix, const struct interface *ifp)
 }
 
 void
-ipv6nd_handleifa(struct dhcpcd_ctx *ctx, int cmd, const char *ifname,
-    const struct in6_addr *addr, int flags)
+ipv6nd_handleifa(int cmd, struct ipv6_addr *addr)
 {
        struct ra *rap;
 
-       if (ctx->ipv6 == NULL)
-               return;
-       TAILQ_FOREACH(rap, ctx->ipv6->ra_routers, next) {
-               if (strcmp(rap->iface->name, ifname))
+       TAILQ_FOREACH(rap, addr->iface->ctx->ipv6->ra_routers, next) {
+               if (rap->iface != addr->iface)
                        continue;
-               ipv6_handleifa_addrs(cmd, &rap->addrs, addr, flags);
+               ipv6_handleifa_addrs(cmd, &rap->addrs, addr);
        }
 }
 
index c6fd2bb17099075ed81854a17309156d7d4e213d..d10b340ac3d3e6cf0eedf897e6ab747b065eb404 100644 (file)
--- a/ipv6nd.h
+++ b/ipv6nd.h
@@ -109,8 +109,7 @@ ssize_t ipv6nd_free(struct interface *);
 void ipv6nd_expirera(void *arg);
 int ipv6nd_hasra(const struct interface *);
 int ipv6nd_hasradhcp(const struct interface *);
-void ipv6nd_handleifa(struct dhcpcd_ctx *, int,
-    const char *, const struct in6_addr *, int);
+void ipv6nd_handleifa(int, struct ipv6_addr *);
 int ipv6nd_dadcompleted(const struct interface *);
 void ipv6nd_expire(struct interface *, uint32_t);
 void ipv6nd_drop(struct interface *);