- Nuke #ifdef SCOPEDROUTING. It was never enabled and is useless now[1].
authorHiroki Sato <hrs@dragonflybsd.org>
Tue, 1 Feb 2005 16:09:37 +0000 (16:09 +0000)
committerHiroki Sato <hrs@dragonflybsd.org>
Tue, 1 Feb 2005 16:09:37 +0000 (16:09 +0000)
- Add in6_domifattach(), in6_domifdetach(), and ifp->if_afdata[2].
- ANSIfy.

Obtained from: KAME via FreeBSD
References (FreeBSD):

net/
if.c 1.168[2]
if_var.h 1.59[2]

netinet/
icmp6.h 1.12[2]
tcp_input.c 1.209[2]

netinet6/
icmp6.c 1.38[1], 1.39[2]
in6.c 1.30[1], 1.31[2]
ip6_forward.c 1.20[1]
in6_gif.c 1.15[1]
in6_proto.c 1.25[2]
in6_ifattach.c 1.17[1], 1.18[2]
ip6_input.c 1.53[1], 1.57[2]
ip6_output.c 1.58[1], 1.59[2]
in6_src.c 1.14[2]
in6_var.h 1.14[2]
nd6.c 1.30[1], 1.32[2]
nd6.h 1.13[2]
nd6_nbr.c 1.19[2]
nd6_rtr.c 1.20[2]
scope6.c 1.8[2]
scope6_var.h 1.3[2]

sys/
domain.h 1.18[2]
kernel.h 1.113[2]

23 files changed:
sys/net/if.c
sys/net/if_var.h
sys/netinet/icmp6.h
sys/netinet/tcp_input.c
sys/netinet6/icmp6.c
sys/netinet6/in6.c
sys/netinet6/in6_gif.c
sys/netinet6/in6_ifattach.c
sys/netinet6/in6_pcb.c
sys/netinet6/in6_proto.c
sys/netinet6/in6_src.c
sys/netinet6/in6_var.h
sys/netinet6/ip6_forward.c
sys/netinet6/ip6_input.c
sys/netinet6/ip6_output.c
sys/netinet6/nd6.c
sys/netinet6/nd6.h
sys/netinet6/nd6_nbr.c
sys/netinet6/nd6_rtr.c
sys/netinet6/scope6.c
sys/netinet6/scope6_var.h
sys/sys/domain.h
sys/sys/kernel.h

index 8eb0d2b..3dde7d8 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.26 2005/01/26 23:09:57 hsu Exp $
+ * $DragonFly: src/sys/net/if.c,v 1.27 2005/02/01 16:09:37 hrs Exp $
  */
 
 #include "opt_compat.h"
@@ -53,6 +53,7 @@
 #include <sys/sockio.h>
 #include <sys/syslog.h>
 #include <sys/sysctl.h>
+#include <sys/domain.h>
 
 #include <net/if.h>
 #include <net/if_arp.h>
@@ -83,6 +84,8 @@
  * System initialization
  */
 
+static void    if_attachdomain(void *);
+static void    if_attachdomain1(struct ifnet *);
 static int ifconf (u_long, caddr_t, struct thread *);
 static void ifinit (void *);
 static void if_qflush (struct ifqueue *);
@@ -237,10 +240,45 @@ if_attach(struct ifnet *ifp)
 
        EVENTHANDLER_INVOKE(ifnet_attach_event, ifp);
 
+       if (domains)
+               if_attachdomain1(ifp);
+
        /* Announce the interface. */
        rt_ifannouncemsg(ifp, IFAN_ARRIVAL);
 }
 
+static void
+if_attachdomain(void *dummy)
+{
+       struct ifnet *ifp;
+       int s;
+
+       s = splnet();
+       for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list))
+               if_attachdomain1(ifp);
+       splx(s);
+}
+SYSINIT(domainifattach, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_FIRST,
+       if_attachdomain, NULL);
+
+static void
+if_attachdomain1(struct ifnet *ifp)
+{
+       struct domain *dp;
+       int s;
+
+       s = splnet();
+
+       /* address family dependent data region */
+       bzero(ifp->if_afdata, sizeof(ifp->if_afdata));
+       for (dp = domains; dp; dp = dp->dom_next) {
+               if (dp->dom_ifattach)
+                       ifp->if_afdata[dp->dom_family] =
+                               (*dp->dom_ifattach)(ifp);
+       }
+       splx(s);
+}
+
 /*
  * Detach an interface, removing it from the
  * list of "active" interfaces.
@@ -252,6 +290,7 @@ if_detach(struct ifnet *ifp)
        struct radix_node_head  *rnh;
        int s;
        int i;
+       struct domain *dp;
 
        EVENTHANDLER_INVOKE(ifnet_detach_event, ifp);
 
@@ -321,6 +360,12 @@ if_detach(struct ifnet *ifp)
        /* Announce that the interface is gone. */
        rt_ifannouncemsg(ifp, IFAN_DEPARTURE);
 
+       for (dp = domains; dp; dp = dp->dom_next) {
+               if (dp->dom_ifdetach && ifp->if_afdata[dp->dom_family])
+                       (*dp->dom_ifdetach)(ifp,
+                               ifp->if_afdata[dp->dom_family]);
+       }
+
        ifindex2ifnet[ifp->if_index] = NULL;
 
        TAILQ_REMOVE(&ifnet, ifp, if_link);
index 5899880..1fd484a 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.21 2005/01/23 13:47:24 joerg Exp $
+ * $DragonFly: src/sys/net/if_var.h,v 1.22 2005/02/01 16:09:37 hrs Exp $
  */
 
 #ifndef        _NET_IF_VAR_H_
@@ -174,6 +174,7 @@ struct ifnet {
        struct  ifqueue if_snd;         /* output queue */
        struct  ifprefixhead if_prefixhead; /* list of prefixes per if */
        const uint8_t   *if_broadcastaddr;
+       void    *if_afdata[AF_MAX];
 };
 typedef void if_init_f_t (void *);
 
index c58fee2..09c454d 100644 (file)
@@ -1,5 +1,5 @@
 /*     $FreeBSD: src/sys/netinet/icmp6.h,v 1.2.2.5 2002/06/29 18:31:11 ume Exp $       */
-/*     $DragonFly: src/sys/netinet/icmp6.h,v 1.5 2004/12/21 02:54:15 hsu Exp $ */
+/*     $DragonFly: src/sys/netinet/icmp6.h,v 1.6 2005/02/01 16:09:37 hrs Exp $ */
 /*     $KAME: icmp6.h,v 1.46 2001/04/27 15:09:48 itojun Exp $  */
 
 /*
@@ -684,11 +684,8 @@ void       icmp6_mtudisc_update (struct ip6ctlparam *, int);
 /* XXX: is this the right place for these macros? */
 #define icmp6_ifstat_inc(ifp, tag) \
 do {                                                           \
-       if ((ifp) && (ifp)->if_index <= if_index                        \
-        && (ifp)->if_index < icmp6_ifstatmax                   \
-        && icmp6_ifstat && icmp6_ifstat[(ifp)->if_index]) {    \
-               icmp6_ifstat[(ifp)->if_index]->tag++;           \
-       }                                                       \
+       if (ifp)                                                \
+               ((struct in6_ifextra *)((ifp)->if_afdata[AF_INET6]))->icmp6_ifstat->tag++; \
 } while (0)
 
 #define icmp6_ifoutstat_inc(ifp, type, code) \
@@ -696,7 +693,7 @@ do { \
                icmp6_ifstat_inc(ifp, ifs6_out_msg); \
                if (type < ICMP6_INFOMSG_MASK) \
                        icmp6_ifstat_inc(ifp, ifs6_out_error); \
-               switch(type) { \
+               switch (type) { \
                 case ICMP6_DST_UNREACH: \
                         icmp6_ifstat_inc(ifp, ifs6_out_dstunreach); \
                         if (code == ICMP6_DST_UNREACH_ADMIN) \
index d601883..644d93a 100644 (file)
@@ -82,7 +82,7 @@
  *
  *     @(#)tcp_input.c 8.12 (Berkeley) 5/24/95
  * $FreeBSD: src/sys/netinet/tcp_input.c,v 1.107.2.38 2003/05/21 04:46:41 cjc Exp $
- * $DragonFly: src/sys/netinet/tcp_input.c,v 1.50 2005/01/08 09:26:32 hsu Exp $
+ * $DragonFly: src/sys/netinet/tcp_input.c,v 1.51 2005/02/01 16:09:37 hrs Exp $
  */
 
 #include "opt_ipfw.h"          /* for ipfw_fwd         */
@@ -2920,8 +2920,7 @@ tcp_mss(struct tcpcb *tp, int offer)
                mss = rt->rt_rmx.rmx_mtu - min_protoh;
        else {
                if (isipv6) {
-                       mss = nd_ifinfo[rt->rt_ifp->if_index].linkmtu -
-                               min_protoh;
+                       mss = ND_IFINFO(rt->rt_ifp)->linkmtu - min_protoh;
                        if (!in6_localaddr(&inp->in6p_faddr))
                                mss = min(mss, tcp_v6mssdflt);
                } else {
index dd7bc3e..15bb72b 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.16 2005/01/06 17:59:32 hsu Exp $       */
+/*     $DragonFly: src/sys/netinet6/icmp6.c,v 1.17 2005/02/01 16:09:37 hrs Exp $       */
 /*     $KAME: icmp6.c,v 1.211 2001/04/04 05:56:20 itojun Exp $ */
 
 /*
@@ -1055,7 +1055,6 @@ icmp6_notify_error(struct mbuf *m, int off, int icmp6len, int code)
                        icmp6dst.sin6_addr = *finaldst;
                icmp6dst.sin6_scope_id = in6_addr2scopeid(m->m_pkthdr.rcvif,
                                                          &icmp6dst.sin6_addr);
-#ifndef SCOPEDROUTING
                if (in6_embedscope(&icmp6dst.sin6_addr, &icmp6dst,
                                   NULL, NULL)) {
                        /* should be impossbile */
@@ -1063,7 +1062,6 @@ icmp6_notify_error(struct mbuf *m, int off, int icmp6len, int code)
                            "icmp6_notify_error: in6_embedscope failed\n"));
                        goto freeit;
                }
-#endif
 
                /*
                 * retrieve parameters from the inner IPv6 header, and convert
@@ -1075,7 +1073,6 @@ icmp6_notify_error(struct mbuf *m, int off, int icmp6len, int code)
                icmp6src.sin6_addr = eip6->ip6_src;
                icmp6src.sin6_scope_id = in6_addr2scopeid(m->m_pkthdr.rcvif,
                                                          &icmp6src.sin6_addr);
-#ifndef SCOPEDROUTING
                if (in6_embedscope(&icmp6src.sin6_addr, &icmp6src,
                                   NULL, NULL)) {
                        /* should be impossbile */
@@ -1083,7 +1080,6 @@ icmp6_notify_error(struct mbuf *m, int off, int icmp6len, int code)
                            "icmp6_notify_error: in6_embedscope failed\n"));
                        goto freeit;
                }
-#endif
                icmp6src.sin6_flowinfo =
                        (eip6->ip6_flow & IPV6_FLOWLABEL_MASK);
 
@@ -1277,18 +1273,14 @@ ni6_input(struct mbuf *m, int off)
                            subjlen, (caddr_t)&sin6.sin6_addr);
                        sin6.sin6_scope_id = in6_addr2scopeid(m->m_pkthdr.rcvif,
                                                              &sin6.sin6_addr);
-#ifndef SCOPEDROUTING
                        in6_embedscope(&sin6.sin6_addr, &sin6, NULL, NULL);
-#endif
                        bzero(&sin6_d, sizeof(sin6_d));
                        sin6_d.sin6_family = AF_INET6; /* not used, actually */
                        sin6_d.sin6_len = sizeof(sin6_d); /* ditto */
                        sin6_d.sin6_addr = ip6->ip6_dst;
                        sin6_d.sin6_scope_id = in6_addr2scopeid(m->m_pkthdr.rcvif,
                                                                &ip6->ip6_dst);
-#ifndef SCOPEDROUTING
                        in6_embedscope(&sin6_d.sin6_addr, &sin6_d, NULL, NULL);
-#endif
                        subj = (char *)&sin6;
                        if (SA6_ARE_ADDR_EQUAL(&sin6, &sin6_d))
                                break;
@@ -2139,7 +2131,7 @@ icmp6_reflect(struct mbuf *m, size_t off)
        ip6->ip6_nxt = IPPROTO_ICMPV6;
        if (m->m_pkthdr.rcvif) {
                /* XXX: This may not be the outgoing interface */
-               ip6->ip6_hlim = nd_ifinfo[m->m_pkthdr.rcvif->if_index].chlim;
+               ip6->ip6_hlim = ND_IFINFO(m->m_pkthdr.rcvif)->chlim;
        } else
                ip6->ip6_hlim = ip6_defhlim;
 
index 7a8d505..ef1b2ef 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.12 2005/01/06 17:59:32 hsu Exp $ */
+/*     $DragonFly: src/sys/netinet6/in6.c,v 1.13 2005/02/01 16:09:37 hrs Exp $ */
 /*     $KAME: in6.c,v 1.259 2002/01/21 11:37:50 keiichi Exp $  */
 
 /*
 #include <netinet/in.h>
 #include <netinet/in_var.h>
 #include <netinet/if_ether.h>
-#ifndef SCOPEDROUTING
 #include <netinet/in_systm.h>
 #include <netinet/ip.h>
 #include <netinet/in_pcb.h>
-#endif
 
 #include <netinet/ip6.h>
 #include <netinet6/ip6_var.h>
 #include <netinet6/ip6_mroute.h>
 #include <netinet6/in6_ifattach.h>
 #include <netinet6/scope6_var.h>
-#ifndef SCOPEDROUTING
 #include <netinet6/in6_pcb.h>
-#endif
 
 #include <net/net_osdep.h>
 
@@ -415,13 +411,16 @@ in6_control(struct socket *so, u_long cmd, caddr_t data,
        case SIOCSSCOPE6:
                if (!privileged)
                        return(EPERM);
-               return(scope6_set(ifp, ifr->ifr_ifru.ifru_scope_id));
+               return(scope6_set(ifp,
+                       (struct scope6_id *)ifr->ifr_ifru.ifru_scope_id));
                break;
        case SIOCGSCOPE6:
-               return(scope6_get(ifp, ifr->ifr_ifru.ifru_scope_id));
+               return(scope6_get(ifp,
+                       (struct scope6_id *)ifr->ifr_ifru.ifru_scope_id));
                break;
        case SIOCGSCOPE6DEF:
-               return(scope6_get_default(ifr->ifr_ifru.ifru_scope_id));
+               return(scope6_get_default((struct scope6_id *)
+                       ifr->ifr_ifru.ifru_scope_id));
                break;
        }
 
@@ -557,26 +556,17 @@ in6_control(struct socket *so, u_long cmd, caddr_t data,
        case SIOCGIFSTAT_IN6:
                if (ifp == NULL)
                        return EINVAL;
-               if (in6_ifstat == NULL || ifp->if_index >= in6_ifstatmax
-                || in6_ifstat[ifp->if_index] == NULL) {
-                       /* return EAFNOSUPPORT? */
-                       bzero(&ifr->ifr_ifru.ifru_stat,
-                               sizeof(ifr->ifr_ifru.ifru_stat));
-               } else
-                       ifr->ifr_ifru.ifru_stat = *in6_ifstat[ifp->if_index];
+               bzero(&ifr->ifr_ifru.ifru_stat,
+                       sizeof(ifr->ifr_ifru.ifru_stat));
+               ifr->ifr_ifru.ifru_stat =
+                       *((struct in6_ifextra *)ifp->if_afdata[AF_INET6])->in6_ifstat;
                break;
 
        case SIOCGIFSTAT_ICMP6:
-               if (ifp == NULL)
-                       return EINVAL;
-               if (icmp6_ifstat == NULL || ifp->if_index >= icmp6_ifstatmax ||
-                   icmp6_ifstat[ifp->if_index] == NULL) {
-                       /* return EAFNOSUPPORT? */
-                       bzero(&ifr->ifr_ifru.ifru_stat,
-                               sizeof(ifr->ifr_ifru.ifru_icmp6stat));
-               } else
-                       ifr->ifr_ifru.ifru_icmp6stat =
-                               *icmp6_ifstat[ifp->if_index];
+               bzero(&ifr->ifr_ifru.ifru_stat,
+                       sizeof(ifr->ifr_ifru.ifru_icmp6stat));
+               ifr->ifr_ifru.ifru_icmp6stat =
+                       *((struct in6_ifextra *)ifp->if_afdata[AF_INET6])->icmp6_ifstat;
                break;
 
        case SIOCGIFALIFETIME_IN6:
@@ -824,23 +814,19 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
            (dst6.sin6_family == AF_INET6)) {
                int scopeid;
 
-#ifndef SCOPEDROUTING
                if ((error = in6_recoverscope(&dst6,
                                              &ifra->ifra_dstaddr.sin6_addr,
                                              ifp)) != 0)
                        return(error);
-#endif
                scopeid = in6_addr2scopeid(ifp, &dst6.sin6_addr);
                if (dst6.sin6_scope_id == 0) /* user omit to specify the ID. */
                        dst6.sin6_scope_id = scopeid;
                else if (dst6.sin6_scope_id != scopeid)
                        return(EINVAL); /* scope ID mismatch. */
-#ifndef SCOPEDROUTING
                if ((error = in6_embedscope(&dst6.sin6_addr, &dst6, NULL, NULL))
                    != 0)
                        return(error);
                dst6.sin6_scope_id = 0; /* XXX */
-#endif
        }
        /*
         * The destination address can be specified only for a p2p or a
@@ -1128,13 +1114,6 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
        } else
                ia->ia6_lifetime.ia6t_preferred = 0;
 
-       /*
-        * make sure to initialize ND6 information.  this is to workaround
-        * issues with interfaces with IPv6 addresses, which have never brought
-        * up.  We are assuming that it is safe to nd6_ifattach multiple times.
-        */
-       nd6_ifattach(ifp);
-
        /*
         * Perform DAD, if needed.
         * XXX It may be of use, if we can administratively
@@ -1467,7 +1446,6 @@ in6_lifaddr_ioctl(struct socket *so, u_long cmd, caddr_t data,
                                break;
 
                        bcopy(IFA_IN6(ifa), &candidate, sizeof(candidate));
-#ifndef SCOPEDROUTING
                        /*
                         * XXX: this is adhoc, but is necessary to allow
                         * a user to specify fe80::/64 (not /10) for a
@@ -1475,7 +1453,6 @@ in6_lifaddr_ioctl(struct socket *so, u_long cmd, caddr_t data,
                         */
                        if (IN6_IS_ADDR_LINKLOCAL(&candidate))
                                candidate.s6_addr16[1] = 0;
-#endif
                        candidate.s6_addr32[0] &= mask.s6_addr32[0];
                        candidate.s6_addr32[1] &= mask.s6_addr32[1];
                        candidate.s6_addr32[2] &= mask.s6_addr32[2];
@@ -1488,24 +1465,19 @@ in6_lifaddr_ioctl(struct socket *so, u_long cmd, caddr_t data,
                ia = ifa2ia6(ifa);
 
                if (cmd == SIOCGLIFADDR) {
-#ifndef SCOPEDROUTING
                        struct sockaddr_in6 *s6;
-#endif
 
                        /* fill in the if_laddrreq structure */
                        bcopy(&ia->ia_addr, &iflr->addr, ia->ia_addr.sin6_len);
-#ifndef SCOPEDROUTING          /* XXX see above */
                        s6 = (struct sockaddr_in6 *)&iflr->addr;
                        if (IN6_IS_ADDR_LINKLOCAL(&s6->sin6_addr)) {
                                s6->sin6_addr.s6_addr16[1] = 0;
                                s6->sin6_scope_id =
                                        in6_addr2scopeid(ifp, &s6->sin6_addr);
                        }
-#endif
                        if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
                                bcopy(&ia->ia_dstaddr, &iflr->dstaddr,
                                        ia->ia_dstaddr.sin6_len);
-#ifndef SCOPEDROUTING          /* XXX see above */
                                s6 = (struct sockaddr_in6 *)&iflr->dstaddr;
                                if (IN6_IS_ADDR_LINKLOCAL(&s6->sin6_addr)) {
                                        s6->sin6_addr.s6_addr16[1] = 0;
@@ -1513,7 +1485,6 @@ in6_lifaddr_ioctl(struct socket *so, u_long cmd, caddr_t data,
                                                in6_addr2scopeid(ifp,
                                                                 &s6->sin6_addr);
                                }
-#endif
                        } else
                                bzero(&iflr->dstaddr, sizeof(iflr->dstaddr));
 
@@ -1832,9 +1803,6 @@ in6_is_addr_deprecated(struct sockaddr_in6 *sa6)
        for (ia = in6_ifaddr; ia; ia = ia->ia_next) {
                if (IN6_ARE_ADDR_EQUAL(&ia->ia_addr.sin6_addr,
                                       &sa6->sin6_addr) &&
-#ifdef SCOPEDROUTING
-                   ia->ia_addr.sin6_scope_id == sa6->sin6_scope_id &&
-#endif
                    (ia->ia6_flags & IN6_IFF_DEPRECATED) != 0)
                        return(1); /* true */
 
@@ -2349,13 +2317,46 @@ in6_setmaxmtu(void)
        for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list))
        {
                if ((ifp->if_flags & IFF_LOOPBACK) == 0 &&
-                   nd_ifinfo[ifp->if_index].linkmtu > maxmtu)
-                       maxmtu =  nd_ifinfo[ifp->if_index].linkmtu;
+                   ND_IFINFO(ifp)->linkmtu > maxmtu)
+                       maxmtu =  ND_IFINFO(ifp)->linkmtu;
        }
        if (maxmtu)     /* update only when maxmtu is positive */
                in6_maxmtu = maxmtu;
 }
 
+void *
+in6_domifattach(struct ifnet *ifp)
+{
+       struct in6_ifextra *ext;
+
+       ext = (struct in6_ifextra *)malloc(sizeof(*ext), M_IFADDR, M_WAITOK);
+       bzero(ext, sizeof(*ext));
+
+       ext->in6_ifstat = (struct in6_ifstat *)malloc(sizeof(struct in6_ifstat),
+               M_IFADDR, M_WAITOK);
+       bzero(ext->in6_ifstat, sizeof(*ext->in6_ifstat));
+
+       ext->icmp6_ifstat =
+               (struct icmp6_ifstat *)malloc(sizeof(struct icmp6_ifstat),
+                       M_IFADDR, M_WAITOK);
+       bzero(ext->icmp6_ifstat, sizeof(*ext->icmp6_ifstat));
+
+       ext->nd_ifinfo = nd6_ifattach(ifp);
+       ext->scope6_id = scope6_ifattach(ifp);
+       return ext;
+}
+
+void
+in6_domifdetach(struct ifnet *ifp, void *aux)
+{
+       struct in6_ifextra *ext = (struct in6_ifextra *)aux;
+       scope6_ifdetach(ext->scope6_id);
+       nd6_ifdetach(ext->nd_ifinfo);
+       free(ext->in6_ifstat, M_IFADDR);
+       free(ext->icmp6_ifstat, M_IFADDR);
+       free(ext, M_IFADDR);
+}
+
 /*
  * Convert sockaddr_in6 to sockaddr_in.  Original sockaddr_in6 must be
  * v4 mapped addr or v4 compat addr
index 369d1e5..f8cd4f4 100644 (file)
@@ -1,5 +1,5 @@
 /*     $FreeBSD: src/sys/netinet6/in6_gif.c,v 1.2.2.7 2003/01/23 21:06:47 sam Exp $    */
-/*     $DragonFly: src/sys/netinet6/in6_gif.c,v 1.11 2005/01/06 17:59:32 hsu Exp $     */
+/*     $DragonFly: src/sys/netinet6/in6_gif.c,v 1.12 2005/02/01 16:09:37 hrs Exp $     */
 /*     $KAME: in6_gif.c,v 1.49 2001/05/14 14:02:17 itojun Exp $        */
 
 /*
@@ -323,9 +323,7 @@ gif_validate6(const struct ip6_hdr *ip6, struct gif_softc *sc,
                sin6.sin6_family = AF_INET6;
                sin6.sin6_len = sizeof(struct sockaddr_in6);
                sin6.sin6_addr = ip6->ip6_src;
-#ifndef SCOPEDROUTING
                sin6.sin6_scope_id = 0; /* XXX */
-#endif
 
                rt = rtpurelookup((struct sockaddr *)&sin6);
                if (rt == NULL || rt->rt_ifp != ifp) {
index c05a595..04faa35 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.11 2005/01/06 17:59:32 hsu Exp $        */
+/*     $DragonFly: src/sys/netinet6/in6_ifattach.c,v 1.12 2005/02/01 16:09:37 hrs Exp $        */
 /*     $KAME: in6_ifattach.c,v 1.118 2001/05/24 07:44:00 itojun Exp $  */
 
 /*
 
 #include <net/net_osdep.h>
 
-struct in6_ifstat **in6_ifstat = NULL;
-struct icmp6_ifstat **icmp6_ifstat = NULL;
-size_t in6_ifstatmax = 0;
-size_t icmp6_ifstatmax = 0;
 unsigned long in6_maxmtu = 0;
 
 #ifdef IP6_AUTO_LINKLOCAL
@@ -437,11 +433,7 @@ in6_ifattach_linklocal(struct ifnet *ifp,
        ifra.ifra_addr.sin6_family = AF_INET6;
        ifra.ifra_addr.sin6_len = sizeof(struct sockaddr_in6);
        ifra.ifra_addr.sin6_addr.s6_addr16[0] = htons(0xfe80);
-#ifdef SCOPEDROUTING
-       ifra.ifra_addr.sin6_addr.s6_addr16[1] = 0
-#else
        ifra.ifra_addr.sin6_addr.s6_addr16[1] = htons(ifp->if_index); /* XXX */
-#endif
        ifra.ifra_addr.sin6_addr.s6_addr32[1] = 0;
        if ((ifp->if_flags & IFF_LOOPBACK) != 0) {
                ifra.ifra_addr.sin6_addr.s6_addr32[2] = 0;
@@ -453,18 +445,11 @@ in6_ifattach_linklocal(struct ifnet *ifp,
                        return -1;
                }
        }
-#ifdef SCOPEDROUTING
-       ifra.ifra_addr.sin6_scope_id =
-               in6_addr2scopeid(ifp,  &ifra.ifra_addr.sin6_addr);
-#endif
 
        ifra.ifra_prefixmask.sin6_len = sizeof(struct sockaddr_in6);
        ifra.ifra_prefixmask.sin6_family = AF_INET6;
        ifra.ifra_prefixmask.sin6_addr = in6mask64;
-#ifdef SCOPEDROUTING
-       /* take into accound the sin6_scope_id field for routing */
-       ifra.ifra_prefixmask.sin6_scope_id = 0xffffffff;
-#endif
+
        /* link-local addresses should NEVER expire. */
        ifra.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
        ifra.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
@@ -717,7 +702,6 @@ void
 in6_ifattach(struct ifnet *ifp,
             struct ifnet *altifp)      /* secondary EUI64 source */
 {
-       static size_t if_indexlim = 8;
        struct in6_ifaddr *ia;
        struct in6_addr in6;
 
@@ -732,50 +716,6 @@ in6_ifattach(struct ifnet *ifp,
                return;
        }
 
-       /*
-        * We have some arrays that should be indexed by if_index.
-        * since if_index will grow dynamically, they should grow too.
-        *      struct in6_ifstat **in6_ifstat
-        *      struct icmp6_ifstat **icmp6_ifstat
-        */
-       if (in6_ifstat == NULL || icmp6_ifstat == NULL ||
-           if_index >= if_indexlim) {
-               size_t n;
-               caddr_t q;
-               size_t olim;
-
-               olim = if_indexlim;
-               while (if_index >= if_indexlim)
-                       if_indexlim <<= 1;
-
-               /* grow in6_ifstat */
-               n = if_indexlim * sizeof(struct in6_ifstat *);
-               q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK);
-               bzero(q, n);
-               if (in6_ifstat) {
-                       bcopy((caddr_t)in6_ifstat, q,
-                               olim * sizeof(struct in6_ifstat *));
-                       free((caddr_t)in6_ifstat, M_IFADDR);
-               }
-               in6_ifstat = (struct in6_ifstat **)q;
-               in6_ifstatmax = if_indexlim;
-
-               /* grow icmp6_ifstat */
-               n = if_indexlim * sizeof(struct icmp6_ifstat *);
-               q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK);
-               bzero(q, n);
-               if (icmp6_ifstat) {
-                       bcopy((caddr_t)icmp6_ifstat, q,
-                               olim * sizeof(struct icmp6_ifstat *));
-                       free((caddr_t)icmp6_ifstat, M_IFADDR);
-               }
-               icmp6_ifstat = (struct icmp6_ifstat **)q;
-               icmp6_ifstatmax = if_indexlim;
-       }
-
-       /* initialize scope identifiers */
-       scope6_ifattach(ifp);
-
        /*
         * quirks based on interface type
         */
@@ -837,20 +777,6 @@ statinit:
        /* update dynamically. */
        if (in6_maxmtu < ifp->if_mtu)
                in6_maxmtu = ifp->if_mtu;
-
-       if (in6_ifstat[ifp->if_index] == NULL) {
-               in6_ifstat[ifp->if_index] = (struct in6_ifstat *)
-                       malloc(sizeof(struct in6_ifstat), M_IFADDR, M_WAITOK);
-               bzero(in6_ifstat[ifp->if_index], sizeof(struct in6_ifstat));
-       }
-       if (icmp6_ifstat[ifp->if_index] == NULL) {
-               icmp6_ifstat[ifp->if_index] = (struct icmp6_ifstat *)
-                       malloc(sizeof(struct icmp6_ifstat), M_IFADDR, M_WAITOK);
-               bzero(icmp6_ifstat[ifp->if_index], sizeof(struct icmp6_ifstat));
-       }
-
-       /* initialize NDP variables */
-       nd6_ifattach(ifp);
 }
 
 /*
@@ -967,7 +893,7 @@ in6_get_tmpifid(struct ifnet *ifp, u_int8_t *retbuf, const u_int8_t *baseid,
                int generate)
 {
        u_int8_t nullbuf[8];
-       struct nd_ifinfo *ndi = &nd_ifinfo[ifp->if_index];
+       struct nd_ifinfo *ndi = ND_IFINFO(ifp);
 
        bzero(nullbuf, sizeof(nullbuf));
        if (bcmp(ndi->randomid, nullbuf, sizeof(nullbuf)) == 0) {
@@ -988,9 +914,9 @@ in6_get_tmpifid(struct ifnet *ifp, u_int8_t *retbuf, const u_int8_t *baseid,
 void
 in6_tmpaddrtimer(void *ignored_arg)
 {
-       int i;
        struct nd_ifinfo *ndi;
        u_int8_t nullbuf[8];
+       struct ifnet *ifp;
        int s = splnet();
 
        callout_reset(&in6_tmpaddrtimer_ch,
@@ -999,8 +925,8 @@ in6_tmpaddrtimer(void *ignored_arg)
                      in6_tmpaddrtimer, NULL);
 
        bzero(nullbuf, sizeof(nullbuf));
-       for (i = 1; i < if_index + 1; i++) {
-               ndi = &nd_ifinfo[i];
+       for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list)) {
+               ndi = ND_IFINFO(ifp);
                if (bcmp(ndi->randomid, nullbuf, sizeof(nullbuf)) != 0) {
                        /*
                         * We've been generating a random ID on this interface.
index 9cfe78c..d97388c 100644 (file)
@@ -1,5 +1,5 @@
 /*     $FreeBSD: src/sys/netinet6/in6_pcb.c,v 1.10.2.9 2003/01/24 05:11:35 sam Exp $   */
-/*     $DragonFly: src/sys/netinet6/in6_pcb.c,v 1.21 2005/01/06 17:59:32 hsu Exp $     */
+/*     $DragonFly: src/sys/netinet6/in6_pcb.c,v 1.22 2005/02/01 16:09:37 hrs Exp $     */
 /*     $KAME: in6_pcb.c,v 1.31 2001/05/21 05:45:10 jinmei Exp $        */
   
 /*
@@ -569,7 +569,7 @@ in6_selecthlim(struct in6pcb *in6p, struct ifnet *ifp)
        if (in6p && in6p->in6p_hops >= 0)
                return(in6p->in6p_hops);
        else if (ifp)
-               return(nd_ifinfo[ifp->if_index].chlim);
+               return(ND_IFINFO(ifp)->chlim);
        else
                return(ip6_defhlim);
 }
index a3847b7..23bc499 100644 (file)
@@ -1,5 +1,5 @@
 /*     $FreeBSD: src/sys/netinet6/in6_proto.c,v 1.6.2.9 2003/01/24 05:11:35 sam Exp $  */
-/*     $DragonFly: src/sys/netinet6/in6_proto.c,v 1.7 2005/01/03 22:11:51 hsu Exp $    */
+/*     $DragonFly: src/sys/netinet6/in6_proto.c,v 1.8 2005/02/01 16:09:37 hrs Exp $    */
 /*     $KAME: in6_proto.c,v 1.91 2001/05/27 13:28:35 itojun Exp $      */
 
 /*
@@ -264,7 +264,8 @@ struct domain inet6domain =
       (struct protosw *)&inet6sw[sizeof(inet6sw)/sizeof(inet6sw[0])], 0,
       in6_inithead,
       offsetof(struct sockaddr_in6, sin6_addr) << 3,
-      sizeof(struct sockaddr_in6) };
+      sizeof(struct sockaddr_in6),
+      in6_domifattach, in6_domifdetach, };
 
 DOMAIN_SET(inet6);
 
index 914a033..8720d91 100644 (file)
@@ -1,5 +1,5 @@
 /*     $FreeBSD: src/sys/netinet6/in6_src.c,v 1.1.2.3 2002/02/26 18:02:06 ume Exp $    */
-/*     $DragonFly: src/sys/netinet6/in6_src.c,v 1.9 2005/01/06 17:59:32 hsu Exp $      */
+/*     $DragonFly: src/sys/netinet6/in6_src.c,v 1.10 2005/02/01 16:09:37 hrs Exp $     */
 /*     $KAME: in6_src.c,v 1.37 2001/03/29 05:34:31 itojun Exp $        */
 
 /*
@@ -316,7 +316,7 @@ in6_selecthlim(struct in6pcb *in6p, struct ifnet *ifp)
        if (in6p && in6p->in6p_hops >= 0)
                return(in6p->in6p_hops);
        else if (ifp)
-               return(nd_ifinfo[ifp->if_index].chlim);
+               return(ND_IFINFO(ifp)->chlim);
        else
                return(ip6_defhlim);
 }
index 4df4278..012cc15 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.5 2004/08/02 13:22:33 joerg Exp $    */
+/*     $DragonFly: src/sys/netinet6/in6_var.h,v 1.6 2005/02/01 16:09:37 hrs Exp $      */
 /*     $KAME: in6_var.h,v 1.56 2001/03/29 05:34:31 itojun Exp $        */
 
 /*
@@ -91,6 +91,15 @@ struct in6_addrlifetime {
        u_int32_t ia6t_pltime;  /* prefix lifetime */
 };
 
+struct nd_ifinfo;
+struct scope6_id;
+struct in6_ifextra {
+       struct in6_ifstat *in6_ifstat;
+       struct icmp6_ifstat *icmp6_ifstat;
+       struct nd_ifinfo *nd_ifinfo;
+       struct scope6_id *scope6_id;
+};
+
 struct in6_ifaddr {
        struct  ifaddr ia_ifa;          /* protocol-independent info */
 #define        ia_ifp          ia_ifa.ifa_ifp
@@ -447,18 +456,11 @@ struct    in6_rrenumreq {
 #ifdef _KERNEL
 extern struct in6_ifaddr *in6_ifaddr;
 
-extern struct in6_ifstat **in6_ifstat;
-extern size_t in6_ifstatmax;
 extern struct icmp6stat icmp6stat;
-extern struct icmp6_ifstat **icmp6_ifstat;
-extern size_t icmp6_ifstatmax;
 #define in6_ifstat_inc(ifp, tag) \
 do {                                                           \
-       if ((ifp) && (ifp)->if_index <= if_index                \
-        && (ifp)->if_index < in6_ifstatmax                     \
-        && in6_ifstat && in6_ifstat[(ifp)->if_index]) {        \
-               in6_ifstat[(ifp)->if_index]->tag++;             \
-       }                                                       \
+       if (ifp)                                                \
+               ((struct in6_ifextra *)((ifp)->if_afdata[AF_INET6]))->in6_ifstat->tag++; \
 } while (0)
 
 extern struct ifqueue ip6intrq;                /* IP6 packet input queue */
@@ -580,6 +582,8 @@ void        in6_purgeaddr (struct ifaddr *);
 int    in6if_do_dad (struct ifnet *);
 void   in6_purgeif (struct ifnet *);
 void   in6_savemkludge (struct in6_ifaddr *);
+void   *in6_domifattach (struct ifnet *);
+void   in6_domifdetach (struct ifnet *, void *);
 void   in6_setmaxmtu   (void);
 void   in6_restoremkludge (struct in6_ifaddr *, struct ifnet *);
 void   in6_purgemkludge (struct ifnet *);
index 5fcebe7..579f111 100644 (file)
@@ -1,5 +1,5 @@
 /*     $FreeBSD: src/sys/netinet6/ip6_forward.c,v 1.4.2.7 2003/01/24 05:11:35 sam Exp $        */
-/*     $DragonFly: src/sys/netinet6/ip6_forward.c,v 1.10 2004/10/15 22:59:10 hsu Exp $ */
+/*     $DragonFly: src/sys/netinet6/ip6_forward.c,v 1.11 2005/02/01 16:09:37 hrs Exp $ */
 /*     $KAME: ip6_forward.c,v 1.69 2001/05/17 03:48:30 itojun Exp $    */
 
 /*
@@ -503,14 +503,12 @@ ip6_forward(struct mbuf *m, int srcrt)
        }
        else
                origifp = rt->rt_ifp;
-#ifndef SCOPEDROUTING
        /*
         * clear embedded scope identifiers if necessary.
         * in6_clearscope will touch the addresses only when necessary.
         */
        in6_clearscope(&ip6->ip6_src);
        in6_clearscope(&ip6->ip6_dst);
-#endif
 
        /*
         * Run through list of hooks for output packets.
index 035f50a..1c96400 100644 (file)
@@ -1,5 +1,5 @@
 /*     $FreeBSD: src/sys/netinet6/ip6_input.c,v 1.11.2.15 2003/01/24 05:11:35 sam Exp $        */
-/*     $DragonFly: src/sys/netinet6/ip6_input.c,v 1.23 2005/01/03 22:03:26 hsu Exp $   */
+/*     $DragonFly: src/sys/netinet6/ip6_input.c,v 1.24 2005/02/01 16:09:37 hrs Exp $   */
 /*     $KAME: ip6_input.c,v 1.259 2002/01/21 04:58:09 jinmei Exp $     */
 
 /*
 #include <netinet6/ip6_var.h>
 #include <netinet/in_pcb.h>
 #include <netinet/icmp6.h>
+#include <netinet6/scope6_var.h>
 #include <netinet6/in6_ifattach.h>
 #include <netinet6/nd6.h>
 #include <netinet6/in6_prefix.h>
@@ -197,6 +198,7 @@ ip6_init(void)
        }
 
        netisr_register(NETISR_IPV6, cpu0_portfn, ip6_input);
+       scope6_init();
        nd6_init();
        frag6_init();
        /*
@@ -212,13 +214,6 @@ ip6_init(void)
 static void
 ip6_init2(void *dummy)
 {
-
-       /*
-        * to route local address of p2p link to loopback,
-        * assign loopback address first.
-        */
-       in6_ifattach(&loif[0], NULL);
-
        /* nd6_timer_init */
        callout_init(&nd6_timer_ch);
        callout_reset(&nd6_timer_ch, hz, nd6_timer, NULL);
@@ -534,10 +529,6 @@ ip6_input(struct netmsg *msg)
                dst6->sin6_len = sizeof(struct sockaddr_in6);
                dst6->sin6_family = AF_INET6;
                dst6->sin6_addr = ip6->ip6_dst;
-#ifdef SCOPEDROUTING
-               ip6_forward_rt.ro_dst.sin6_scope_id =
-                       in6_addr2scopeid(m->m_pkthdr.rcvif, &ip6->ip6_dst);
-#endif
 
                rtalloc_ign((struct route *)&ip6_forward_rt, RTF_PRCLONING);
        }
index d1eb409..6fe63ea 100644 (file)
@@ -1,5 +1,5 @@
 /*     $FreeBSD: src/sys/netinet6/ip6_output.c,v 1.13.2.18 2003/01/24 05:11:35 sam Exp $       */
-/*     $DragonFly: src/sys/netinet6/ip6_output.c,v 1.16 2005/01/06 17:59:32 hsu Exp $  */
+/*     $DragonFly: src/sys/netinet6/ip6_output.c,v 1.17 2005/02/01 16:09:37 hrs Exp $  */
 /*     $KAME: ip6_output.c,v 1.279 2002/01/26 06:12:30 jinmei Exp $    */
 
 /*
@@ -521,11 +521,6 @@ skip_ipsec2:;
                dst->sin6_family = AF_INET6;
                dst->sin6_len = sizeof(struct sockaddr_in6);
                dst->sin6_addr = ip6->ip6_dst;
-#ifdef SCOPEDROUTING
-               /* XXX: sin6_scope_id should already be fixed at this point */
-               if (IN6_IS_SCOPE_LINKLOCAL(&dst->sin6_addr))
-                       dst->sin6_scope_id = ntohs(dst->sin6_addr.s6_addr16[1]);
-#endif
        }
 #if defined(IPSEC) || defined(FAST_IPSEC)
        if (needipsec && needipsectun) {
@@ -788,7 +783,7 @@ skip_ipsec2:;
                }
        }
        if (ro_pmtu->ro_rt != NULL) {
-               u_int32_t ifmtu = nd_ifinfo[ifp->if_index].linkmtu;
+               u_int32_t ifmtu = ND_IFINFO(ifp)->linkmtu;
 
                mtu = ro_pmtu->ro_rt->rt_rmx.rmx_mtu;
                if (mtu > ifmtu || mtu == 0) {
@@ -808,7 +803,7 @@ skip_ipsec2:;
                                 ro_pmtu->ro_rt->rt_rmx.rmx_mtu = mtu; /* XXX */
                }
        } else {
-               mtu = nd_ifinfo[ifp->if_index].linkmtu;
+               mtu = ND_IFINFO(ifp)->linkmtu;
        }
 
        /*
@@ -855,14 +850,12 @@ skip_ipsec2:;
        }
        else
                origifp = ifp;
-#ifndef SCOPEDROUTING
        /*
         * clear embedded scope identifiers if necessary.
         * in6_clearscope will touch the addresses only when necessary.
         */
        in6_clearscope(&ip6->ip6_src);
        in6_clearscope(&ip6->ip6_dst);
-#endif
 
        /*
         * Check with the firewall...
@@ -2496,14 +2489,12 @@ ip6_mloopback(struct ifnet *ifp, struct mbuf *m, struct sockaddr_in6 *dst)
 #endif
 
        ip6 = mtod(copym, struct ip6_hdr *);
-#ifndef SCOPEDROUTING
        /*
         * clear embedded scope identifiers if necessary.
         * in6_clearscope will touch the addresses only when necessary.
         */
        in6_clearscope(&ip6->ip6_src);
        in6_clearscope(&ip6->ip6_dst);
-#endif
 
        (void)if_simloop(ifp, copym, dst->sin6_family, NULL);
 }
index 42aa8fa..5c690c2 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.14 2005/01/06 17:59:32 hsu Exp $ */
+/*     $DragonFly: src/sys/netinet6/nd6.c,v 1.15 2005/02/01 16:09:37 hrs Exp $ */
 /*     $KAME: nd6.c,v 1.144 2001/05/24 07:44:00 itojun Exp $   */
 
 /*
@@ -106,14 +106,13 @@ int nd6_debug = 0;
 static int nd6_inuse, nd6_allocated;
 
 struct llinfo_nd6 llinfo_nd6 = {&llinfo_nd6, &llinfo_nd6};
-static size_t nd_ifinfo_indexlim = 8;
-struct nd_ifinfo *nd_ifinfo = NULL;
 struct nd_drhead nd_defrouter;
 struct nd_prhead nd_prefix = { 0 };
 
 int nd6_recalc_reachtm_interval = ND6_RECALC_REACHTM_INTERVAL;
 static struct sockaddr_in6 all1_sa;
 
+static void nd6_setmtu0 (struct ifnet *, struct nd_ifinfo *);
 static void nd6_slowtimo (void *);
 static int regen_tmpaddr (struct in6_ifaddr *);
 
@@ -148,58 +147,39 @@ nd6_init(void)
            nd6_slowtimo, NULL);
 }
 
-void
+struct nd_ifinfo *
 nd6_ifattach(struct ifnet *ifp)
 {
+       struct nd_ifinfo *nd;
 
-       /*
-        * We have some arrays that should be indexed by if_index.
-        * since if_index will grow dynamically, they should grow too.
-        */
-       if (nd_ifinfo == NULL || if_index >= nd_ifinfo_indexlim) {
-               size_t n;
-               caddr_t q;
-
-               while (if_index >= nd_ifinfo_indexlim)
-                       nd_ifinfo_indexlim <<= 1;
-
-               /* grow nd_ifinfo */
-               n = nd_ifinfo_indexlim * sizeof(struct nd_ifinfo);
-               q = (caddr_t)malloc(n, M_IP6NDP, M_WAITOK);
-               bzero(q, n);
-               if (nd_ifinfo) {
-                       bcopy((caddr_t)nd_ifinfo, q, n/2);
-                       free((caddr_t)nd_ifinfo, M_IP6NDP);
-               }
-               nd_ifinfo = (struct nd_ifinfo *)q;
-       }
+       nd = (struct nd_ifinfo *)malloc(sizeof(*nd), M_IP6NDP, M_WAITOK);
+       bzero(nd, sizeof(*nd));
 
-#define ND nd_ifinfo[ifp->if_index]
+       nd->initialized = 1;
 
-       /*
-        * Don't initialize if called twice.
-        * XXX: to detect this, we should choose a member that is never set
-        * before initialization of the ND structure itself.  We formaly used
-        * the linkmtu member, which was not suitable because it could be 
-        * initialized via "ifconfig mtu".
-        */
-       if (ND.basereachable)
-               return;
+       nd->linkmtu = ifindex2ifnet[ifp->if_index]->if_mtu;
+       nd->chlim = IPV6_DEFHLIM;
+       nd->basereachable = REACHABLE_TIME;
+       nd->reachable = ND_COMPUTE_RTIME(nd->basereachable);
+       nd->retrans = RETRANS_TIMER;
+       nd->receivedra = 0;
 
-       ND.linkmtu = ifindex2ifnet[ifp->if_index]->if_mtu;
-       ND.chlim = IPV6_DEFHLIM;
-       ND.basereachable = REACHABLE_TIME;
-       ND.reachable = ND_COMPUTE_RTIME(ND.basereachable);
-       ND.retrans = RETRANS_TIMER;
-       ND.receivedra = 0;
        /*
         * Note that the default value of ip6_accept_rtadv is 0, which means
         * we won't accept RAs by default even if we set ND6_IFF_ACCEPT_RTADV
         * here.
         */
-       ND.flags = (ND6_IFF_PERFORMNUD | ND6_IFF_ACCEPT_RTADV);
-       nd6_setmtu(ifp);
-#undef ND
+       nd->flags = (ND6_IFF_PERFORMNUD | ND6_IFF_ACCEPT_RTADV);
+
+       /* XXX: we cannot call nd6_setmtu since ifp is not fully initialized */
+       nd6_setmtu0(ifp, nd);
+       return nd;
+}
+
+void
+nd6_ifdetach(struct nd_ifinfo *nd)
+{
+       free(nd, M_IP6NDP);
 }
 
 /*
@@ -209,9 +189,18 @@ nd6_ifattach(struct ifnet *ifp)
 void
 nd6_setmtu(struct ifnet *ifp)
 {
-       struct nd_ifinfo *ndi = &nd_ifinfo[ifp->if_index];
-       u_long oldmaxmtu = ndi->maxmtu;
-       u_long oldlinkmtu = ndi->linkmtu;
+       nd6_setmtu0(ifp, ND_IFINFO(ifp));
+}
+
+/* XXX todo: do not maintain copy of ifp->if_mtu in ndi->maxmtu */
+void
+nd6_setmtu0(struct ifnet *ifp, struct nd_ifinfo *ndi)
+{
+       u_long oldmaxmtu;
+       u_long oldlinkmtu;
+
+       oldmaxmtu = ndi->maxmtu;
+       oldlinkmtu = ndi->linkmtu;
 
        switch (ifp->if_type) {
        case IFT_ARCNET:        /* XXX MTU handling needs more work */
@@ -443,7 +432,7 @@ nd6_timer(void *ignored_arg)
                        ln = next;
                        continue;
                }
-               ndi = &nd_ifinfo[ifp->if_index];
+               ndi = ND_IFINFO(ifp);
                dst = (struct sockaddr_in6 *)rt_key(rt);
 
                if (ln->ln_expire > time_second) {
@@ -465,7 +454,7 @@ nd6_timer(void *ignored_arg)
                        if (ln->ln_asked < nd6_mmaxtries) {
                                ln->ln_asked++;
                                ln->ln_expire = time_second +
-                                       nd_ifinfo[ifp->if_index].retrans / 1000;
+                                       ND_IFINFO(ifp)->retrans / 1000;
                                nd6_ns_output(ifp, NULL, &dst->sin6_addr,
                                        ln, 0);
                        } else {
@@ -520,7 +509,7 @@ nd6_timer(void *ignored_arg)
                        if (ln->ln_asked < nd6_umaxtries) {
                                ln->ln_asked++;
                                ln->ln_expire = time_second +
-                                       nd_ifinfo[ifp->if_index].retrans / 1000;
+                                       ND_IFINFO(ifp)->retrans / 1000;
                                nd6_ns_output(ifp, &dst->sin6_addr,
                                               &dst->sin6_addr, ln, 0);
                        } else {
@@ -791,9 +780,7 @@ nd6_lookup(struct in6_addr *addr6, int create, struct ifnet *ifp)
        sin6.sin6_len = sizeof(struct sockaddr_in6);
        sin6.sin6_family = AF_INET6;
        sin6.sin6_addr = *addr6;
-#ifdef SCOPEDROUTING
-       sin6.sin6_scope_id = in6_addr2scopeid(ifp, addr6);
-#endif
+
        if (create)
                rt = rtlookup((struct sockaddr *)&sin6);
        else
@@ -1066,7 +1053,7 @@ nd6_nud_hint(struct rtentry *rt, struct in6_addr *dst6, int force)
        ln->ln_state = ND6_LLINFO_REACHABLE;
        if (ln->ln_expire)
                ln->ln_expire = time_second +
-                       nd_ifinfo[rt->rt_ifp->if_index].reachable;
+                       ND_IFINFO(rt->rt_ifp)->reachable;
 }
 
 void
@@ -1439,35 +1426,23 @@ nd6_ioctl(u_long cmd, caddr_t   data, struct ifnet *ifp)
 
                break;
        case OSIOCGIFINFO_IN6:
-               if (!nd_ifinfo || i >= nd_ifinfo_indexlim) {
-                       error = EINVAL;
-                       break;
-               }
-               ndi->ndi.linkmtu = nd_ifinfo[ifp->if_index].linkmtu;
-               ndi->ndi.maxmtu = nd_ifinfo[ifp->if_index].maxmtu;
-               ndi->ndi.basereachable =
-                   nd_ifinfo[ifp->if_index].basereachable;
-               ndi->ndi.reachable = nd_ifinfo[ifp->if_index].reachable;
-               ndi->ndi.retrans = nd_ifinfo[ifp->if_index].retrans;
-               ndi->ndi.flags = nd_ifinfo[ifp->if_index].flags;
-               ndi->ndi.recalctm = nd_ifinfo[ifp->if_index].recalctm;
-               ndi->ndi.chlim = nd_ifinfo[ifp->if_index].chlim;
-               ndi->ndi.receivedra = nd_ifinfo[ifp->if_index].receivedra;
+               /* XXX: old ndp(8) assumes a positive value for linkmtu. */
+               bzero(&ndi->ndi, sizeof(ndi->ndi));
+               ndi->ndi.linkmtu = ND_IFINFO(ifp)->linkmtu;
+               ndi->ndi.maxmtu = ND_IFINFO(ifp)->maxmtu;
+               ndi->ndi.basereachable = ND_IFINFO(ifp)->basereachable;
+               ndi->ndi.reachable = ND_IFINFO(ifp)->reachable;
+               ndi->ndi.retrans = ND_IFINFO(ifp)->retrans;
+               ndi->ndi.flags = ND_IFINFO(ifp)->flags;
+               ndi->ndi.recalctm = ND_IFINFO(ifp)->recalctm;
+               ndi->ndi.chlim = ND_IFINFO(ifp)->chlim;
+               ndi->ndi.receivedra = ND_IFINFO(ifp)->receivedra;
                break;
        case SIOCGIFINFO_IN6:
-               if (!nd_ifinfo || i >= nd_ifinfo_indexlim) {
-                       error = EINVAL;
-                       break;
-               }
-               ndi->ndi = nd_ifinfo[ifp->if_index];
+               ndi->ndi = *ND_IFINFO(ifp);
                break;
        case SIOCSIFINFO_FLAGS:
-               /* XXX: almost all other fields of ndi->ndi is unused */
-               if (!nd_ifinfo || i >= nd_ifinfo_indexlim) {
-                       error = EINVAL;
-                       break;
-               }
-               nd_ifinfo[ifp->if_index].flags = ndi->ndi.flags;
+               ND_IFINFO(ifp)->flags = ndi->ndi.flags;
                break;
        case SIOCSNDFLUSH_IN6:  /* XXX: the ioctl name is confusing... */
                /* flush default router list */
@@ -1808,15 +1783,13 @@ static void
 nd6_slowtimo(void *ignored_arg)
 {
        int s = splnet();
-       int i;
        struct nd_ifinfo *nd6if;
+       struct ifnet *ifp;
 
        callout_reset(&nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz,
            nd6_slowtimo, NULL);
-       for (i = 1; i < if_index + 1; i++) {
-               if (!nd_ifinfo || i >= nd_ifinfo_indexlim)
-                       continue;
-               nd6if = &nd_ifinfo[i];
+       for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list)) {
+               nd6if = ND_IFINFO(ifp);
                if (nd6if->basereachable && /* already initialized */
                    (nd6if->recalctm -= ND6_SLOWTIMER_INTERVAL) <= 0) {
                        /*
@@ -1922,7 +1895,7 @@ lookup:                           rt->rt_gwroute = rtlookup(rt->rt_gateway);
        }
        if (!ln || !rt) {
                if ((ifp->if_flags & IFF_POINTOPOINT) == 0 &&
-                   !(nd_ifinfo[ifp->if_index].flags & ND6_IFF_PERFORMNUD)) {
+                   !(ND_IFINFO(ifp)->flags & ND6_IFF_PERFORMNUD)) {
                        log(LOG_DEBUG,
                            "nd6_output: can't allocate llinfo for %s "
                            "(ln=%p, rt=%p)\n",
@@ -1980,7 +1953,7 @@ lookup:                           rt->rt_gwroute = rtlookup(rt->rt_gateway);
                    ln->ln_expire < time_second) {
                        ln->ln_asked++;
                        ln->ln_expire = time_second +
-                               nd_ifinfo[ifp->if_index].retrans / 1000;
+                               ND_IFINFO(ifp)->retrans / 1000;
                        nd6_ns_output(ifp, NULL, &dst->sin6_addr, ln, 0);
                }
        }
index de92bc2..69a47a5 100644 (file)
@@ -1,5 +1,5 @@
 /*     $FreeBSD: src/sys/netinet6/nd6.h,v 1.2.2.5 2002/04/28 05:40:27 suz Exp $        */
-/*     $DragonFly: src/sys/netinet6/nd6.h,v 1.5 2004/12/30 02:26:12 hsu Exp $  */
+/*     $DragonFly: src/sys/netinet6/nd6.h,v 1.6 2005/02/01 16:09:37 hrs Exp $  */
 /*     $KAME: nd6.h,v 1.76 2001/12/18 02:10:31 itojun Exp $    */
 
 /*
@@ -81,6 +81,7 @@ struct nd_ifinfo {
        int recalctm;                   /* BaseReacable re-calculation timer */
        u_int8_t chlim;                 /* CurHopLimit */
        u_int8_t receivedra;
+       u_int8_t initialized;           /* Flag to see the entry is initialized */
        /* the following 3 members are for privacy extension for addrconf */
        u_int8_t randomseed0[8]; /* upper 64 bits of MD5 digest */
        u_int8_t randomseed1[8]; /* lower 64 bits (usually the EUI64 IFID) */
@@ -90,6 +91,16 @@ struct nd_ifinfo {
 #define ND6_IFF_PERFORMNUD     0x1
 #define ND6_IFF_ACCEPT_RTADV   0x2
 
+#ifdef _KERNEL
+#define ND_IFINFO(ifp) \
+       (((struct in6_ifextra *)(ifp)->if_afdata[AF_INET6])->nd_ifinfo)
+#define IN6_LINKMTU(ifp) \
+       ((ND_IFINFO(ifp)->linkmtu && ND_IFINFO(ifp)->linkmtu < (ifp)->if_mtu) \
+               ? ND_IFINFO(ifp)->linkmtu \
+               : ((ND_IFINFO(ifp)->maxmtu && ND_IFINFO(ifp)->maxmtu < (ifp)->if_mtu) \
+                       ? ND_IFINFO(ifp)->maxmtu : (ifp)->if_mtu))
+#endif
+
 struct in6_nbrinfo {
        char ifname[IFNAMSIZ];  /* if name, e.g. "en0" */
        struct in6_addr addr;   /* IPv6 address of the neighbor */
@@ -342,7 +353,8 @@ union nd_opts {
 /* XXX: need nd6_var.h?? */
 /* nd6.c */
 void nd6_init (void);
-void nd6_ifattach (struct ifnet *);
+struct nd_ifinfo *nd6_ifattach (struct ifnet *);
+void nd6_ifdetach (struct nd_ifinfo *);
 int nd6_is_addr_neighbor (struct sockaddr_in6 *, struct ifnet *);
 void nd6_option_init (void *, int, union nd_opts *);
 struct nd_opt_hdr *nd6_option (union nd_opts *);
index 9c0f0bc..225ee4d 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.9 2005/01/06 17:59:32 hsu Exp $      */
+/*     $DragonFly: src/sys/netinet6/nd6_nbr.c,v 1.10 2005/02/01 16:09:37 hrs Exp $     */
 /*     $KAME: nd6_nbr.c,v 1.86 2002/01/21 02:33:04 jinmei Exp $        */
 
 /*
@@ -657,7 +657,7 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
                        ln->ln_byhint = 0;
                        if (ln->ln_expire)
                                ln->ln_expire = time_second +
-                                   nd_ifinfo[rt->rt_ifp->if_index].reachable;
+                                   ND_IFINFO(rt->rt_ifp)->reachable;
                } else {
                        ln->ln_state = ND6_LLINFO_STALE;
                        ln->ln_expire = time_second + nd6_gctimer;
@@ -738,7 +738,7 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
                                ln->ln_byhint = 0;
                                if (ln->ln_expire) {
                                        ln->ln_expire = time_second +
-                                           nd_ifinfo[ifp->if_index].reachable;
+                                           ND_IFINFO(ifp)->reachable;
                                }
                        } else {
                                if (lladdr && llchange) {
@@ -1088,8 +1088,8 @@ nd6_dad_start(struct ifaddr *ifa,
        dp->dad_ns_ocount = dp->dad_ns_tcount = 0;
        if (tick == NULL) {
                nd6_dad_ns_output(dp, ifa);
-               nd6_dad_starttimer(dp, 
-                   nd_ifinfo[ifa->ifa_ifp->if_index].retrans * hz / 1000);
+               nd6_dad_starttimer(dp,
+                   ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000);
        } else {
                int ntick;
 
@@ -1178,8 +1178,8 @@ nd6_dad_timer(struct ifaddr *ifa)
                 * We have more NS to go.  Send NS packet for DAD.
                 */
                nd6_dad_ns_output(dp, ifa);
-               nd6_dad_starttimer(dp, 
-                   nd_ifinfo[ifa->ifa_ifp->if_index].retrans * hz / 1000);
+               nd6_dad_starttimer(dp,
+                       ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000);
        } else {
                /*
                 * We have transmitted sufficient number of DAD packets.
index e8a5785..8b8f2d6 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.7 2004/12/30 02:26:12 hsu Exp $      */
+/*     $DragonFly: src/sys/netinet6/nd6_rtr.c,v 1.8 2005/02/01 16:09:37 hrs Exp $      */
 /*     $KAME: nd6_rtr.c,v 1.111 2001/04/27 01:37:15 jinmei Exp $       */
 
 /*
@@ -205,7 +205,7 @@ nd6_ra_input(m, off, icmp6len)
        int off, icmp6len;
 {
        struct ifnet *ifp = m->m_pkthdr.rcvif;
-       struct nd_ifinfo *ndi = &nd_ifinfo[ifp->if_index];
+       struct nd_ifinfo *ndi = ND_IFINFO(ifp);
        struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
        struct nd_router_advert *nd_ra;
        struct in6_addr saddr6 = ip6->ip6_src;
index 189f936..0c9ff9b 100644 (file)
@@ -1,5 +1,5 @@
 /*     $FreeBSD: src/sys/netinet6/scope6.c,v 1.1.2.3 2002/04/01 15:29:04 ume Exp $     */
-/*     $DragonFly: src/sys/netinet6/scope6.c,v 1.3 2004/05/20 18:30:36 cpressey Exp $  */
+/*     $DragonFly: src/sys/netinet6/scope6.c,v 1.4 2005/02/01 16:09:37 hrs Exp $       */
 /*     $KAME: scope6.c,v 1.10 2000/07/24 13:29:31 itojun Exp $ */
 
 /*
 #include <netinet6/in6_var.h>
 #include <netinet6/scope6_var.h>
 
-struct scope6_id {
-       /*
-        * 16 is correspondent to 4bit multicast scope field.
-        * i.e. from node-local to global with some reserved/unassigned types.
-        */
-       u_int32_t s6id_list[16];
-};
-static size_t if_indexlim = 8;
-struct scope6_id *scope6_ids = NULL;
+static struct scope6_id sid_default;
+#define SID(ifp) \
+       (((struct in6_ifextra *)(ifp)->if_afdata[AF_INET6])->scope6_id)
 
 void
+scope6_init()
+{
+       bzero(&sid_default, sizeof(sid_default));
+}
+
+struct scope6_id *
 scope6_ifattach(struct ifnet *ifp)
 {
        int s = splnet();
+       struct scope6_id *sid;
 
-       /*
-        * We have some arrays that should be indexed by if_index.
-        * since if_index will grow dynamically, they should grow too.
-        */
-       if (scope6_ids == NULL || if_index >= if_indexlim) {
-               size_t n;
-               caddr_t q;
-
-               while (if_index >= if_indexlim)
-                       if_indexlim <<= 1;
-
-               /* grow scope index array */
-               n = if_indexlim * sizeof(struct scope6_id);
-               /* XXX: need new malloc type? */
-               q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK);
-               bzero(q, n);
-               if (scope6_ids) {
-                       bcopy((caddr_t)scope6_ids, q, n/2);
-                       free((caddr_t)scope6_ids, M_IFADDR);
-               }
-               scope6_ids = (struct scope6_id *)q;
-       }
-
-#define SID scope6_ids[ifp->if_index]
-
-       /* don't initialize if called twice */
-       if (SID.s6id_list[IPV6_ADDR_SCOPE_LINKLOCAL]) {
-               splx(s);
-               return;
-       }
+       sid = (struct scope6_id *)malloc(sizeof(*sid), M_IFADDR, M_WAITOK);
+       bzero(sid, sizeof(*sid));
 
        /*
         * XXX: IPV6_ADDR_SCOPE_xxx macros are not standard.
         * Should we rather hardcode here?
         */
-       SID.s6id_list[IPV6_ADDR_SCOPE_LINKLOCAL] = ifp->if_index;
+       sid->s6id_list[IPV6_ADDR_SCOPE_NODELOCAL] = ifp->if_index;
+       sid->s6id_list[IPV6_ADDR_SCOPE_LINKLOCAL] = ifp->if_index;
 #ifdef MULTI_SCOPE
        /* by default, we don't care about scope boundary for these scopes. */
-       SID.s6id_list[IPV6_ADDR_SCOPE_SITELOCAL] = 1;
-       SID.s6id_list[IPV6_ADDR_SCOPE_ORGLOCAL] = 1;
+       sid->s6id_list[IPV6_ADDR_SCOPE_SITELOCAL] = 1;
+       sid->s6id_list[IPV6_ADDR_SCOPE_ORGLOCAL] = 1;
 #endif
-#undef SID
 
        splx(s);
+       return sid;
+}
+
+void
+scope6_ifdetach(struct scope6_id *sid)
+{
+       free(sid, M_IFADDR);
 }
 
 int
-scope6_set(struct ifnet *ifp, u_int32_t *idlist)
+scope6_set(struct ifnet *ifp, struct scope6_id *idlist)
 {
        int i, s;
        int error = 0;
+       struct scope6_id *sid = SID(ifp);
 
-       if (scope6_ids == NULL) /* paranoid? */
+       if (!sid)       /* paranoid? */
                return(EINVAL);
 
        /*
@@ -129,10 +110,10 @@ scope6_set(struct ifnet *ifp, u_int32_t *idlist)
        s = splnet();
 
        for (i = 0; i < 16; i++) {
-               if (idlist[i] &&
-                   idlist[i] != scope6_ids[ifp->if_index].s6id_list[i]) {
+               if (idlist->s6id_list[i] &&
+                   idlist->s6id_list[i] != sid->s6id_list[i]) {
                        if (i == IPV6_ADDR_SCOPE_LINKLOCAL &&
-                           idlist[i] > if_index) {
+                           idlist->s6id_list[i] > if_index) {
                                /*
                                 * XXX: theoretically, there should be no
                                 * relationship between link IDs and interface
@@ -148,7 +129,7 @@ scope6_set(struct ifnet *ifp, u_int32_t *idlist)
                         * but we simply set the new value in this initial
                         * implementation.
                         */
-                       scope6_ids[ifp->if_index].s6id_list[i] = idlist[i];
+                       sid->s6id_list[i] = idlist->s6id_list[i];
                }
        }
        splx(s);
@@ -157,13 +138,14 @@ scope6_set(struct ifnet *ifp, u_int32_t *idlist)
 }
 
 int
-scope6_get(struct ifnet *ifp, u_int32_t *idlist)
+scope6_get(struct ifnet *ifp, struct scope6_id *idlist)
 {
-       if (scope6_ids == NULL) /* paranoid? */
+       struct scope6_id *sid = SID(ifp);
+
+       if (sid == NULL)        /* paranoid? */
                return(EINVAL);
 
-       bcopy(scope6_ids[ifp->if_index].s6id_list, idlist,
-             sizeof(scope6_ids[ifp->if_index].s6id_list));
+       *idlist = *sid;
 
        return(0);
 }
@@ -231,58 +213,71 @@ int
 in6_addr2scopeid(struct ifnet *ifp,    /* must not be NULL */
                 struct in6_addr *addr) /* must not be NULL */
 {
-       int scope = in6_addrscope(addr);
+       int scope;
+       struct scope6_id *sid = SID(ifp);
+
+#ifdef DIAGNOSTIC
+       if (sid == NULL) { /* should not happen */
+               panic("in6_addr2zoneid: scope array is NULL");
+               /* NOTREACHED */
+       }
+#endif
 
-       if (scope6_ids == NULL) /* paranoid? */
-               return(0);      /* XXX */
-       if (ifp->if_index >= if_indexlim)
-               return(0);      /* XXX */
+       /*
+        * special case: the loopback address can only belong to a loopback
+        * interface.
+        */
+       if (IN6_IS_ADDR_LOOPBACK(addr)) {
+               if (!(ifp->if_flags & IFF_LOOPBACK))
+                       return (-1);
+               else
+                       return (0); /* there's no ambiguity */
+       }
+
+       scope = in6_addrscope(addr);
 
-#define SID scope6_ids[ifp->if_index]
        switch(scope) {
        case IPV6_ADDR_SCOPE_NODELOCAL:
                return(-1);     /* XXX: is this an appropriate value? */
 
        case IPV6_ADDR_SCOPE_LINKLOCAL:
-               return(SID.s6id_list[IPV6_ADDR_SCOPE_LINKLOCAL]);
+               return (sid->s6id_list[IPV6_ADDR_SCOPE_LINKLOCAL]);
 
        case IPV6_ADDR_SCOPE_SITELOCAL:
-               return(SID.s6id_list[IPV6_ADDR_SCOPE_SITELOCAL]);
+               return (sid->s6id_list[IPV6_ADDR_SCOPE_SITELOCAL]);
 
        case IPV6_ADDR_SCOPE_ORGLOCAL:
-               return(SID.s6id_list[IPV6_ADDR_SCOPE_ORGLOCAL]);
+               return (sid->s6id_list[IPV6_ADDR_SCOPE_ORGLOCAL]);
 
        default:
                return(0);      /* XXX: treat as global. */
        }
-#undef SID
 }
 
 void
 scope6_setdefault(struct ifnet *ifp)   /* note that this might be NULL */
 {
        /*
-        * Currently, this function just set the default "link" according to
-        * the given interface.
+        * Currently, this function just set the default "interfaces"
+        * and "links" according to the given interface.
         * We might eventually have to separate the notion of "link" from
         * "interface" and provide a user interface to set the default.
         */
        if (ifp) {
-               scope6_ids[0].s6id_list[IPV6_ADDR_SCOPE_LINKLOCAL] =
+               sid_default.s6id_list[IPV6_ADDR_SCOPE_NODELOCAL] =
+                       ifp->if_index;
+               sid_default.s6id_list[IPV6_ADDR_SCOPE_LINKLOCAL] =
                        ifp->if_index;
+       } else {
+               sid_default.s6id_list[IPV6_ADDR_SCOPE_NODELOCAL] = 0;
+               sid_default.s6id_list[IPV6_ADDR_SCOPE_LINKLOCAL] = 0;
        }
-       else
-               scope6_ids[0].s6id_list[IPV6_ADDR_SCOPE_LINKLOCAL] = 0;
 }
 
 int
-scope6_get_default(u_int32_t *idlist)
+scope6_get_default(struct scope6_id *idlist)
 {
-       if (scope6_ids == NULL) /* paranoid? */
-               return(EINVAL);
-
-       bcopy(scope6_ids[0].s6id_list, idlist,
-             sizeof(scope6_ids[0].s6id_list));
+       *idlist = sid_default;
 
        return(0);
 }
@@ -290,5 +285,12 @@ scope6_get_default(u_int32_t *idlist)
 u_int32_t
 scope6_addr2default(struct in6_addr *addr)
 {
-       return(scope6_ids[0].s6id_list[in6_addrscope(addr)]);
+       /*
+        * special case: The loopback address should be considered as
+        * link-local, but there's no ambiguity in the syntax.
+        */
+       if (IN6_IS_ADDR_LOOPBACK(addr))
+               return (0);
+
+       return (sid_default.s6id_list[in6_addrscope(addr)]);
 }
index 63ec878..dd3d88d 100644 (file)
@@ -1,5 +1,5 @@
 /*     $FreeBSD: src/sys/netinet6/scope6_var.h,v 1.1.2.1 2000/07/15 07:14:38 kris Exp $        */
-/*     $DragonFly: src/sys/netinet6/scope6_var.h,v 1.3 2003/08/23 11:02:46 rob Exp $   */
+/*     $DragonFly: src/sys/netinet6/scope6_var.h,v 1.4 2005/02/01 16:09:37 hrs Exp $   */
 /*     $KAME: scope6_var.h,v 1.4 2000/05/18 15:03:27 jinmei Exp $      */
 
 /*
 #define _NETINET6_SCOPE6_VAR_H_
 
 #ifdef _KERNEL
-void   scope6_ifattach (struct ifnet *);
-int    scope6_set (struct ifnet *, u_int32_t *);
-int    scope6_get (struct ifnet *, u_int32_t *);
+struct scope6_id {
+       /*
+        * 16 is correspondent to 4bit multicast scope field.
+        * i.e. from node-local to global with some reserved/unassigned types.
+        */
+       u_int32_t s6id_list[16];
+};
+
+void   scope6_init (void);
+struct scope6_id *scope6_ifattach (struct ifnet *);
+void   scope6_ifdetach (struct scope6_id *);
+int    scope6_set (struct ifnet *, struct scope6_id *);
+int    scope6_get (struct ifnet *, struct scope6_id *);
 void   scope6_setdefault (struct ifnet *);
-int    scope6_get_default (u_int32_t *);
+int    scope6_get_default (struct scope6_id *);
 u_int32_t scope6_in6_addrscope (struct in6_addr *);
 u_int32_t scope6_addr2default (struct in6_addr *);
 #endif /* _KERNEL */
index 10ec8c6..ca47b7e 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)domain.h    8.1 (Berkeley) 6/2/93
  * $FreeBSD: src/sys/sys/domain.h,v 1.14 1999/12/29 04:24:40 peter Exp $
- * $DragonFly: src/sys/sys/domain.h,v 1.4 2004/12/14 18:46:08 hsu Exp $
+ * $DragonFly: src/sys/sys/domain.h,v 1.5 2005/02/01 16:09:37 hrs Exp $
  */
 
 #ifndef _SYS_DOMAIN_H_
@@ -46,6 +46,7 @@
  * Forward structure declarations for function prototypes [sic].
  */
 struct mbuf;
+struct ifnet;
 
 struct domain {
        int     dom_family;             /* AF_xxx */
@@ -61,6 +62,9 @@ struct        domain {
        int     (*dom_rtattach)(void **, int);  /* initialize routing table */
        int     dom_rtoffset;           /* an arg to rtattach, in bits */
        int     dom_maxrtkey;           /* for routing layer */
+       void    *(*dom_ifattach)(struct ifnet *);
+       void    (*dom_ifdetach)(struct ifnet *, void *);
+                                       /* af-dependent data on ifnet */
 };
 
 #ifdef _KERNEL
index f774498..9ffedaf 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.11 2004/03/30 17:18:58 joerg Exp $
+ * $DragonFly: src/sys/sys/kernel.h,v 1.12 2005/02/01 16:09:37 hrs Exp $
  */
 
 #ifndef _SYS_KERNEL_H_
@@ -140,6 +140,7 @@ enum sysinit_sub_id {
        SI_SUB_PROTO_BEGIN      = 0x8000000,    /* XXX: set splimp (kludge)*/
        SI_SUB_PROTO_IF         = 0x8400000,    /* interfaces*/
        SI_SUB_PROTO_DOMAIN     = 0x8800000,    /* domains (address families?)*/
+       SI_SUB_PROTO_IFATTACHDOMAIN     = 0x8800001,    /* domain dependent data init */
        SI_SUB_PROTO_END        = 0x8ffffff,    /* XXX: set splx (kludge)*/
        SI_SUB_KPROF            = 0x9000000,    /* kernel profiling*/
        SI_SUB_KICK_SCHEDULER   = 0xa000000,    /* start the timeout events*/