This ugly loop correspond to ndp(8)'s purge functionality.  Hopefully
this will go away when moving autoconf code to userland.

In the meantime this conversion will allow me to get rid of one more
global list.

ok?

Index: netinet6/nd6.c
===================================================================
RCS file: /cvs/src/sys/netinet6/nd6.c,v
retrieving revision 1.204
diff -u -p -r1.204 nd6.c
--- netinet6/nd6.c      2 Mar 2017 09:24:02 -0000       1.204
+++ netinet6/nd6.c      2 Mar 2017 10:37:14 -0000
@@ -1156,18 +1156,29 @@ nd6_ioctl(u_long cmd, caddr_t data, stru
 
                /* First purge the addresses referenced by a prefix. */
                LIST_FOREACH_SAFE(pr, &nd_prefix, ndpr_entry, npr) {
-                       struct in6_ifaddr *ia6, *ia6_next;
+                       struct ifnet *ifp;
+                       struct ifaddr *ifa, *nifa;
+                       struct in6_ifaddr *ia6;
 
                        if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr))
                                continue; /* XXX */
 
                        /* do we really have to remove addresses as well? */
-                       TAILQ_FOREACH_SAFE(ia6, &in6_ifaddr, ia_list, ia6_next) 
{
-                               if ((ia6->ia6_flags & IN6_IFF_AUTOCONF) == 0)
-                                       continue;
+                       TAILQ_FOREACH(ifp, &ifnet, if_list) {
+                               TAILQ_FOREACH_SAFE(ifa, &ifp->if_addrlist,
+                                   ifa_list, nifa) {
+                                       if (ifa->ifa_addr->sa_family !=
+                                           AF_INET6)
+                                               continue;
 
-                               if (ia6->ia6_ndpr == pr)
-                                       in6_purgeaddr(&ia6->ia_ifa);
+                                       ia6 = ifatoia6(ifa);
+                                       if ((ia6->ia6_flags & IN6_IFF_AUTOCONF)
+                                           == 0)
+                                               continue;
+
+                                       if (ia6->ia6_ndpr == pr)
+                                               in6_purgeaddr(&ia6->ia_ifa);
+                               }
                        }
                }
                /*

Reply via email to