From 9c4380a8eea873952968c44b6e2567cd55ba5011 Mon Sep 17 00:00:00 2001 From: rwatson Date: Wed, 24 Jun 2009 21:00:25 +0000 Subject: 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?) --- sys/netinet/ip_carp.c | 2 +- sys/netinet6/in6.c | 42 +++++++++++------------------------------- sys/netinet6/in6_ifattach.c | 25 +++++-------------------- sys/netinet6/in6_pcb.c | 4 ++-- sys/netinet6/in6_src.c | 2 +- sys/netinet6/in6_var.h | 5 ++++- sys/netinet6/ip6_input.c | 4 +++- sys/netinet6/nd6.c | 9 +++------ sys/netinet6/nd6_rtr.c | 8 ++++---- sys/netinet6/vinet6.h | 4 ++-- sys/netipsec/key.c | 2 +- 11 files changed, 37 insertions(+), 70 deletions(-) (limited to 'sys') diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c index fcfe28a..44845b5 100644 --- a/sys/netinet/ip_carp.c +++ b/sys/netinet/ip_carp.c @@ -1667,7 +1667,7 @@ carp_set_addr6(struct carp_softc *sc, struct sockaddr_in6 *sin6) /* 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++) { diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index 243fd21..9ad447e 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -684,7 +684,6 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, { 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 in6_aliasreq *ifra, 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, struct ifnet *ifp) 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, struct ifnet *ifp) * 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, struct ifnet *ifp) * 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_in6 *sa6) 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) diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c index ebfdf6e..3069c46 100644 --- a/sys/netinet6/in6_ifattach.c +++ b/sys/netinet6/in6_ifattach.c @@ -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); - - /* 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(ifa); /* if_addrhead */ - ifa_free(&oia->ia_ifa); + TAILQ_REMOVE(&V_in6_ifaddrhead, ia, ia_link); + ifa_free(ifa); } in6_pcbpurgeif0(&V_udbinfo, ifp); diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index d0fb235..9df8c33 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -123,7 +123,7 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam, 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, struct sockaddr *nam, 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. diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c index 364b262..b38fbc7 100644 --- a/sys/netinet6/in6_src.c +++ b/sys/netinet6/in6_src.c @@ -289,7 +289,7 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, 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; diff --git a/sys/netinet6/in6_var.h b/sys/netinet6/in6_var.h index 37c3c6a..4ed407b 100644 --- a/sys/netinet6/in6_var.h +++ b/sys/netinet6/in6_var.h @@ -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 */ diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index 53cfdf8..47f83e2 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -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(); diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index e5fa6ae2..8cfb135 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -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, struct ifnet *ifp) 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; diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c index 6b76e30..c5021f6 100644 --- a/sys/netinet6/nd6_rtr.c +++ b/sys/netinet6/nd6_rtr.c @@ -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 *ia0, int forcegen, int delay) * 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) { diff --git a/sys/netinet6/vinet6.h b/sys/netinet6/vinet6.h index f0ea4b9..2b0344f 100644 --- a/sys/netinet6/vinet6.h +++ b/sys/netinet6/vinet6.h @@ -48,7 +48,7 @@ #include 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 \ diff --git a/sys/netipsec/key.c b/sys/netipsec/key.c index 027d408..0ab2eb0 100644 --- a/sys/netipsec/key.c +++ b/sys/netipsec/key.c @@ -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; -- cgit v1.1