Parallelize in_ifaddrhead operation
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Sun, 8 Jun 2008 08:38:06 +0000 (08:38 +0000)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Sun, 8 Jun 2008 08:38:06 +0000 (08:38 +0000)
18 files changed:
sys/net/if_var.h
sys/net/stf/if_stf.c
sys/netinet/igmp.c
sys/netinet/in.c
sys/netinet/in_gif.c
sys/netinet/in_pcb.c
sys/netinet/in_var.h
sys/netinet/ip_carp.c
sys/netinet/ip_input.c
sys/netinet/ip_output.c
sys/netinet/raw_ip.c
sys/netproto/atm/atm_if.c
sys/netproto/atm/ipatm/ipatm_load.c
sys/netproto/atm/ipatm/ipatm_output.c
sys/netproto/ipsec/key.c
sys/netproto/ipx/ipx_ip.c
sys/netproto/key/key.c
sys/vfs/nfs/nfs_vnops.c

index 39840b2..f9b8210 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.55 2008/06/07 07:22:22 sephe Exp $
+ * $DragonFly: src/sys/net/if_var.h,v 1.56 2008/06/08 08:38:05 sephe Exp $
  */
 
 #ifndef        _NET_IF_VAR_H_
@@ -363,6 +363,17 @@ if_handoff(struct ifqueue *_ifq, struct mbuf *_m, struct ifnet *_ifp,
 
 #endif /* _KERNEL */
 
+struct in_ifaddr;
+
+struct in_ifaddr_container {
+       struct in_ifaddr        *ia;
+       LIST_ENTRY(in_ifaddr_container) ia_hash;
+                               /* entry in bucket of inet addresses */
+       TAILQ_ENTRY(in_ifaddr_container) ia_link;
+                               /* list of internet addresses */
+       struct ifaddr_container *ia_ifac; /* parent ifaddr_container */
+};
+
 struct ifaddr_container {
 #define IFA_CONTAINER_MAGIC    0x19810219
 #define IFA_CONTAINER_DEAD     0xc0dedead
@@ -371,9 +382,17 @@ struct ifaddr_container {
        TAILQ_ENTRY(ifaddr_container)   ifa_link;   /* queue macro glue */
        u_int                   ifa_refcnt; /* references to this structure */
        uint32_t                ifa_listmask;   /* IFA_LIST_ */
+
+       /*
+        * Protocol specific states
+        */
+       union {
+               struct in_ifaddr_container u_in_ifac;
+       } ifa_proto_u;
 };
 
 #define IFA_LIST_IFADDRHEAD    0x1     /* on ifnet.if_addrheads[cpuid] */
+#define IFA_LIST_IN_IFADDRHEAD 0x2     /* on in_ifaddrheads[cpuid] */
 
 /*
  * The ifaddr structure contains information about one address
index 1419b57..907aad9 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.22 2008/05/14 11:59:24 sephe Exp $     */
+/*     $DragonFly: src/sys/net/stf/if_stf.c,v 1.23 2008/06/08 08:38:05 sephe Exp $     */
 /*     $KAME: if_stf.c,v 1.73 2001/12/03 11:08:30 keiichi Exp $        */
 
 /*
@@ -424,7 +424,7 @@ stf_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
 static int
 stf_checkaddr4(struct stf_softc *sc, struct in_addr *in, struct ifnet *inifp)
 {
-       struct in_ifaddr *ia4;
+       struct in_ifaddr_container *iac;
 
        /*
         * reject packets with the following address:
@@ -440,8 +440,9 @@ stf_checkaddr4(struct stf_softc *sc, struct in_addr *in, struct ifnet *inifp)
        /*
         * reject packets with broadcast
         */
-       TAILQ_FOREACH(ia4, &in_ifaddrhead, ia_link)
-       {
+       TAILQ_FOREACH(iac, &in_ifaddrheads[mycpuid], ia_link) {
+               struct in_ifaddr *ia4 = iac->ia;
+
                if ((ia4->ia_ifa.ifa_ifp->if_flags & IFF_BROADCAST) == 0)
                        continue;
                if (in->s_addr == ia4->ia_broadaddr.sin_addr.s_addr)
index ac63be9..7179b26 100644 (file)
@@ -36,7 +36,7 @@
  *
  *     @(#)igmp.c      8.1 (Berkeley) 7/19/93
  * $FreeBSD: src/sys/netinet/igmp.c,v 1.29.2.2 2003/01/23 21:06:44 sam Exp $
- * $DragonFly: src/sys/netinet/igmp.c,v 1.13 2006/12/22 23:57:52 swildner Exp $
+ * $DragonFly: src/sys/netinet/igmp.c,v 1.14 2008/06/08 08:38:05 sephe Exp $
  */
 
 /*
@@ -299,7 +299,7 @@ igmp_input(struct mbuf *m, ...)
                 * can potentially get looped back if we are a multicast
                 * router, so discard reports sourced by me.
                 */
-               IFP_TO_IA(ifp, ia);
+               ia = IFP_TO_IA(ifp);
                if (ia && ip->ip_src.s_addr == IA_SIN(ia)->sin_addr.s_addr)
                        break;
 
index 9818151..e0ac707 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)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.36 2008/06/08 03:58:03 sephe Exp $
+ * $DragonFly: src/sys/netinet/in.c,v 1.37 2008/06/08 08:38:05 sephe Exp $
  */
 
 #include "opt_bootp.h"
@@ -94,16 +94,23 @@ int
 in_localaddr(struct in_addr in)
 {
        u_long i = ntohl(in.s_addr);
+       struct in_ifaddr_container *iac;
        struct in_ifaddr *ia;
 
        if (subnetsarelocal) {
-               TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link)
+               TAILQ_FOREACH(iac, &in_ifaddrheads[mycpuid], ia_link) {
+                       ia = iac->ia;
+
                        if ((i & ia->ia_netmask) == ia->ia_net)
                                return (1);
+               }
        } else {
-               TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link)
+               TAILQ_FOREACH(iac, &in_ifaddrheads[mycpuid], ia_link) {
+                       ia = iac->ia;
+
                        if ((i & ia->ia_subnetmask) == ia->ia_subnet)
                                return (1);
+               }
        }
        return (0);
 }
@@ -261,6 +268,101 @@ in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
        }
 }
 
+static void
+in_ialink_dispatch(struct netmsg *nmsg)
+{
+       struct lwkt_msg *lmsg = &nmsg->nm_lmsg;
+       struct in_ifaddr *ia = lmsg->u.ms_resultp;
+       struct ifaddr_container *ifac;
+       struct in_ifaddr_container *iac;
+       int cpu = mycpuid;
+
+       crit_enter();
+
+       ifac = &ia->ia_ifa.ifa_containers[cpu];
+       ASSERT_IFAC_VALID(ifac);
+       KASSERT((ifac->ifa_listmask & IFA_LIST_IN_IFADDRHEAD) == 0,
+               ("ia is on in_ifaddrheads\n"));
+
+       ifac->ifa_listmask |= IFA_LIST_IN_IFADDRHEAD;
+       iac = &ifac->ifa_proto_u.u_in_ifac;
+       TAILQ_INSERT_TAIL(&in_ifaddrheads[cpu], iac, ia_link);
+
+       crit_exit();
+
+       ifa_forwardmsg(lmsg, cpu + 1);
+}
+
+static void
+in_iaunlink_dispatch(struct netmsg *nmsg)
+{
+       struct lwkt_msg *lmsg = &nmsg->nm_lmsg;
+       struct in_ifaddr *ia = lmsg->u.ms_resultp;
+       struct ifaddr_container *ifac;
+       struct in_ifaddr_container *iac;
+       int cpu = mycpuid;
+
+       crit_enter();
+
+       ifac = &ia->ia_ifa.ifa_containers[cpu];
+       ASSERT_IFAC_VALID(ifac);
+       KASSERT(ifac->ifa_listmask & IFA_LIST_IN_IFADDRHEAD,
+               ("ia is not on in_ifaddrheads\n"));
+
+       iac = &ifac->ifa_proto_u.u_in_ifac;
+       TAILQ_REMOVE(&in_ifaddrheads[cpu], iac, ia_link);
+       ifac->ifa_listmask &= ~IFA_LIST_IN_IFADDRHEAD;
+
+       crit_exit();
+
+       ifa_forwardmsg(lmsg, cpu + 1);
+}
+
+static void
+in_ialink(struct in_ifaddr *ia)
+{
+       struct netmsg nmsg;
+       struct lwkt_msg *lmsg;
+
+       netmsg_init(&nmsg, &curthread->td_msgport, 0, in_ialink_dispatch);
+       lmsg = &nmsg.nm_lmsg;
+       lmsg->u.ms_resultp = ia;
+
+       ifa_domsg(lmsg);
+}
+
+void
+in_iaunlink(struct in_ifaddr *ia)
+{
+       struct netmsg nmsg;
+       struct lwkt_msg *lmsg;
+
+       netmsg_init(&nmsg, &curthread->td_msgport, 0, in_iaunlink_dispatch);
+       lmsg = &nmsg.nm_lmsg;
+       lmsg->u.ms_resultp = ia;
+
+       ifa_domsg(lmsg);
+}
+
+static __inline struct in_ifaddr *
+in_ianext(struct in_ifaddr *oia)
+{
+       struct ifaddr_container *ifac;
+       struct in_ifaddr_container *iac;
+
+       ifac = &oia->ia_ifa.ifa_containers[mycpuid];
+       ASSERT_IFAC_VALID(ifac);
+       KASSERT(ifac->ifa_listmask & IFA_LIST_IN_IFADDRHEAD,
+               ("ia is not on in_ifaddrheads\n"));
+
+       iac = &ifac->ifa_proto_u.u_in_ifac;
+       iac = TAILQ_NEXT(iac, ia_link);
+       if (iac != NULL)
+               return iac->ia;
+       else
+               return NULL;
+}
+
 static int
 in_control_internal(u_long cmd, caddr_t data, struct ifnet *ifp,
                    struct thread *td)
@@ -269,6 +371,7 @@ in_control_internal(u_long cmd, caddr_t data, struct ifnet *ifp,
        struct in_ifaddr *ia = 0, *iap;
        struct in_addr dst;
        struct in_aliasreq *ifra = (struct in_aliasreq *)data;
+       struct ifaddr_container *ifac;
        struct sockaddr_in oldaddr;
        int hostIsNew, iaIsNew, maskIsNew;
        int error = 0;
@@ -290,8 +393,6 @@ in_control_internal(u_long cmd, caddr_t data, struct ifnet *ifp,
                                break;
                        }
                if (ia == NULL) {
-                       struct ifaddr_container *ifac;
-
                        TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid],
                                      ifa_link) {
                                iap = ifatoia(ifac->ifa);
@@ -314,7 +415,7 @@ in_control_internal(u_long cmd, caddr_t data, struct ifnet *ifp,
                                    ia->ia_addr.sin_addr.s_addr ==
                                    ifra->ifra_addr.sin_addr.s_addr)
                                        break;
-                               ia = TAILQ_NEXT(ia, ia_link);
+                               ia = in_ianext(ia);
                        }
                        if ((ifp->if_flags & IFF_POINTOPOINT) &&
                            cmd == SIOCAIFADDR &&
@@ -340,8 +441,22 @@ in_control_internal(u_long cmd, caddr_t data, struct ifnet *ifp,
 
                if (ia == NULL) {
                        struct ifaddr *ifa;
+                       int i;
 
                        ia = ifa_create(sizeof(*ia), M_WAITOK);
+                       ifa = &ia->ia_ifa;
+
+                       /*
+                        * Setup per-CPU information
+                        */
+                       for (i = 0; i < ncpus; ++i) {
+                               struct in_ifaddr_container *iac;
+
+                               ifac = &ifa->ifa_containers[i];
+                               iac = &ifac->ifa_proto_u.u_in_ifac;
+                               iac->ia = ia;
+                               iac->ia_ifac = ifac;
+                       }
 
                        /*
                         * Protect from NETISR_IP traversing address list
@@ -349,8 +464,7 @@ in_control_internal(u_long cmd, caddr_t data, struct ifnet *ifp,
                         */
                        crit_enter();
 
-                       TAILQ_INSERT_TAIL(&in_ifaddrhead, ia, ia_link);
-                       ifa = &ia->ia_ifa;
+                       in_ialink(ia);
                        ifa_iflink(ifa, ifp, 1);
 
                        ifa->ifa_addr = (struct sockaddr *)&ia->ia_addr;
@@ -517,13 +631,13 @@ in_control_internal(u_long cmd, caddr_t data, struct ifnet *ifp,
        }
 
        ifa_ifunlink(&ia->ia_ifa, ifp);
+       in_iaunlink(ia);
 
        /*
         * Protect from NETISR_IP traversing address list while we're modifying
         * it.
         */
        crit_enter();   /* XXX MP */
-       TAILQ_REMOVE(&in_ifaddrhead, ia, ia_link);
        if (cmd == SIOCDIFADDR && ia->ia_addr.sin_family == AF_INET) {
                /* XXX Assume that 'ia' is in hash table */
                LIST_REMOVE(ia, ia_hash);
index 74684ac..0b7ce01 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * $FreeBSD: src/sys/netinet/in_gif.c,v 1.5.2.11 2003/01/23 21:06:45 sam Exp $
- * $DragonFly: src/sys/netinet/in_gif.c,v 1.16 2006/12/22 23:57:52 swildner Exp $
+ * $DragonFly: src/sys/netinet/in_gif.c,v 1.17 2008/06/08 08:38:05 sephe Exp $
  * $KAME: in_gif.c,v 1.54 2001/05/14 14:02:16 itojun Exp $
  */
 /*
@@ -296,7 +296,7 @@ static int
 gif_validate4(const struct ip *ip, struct gif_softc *sc, struct ifnet *ifp)
 {
        struct sockaddr_in *src, *dst;
-       struct in_ifaddr *ia4;
+       struct in_ifaddr_container *iac;
 
        src = (struct sockaddr_in *)sc->gif_psrc;
        dst = (struct sockaddr_in *)sc->gif_pdst;
@@ -314,7 +314,9 @@ gif_validate4(const struct ip *ip, struct gif_softc *sc, struct ifnet *ifp)
                return 0;
        }
        /* reject packets with broadcast on source */
-       TAILQ_FOREACH(ia4, &in_ifaddrhead, ia_link) {
+       TAILQ_FOREACH(iac, &in_ifaddrheads[mycpuid], ia_link) {
+               struct in_ifaddr *ia4 = iac->ia;
+
                if (!(ia4->ia_ifa.ifa_ifp->if_flags & IFF_BROADCAST))
                        continue;
                if (ip->ip_src.s_addr == ia4->ia_broadaddr.sin_addr.s_addr)
index afaa40f..a69b9c1 100644 (file)
@@ -65,7 +65,7 @@
  *
  *     @(#)in_pcb.c    8.4 (Berkeley) 5/24/95
  * $FreeBSD: src/sys/netinet/in_pcb.c,v 1.59.2.27 2004/01/02 04:06:42 ambrisko Exp $
- * $DragonFly: src/sys/netinet/in_pcb.c,v 1.45 2008/03/26 14:44:59 sephe Exp $
+ * $DragonFly: src/sys/netinet/in_pcb.c,v 1.46 2008/06/08 08:38:05 sephe Exp $
  */
 
 #include "opt_ipsec.h"
@@ -246,7 +246,7 @@ in_pcbbind(struct inpcb *inp, struct sockaddr *nam, struct thread *td)
 
        KKASSERT(p);
 
-       if (TAILQ_EMPTY(&in_ifaddrhead)) /* XXX broken! */
+       if (TAILQ_EMPTY(&in_ifaddrheads[mycpuid])) /* XXX broken! */
                return (EADDRNOTAVAIL);
        if (inp->inp_lport != 0 || inp->inp_laddr.s_addr != INADDR_ANY)
                return (EINVAL);        /* already bound */
@@ -453,8 +453,8 @@ in_pcbladdr(struct inpcb *inp, struct sockaddr *nam,
                cred = td->td_proc->p_ucred;
        if (cred && cred->cr_prison)
                jailed = 1;
-       if (!TAILQ_EMPTY(&in_ifaddrhead)) {
-               ia = TAILQ_FIRST(&in_ifaddrhead);
+       if (!TAILQ_EMPTY(&in_ifaddrheads[mycpuid])) {
+               ia = TAILQ_FIRST(&in_ifaddrheads[mycpuid])->ia;
                /*
                 * If the destination address is INADDR_ANY,
                 * use the primary local address.
@@ -530,8 +530,9 @@ in_pcbladdr(struct inpcb *inp, struct sockaddr *nam,
                            sintosa(&ia->ia_addr)))
                                ia = NULL;
                        sin->sin_port = fport;
-                       if (ia == NULL)
-                               ia = TAILQ_FIRST(&in_ifaddrhead);
+                       if (ia == NULL &&
+                           !TAILQ_EMPTY(&in_ifaddrheads[mycpuid]))
+                               ia = TAILQ_FIRST(&in_ifaddrheads[mycpuid])->ia;
                        if (ia && jailed && !jailed_ip(cred->cr_prison,
                            sintosa(&ia->ia_addr)))
                                ia = NULL;
@@ -551,10 +552,17 @@ in_pcbladdr(struct inpcb *inp, struct sockaddr *nam,
 
                        imo = inp->inp_moptions;
                        if (imo->imo_multicast_ifp != NULL) {
+                               struct in_ifaddr_container *iac;
+
                                ifp = imo->imo_multicast_ifp;
-                               TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link)
-                                       if (ia->ia_ifp == ifp)
+                               ia = NULL;
+                               TAILQ_FOREACH(iac,
+                               &in_ifaddrheads[mycpuid], ia_link) {
+                                       if (iac->ia->ia_ifp == ifp) {
+                                               ia = iac->ia;
                                                break;
+                                       }
+                               }
                                if (ia == NULL)
                                        goto fail;
                        }
index a9d665f..0b33312 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)in_var.h    8.2 (Berkeley) 1/9/95
  * $FreeBSD: src/sys/netinet/in_var.h,v 1.33.2.3 2001/12/14 20:09:34 jlemon Exp $
- * $DragonFly: src/sys/netinet/in_var.h,v 1.11 2006/05/20 02:42:12 dillon Exp $
+ * $DragonFly: src/sys/netinet/in_var.h,v 1.12 2008/06/08 08:38:05 sephe Exp $
  */
 
 #ifndef _NETINET_IN_VAR_H_
@@ -68,7 +68,7 @@ struct in_ifaddr {
        u_long  ia_subnetmask;          /* mask of subnet part */
        struct  in_addr ia_netbroadcast; /* to recognize net broadcasts */
        LIST_ENTRY(in_ifaddr) ia_hash;  /* entry in bucket of inet addresses */
-       TAILQ_ENTRY(in_ifaddr) ia_link; /* list of internet addresses */
+       void    *ia_pad2[2];
        struct  sockaddr_in ia_addr;    /* reserve space for interface name */
        struct  sockaddr_in ia_dstaddr; /* reserve space for broadcast addr */
 #define        ia_broadaddr    ia_dstaddr
@@ -94,6 +94,8 @@ struct        in_aliasreq {
 
 
 #ifdef _KERNEL
+struct in_ifaddr_container;
+
 extern struct  in_addr zeroin_addr;
 extern u_char  inetctlerrmap[];
 
@@ -101,7 +103,7 @@ extern      u_char  inetctlerrmap[];
  * Hash table for IP addresses.
  */
 extern LIST_HEAD(in_ifaddrhashhead, in_ifaddr) *in_ifaddrhashtbl;
-extern TAILQ_HEAD(in_ifaddrhead, in_ifaddr) in_ifaddrhead;
+extern TAILQ_HEAD(in_ifaddrhead, in_ifaddr_container) in_ifaddrheads[];
 extern u_long in_ifaddrhmask;                  /* mask for hash table */
 
 #define INADDR_NHASH_LOG2       9
@@ -131,16 +133,18 @@ extern    u_long in_ifaddrhmask;                  /* mask for hash table */
  * Macro for finding the internet address structure (in_ifaddr) corresponding
  * to a given interface (ifnet structure).
  */
-#define IFP_TO_IA(ifp, ia) \
-       /* struct ifnet *ifp; */ \
-       /* struct in_ifaddr *ia; */ \
-{ \
-       for ((ia) = TAILQ_FIRST(&in_ifaddrhead); \
-           (ia) != NULL && (ia)->ia_ifp != (ifp); \
-           (ia) = TAILQ_NEXT((ia), ia_link)) \
-               continue; \
+static __inline struct in_ifaddr *
+IFP_TO_IA(const struct ifnet *_ifp)
+{
+       struct in_ifaddr_container *_iac;
+
+       TAILQ_FOREACH(_iac, &in_ifaddrheads[mycpuid], ia_link)
+               if (_iac->ia->ia_ifp == _ifp)
+                       return _iac->ia;
+       return NULL;
 }
-#endif
+
+#endif /* _KERNEL */
 
 /*
  * This information should be part of the ifnet structure but we don't wish
@@ -245,6 +249,7 @@ void        in_rtqdrain (void);
 void   ip_input (struct mbuf *);
 int    in_ifadown (struct ifaddr *ifa, int);
 void   in_ifscrub (struct ifnet *, struct in_ifaddr *);
+void   in_iaunlink (struct in_ifaddr *);
 int    ipflow_fastforward (struct mbuf *, struct lwkt_serialize *);
 void   ipflow_create (const struct route *, struct mbuf *);
 void   ipflow_slowtimo (void);
index f775f29..7ab9546 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.8 2008/05/28 12:11:13 sephe Exp $
+ * $DragonFly: src/sys/netinet/ip_carp.c,v 1.9 2008/06/08 08:38:05 sephe Exp $
  */
 
 #include "opt_carp.h"
@@ -1431,6 +1431,7 @@ carp_set_addr(struct carp_softc *sc, struct sockaddr_in *sin)
        struct ifnet *ifp;
        struct carp_if *cif;
        struct in_ifaddr *ia, *ia_if;
+       struct in_ifaddr_container *iac;
        struct ip_moptions *imo = &sc->sc_imo;
        struct in_addr addr;
        u_long iaddr = htonl(sin->sin_addr.s_addr);
@@ -1451,7 +1452,9 @@ carp_set_addr(struct carp_softc *sc, struct sockaddr_in *sin)
        }
        /* we have to do it by hands to check we won't match on us */
        ia_if = NULL; own = 0;
-       TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) {
+       TAILQ_FOREACH(iac, &in_ifaddrheads[mycpuid], ia_link) {
+               ia = iac->ia;
+
                /* and, yeah, we need a multicast-capable iface too */
                if (ia->ia_ifp != SC2IFP(sc) &&
                    (ia->ia_ifp->if_flags & IFF_MULTICAST) &&
index ba9a853..f247753 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.79 2008/04/20 13:44:25 swildner Exp $
+ * $DragonFly: src/sys/netinet/ip_input.c,v 1.80 2008/06/08 08:38:05 sephe Exp $
  */
 
 #define        _IP_VHL
@@ -205,7 +205,7 @@ static int ipprintfs = 0;
 extern struct domain inetdomain;
 extern struct protosw inetsw[];
 u_char ip_protox[IPPROTO_MAX];
-struct in_ifaddrhead in_ifaddrhead;            /* first inet address */
+struct in_ifaddrhead in_ifaddrheads[MAXCPU];   /* first inet address */
 struct in_ifaddrhashhead *in_ifaddrhashtbl;    /* inet addr hash table */
 u_long in_ifaddrhmask;                         /* mask for hash table */
 
@@ -318,7 +318,8 @@ ip_init(void)
         */
        mpipe_init(&ipq_mpipe, M_IPQ, sizeof(struct ipq),
                    IFQ_MAXLEN, 4000, 0, NULL);
-       TAILQ_INIT(&in_ifaddrhead);
+       for (i = 0; i < ncpus; ++i)
+               TAILQ_INIT(&in_ifaddrheads[i]);
        in_ifaddrhashtbl = hashinit(INADDR_NHASH, M_IFADDR, &in_ifaddrhmask);
        pr = pffindproto(PF_INET, IPPROTO_RAW, SOCK_RAW);
        if (pr == NULL)
@@ -663,7 +664,8 @@ pass:
         * we receive might be for us (and let the upper layers deal
         * with it).
         */
-       if (TAILQ_EMPTY(&in_ifaddrhead) && !(m->m_flags & (M_MCAST | M_BCAST)))
+       if (TAILQ_EMPTY(&in_ifaddrheads[mycpuid]) &&
+           !(m->m_flags & (M_MCAST | M_BCAST)))
                goto ours;
 
        /*
index 34e754e..d97525b 100644 (file)
@@ -28,7 +28,7 @@
  *
  *     @(#)ip_output.c 8.3 (Berkeley) 1/21/94
  * $FreeBSD: src/sys/netinet/ip_output.c,v 1.99.2.37 2003/04/15 06:44:45 silby Exp $
- * $DragonFly: src/sys/netinet/ip_output.c,v 1.42 2008/05/14 11:59:24 sephe Exp $
+ * $DragonFly: src/sys/netinet/ip_output.c,v 1.43 2008/06/08 08:38:05 sephe Exp $
  */
 
 #define _IP_VHL
@@ -272,7 +272,7 @@ ip_output(struct mbuf *m0, struct mbuf *opt, struct route *ro,
                 * packets if the interface is specified.
                 */
                ifp = imo->imo_multicast_ifp;
-               IFP_TO_IA(ifp, ia);
+               ia = IFP_TO_IA(ifp);
                isbroadcast = 0;        /* fool gcc */
        } else {
                /*
@@ -2111,7 +2111,7 @@ ip_getmoptions(struct sockopt *sopt, struct ip_moptions *imo)
                        /* return the value user has set */
                        addr = imo->imo_multicast_addr;
                } else {
-                       IFP_TO_IA(imo->imo_multicast_ifp, ia);
+                       ia = IFP_TO_IA(imo->imo_multicast_ifp);
                        addr.s_addr = (ia == NULL) ? INADDR_ANY
                                : IA_SIN(ia)->sin_addr.s_addr;
                }
index 9363832..b6c05ed 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)raw_ip.c    8.7 (Berkeley) 5/15/95
  * $FreeBSD: src/sys/netinet/raw_ip.c,v 1.64.2.16 2003/08/24 08:24:38 hsu Exp $
- * $DragonFly: src/sys/netinet/raw_ip.c,v 1.29 2008/05/17 20:33:35 dillon Exp $
+ * $DragonFly: src/sys/netinet/raw_ip.c,v 1.30 2008/06/08 08:38:05 sephe Exp $
  */
 
 #include "opt_inet6.h"
@@ -448,13 +448,16 @@ void
 rip_ctlinput(int cmd, struct sockaddr *sa, void *vip)
 {
        struct in_ifaddr *ia;
+       struct in_ifaddr_container *iac;
        struct ifnet *ifp;
        int err;
        int flags;
 
        switch (cmd) {
        case PRC_IFDOWN:
-               TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) {
+               TAILQ_FOREACH(iac, &in_ifaddrheads[mycpuid], ia_link) {
+                       ia = iac->ia;
+
                        if (ia->ia_ifa.ifa_addr == sa &&
                            (ia->ia_flags & IFA_ROUTE)) {
                                /*
@@ -474,11 +477,14 @@ rip_ctlinput(int cmd, struct sockaddr *sa, void *vip)
                break;
 
        case PRC_IFUP:
-               TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) {
-                       if (ia->ia_ifa.ifa_addr == sa)
+               ia = NULL;
+               TAILQ_FOREACH(iac, &in_ifaddrheads[mycpuid], ia_link) {
+                       if (iac->ia->ia_ifa.ifa_addr == sa) {
+                               ia = iac->ia;
                                break;
+                       }
                }
-               if (ia == 0 || (ia->ia_flags & IFA_ROUTE))
+               if (ia == NULL || (ia->ia_flags & IFA_ROUTE))
                        return;
                flags = RTF_UP;
                ifp = ia->ia_ifa.ifa_ifp;
index bedb637..5c59bba 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.17 2008/05/14 11:59:24 sephe Exp $
+ *     @(#) $DragonFly: src/sys/netproto/atm/atm_if.c,v 1.18 2008/06/08 08:38:05 sephe Exp $
  */
 
 /*
@@ -360,7 +360,7 @@ atm_physif_ioctl(int code, caddr_t data, caddr_t arg)
                KM_ZERO((caddr_t)&anr, sizeof(anr));
                ksnprintf(anr.anp_intf, sizeof(anr.anp_intf),
                    "%s", ifp->if_xname);
-               IFP_TO_IA(ifp, ia);
+               ia = IFP_TO_IA(ifp);
                if (ia) {
                        anr.anp_proto_addr = *ia->ia_ifa.ifa_addr;
                }
@@ -799,7 +799,7 @@ atm_nif_detach(struct atm_nif *nip)
         * Free all interface routes and addresses
         */
        while (1) {
-               IFP_TO_IA(ifp, ia);
+               ia = IFP_TO_IA(ifp);
                if (ia == NULL)
                        break;
 
@@ -809,7 +809,7 @@ atm_nif_detach(struct atm_nif *nip)
                /* Remove interface address from queues */
                ifa = &ia->ia_ifa;
                ifa_ifunlink(ifa, ifp);
-               TAILQ_REMOVE(&in_ifaddrhead, ia, ia_link);
+               in_iaunlink(ia);
 
                /* Free interface address */
                ifa_destroy(ifa);
index dd1013c..844b75b 100644 (file)
@@ -24,7 +24,7 @@
  * notice must be reproduced on all copies.
  *
  *     @(#) $FreeBSD: src/sys/netatm/ipatm/ipatm_load.c,v 1.6 2000/01/17 20:49:43 mks Exp $
- *     @(#) $DragonFly: src/sys/netproto/atm/ipatm/ipatm_load.c,v 1.9 2006/01/14 13:36:39 swildner Exp $
+ *     @(#) $DragonFly: src/sys/netproto/atm/ipatm/ipatm_load.c,v 1.10 2008/06/08 08:38:05 sephe Exp $
  */
 
 /*
@@ -414,6 +414,7 @@ ipatm_start(void)
                for (nip = pip->pif_nif; nip; nip = nip->nif_pnext) {
                        struct ifnet    *ifp = (struct ifnet *)nip;
                        struct in_ifaddr        *ia;
+                       struct in_ifaddr_container *iac;
 
                        /*
                         * Attach interface
@@ -427,11 +428,12 @@ ipatm_start(void)
                        /*
                         * If IP address has been set, register it
                         */
-                       TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) {
-                               if (ia->ia_ifp == ifp)
+                       TAILQ_FOREACH(iac, &in_ifaddrheads[mycpuid], ia_link) {
+                               if (iac->ia->ia_ifp == ifp)
                                        break;
                        }
-                       if (ia) {
+                       if (iac) {
+                               ia = iac->ia;
                                err = ipatm_nifstat(NCM_SETADDR, nip, (int)ia);
                                if (err) {
                                        crit_exit();
index c1ae392..64c444e 100644 (file)
@@ -24,7 +24,7 @@
  * notice must be reproduced on all copies.
  *
  *     @(#) $FreeBSD: src/sys/netatm/ipatm/ipatm_output.c,v 1.4.2.1 2000/06/02 22:39:08 archie Exp $
- *     @(#) $DragonFly: src/sys/netproto/atm/ipatm/ipatm_output.c,v 1.7 2006/01/14 13:36:39 swildner Exp $
+ *     @(#) $DragonFly: src/sys/netproto/atm/ipatm/ipatm_output.c,v 1.8 2008/06/08 08:38:05 sephe Exp $
  */
 
 /*
@@ -110,7 +110,7 @@ ipatm_ifoutput(struct ifnet *ifp, KBuffer *m, struct sockaddr *dst)
                        ivp->iv_queue = m;
                }
        } else {
-               struct in_ifaddr        *ia;
+               struct in_ifaddr_container *iac;
 
                /*
                 * No VCC to destination
@@ -119,7 +119,9 @@ ipatm_ifoutput(struct ifnet *ifp, KBuffer *m, struct sockaddr *dst)
                /*
                 * Is packet for our interface address?
                 */
-               TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) {
+               TAILQ_FOREACH(iac, &in_ifaddrheads[mycpuid], ia_link) {
+                       struct in_ifaddr *ia = iac->ia;
+
                        if (ia->ia_ifp != ifp)
                                continue;
                        if (((struct sockaddr_in *)dst)->sin_addr.s_addr == 
index a6fc2cf..edf2a0c 100644 (file)
@@ -1,5 +1,5 @@
 /*     $FreeBSD: src/sys/netipsec/key.c,v 1.3.2.1 2003/01/24 05:11:35 sam Exp $        */
-/*     $DragonFly: src/sys/netproto/ipsec/key.c,v 1.25 2007/05/13 18:33:58 swildner Exp $      */
+/*     $DragonFly: src/sys/netproto/ipsec/key.c,v 1.26 2008/06/08 08:38:05 sephe Exp $ */
 /*     $KAME: key.c,v 1.191 2001/06/27 10:46:49 sakane Exp $   */
 
 /*
@@ -3506,7 +3506,7 @@ key_ismyaddr(struct sockaddr *sa)
 {
 #ifdef INET
        struct sockaddr_in *sin;
-       struct in_ifaddr *ia;
+       struct in_ifaddr_container *iac;
 #endif
 
        /* sanity check */
@@ -3517,7 +3517,9 @@ key_ismyaddr(struct sockaddr *sa)
 #ifdef INET
        case AF_INET:
                sin = (struct sockaddr_in *)sa;
-               TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) {
+               TAILQ_FOREACH(iac, &in_ifaddrheads[mycpuid], ia_link) {
+                       struct in_ifaddr *ia = iac->ia;
+
                        if (sin->sin_family == ia->ia_addr.sin_family &&
                            sin->sin_len == ia->ia_addr.sin_len &&
                            sin->sin_addr.s_addr == ia->ia_addr.sin_addr.s_addr)
index 83be382..4f4cab5 100644 (file)
@@ -34,7 +34,7 @@
  *     @(#)ipx_ip.c
  *
  * $FreeBSD: src/sys/netipx/ipx_ip.c,v 1.24.2.2 2003/01/23 21:06:48 sam Exp $
- * $DragonFly: src/sys/netproto/ipx/ipx_ip.c,v 1.17 2008/05/14 11:59:24 sephe Exp $
+ * $DragonFly: src/sys/netproto/ipx/ipx_ip.c,v 1.18 2008/06/08 08:38:05 sephe Exp $
  */
 
 /*
@@ -344,14 +344,18 @@ ipxip_route(struct socket *so, struct sockopt *sopt)
         */
        {
                struct in_ifaddr *ia;
+               struct in_ifaddr_container *iac;
                struct ifnet *ifp = ro.ro_rt->rt_ifp;
 
-               for (ia = TAILQ_FIRST(&in_ifaddrhead); ia != NULL; 
-                    ia = TAILQ_NEXT(ia, ia_link))
-                       if (ia->ia_ifp == ifp)
+               ia = NULL;
+               TAILQ_FOREACH(iac, &in_ifaddrheads[mycpuid], ia_link) {
+                       if (iac->ia->ia_ifp == ifp) {
+                               ia = iac->ia;
                                break;
-               if (ia == NULL)
-                       ia = TAILQ_FIRST(&in_ifaddrhead);
+                       }
+               }
+               if (ia == NULL && !TAILQ_EMPTY(&in_ifaddrheads[mycpuid]))
+                       ia = TAILQ_FIRST(&in_ifaddrheads[mycpuid])->ia;
                if (ia == NULL) {
                        RTFREE(ro.ro_rt);
                        return (EADDRNOTAVAIL);
index 2e39146..c2a0fd5 100644 (file)
@@ -1,5 +1,5 @@
 /*     $FreeBSD: src/sys/netkey/key.c,v 1.16.2.13 2002/07/24 18:17:40 ume Exp $        */
-/*     $DragonFly: src/sys/netproto/key/key.c,v 1.20 2007/05/13 18:33:58 swildner Exp $        */
+/*     $DragonFly: src/sys/netproto/key/key.c,v 1.21 2008/06/08 08:38:05 sephe Exp $   */
 /*     $KAME: key.c,v 1.191 2001/06/27 10:46:49 sakane Exp $   */
 
 /*
@@ -3714,7 +3714,7 @@ key_ismyaddr(struct sockaddr *sa)
 {
 #ifdef INET
        struct sockaddr_in *sin;
-       struct in_ifaddr *ia;
+       struct in_ifaddr_container *iac;
 #endif
 
        /* sanity check */
@@ -3725,7 +3725,9 @@ key_ismyaddr(struct sockaddr *sa)
 #ifdef INET
        case AF_INET:
                sin = (struct sockaddr_in *)sa;
-               TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) {
+               TAILQ_FOREACH(iac, &in_ifaddrheads[mycpuid], ia_link) {
+                       struct in_ifaddr *ia = iac->ia;
+
                        if (sin->sin_family == ia->ia_addr.sin_family &&
                            sin->sin_len == ia->ia_addr.sin_len &&
                            sin->sin_addr.s_addr == ia->ia_addr.sin_addr.s_addr)
index 99ef955..2b5658e 100644 (file)
@@ -35,7 +35,7 @@
  *
  *     @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95
  * $FreeBSD: src/sys/nfs/nfs_vnops.c,v 1.150.2.5 2001/12/20 19:56:28 dillon Exp $
- * $DragonFly: src/sys/vfs/nfs/nfs_vnops.c,v 1.76 2007/11/02 19:52:28 dillon Exp $
+ * $DragonFly: src/sys/vfs/nfs/nfs_vnops.c,v 1.77 2008/06/08 08:38:06 sephe Exp $
  */
 
 
@@ -1498,8 +1498,8 @@ again:
                        *tl = txdr_unsigned(NFSV3CREATE_EXCLUSIVE);
                        nfsm_build(tl, u_int32_t *, NFSX_V3CREATEVERF);
 #ifdef INET
-                       if (!TAILQ_EMPTY(&in_ifaddrhead))
-                               *tl++ = IA_SIN(TAILQ_FIRST(&in_ifaddrhead))->sin_addr.s_addr;
+                       if (!TAILQ_EMPTY(&in_ifaddrheads[mycpuid]))
+                               *tl++ = IA_SIN(TAILQ_FIRST(&in_ifaddrheads[mycpuid])->ia)->sin_addr.s_addr;
                        else
 #endif
                                *tl++ = create_verf;