summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2009-06-24 21:00:25 +0000
committerrwatson <rwatson@FreeBSD.org>2009-06-24 21:00:25 +0000
commit9c4380a8eea873952968c44b6e2567cd55ba5011 (patch)
treed5254cdd84bc71793efc3d8e4ce92756811f0fc7 /sys
parentcb4def77ea11a26ecabee87b4221b746f96d689d (diff)
downloadFreeBSD-src-9c4380a8eea873952968c44b6e2567cd55ba5011.zip
FreeBSD-src-9c4380a8eea873952968c44b6e2567cd55ba5011.tar.gz
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?)
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/ip_carp.c2
-rw-r--r--sys/netinet6/in6.c42
-rw-r--r--sys/netinet6/in6_ifattach.c25
-rw-r--r--sys/netinet6/in6_pcb.c4
-rw-r--r--sys/netinet6/in6_src.c2
-rw-r--r--sys/netinet6/in6_var.h5
-rw-r--r--sys/netinet6/ip6_input.c4
-rw-r--r--sys/netinet6/nd6.c9
-rw-r--r--sys/netinet6/nd6_rtr.c8
-rw-r--r--sys/netinet6/vinet6.h4
-rw-r--r--sys/netipsec/key.c2
11 files changed, 37 insertions, 70 deletions
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 <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 \
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;
OpenPOWER on IntegriCloud