Index: netinet/ip_carp.c
===================================================================
--- netinet/ip_carp.c	(revision 194846)
+++ netinet/ip_carp.c	(working copy)
@@ -1667,7 +1667,7 @@
 
 	/* we have to do it by hands to check we won't match on us */
 	ia_if = NULL; own = 0;
-	for (ia = V_in6_ifaddr; ia; ia = ia->ia_next) {
+	TAILQ_FOREACH(ia6, &V_in6_ifaddrhead, ia_link) {
 		int i;
 
 		for (i = 0; i < 4; i++) {
Index: netinet6/in6_ifattach.c
===================================================================
--- netinet6/in6_ifattach.c	(revision 194846)
+++ netinet6/in6_ifattach.c	(working copy)
@@ -784,7 +784,7 @@
 {
 	INIT_VNET_INET(ifp->if_vnet);
 	INIT_VNET_INET6(ifp->if_vnet);
-	struct in6_ifaddr *ia, *oia;
+	struct in6_ifaddr *ia;
 	struct ifaddr *ifa, *next;
 	struct radix_node_head *rnh;
 	struct rtentry *rt;
@@ -832,27 +832,12 @@
 
 		/* remove from the linked list */
 		IF_ADDR_LOCK(ifp);
-		TAILQ_REMOVE(&ifp->if_addrhead, (struct ifaddr *)ia, ifa_link);
+		TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link);
 		IF_ADDR_UNLOCK(ifp);
-		ifa_free(&ia->ia_ifa);
+		ifa_free(ifa);				/* if_addrhead */
 
-		/* also remove from the IPv6 address chain(itojun&jinmei) */
-		oia = ia;
-		if (oia == (ia = V_in6_ifaddr))
-			V_in6_ifaddr = ia->ia_next;
-		else {
-			while (ia->ia_next && (ia->ia_next != oia))
-				ia = ia->ia_next;
-			if (ia->ia_next)
-				ia->ia_next = oia->ia_next;
-			else {
-				nd6log((LOG_ERR,
-				    "%s: didn't unlink in6ifaddr from list\n",
-				    if_name(ifp)));
-			}
-		}
-
-		ifa_free(&oia->ia_ifa);
+		TAILQ_REMOVE(&V_in6_ifaddrhead, ia, ia_link);
+		ifa_free(ifa);
 	}
 
 	in6_pcbpurgeif0(&V_udbinfo, ifp);
Index: netinet6/in6_var.h
===================================================================
--- netinet6/in6_var.h	(revision 194846)
+++ netinet6/in6_var.h	(working copy)
@@ -117,7 +117,7 @@
 	struct	sockaddr_in6 ia_dstaddr; /* space for destination addr */
 	struct	sockaddr_in6 ia_prefixmask; /* prefix mask */
 	u_int32_t ia_plen;		/* prefix length */
-	struct	in6_ifaddr *ia_next;	/* next in6 list of IP6 addresses */
+	TAILQ_ENTRY(in6_ifaddr)	ia_link;	/* list of IPv6 addresses */
 	int	ia6_flags;
 
 	struct in6_addrlifetime ia6_lifetime;
@@ -133,6 +133,9 @@
 	LIST_HEAD(, in6_multi_mship) ia6_memberships;
 };
 
+/* List of in6_ifaddr's. */
+TAILQ_HEAD(in6_ifaddrhead, in6_ifaddr);
+
 /* control structure to manage address selection policy */
 struct in6_addrpolicy {
 	struct sockaddr_in6 addr; /* prefix address */
Index: netinet6/nd6.c
===================================================================
--- netinet6/nd6.c	(revision 194846)
+++ netinet6/nd6.c	(working copy)
@@ -626,8 +626,7 @@
 	 * rather separate address lifetimes and prefix lifetimes.
 	 */
   addrloop:
-	for (ia6 = V_in6_ifaddr; ia6; ia6 = nia6) {
-		nia6 = ia6->ia_next;
+	TAILQ_FOREACH_SAFE(ia6, &V_in6_ifaddrhead, ia_link, nia6) {
 		/* check address lifetime */
 		lt6 = &ia6->ia6_lifetime;
 		if (IFA6_IS_INVALID(ia6)) {
@@ -1329,10 +1328,8 @@
 				continue; /* XXX */
 
 			/* do we really have to remove addresses as well? */
-			for (ia = V_in6_ifaddr; ia; ia = ia_next) {
-				/* ia might be removed.  keep the next ptr. */
-				ia_next = ia->ia_next;
-
+			TAILQ_FOREACH_SAFE(ia, &V_in6_ifaddrhead, ia_link,
+			    ia_next) {
 				if ((ia->ia6_flags & IN6_IFF_AUTOCONF) == 0)
 					continue;
 
Index: netinet6/in6.c
===================================================================
--- netinet6/in6.c	(revision 194846)
+++ netinet6/in6.c	(working copy)
@@ -684,7 +684,6 @@
 {
 	INIT_VNET_INET6(ifp->if_vnet);
 	int error = 0, hostIsNew = 0, plen = -1;
-	struct in6_ifaddr *oia;
 	struct sockaddr_in6 dst6;
 	struct in6_addrlifetime *lt;
 	struct in6_multi_mship *imm;
@@ -826,19 +825,13 @@
 			ia->ia_ifa.ifa_dstaddr = NULL;
 		}
 		ia->ia_ifa.ifa_netmask = (struct sockaddr *)&ia->ia_prefixmask;
-
 		ia->ia_ifp = ifp;
-		if ((oia = V_in6_ifaddr) != NULL) {
-			for ( ; oia->ia_next; oia = oia->ia_next)
-				continue;
-			oia->ia_next = ia;
-		} else
-			V_in6_ifaddr = ia;
-
 		ifa_ref(&ia->ia_ifa);			/* if_addrhead */
 		IF_ADDR_LOCK(ifp);
 		TAILQ_INSERT_TAIL(&ifp->if_addrhead, &ia->ia_ifa, ifa_link);
 		IF_ADDR_UNLOCK(ifp);
+
+		TAILQ_INSERT_TAIL(&V_in6_ifaddrhead, ia, ia_link);
 	}
 
 	/* update timestamp */
@@ -1375,7 +1368,6 @@
 in6_unlink_ifa(struct in6_ifaddr *ia, struct ifnet *ifp)
 {
 	INIT_VNET_INET6(ifp->if_vnet);
-	struct in6_ifaddr *oia;
 	int	s = splnet();
 
 	IF_ADDR_LOCK(ifp);
@@ -1383,31 +1375,19 @@
 	IF_ADDR_UNLOCK(ifp);
 	ifa_free(&ia->ia_ifa);			/* if_addrhead */
 
-	oia = ia;
-	if (oia == (ia = V_in6_ifaddr))
-		V_in6_ifaddr = ia->ia_next;
-	else {
-		while (ia->ia_next && (ia->ia_next != oia))
-			ia = ia->ia_next;
-		if (ia->ia_next)
-			ia->ia_next = oia->ia_next;
-		else {
-			/* search failed */
-			printf("Couldn't unlink in6_ifaddr from in6_ifaddr\n");
-		}
-	}
+	TAILQ_REMOVE(&V_in6_ifaddrhead, ia, ia_link);
 
 	/*
 	 * Release the reference to the base prefix.  There should be a
 	 * positive reference.
 	 */
-	if (oia->ia6_ndpr == NULL) {
+	if (ia->ia6_ndpr == NULL) {
 		nd6log((LOG_NOTICE,
 		    "in6_unlink_ifa: autoconf'ed address "
-		    "%p has no prefix\n", oia));
+		    "%p has no prefix\n", ia));
 	} else {
-		oia->ia6_ndpr->ndpr_refcnt--;
-		oia->ia6_ndpr = NULL;
+		ia->ia6_ndpr->ndpr_refcnt--;
+		ia->ia6_ndpr = NULL;
 	}
 
 	/*
@@ -1415,7 +1395,7 @@
 	 * pfxlist_onlink_check() since the release might affect the status of
 	 * other (detached) addresses.
 	 */
-	if ((oia->ia6_flags & IN6_IFF_AUTOCONF)) {
+	if ((ia->ia6_flags & IN6_IFF_AUTOCONF)) {
 		pfxlist_onlink_check();
 	}
 
@@ -1423,7 +1403,7 @@
 	 * release another refcnt for the link from in6_ifaddr.
 	 * Note that we should decrement the refcnt at least once for all *BSD.
 	 */
-	ifa_free(&oia->ia_ifa);
+	ifa_free(&ia->ia_ifa);
 
 	splx(s);
 }
@@ -1941,7 +1921,7 @@
 	if (IN6_IS_ADDR_LOOPBACK(in6) || IN6_IS_ADDR_LINKLOCAL(in6))
 		return 1;
 
-	for (ia = V_in6_ifaddr; ia; ia = ia->ia_next) {
+	TAILQ_FOREACH(ia, &V_in6_ifaddrhead, ia_link) {
 		if (IN6_ARE_MASKED_ADDR_EQUAL(in6, &ia->ia_addr.sin6_addr,
 		    &ia->ia_prefixmask.sin6_addr)) {
 			return 1;
@@ -1957,7 +1937,7 @@
 	INIT_VNET_INET6(curvnet);
 	struct in6_ifaddr *ia;
 
-	for (ia = V_in6_ifaddr; ia; ia = ia->ia_next) {
+	TAILQ_FOREACH(ia, &V_in6_ifaddrhead, ia_link) {
 		if (IN6_ARE_ADDR_EQUAL(&ia->ia_addr.sin6_addr,
 				       &sa6->sin6_addr) &&
 		    (ia->ia6_flags & IN6_IFF_DEPRECATED) != 0)
Index: netinet6/in6_src.c
===================================================================
--- netinet6/in6_src.c	(revision 194846)
+++ netinet6/in6_src.c	(working copy)
@@ -289,7 +289,7 @@
 	if (error)
 		return (error);
 
-	for (ia = V_in6_ifaddr; ia; ia = ia->ia_next) {
+	TAILQ_FOREACH(ia, &V_in6_ifaddrhead, ia_link) {
 		int new_scope = -1, new_matchlen = -1;
 		struct in6_addrpolicy *new_policy = NULL;
 		u_int32_t srczone, osrczone, dstzone;
Index: netinet6/ip6_input.c
===================================================================
--- netinet6/ip6_input.c	(revision 194846)
+++ netinet6/ip6_input.c	(working copy)
@@ -134,7 +134,7 @@
 #endif
 
 #ifdef VIMAGE_GLOBALS
-struct in6_ifaddr *in6_ifaddr;
+struct in6_ifaddrhead in6_ifaddrhead;
 struct ip6stat ip6stat;
 
 extern struct callout in6_tmpaddrtimer_ch;
@@ -257,6 +257,8 @@
 					/* 40 1K datagrams */
 	V_dad_init = 0;
 
+	TAILQ_INIT(&V_in6_ifaddrhead);
+
 	scope6_init();
 	addrsel_policy_init();
 	nd6_init();
Index: netinet6/nd6_rtr.c
===================================================================
--- netinet6/nd6_rtr.c	(revision 194846)
+++ netinet6/nd6_rtr.c	(working copy)
@@ -1501,7 +1501,7 @@
 	 * always be attached.
 	 * The precise detection logic is same as the one for prefixes.
 	 */
-	for (ifa = V_in6_ifaddr; ifa; ifa = ifa->ia_next) {
+	TAILQ_FOREACH(ifa, &V_in6_ifaddrhead, ia_link) {
 		if (!(ifa->ia6_flags & IN6_IFF_AUTOCONF))
 			continue;
 
@@ -1518,7 +1518,7 @@
 			break;
 	}
 	if (ifa) {
-		for (ifa = V_in6_ifaddr; ifa; ifa = ifa->ia_next) {
+		TAILQ_FOREACH(ifa, &V_in6_ifaddrhead, ia_link) {
 			if ((ifa->ia6_flags & IN6_IFF_AUTOCONF) == 0)
 				continue;
 
@@ -1537,7 +1537,7 @@
 		}
 	}
 	else {
-		for (ifa = V_in6_ifaddr; ifa; ifa = ifa->ia_next) {
+		TAILQ_FOREACH(ifa, &V_in6_ifaddrhead, ia_link) {
 			if ((ifa->ia6_flags & IN6_IFF_AUTOCONF) == 0)
 				continue;
 
@@ -1949,7 +1949,7 @@
 	 * there may be a time lag between generation of the ID and generation
 	 * of the address.  So, we'll do one more sanity check.
 	 */
-	for (ia = V_in6_ifaddr; ia; ia = ia->ia_next) {
+	TAILQ_FOREACH(ia, &V_in6_ifaddrhead, ia_link) {
 		if (IN6_ARE_ADDR_EQUAL(&ia->ia_addr.sin6_addr,
 		    &ifra.ifra_addr.sin6_addr)) {
 			if (trylimit-- == 0) {
Index: netinet6/in6_pcb.c
===================================================================
--- netinet6/in6_pcb.c	(revision 194846)
+++ netinet6/in6_pcb.c	(working copy)
@@ -123,7 +123,7 @@
 	INP_INFO_WLOCK_ASSERT(pcbinfo);
 	INP_WLOCK_ASSERT(inp);
 
-	if (!V_in6_ifaddr) /* XXX broken! */
+	if (TAILQ_EMPTY(&V_in6_ifaddrhead))	/* XXX broken! */
 		return (EADDRNOTAVAIL);
 	if (inp->inp_lport || !IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
 		return (EINVAL);
@@ -313,7 +313,7 @@
 	if ((error = sa6_embedscope(sin6, V_ip6_use_defzone)) != 0)
 		return(error);
 
-	if (V_in6_ifaddr) {
+	if (!TAILQ_EMPTY(&V_in6_ifaddrhead)) {
 		/*
 		 * If the destination address is UNSPECIFIED addr,
 		 * use the loopback addr, e.g ::1.
Index: netinet6/vinet6.h
===================================================================
--- netinet6/vinet6.h	(revision 194846)
+++ netinet6/vinet6.h	(working copy)
@@ -48,7 +48,7 @@
 #include <netinet6/scope6_var.h>
 
 struct vnet_inet6 {
-	struct in6_ifaddr *	_in6_ifaddr;
+	struct in6_ifaddrhead	_in6_ifaddrhead;
 
 	u_int			_frag6_nfragpackets;
 	u_int			_frag6_nfrags;
@@ -189,7 +189,7 @@
 #define	V_icmp6errppslim		VNET_INET6(icmp6errppslim)
 #define	V_icmp6errppslim_last		VNET_INET6(icmp6errppslim_last)
 #define	V_icmp6stat			VNET_INET6(icmp6stat)
-#define	V_in6_ifaddr			VNET_INET6(in6_ifaddr)
+#define	V_in6_ifaddrhead		VNET_INET6(in6_ifaddrhead)
 #define	V_in6_maxmtu			VNET_INET6(in6_maxmtu)
 #define	V_in6_tmpaddrtimer_ch		VNET_INET6(in6_tmpaddrtimer_ch)
 #define	V_interface_timers_running6	\
Index: netipsec/key.c
===================================================================
--- netipsec/key.c	(revision 194846)
+++ netipsec/key.c	(working copy)
@@ -3979,7 +3979,7 @@
 	struct in6_multi *in6m;
 #endif
 
-	for (ia = V_in6_ifaddr; ia; ia = ia->ia_next) {
+	TAILQ_FOREACH(ia, &V_in6_ifaddrhead, ia_link) {
 		if (key_sockaddrcmp((struct sockaddr *)&sin6,
 		    (struct sockaddr *)&ia->ia_addr, 0) == 0)
 			return 1;
