Author: rwatson
Date: Wed Jun 24 21:00:25 2009
New Revision: 194907
URL: http://svn.freebsd.org/changeset/base/194907

Log:
  Convert netinet6 to using queue(9) rather than hand-crafted linked lists
  for the global IPv6 address list (in6_ifaddr -> in6_ifaddrhead).  Adopt
  the code styles and conventions present in netinet where possible.
  
  Reviewed by:  gnn, bz
  MFC after:    6 weeks (possibly not MFCable?)

Modified:
  head/sys/netinet/ip_carp.c
  head/sys/netinet6/in6.c
  head/sys/netinet6/in6_ifattach.c
  head/sys/netinet6/in6_pcb.c
  head/sys/netinet6/in6_src.c
  head/sys/netinet6/in6_var.h
  head/sys/netinet6/ip6_input.c
  head/sys/netinet6/nd6.c
  head/sys/netinet6/nd6_rtr.c
  head/sys/netinet6/vinet6.h
  head/sys/netipsec/key.c

Modified: head/sys/netinet/ip_carp.c
==============================================================================
--- head/sys/netinet/ip_carp.c  Wed Jun 24 21:00:13 2009        (r194906)
+++ head/sys/netinet/ip_carp.c  Wed Jun 24 21:00:25 2009        (r194907)
@@ -1667,7 +1667,7 @@ carp_set_addr6(struct carp_softc *sc, st
 
        /* 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++) {

Modified: head/sys/netinet6/in6.c
==============================================================================
--- head/sys/netinet6/in6.c     Wed Jun 24 21:00:13 2009        (r194906)
+++ head/sys/netinet6/in6.c     Wed Jun 24 21:00:25 2009        (r194907)
@@ -684,7 +684,6 @@ in6_update_ifa(struct ifnet *ifp, struct
 {
        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 @@ in6_update_ifa(struct ifnet *ifp, struct
                        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 @@ static void
 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 @@ in6_unlink_ifa(struct in6_ifaddr *ia, st
        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 @@ in6_unlink_ifa(struct in6_ifaddr *ia, st
         * 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 @@ in6_unlink_ifa(struct in6_ifaddr *ia, st
         * 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 @@ in6_localaddr(struct in6_addr *in6)
        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 @@ in6_is_addr_deprecated(struct sockaddr_i
        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)

Modified: head/sys/netinet6/in6_ifattach.c
==============================================================================
--- head/sys/netinet6/in6_ifattach.c    Wed Jun 24 21:00:13 2009        
(r194906)
+++ head/sys/netinet6/in6_ifattach.c    Wed Jun 24 21:00:25 2009        
(r194907)
@@ -784,7 +784,7 @@ in6_ifdetach(struct ifnet *ifp)
 {
        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 @@ in6_ifdetach(struct ifnet *ifp)
 
                /* 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);

Modified: head/sys/netinet6/in6_pcb.c
==============================================================================
--- head/sys/netinet6/in6_pcb.c Wed Jun 24 21:00:13 2009        (r194906)
+++ head/sys/netinet6/in6_pcb.c Wed Jun 24 21:00:25 2009        (r194907)
@@ -123,7 +123,7 @@ in6_pcbbind(register struct inpcb *inp, 
        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 @@ in6_pcbladdr(register struct inpcb *inp,
        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.

Modified: head/sys/netinet6/in6_src.c
==============================================================================
--- head/sys/netinet6/in6_src.c Wed Jun 24 21:00:13 2009        (r194906)
+++ head/sys/netinet6/in6_src.c Wed Jun 24 21:00:25 2009        (r194907)
@@ -289,7 +289,7 @@ in6_selectsrc(struct sockaddr_in6 *dstso
        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;

Modified: head/sys/netinet6/in6_var.h
==============================================================================
--- head/sys/netinet6/in6_var.h Wed Jun 24 21:00:13 2009        (r194906)
+++ head/sys/netinet6/in6_var.h Wed Jun 24 21:00:25 2009        (r194907)
@@ -117,7 +117,7 @@ struct      in6_ifaddr {
        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 @@ struct      in6_ifaddr {
        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 */

Modified: head/sys/netinet6/ip6_input.c
==============================================================================
--- head/sys/netinet6/ip6_input.c       Wed Jun 24 21:00:13 2009        
(r194906)
+++ head/sys/netinet6/ip6_input.c       Wed Jun 24 21:00:25 2009        
(r194907)
@@ -134,7 +134,7 @@ struct vnet_inet6 vnet_inet6_0;
 #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 @@ ip6_init(void)
                                        /* 40 1K datagrams */
        V_dad_init = 0;
 
+       TAILQ_INIT(&V_in6_ifaddrhead);
+
        scope6_init();
        addrsel_policy_init();
        nd6_init();

Modified: head/sys/netinet6/nd6.c
==============================================================================
--- head/sys/netinet6/nd6.c     Wed Jun 24 21:00:13 2009        (r194906)
+++ head/sys/netinet6/nd6.c     Wed Jun 24 21:00:25 2009        (r194907)
@@ -626,8 +626,7 @@ nd6_timer(void *arg)
         * 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 @@ nd6_ioctl(u_long cmd, caddr_t data, stru
                                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;
 

Modified: head/sys/netinet6/nd6_rtr.c
==============================================================================
--- head/sys/netinet6/nd6_rtr.c Wed Jun 24 21:00:13 2009        (r194906)
+++ head/sys/netinet6/nd6_rtr.c Wed Jun 24 21:00:25 2009        (r194907)
@@ -1501,7 +1501,7 @@ pfxlist_onlink_check()
         * 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 @@ pfxlist_onlink_check()
                        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 @@ pfxlist_onlink_check()
                }
        }
        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 @@ in6_tmpifadd(const struct in6_ifaddr *ia
         * 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) {

Modified: head/sys/netinet6/vinet6.h
==============================================================================
--- head/sys/netinet6/vinet6.h  Wed Jun 24 21:00:13 2009        (r194906)
+++ head/sys/netinet6/vinet6.h  Wed Jun 24 21:00:25 2009        (r194907)
@@ -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 @@ extern struct vnet_inet6 vnet_inet6_0;
 #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     \

Modified: head/sys/netipsec/key.c
==============================================================================
--- head/sys/netipsec/key.c     Wed Jun 24 21:00:13 2009        (r194906)
+++ head/sys/netipsec/key.c     Wed Jun 24 21:00:25 2009        (r194907)
@@ -3979,7 +3979,7 @@ key_ismyaddr6(sin6)
        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;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to