diff options
-rw-r--r-- | sys/net/if.c | 48 | ||||
-rw-r--r-- | sys/net/if_var.h | 2 | ||||
-rw-r--r-- | sys/netinet/icmp6.h | 9 | ||||
-rw-r--r-- | sys/netinet/tcp_input.c | 3 | ||||
-rw-r--r-- | sys/netinet/tcp_reass.c | 3 | ||||
-rw-r--r-- | sys/netinet6/icmp6.c | 2 | ||||
-rw-r--r-- | sys/netinet6/in6.c | 85 | ||||
-rw-r--r-- | sys/netinet6/in6_ifattach.c | 71 | ||||
-rw-r--r-- | sys/netinet6/in6_proto.c | 3 | ||||
-rw-r--r-- | sys/netinet6/in6_src.c | 2 | ||||
-rw-r--r-- | sys/netinet6/in6_var.h | 22 | ||||
-rw-r--r-- | sys/netinet6/ip6_input.c | 8 | ||||
-rw-r--r-- | sys/netinet6/ip6_output.c | 4 | ||||
-rw-r--r-- | sys/netinet6/nd6.c | 146 | ||||
-rw-r--r-- | sys/netinet6/nd6.h | 14 | ||||
-rw-r--r-- | sys/netinet6/nd6_nbr.c | 10 | ||||
-rw-r--r-- | sys/netinet6/nd6_rtr.c | 2 | ||||
-rw-r--r-- | sys/netinet6/scope6.c | 153 | ||||
-rw-r--r-- | sys/netinet6/scope6_var.h | 18 | ||||
-rw-r--r-- | sys/sys/domain.h | 4 | ||||
-rw-r--r-- | sys/sys/kernel.h | 1 |
21 files changed, 313 insertions, 297 deletions
diff --git a/sys/net/if.c b/sys/net/if.c index 6f3091b..9423d29 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -54,6 +54,7 @@ #include <sys/sockio.h> #include <sys/syslog.h> #include <sys/sysctl.h> +#include <sys/domain.h> #include <sys/jail.h> #include <machine/stdarg.h> @@ -78,6 +79,8 @@ #include <netinet/if_ether.h> #endif +static void if_attachdomain(void *); +static void if_attachdomain1(struct ifnet *); static int ifconf(u_long, caddr_t); static void if_grow(void); static void if_init(void *); @@ -442,10 +445,48 @@ if_attach(ifp) } ifp->if_broadcastaddr = 0; /* reliably crash if used uninitialized */ + if (domains) + if_attachdomain1(ifp); + /* Announce the interface. */ rt_ifannouncemsg(ifp, IFAN_ARRIVAL); } +static void +if_attachdomain(dummy) + 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(ifp) + 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. @@ -458,6 +499,7 @@ if_detach(ifp) struct radix_node_head *rnh; int s; int i; + struct domain *dp; /* * Remove routes and flush queues. @@ -538,6 +580,12 @@ if_detach(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]); + } + #ifdef MAC mac_destroy_ifnet(ifp); #endif /* MAC */ diff --git a/sys/net/if_var.h b/sys/net/if_var.h index 4c95804..a1dc0b6 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -178,6 +178,8 @@ struct ifnet { struct ifprefixhead if_prefixhead; /* list of prefixes per if */ u_int8_t *if_broadcastaddr; /* linklevel broadcast bytestring */ struct label if_label; /* interface MAC label */ + + void *if_afdata[AF_MAX]; }; typedef void if_init_f_t(void *); diff --git a/sys/netinet/icmp6.h b/sys/netinet/icmp6.h index 5d7ca8b..2d29006 100644 --- a/sys/netinet/icmp6.h +++ b/sys/netinet/icmp6.h @@ -649,11 +649,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 (/*CONSTCOND*/ 0) #define icmp6_ifoutstat_inc(ifp, type, code) \ @@ -661,7 +658,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) \ diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 54a87bc..9d8d733 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -2712,8 +2712,7 @@ tcp_mss(tp, 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 { diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c index 54a87bc..9d8d733 100644 --- a/sys/netinet/tcp_reass.c +++ b/sys/netinet/tcp_reass.c @@ -2712,8 +2712,7 @@ tcp_mss(tp, 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 { diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index 32d01ce..642b7bd 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -2158,7 +2158,7 @@ icmp6_reflect(m, 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; diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index b3b6feb..9faa341 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -420,14 +420,14 @@ in6_control(so, cmd, data, ifp, td) case SIOCSSCOPE6: if (!privileged) return (EPERM); - return (scope6_set(ifp, ifr->ifr_ifru.ifru_scope_id)); - break; + return (scope6_set(ifp, + (struct scope6_id *)ifr->ifr_ifru.ifru_scope_id)); case SIOCGSCOPE6: - return (scope6_get(ifp, ifr->ifr_ifru.ifru_scope_id)); - break; + return (scope6_get(ifp, + (struct scope6_id *)ifr->ifr_ifru.ifru_scope_id)); case SIOCGSCOPE6DEF: - return (scope6_get_default(ifr->ifr_ifru.ifru_scope_id)); - break; + return (scope6_get_default((struct scope6_id *) + ifr->ifr_ifru.ifru_scope_id)); } switch (cmd) { @@ -560,28 +560,19 @@ in6_control(so, cmd, data, ifp, td) break; 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: @@ -1110,13 +1101,6 @@ in6_update_ifa(ifp, ifra, ia) 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 * disable DAD. @@ -2341,14 +2325,51 @@ in6_setmaxmtu() IFNET_RLOCK(); 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; } IFNET_RUNLOCK(); if (maxmtu) /* update only when maxmtu is positive */ in6_maxmtu = maxmtu; } +void * +in6_domifattach(ifp) + 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(ifp, aux) + 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 diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c index 6b9707c..7e6f4c7 100644 --- a/sys/netinet6/in6_ifattach.c +++ b/sys/netinet6/in6_ifattach.c @@ -60,10 +60,6 @@ #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 @@ -727,7 +723,6 @@ in6_ifattach(ifp, altifp) struct ifnet *ifp; struct ifnet *altifp; /* secondary EUI64 source */ { - static size_t if_indexlim = 8; struct in6_ifaddr *ia; struct in6_addr in6; @@ -740,50 +735,6 @@ in6_ifattach(ifp, altifp) } /* - * 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 */ switch (ifp->if_type) { @@ -844,20 +795,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); } /* @@ -987,7 +924,7 @@ in6_get_tmpifid(ifp, retbuf, baseid, generate) 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) { @@ -1009,9 +946,9 @@ void in6_tmpaddrtimer(ignored_arg) 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, @@ -1019,8 +956,8 @@ in6_tmpaddrtimer(ignored_arg) ip6_temp_regen_advance) * hz, 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. diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c index 893dba2..7f477a6 100644 --- a/sys/netinet6/in6_proto.c +++ b/sys/netinet6/in6_proto.c @@ -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); diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c index c2acf30..6f81fe7 100644 --- a/sys/netinet6/in6_src.c +++ b/sys/netinet6/in6_src.c @@ -300,7 +300,7 @@ in6_selecthlim(in6p, 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); } diff --git a/sys/netinet6/in6_var.h b/sys/netinet6/in6_var.h index 0042eec..098eb9f 100644 --- a/sys/netinet6/in6_var.h +++ b/sys/netinet6/in6_var.h @@ -90,6 +90,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 @@ -445,18 +454,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 (/*CONSTCOND*/ 0) extern struct in6_addr zeroin6_addr; @@ -576,6 +578,8 @@ void in6_purgeaddr __P((struct ifaddr *)); int in6if_do_dad __P((struct ifnet *)); void in6_purgeif __P((struct ifnet *)); void in6_savemkludge __P((struct in6_ifaddr *)); +void *in6_domifattach __P((struct ifnet *)); +void in6_domifdetach __P((struct ifnet *, void *)); void in6_setmaxmtu __P((void)); void in6_restoremkludge __P((struct in6_ifaddr *, struct ifnet *)); void in6_purgemkludge __P((struct ifnet *)); diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index 01bd0ca..8062ffe 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -106,6 +106,7 @@ #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> @@ -196,6 +197,7 @@ ip6_init() ip6intrq.ifq_maxlen = ip6qmaxlen; mtx_init(&ip6intrq.ifq_mtx, "ip6_inq", NULL, MTX_DEF); netisr_register(NETISR_IPV6, ip6_input, &ip6intrq); + scope6_init(); nd6_init(); frag6_init(); #ifndef RANDOM_IP_ID @@ -209,12 +211,6 @@ ip6_init2(dummy) 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, 0); callout_reset(&nd6_timer_ch, hz, nd6_timer, NULL); diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index 55eb3c3..1f0c0cc 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -794,7 +794,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) { @@ -814,7 +814,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; } /* diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index be14f33..e091dee 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -98,14 +98,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 __P((struct ifnet *, struct nd_ifinfo *)); static void nd6_slowtimo __P((void *)); static int regen_tmpaddr __P((struct in6_ifaddr *)); @@ -139,59 +138,42 @@ nd6_init() nd6_slowtimo, NULL); } -void +struct nd_ifinfo * nd6_ifattach(ifp) 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] - - /* - * 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->initialized = 1; - ND.linkmtu = ifnet_byindex(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 = ifnet_byindex(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(nd) + struct nd_ifinfo *nd; +{ + + free(nd, M_IP6NDP); } /* @@ -202,9 +184,21 @@ void nd6_setmtu(ifp) 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(ifp, ndi) + 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 */ @@ -446,7 +440,7 @@ nd6_timer(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) { @@ -468,7 +462,7 @@ nd6_timer(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 { @@ -523,7 +517,7 @@ nd6_timer(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 { @@ -1079,7 +1073,7 @@ nd6_nud_hint(rt, dst6, 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 @@ -1453,35 +1447,23 @@ nd6_ioctl(cmd, data, 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 */ @@ -1824,15 +1806,13 @@ nd6_slowtimo(ignored_arg) 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) { /* @@ -1946,7 +1926,7 @@ nd6_output(ifp, origifp, m0, dst, rt0) } 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", @@ -2004,7 +1984,7 @@ nd6_output(ifp, origifp, m0, dst, rt0) 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); } } diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h index e8bf02e..2ee4a48 100644 --- a/sys/netinet6/nd6.h +++ b/sys/netinet6/nd6.h @@ -80,6 +80,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) */ @@ -89,6 +90,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 */ @@ -341,7 +352,8 @@ union nd_opts { /* XXX: need nd6_var.h?? */ /* nd6.c */ void nd6_init __P((void)); -void nd6_ifattach __P((struct ifnet *)); +struct nd_ifinfo *nd6_ifattach __P((struct ifnet *)); +void nd6_ifdetach __P((struct nd_ifinfo *)); int nd6_is_addr_neighbor __P((struct sockaddr_in6 *, struct ifnet *)); void nd6_option_init __P((void *, int, union nd_opts *)); struct nd_opt_hdr *nd6_option __P((union nd_opts *)); diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c index 7a56bad..0cac161 100644 --- a/sys/netinet6/nd6_nbr.c +++ b/sys/netinet6/nd6_nbr.c @@ -641,7 +641,7 @@ nd6_na_input(m, off, 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; @@ -723,7 +723,7 @@ nd6_na_input(m, off, 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) { @@ -1081,8 +1081,8 @@ nd6_dad_start(ifa, tick) 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; @@ -1174,7 +1174,7 @@ nd6_dad_timer(ifa) */ nd6_dad_ns_output(dp, ifa); nd6_dad_starttimer(dp, - nd_ifinfo[ifa->ifa_ifp->if_index].retrans * hz / 1000); + ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000); } else { /* * We have transmitted sufficient number of DAD packets. diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c index 65d219d..bf50a7c 100644 --- a/sys/netinet6/nd6_rtr.c +++ b/sys/netinet6/nd6_rtr.c @@ -202,7 +202,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; diff --git a/sys/netinet6/scope6.c b/sys/netinet6/scope6.c index 1e6c135..fbb681a 100644 --- a/sys/netinet6/scope6.c +++ b/sys/netinet6/scope6.c @@ -45,77 +45,61 @@ #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(ifp) 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(sid) + struct scope6_id *sid; +{ + + free(sid, M_IFADDR); } int scope6_set(ifp, idlist) struct ifnet *ifp; - u_int32_t *idlist; + 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); /* @@ -131,10 +115,10 @@ scope6_set(ifp, 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 @@ -150,7 +134,7 @@ scope6_set(ifp, 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); @@ -161,13 +145,14 @@ scope6_set(ifp, idlist) int scope6_get(ifp, idlist) struct ifnet *ifp; - u_int32_t *idlist; + 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); } @@ -237,31 +222,45 @@ in6_addr2scopeid(ifp, addr) 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 + + /* + * 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 */ + } - if (scope6_ids == NULL) /* paranoid? */ - return (0); /* XXX */ - if (ifp->if_index >= if_indexlim) - return (0); /* XXX */ + 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 @@ -269,28 +268,27 @@ scope6_setdefault(ifp) 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 { - scope6_ids[0].s6id_list[IPV6_ADDR_SCOPE_LINKLOCAL] = 0; + sid_default.s6id_list[IPV6_ADDR_SCOPE_NODELOCAL] = 0; + sid_default.s6id_list[IPV6_ADDR_SCOPE_LINKLOCAL] = 0; } } int scope6_get_default(idlist) - u_int32_t *idlist; + 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); } @@ -299,5 +297,12 @@ u_int32_t scope6_addr2default(addr) 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)]); } diff --git a/sys/netinet6/scope6_var.h b/sys/netinet6/scope6_var.h index b4eda9c..0744d48 100644 --- a/sys/netinet6/scope6_var.h +++ b/sys/netinet6/scope6_var.h @@ -34,11 +34,21 @@ #define _NETINET6_SCOPE6_VAR_H_ #ifdef _KERNEL -void scope6_ifattach __P((struct ifnet *)); -int scope6_set __P((struct ifnet *, u_int32_t *)); -int scope6_get __P((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 __P((void)); +struct scope6_id *scope6_ifattach __P((struct ifnet *)); +void scope6_ifdetach __P((struct scope6_id *)); +int scope6_set __P((struct ifnet *, struct scope6_id *)); +int scope6_get __P((struct ifnet *, struct scope6_id *)); void scope6_setdefault __P((struct ifnet *)); -int scope6_get_default __P((u_int32_t *)); +int scope6_get_default __P((struct scope6_id *)); u_int32_t scope6_in6_addrscope __P((struct in6_addr *)); u_int32_t scope6_addr2default __P((struct in6_addr *)); #endif /* _KERNEL */ diff --git a/sys/sys/domain.h b/sys/sys/domain.h index 77b8ad8..b5e29c9 100644 --- a/sys/sys/domain.h +++ b/sys/sys/domain.h @@ -45,6 +45,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 { (void **, int); 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 diff --git a/sys/sys/kernel.h b/sys/sys/kernel.h index f8a5423..fe75bf2 100644 --- a/sys/sys/kernel.h +++ b/sys/sys/kernel.h @@ -151,6 +151,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*/ |