Parallelize ifnet.if_addrhead accessing by duplicating the list itself
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Fri, 7 Mar 2008 11:34:21 +0000 (11:34 +0000)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Fri, 7 Mar 2008 11:34:21 +0000 (11:34 +0000)
on each CPU, each list element points to ifaddr:
- Add SI_SUB_PRE_DRIVERS before SI_SUB_DRIVERS, so action could be taken
  before drivers' initialization (mainly before NIC driver's if_attach())
- Move netisr_init() to the FIRST of SI_SUB_PRE_DRIVERS, so that
  netmsg_service_port_init() could be called in earlier stage of system
  initialization.
- Create one thread on each CPU to propagate changes to ifnet.if_addrhead.
  Their thread ports are registered with netmsg_service_port_init() for
  port syncing operation.
- Change to ifnet.if_addrhead begins in netisr0, i.e. serial of changes
  to ifnet.if_addrhead are serialized by netisr0
- ifaddr's refcnt is moved to its list elements, i.e. per-CPU refcnt.
  They are initialized to 1 instead of 0.
- A magic field is added to ifaddr list element to make sure that IFAREF
  and IFAFREE are called on valid ifaddr list element.  This field is
  initialized to a magic value and is wiped out once the list element's
  refcnt drops to 0
- To close the gap between testing and freeing, once the ifaddr list
  element's refcnt drops to 0, ifa_portfn(0) (a thread's port on CPU0) is
  poked to check whether ifaddr is referenced on other CPUs, if not, then
  ifaddr is freed on ifa_portfn(0)

Reviewed-by: dillon@ (earlier version)
52 files changed:
sys/contrib/ipfilter/netinet/fil.c
sys/dev/netif/sr/if_sr.c
sys/emulation/linux/linux_ioctl.c
sys/net/ef/if_ef.c
sys/net/if.c
sys/net/if_atmsubr.c
sys/net/if_var.h
sys/net/ip6fw/ip6_fw.c
sys/net/ipfw/ip_fw2.c
sys/net/net_osdep.h
sys/net/netisr.c
sys/net/pf/pf_if.c
sys/net/rtsock.c
sys/net/sppp/if_spppsubr.c
sys/net/stf/if_stf.c
sys/net/tun/if_tun.c
sys/netgraph/eiface/ng_eiface.c
sys/netgraph/fec/ng_fec.c
sys/netgraph/iface/ng_iface.c
sys/netinet/if_ether.c
sys/netinet/in.c
sys/netinet/ip_carp.c
sys/netinet/ip_divert.c
sys/netinet/ip_icmp.c
sys/netinet/ip_input.c
sys/netinet/sctp_asconf.c
sys/netinet/sctp_output.c
sys/netinet/sctp_pcb.c
sys/netinet/sctp_usrreq.c
sys/netinet/sctputil.c
sys/netinet6/icmp6.c
sys/netinet6/in6.c
sys/netinet6/in6_ifattach.c
sys/netinet6/in6_prefix.c
sys/netinet6/in6_var.h
sys/netinet6/nd6.c
sys/netinet6/nd6_nbr.c
sys/netinet6/nd6_rtr.c
sys/netproto/atalk/aarp.c
sys/netproto/atalk/at_control.c
sys/netproto/atm/atm_if.c
sys/netproto/ipx/ipx.c
sys/netproto/ipx/ipx_input.c
sys/netproto/ipx/ipx_usrreq.c
sys/netproto/ns/idp_usrreq.c
sys/netproto/ns/ns.c
sys/netproto/ns/ns_input.c
sys/platform/pc32/i386/autoconf.c
sys/sys/kernel.h
sys/vfs/nfs/bootp_subr.c
usr.bin/netstat/if.c
usr.sbin/ifmcstat/ifmcstat.c

index 3c7d2e2..0d7373b 100644 (file)
@@ -5,7 +5,7 @@
  *
  * @(#)fil.c        1.36 6/5/96 (C) 1993-2000 Darren Reed
  * $FreeBSD: src/sys/contrib/ipfilter/netinet/fil.c,v 1.23.2.7 2004/07/04 09:24:38 darrenr Exp $
- * $DragonFly: src/sys/contrib/ipfilter/netinet/fil.c,v 1.10 2006/12/23 00:27:02 swildner Exp $
+ * $DragonFly: src/sys/contrib/ipfilter/netinet/fil.c,v 1.11 2008/03/07 11:34:19 sephe Exp $
  */
 #if defined(__sgi) && (IRIX > 602)
 # include <sys/ptimers.h>
@@ -2031,8 +2031,17 @@ struct in_addr *inp;
 #  else /* linux */
        struct sockaddr_in *sin;
        struct ifaddr *ifa;
+#ifdef __DragonFly__
+       struct ifaddr_container *ifac;
+#endif
 
-#   if defined(__DragonFly__) || (__FreeBSD_version >= 300000)
+#   if  defined(__DragonFly__)
+       ifac = TAILQ_FIRST(&ifp->if_addrheads[mycpuid]);
+       if (ifac != NULL)
+               ifa = ifac->ifa;
+       else
+               ifa = NULL;
+#   elif defined(__FreeBSD__) && (__FreeBSD_version >= 300000)
        ifa = TAILQ_FIRST(&ifp->if_addrhead);
 #   else
 #    if defined(__NetBSD__) || defined(__OpenBSD__)
@@ -2060,7 +2069,13 @@ struct in_addr *inp;
                                break;
                }
 #    endif
-#    if        defined(__DragonFly__) || (__FreeBSD_version >= 300000)
+#    if        defined(__DragonFly__)
+               ifac = TAILQ_NEXT(ifac, ifa_link);
+               if (ifac != NULL)
+                       ifa = ifac->ifa;
+               else
+                       ifa = NULL;
+#    elif defined(__FreeBSD__) && (__FreeBSD_version >= 300000)
                ifa = TAILQ_NEXT(ifa, ifa_link);
 #    else
 #     if defined(__NetBSD__) || defined(__OpenBSD__)
index 8860292..96ec7e5 100644 (file)
@@ -28,7 +28,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/sr/if_sr.c,v 1.48.2.1 2002/06/17 15:10:58 jhay Exp $
- * $DragonFly: src/sys/dev/netif/sr/if_sr.c,v 1.23 2008/01/06 16:55:50 swildner Exp $
+ * $DragonFly: src/sys/dev/netif/sr/if_sr.c,v 1.24 2008/03/07 11:34:19 sephe Exp $
  */
 
 /*
@@ -1018,8 +1018,8 @@ srioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cr)
        if ((cmd != SIOCSIFFLAGS) && (cmd != SIOCSIFADDR)) {
 #if BUGGY > 2
                if (bug_splats[sc->unit]++ < 2) {
-                       kprintf("sr(%d).if_addrlist = %08x\n",
-                              sc->unit, ifp->if_addrlist);
+                       kprintf("sr(%d).if_addrheads = %08x\n",
+                              sc->unit, ifp->if_addrheads);
                        kprintf("sr(%d).if_bpf = %08x\n",
                               sc->unit, ifp->if_bpf);
                        kprintf("sr(%d).if_init = %08x\n",
index 44b37d3..7846e28 100644 (file)
@@ -27,7 +27,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/compat/linux/linux_ioctl.c,v 1.55.2.11 2003/05/01 20:16:09 anholt Exp $
- * $DragonFly: src/sys/emulation/linux/linux_ioctl.c,v 1.24 2007/05/17 21:07:13 dillon Exp $
+ * $DragonFly: src/sys/emulation/linux/linux_ioctl.c,v 1.25 2008/03/07 11:34:19 sephe Exp $
  */
 
 #include <sys/param.h>
@@ -981,7 +981,6 @@ linux_ioctl_SIOCGIFCONF(struct file *fp, u_long cmd, u_long ocmd, caddr_t data,
        struct ifconf *ifc = (struct ifconf *)data;
        struct l_ifreq ifr;
        struct ifnet *ifp;
-       struct ifaddr *ifa;
        struct iovec iov;
        struct uio uio;
        int error, ethno;
@@ -1002,6 +1001,8 @@ linux_ioctl_SIOCGIFCONF(struct file *fp, u_long cmd, u_long ocmd, caddr_t data,
 
        /* Return all AF_INET addresses of all interfaces */
        TAILQ_FOREACH(ifp, &ifnet, if_link) {
+               struct ifaddr_container *ifac;
+
                if (uio.uio_resid <= 0)
                        break;
 
@@ -1013,7 +1014,8 @@ linux_ioctl_SIOCGIFCONF(struct file *fp, u_long cmd, u_long ocmd, caddr_t data,
                        strlcpy(ifr.ifr_name, ifp->if_xname, LINUX_IFNAMSIZ);
 
                /* Walk the address list */
-               TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+               TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+                       struct ifaddr *ifa = ifac->ifa;
                        struct sockaddr *sa = ifa->ifa_addr;
 
                        if (uio.uio_resid <= 0)
@@ -1077,9 +1079,9 @@ linux_ioctl_SIOGIFHWADDR(struct file *fp, u_long cmd, u_long ocmd, caddr_t data,
        struct l_ifreq *ifr = (struct l_ifreq *)data;
        struct ifnet *ifp;
        char ifname[IFNAMSIZ];
-       struct ifaddr *ifa;
        struct sockaddr_dl *sdl;
        struct l_sockaddr lsa;
+       struct ifaddr_container *ifac;
 
        ifp = ifname_linux_to_bsd(ifr->ifr_name, ifname);
        if (ifp->if_type == IFT_LOOP) {
@@ -1091,7 +1093,9 @@ linux_ioctl_SIOGIFHWADDR(struct file *fp, u_long cmd, u_long ocmd, caddr_t data,
        if (ifp->if_type != IFT_ETHER)
                return (ENOENT);
 
-       TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
+
                sdl = (struct sockaddr_dl*)ifa->ifa_addr;
                if (sdl != NULL && (sdl->sdl_family == AF_LINK) &&
                    (sdl->sdl_type == IFT_ETHER)) {
index f048182..70bde26 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/net/if_ef.c,v 1.2.2.4 2001/02/22 09:27:04 bp Exp $
- * $DragonFly: src/sys/net/ef/if_ef.c,v 1.25 2008/01/06 16:55:52 swildner Exp $
+ * $DragonFly: src/sys/net/ef/if_ef.c,v 1.26 2008/03/07 11:34:19 sephe Exp $
  */
 
 #include "opt_inet.h"
@@ -145,29 +145,13 @@ ef_attach(struct efnet *sc)
 static int
 ef_detach(struct efnet *sc)
 {
-       struct ifnet *ifp = (struct ifnet*)&sc->ef_ac.ac_if;
-
-       crit_enter();
-
-       if (ifp->if_flags & IFF_UP) {
-               if_down(ifp);
-               if (ifp->if_flags & IFF_RUNNING) {
-                   /* find internet addresses and delete routes */
-                   struct ifaddr *ifa;
-                   TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
-                           rtinit(ifa, (int)RTM_DELETE, 0);
-                   }
-               }
-       }
-
-       TAILQ_REMOVE(&ifnet, ifp, if_link);
-       crit_exit();
+       ether_ifdetach(&sc->ef_ac.ac_if);
        return 0;
 }
 
 static void
-ef_init(void *foo) {
-       return;
+ef_init(void *foo __unused)
+{
 }
 
 static int
index d830ddf..af1d438 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)if.c        8.3 (Berkeley) 1/4/94
  * $FreeBSD: src/sys/net/if.c,v 1.185 2004/03/13 02:35:03 brooks Exp $
- * $DragonFly: src/sys/net/if.c,v 1.60 2008/01/11 11:59:40 sephe Exp $
+ * $DragonFly: src/sys/net/if.c,v 1.61 2008/03/07 11:34:19 sephe Exp $
  */
 
 #include "opt_compat.h"
@@ -58,6 +58,7 @@
 #include <sys/thread.h>
 #include <sys/thread2.h>
 #include <sys/serialize.h>
+#include <sys/msgport2.h>
 
 #include <net/if.h>
 #include <net/if_arp.h>
 #include <net/radix.h>
 #include <net/route.h>
 #include <net/if_clone.h>
+#include <net/netmsg2.h>
+
 #include <machine/stdarg.h>
+#include <machine/smp.h>
 
 #if defined(INET) || defined(INET6)
 /*XXX*/
 #include <emulation/43bsd/43bsd_socket.h>
 #endif /* COMPAT_43 */
 
+struct netmsg_ifaddr {
+       struct netmsg   netmsg;
+       struct ifaddr   *ifa;
+       struct ifnet    *ifp;
+       int             tail;
+};
+
 /*
  * Support for non-ALTQ interfaces.
  */
@@ -101,6 +112,7 @@ static void if_attachdomain(void *);
 static void    if_attachdomain1(struct ifnet *);
 static int     ifconf(u_long, caddr_t, struct ucred *);
 static void    ifinit(void *);
+static void    ifaddrinit(void *);
 static void    if_slowtimo(void *);
 static void    link_rtrequest(int, struct rtentry *, struct rt_addrinfo *);
 static int     if_rtdel(struct radix_node *, void *);
@@ -117,6 +129,8 @@ SYSCTL_NODE(_net, PF_LINK, link, CTLFLAG_RW, 0, "Link layers");
 SYSCTL_NODE(_net_link, 0, generic, CTLFLAG_RW, 0, "Generic link-management");
 
 SYSINIT(interfaces, SI_SUB_PROTO_IF, SI_ORDER_FIRST, ifinit, NULL)
+/* Must be after netisr_init */
+SYSINIT(ifaddr, SI_SUB_PRE_DRIVERS, SI_ORDER_SECOND, ifaddrinit, NULL)
 
 MALLOC_DEFINE(M_IFADDR, "ifaddr", "interface address");
 MALLOC_DEFINE(M_IFMADDR, "ether_multi", "link-level multicast address");
@@ -128,6 +142,7 @@ struct callout              if_slowtimo_timer;
 
 int                    if_index = 0;
 struct ifnet           **ifindex2ifnet = NULL;
+static struct thread   ifaddr_threads[MAXCPU];
 
 /*
  * Network interface utility routines.
@@ -169,6 +184,7 @@ if_attach(struct ifnet *ifp, lwkt_serialize_t serializer)
        struct sockaddr_dl *sdl;
        struct ifaddr *ifa;
        struct ifaltq *ifq;
+       int i;
 
        static int if_indexlim = 8;
 
@@ -191,6 +207,7 @@ if_attach(struct ifnet *ifp, lwkt_serialize_t serializer)
 
        TAILQ_INSERT_TAIL(&ifnet, ifp, if_link);
        ifp->if_index = ++if_index;
+
        /*
         * XXX -
         * The old code would work if the interface passed a pre-existing
@@ -198,7 +215,11 @@ if_attach(struct ifnet *ifp, lwkt_serialize_t serializer)
         * properly initialize the tailq, however, so we no longer allow
         * this unlikely case.
         */
-       TAILQ_INIT(&ifp->if_addrhead);
+       ifp->if_addrheads = kmalloc(ncpus * sizeof(struct ifaddrhead),
+                                   M_IFADDR, M_WAITOK | M_ZERO);
+       for (i = 0; i < ncpus; ++i)
+               TAILQ_INIT(&ifp->if_addrheads[i]);
+
        TAILQ_INIT(&ifp->if_prefixhead);
        LIST_INIT(&ifp->if_multiaddrs);
        getmicrotime(&ifp->if_lastchange);
@@ -232,7 +253,7 @@ if_attach(struct ifnet *ifp, lwkt_serialize_t serializer)
                socksize = sizeof(*sdl);
        socksize = ROUNDUP(socksize);
        ifasize = sizeof(struct ifaddr) + 2 * socksize;
-       ifa = kmalloc(ifasize, M_IFADDR, M_WAITOK | M_ZERO);
+       ifa = ifa_create(ifasize, M_WAITOK);
        sdl = (struct sockaddr_dl *)(ifa + 1);
        sdl->sdl_len = socksize;
        sdl->sdl_family = AF_LINK;
@@ -249,7 +270,7 @@ if_attach(struct ifnet *ifp, lwkt_serialize_t serializer)
        sdl->sdl_len = masklen;
        while (namelen != 0)
                sdl->sdl_data[--namelen] = 0xff;
-       TAILQ_INSERT_HEAD(&ifp->if_addrhead, ifa, ifa_link);
+       ifa_iflink(ifa, ifp, 0 /* Insert head */);
 
        EVENTHANDLER_INVOKE(ifnet_attach_event, ifp);
 
@@ -303,9 +324,12 @@ if_attachdomain1(struct ifnet *ifp)
 void
 if_purgeaddrs_nolink(struct ifnet *ifp)
 {
-       struct ifaddr *ifa, *next;
+       struct ifaddr_container *ifac, *next;
+
+       TAILQ_FOREACH_MUTABLE(ifac, &ifp->if_addrheads[mycpuid],
+                             ifa_link, next) {
+               struct ifaddr *ifa = ifac->ifa;
 
-       TAILQ_FOREACH_MUTABLE(ifa, &ifp->if_addrhead, ifa_link, next) {
                /* Leave link ifaddr as it is */
                if (ifa->ifa_addr->sa_family == AF_LINK)
                        continue;
@@ -313,6 +337,14 @@ if_purgeaddrs_nolink(struct ifnet *ifp)
                /* XXX: Ugly!! ad hoc just for INET */
                if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET) {
                        struct ifaliasreq ifr;
+#ifdef IFADDR_DEBUG_VERBOSE
+                       int i;
+
+                       kprintf("purge in4 addr %p: ", ifa);
+                       for (i = 0; i < ncpus; ++i)
+                               kprintf("%d ", ifa->ifa_containers[i].ifa_refcnt);
+                       kprintf("\n");
+#endif
 
                        bzero(&ifr, sizeof ifr);
                        ifr.ifra_addr = *ifa->ifa_addr;
@@ -325,13 +357,22 @@ if_purgeaddrs_nolink(struct ifnet *ifp)
 #endif /* INET */
 #ifdef INET6
                if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET6) {
+#ifdef IFADDR_DEBUG_VERBOSE
+                       int i;
+
+                       kprintf("purge in6 addr %p: ", ifa);
+                       for (i = 0; i < ncpus; ++i)
+                               kprintf("%d ", ifa->ifa_containers[i].ifa_refcnt);
+                       kprintf("\n");
+#endif
+
                        in6_purgeaddr(ifa);
                        /* ifp_addrhead is already updated */
                        continue;
                }
 #endif /* INET6 */
-               TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link);
-               IFAFREE(ifa);
+               ifa_ifunlink(ifa, ifp);
+               ifa_destroy(ifa);
        }
 }
 
@@ -370,16 +411,16 @@ if_detach(struct ifnet *ifp)
        ifp->if_lladdr = NULL;
 
        if_purgeaddrs_nolink(ifp);
-       if (!TAILQ_EMPTY(&ifp->if_addrhead)) {
+       if (!TAILQ_EMPTY(&ifp->if_addrheads[mycpuid])) {
                struct ifaddr *ifa;
 
-               ifa = TAILQ_FIRST(&ifp->if_addrhead);
+               ifa = TAILQ_FIRST(&ifp->if_addrheads[mycpuid])->ifa;
                KASSERT(ifa->ifa_addr->sa_family == AF_LINK,
                        ("non-link ifaddr is left on if_addrhead"));
 
-               TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link);
-               IFAFREE(ifa);
-               KASSERT(TAILQ_EMPTY(&ifp->if_addrhead),
+               ifa_ifunlink(ifa, ifp);
+               ifa_destroy(ifa);
+               KASSERT(TAILQ_EMPTY(&ifp->if_addrheads[mycpuid]),
                        ("there are still ifaddrs left on if_addrhead"));
        }
 
@@ -410,7 +451,7 @@ if_detach(struct ifnet *ifp)
        for (cpu = 0; cpu < ncpus2; cpu++) {
                lwkt_migratecpu(cpu);
                for (i = 1; i <= AF_MAX; i++) {
-                       if ((rnh = rt_tables[mycpuid][i]) == NULL)
+                       if ((rnh = rt_tables[cpu][i]) == NULL)
                                continue;
                        rnh->rnh_walktree(rnh, if_rtdel, ifp);
                }
@@ -433,6 +474,7 @@ if_detach(struct ifnet *ifp)
                if_index--;
 
        TAILQ_REMOVE(&ifnet, ifp, if_link);
+       kfree(ifp->if_addrheads, M_IFADDR);
        crit_exit();
 }
 
@@ -485,21 +527,26 @@ struct ifaddr *
 ifa_ifwithaddr(struct sockaddr *addr)
 {
        struct ifnet *ifp;
-       struct ifaddr *ifa;
 
-       TAILQ_FOREACH(ifp, &ifnet, if_link)
-           TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
-               if (ifa->ifa_addr->sa_family != addr->sa_family)
-                       continue;
-               if (sa_equal(addr, ifa->ifa_addr))
-                       return (ifa);
-               if ((ifp->if_flags & IFF_BROADCAST) && ifa->ifa_broadaddr &&
-                   /* IPv6 doesn't have broadcast */
-                   ifa->ifa_broadaddr->sa_len != 0 &&
-                   sa_equal(ifa->ifa_broadaddr, addr))
-                       return (ifa);
+       TAILQ_FOREACH(ifp, &ifnet, if_link) {
+               struct ifaddr_container *ifac;
+
+               TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+                       struct ifaddr *ifa = ifac->ifa;
+
+                       if (ifa->ifa_addr->sa_family != addr->sa_family)
+                               continue;
+                       if (sa_equal(addr, ifa->ifa_addr))
+                               return (ifa);
+                       if ((ifp->if_flags & IFF_BROADCAST) &&
+                           ifa->ifa_broadaddr &&
+                           /* IPv6 doesn't have broadcast */
+                           ifa->ifa_broadaddr->sa_len != 0 &&
+                           sa_equal(ifa->ifa_broadaddr, addr))
+                               return (ifa);
+               }
        }
-       return ((struct ifaddr *)NULL);
+       return (NULL);
 }
 /*
  * Locate the point to point interface with a given destination address.
@@ -508,18 +555,24 @@ struct ifaddr *
 ifa_ifwithdstaddr(struct sockaddr *addr)
 {
        struct ifnet *ifp;
-       struct ifaddr *ifa;
 
-       TAILQ_FOREACH(ifp, &ifnet, if_link)
-           if (ifp->if_flags & IFF_POINTOPOINT)
-               TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+       TAILQ_FOREACH(ifp, &ifnet, if_link) {
+               struct ifaddr_container *ifac;
+
+               if (!(ifp->if_flags & IFF_POINTOPOINT))
+                       continue;
+
+               TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+                       struct ifaddr *ifa = ifac->ifa;
+
                        if (ifa->ifa_addr->sa_family != addr->sa_family)
                                continue;
                        if (ifa->ifa_dstaddr &&
                            sa_equal(addr, ifa->ifa_dstaddr))
                                return (ifa);
+               }
        }
-       return ((struct ifaddr *)NULL);
+       return (NULL);
 }
 
 /*
@@ -530,8 +583,7 @@ struct ifaddr *
 ifa_ifwithnet(struct sockaddr *addr)
 {
        struct ifnet *ifp;
-       struct ifaddr *ifa;
-       struct ifaddr *ifa_maybe = (struct ifaddr *) 0;
+       struct ifaddr *ifa_maybe = NULL;
        u_int af = addr->sa_family;
        char *addr_data = addr->sa_data, *cplim;
 
@@ -540,10 +592,10 @@ ifa_ifwithnet(struct sockaddr *addr)
         * so do that if we can.
         */
        if (af == AF_LINK) {
-           struct sockaddr_dl *sdl = (struct sockaddr_dl *)addr;
+               struct sockaddr_dl *sdl = (struct sockaddr_dl *)addr;
 
-           if (sdl->sdl_index && sdl->sdl_index <= if_index)
-               return (ifindex2ifnet[sdl->sdl_index]->if_lladdr);
+               if (sdl->sdl_index && sdl->sdl_index <= if_index)
+                       return (ifindex2ifnet[sdl->sdl_index]->if_lladdr);
        }
 
        /*
@@ -551,7 +603,10 @@ ifa_ifwithnet(struct sockaddr *addr)
         * addresses in this address family.
         */
        TAILQ_FOREACH(ifp, &ifnet, if_link) {
-               TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+               struct ifaddr_container *ifac;
+
+               TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+                       struct ifaddr *ifa = ifac->ifa;
                        char *cp, *cp2, *cp3;
 
                        if (ifa->ifa_addr->sa_family != af)
@@ -622,7 +677,7 @@ next:                               continue;
 struct ifaddr *
 ifaof_ifpforaddr(struct sockaddr *addr, struct ifnet *ifp)
 {
-       struct ifaddr *ifa;
+       struct ifaddr_container *ifac;
        char *cp, *cp2, *cp3;
        char *cplim;
        struct ifaddr *ifa_maybe = 0;
@@ -630,7 +685,9 @@ ifaof_ifpforaddr(struct sockaddr *addr, struct ifnet *ifp)
 
        if (af >= AF_MAX)
                return (0);
-       TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
+
                if (ifa->ifa_addr->sa_family != af)
                        continue;
                if (ifa_maybe == 0)
@@ -693,13 +750,16 @@ link_rtrequest(int cmd, struct rtentry *rt, struct rt_addrinfo *info)
 void
 if_unroute(struct ifnet *ifp, int flag, int fam)
 {
-       struct ifaddr *ifa;
+       struct ifaddr_container *ifac;
 
        ifp->if_flags &= ~flag;
        getmicrotime(&ifp->if_lastchange);
-       TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
+       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
+
                if (fam == PF_UNSPEC || (fam == ifa->ifa_addr->sa_family))
                        pfctlinput(PRC_IFDOWN, ifa->ifa_addr);
+       }
        ifq_purge(&ifp->if_snd);
        rt_ifmsg(ifp);
 }
@@ -712,13 +772,16 @@ if_unroute(struct ifnet *ifp, int flag, int fam)
 void
 if_route(struct ifnet *ifp, int flag, int fam)
 {
-       struct ifaddr *ifa;
+       struct ifaddr_container *ifac;
 
        ifp->if_flags |= flag;
        getmicrotime(&ifp->if_lastchange);
-       TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
+       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
+
                if (fam == PF_UNSPEC || (fam == ifa->ifa_addr->sa_family))
                        pfctlinput(PRC_IFUP, ifa->ifa_addr);
+       }
        rt_ifmsg(ifp);
 #ifdef INET6
        in6_if_up(ifp);
@@ -997,7 +1060,7 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct ucred *cred)
                rt_ifannouncemsg(ifp, IFAN_DEPARTURE);
 
                strlcpy(ifp->if_xname, new_name, sizeof(ifp->if_xname));
-               ifa = TAILQ_FIRST(&ifp->if_addrhead);
+               ifa = TAILQ_FIRST(&ifp->if_addrheads[mycpuid])->ifa;
                /* XXX IFA_LOCK(ifa); */
                sdl = (struct sockaddr_dl *)ifa->ifa_addr;
                namelen = strlen(new_name);
@@ -1276,13 +1339,13 @@ ifconf(u_long cmd, caddr_t data, struct ucred *cred)
 {
        struct ifconf *ifc = (struct ifconf *)data;
        struct ifnet *ifp;
-       struct ifaddr *ifa;
        struct sockaddr *sa;
        struct ifreq ifr, *ifrp;
        int space = ifc->ifc_len, error = 0;
 
        ifrp = ifc->ifc_req;
        TAILQ_FOREACH(ifp, &ifnet, if_link) {
+               struct ifaddr_container *ifac;
                int addrs;
 
                if (space <= sizeof ifr)
@@ -1300,7 +1363,9 @@ ifconf(u_long cmd, caddr_t data, struct ucred *cred)
                }
 
                addrs = 0;
-               TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+               TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+                       struct ifaddr *ifa = ifac->ifa;
+
                        if (space <= sizeof ifr)
                                break;
                        sa = ifa->ifa_addr;
@@ -1577,7 +1642,6 @@ int
 if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len)
 {
        struct sockaddr_dl *sdl;
-       struct ifaddr *ifa;
        struct ifreq ifr;
 
        sdl = IF_LLSOCKADDR(ifp);
@@ -1602,6 +1666,8 @@ if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len)
         */
        lwkt_serialize_enter(ifp->if_serializer);
        if ((ifp->if_flags & IFF_UP) != 0) {
+               struct ifaddr_container *ifac;
+
                ifp->if_flags &= ~IFF_UP;
                ifr.ifr_flags = ifp->if_flags;
                ifr.ifr_flagshigh = ifp->if_flags >> 16;
@@ -1617,7 +1683,9 @@ if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len)
                 * Also send gratuitous ARPs to notify other nodes about
                 * the address change.
                 */
-               TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+               TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+                       struct ifaddr *ifa = ifac->ifa;
+
                        if (ifa->ifa_addr != NULL &&
                            ifa->ifa_addr->sa_family == AF_INET)
                                arp_ifinit(ifp, ifa);
@@ -1754,3 +1822,194 @@ ifq_classic_request(struct ifaltq *ifq, int req, void *arg)
        crit_exit();
        return(0);
 }
+
+void *
+ifa_create(int size, int flags)
+{
+       struct ifaddr *ifa;
+       int i;
+
+       KASSERT(size >= sizeof(*ifa), ("ifaddr size too small\n"));
+
+       ifa = kmalloc(size, M_IFADDR, flags | M_ZERO);
+       if (ifa == NULL)
+               return NULL;
+
+       ifa->ifa_containers = kmalloc(ncpus * sizeof(struct ifaddr_container),
+                                     M_IFADDR, M_WAITOK | M_ZERO);
+       ifa->ifa_cpumask = smp_active_mask;
+       for (i = 0; i < ncpus; ++i) {
+               struct ifaddr_container *ifac = &ifa->ifa_containers[i];
+
+               ifac->ifa_magic = IFA_CONTAINER_MAGIC;
+               ifac->ifa = ifa;
+               ifac->ifa_refcnt = 1;
+       }
+#ifdef IFADDR_DEBUG
+       kprintf("alloc ifa %p %d\n", ifa, size);
+#endif
+       return ifa;
+}
+
+struct ifac_free_arg {
+       struct ifaddr   *ifa;
+       int             cpuid;
+};
+
+static void
+ifac_free_dispatch(struct netmsg *nmsg)
+{
+       struct lwkt_msg *msg = &nmsg->nm_lmsg;
+       struct ifac_free_arg *arg = msg->u.ms_resultp;
+       struct ifaddr *ifa = arg->ifa;
+
+       ifa->ifa_cpumask &= ~(1 << arg->cpuid);
+       if (ifa->ifa_cpumask == 0) {
+#ifdef IFADDR_DEBUG
+               kprintf("free ifa %p\n", ifa);
+#endif
+               kfree(ifa->ifa_containers, M_IFADDR);
+               kfree(ifa, M_IFADDR);
+       }
+       lwkt_replymsg(msg, 0);
+}
+
+void
+ifac_free(struct ifaddr_container *ifac, int cpu_id)
+{
+       struct ifac_free_arg arg;
+       struct netmsg nmsg;
+       struct lwkt_msg *msg;
+
+       KKASSERT(ifac->ifa_magic == IFA_CONTAINER_MAGIC);
+       KKASSERT(ifac->ifa_refcnt == 0);
+
+       ifac->ifa_magic = IFA_CONTAINER_DEAD;
+
+       bzero(&arg, sizeof(arg));
+       arg.ifa = ifac->ifa;
+       arg.cpuid = cpu_id;
+#ifdef IFADDR_DEBUG_VERBOSE
+       kprintf("try free ifa %p cpu_id %d\n", ifac->ifa, arg.cpuid);
+#endif
+
+       netmsg_init(&nmsg, &curthread->td_msgport, 0, ifac_free_dispatch);
+       msg = &nmsg.nm_lmsg;
+       msg->u.ms_resultp = &arg;
+
+       lwkt_domsg(ifa_portfn(0), msg, 0);
+}
+
+static __inline void
+ifa_forwardmsg(struct lwkt_msg *lmsg, int next_cpu)
+{
+       if (next_cpu < ncpus)
+               lwkt_forwardmsg(ifa_portfn(next_cpu), lmsg);
+       else
+               lwkt_replymsg(lmsg, 0);
+}
+
+static void
+ifa_iflink_dispatch(struct netmsg *nmsg)
+{
+       struct netmsg_ifaddr *msg = (struct netmsg_ifaddr *)nmsg;
+       struct ifaddr *ifa = msg->ifa;
+       struct ifnet *ifp = msg->ifp;
+       int cpu = mycpuid;
+
+       crit_enter();
+       if (msg->tail) {
+               TAILQ_INSERT_TAIL(&ifp->if_addrheads[cpu],
+                                 &ifa->ifa_containers[cpu], ifa_link);
+       } else {
+               TAILQ_INSERT_HEAD(&ifp->if_addrheads[cpu],
+                                 &ifa->ifa_containers[cpu], ifa_link);
+       }
+       crit_exit();
+
+       ifa_forwardmsg(&nmsg->nm_lmsg, cpu + 1);
+}
+
+void
+ifa_iflink(struct ifaddr *ifa, struct ifnet *ifp, int tail)
+{
+       struct netmsg_ifaddr msg;
+
+       netmsg_init(&msg.netmsg, &curthread->td_msgport, 0,
+                   ifa_iflink_dispatch);
+       msg.ifa = ifa;
+       msg.ifp = ifp;
+       msg.tail = tail;
+
+       lwkt_domsg(ifa_portfn(0), &msg.netmsg.nm_lmsg, 0);
+}
+
+static void
+ifa_ifunlink_dispatch(struct netmsg *nmsg)
+{
+       struct netmsg_ifaddr *msg = (struct netmsg_ifaddr *)nmsg;
+       struct ifaddr *ifa = msg->ifa;
+       struct ifnet *ifp = msg->ifp;
+       int cpu = mycpuid;
+
+       crit_enter();
+       TAILQ_REMOVE(&ifp->if_addrheads[cpu],
+                    &ifa->ifa_containers[cpu], ifa_link);
+       crit_exit();
+
+       ifa_forwardmsg(&nmsg->nm_lmsg, cpu + 1);
+}
+
+void
+ifa_ifunlink(struct ifaddr *ifa, struct ifnet *ifp)
+{
+       struct netmsg_ifaddr msg;
+
+       netmsg_init(&msg.netmsg, &curthread->td_msgport, 0,
+                   ifa_ifunlink_dispatch);
+       msg.ifa = ifa;
+       msg.ifp = ifp;
+
+       lwkt_domsg(ifa_portfn(0), &msg.netmsg.nm_lmsg, 0);
+}
+
+static void
+ifa_destroy_dispatch(struct netmsg *nmsg)
+{
+       struct netmsg_ifaddr *msg = (struct netmsg_ifaddr *)nmsg;
+
+       IFAFREE(msg->ifa);
+       ifa_forwardmsg(&nmsg->nm_lmsg, mycpuid + 1);
+}
+
+void
+ifa_destroy(struct ifaddr *ifa)
+{
+       struct netmsg_ifaddr msg;
+
+       netmsg_init(&msg.netmsg, &curthread->td_msgport, 0,
+                   ifa_destroy_dispatch);
+       msg.ifa = ifa;
+
+       lwkt_domsg(ifa_portfn(0), &msg.netmsg.nm_lmsg, 0);
+}
+
+struct lwkt_port *
+ifa_portfn(int cpu)
+{
+       return &ifaddr_threads[cpu].td_msgport;
+}
+
+static void
+ifaddrinit(void *dummy __unused)
+{
+       int i;
+
+       for (i = 0; i < ncpus; ++i) {
+               struct thread *thr = &ifaddr_threads[i];
+
+               lwkt_create(netmsg_service_loop, NULL, NULL, thr, 0, i,
+                           "ifaddr %d", i);
+               netmsg_service_port_init(&thr->td_msgport);
+       }
+}
index a26a851..2280343 100644 (file)
@@ -32,7 +32,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/net/if_atmsubr.c,v 1.10.2.1 2001/03/06 00:29:26 obrien Exp $
- * $DragonFly: src/sys/net/if_atmsubr.c,v 1.17 2006/12/22 23:44:54 swildner Exp $
+ * $DragonFly: src/sys/net/if_atmsubr.c,v 1.18 2008/03/07 11:34:19 sephe Exp $
  */
 
 /*
@@ -305,7 +305,7 @@ atm_input(struct ifnet *ifp, struct atm_pseudohdr *ah, struct mbuf *m,
 void
 atm_ifattach(struct ifnet *ifp, lwkt_serialize_t serializer)
 {
-       struct ifaddr *ifa;
+       struct ifaddr_container *ifac;
        struct sockaddr_dl *sdl;
 
        ifp->if_type = IFT_ATM;
@@ -319,15 +319,9 @@ atm_ifattach(struct ifnet *ifp, lwkt_serialize_t serializer)
        ifq_set_maxlen(&ifp->if_snd, 50);
        if_attach(ifp, serializer);
 
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-       for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != 0;
-           ifa = TAILQ_NEXT(ifa, ifa_list))
-#elif defined(__DragonFly__) || (defined(__FreeBSD__) && (__FreeBSD__ > 2))
-       for (ifa = TAILQ_FIRST(&ifp->if_addrhead); ifa; 
-           ifa = TAILQ_NEXT(ifa, ifa_link))
-#elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__bsdi__)
-       for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) 
-#endif
+       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
+
                if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) &&
                    sdl->sdl_family == AF_LINK) {
                        sdl->sdl_type = IFT_ATM;
@@ -337,5 +331,6 @@ atm_ifattach(struct ifnet *ifp, lwkt_serialize_t serializer)
 #endif
                        break;
                }
+       }
        bpfattach(ifp, DLT_ATM_RFC1483, sizeof(struct atmllc));
 }
index 4413d7d..8415057 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     From: @(#)if.h  8.1 (Berkeley) 6/10/93
  * $FreeBSD: src/sys/net/if_var.h,v 1.18.2.16 2003/04/15 18:11:19 fjoe Exp $
- * $DragonFly: src/sys/net/if_var.h,v 1.44 2008/01/11 11:59:40 sephe Exp $
+ * $DragonFly: src/sys/net/if_var.h,v 1.45 2008/03/07 11:34:19 sephe Exp $
  */
 
 #ifndef        _NET_IF_VAR_H_
@@ -84,6 +84,9 @@ struct        ether_header;
 struct carp_if;
 struct ucred;
 struct lwkt_serialize;
+struct ifaddr_container;
+struct ifaddr;
+struct lwkt_port;
 
 #include <sys/queue.h>         /* get TAILQ macros */
 
@@ -99,7 +102,7 @@ struct       lwkt_serialize;
 #define IF_DUNIT_NONE   -1
 
 TAILQ_HEAD(ifnethead, ifnet);  /* we use TAILQs so that the order of */
-TAILQ_HEAD(ifaddrhead, ifaddr);        /* instantiation is preserved in the list */
+TAILQ_HEAD(ifaddrhead, ifaddr_container); /* instantiation is preserved in the list */
 TAILQ_HEAD(ifprefixhead, ifprefix);
 LIST_HEAD(ifmultihead, ifmultiaddr);
 
@@ -177,7 +180,8 @@ struct ifnet {
        char    if_xname[IFNAMSIZ];     /* external name (name + unit) */
        const char *if_dname;           /* driver name */
        int     if_dunit;               /* unit or IF_DUNIT_NONE */
-       struct  ifaddrhead if_addrhead; /* linked list of addresses per if */
+       void    *if_addrhead_pad;
+       struct  ifaddrhead *if_addrheads;       /* linked list of addresses per if */
        int     if_pcount;              /* number of promiscuous listeners */
        struct  carp_if *if_carp;       /* carp interface structure */
        struct  bpf_if *if_bpf;         /* packet filter structure */
@@ -253,9 +257,9 @@ typedef void if_init_f_t (void *);
 #define if_rawoutput(if, m, sa) if_output(if, m, sa, (struct rtentry *)0)
 
 /* for compatibility with other BSDs */
-#define        if_addrlist     if_addrhead
 #define        if_list         if_link
 
+
 /*
  * Output queues (ifp->if_snd) and slow device input queues (*ifp->if_slowq)
  * are queues of messages stored on ifqueue structures
@@ -351,6 +355,15 @@ if_handoff(struct ifqueue *_ifq, struct mbuf *_m, struct ifnet *_ifp,
 
 #endif /* _KERNEL */
 
+struct ifaddr_container {
+#define IFA_CONTAINER_MAGIC    0x19810219
+#define IFA_CONTAINER_DEAD     0xc0dedead
+       uint32_t                ifa_magic;  /* IFA_CONTAINER_MAGIC */
+       struct ifaddr           *ifa;
+       TAILQ_ENTRY(ifaddr_container)   ifa_link;   /* queue macro glue */
+       u_int                   ifa_refcnt; /* references to this structure */
+};
+
 /*
  * The ifaddr structure contains information about one address
  * of an interface.  They are maintained by the different address families,
@@ -364,11 +377,12 @@ struct ifaddr {
        struct  sockaddr *ifa_netmask;  /* used to determine subnet */
        struct  if_data if_data;        /* not all members are meaningful */
        struct  ifnet *ifa_ifp;         /* back-pointer to interface */
-       TAILQ_ENTRY(ifaddr) ifa_link;   /* queue macro glue */
+       void    *ifa_link_pad;
+       struct ifaddr_container *ifa_containers;
        void    (*ifa_rtrequest)        /* check or clean routes (+ or -)'d */
                (int, struct rtentry *, struct rt_addrinfo *);
        u_short ifa_flags;              /* mostly rt_flags for cloning */
-       u_int   ifa_refcnt;             /* references to this structure */
+       cpumask_t ifa_cpumask;
        int     ifa_metric;             /* cost of going out this interface */
 #ifdef notdef
        struct  rtentry *ifa_rt;        /* XXXX for ROUTETOIF ????? */
@@ -422,10 +436,21 @@ EVENTHANDLER_DECLARE(ifnet_attach_event, ifnet_attach_event_handler_t);
 typedef void (*ifnet_detach_event_handler_t)(void *, struct ifnet *);
 EVENTHANDLER_DECLARE(ifnet_detach_event, ifnet_detach_event_handler_t);
 
+static __inline void
+_IFAREF(struct ifaddr *_ifa, int _cpu_id)
+{
+       struct ifaddr_container *_ifac = &_ifa->ifa_containers[_cpu_id];
+
+       crit_enter();
+       KKASSERT(_ifac->ifa_magic == IFA_CONTAINER_MAGIC);
+       ++_ifac->ifa_refcnt;
+       crit_exit();
+}
+
 static __inline void
 IFAREF(struct ifaddr *_ifa)
 {
-       ++_ifa->ifa_refcnt;
+       _IFAREF(_ifa, mycpuid);
 }
 
 #include <sys/malloc.h>
@@ -433,13 +458,25 @@ IFAREF(struct ifaddr *_ifa)
 MALLOC_DECLARE(M_IFADDR);
 MALLOC_DECLARE(M_IFMADDR);
 
+void   ifac_free(struct ifaddr_container *, int);
+
+static __inline void
+_IFAFREE(struct ifaddr *_ifa, int _cpu_id)
+{
+       struct ifaddr_container *_ifac = &_ifa->ifa_containers[_cpu_id];
+
+       crit_enter();
+       KKASSERT(_ifac->ifa_magic == IFA_CONTAINER_MAGIC);
+       KKASSERT(_ifac->ifa_refcnt > 0);
+       if (--_ifac->ifa_refcnt == 0)
+               ifac_free(_ifac, _cpu_id);
+       crit_exit();
+}
+
 static __inline void
 IFAFREE(struct ifaddr *_ifa)
 {
-       if (_ifa->ifa_refcnt <= 0)
-               kfree(_ifa, M_IFADDR);
-       else
-               _ifa->ifa_refcnt--;
+       _IFAFREE(_ifa, mycpuid);
 }
 
 extern struct ifnethead ifnet;
@@ -486,6 +523,12 @@ struct     ifaddr *ifa_ifwithnet(struct sockaddr *);
 struct ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *);
 struct ifaddr *ifaof_ifpforaddr(struct sockaddr *, struct ifnet *);
 
+void   *ifa_create(int, int);
+void   ifa_destroy(struct ifaddr *);
+void   ifa_iflink(struct ifaddr *, struct ifnet *, int);
+void   ifa_ifunlink(struct ifaddr *, struct ifnet *);
+struct lwkt_port *ifa_portfn(int);
+
 struct ifmultiaddr *ifmaof_ifpforaddr(struct sockaddr *, struct ifnet *);
 int    if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen);
 
index 8cbc83e..ca8b94e 100644 (file)
@@ -1,5 +1,5 @@
 /*     $FreeBSD: src/sys/netinet6/ip6_fw.c,v 1.2.2.10 2003/08/03 17:52:54 ume Exp $    */
-/*     $DragonFly: src/sys/net/ip6fw/ip6_fw.c,v 1.18 2006/12/22 23:44:56 swildner Exp $        */
+/*     $DragonFly: src/sys/net/ip6fw/ip6_fw.c,v 1.19 2008/03/07 11:34:20 sephe Exp $   */
 /*     $KAME: ip6_fw.c,v 1.21 2001/01/24 01:25:32 itojun Exp $ */
 
 /*
@@ -336,9 +336,11 @@ iface_match(struct ifnet *ifp, union ip6_fw_if *ifu, int byname)
                }
                return(1);
        } else if (!IN6_IS_ADDR_UNSPECIFIED(&ifu->fu_via_ip6)) {        /* Zero == wildcard */
-               struct ifaddr *ifa;
+               struct ifaddr_container *ifac;
+
+               TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+                       struct ifaddr *ifa = ifac->ifa;
 
-               TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
                        if (ifa->ifa_addr == NULL)
                                continue;
                        if (ifa->ifa_addr->sa_family != AF_INET6)
index c0544f6..7f5f83b 100644 (file)
@@ -23,7 +23,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/netinet/ip_fw2.c,v 1.6.2.12 2003/04/08 10:42:32 maxim Exp $
- * $DragonFly: src/sys/net/ipfw/ip_fw2.c,v 1.40 2007/12/19 12:13:17 sephe Exp $
+ * $DragonFly: src/sys/net/ipfw/ip_fw2.c,v 1.41 2008/03/07 11:34:20 sephe Exp $
  */
 
 #define        DEB(x)
@@ -417,9 +417,11 @@ iface_match(struct ifnet *ifp, ipfw_insn_if *cmd)
                                return(1);
                }
        } else {
-               struct ifaddr *ia;
+               struct ifaddr_container *ifac;
+
+               TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+                       struct ifaddr *ia = ifac->ifa;
 
-               TAILQ_FOREACH(ia, &ifp->if_addrhead, ifa_link) {
                        if (ia->ifa_addr == NULL)
                                continue;
                        if (ia->ifa_addr->sa_family != AF_INET)
index fde3994..41e9534 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * $KAME: net_osdep.h,v 1.68 2001/12/21 08:14:58 itojun Exp $
  * $FreeBSD: src/sys/net/net_osdep.h,v 1.1.2.3 2002/04/28 05:40:25 suz Exp $
- * $DragonFly: src/sys/net/net_osdep.h,v 1.7 2006/05/20 02:42:08 dillon Exp $
+ * $DragonFly: src/sys/net/net_osdep.h,v 1.8 2008/03/07 11:34:19 sephe Exp $
  */
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -291,8 +291,6 @@ extern const char *if_name (struct ifnet *);
 
 #define HAVE_OLD_BPF
 
-#define ifa_list       ifa_link
-#define if_addrlist    if_addrhead
 #define if_list                if_link
 
 #define WITH_CONVERT_AND_STRIP_IP_LEN
index 359096a..66317a3 100644 (file)
@@ -35,7 +35,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/sys/net/netisr.c,v 1.36 2007/12/19 11:00:22 sephe Exp $
+ * $DragonFly: src/sys/net/netisr.c,v 1.37 2008/03/07 11:34:19 sephe Exp $
  */
 
 #include <sys/param.h>
@@ -166,7 +166,7 @@ netisr_init(void)
     lwkt_initport_putonly(&netisr_sync_port, netmsg_sync_putport);
 }
 
-SYSINIT(netisr, SI_SUB_PROTO_BEGIN, SI_ORDER_FIRST, netisr_init, NULL);
+SYSINIT(netisr, SI_SUB_PRE_DRIVERS, SI_ORDER_FIRST, netisr_init, NULL);
 
 /*
  * Finish initializing the message port for a netmsg service.  This also
index fe53830..6a3e5ec 100644 (file)
@@ -1,7 +1,7 @@
 /*     $FreeBSD: src/sys/contrib/pf/net/pf_if.c,v 1.6 2004/09/14 15:20:24 mlaier Exp $ */
 /*     $OpenBSD: pf_if.c,v 1.11 2004/03/15 11:38:23 cedric Exp $ */
 /* add $OpenBSD: pf_if.c,v 1.19 2004/08/11 12:06:44 henning Exp $ */
-/*     $DragonFly: src/sys/net/pf/pf_if.c,v 1.9 2008/01/05 14:02:38 swildner Exp $ */
+/*     $DragonFly: src/sys/net/pf/pf_if.c,v 1.10 2008/03/07 11:34:20 sephe Exp $ */
 
 /*
  * Copyright (c) 2004 The DragonFly Project.  All rights reserved.
@@ -531,13 +531,15 @@ pfi_table_update(struct pfr_ktable *kt, struct pfi_kif *kif, int net, int flags)
 void
 pfi_instance_add(struct ifnet *ifp, int net, int flags)
 {
-       struct ifaddr   *ia;
+       struct ifaddr_container *ifac;
        int              got4 = 0, got6 = 0;
        int              net2, af;
 
        if (ifp == NULL)
                return;
-       TAILQ_FOREACH(ia, &ifp->if_addrlist, ifa_list) {
+       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ia = ifac->ifa;
+
                if (ia->ifa_addr == NULL)
                        continue;
                af = ia->ifa_addr->sa_family;
index 9e9cb1b..bb574c0 100644 (file)
@@ -64,7 +64,7 @@
  *
  *     @(#)rtsock.c    8.7 (Berkeley) 10/12/95
  * $FreeBSD: src/sys/net/rtsock.c,v 1.44.2.11 2002/12/04 14:05:41 ru Exp $
- * $DragonFly: src/sys/net/rtsock.c,v 1.42 2008/01/06 16:55:51 swildner Exp $
+ * $DragonFly: src/sys/net/rtsock.c,v 1.43 2008/03/07 11:34:19 sephe Exp $
  */
 
 #include "opt_sctp.h"
@@ -405,7 +405,8 @@ fillrtmsg(struct rt_msghdr **prtm, struct rtentry *rt,
        if (rtm->rtm_addrs & (RTA_IFP | RTA_IFA)) {
                if (rt->rt_ifp != NULL) {
                        rtinfo->rti_ifpaddr =
-                           TAILQ_FIRST(&rt->rt_ifp->if_addrhead)->ifa_addr;
+                           TAILQ_FIRST(&rt->rt_ifp->if_addrheads[mycpuid])
+                           ->ifa->ifa_addr;
                        rtinfo->rti_ifaaddr = rt->rt_ifa->ifa_addr;
                        if (rt->rt_ifp->if_flags & IFF_POINTOPOINT)
                                rtinfo->rti_bcastaddr = rt->rt_ifa->ifa_dstaddr;
@@ -960,7 +961,8 @@ rt_ifamsg(int cmd, struct ifaddr *ifa)
 
        bzero(&rtinfo, sizeof(struct rt_addrinfo));
        rtinfo.rti_ifaaddr = ifa->ifa_addr;
-       rtinfo.rti_ifpaddr = TAILQ_FIRST(&ifp->if_addrhead)->ifa_addr;
+       rtinfo.rti_ifpaddr =
+               TAILQ_FIRST(&ifp->if_addrheads[mycpuid])->ifa->ifa_addr;
        rtinfo.rti_netmask = ifa->ifa_netmask;
        rtinfo.rti_bcastaddr = ifa->ifa_dstaddr;
 
@@ -992,8 +994,10 @@ rt_rtmsg(int cmd, struct rtentry *rt, struct ifnet *ifp, int error)
        rtinfo.rti_dst = dst = rt_key(rt);
        rtinfo.rti_gateway = rt->rt_gateway;
        rtinfo.rti_netmask = rt_mask(rt);
-       if (ifp != NULL)
-               rtinfo.rti_ifpaddr = TAILQ_FIRST(&ifp->if_addrhead)->ifa_addr;
+       if (ifp != NULL) {
+               rtinfo.rti_ifpaddr =
+               TAILQ_FIRST(&ifp->if_addrheads[mycpuid])->ifa->ifa_addr;
+       }
        rtinfo.rti_ifaaddr = rt->rt_ifa->ifa_addr;
 
        m = rt_msg_mbuf(cmd, &rtinfo);
@@ -1064,8 +1068,10 @@ rt_newmaddrmsg(int cmd, struct ifmultiaddr *ifma)
 
        bzero(&rtinfo, sizeof(struct rt_addrinfo));
        rtinfo.rti_ifaaddr = ifma->ifma_addr;
-       if (ifp != NULL && !TAILQ_EMPTY(&ifp->if_addrhead))
-               rtinfo.rti_ifpaddr = TAILQ_FIRST(&ifp->if_addrhead)->ifa_addr;
+       if (ifp != NULL && !TAILQ_EMPTY(&ifp->if_addrheads[mycpuid])) {
+               rtinfo.rti_ifpaddr =
+               TAILQ_FIRST(&ifp->if_addrheads[mycpuid])->ifa->ifa_addr;
+       }
        /*
         * If a link-layer address is present, present it as a ``gateway''
         * (similarly to how ARP entries, e.g., are presented).
@@ -1198,7 +1204,7 @@ sysctl_dumpentry(struct radix_node *rn, void *vw)
        rtinfo.rti_genmask = rt->rt_genmask;
        if (rt->rt_ifp != NULL) {
                rtinfo.rti_ifpaddr =
-                   TAILQ_FIRST(&rt->rt_ifp->if_addrhead)->ifa_addr;
+               TAILQ_FIRST(&rt->rt_ifp->if_addrheads[mycpuid])->ifa->ifa_addr;
                rtinfo.rti_ifaaddr = rt->rt_ifa->ifa_addr;
                if (rt->rt_ifp->if_flags & IFF_POINTOPOINT)
                        rtinfo.rti_bcastaddr = rt->rt_ifa->ifa_dstaddr;
@@ -1226,15 +1232,18 @@ static int
 sysctl_iflist(int af, struct walkarg *w)
 {
        struct ifnet *ifp;
-       struct ifaddr *ifa;
        struct rt_addrinfo rtinfo;
        int msglen, error;
 
        bzero(&rtinfo, sizeof(struct rt_addrinfo));
        TAILQ_FOREACH(ifp, &ifnet, if_link) {
+               struct ifaddr_container *ifac;
+               struct ifaddr *ifa;
+
                if (w->w_arg && w->w_arg != ifp->if_index)
                        continue;
-               ifa = TAILQ_FIRST(&ifp->if_addrhead);
+               ifac = TAILQ_FIRST(&ifp->if_addrheads[mycpuid]);
+               ifa = ifac->ifa;
                rtinfo.rti_ifpaddr = ifa->ifa_addr;
                msglen = rt_msgsize(RTM_IFINFO, &rtinfo);
                if (w->w_tmemsize < msglen && resizewalkarg(w, msglen) != 0)
@@ -1252,7 +1261,9 @@ sysctl_iflist(int af, struct walkarg *w)
                        if (error)
                                return (error);
                }
-               while ((ifa = TAILQ_NEXT(ifa, ifa_link)) != NULL) {
+               while ((ifac = TAILQ_NEXT(ifac, ifa_link)) != NULL) {
+                       ifa = ifac->ifa;
+
                        if (af && af != ifa->ifa_addr->sa_family)
                                continue;
                        if (curproc->p_ucred->cr_prison &&
index 91cb3b5..d86d8cf 100644 (file)
@@ -18,7 +18,7 @@
  * From: Version 2.4, Thu Apr 30 17:17:21 MSD 1997
  *
  * $FreeBSD: src/sys/net/if_spppsubr.c,v 1.59.2.13 2002/07/03 15:44:41 joerg Exp $
- * $DragonFly: src/sys/net/sppp/if_spppsubr.c,v 1.29 2006/12/26 11:01:07 swildner Exp $
+ * $DragonFly: src/sys/net/sppp/if_spppsubr.c,v 1.30 2008/03/07 11:34:20 sephe Exp $
  */
 
 #include <sys/param.h>
@@ -4860,6 +4860,7 @@ static void
 sppp_get_ip_addrs(struct sppp *sp, u_long *src, u_long *dst, u_long *srcmask)
 {
        struct ifnet *ifp = &sp->pp_if;
+       struct ifaddr_container *ifac;
        struct ifaddr *ifa;
        struct sockaddr_in *si, *sm;
        u_long ssrc, ddst;
@@ -4871,24 +4872,16 @@ sppp_get_ip_addrs(struct sppp *sp, u_long *src, u_long *dst, u_long *srcmask)
         * aliases don't make any sense on a p2p link anyway.
         */
        si = 0;
-#if defined(__DragonFly__)
-       TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
-#elif defined(__NetBSD__) || defined (__OpenBSD__)
-       for (ifa = ifp->if_addrlist.tqh_first;
-            ifa;
-            ifa = ifa->ifa_list.tqe_next)
-#else
-       for (ifa = ifp->if_addrlist;
-            ifa;
-            ifa = ifa->ifa_next)
-#endif
+       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+               ifa = ifac->ifa;
                if (ifa->ifa_addr->sa_family == AF_INET) {
                        si = (struct sockaddr_in *)ifa->ifa_addr;
                        sm = (struct sockaddr_in *)ifa->ifa_netmask;
                        if (si)
                                break;
                }
-       if (ifa) {
+       }
+       if (ifac != NULL) {
                if (si && si->sin_addr.s_addr) {
                        ssrc = si->sin_addr.s_addr;
                        if (srcmask)
@@ -4911,6 +4904,7 @@ static void
 sppp_set_ip_addr(struct sppp *sp, u_long src)
 {
        STDDCL;
+       struct ifaddr_container *ifac;
        struct ifaddr *ifa;
        struct sockaddr_in *si;
        struct in_ifaddr *ia;
@@ -4920,28 +4914,16 @@ sppp_set_ip_addr(struct sppp *sp, u_long src)
         * aliases don't make any sense on a p2p link anyway.
         */
        si = 0;
-#if defined(__DragonFly__) 
-       TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
-#elif defined(__NetBSD__) || defined (__OpenBSD__)
-       for (ifa = ifp->if_addrlist.tqh_first;
-            ifa;
-            ifa = ifa->ifa_list.tqe_next)
-#else
-       for (ifa = ifp->if_addrlist;
-            ifa;
-            ifa = ifa->ifa_next)
-#endif
-       {
-               if (ifa->ifa_addr->sa_family == AF_INET)
-               {
+       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+               ifa = ifac->ifa;
+               if (ifa->ifa_addr->sa_family == AF_INET) {
                        si = (struct sockaddr_in *)ifa->ifa_addr;
                        if (si)
                                break;
                }
        }
 
-       if (ifa && si)
-       {
+       if (ifac != NULL && si != NULL) {
                int error;
 #if __NetBSD_Version__ >= 103080000
                struct sockaddr_in new_sin = *si;
@@ -4988,6 +4970,7 @@ sppp_get_ip6_addrs(struct sppp *sp, struct in6_addr *src, struct in6_addr *dst,
                   struct in6_addr *srcmask)
 {
        struct ifnet *ifp = &sp->pp_if;
+       struct ifaddr_container *ifac;
        struct ifaddr *ifa;
        struct sockaddr_in6 *si, *sm;
        struct in6_addr ssrc, ddst;
@@ -4999,25 +4982,17 @@ sppp_get_ip6_addrs(struct sppp *sp, struct in6_addr *src, struct in6_addr *dst,
         * Pick the first link-local AF_INET6 address from the list,
         * aliases don't make any sense on a p2p link anyway.
         */
-#if defined(__DragonFly__)
        si = 0;
-       TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
-#elif defined(__NetBSD__) || defined (__OpenBSD__)
-       for (ifa = ifp->if_addrlist.tqh_first, si = 0;
-            ifa;
-            ifa = ifa->ifa_list.tqe_next)
-#else
-       for (ifa = ifp->if_addrlist, si = 0;
-            ifa;
-            ifa = ifa->ifa_next)
-#endif
+       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+               ifa = ifac->ifa;
                if (ifa->ifa_addr->sa_family == AF_INET6) {
                        si = (struct sockaddr_in6 *)ifa->ifa_addr;
                        sm = (struct sockaddr_in6 *)ifa->ifa_netmask;
                        if (si && IN6_IS_ADDR_LINKLOCAL(&si->sin6_addr))
                                break;
                }
-       if (ifa) {
+       }
+       if (ifac != NULL) {
                if (si && !IN6_IS_ADDR_UNSPECIFIED(&si->sin6_addr)) {
                        bcopy(&si->sin6_addr, &ssrc, sizeof(ssrc));
                        if (srcmask) {
@@ -5054,6 +5029,7 @@ static void
 sppp_set_ip6_addr(struct sppp *sp, const struct in6_addr *src)
 {
        STDDCL;
+       struct ifaddr_container *ifac;
        struct ifaddr *ifa;
        struct sockaddr_in6 *sin6;
 
@@ -5063,33 +5039,22 @@ sppp_set_ip6_addr(struct sppp *sp, const struct in6_addr *src)
         */
 
        sin6 = NULL;
-#if defined(__DragonFly__) 
-       TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
-#elif defined(__NetBSD__) || defined (__OpenBSD__)
-       for (ifa = ifp->if_addrlist.tqh_first;
-            ifa;
-            ifa = ifa->ifa_list.tqe_next)
-#else
-       for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
-#endif
-       {
-               if (ifa->ifa_addr->sa_family == AF_INET6)
-               {
+       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+               ifa = ifac->ifa;
+               if (ifa->ifa_addr->sa_family == AF_INET6) {
                        sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
                        if (sin6 && IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
                                break;
                }
        }
 
-       if (ifa && sin6)
-       {
+       if (ifac != NULL && sin6 != NULL) {
                int error;
                struct sockaddr_in6 new_sin6 = *sin6;
 
                bcopy(src, &new_sin6.sin6_addr, sizeof(new_sin6.sin6_addr));
                error = in6_ifinit(ifp, ifatoia6(ifa), &new_sin6, 1);
-               if (debug && error)
-               {
+               if (debug && error) {
                        log(LOG_DEBUG, SPP_FMT "sppp_set_ip6_addr: in6_ifinit "
                            " failed, error=%d\n", SPP_ARGS(ifp), error);
                }
index 2160885..7616811 100644 (file)
@@ -1,5 +1,5 @@
 /*     $FreeBSD: src/sys/net/if_stf.c,v 1.1.2.11 2003/01/23 21:06:44 sam Exp $ */
-/*     $DragonFly: src/sys/net/stf/if_stf.c,v 1.20 2008/01/05 14:02:38 swildner Exp $  */
+/*     $DragonFly: src/sys/net/stf/if_stf.c,v 1.21 2008/03/07 11:34:20 sephe Exp $     */
 /*     $KAME: if_stf.c,v 1.73 2001/12/03 11:08:30 keiichi Exp $        */
 
 /*
@@ -273,12 +273,14 @@ stf_encapcheck(const struct mbuf *m, int off, int proto, void *arg)
 static struct in6_ifaddr *
 stf_getsrcifa6(struct ifnet *ifp)
 {
-       struct ifaddr *ia;
+       struct ifaddr_container *ifac;
        struct in_ifaddr *ia4;
        struct sockaddr_in6 *sin6;
        struct in_addr in;
 
-       TAILQ_FOREACH(ia, &ifp->if_addrlist, ifa_list) {
+       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ia = ifac->ifa;
+
                if (ia->ifa_addr == NULL)
                        continue;
                if (ia->ifa_addr->sa_family != AF_INET6)
index eff7b02..375a34b 100644 (file)
@@ -14,7 +14,7 @@
  * operation though.
  *
  * $FreeBSD: src/sys/net/if_tun.c,v 1.74.2.8 2002/02/13 00:43:11 dillon Exp $
- * $DragonFly: src/sys/net/tun/if_tun.c,v 1.33 2008/01/06 01:51:55 swildner Exp $
+ * $DragonFly: src/sys/net/tun/if_tun.c,v 1.34 2008/03/07 11:34:20 sephe Exp $
  */
 
 #include "opt_atalk.h"
@@ -196,7 +196,7 @@ static int
 tuninit(struct ifnet *ifp)
 {
        struct tun_softc *tp = ifp->if_softc;
-       struct ifaddr *ifa;
+       struct ifaddr_container *ifac;
        int error = 0;
 
        TUNDEBUG(ifp, "tuninit\n");
@@ -204,12 +204,13 @@ tuninit(struct ifnet *ifp)
        ifp->if_flags |= IFF_UP | IFF_RUNNING;
        getmicrotime(&ifp->if_lastchange);
 
-       for (ifa = TAILQ_FIRST(&ifp->if_addrhead); ifa; 
-            ifa = TAILQ_NEXT(ifa, ifa_link)) {
-               if (ifa->ifa_addr == NULL)
+       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
+
+               if (ifa->ifa_addr == NULL) {
                        error = EFAULT;
                        /* XXX: Should maybe return straight off? */
-               else {
+               else {
 #ifdef INET
                        if (ifa->ifa_addr->sa_family == AF_INET) {
                            struct sockaddr_in *si;
index 5e57e90..4ea34ec 100644 (file)
@@ -28,7 +28,7 @@
  *
  *     $Id: ng_eiface.c,v 1.14 2000/03/15 12:28:44 vitaly Exp $
  * $FreeBSD: src/sys/netgraph/ng_eiface.c,v 1.4.2.5 2002/12/17 21:47:48 julian Exp $
- * $DragonFly: src/sys/netgraph/eiface/ng_eiface.c,v 1.16 2008/01/06 16:55:52 swildner Exp $
+ * $DragonFly: src/sys/netgraph/eiface/ng_eiface.c,v 1.17 2008/03/07 11:34:20 sephe Exp $
  */
 
 #include <sys/param.h>
@@ -344,8 +344,6 @@ ng_eiface_constructor(node_p *nodep)
        ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
        ifp->if_flags = (IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST);
 
-       TAILQ_INIT(&ifp->if_addrhead);
-
        /* Give this node name *
        bzero(ifname, sizeof(ifname));
        ksprintf(ifname, "if%s", ifp->if_xname);
@@ -431,7 +429,7 @@ ng_eiface_rcvmsg(node_p node, struct ng_mesg *msg,
 
                case NGM_EIFACE_GET_IFADDRS:
                    {
-                       struct ifaddr *ifa;
+                       struct ifaddr_container *ifac;
                        caddr_t ptr;
                        int buflen;
 
@@ -439,8 +437,9 @@ ng_eiface_rcvmsg(node_p node, struct ng_mesg *msg,
 
                        /* Determine size of response and allocate it */
                        buflen = 0;
-                       TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
-                               buflen += SA_SIZE(ifa->ifa_addr);
+                       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid],
+                                     ifa_link)
+                               buflen += SA_SIZE(ifac->ifa->ifa_addr);
                        NG_MKRESPONSE(resp, msg, buflen, M_NOWAIT);
                        if (resp == NULL) {
                                error = ENOMEM;
@@ -449,7 +448,9 @@ ng_eiface_rcvmsg(node_p node, struct ng_mesg *msg,
 
                        /* Add addresses */
                        ptr = resp->data;
-                       TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+                       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid],
+                                     ifa_link) {
+                               struct ifaddr *ifa = ifac->ifa;
                                const int len = SA_SIZE(ifa->ifa_addr);
 
                                if (buflen < len) {
index 3a3ecd0..15ce8ca 100644 (file)
@@ -33,7 +33,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/netgraph/ng_fec.c,v 1.1.2.1 2002/11/01 21:39:31 julian Exp $
- * $DragonFly: src/sys/netgraph/fec/ng_fec.c,v 1.22 2008/01/05 14:02:39 swildner Exp $
+ * $DragonFly: src/sys/netgraph/fec/ng_fec.c,v 1.23 2008/03/07 11:34:20 sephe Exp $
  */
 /*
  * Copyright (c) 1996-1999 Whistle Communications, Inc.
@@ -1092,7 +1092,6 @@ ng_fec_constructor(node_p *nodep)
        ifp->if_addrlen = 0;                    /* XXX */
        ifp->if_hdrlen = 0;                     /* XXX */
        ifp->if_baudrate = 100000000;           /* XXX */
-       TAILQ_INIT(&ifp->if_addrhead);
 
        /* Give this node the same name as the interface (if possible) */
        bzero(ifname, sizeof(ifname));
index b92dcea..8d34693 100644 (file)
@@ -37,7 +37,7 @@
  * Author: Archie Cobbs <archie@freebsd.org>
  *
  * $FreeBSD: src/sys/netgraph/ng_iface.c,v 1.7.2.5 2002/07/02 23:44:02 archie Exp $
- * $DragonFly: src/sys/netgraph/iface/ng_iface.c,v 1.14 2008/01/05 14:02:39 swildner Exp $
+ * $DragonFly: src/sys/netgraph/iface/ng_iface.c,v 1.15 2008/03/07 11:34:20 sephe Exp $
  * $Whistle: ng_iface.c,v 1.33 1999/11/01 09:24:51 julian Exp $
  */
 
@@ -580,7 +580,6 @@ ng_iface_constructor(node_p *nodep)
        ifp->if_addrlen = 0;                    /* XXX */
        ifp->if_hdrlen = 0;                     /* XXX */
        ifp->if_baudrate = 64000;               /* XXX */
-       TAILQ_INIT(&ifp->if_addrhead);
 
        /* Give this node the same name as the interface (if possible) */
        bzero(ifname, sizeof(ifname));
@@ -675,10 +674,12 @@ ng_iface_rcvmsg(node_p node, struct ng_mesg *msg,
                switch (msg->header.cmd) {
                case NGM_CISCO_GET_IPADDR:      /* we understand this too */
                    {
-                       struct ifaddr *ifa;
+                       struct ifaddr_container *ifac;
 
                        /* Return the first configured IP address */
-                       TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+                       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid],
+                                     ifa_link) {
+                               struct ifaddr *ifa = ifac->ifa;
                                struct ng_cisco_ipaddr *ips;
 
                                if (ifa->ifa_addr->sa_family != AF_INET)
@@ -697,7 +698,7 @@ ng_iface_rcvmsg(node_p node, struct ng_mesg *msg,
                        }
 
                        /* No IP addresses on this interface? */
-                       if (ifa == NULL)
+                       if (ifac == NULL)
                                error = EADDRNOTAVAIL;
                        break;
                    }
index 069c45e..94e96e1 100644 (file)
@@ -64,7 +64,7 @@
  *
  *     @(#)if_ether.c  8.1 (Berkeley) 6/10/93
  * $FreeBSD: src/sys/netinet/if_ether.c,v 1.64.2.23 2003/04/11 07:23:15 fjoe Exp $
- * $DragonFly: src/sys/netinet/if_ether.c,v 1.44 2008/02/11 16:42:39 nant Exp $
+ * $DragonFly: src/sys/netinet/if_ether.c,v 1.45 2008/03/07 11:34:20 sephe Exp $
  */
 
 /*
@@ -665,7 +665,7 @@ in_arpinput(struct mbuf *m)
        struct ifnet *ifp = m->m_pkthdr.rcvif;
        struct ether_header *eh;
        struct rtentry *rt;
-       struct ifaddr *ifa;
+       struct ifaddr_container *ifac;
        struct in_ifaddr *ia;
        struct sockaddr sa;
        struct in_addr isaddr, itaddr, myaddr;
@@ -737,7 +737,9 @@ in_arpinput(struct mbuf *m)
         * No match, use the first inet address on the receive interface
         * as a dummy address for the rest of the function.
         */
-       TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
+
                if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET) {
                        ia = ifatoia(ifa);
                        goto match;
index 4ea01b4..deb699d 100644 (file)
  *
  *     @(#)in.c        8.4 (Berkeley) 1/9/95
  * $FreeBSD: src/sys/netinet/in.c,v 1.44.2.14 2002/11/08 00:45:50 suz Exp $
- * $DragonFly: src/sys/netinet/in.c,v 1.25 2008/01/03 11:41:05 sephe Exp $
+ * $DragonFly: src/sys/netinet/in.c,v 1.26 2008/03/07 11:34:20 sephe Exp $
  */
 
 #include "opt_bootp.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/sockio.h>
 #include <sys/malloc.h>
 #include <sys/proc.h>
+#include <sys/msgport.h>
 #include <sys/socket.h>
+
 #include <sys/kernel.h>
 #include <sys/sysctl.h>
 #include <sys/thread2.h>
@@ -49,6 +52,7 @@
 #include <net/if.h>
 #include <net/if_types.h>
 #include <net/route.h>
+#include <net/netmsg2.h>
 
 #include <netinet/in.h>
 #include <netinet/in_var.h>
@@ -67,6 +71,10 @@ static void  in_socktrim (struct sockaddr_in *);
 static int     in_ifinit (struct ifnet *,
            struct in_ifaddr *, struct sockaddr_in *, int);
 
+static void    in_control_dispatch(struct netmsg *);
+static int     in_control_internal(u_long, caddr_t, struct ifnet *,
+                   struct thread *);
+
 static int subnetsarelocal = 0;
 SYSCTL_INT(_net_inet_ip, OID_AUTO, subnets_are_local, CTLFLAG_RW,
        &subnetsarelocal, 0, "");
@@ -175,6 +183,24 @@ in_len2mask(struct in_addr *mask, int len)
 
 static int in_interfaces;      /* number of external internet interfaces */
 
+struct in_control_arg {
+       u_long          cmd;
+       caddr_t         data;
+       struct ifnet    *ifp;
+       struct thread   *td;
+};
+
+static void
+in_control_dispatch(struct netmsg *nmsg)
+{
+       struct lwkt_msg *msg = &nmsg->nm_lmsg;
+       const struct in_control_arg *arg = msg->u.ms_resultp;
+       int error;
+
+       error = in_control_internal(arg->cmd, arg->data, arg->ifp, arg->td);
+       lwkt_replymsg(msg, error);
+}
+
 /*
  * Generic internet control operations (ioctl's).
  * Ifp is 0 if not an interface-specific ioctl.
@@ -186,17 +212,10 @@ int
 in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
           struct thread *td)
 {
-       struct ifreq *ifr = (struct ifreq *)data;
-       struct in_ifaddr *ia = 0, *iap;
-       struct ifaddr *ifa;
-       struct in_addr dst;
-       struct in_ifaddr *oia;
-       struct in_aliasreq *ifra = (struct in_aliasreq *)data;
-       struct sockaddr_in oldaddr;
-       int hostIsNew, iaIsNew, maskIsNew;
-       int error = 0;
-
-       iaIsNew = 0;
+       struct netmsg nmsg;
+       struct in_control_arg arg;
+       struct lwkt_msg *msg;
+       int error;
 
        switch (cmd) {
        case SIOCALIFADDR:
@@ -210,6 +229,50 @@ in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
                return in_lifaddr_ioctl(so, cmd, data, ifp, td);
        }
 
+       KASSERT(cmd != SIOCALIFADDR && cmd != SIOCDLIFADDR,
+               ("recursive SIOC%cLIFADDR!\n",
+                cmd == SIOCDLIFADDR ? 'D' : 'A'));
+
+       switch (cmd) {
+       case SIOCSIFDSTADDR:
+       case SIOCSIFBRDADDR:
+       case SIOCSIFADDR:
+       case SIOCSIFNETMASK:
+       case SIOCAIFADDR:
+       case SIOCDIFADDR:
+               bzero(&arg, sizeof(arg));
+               arg.cmd = cmd;
+               arg.data = data;
+               arg.ifp = ifp;
+               arg.td = td;
+
+               netmsg_init(&nmsg, &curthread->td_msgport, 0,
+                           in_control_dispatch);
+               msg = &nmsg.nm_lmsg;
+               msg->u.ms_resultp = &arg;
+
+               lwkt_domsg(cpu_portfn(0), msg, 0);
+               return msg->ms_error;
+       default:
+               return in_control_internal(cmd, data, ifp, td);
+       }
+}
+
+static int
+in_control_internal(u_long cmd, caddr_t data, struct ifnet *ifp,
+                   struct thread *td)
+{
+       struct ifreq *ifr = (struct ifreq *)data;
+       struct in_ifaddr *ia = 0, *iap;
+       struct in_addr dst;
+       struct in_ifaddr *oia;
+       struct in_aliasreq *ifra = (struct in_aliasreq *)data;
+       struct sockaddr_in oldaddr;
+       int hostIsNew, iaIsNew, maskIsNew;
+       int error = 0;
+
+       iaIsNew = 0;
+
        /*
         * Find address for this interface, if it exists.
         *
@@ -224,14 +287,18 @@ in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
                                ia = iap;
                                break;
                        }
-               if (ia == NULL)
-                       TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
-                               iap = ifatoia(ifa);
+               if (ia == NULL) {
+                       struct ifaddr_container *ifac;
+
+                       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid],
+                                     ifa_link) {
+                               iap = ifatoia(ifac->ifa);
                                if (iap->ia_addr.sin_family == AF_INET) {
                                        ia = iap;
                                        break;
                                }
                        }
+               }
        }
 
        switch (cmd) {
@@ -266,7 +333,9 @@ in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
                if (ifp == NULL)
                        return (EADDRNOTAVAIL);
                if (ia == NULL) {
-                       ia = kmalloc(sizeof *ia, M_IFADDR, M_WAITOK | M_ZERO);
+                       struct ifaddr *ifa;
+
+                       ia = ifa_create(sizeof(*ia), M_WAITOK);
 
                        /*
                         * Protect from NETISR_IP traversing address list
@@ -276,7 +345,7 @@ in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
                        
                        TAILQ_INSERT_TAIL(&in_ifaddrhead, ia, ia_link);
                        ifa = &ia->ia_ifa;
-                       TAILQ_INSERT_TAIL(&ifp->if_addrhead, ifa, ifa_link);
+                       ifa_iflink(ifa, ifp, 1);
 
                        ifa->ifa_addr = (struct sockaddr *)&ia->ia_addr;
                        ifa->ifa_dstaddr = (struct sockaddr *)&ia->ia_dstaddr;
@@ -438,16 +507,18 @@ in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
                return (error);
        }
 
+       ifa_ifunlink(&ia->ia_ifa, ifp);
+
        /*
         * Protect from NETISR_IP traversing address list while we're modifying
         * it.
         */
-       lwkt_serialize_enter(ifp->if_serializer);
-       TAILQ_REMOVE(&ifp->if_addrhead, &ia->ia_ifa, ifa_link);
+       crit_enter();   /* XXX MP */
        TAILQ_REMOVE(&in_ifaddrhead, ia, ia_link);
        LIST_REMOVE(ia, ia_hash);
-       IFAFREE(&ia->ia_ifa);
-       lwkt_serialize_exit(ifp->if_serializer);
+       crit_exit();    /* XXX MP */
+
+       ifa_destroy(&ia->ia_ifa);
 
        return (error);
 }
@@ -475,7 +546,6 @@ in_lifaddr_ioctl(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
                 struct thread *td)
 {
        struct if_laddrreq *iflr = (struct if_laddrreq *)data;
-       struct ifaddr *ifa;
 
        /* sanity checks */
        if (!data || !ifp) {
@@ -538,6 +608,7 @@ in_lifaddr_ioctl(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
        case SIOCGLIFADDR:
        case SIOCDLIFADDR:
            {
+               struct ifaddr_container *ifac;
                struct in_ifaddr *ia;
                struct in_addr mask, candidate, match;
                struct sockaddr_in *sin;
@@ -572,19 +643,22 @@ in_lifaddr_ioctl(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
                        }
                }
 
-               TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+               TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+                       struct ifaddr *ifa = ifac->ifa;
+
                        if (ifa->ifa_addr->sa_family != AF_INET6)
                                continue;
                        if (!cmp)
                                break;
-                       candidate.s_addr = ((struct sockaddr_in *)&ifa->ifa_addr)->sin_addr.s_addr;
+                       candidate.s_addr =
+                       ((struct sockaddr_in *)&ifa->ifa_addr)->sin_addr.s_addr;
                        candidate.s_addr &= mask.s_addr;
                        if (candidate.s_addr == match.s_addr)
                                break;
                }
-               if (!ifa)
+               if (ifac == NULL)
                        return EADDRNOTAVAIL;
-               ia = (struct in_ifaddr *)ifa;
+               ia = (struct in_ifaddr *)(ifac->ifa);
 
                if (cmd == SIOCGLIFADDR) {
                        /* fill in the if_laddrreq structure */
@@ -761,7 +835,7 @@ in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin, int
 int
 in_broadcast(struct in_addr in, struct ifnet *ifp)
 {
-       struct ifaddr *ifa;
+       struct ifaddr_container *ifac;
        u_long t;
 
        if (in.s_addr == INADDR_BROADCAST ||
@@ -775,7 +849,9 @@ in_broadcast(struct in_addr in, struct ifnet *ifp)
         * with a broadcast address.
         */
 #define ia ((struct in_ifaddr *)ifa)
-       TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
+       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
+
                if (ifa->ifa_addr->sa_family == AF_INET &&
                    (in.s_addr == ia->ia_broadaddr.sin_addr.s_addr ||
                     in.s_addr == ia->ia_netbroadcast.s_addr ||
@@ -790,6 +866,7 @@ in_broadcast(struct in_addr in, struct ifnet *ifp)
                      */
                     ia->ia_subnetmask != (u_long)0xffffffff)
                            return 1;
+       }
        return (0);
 #undef ia
 }
index fb47195..6e704c1 100644 (file)
@@ -25,7 +25,7 @@
  */
 /*
  * $FreeBSD: src/sys/netinet/ip_carp.c,v 1.48 2007/02/02 09:39:09 glebius Exp $
- * $DragonFly: src/sys/netinet/ip_carp.c,v 1.6 2008/01/11 11:59:40 sephe Exp $
+ * $DragonFly: src/sys/netinet/ip_carp.c,v 1.7 2008/03/07 11:34:20 sephe Exp $
  */
 
 #include "opt_carp.h"
@@ -237,7 +237,7 @@ carp_hmac_prepare(struct carp_softc *sc)
 {
        u_int8_t version = CARP_VERSION, type = CARP_ADVERTISEMENT;
        u_int8_t vhid = sc->sc_vhid & 0xff;
-       struct ifaddr *ifa;
+       struct ifaddr_container *ifac;
        int i;
 #ifdef INET6
        struct in6_addr in6;
@@ -261,7 +261,9 @@ carp_hmac_prepare(struct carp_softc *sc)
        SHA1Update(&sc->sc_sha1, (void *)&type, sizeof(type));
        SHA1Update(&sc->sc_sha1, (void *)&vhid, sizeof(vhid));
 #ifdef INET
-       TAILQ_FOREACH(ifa, &SC2IFP(sc)->if_addrlist, ifa_list) {
+       TAILQ_FOREACH(ifac, &SC2IFP(sc)->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
+
                if (ifa->ifa_addr->sa_family == AF_INET)
                        SHA1Update(&sc->sc_sha1,
                            (void *)&ifatoia(ifa)->ia_addr.sin_addr.s_addr,
@@ -269,7 +271,9 @@ carp_hmac_prepare(struct carp_softc *sc)
        }
 #endif /* INET */
 #ifdef INET6
-       TAILQ_FOREACH(ifa, &SC2IFP(sc)->if_addrlist, ifa_list) {
+       TAILQ_FOREACH(ifac, &SC2IFP(sc)->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
+
                if (ifa->ifa_addr->sa_family == AF_INET6) {
                        in6 = ifatoia6(ifa)->ia_addr.sin6_addr;
                        in6_clearscope(&in6);
@@ -321,13 +325,15 @@ carp_hmac_verify(struct carp_softc *sc, u_int32_t counter[2],
 static void
 carp_setroute(struct carp_softc *sc, int cmd)
 {
-       struct ifaddr *ifa;
+       struct ifaddr_container *ifac;
 
        if (sc->sc_carpdev)
                CARP_SCLOCK_ASSERT(sc);
 
        crit_enter();
-       TAILQ_FOREACH(ifa, &SC2IFP(sc)->if_addrlist, ifa_list) {
+       TAILQ_FOREACH(ifac, &SC2IFP(sc)->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
+
                if (ifa->ifa_addr->sa_family == AF_INET &&
                    sc->sc_carpdev != NULL) {
                        int count = carp_addrcount(
@@ -1039,9 +1045,10 @@ carp_send_ad_locked(struct carp_softc *sc)
 static void
 carp_send_arp(struct carp_softc *sc)
 {
-       struct ifaddr *ifa;
+       struct ifaddr_container *ifac;
 
-       TAILQ_FOREACH(ifa, &SC2IFP(sc)->if_addrlist, ifa_list) {
+       TAILQ_FOREACH(ifac, &SC2IFP(sc)->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
 
                if (ifa->ifa_addr->sa_family != AF_INET)
                        continue;
@@ -1057,11 +1064,12 @@ carp_send_arp(struct carp_softc *sc)
 static void
 carp_send_na(struct carp_softc *sc)
 {
-       struct ifaddr *ifa;
+       struct ifaddr_container *ifac;
        struct in6_addr *in6;
        static struct in6_addr mcast = IN6ADDR_LINKLOCAL_ALLNODES_INIT;
 
-       TAILQ_FOREACH(ifa, &SC2IFP(sc)->if_addrlist, ifa_list) {
+       TAILQ_FOREACH(ifac, &SC2IFP(sc)->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
 
                if (ifa->ifa_addr->sa_family != AF_INET6)
                        continue;
@@ -1078,7 +1086,6 @@ static int
 carp_addrcount(struct carp_if *cif, struct in_ifaddr *ia, int type)
 {
        struct carp_softc *vh;
-       struct ifaddr *ifa;
        int count = 0;
 
        CARP_LOCK_ASSERT(cif);
@@ -1087,8 +1094,12 @@ carp_addrcount(struct carp_if *cif, struct in_ifaddr *ia, int type)
                if ((type == CARP_COUNT_RUNNING &&
                    (SC2IFP(vh)->if_flags & IFF_UP) && (SC2IFP(vh)->if_flags & IFF_RUNNING)) ||
                    (type == CARP_COUNT_MASTER && vh->sc_state == MASTER)) {
-                       TAILQ_FOREACH(ifa, &SC2IFP(vh)->if_addrlist,
-                           ifa_list) {
+                       struct ifaddr_container *ifac;
+
+                       TAILQ_FOREACH(ifac, &SC2IFP(vh)->if_addrheads[mycpuid],
+                                     ifa_link) {
+                               struct ifaddr *ifa = ifac->ifa;
+
                                if (ifa->ifa_addr->sa_family == AF_INET &&
                                    ia->ia_addr.sin_addr.s_addr ==
                                    ifatoia(ifa)->ia_addr.sin_addr.s_addr)
@@ -1106,7 +1117,6 @@ carp_iamatch(void *v, struct in_ifaddr *ia,
        struct carp_if *cif = v;
        struct carp_softc *vh;
        int index, count = 0;
-       struct ifaddr *ifa;
 
        CARP_LOCK(cif);
 
@@ -1131,8 +1141,11 @@ carp_iamatch(void *v, struct in_ifaddr *ia,
 
                TAILQ_FOREACH(vh, &cif->vhif_vrs, sc_list) {
                        if ((SC2IFP(vh)->if_flags & IFF_UP) && (SC2IFP(vh)->if_flags & IFF_RUNNING)) {
-                               TAILQ_FOREACH(ifa, &SC2IFP(vh)->if_addrlist,
-                                   ifa_list) {
+                               struct ifaddr_container *ifac;
+
+                               TAILQ_FOREACH(ifac, &SC2IFP(vh)->if_addrheads[mycpuid], ifa_link) {
+                                       struct ifaddr *ifa = ifac->ifa;
+
                                        if (ifa->ifa_addr->sa_family ==
                                            AF_INET &&
                                            ia->ia_addr.sin_addr.s_addr ==
@@ -1173,11 +1186,14 @@ carp_iamatch6(void *v, struct in6_addr *taddr)
 {
        struct carp_if *cif = v;
        struct carp_softc *vh;
-       struct ifaddr *ifa;
 
        CARP_LOCK(cif);
        TAILQ_FOREACH(vh, &cif->vhif_vrs, sc_list) {
-               TAILQ_FOREACH(ifa, &SC2IFP(vh)->if_addrlist, ifa_list) {
+               struct ifaddr_container *ifac;
+
+               TAILQ_FOREACH(ifac, &SC2IFP(vh)->if_addrheads[mycpuid], ifa_link) {
+                       struct ifaddr *ifa = ifac->ifa;
+
                        if (IN6_ARE_ADDR_EQUAL(taddr,
                            &ifatoia6(ifa)->ia_addr.sin6_addr) &&
                            (SC2IFP(vh)->if_flags & IFF_UP) && (SC2IFP(vh)->if_flags & IFF_RUNNING) &&
@@ -1198,11 +1214,14 @@ carp_macmatch6(void *v, struct mbuf *m, const struct in6_addr *taddr)
        struct m_tag *mtag;
        struct carp_if *cif = v;
        struct carp_softc *sc;
-       struct ifaddr *ifa;
 
        CARP_LOCK(cif);
        TAILQ_FOREACH(sc, &cif->vhif_vrs, sc_list) {
-               TAILQ_FOREACH(ifa, &SC2IFP(sc)->if_addrlist, ifa_list) {
+               struct ifaddr_container *ifac;
+
+               TAILQ_FOREACH(ifac, &SC2IFP(sc)->if_addrheads[mycpuid], ifa_link) {
+                       struct ifaddr *ifa = ifac->ifa;
+
                        if (IN6_ARE_ADDR_EQUAL(taddr,
                            &ifatoia6(ifa)->ia_addr.sin6_addr) &&
                            (SC2IFP(sc)->if_flags & IFF_UP) && (SC2IFP(sc)->if_flags & IFF_RUNNING)) {
index 53caef8..95d0161 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/netinet/ip_divert.c,v 1.42.2.6 2003/01/23 21:06:45 sam Exp $
- * $DragonFly: src/sys/netinet/ip_divert.c,v 1.35 2007/12/21 13:17:51 sephe Exp $
+ * $DragonFly: src/sys/netinet/ip_divert.c,v 1.36 2008/03/07 11:34:20 sephe Exp $
  */
 
 #include "opt_inet.h"
@@ -240,10 +240,13 @@ div_packet(struct mbuf *m, int incoming, int port)
         */
        divsrc.sin_addr.s_addr = 0;
        if (incoming) {
-               struct ifaddr *ifa;
+               struct ifaddr_container *ifac;
 
                /* Find IP address for receive interface */
-               TAILQ_FOREACH(ifa, &m->m_pkthdr.rcvif->if_addrhead, ifa_link) {
+               TAILQ_FOREACH(ifac, &m->m_pkthdr.rcvif->if_addrheads[mycpuid],
+                             ifa_link) {
+                       struct ifaddr *ifa = ifac->ifa;
+
                        if (ifa->ifa_addr == NULL)
                                continue;
                        if (ifa->ifa_addr->sa_family != AF_INET)
index 561dea6..b4aa84e 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)ip_icmp.c   8.2 (Berkeley) 1/4/94
  * $FreeBSD: src/sys/netinet/ip_icmp.c,v 1.39.2.19 2003/01/24 05:11:34 sam Exp $
- * $DragonFly: src/sys/netinet/ip_icmp.c,v 1.27 2007/12/19 12:13:17 sephe Exp $
+ * $DragonFly: src/sys/netinet/ip_icmp.c,v 1.28 2008/03/07 11:34:20 sephe Exp $
  */
 
 #include "opt_ipsec.h"
@@ -611,7 +611,6 @@ static void
 icmp_reflect(struct mbuf *m)
 {
        struct ip *ip = mtod(m, struct ip *);
-       struct ifaddr *ifa;
        struct in_ifaddr *ia;
        struct in_addr t;
        struct mbuf *opts = 0;
@@ -640,7 +639,12 @@ icmp_reflect(struct mbuf *m)
                        goto match;
        if (m->m_pkthdr.rcvif != NULL &&
            m->m_pkthdr.rcvif->if_flags & IFF_BROADCAST) {
-               TAILQ_FOREACH(ifa, &m->m_pkthdr.rcvif->if_addrhead, ifa_link) {
+               struct ifaddr_container *ifac;
+
+               TAILQ_FOREACH(ifac, &m->m_pkthdr.rcvif->if_addrheads[mycpuid],
+                             ifa_link) {
+                       struct ifaddr *ifa = ifac->ifa;
+
                        if (ifa->ifa_addr->sa_family != AF_INET)
                                continue;
                        ia = ifatoia(ifa);
index a66d124..eacac9c 100644 (file)
@@ -65,7 +65,7 @@
  *
  *     @(#)ip_input.c  8.2 (Berkeley) 1/4/94
  * $FreeBSD: src/sys/netinet/ip_input.c,v 1.130.2.52 2003/03/07 07:01:28 silby Exp $
- * $DragonFly: src/sys/netinet/ip_input.c,v 1.76 2007/12/28 13:27:45 sephe Exp $
+ * $DragonFly: src/sys/netinet/ip_input.c,v 1.77 2008/03/07 11:34:20 sephe Exp $
  */
 
 #define        _IP_VHL
@@ -432,7 +432,6 @@ ip_input(struct mbuf *m)
        struct ip *ip;
        struct ipq *fp;
        struct in_ifaddr *ia = NULL;
-       struct ifaddr *ifa;
        int i, hlen, checkif;
        u_short sum;
        struct in_addr pkt_dst;
@@ -715,7 +714,12 @@ pass:
         * into the stack for SIMPLEX interfaces handled by ether_output().
         */
        if (m->m_pkthdr.rcvif->if_flags & IFF_BROADCAST) {
-               TAILQ_FOREACH(ifa, &m->m_pkthdr.rcvif->if_addrhead, ifa_link) {
+               struct ifaddr_container *ifac;
+
+               TAILQ_FOREACH(ifac, &m->m_pkthdr.rcvif->if_addrheads[mycpuid],
+                             ifa_link) {
+                       struct ifaddr *ifa = ifac->ifa;
+
                        if (ifa->ifa_addr == NULL) /* shutdown/startup race */
                                continue;
                        if (ifa->ifa_addr->sa_family != AF_INET)
index f02ffa7..249ca35 100644 (file)
@@ -1,5 +1,5 @@
 /*     $KAME: sctp_asconf.c,v 1.23 2004/08/17 06:28:01 t-momose Exp $  */
-/*     $DragonFly: src/sys/netinet/sctp_asconf.c,v 1.6 2007/08/27 16:15:42 hasso Exp $ */
+/*     $DragonFly: src/sys/netinet/sctp_asconf.c,v 1.7 2008/03/07 11:34:20 sephe Exp $ */
 
 /*
  * Copyright (c) 2001, 2002, 2003, 2004 Cisco Systems, Inc.
@@ -2144,14 +2144,17 @@ static struct sockaddr *
 sctp_find_valid_localaddr(struct sctp_tcb *stcb)
 {
        struct ifnet *ifn;
-       struct ifaddr *ifa;
 
        TAILQ_FOREACH(ifn, &ifnet, if_list) {
+               struct ifaddr_container *ifac;
+
                if (stcb->asoc.loopback_scope == 0 && ifn->if_type == IFT_LOOP) {
                        /* Skip if loopback_scope not set */
                        continue;
                }
-               TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
+               TAILQ_FOREACH(ifac, &ifn->if_addrheads[mycpuid], ifa_link) {
+                       struct ifaddr *ifa = ifac->ifa;
+
                        if (ifa->ifa_addr->sa_family == AF_INET &&
                            stcb->asoc.ipv4_addr_legal) {
                                struct sockaddr_in *sin;
@@ -2801,22 +2804,26 @@ sctp_check_address_list_all(struct sctp_tcb *stcb, struct mbuf *m, int offset,
     uint16_t site_scope, uint16_t ipv4_scope, uint16_t loopback_scope)
 {
        struct ifnet *ifn;
-       struct ifaddr *ifa;
 
        /* go through all our known interfaces */
        TAILQ_FOREACH(ifn, &ifnet, if_list) {
+               struct ifaddr_container *ifac;
+
                if (loopback_scope == 0 && ifn->if_type == IFT_LOOP) {
                        /* skip loopback interface */
                        continue;
                }
 
                /* go through each interface address */
-               TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
+               TAILQ_FOREACH(ifac, &ifn->if_addrheads[mycpuid], ifa_link) {
+                       struct ifaddr *ifa = ifac->ifa;
+
                        /* do i have it implicitly? */
                        if (sctp_cmpaddr(ifa->ifa_addr, init_addr)) {
 #ifdef SCTP_DEBUG
                                if (sctp_debug_on & SCTP_DEBUG_ASCONF2) {
-                                       kprintf("check_address_list_all: skipping ");
+                                       kprintf("check_address_list_all: "
+                                               "skipping ");
                                        sctp_print_address(ifa->ifa_addr);
                                }
 #endif /* SCTP_DEBUG */
index d7da9f3..a89a9c1 100644 (file)
@@ -1,5 +1,5 @@
 /*     $KAME: sctp_output.c,v 1.46 2005/03/06 16:04:17 itojun Exp $    */
-/*     $DragonFly: src/sys/netinet/sctp_output.c,v 1.12 2007/11/10 17:55:25 swildner Exp $     */
+/*     $DragonFly: src/sys/netinet/sctp_output.c,v 1.13 2008/03/07 11:34:20 sephe Exp $        */
 
 /*
  * Copyright (C) 2002, 2003, 2004 Cisco Systems Inc,
@@ -565,7 +565,6 @@ sctp_choose_v4_boundspecific_inp(struct sctp_inpcb *inp,
        struct sctp_laddr *laddr;
        struct sockaddr_in *sin;
        struct ifnet *ifn;
-       struct ifaddr *ifa;
        uint8_t sin_loop, sin_local;
 
        /* first question, is the ifn we will emit on
@@ -573,8 +572,12 @@ sctp_choose_v4_boundspecific_inp(struct sctp_inpcb *inp,
         */
        ifn = rt->rt_ifp;
        if (ifn) {
+               struct ifaddr_container *ifac;
+
                /* is a prefered one on the interface we route out? */
-               TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
+               TAILQ_FOREACH(ifac, &ifn->if_addrheads[mycpuid], ifa_link) {
+                       struct ifaddr *ifa = ifac->ifa;
+
                        sin = sctp_is_v4_ifa_addr_prefered (ifa, loopscope, ipv4_scope, &sin_loop, &sin_local);
                        if (sin == NULL)
                                continue;
@@ -583,7 +586,9 @@ sctp_choose_v4_boundspecific_inp(struct sctp_inpcb *inp,
                        }
                }
                /* is an acceptable one on the interface we route out? */
-               TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
+               TAILQ_FOREACH(ifac, &ifn->if_addrheads[mycpuid], ifa_link) {
+                       struct ifaddr *ifa = ifac->ifa;
+
                        sin = sctp_is_v4_ifa_addr_acceptable (ifa, loopscope, ipv4_scope, &sin_loop, &sin_local);
                        if (sin == NULL)
                                continue;
@@ -650,7 +655,6 @@ sctp_choose_v4_boundspecific_stcb(struct sctp_inpcb *inp,
        struct sctp_laddr *laddr, *starting_point;
        struct in_addr ans;
        struct ifnet *ifn;
-       struct ifaddr *ifa;
        uint8_t sin_loop, sin_local, start_at_beginning=0;
        struct sockaddr_in *sin;
 
@@ -675,8 +679,12 @@ sctp_choose_v4_boundspecific_stcb(struct sctp_inpcb *inp,
                 * in our list, if so, we want that one.
                 */
                if (ifn) {
+                       struct ifaddr_container *ifac;
+
                        /* first try for an prefered address on the ep */
-                       TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
+                       TAILQ_FOREACH(ifac, &ifn->if_addrheads[mycpuid], ifa_link) {
+                               struct ifaddr *ifa = ifac->ifa;
+
                                if (sctp_is_addr_in_ep(inp, ifa)) {
                                        sin = sctp_is_v4_ifa_addr_prefered (ifa, loopscope, ipv4_scope, &sin_loop, &sin_local);
                                        if (sin == NULL)
@@ -690,7 +698,9 @@ sctp_choose_v4_boundspecific_stcb(struct sctp_inpcb *inp,
                                }
                        }
                        /* next try for an acceptable address on the ep */
-                       TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
+                       TAILQ_FOREACH(ifac, &ifn->if_addrheads[mycpuid], ifa_link) {
+                               struct ifaddr *ifa = ifac->ifa;
+
                                if (sctp_is_addr_in_ep(inp, ifa)) {
                                        sin = sctp_is_v4_ifa_addr_acceptable (ifa, loopscope, ipv4_scope, &sin_loop, &sin_local);
                                        if (sin == NULL)
@@ -790,7 +800,11 @@ sctp_choose_v4_boundspecific_stcb(struct sctp_inpcb *inp,
                                continue;
                        /* first question, is laddr->ifa an address associated with the emit interface */
                        if (ifn) {
-                               TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
+                               struct ifaddr_container *ifac;
+
+                               TAILQ_FOREACH(ifac, &ifn->if_addrheads[mycpuid], ifa_link) {
+                                       struct ifaddr *ifa = ifac->ifa;
+
                                        if (laddr->ifa == ifa) {
                                                sin = (struct sockaddr_in *)laddr->ifa->ifa_addr;
                                                return (sin->sin_addr);
@@ -814,7 +828,11 @@ sctp_choose_v4_boundspecific_stcb(struct sctp_inpcb *inp,
                                continue;
                        /* first question, is laddr->ifa an address associated with the emit interface */
                        if (ifn) {
-                               TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
+                               struct ifaddr_container *ifac;
+
+                               TAILQ_FOREACH(ifac, &ifn->if_addrheads[mycpuid], ifa_link) {
+                                       struct ifaddr *ifa = ifac->ifa;
+
                                        if (laddr->ifa == ifa) {
                                                sin = (struct sockaddr_in *)laddr->ifa->ifa_addr;
                                                return (sin->sin_addr);
@@ -860,11 +878,14 @@ static struct sockaddr_in *
 sctp_select_v4_nth_prefered_addr_from_ifn_boundall (struct ifnet *ifn, struct sctp_tcb *stcb, int non_asoc_addr_ok,
                                                    uint8_t loopscope, uint8_t ipv4_scope, int cur_addr_num)
 {
-       struct ifaddr *ifa;
+       struct ifaddr_container *ifac;
        struct sockaddr_in *sin;
        uint8_t sin_loop, sin_local;
        int num_eligible_addr = 0;
-       TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
+
+       TAILQ_FOREACH(ifac, &ifn->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
+
                sin = sctp_is_v4_ifa_addr_prefered (ifa, loopscope, ipv4_scope, &sin_loop, &sin_local);
                if (sin == NULL)
                        continue;
@@ -888,11 +909,13 @@ static int
 sctp_count_v4_num_prefered_boundall (struct ifnet *ifn, struct sctp_tcb *stcb, int non_asoc_addr_ok,
                                     uint8_t loopscope, uint8_t ipv4_scope, uint8_t *sin_loop, uint8_t *sin_local)
 {
-       struct ifaddr *ifa;
+       struct ifaddr_container *ifac;
        struct sockaddr_in *sin;
        int num_eligible_addr = 0;
 
-       TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
+       TAILQ_FOREACH(ifac, &ifn->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
+
                sin = sctp_is_v4_ifa_addr_prefered (ifa, loopscope, ipv4_scope, sin_loop, sin_local);
                if (sin == NULL)
                        continue;
@@ -924,7 +947,7 @@ sctp_choose_v4_boundall(struct sctp_inpcb *inp,
        struct ifnet *ifn;
        struct sockaddr_in *sin;
        struct in_addr ans;
-       struct ifaddr *ifa;
+       struct ifaddr_container *ifac;
        /*
         * For v4 we can use (in boundall) any address in the association. If
         * non_asoc_addr_ok is set we can use any address (at least in theory).
@@ -984,7 +1007,9 @@ sctp_choose_v4_boundall(struct sctp_inpcb *inp,
         *         and see if we can find an acceptable address.
         */
  bound_all_v4_plan_b:
-       TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
+       TAILQ_FOREACH(ifac, &ifn->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
+
                sin = sctp_is_v4_ifa_addr_acceptable (ifa, loopscope, ipv4_scope, &sin_loop, &sin_local);
                if (sin == NULL)
                        continue;
@@ -1060,7 +1085,9 @@ sctp_choose_v4_boundall(struct sctp_inpcb *inp,
                        /* already looked at this guy */
                        continue;
 
-               TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
+               TAILQ_FOREACH(ifac, &ifn->if_addrheads[mycpuid], ifa_link) {
+                       struct ifaddr *ifa = ifac->ifa;
+
                        sin = sctp_is_v4_ifa_addr_acceptable (ifa, loopscope, ipv4_scope, &sin_loop, &sin_local);
                        if (sin == NULL)
                                continue;
@@ -1315,7 +1342,6 @@ sctp_choose_v6_boundspecific_stcb(struct sctp_inpcb *inp,
        int sin_loop, sin_local;
        int start_at_beginning=0;
        struct ifnet *ifn;
-       struct ifaddr *ifa;
 
        ifn = rt->rt_ifp;
        if (inp->sctp_flags & SCTP_PCB_FLAGS_DO_ASCONF) {
@@ -1328,7 +1354,11 @@ sctp_choose_v6_boundspecific_stcb(struct sctp_inpcb *inp,
                 * in our list, if so, we want that one.
                 */
                if (ifn) {
-                       TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
+                       struct ifaddr_container *ifac;
+
+                       TAILQ_FOREACH(ifac, &ifn->if_addrheads[mycpuid], ifa_link) {
+                               struct ifaddr *ifa = ifac->ifa;
+
                                if (sctp_is_addr_in_ep(inp, ifa)) {
                                        sin6 = sctp_is_v6_ifa_addr_acceptable (ifa, loopscope, loc_scope, &sin_loop, &sin_local);
                                        if (sin6 == NULL)
@@ -1429,7 +1459,11 @@ sctp_choose_v6_boundspecific_stcb(struct sctp_inpcb *inp,
                                continue;
                        /* first question, is laddr->ifa an address associated with the emit interface */
                        if (ifn) {
-                               TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
+                               struct ifaddr_container *ifac;
+
+                               TAILQ_FOREACH(ifac, &ifn->if_addrheads[mycpuid], ifa_link) {
+                                       struct ifaddr *ifa = ifac->ifa;
+
                                        if (laddr->ifa == ifa) {
                                                sin6 = (struct sockaddr_in6 *)laddr->ifa->ifa_addr;
                                                return (sin6);
@@ -1499,7 +1533,6 @@ sctp_choose_v6_boundspecific_inp(struct sctp_inpcb *inp,
        struct sctp_laddr *laddr;
        struct sockaddr_in6 *sin6;
        struct ifnet *ifn;
-       struct ifaddr *ifa;
        int sin_loop, sin_local;
 
        /* first question, is the ifn we will emit on
@@ -1508,7 +1541,11 @@ sctp_choose_v6_boundspecific_inp(struct sctp_inpcb *inp,
 
        ifn = rt->rt_ifp;
        if (ifn) {
-               TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
+               struct ifaddr_container *ifac;
+
+               TAILQ_FOREACH(ifac, &ifn->if_addrheads[mycpuid], ifa_link) {
+                       struct ifaddr *ifa = ifac->ifa;
+
                        sin6 = sctp_is_v6_ifa_addr_acceptable (ifa, loopscope, loc_scope, &sin_loop, &sin_local);
                        if (sin6 == NULL)
                                continue;
@@ -1573,12 +1610,14 @@ static struct sockaddr_in6 *
 sctp_select_v6_nth_addr_from_ifn_boundall (struct ifnet *ifn, struct sctp_tcb *stcb, int non_asoc_addr_ok, uint8_t loopscope,
                                           uint8_t loc_scope, int cur_addr_num, int match_scope)
 {
-       struct ifaddr *ifa;
+       struct ifaddr_container *ifac;
        struct sockaddr_in6 *sin6;
        int sin_loop, sin_local;
        int num_eligible_addr = 0;
 
-       TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
+       TAILQ_FOREACH(ifac, &ifn->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
+
                sin6 = sctp_is_v6_ifa_addr_acceptable (ifa, loopscope, loc_scope, &sin_loop, &sin_local);
                if (sin6 == NULL)
                        continue;
@@ -1621,12 +1660,14 @@ static int
 sctp_count_v6_num_eligible_boundall (struct ifnet *ifn, struct sctp_tcb *stcb,
                                     int non_asoc_addr_ok, uint8_t loopscope, uint8_t loc_scope)
 {
-       struct ifaddr *ifa;
+       struct ifaddr_container *ifac;
        struct sockaddr_in6 *sin6;
        int num_eligible_addr = 0;
        int sin_loop, sin_local;
 
-       TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
+       TAILQ_FOREACH(ifac, &ifn->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
+
                sin6 = sctp_is_v6_ifa_addr_acceptable (ifa, loopscope, loc_scope, &sin_loop, &sin_local);
                if (sin6 == NULL)
                        continue;
@@ -2826,11 +2867,12 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
        /* now the addresses */
        if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
                struct ifnet *ifn;
-               struct ifaddr *ifa;
                int cnt;
 
                cnt = cnt_inits_to;
                TAILQ_FOREACH(ifn, &ifnet, if_list) {
+                       struct ifaddr_container *ifac;
+
                        if ((stcb->asoc.loopback_scope == 0) &&
                            (ifn->if_type == IFT_LOOP)) {
                                /*
@@ -2839,7 +2881,9 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
                                 */
                                continue;
                        }
-                       TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
+                       TAILQ_FOREACH(ifac, &ifn->if_addrheads[mycpuid], ifa_link) {
+                               struct ifaddr *ifa = ifac->ifa;
+
                                if (sctp_is_address_in_scope(ifa,
                                    stcb->asoc.ipv4_addr_legal,
                                    stcb->asoc.ipv6_addr_legal,
@@ -2854,6 +2898,8 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
                }
                if (cnt > 1) {
                        TAILQ_FOREACH(ifn, &ifnet, if_list) {
+                               struct ifaddr_container *ifac;
+
                                if ((stcb->asoc.loopback_scope == 0) &&
                                    (ifn->if_type == IFT_LOOP)) {
                                        /*
@@ -2862,7 +2908,9 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
                                         */
                                        continue;
                                }
-                               TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
+                               TAILQ_FOREACH(ifac, &ifn->if_addrheads[mycpuid], ifa_link) {
+                                       struct ifaddr *ifa = ifac->ifa;
+
                                        if (sctp_is_address_in_scope(ifa,
                                            stcb->asoc.ipv4_addr_legal,
                                            stcb->asoc.ipv6_addr_legal,
@@ -3778,10 +3826,11 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
        /* now the addresses */
        if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
                struct ifnet *ifn;
-               struct ifaddr *ifa;
                int cnt = cnt_inits_to;
 
                TAILQ_FOREACH(ifn, &ifnet, if_list) {
+                       struct ifaddr_container *ifac;
+
                        if ((stc.loopback_scope == 0) &&
                            (ifn->if_type == IFT_LOOP)) {
                                /*
@@ -3790,7 +3839,9 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
                                 */
                                continue;
                        }
-                       TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
+                       TAILQ_FOREACH(ifac, &ifn->if_addrheads[mycpuid], ifa_link) {
+                               struct ifaddr *ifa = ifac->ifa;
+
                                if (sctp_is_address_in_scope(ifa,
                                    stc.ipv4_addr_legal, stc.ipv6_addr_legal,
                                    stc.loopback_scope, stc.ipv4_scope,
@@ -3802,6 +3853,8 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
                }
                if (cnt > 1) {
                        TAILQ_FOREACH(ifn, &ifnet, if_list) {
+                               struct ifaddr_container *ifac;
+
                                if ((stc.loopback_scope == 0) &&
                                    (ifn->if_type == IFT_LOOP)) {
                                        /*
@@ -3810,7 +3863,9 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
                                         */
                                        continue;
                                }
-                               TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
+                               TAILQ_FOREACH(ifac, &ifn->if_addrheads[mycpuid], ifa_link) {
+                                       struct ifaddr *ifa = ifac->ifa;
+
                                        if (sctp_is_address_in_scope(ifa,
                                            stc.ipv4_addr_legal,
                                            stc.ipv6_addr_legal,
index a966f0b..6ca9161 100644 (file)
@@ -1,5 +1,5 @@
 /*     $KAME: sctp_pcb.c,v 1.37 2004/08/17 06:28:02 t-momose Exp $     */
-/*     $DragonFly: src/sys/netinet/sctp_pcb.c,v 1.13 2008/01/06 16:55:52 swildner Exp $        */
+/*     $DragonFly: src/sys/netinet/sctp_pcb.c,v 1.14 2008/03/07 11:34:20 sephe Exp $   */
 
 /*
  * Copyright (c) 2001, 2002, 2003, 2004 Cisco Systems, Inc.
@@ -2552,9 +2552,13 @@ int
 sctp_is_address_on_local_host(struct sockaddr *addr)
 {
        struct ifnet *ifn;
-       struct ifaddr *ifa;
+
        TAILQ_FOREACH(ifn, &ifnet, if_list) {
-               TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
+               struct ifaddr_container *ifac;
+
+               TAILQ_FOREACH(ifac, &ifn->if_addrheads[mycpuid], ifa_link) {
+                       struct ifaddr *ifa = ifac->ifa;
+
                        if (addr->sa_family == ifa->ifa_addr->sa_family) {
                                /* same family */
                                if (addr->sa_family == AF_INET) {
index c281308..5ddd342 100644 (file)
@@ -1,5 +1,5 @@
 /*     $KAME: sctp_usrreq.c,v 1.47 2005/03/06 16:04:18 itojun Exp $    */
-/*     $DragonFly: src/sys/netinet/sctp_usrreq.c,v 1.12 2007/04/22 01:13:14 dillon Exp $       */
+/*     $DragonFly: src/sys/netinet/sctp_usrreq.c,v 1.13 2008/03/07 11:34:20 sephe Exp $        */
 
 /*
  * Copyright (c) 2001, 2002, 2003, 2004 Cisco Systems, Inc.
@@ -1184,7 +1184,6 @@ sctp_fill_up_addresses(struct sctp_inpcb *inp,
                       struct sockaddr_storage *sas)
 {
        struct ifnet *ifn;
-       struct ifaddr *ifa;
        int loopback_scope, ipv4_local_scope, local_scope, site_scope, actual;
        int ipv4_addr_legal, ipv6_addr_legal;
        actual = 0;
@@ -1222,12 +1221,17 @@ sctp_fill_up_addresses(struct sctp_inpcb *inp,
 
        if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
                TAILQ_FOREACH(ifn, &ifnet, if_list) {
+                       struct ifaddr_container *ifac;
+
                        if ((loopback_scope == 0) &&
                            (ifn->if_type == IFT_LOOP)) {
                                /* Skip loopback if loopback_scope not set */
                                continue;
                        }
-                       TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
+                       TAILQ_FOREACH(ifac, &ifn->if_addrheads[mycpuid],
+                                     ifa_link) {
+                               struct ifaddr *ifa = ifac->ifa;
+
                                if (stcb) {
                                /*
                                 * For the BOUND-ALL case, the list
@@ -1382,10 +1386,13 @@ sctp_count_max_addresses(struct sctp_inpcb *inp)
         */
        if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
                struct ifnet *ifn;
-               struct ifaddr *ifa;
 
                TAILQ_FOREACH(ifn, &ifnet, if_list) {
-                       TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
+                       struct ifaddr_container *ifac;
+
+                       TAILQ_FOREACH(ifac, &ifn->if_addrheads[mycpuid], ifa_link) {
+                               struct ifaddr *ifa = ifac->ifa;
+
                                /* Count them if they are the right type */
                                if (ifa->ifa_addr->sa_family == AF_INET) {
                                        if (inp->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)
index d74b975..493a7a2 100644 (file)
@@ -1,5 +1,5 @@
 /*     $KAME: sctputil.c,v 1.36 2005/03/06 16:04:19 itojun Exp $       */
-/*     $DragonFly: src/sys/netinet/sctputil.c,v 1.8 2007/04/22 01:13:14 dillon Exp $   */
+/*     $DragonFly: src/sys/netinet/sctputil.c,v 1.9 2008/03/07 11:34:20 sephe Exp $    */
 
 /*
  * Copyright (c) 2001, 2002, 2003, 2004 Cisco Systems, Inc.
@@ -3621,12 +3621,15 @@ struct ifaddr *
 sctp_find_ifa_by_addr(struct sockaddr *sa)
 {
        struct ifnet *ifn;
-       struct ifaddr *ifa;
 
        /* go through all our known interfaces */
        TAILQ_FOREACH(ifn, &ifnet, if_list) {
+               struct ifaddr_container *ifac;
+
                /* go through each interface addresses */
-               TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
+               TAILQ_FOREACH(ifac, &ifn->if_addrheads[mycpuid], ifa_link) {
+                       struct ifaddr *ifa = ifac->ifa;
+
                        /* correct family? */
                        if (ifa->ifa_addr->sa_family != sa->sa_family)
                                continue;
index 1aaaf8d..fe1d7ad 100644 (file)
@@ -1,5 +1,5 @@
 /*     $FreeBSD: src/sys/netinet6/icmp6.c,v 1.6.2.13 2003/05/06 06:46:58 suz Exp $     */
-/*     $DragonFly: src/sys/netinet6/icmp6.c,v 1.26 2007/04/22 01:13:14 dillon Exp $    */
+/*     $DragonFly: src/sys/netinet6/icmp6.c,v 1.27 2008/03/07 11:34:21 sephe Exp $     */
 /*     $KAME: icmp6.c,v 1.211 2001/04/04 05:56:20 itojun Exp $ */
 
 /*
@@ -1604,7 +1604,6 @@ ni6_addrs(struct icmp6_nodeinfo *ni6, struct mbuf *m, struct ifnet **ifpp,
 {
        struct ifnet *ifp;
        struct in6_ifaddr *ifa6;
-       struct ifaddr *ifa;
        struct sockaddr_in6 *subj_ip6 = NULL; /* XXX pedant */
        int addrs = 0, addrsofif, iffound = 0;
        int niflags = ni6->ni_flags;
@@ -1627,9 +1626,13 @@ ni6_addrs(struct icmp6_nodeinfo *ni6, struct mbuf *m, struct ifnet **ifpp,
 
        for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list))
        {
+               struct ifaddr_container *ifac;
+
                addrsofif = 0;
-               TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
+               TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link)
                {
+                       struct ifaddr *ifa = ifac->ifa;
+
                        if (ifa->ifa_addr->sa_family != AF_INET6)
                                continue;
                        ifa6 = (struct in6_ifaddr *)ifa;
@@ -1697,7 +1700,6 @@ ni6_store_addrs(struct icmp6_nodeinfo *ni6, struct icmp6_nodeinfo *nni6,
 {
        struct ifnet *ifp = ifp0 ? ifp0 : TAILQ_FIRST(&ifnet);
        struct in6_ifaddr *ifa6;
-       struct ifaddr *ifa;
        struct ifnet *ifp_dep = NULL;
        int copied = 0, allow_deprecated = 0;
        u_char *cp = (u_char *)(nni6 + 1);
@@ -1711,7 +1713,11 @@ again:
 
        for (; ifp; ifp = TAILQ_NEXT(ifp, if_list))
        {
-               TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
+               struct ifaddr_container *ifac;
+
+               TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+                       struct ifaddr *ifa = ifac->ifa;
+
                        if (ifa->ifa_addr->sa_family != AF_INET6)
                                continue;
                        ifa6 = (struct in6_ifaddr *)ifa;
index 7552d35..7dff8c0 100644 (file)
@@ -1,5 +1,5 @@
 /*     $FreeBSD: src/sys/netinet6/in6.c,v 1.7.2.9 2002/04/28 05:40:26 suz Exp $        */
-/*     $DragonFly: src/sys/netinet6/in6.c,v 1.27 2008/03/01 22:03:13 swildner Exp $    */
+/*     $DragonFly: src/sys/netinet6/in6.c,v 1.28 2008/03/07 11:34:21 sephe Exp $       */
 /*     $KAME: in6.c,v 1.259 2002/01/21 11:37:50 keiichi Exp $  */
 
 /*
@@ -302,15 +302,17 @@ int
 in6_ifindex2scopeid(int idx)
 {
        struct ifnet *ifp;
-       struct ifaddr *ifa;
        struct sockaddr_in6 *sin6;
+       struct ifaddr_container *ifac;
 
        if (idx < 0 || if_index < idx)
                return -1;
        ifp = ifindex2ifnet[idx];
 
-       TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
+       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link)
        {
+               struct ifaddr *ifa = ifac->ifa;
+
                if (ifa->ifa_addr->sa_family != AF_INET6)
                        continue;
                sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
@@ -903,8 +905,7 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
                 * RA, it is called under splnet().  So, we should call malloc
                 * with M_NOWAIT.
                 */
-               ia = (struct in6_ifaddr *)
-                       kmalloc(sizeof(*ia), M_IFADDR, M_NOWAIT | M_ZERO);
+               ia = ifa_create(sizeof(*ia), M_NOWAIT);
                if (ia == NULL)
                        return (ENOBUFS);
                /* Initialize the address and masks */
@@ -932,8 +933,7 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
                } else
                        in6_ifaddr = ia;
 
-               TAILQ_INSERT_TAIL(&ifp->if_addrlist, &ia->ia_ifa,
-                                 ifa_list);
+               ifa_iflink(&ia->ia_ifa, ifp, 1);
        }
 
        /* set prefix mask */
@@ -1216,7 +1216,7 @@ in6_unlink_ifa(struct in6_ifaddr *ia, struct ifnet *ifp)
 
        crit_enter();
 
-       TAILQ_REMOVE(&ifp->if_addrlist, &ia->ia_ifa, ifa_list);
+       ifa_ifunlink(&ia->ia_ifa, ifp);
 
        oia = ia;
        if (oia == (ia = in6_ifaddr))
@@ -1261,7 +1261,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.
         */
-       IFAFREE(&oia->ia_ifa);
+       ifa_destroy(&oia->ia_ifa);
 
        crit_exit();
 }
@@ -1269,14 +1269,13 @@ in6_unlink_ifa(struct in6_ifaddr *ia, struct ifnet *ifp)
 void
 in6_purgeif(struct ifnet *ifp)
 {
-       struct ifaddr *ifa, *nifa;
+       struct ifaddr_container *ifac, *next;
 
-       for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; ifa = nifa)
-       {
-               nifa = TAILQ_NEXT(ifa, ifa_list);
-               if (ifa->ifa_addr->sa_family != AF_INET6)
+       TAILQ_FOREACH_MUTABLE(ifac, &ifp->if_addrheads[mycpuid],
+                             ifa_link, next) {
+               if (ifac->ifa->ifa_addr->sa_family != AF_INET6)
                        continue;
-               in6_purgeaddr(ifa);
+               in6_purgeaddr(ifac->ifa);
        }
 
        in6_ifdetach(ifp);
@@ -1310,7 +1309,6 @@ in6_lifaddr_ioctl(struct socket *so, u_long cmd, caddr_t data,
                  struct ifnet *ifp, struct thread *td)
 {
        struct if_laddrreq *iflr = (struct if_laddrreq *)data;
-       struct ifaddr *ifa;
        struct sockaddr *sa;
 
        /* sanity checks */
@@ -1359,6 +1357,7 @@ in6_lifaddr_ioctl(struct socket *so, u_long cmd, caddr_t data,
                int prefixlen;
 
                if (iflr->flags & IFLR_PREFIX) {
+                       struct ifaddr *ifa;
                        struct sockaddr_in6 *sin6;
 
                        /*
@@ -1420,6 +1419,7 @@ in6_lifaddr_ioctl(struct socket *so, u_long cmd, caddr_t data,
        case SIOCGLIFADDR:
        case SIOCDLIFADDR:
            {
+               struct ifaddr_container *ifac;
                struct in6_ifaddr *ia;
                struct in6_addr mask, candidate, match;
                struct sockaddr_in6 *sin6;
@@ -1456,8 +1456,9 @@ in6_lifaddr_ioctl(struct socket *so, u_long cmd, caddr_t data,
                        }
                }
 
-               TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
-               {
+               TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+                       struct ifaddr *ifa = ifac->ifa;
+
                        if (ifa->ifa_addr->sa_family != AF_INET6)
                                continue;
                        if (!cmp)
@@ -1478,9 +1479,9 @@ in6_lifaddr_ioctl(struct socket *so, u_long cmd, caddr_t data,
                        if (IN6_ARE_ADDR_EQUAL(&candidate, &match))
                                break;
                }
-               if (!ifa)
+               if (ifac == NULL)
                        return EADDRNOTAVAIL;
-               ia = ifa2ia6(ifa);
+               ia = ifa2ia6(ifac->ifa);
 
                if (cmd == SIOCGLIFADDR) {
                        struct sockaddr_in6 *s6;
@@ -1551,24 +1552,23 @@ in6_ifinit(struct ifnet *ifp, struct in6_ifaddr *ia, struct sockaddr_in6 *sin6,
           int newhost)
 {
        int     error = 0, plen, ifacount = 0;
-       struct ifaddr *ifa;
-
-       lwkt_serialize_enter(ifp->if_serializer);
+       struct ifaddr_container *ifac;
 
        /*
         * Give the interface a chance to initialize
         * if this is its first address,
         * and to validate the address if necessary.
         */
-       TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
-       {
-               if (ifa->ifa_addr == NULL)
+       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+               if (ifac->ifa->ifa_addr == NULL)
                        continue;       /* just for safety */
-               if (ifa->ifa_addr->sa_family != AF_INET6)
+               if (ifac->ifa->ifa_addr->sa_family != AF_INET6)
                        continue;
                ifacount++;
        }
 
+       lwkt_serialize_enter(ifp->if_serializer);
+
        ia->ia_addr = *sin6;
 
        if (ifacount <= 1 && ifp->if_ioctl &&
@@ -1736,10 +1736,11 @@ in6_delmulti(struct in6_multi *in6m)
 struct in6_ifaddr *
 in6ifa_ifpforlinklocal(struct ifnet *ifp, int ignoreflags)
 {
-       struct ifaddr *ifa;
+       struct ifaddr_container *ifac;
+
+       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
 
-       TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
-       {
                if (ifa->ifa_addr == NULL)
                        continue;       /* just for safety */
                if (ifa->ifa_addr->sa_family != AF_INET6)
@@ -1751,8 +1752,10 @@ in6ifa_ifpforlinklocal(struct ifnet *ifp, int ignoreflags)
                        break;
                }
        }
-
-       return ((struct in6_ifaddr *)ifa);
+       if (ifac != NULL)
+               return ((struct in6_ifaddr *)(ifac->ifa));
+       else
+               return (NULL);
 }
 
 
@@ -1762,10 +1765,11 @@ in6ifa_ifpforlinklocal(struct ifnet *ifp, int ignoreflags)
 struct in6_ifaddr *
 in6ifa_ifpwithaddr(struct ifnet *ifp, struct in6_addr *addr)
 {
-       struct ifaddr *ifa;
+       struct ifaddr_container *ifac;
+
+       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
 
-       TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
-       {
                if (ifa->ifa_addr == NULL)
                        continue;       /* just for safety */
                if (ifa->ifa_addr->sa_family != AF_INET6)
@@ -1773,8 +1777,10 @@ in6ifa_ifpwithaddr(struct ifnet *ifp, struct in6_addr *addr)
                if (IN6_ARE_ADDR_EQUAL(addr, IFA_IN6(ifa)))
                        break;
        }
-
-       return ((struct in6_ifaddr *)ifa);
+       if (ifac != NULL)
+               return ((struct in6_ifaddr *)(ifac->ifa));
+       else
+               return (NULL);
 }
 
 /*
@@ -1941,7 +1947,6 @@ in6_ifawithscope(struct ifnet *oifp, struct in6_addr *dst)
 {
        int dst_scope = in6_addrscope(dst), src_scope, best_scope = 0;
        int blen = -1;
-       struct ifaddr *ifa;
        struct ifnet *ifp;
        struct in6_ifaddr *ifa_best = NULL;
 
@@ -1959,6 +1964,8 @@ in6_ifawithscope(struct ifnet *oifp, struct in6_addr *dst)
         */
        for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list))
        {
+               struct ifaddr_container *ifac;
+
                /*
                 * We can never take an address that breaks the scope zone
                 * of the destination.
@@ -1966,9 +1973,9 @@ in6_ifawithscope(struct ifnet *oifp, struct in6_addr *dst)
                if (in6_addr2scopeid(ifp, dst) != in6_addr2scopeid(oifp, dst))
                        continue;
 
-               TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
-               {
+               TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
                        int tlen = -1, dscopecmp, bscopecmp, matchcmp;
+                       struct ifaddr *ifa = ifac->ifa;
 
                        if (ifa->ifa_addr->sa_family != AF_INET6)
                                continue;
@@ -2217,7 +2224,7 @@ struct in6_ifaddr *
 in6_ifawithifp(struct ifnet *ifp, struct in6_addr *dst)
 {
        int dst_scope = in6_addrscope(dst), blen = -1, tlen;
-       struct ifaddr *ifa;
+       struct ifaddr_container *ifac;
        struct in6_ifaddr *besta = 0;
        struct in6_ifaddr *dep[2];      /* last-resort: deprecated */
 
@@ -2229,8 +2236,9 @@ in6_ifawithifp(struct ifnet *ifp, struct in6_addr *dst)
         * If two or more, return one which matches the dst longest.
         * If none, return one of global addresses assigned other ifs.
         */
-       TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
-       {
+       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
+
                if (ifa->ifa_addr->sa_family != AF_INET6)
                        continue;
                if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST)
@@ -2264,8 +2272,9 @@ in6_ifawithifp(struct ifnet *ifp, struct in6_addr *dst)
        if (besta)
                return (besta);
 
-       TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
-       {
+       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
+
                if (ifa->ifa_addr->sa_family != AF_INET6)
                        continue;
                if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST)
@@ -2298,7 +2307,7 @@ in6_ifawithifp(struct ifnet *ifp, struct in6_addr *dst)
 void
 in6_if_up(struct ifnet *ifp)
 {
-       struct ifaddr *ifa;
+       struct ifaddr_container *ifac;
        struct in6_ifaddr *ia;
        int dad_delay;          /* delay ticks before DAD output */
 
@@ -2308,8 +2317,9 @@ in6_if_up(struct ifnet *ifp)
        in6_ifattach(ifp, NULL);
 
        dad_delay = 0;
-       TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
-       {
+       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
+
                if (ifa->ifa_addr->sa_family != AF_INET6)
                        continue;
                ia = (struct in6_ifaddr *)ifa;
index 798b0dd..57565df 100644 (file)
@@ -1,5 +1,5 @@
 /*     $FreeBSD: src/sys/netinet6/in6_ifattach.c,v 1.2.2.6 2002/04/28 05:40:26 suz Exp $       */
-/*     $DragonFly: src/sys/netinet6/in6_ifattach.c,v 1.21 2007/08/27 16:15:42 hasso Exp $      */
+/*     $DragonFly: src/sys/netinet6/in6_ifattach.c,v 1.22 2008/03/07 11:34:21 sephe Exp $      */
 /*     $KAME: in6_ifattach.c,v 1.118 2001/05/24 07:44:00 itojun Exp $  */
 
 /*
@@ -224,7 +224,7 @@ static int
 get_hw_ifid(struct ifnet *ifp,
            struct in6_addr *in6)       /* upper 64bits are preserved */
 {
-       struct ifaddr *ifa;
+       struct ifaddr_container *ifac;
        struct sockaddr_dl *sdl;
        u_int8_t *addr;
        size_t addrlen;
@@ -232,7 +232,9 @@ get_hw_ifid(struct ifnet *ifp,
        static u_int8_t allone[8] =
                { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 
-       TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
+       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
+
                if (ifa->ifa_addr->sa_family != AF_LINK)
                        continue;
                sdl = (struct sockaddr_dl *)ifa->ifa_addr;
@@ -772,7 +774,7 @@ void
 in6_ifdetach(struct ifnet *ifp)
 {
        struct in6_ifaddr *ia, *oia;
-       struct ifaddr *ifa, *next;
+       struct ifaddr_container *ifac, *next;
        struct rtentry *rt;
        short rtflags;
        struct sockaddr_in6 sin6;
@@ -786,15 +788,18 @@ in6_ifdetach(struct ifnet *ifp)
        nd6_purge(ifp);
 
        /* nuke any of IPv6 addresses we have */
-       TAILQ_FOREACH_MUTABLE(ifa, &ifp->if_addrlist, ifa_list, next)
-       {
+       TAILQ_FOREACH_MUTABLE(ifac, &ifp->if_addrheads[mycpuid], ifa_link, next) {
+               struct ifaddr *ifa = ifac->ifa;
+
                if (ifa->ifa_addr->sa_family != AF_INET6)
                        continue;
                in6_purgeaddr(ifa);
        }
 
        /* undo everything done by in6_ifattach(), just in case */
-       TAILQ_FOREACH_MUTABLE(ifa, &ifp->if_addrlist, ifa_list, next) {
+       TAILQ_FOREACH_MUTABLE(ifac, &ifp->if_addrheads[mycpuid], ifa_link, next) {
+               struct ifaddr *ifa = ifac->ifa;
+
                if (ifa->ifa_addr->sa_family != AF_INET6
                 || !IN6_IS_ADDR_LINKLOCAL(&satosin6(&ifa->ifa_addr)->sin6_addr)) {
                        continue;
@@ -815,8 +820,7 @@ in6_ifdetach(struct ifnet *ifp)
                }
 
                /* remove from the linked list */
-               TAILQ_REMOVE(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list);
-               IFAFREE(&ia->ia_ifa);
+               ifa_ifunlink((struct ifaddr *)ia, ifp);
 
                /* also remove from the IPv6 address chain(itojun&jinmei) */
                oia = ia;
@@ -834,7 +838,11 @@ in6_ifdetach(struct ifnet *ifp)
                        }
                }
 
-               IFAFREE(&oia->ia_ifa);
+               crit_enter();   /* XXX MP not MP safe */
+               _IFAFREE(&oia->ia_ifa, 0);
+               crit_exit();
+
+               ifa_destroy(&ia->ia_ifa);
        }
 
        /* leave from all multicast groups joined */
index 06e2d19..0099540 100644 (file)
@@ -1,5 +1,5 @@
 /*     $FreeBSD: src/sys/netinet6/in6_prefix.c,v 1.4.2.3 2001/07/03 11:01:52 ume Exp $ */
-/*     $DragonFly: src/sys/netinet6/in6_prefix.c,v 1.12 2008/01/05 14:02:40 swildner Exp $     */
+/*     $DragonFly: src/sys/netinet6/in6_prefix.c,v 1.13 2008/03/07 11:34:21 sephe Exp $        */
 /*     $KAME: in6_prefix.c,v 1.47 2001/03/25 08:41:39 itojun Exp $     */
 
 /*
@@ -178,6 +178,7 @@ static struct rr_prefix *
 search_matched_prefix(struct ifnet *ifp, struct in6_prefixreq *ipr)
 {
        struct ifprefix *ifpr;
+       struct ifaddr_container *ifac;
        struct ifaddr *ifa;
        struct rr_prefix *rpp;
 
@@ -192,15 +193,16 @@ search_matched_prefix(struct ifnet *ifp, struct in6_prefixreq *ipr)
         * which matches the addr
         */
 
-       TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
-       {
+       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+               ifa = ifac->ifa;
+
                if (ifa->ifa_addr->sa_family != AF_INET6)
                        continue;
                if (ipr->ipr_plen <=
                    in6_matchlen(&ipr->ipr_prefix.sin6_addr, IFA_IN6(ifa)))
                        break;
        }
-       if (ifa == NULL)
+       if (ifac == NULL)
                return NULL;
 
        rpp = ifpr2rp(((struct in6_ifaddr *)ifa)->ia6_ifpr);
@@ -232,8 +234,8 @@ search_matched_prefix(struct ifnet *ifp, struct in6_prefixreq *ipr)
 static int
 mark_matched_prefixes(u_long cmd, struct ifnet *ifp, struct in6_rrenumreq *irr)
 {
+       struct ifaddr_container *ifac;
        struct ifprefix *ifpr;
-       struct ifaddr *ifa;
        int matchlen, matched = 0;
 
        /* search matched prefixes */
@@ -259,8 +261,8 @@ mark_matched_prefixes(u_long cmd, struct ifnet *ifp, struct in6_rrenumreq *irr)
         * search matched addr, and then search prefixes
         * which matche the addr
         */
-       TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
-       {
+       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
                struct rr_prefix *rpp;
 
                if (ifa->ifa_addr->sa_family != AF_INET6)
@@ -402,11 +404,11 @@ assign_ra_entry(struct rr_prefix *rpp, int iilen, struct in6_ifaddr *ia)
                 sizeof(*IA6_IN6(ia)) << 3, rpp->rp_plen, iilen);
        /* link to ia, and put into list */
        rap->ra_addr = ia;
-       IFAREF(&rap->ra_addr->ia_ifa);
+       crit_enter();
+       _IFAREF(&rap->ra_addr->ia_ifa, 0);
 #if 0 /* Can't do this now, because rpp may be on th stack. should fix it? */
        ia->ia6_ifpr = rp2ifpr(rpp);
 #endif
-       crit_enter();
        LIST_INSERT_HEAD(&rpp->rp_addrhead, rap, ra_entry);
        crit_exit();
 
@@ -517,7 +519,9 @@ in6_prefix_add_ifid(int iilen, struct in6_ifaddr *ia)
        if (rap != NULL) {
                if (rap->ra_addr == NULL) {
                        rap->ra_addr = ia;
-                       IFAREF(&rap->ra_addr->ia_ifa);
+                       crit_enter();   /* XXX MP not MP safe */
+                       _IFAREF(&rap->ra_addr->ia_ifa, 0);
+                       crit_exit();
                } else if (rap->ra_addr != ia) {
                        /* There may be some inconsistencies between addrs. */
                        log(LOG_ERR, "ip6_prefix.c: addr %s/%d matched prefix"
@@ -547,9 +551,9 @@ in6_prefix_remove_ifid(int iilen, struct in6_ifaddr *ia)
        if (rap != NULL) {
                crit_enter();
                LIST_REMOVE(rap, ra_entry);
-               crit_exit();
                if (rap->ra_addr)
-                       IFAFREE(&rap->ra_addr->ia_ifa);
+                       _IFAFREE(&rap->ra_addr->ia_ifa, 0);
+               crit_exit();
                kfree(rap, M_RR_ADDR);
        }
 
@@ -612,19 +616,23 @@ add_each_addr(struct socket *so, struct rr_prefix *rpp, struct rp_addr *rap)
        ia6 = in6ifa_ifpwithaddr(rpp->rp_ifp, &ifra.ifra_addr.sin6_addr);
        if (ia6 != NULL) {
                if (ia6->ia6_ifpr == NULL) {
+                       crit_enter();   /* XXX MP not MP safe */
                        /* link this addr and the prefix each other */
                        if (rap->ra_addr)
-                               IFAFREE(&rap->ra_addr->ia_ifa);
+                               _IFAFREE(&rap->ra_addr->ia_ifa, 0);
                        rap->ra_addr = ia6;
-                       IFAREF(&rap->ra_addr->ia_ifa);
+                       _IFAREF(&rap->ra_addr->ia_ifa, 0);
+                       crit_exit();
                        ia6->ia6_ifpr = rp2ifpr(rpp);
                        return;
                }
                if (ia6->ia6_ifpr == rp2ifpr(rpp)) {
+                       crit_enter();   /* XXX MP not MP safe */
                        if (rap->ra_addr)
-                               IFAFREE(&rap->ra_addr->ia_ifa);
+                               _IFAFREE(&rap->ra_addr->ia_ifa, 0);
                        rap->ra_addr = ia6;
-                       IFAREF(&rap->ra_addr->ia_ifa);
+                       _IFAREF(&rap->ra_addr->ia_ifa, 0);
+                       crit_exit();
                        return;
                }
                /*
@@ -715,8 +723,11 @@ rrpr_update(struct socket *so, struct rr_prefix *new)
                        LIST_REMOVE(rap, ra_entry);
                        if (search_ifidwithprefix(rpp, &rap->ra_ifid)
                            != NULL) {
-                               if (rap->ra_addr)
-                                       IFAFREE(&rap->ra_addr->ia_ifa);
+                               if (rap->ra_addr) {
+                                       crit_enter();   /* XXX MP not MP safe */
+                                       _IFAFREE(&rap->ra_addr->ia_ifa, 0);
+                                       crit_exit();
+                               }
                                kfree(rap, M_RR_ADDR);
                                continue;
                        }
@@ -904,8 +915,11 @@ free_rp_entries(struct rr_prefix *rpp)
 
                rap = LIST_FIRST(&rpp->rp_addrhead);
                LIST_REMOVE(rap, ra_entry);
-               if (rap->ra_addr)
-                       IFAFREE(&rap->ra_addr->ia_ifa);
+               if (rap->ra_addr) {
+                       crit_enter();   /* XXX MP not MP safe */
+                       _IFAFREE(&rap->ra_addr->ia_ifa, 0);
+                       crit_exit();
+               }
                kfree(rap, M_RR_ADDR);
        }
 }
@@ -977,7 +991,9 @@ delete_each_prefix(struct rr_prefix *rpp, u_char origin)
                rap->ra_addr->ia6_ifpr = NULL;
 
                in6_purgeaddr(&rap->ra_addr->ia_ifa);
-               IFAFREE(&rap->ra_addr->ia_ifa);
+               crit_enter();   /* XXX MP not MP safe */
+               _IFAFREE(&rap->ra_addr->ia_ifa, 0);
+               crit_exit();
                kfree(rap, M_RR_ADDR);
        }
        rp_remove(rpp);
@@ -1005,9 +1021,10 @@ delete_prefixes(struct ifnet *ifp, u_char origin)
 static int
 link_stray_ia6s(struct rr_prefix *rpp)
 {
-       struct ifaddr *ifa;
+       struct ifaddr_container *ifac;
 
-       TAILQ_FOREACH(ifa, &rpp->rp_ifp->if_addrlist, ifa_list) {
+       TAILQ_FOREACH(ifac, &rpp->rp_ifp->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
                struct rp_addr *rap;
                struct rr_prefix *orpp;
                int error = 0;
@@ -1043,11 +1060,11 @@ int
 in6_prefix_ioctl(struct socket *so, u_long cmd, caddr_t data,
                 struct ifnet *ifp)
 {
+       struct ifaddr_container *ifac;
        struct rr_prefix *rpp, rp_tmp;
        struct rp_addr *rap;
        struct in6_prefixreq *ipr = (struct in6_prefixreq *)data;
        struct in6_rrenumreq *irr = (struct in6_rrenumreq *)data;
-       struct ifaddr *ifa;
        int error = 0;
 
        /*
@@ -1123,7 +1140,9 @@ in6_prefix_ioctl(struct socket *so, u_long cmd, caddr_t data,
                        free_rp_entries(&rp_tmp);
                        break;
                }
-               TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_list) {
+               TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_list) {
+                       struct ifaddr *ifa = ifac->ifa;
+
                        if (ifa->ifa_addr == NULL)
                                continue;       /* just for safety */
                        if (ifa->ifa_addr->sa_family != AF_INET6)
index 5e5ae97..ee47cf8 100644 (file)
@@ -1,5 +1,5 @@
 /*     $FreeBSD: src/sys/netinet6/in6_var.h,v 1.3.2.3 2002/04/28 05:40:27 suz Exp $    */
-/*     $DragonFly: src/sys/netinet6/in6_var.h,v 1.8 2007/08/16 20:03:58 dillon Exp $   */
+/*     $DragonFly: src/sys/netinet6/in6_var.h,v 1.9 2008/03/07 11:34:21 sephe Exp $    */
 /*     $KAME: in6_var.h,v 1.56 2001/03/29 05:34:31 itojun Exp $        */
 
 /*
@@ -494,14 +494,14 @@ MALLOC_DECLARE(M_IPMADDR);
 /* struct ifnet *ifp; */                               \
 /* struct in6_ifaddr *ia; */                           \
 do {                                                                   \
-       struct ifaddr *ifa;                                             \
-       TAILQ_FOREACH(ifa, &(ifp)->if_addrhead, ifa_list) {             \
-               if (!ifa->ifa_addr)                                     \
+       struct ifaddr_container *ifac;                                  \
+       TAILQ_FOREACH(ifac, &(ifp)->if_addrheads[mycpuid], ifa_list) {  \
+               if (!ifac->ifa->ifa_addr)                               \
                        continue;                                       \
-               if (ifa->ifa_addr->sa_family == AF_INET6)               \
+               if (ifac->ifa->ifa_addr->sa_family == AF_INET6)         \
                        break;                                          \
        }                                                               \
-       (ia) = (struct in6_ifaddr *)ifa;                                \
+       (ia) = ifac == NULL ? NULL : (struct in6_ifaddr *)(ifac->ifa);  \
 } while (0)
 
 #endif /* _KERNEL */
index 784f4f5..aafa7ec 100644 (file)
@@ -1,5 +1,5 @@
 /*     $FreeBSD: src/sys/netinet6/nd6.c,v 1.2.2.15 2003/05/06 06:46:58 suz Exp $       */
-/*     $DragonFly: src/sys/netinet6/nd6.c,v 1.26 2008/01/05 14:02:40 swildner Exp $    */
+/*     $DragonFly: src/sys/netinet6/nd6.c,v 1.27 2008/03/07 11:34:21 sephe Exp $       */
 /*     $KAME: nd6.c,v 1.144 2001/05/24 07:44:00 itojun Exp $   */
 
 /*
@@ -628,12 +628,13 @@ static int
 regen_tmpaddr(struct in6_ifaddr *ia6) /* deprecated/invalidated temporary
                                         address */
 {
-       struct ifaddr *ifa;
+       struct ifaddr_container *ifac;
        struct ifnet *ifp;
        struct in6_ifaddr *public_ifa6 = NULL;
 
        ifp = ia6->ia_ifa.ifa_ifp;
-       TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_list) {
+       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
                struct in6_ifaddr *it6;
 
                if (ifa->ifa_addr->sa_family != AF_INET6)
@@ -866,7 +867,7 @@ nd6_lookup(struct in6_addr *addr6, int create, struct ifnet *ifp)
 int
 nd6_is_addr_neighbor(struct sockaddr_in6 *addr, struct ifnet *ifp)
 {
-       struct ifaddr *ifa;
+       struct ifaddr_container *ifac;
        int i;
 
 #define IFADDR6(a) ((((struct in6_ifaddr *)(a))->ia_addr).sin6_addr)
@@ -885,7 +886,9 @@ nd6_is_addr_neighbor(struct sockaddr_in6 *addr, struct ifnet *ifp)
         * If the address matches one of our addresses,
         * it should be a neighbor.
         */
-       TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
+       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
+
                if (ifa->ifa_addr->sa_family != AF_INET6)
                        next: continue;
 
index 79e1f2a..5aff021 100644 (file)
@@ -1,5 +1,5 @@
 /*     $FreeBSD: src/sys/netinet6/nd6_nbr.c,v 1.4.2.6 2003/01/23 21:06:47 sam Exp $    */
-/*     $DragonFly: src/sys/netinet6/nd6_nbr.c,v 1.22 2008/01/05 14:02:40 swildner Exp $        */
+/*     $DragonFly: src/sys/netinet6/nd6_nbr.c,v 1.23 2008/03/07 11:34:21 sephe Exp $   */
 /*     $KAME: nd6_nbr.c,v 1.86 2002/01/21 02:33:04 jinmei Exp $        */
 
 /*
@@ -1086,7 +1086,9 @@ nd6_dad_start(struct ifaddr *ifa,
         * (re)initialization.
         */
        dp->dad_ifa = ifa;
-       IFAREF(ifa);    /* just for safety */
+       crit_enter();   /* XXX MP not MP safe */
+       _IFAREF(ifa, 0);        /* just for safety */
+       crit_exit();
        dp->dad_count = ip6_dad_count;
        dp->dad_ns_icount = dp->dad_na_icount = 0;
        dp->dad_ns_ocount = dp->dad_ns_tcount = 0;
@@ -1127,7 +1129,9 @@ nd6_dad_stop(struct ifaddr *ifa)
        TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list);
        kfree(dp, M_IP6NDP);
        dp = NULL;
-       IFAFREE(ifa);
+       crit_enter();   /* XXX MP not MP safe */
+       _IFAFREE(ifa, 0);
+       crit_exit();
 }
 
 static void
@@ -1171,7 +1175,9 @@ nd6_dad_timer(struct ifaddr *ifa)
                TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list);
                kfree(dp, M_IP6NDP);
                dp = NULL;
-               IFAFREE(ifa);
+               crit_enter();   /* XXX MP not MP safe */
+               _IFAFREE(ifa, 0);
+               crit_exit();
                goto done;
        }
 
@@ -1249,7 +1255,7 @@ nd6_dad_timer(struct ifaddr *ifa)
                        TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list);
                        kfree(dp, M_IP6NDP);
                        dp = NULL;
-                       IFAFREE(ifa);
+                       _IFAFREE(ifa, 0);
                }
        }
 
@@ -1288,7 +1294,9 @@ nd6_dad_duplicated(struct ifaddr *ifa)
        TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list);
        kfree(dp, M_IP6NDP);
        dp = NULL;
-       IFAFREE(ifa);
+       crit_enter();   /* XXX MP not MP safe */
+       _IFAFREE(ifa, 0);
+       crit_exit();
 }
 
 static void
index 05362ec..78e4465 100644 (file)
@@ -1,5 +1,5 @@
 /*     $FreeBSD: src/sys/netinet6/nd6_rtr.c,v 1.2.2.5 2003/04/05 10:28:53 ume Exp $    */
-/*     $DragonFly: src/sys/netinet6/nd6_rtr.c,v 1.16 2008/01/05 14:02:40 swildner Exp $        */
+/*     $DragonFly: src/sys/netinet6/nd6_rtr.c,v 1.17 2008/03/07 11:34:21 sephe Exp $   */
 /*     $KAME: nd6_rtr.c,v 1.111 2001/04/27 01:37:15 jinmei Exp $       */
 
 /*
@@ -456,8 +456,13 @@ nd6_rtmsg(int cmd, struct rtentry *rt)
        info.rti_info[RTAX_DST] = rt_key(rt);
        info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
        info.rti_info[RTAX_NETMASK] = rt_mask(rt);
-       info.rti_info[RTAX_IFP] =
-               (struct sockaddr *)TAILQ_FIRST(&rt->rt_ifp->if_addrlist);
+       if (TAILQ_EMPTY(&rt->rt_ifp->if_addrheads[mycpuid])) {
+               info.rti_info[RTAX_IFP] = NULL;
+       } else {
+               info.rti_info[RTAX_IFP] =
+               (struct sockaddr *)
+               TAILQ_FIRST(&rt->rt_ifp->if_addrheads[mycpuid])->ifa;
+       }
        info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
 
        rt_missmsg(cmd, &info, rt->rt_flags, 0);
@@ -914,7 +919,7 @@ int
 prelist_update(struct nd_prefix *new, struct nd_defrouter *dr, struct mbuf *m)
 {
        struct in6_ifaddr *ia6 = NULL, *ia6_match = NULL;
-       struct ifaddr *ifa;
+       struct ifaddr_container *ifac;
        struct ifnet *ifp = new->ndpr_ifp;
        struct nd_prefix *pr;
        int error = 0;
@@ -1039,8 +1044,8 @@ prelist_update(struct nd_prefix *new, struct nd_defrouter *dr, struct mbuf *m)
         * form an address.  Note that even a manually configured address
         * should reject autoconfiguration of a new address.
         */
-       TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
-       {
+       TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
                struct in6_ifaddr *ifa6;
                int ifa_plen;
                u_int32_t storedlifetime;
@@ -1428,11 +1433,14 @@ nd6_prefix_onlink(struct nd_prefix *pr)
                                                      IN6_IFF_NOTREADY|
                                                      IN6_IFF_ANYCAST);
        if (ifa == NULL) {
+               struct ifaddr_container *ifac;
+
                /* XXX: freebsd does not have ifa_ifwithaf */
-               TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
-               {
-                       if (ifa->ifa_addr->sa_family == AF_INET6)
+               TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+                       if (ifac->ifa->ifa_addr->sa_family == AF_INET6) {
+                               ifa = ifac->ifa;
                                break;
+                       }
                }
                /* should we care about ia6_flags? */
        }
index d850d07..40c1109 100644 (file)
@@ -3,7 +3,7 @@
  * All Rights Reserved.
  *
  * $FreeBSD: src/sys/netatalk/aarp.c,v 1.12.2.2 2001/06/23 20:43:09 iedowse Exp $
- * $DragonFly: src/sys/netproto/atalk/aarp.c,v 1.21 2007/05/23 08:57:06 dillon Exp $
+ * $DragonFly: src/sys/netproto/atalk/aarp.c,v 1.22 2008/03/07 11:34:21 sephe Exp $
  */
 
 #include "opt_atalk.h"
@@ -290,7 +290,6 @@ static void
 at_aarpinput( struct arpcom *ac, struct mbuf *m)
 {
     struct ether_aarp  *ea;
-    struct ifaddr      *ifa;
     struct at_ifaddr   *aa = NULL;
     struct aarptab     *aat;
     struct ether_header        *eh;
@@ -324,12 +323,14 @@ at_aarpinput( struct arpcom *ac, struct mbuf *m)
        bcopy(ea->aarp_spnet, &spa.s_net, sizeof spa.s_net);
        bcopy(ea->aarp_tpnet, &tpa.s_net, sizeof tpa.s_net);
     } else {
+       struct ifaddr_container *ifac;
+
        /*
         * Since we don't know the net, we just look for the first
         * phase 1 address on the interface.
         */
-       TAILQ_FOREACH(ifa, &ac->ac_if.if_addrhead, ifa_link) {
-           aa = (struct at_ifaddr *)ifa;
+       TAILQ_FOREACH(ifac, &ac->ac_if.if_addrheads[mycpuid], ifa_link) {
+           aa = (struct at_ifaddr *)(ifac->ifa);
            if ( AA_SAT( aa )->sat_family == AF_APPLETALK &&
                    ( aa->aa_flags & AFA_PHASE2 ) == 0 ) {
                break;
@@ -517,7 +518,7 @@ aarpprobe(void *arg)
     struct mbuf                *m;
     struct ether_header        *eh;
     struct ether_aarp  *ea;
-    struct ifaddr      *ifa;
+    struct ifaddr_container *ifac;
     struct at_ifaddr   *aa = NULL;
     struct llc         *llc;
     struct sockaddr    sa;
@@ -529,8 +530,8 @@ aarpprobe(void *arg)
      * interface with the same address as we're looking for. If the
      * net is phase 2, generate an 802.2 and SNAP header.
      */
-    TAILQ_FOREACH(ifa, &ac->ac_if.if_addrhead, ifa_link) {
-       aa = (struct at_ifaddr *)ifa;
+    TAILQ_FOREACH(ifac, &ac->ac_if.if_addrheads[mycpuid], ifa_link) {
+       aa = (struct at_ifaddr *)(ifac->ifa);
        if ( AA_SAT( aa )->sat_family == AF_APPLETALK &&
                ( aa->aa_flags & AFA_PROBING )) {
            break;
index abd0fd5..eb2b8eb 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1990,1991 Regents of The University of Michigan.
  * All Rights Reserved.
  *
- * $DragonFly: src/sys/netproto/atalk/at_control.c,v 1.12 2006/12/22 23:57:53 swildner Exp $
+ * $DragonFly: src/sys/netproto/atalk/at_control.c,v 1.13 2008/03/07 11:34:21 sephe Exp $
  */
 
 #include <sys/param.h>
@@ -140,7 +140,7 @@ at_control(struct socket *so, u_long cmd, caddr_t data,
         * allocate a fresh one. 
         */
        if ( aa == (struct at_ifaddr *) 0 ) {
-           aa0 = kmalloc(sizeof(struct at_ifaddr), M_IFADDR, M_WAITOK | M_ZERO);
+           aa0 = ifa_create(sizeof(struct at_ifaddr), M_WAITOK);
            callout_init(&aa0->aa_ch);
            if (( aa = at_ifaddr ) != NULL ) {
                /*
@@ -162,12 +162,6 @@ at_control(struct socket *so, u_long cmd, caddr_t data,
            } else {
                at_ifaddr = aa0;
            }
-           /* 
-            * Don't Add a reference for the aa itself!
-            * I fell into this trap. IFAFREE tests for <=0
-            * not <= 1 like RTFREE
-            */
-           /* aa->aa_ifa.ifa_refcnt++; DON'T DO THIS!! */
            aa = aa0;
 
            /*
@@ -175,12 +169,7 @@ at_control(struct socket *so, u_long cmd, caddr_t data,
             * and link our new one on the end 
             */
            ifa = (struct ifaddr *)aa;
-           TAILQ_INSERT_TAIL(&ifp->if_addrhead, ifa, ifa_link);
-
-           /*
-            * Add a reference for the linking into the ifp_if_addrlist.
-            */
-           ifa->ifa_refcnt++;
+           ifa_iflink(ifa, ifp, 1);
 
            /*
             * As the at_ifaddr contains the actual sockaddrs,
@@ -282,13 +271,7 @@ at_control(struct socket *so, u_long cmd, caddr_t data,
         * remove the ifaddr from the interface
         */
        ifa0 = (struct ifaddr *)aa;
-       TAILQ_REMOVE(&ifp->if_addrhead, ifa0, ifa_link);
-
-       /*
-        * refs goes from 1->0 if no external refs. note.. 
-        * This will not free it ... looks for -1.
-        */
-       IFAFREE(ifa0);
+       ifa_ifunlink(ifa0, ifp);
 
        /*
         * Now remove the at_ifaddr from the parallel structure
@@ -316,10 +299,10 @@ at_control(struct socket *so, u_long cmd, caddr_t data,
         * Now dump the memory we were using.
         * Decrement the reference count.
         * This should probably be the last reference
-        * as the count will go from 0 to -1.
+        * as the count will go from 1 to 0.
         * (unless there is still a route referencing this)
         */
-       IFAFREE(ifa0);
+       ifa_destroy(ifa0);
        break;
 
     default:
@@ -817,37 +800,6 @@ aa_dosingleroute(struct ifaddr *ifa,
        (struct sockaddr *) &mask, flags, NULL));
 }
 
-#if 0
-
-static void
-aa_clean(void)
-{
-    struct at_ifaddr   *aa;
-    struct ifaddr      *ifa;
-    struct ifnet       *ifp;
-
-    while ( aa = at_ifaddr ) {
-       ifp = aa->aa_ifp;
-       at_scrub( ifp, aa );
-       at_ifaddr = aa->aa_next;
-       if (( ifa = ifp->if_addrlist ) == (struct ifaddr *)aa ) {
-           ifp->if_addrlist = ifa->ifa_next;
-       } else {
-           while ( ifa->ifa_next &&
-                   ( ifa->ifa_next != (struct ifaddr *)aa )) {
-               ifa = ifa->ifa_next;
-           }
-           if ( ifa->ifa_next ) {
-               ifa->ifa_next = ((struct ifaddr *)aa)->ifa_next;
-           } else {
-               panic( "at_entry" );
-           }
-       }
-    }
-}
-
-#endif
-
 static int
 aa_claim_addr(struct ifaddr *ifa, struct sockaddr *gw0)
 {
index 203bc2e..1272bc1 100644 (file)
@@ -24,7 +24,7 @@
  * notice must be reproduced on all copies.
  *
  *     @(#) $FreeBSD: src/sys/netatm/atm_if.c,v 1.5 1999/08/28 00:48:35 peter Exp $
- *     @(#) $DragonFly: src/sys/netproto/atm/atm_if.c,v 1.15 2006/12/20 18:14:43 dillon Exp $
+ *     @(#) $DragonFly: src/sys/netproto/atm/atm_if.c,v 1.16 2008/03/07 11:34:21 sephe Exp $
  */
 
 /*
@@ -808,11 +808,11 @@ atm_nif_detach(struct atm_nif *nip)
 
                /* Remove interface address from queues */
                ifa = &ia->ia_ifa;
-               TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link);
+               ifa_ifunlink(ifa, ifp);
                TAILQ_REMOVE(&in_ifaddrhead, ia, ia_link);
 
                /* Free interface address */
-               IFAFREE(ifa);
+               ifa_destroy(ifa);
        }
 
        /*
index 5453126..708d2a7 100644 (file)
@@ -34,7 +34,7 @@
  *     @(#)ipx.c
  *
  * $FreeBSD: src/sys/netipx/ipx.c,v 1.17.2.3 2003/04/04 09:35:43 tjr Exp $
- * $DragonFly: src/sys/netproto/ipx/ipx.c,v 1.14 2008/01/06 16:55:52 swildner Exp $
+ * $DragonFly: src/sys/netproto/ipx/ipx.c,v 1.15 2008/03/07 11:34:21 sephe Exp $
  */
 
 #include <sys/param.h>
@@ -127,9 +127,7 @@ ipx_control(struct socket *so, u_long cmd, caddr_t data,
        case SIOCSIFADDR:
        case SIOCSIFDSTADDR:
                if (ia == NULL) {
-                       oia = (struct ipx_ifaddr *)
-                               kmalloc(sizeof(*ia), M_IFADDR,
-                               M_WAITOK | M_ZERO);
+                       oia = ifa_create(sizeof(*ia), M_WAITOK);
                        if ((ia = ipx_ifaddr) != NULL) {
                                for ( ; ia->ia_next != NULL; ia = ia->ia_next)
                                        ;
@@ -138,7 +136,7 @@ ipx_control(struct socket *so, u_long cmd, caddr_t data,
                                ipx_ifaddr = oia;
                        ia = oia;
                        ifa = (struct ifaddr *)ia;
-                       TAILQ_INSERT_TAIL(&ifp->if_addrhead, ifa, ifa_link);
+                       ifa_iflink(ifa, ifp, 1);
                        ia->ia_ifp = ifp;
                        ifa->ifa_addr = (struct sockaddr *)&ia->ia_addr;
 
@@ -180,7 +178,7 @@ ipx_control(struct socket *so, u_long cmd, caddr_t data,
        case SIOCDIFADDR:
                ipx_ifscrub(ifp, ia);
                ifa = (struct ifaddr *)ia;
-               TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link);
+               ifa_ifunlink(ifa, ifp);
                oia = ia;
                if (oia == (ia = ipx_ifaddr)) {
                        ipx_ifaddr = ia->ia_next;
@@ -193,7 +191,7 @@ ipx_control(struct socket *so, u_long cmd, caddr_t data,
                        else
                                kprintf("Didn't unlink ipxifadr from list\n");
                }
-               IFAFREE((&oia->ia_ifa));
+               ifa_destroy(&oia->ia_ifa);
                return (0);
        
        case SIOCAIFADDR:
index 0c58e7a..a8699ce 100644 (file)
@@ -34,7 +34,7 @@
  *     @(#)ipx_input.c
  *
  * $FreeBSD: src/sys/netipx/ipx_input.c,v 1.22.2.2 2001/02/22 09:44:18 bp Exp $
- * $DragonFly: src/sys/netproto/ipx/ipx_input.c,v 1.17 2007/11/16 05:07:36 sephe Exp $
+ * $DragonFly: src/sys/netproto/ipx/ipx_input.c,v 1.18 2008/03/07 11:34:21 sephe Exp $
  */
 
 #include <sys/param.h>
@@ -457,8 +457,8 @@ void
 ipx_watch_output(struct mbuf *m, struct ifnet *ifp)
 {
        struct ipxpcb *ipxp;
-       struct ifaddr *ifa;
        struct ipx_ifaddr *ia;
+
        /*
         * Give any raw listeners a crack at the packet
         */
@@ -482,13 +482,19 @@ ipx_watch_output(struct mbuf *m, struct ifnet *ifp)
                                ipx->ipx_sna.x_host =
                                    ia->ia_addr.sipx_addr.x_host;
 
-                       if (ifp != NULL && (ifp->if_flags & IFF_POINTOPOINT))
-                           TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+                       if (ifp != NULL && (ifp->if_flags & IFF_POINTOPOINT)) {
+                           struct ifaddr_container *ifac;
+
+                           TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid],
+                                         ifa_link) {
+                               struct ifaddr *ifa = ifac->ifa;
+
                                if (ifa->ifa_addr->sa_family == AF_IPX) {
                                    ipx->ipx_sna = IA_SIPX(ifa)->sipx_addr;
                                    break;
                                }
                            }
+                       }
                        ipx->ipx_len = ntohl(m0->m_pkthdr.len);
                        ipx_input(m0, ipxp);
                }
index f3ad748..fcda47e 100644 (file)
@@ -34,7 +34,7 @@
  *     @(#)ipx_usrreq.c
  *
  * $FreeBSD: src/sys/netipx/ipx_usrreq.c,v 1.26.2.1 2001/02/22 09:44:18 bp Exp $
- * $DragonFly: src/sys/netproto/ipx/ipx_usrreq.c,v 1.12 2007/04/22 01:13:15 dillon Exp $
+ * $DragonFly: src/sys/netproto/ipx/ipx_usrreq.c,v 1.13 2008/03/07 11:34:21 sephe Exp $
  */
 
 #include "opt_ipx.h"
@@ -157,10 +157,11 @@ ipx_input(struct mbuf *m, struct ipxpcb *ipxp)
        ipx_ipx.sipx_zero[0] = '\0';
        ipx_ipx.sipx_zero[1] = '\0';
        if (ipx_neteqnn(ipx->ipx_sna.x_net, ipx_zeronet) && ifp != NULL) {
-               struct ifaddr *ifa;
+               struct ifaddr_container *ifac;
+
+               TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+                       struct ifaddr *ifa = ifac->ifa;
 
-               for (ifa = TAILQ_FIRST(&ifp->if_addrhead); ifa != NULL; 
-                    ifa = TAILQ_NEXT(ifa, ifa_link)) {
                        if (ifa->ifa_addr->sa_family == AF_IPX) {
                                ipx_ipx.sipx_addr.x_net =
                                        IA_SIPX(ifa)->sipx_addr.x_net;
index 7521791..c5f4d69 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)idp_usrreq.c        8.1 (Berkeley) 6/10/93
  * $FreeBSD: src/sys/netns/idp_usrreq.c,v 1.9 1999/08/28 00:49:47 peter Exp $
- * $DragonFly: src/sys/netproto/ns/idp_usrreq.c,v 1.14 2007/04/22 01:13:16 dillon Exp $
+ * $DragonFly: src/sys/netproto/ns/idp_usrreq.c,v 1.15 2008/03/07 11:34:21 sephe Exp $
  */
 
 #include <sys/param.h>
@@ -91,16 +91,17 @@ idp_input(struct mbuf *m, ...)
         */
        idp_ns.sns_addr = idp->idp_sna;
        if (ns_neteqnn(idp->idp_sna.x_net, ns_zeronet) && ifp) {
-               struct ifaddr *ifa;
+               struct ifaddr_container *ifac;
+
+               TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+                       struct ifaddr *ifa = ifac->ifa;
 
-               crit_enter();
-               TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
                        if (ifa->ifa_addr->sa_family == AF_NS) {
                                idp_ns.sns_addr.x_net =
                                        IA_SNS(ifa)->sns_addr.x_net;
                                break;
                        }
-               crit_exit();
+               }
        }
        nsp->nsp_rpt = idp->idp_pt;
        if ( ! (nsp->nsp_flags & NSP_RAWIN) ) {
index 8c46eed..182d796 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)ns.c        8.2 (Berkeley) 11/15/93
  * $FreeBSD: src/sys/netns/ns.c,v 1.9 1999/08/28 00:49:47 peter Exp $
- * $DragonFly: src/sys/netproto/ns/ns.c,v 1.16 2008/01/06 16:55:52 swildner Exp $
+ * $DragonFly: src/sys/netproto/ns/ns.c,v 1.17 2008/03/07 11:34:21 sephe Exp $
  */
 
 #include <sys/param.h>
@@ -72,7 +72,6 @@ ns_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
        struct ifreq *ifr = (struct ifreq *)data;
        struct ns_aliasreq *ifra = (struct ns_aliasreq *)data;
        struct ns_ifaddr *ia;
-       struct ifaddr *ifa = NULL; /* XXX used ininitialized ?*/
        struct ns_ifaddr *oia;
        int dstIsNew, hostIsNew;
        int error = 0; /* initalize because of scoping */
@@ -134,8 +133,7 @@ ns_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
        case SIOCSIFADDR:
        case SIOCSIFDSTADDR:
                if (ia == (struct ns_ifaddr *)0) {
-                       oia = (struct ns_ifaddr *)
-                               kmalloc(sizeof *ia, M_IFADDR, M_WAITOK | M_ZERO);
+                       oia = ifa_create(sizeof(*ia), M_WAITOK);
                        if ((ia = ns_ifaddr) != NULL) {
                                for ( ; ia->ia_next; ia = ia->ia_next)
                                        ;
@@ -144,7 +142,7 @@ ns_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
                                ns_ifaddr = oia;
                        ia = oia;
 
-                       TAILQ_INSERT_TAIL(&ifp->if_addrhead, ifa, ifa_link);
+                       ifa_iflink(&ia->ia_ifa, ifp, 1);
                        ia->ia_ifp = ifp;
                        ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
 
@@ -190,7 +188,7 @@ ns_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
                ns_ifscrub(ifp, (struct ns_ifaddr *)ia);
                /* XXX not on list */
                oia = ia;
-               TAILQ_REMOVE(&ifp->if_addrhead, (struct ifaddr *)ia, ifa_link);
+               ifa_ifunlink(&ia->ia_ifa, ifp);
                 if (oia == (ia = ns_ifaddr)) {
                         ns_ifaddr = ia->ia_next;
                 } else {
@@ -202,7 +200,7 @@ ns_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
                         else
                                 kprintf("Didn't unlink nsifadr from list\n");
                 }
-               IFAFREE((&oia->ia_ifa));
+               ifa_destroy(&oia->ia_ifa);
                if (0 == --ns_interfaces) {
                        /*
                         * We reset to virginity and start all over again
index b7c890b..e2fb775 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)ns_input.c  8.1 (Berkeley) 6/10/93
  * $FreeBSD: src/sys/netns/ns_input.c,v 1.13 2000/02/13 03:32:04 peter Exp $
- * $DragonFly: src/sys/netproto/ns/ns_input.c,v 1.20 2007/05/23 08:57:08 dillon Exp $
+ * $DragonFly: src/sys/netproto/ns/ns_input.c,v 1.21 2008/03/07 11:34:21 sephe Exp $
  */
 
 #include <sys/param.h>
@@ -452,7 +452,6 @@ void
 ns_watch_output(struct mbuf *m, struct ifnet *ifp)
 {
        struct nspcb *nsp;
-       struct ifaddr *ifa;
        /*
         * Give any raw listeners a crack at the packet
         */
@@ -467,12 +466,19 @@ ns_watch_output(struct mbuf *m, struct ifnet *ifp)
                        idp = mtod(m0, struct idp *);
                        idp->idp_sna.x_net = ns_zeronet;
                        idp->idp_sna.x_host = ns_thishost;
-                       if (ifp && (ifp->if_flags & IFF_POINTOPOINT))
-                               TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
-                               if (ifa->ifa_addr->sa_family==AF_NS) {
-                                   idp->idp_sna = IA_SNS(ifa)->sns_addr;
-                                   break;
+                       if (ifp && (ifp->if_flags & IFF_POINTOPOINT)) {
+                               struct ifaddr_container *ifac;
+
+                               TAILQ_FOREACH(ifac,
+                               &ifp->if_addrheads[mycpuid], ifa_link) {
+                                       struct ifaddr *ifa = ifac->ifa;
+
+                                       if (ifa->ifa_addr->sa_family==AF_NS) {
+                                               idp->idp_sna = IA_SNS(ifa)->sns_addr;
+                                               break;
+                                       }
                                }
+                       }
                        idp->idp_len = ntohl(m0->m_pkthdr.len);
                        idp_input(m0, nsp);
                }
index a2c1f75..03fcd36 100644 (file)
@@ -35,7 +35,7 @@
  *
  *     from: @(#)autoconf.c    7.1 (Berkeley) 5/9/91
  * $FreeBSD: src/sys/i386/i386/autoconf.c,v 1.146.2.2 2001/06/07 06:05:58 dd Exp $
- * $DragonFly: src/sys/platform/pc32/i386/autoconf.c,v 1.38 2007/06/17 23:50:16 dillon Exp $
+ * $DragonFly: src/sys/platform/pc32/i386/autoconf.c,v 1.39 2008/03/07 11:34:21 sephe Exp $
  */
 
 /*
@@ -420,7 +420,6 @@ pxe_setup_nfsdiskless(void)
 {
        struct nfs_diskless     *nd = &nfs_diskless;
        struct ifnet            *ifp;
-       struct ifaddr           *ifa;
        struct sockaddr_dl      *sdl, ourdl;
        struct sockaddr_in      myaddr, netmask;
        char                    *cp;
@@ -442,10 +441,13 @@ pxe_setup_nfsdiskless(void)
                kprintf("PXE: no hardware address\n");
                return;
        }
-       ifa = NULL;
        ifp = TAILQ_FIRST(&ifnet);
        TAILQ_FOREACH(ifp, &ifnet, if_link) {
-               TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+               struct ifaddr_container *ifac;
+
+               TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
+                       struct ifaddr *ifa = ifac->ifa;
+
                        if ((ifa->ifa_addr->sa_family == AF_LINK) &&
                            (sdl = ((struct sockaddr_dl *)ifa->ifa_addr))) {
                                if ((sdl->sdl_type == ourdl.sdl_type) &&
index cc82c36..9693d08 100644 (file)
@@ -40,7 +40,7 @@
  *
  *     @(#)kernel.h    8.3 (Berkeley) 1/21/94
  * $FreeBSD: src/sys/sys/kernel.h,v 1.63.2.9 2002/07/02 23:00:30 archie Exp $
- * $DragonFly: src/sys/sys/kernel.h,v 1.29 2007/07/28 23:24:32 dillon Exp $
+ * $DragonFly: src/sys/sys/kernel.h,v 1.30 2008/03/07 11:34:21 sephe Exp $
  */
 
 #ifndef _SYS_KERNEL_H_
@@ -149,6 +149,7 @@ enum sysinit_sub_id {
         * Continue with miscellanious system initialization
         */
        SI_SUB_CREATE_INIT      = 0x2300000,    /* create the init process */
+       SI_SUB_PRE_DRIVERS      = 0x2380000,
        SI_SUB_DRIVERS          = 0x2400000,    /* Let Drivers initialize */
        SI_SUB_CONFIGURE        = 0x3800000,    /* Configure devices */
        SI_SUB_ISWARM           = 0x3c00000,    /* No longer in cold boot */
index 90e2a8f..3e43c69 100644 (file)
@@ -38,7 +38,7 @@
  * nfs/krpc_subr.c
  * $NetBSD: krpc_subr.c,v 1.10 1995/08/08 20:43:43 gwr Exp $
  * $FreeBSD: src/sys/nfs/bootp_subr.c,v 1.20.2.9 2003/04/24 16:51:08 ambrisko Exp $
- * $DragonFly: src/sys/vfs/nfs/bootp_subr.c,v 1.24 2008/01/06 16:55:53 swildner Exp $
+ * $DragonFly: src/sys/vfs/nfs/bootp_subr.c,v 1.25 2008/03/07 11:34:21 sephe Exp $
  */
 
 #include "opt_bootp.h"
@@ -967,12 +967,12 @@ bootpc_fakeup_interface(struct bootpc_ifcontext *ifctx,
                        struct bootpc_globalcontext *gctx,
                        struct thread *td)
 {
+       struct ifaddr_container *ifac;
        struct sockaddr_in *sin;
        int error;
        
        struct ifreq *ireq;
        struct socket *so;
-       struct ifaddr *ifa;
        struct sockaddr_dl *sdl;
 
        error = socreate(AF_INET, &ifctx->so, SOCK_DGRAM, 0, td);
@@ -1038,12 +1038,15 @@ bootpc_fakeup_interface(struct bootpc_ifcontext *ifctx,
        /* Get HW address */
        
        sdl = NULL;
-       TAILQ_FOREACH(ifa, &ifctx->ifp->if_addrhead, ifa_link)
+       TAILQ_FOREACH(ifac, &ifctx->ifp->if_addrheads[mycpuid], ifa_link) {
+               struct ifaddr *ifa = ifac->ifa;
+
                if (ifa->ifa_addr->sa_family == AF_LINK &&
                    (sdl = ((struct sockaddr_dl *) ifa->ifa_addr)) != NULL &&
                    sdl->sdl_type == IFT_ETHER)
                        break;
-       
+       }
+
        if (sdl == NULL)
                panic("bootpc: Unable to find HW address for %s",
                      ifctx->ireq.ifr_name);
index b8d3700..3864a3f 100644 (file)
@@ -32,7 +32,7 @@
  *
  * @(#)if.c    8.3 (Berkeley) 4/28/95
  * $FreeBSD: src/usr.bin/netstat/if.c,v 1.32.2.9 2001/09/17 14:35:46 ru Exp $
- * $DragonFly: src/usr.bin/netstat/if.c,v 1.11 2006/08/03 16:40:48 swildner Exp $
+ * $DragonFly: src/usr.bin/netstat/if.c,v 1.12 2008/03/07 11:34:21 sephe Exp $
  */
 
 #include <sys/param.h>
@@ -107,6 +107,7 @@ void
 intpr(int interval, u_long ifnetaddr, void (*pfunc)(char *))
 {
        struct ifnet ifnet;
+       struct ifaddr_container ifac;
        struct ifnethead ifnethead;
        union {
                struct ifaddr ifa;
@@ -123,6 +124,7 @@ intpr(int interval, u_long ifnetaddr, void (*pfunc)(char *))
 #endif
        } ifaddr;
        u_long ifaddraddr;
+       u_long ifaddrcont_addr;
        u_long ifaddrfound;
        u_long ifnetfound;
        u_long opackets;
@@ -181,6 +183,8 @@ intpr(int interval, u_long ifnetaddr, void (*pfunc)(char *))
                link_layer = 0;
 
                if (ifaddraddr == 0) {
+                       struct ifaddrhead head;
+
                        ifnetfound = ifnetaddr;
                        if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet))
                                return;
@@ -198,7 +202,21 @@ intpr(int interval, u_long ifnetaddr, void (*pfunc)(char *))
                        if ((ifnet.if_flags&IFF_UP) == 0)
                                *cp++ = '*';
                        *cp = '\0';
-                       ifaddraddr = (u_long)TAILQ_FIRST(&ifnet.if_addrhead);
+
+                       if (kread((u_long)ifnet.if_addrheads,
+                                 (char *)&head, sizeof(head)))
+                               return;
+
+                       ifaddrcont_addr =
+                               (u_long)TAILQ_FIRST(&head);
+                       if (ifaddrcont_addr == 0) {
+                               ifaddraddr = 0;
+                       } else {
+                               if (kread(ifaddrcont_addr, (char *)&ifac,
+                                         sizeof(ifac)))
+                                       return;
+                               ifaddraddr = (u_long)ifac.ifa;
+                       }
                }
                ifaddrfound = ifaddraddr;
 
@@ -230,8 +248,18 @@ intpr(int interval, u_long ifnetaddr, void (*pfunc)(char *))
                                CP(&ifaddr);
                        sa = (struct sockaddr *)cp;
                        if (af != AF_UNSPEC && sa->sa_family != af) {
-                               ifaddraddr =
-                                   (u_long)TAILQ_NEXT(&ifaddr.ifa, ifa_link);
+                               ifaddrcont_addr =
+                                       (u_long)TAILQ_NEXT(&ifac, ifa_link);
+                               if (ifaddrcont_addr == 0) {
+                                       ifaddraddr = 0;
+                               } else {
+                                       if (kread(ifaddrcont_addr,
+                                           (char *)&ifac, sizeof(ifac))) {
+                                               ifaddraddr = 0;
+                                               continue;
+                                       }
+                                       ifaddraddr = (u_long)ifac.ifa;
+                               }
                                continue;
                        }
                        printf("%-7.7s %-5lu ", name, ifnet.if_mtu);
@@ -351,7 +379,18 @@ intpr(int interval, u_long ifnetaddr, void (*pfunc)(char *))
                                ibytes = ifaddr.in.ia_ifa.if_ibytes;
                        }
 
-                       ifaddraddr = (u_long)TAILQ_NEXT(&ifaddr.ifa, ifa_link);
+                       ifaddrcont_addr =
+                               (u_long)TAILQ_NEXT(&ifac, ifa_link);
+                       if (ifaddrcont_addr == 0) {
+                               ifaddraddr = 0;
+                       } else {
+                               if (kread(ifaddrcont_addr,
+                                   (char *)&ifac, sizeof(ifac))) {
+                                       ifaddraddr = 0;
+                               } else {
+                                       ifaddraddr = (u_long)ifac.ifa;
+                               }
+                       }
                }
 
                show_stat("lu", 8, ipackets, link_layer|network_layer);
index e77addc..48071e4 100644 (file)
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/usr.sbin/ifmcstat/ifmcstat.c,v 1.3.2.2 2001/07/03 11:02:06 ume Exp $
- * $DragonFly: src/usr.sbin/ifmcstat/ifmcstat.c,v 1.8 2005/10/30 23:00:57 swildner Exp $
+ * $DragonFly: src/usr.sbin/ifmcstat/ifmcstat.c,v 1.9 2008/03/07 11:34:21 sephe Exp $
  */
 
 #define _KERNEL_STRUCTURES
@@ -67,7 +67,7 @@ const char *inet6_n2a(struct in6_addr *);
 int main(int, char **);
 char *ifname(struct ifnet *);
 void kread(u_long, void *, int);
-void if6_addrlist(struct ifaddr *);
+void if6_addrlist(struct ifaddr_container *);
 void in6_multilist(struct in6_multi *);
 struct in6_multi * in6_multientry(struct in6_multi *);
 
@@ -134,10 +134,20 @@ main(int argc __unused, char **argv __unused)
        }
        KREAD(nl[N_IFNET].n_value, &ifp, struct ifnet *);
        while (ifp) {
+               struct ifaddrhead head;
+               struct ifaddr_container ifac, *ifacp = NULL;
+
                KREAD(ifp, &ifnet, struct ifnet);
                printf("%s:\n", if_indextoname(ifnet.if_index, ifname));
 
-               if6_addrlist(TAILQ_FIRST(&ifnet.if_addrhead));
+               KREAD(ifnet.if_addrheads, &head, struct ifaddrhead);
+               if (TAILQ_FIRST(&head) != NULL) {
+                       KREAD(TAILQ_FIRST(&head), &ifac,
+                             struct ifaddr_container);
+                       ifacp = &ifac;
+               }
+
+               if6_addrlist(ifacp);
                nifp = ifnet.if_link.tqe_next;
 
                /* not supported */
@@ -170,14 +180,20 @@ kread(u_long addr, void *buf, int len)
 }
 
 void
-if6_addrlist(struct ifaddr *ifap)
+if6_addrlist(struct ifaddr_container *ifac)
 {
+       struct ifaddr *ifap;
        struct ifaddr ifa;
        struct sockaddr sa;
        struct in6_ifaddr if6a;
        struct in6_multi *mc = 0;
        struct ifaddr *ifap0;
 
+       if (ifac != NULL)
+               ifap = ifac->ifa;
+       else
+               ifap = NULL;
+
        ifap0 = ifap;
        while (ifap) {
                KREAD(ifap, &ifa, struct ifaddr);
@@ -189,7 +205,13 @@ if6_addrlist(struct ifaddr *ifap)
                KREAD(ifap, &if6a, struct in6_ifaddr);
                printf("\tinet6 %s\n", inet6_n2a(&if6a.ia_addr.sin6_addr));
        nextifap:
-               ifap = ifa.ifa_link.tqe_next;
+               if (TAILQ_NEXT(ifac, ifa_link) == NULL) {
+                       ifap = NULL;
+               } else {
+                       KREAD(TAILQ_NEXT(ifac, ifa_link), ifac,
+                             struct ifaddr_container);
+                       ifap = ifac->ifa;
+               }
        }
        if (ifap0) {
                struct ifnet ifnet;