Index: sys/i386/conf/LIMUNES =================================================================== RCS file: /home/xbone/CVSROOT/netmerge/4.11-ipv6/sys/i386/conf/LIMUNES,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- sys/i386/conf/LIMUNES 10 May 2005 20:39:22 -0000 1.1 +++ sys/i386/conf/LIMUNES 14 Jun 2005 04:37:30 -0000 1.3 @@ -7,7 +7,8 @@ #makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols options INET #InterNETworking -#options INET6 #IPv6 communications protocols +options INET6 #IPv6 communications protocols +options NETCONTEXTSWITCHING # Enable Network Context switching for gifs options FFS #Berkeley Fast Filesystem options FFS_ROOT #FFS usable as root device [keep this!] options SOFTUPDATES #Enable FFS soft updates support @@ -132,6 +133,7 @@ pseudo-device tun # Packet tunnel. pseudo-device pty # Pseudo-ttys (telnet etc) pseudo-device md # Memory "disks" +pseudo-device gif # Memory "disks" # The `bpf' pseudo-device enables the Berkeley Packet Filter. # Be aware of the administrative consequences of enabling this! Index: sys/kern/kern_vimage.c =================================================================== RCS file: /home/xbone/CVSROOT/netmerge/4.11-ipv6/sys/kern/kern_vimage.c,v retrieving revision 1.1 retrieving revision 1.6 diff -u -r1.1 -r1.6 --- sys/kern/kern_vimage.c 10 May 2005 20:39:23 -0000 1.1 +++ sys/kern/kern_vimage.c 14 Jun 2005 04:47:43 -0000 1.6 @@ -54,6 +54,7 @@ #include #include +#include /* Arbitrary values */ #define TCP_SYNCACHE_HASHSIZE 512 @@ -118,6 +119,19 @@ struct vnet *vintr = NULL; +struct vimage *vnet_vip(vnet) + struct vnet *vnet; +{ + struct vimage *vip; + + LIST_FOREACH(vip, &vimage_head, vi_le) + if (vip->v_net == vnet) + return(vip); + + panic("vnet_vip"); /* must not happen */ +} + + char *vnet_name(vnet) struct vnet *vnet; { @@ -189,6 +203,7 @@ if (vi_req == NULL || strcmp(vi_req->vi_name, "-") == 0) { if (vip == vimage0) return (ENXIO); + new_vip = vip->vi_parent; new_vnet = vip->vi_parent->v_net; } else LIST_FOREACH(new_vip, &vimage_head, vi_le) { @@ -229,6 +244,9 @@ case IFT_L2VLAN: ether_ifdetach(ifp, ETHER_BPF_SUPPORTED); break; + case IFT_GIF: + gif_move_detach(ifp); + break; default: if_detach(ifp); } @@ -244,7 +262,12 @@ if (vip->vi_parent != NULL && new_vnet == vip->vi_parent->v_net && ifp->if_rname != NULL) { ifp->if_name = ifp->if_rname; +#ifndef NETCONTEXTSWITCHING + /* Always start with zero for to see which is the + first available interface unit number */ + unit = ifp->if_runit; +#endif } if (vi_req != NULL && strlen(vi_req->vi_parent_name) && unit == 0 ) { @@ -295,6 +318,29 @@ case IFT_L2VLAN: ether_ifattach(ifp, ETHER_BPF_SUPPORTED); break; + case IFT_GIF: + /* This should be the same code as gif_clone_create */ + if (1){ + struct gif_softc *sc = ifp->if_softc; + + sc->gif_vnet = ifp->if_vnet; + bzero(&sc->gif_list, sizeof(sc->gif_list)); + gif_move_attach(sc); + + /* XXX - Should be done based on user argument to + vimage [-??] -i ! */ + if (ifp->if_type == IFT_GIF){ + printf("cur vnet = %s, new vnet = %s \n", + vnet_name(cur_vnet), vnet_name(new_vnet)); + if (cur_vnet != new_vnet && new_vip->vi_parent == vip){ + printf("Setting switch for interface %s%d\n", + ifp->if_name, ifp->if_unit); + gif_setswitch(ifp); + } + } + }; + break; + default: if_attach(ifp); } @@ -717,7 +763,7 @@ (1 + 3*(vip->vi_id != 0)); vi_ifinit(vnet); - vi_loopattach(vnet); + /* vi_loopattach(vnet); */ for (dp = domains; dp; dp = dp->dom_next) for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++){ if (pr->pr_usrreqs == 0) @@ -728,7 +774,8 @@ (*pr->pr_init)(vnet); } - rtable_init((void **)vnet->rt_tables, vnet); + rtable_init((void **)vnet->rt_tables, vnet); + vi_loopattach(vnet); if (IPFW_LOADED) ip_fw_init_ptr(vnet); Index: sys/net/if.c =================================================================== RCS file: /home/xbone/CVSROOT/netmerge/4.11-ipv6/sys/net/if.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- sys/net/if.c 10 May 2005 20:25:38 -0000 1.2 +++ sys/net/if.c 14 Jun 2005 04:37:29 -0000 1.3 @@ -63,6 +63,8 @@ #include #include +#include + #if defined(INET) || defined(INET6) /*XXX*/ #include @@ -135,10 +137,13 @@ if_slowtimo(0); } -int if_index = 0; -struct ifaddr **ifnet_addrs; -struct ifnet **ifindex2ifnet = NULL; - +/* + * Commenting out to make sure that there is no non-stack + * if_index that is being accessed -Venkata June 03/05 + * int if_index = 0; + * struct ifaddr **ifnet_addrs; + * struct ifnet **ifindex2ifnet = NULL; + */ /* * Attach an interface to the Index: sys/net/if_gif.c =================================================================== RCS file: /home/xbone/CVSROOT/netmerge/4.11-ipv6/sys/net/if_gif.c,v retrieving revision 1.2 retrieving revision 1.6 diff -u -r1.2 -r1.6 --- sys/net/if_gif.c 10 May 2005 20:25:39 -0000 1.2 +++ sys/net/if_gif.c 14 Jun 2005 04:47:43 -0000 1.6 @@ -131,6 +131,59 @@ SYSCTL_INT(_net_link_gif, OID_AUTO, parallel_tunnels, CTLFLAG_RW, ¶llel_tunnels, 0, "Allow parallel tunnels?"); +void printgifs(msg) + char *msg; +{ + + struct vnet *vnet; + struct gif_softc *sc1; + + LIST_FOREACH(vnet, &vnet_head, vnet_le){ + LIST_FOREACH(sc1, &vnet->gif_softc_list, gif_list) { + printf("[%s][%s] (sc=%x) %s%d (prev = %x, next = %x (& = %x ), switch=%x (& = %x))\n", + vnet_name(vnet), msg, (u_int32_t)sc1, + ((u_int32_t)sc1->gif_if.if_name > 0x1000)? + sc1->gif_if.if_name : "NONAME", + sc1->gif_if.if_unit, + (u_int32_t)sc1->gif_list.le_prev, + (u_int32_t)sc1->gif_list.le_next, + (u_int32_t)&sc1->gif_list.le_next, + sc1->vnet_switch, (u_int32_t)&sc1->vnet_switch); + } + } +} + +/* + * Find a unit number that has not been assigned already. We dont use + * the resource starting address as the starting point. + */ +int +gif_find_freeunit(vnet) + struct vnet *vnet; +{ + int unit; + struct ifnet *ifp; + + unit = 0; + do { + TAILQ_FOREACH(ifp, &vnet->ifnet, if_link) { + if (strcmp(ifp->if_name, "gif")) + continue; + + if (unit == ifp->if_unit) + break; + } + unit++; + } while (ifp); + unit--; + + if (unit > GIF_MAXUNIT) + return -1; + else + return unit; +} + + int gif_clone_create(ifc, unit, vnet) struct if_clone *ifc; @@ -143,19 +196,22 @@ if (*unit > GIF_MAXUNIT) return (ENXIO); - if (*unit < 0) { - r = rman_reserve_resource(gifunits, 0, GIF_MAXUNIT, 1, - RF_ALLOCATED | RF_ACTIVE, NULL); - if (r == NULL) - return (ENOSPC); - *unit = rman_get_start(r); - } else { - r = rman_reserve_resource(gifunits, *unit, *unit, 1, - RF_ALLOCATED | RF_ACTIVE, NULL); - if (r == NULL) - return (EEXIST); - } - + r = rman_reserve_resource(gifunits, 0, GIF_MAXUNIT, 1, + RF_ALLOCATED | RF_ACTIVE, NULL); + if (r == NULL) + return (ENOSPC); + if (*unit < 0) { + /* *unit = rman_get_start(r); */ + *unit = gif_find_freeunit(vnet); + if ((*unit < 0) || (*unit > GIF_MAXUNIT)) { + int err = rman_release_resource(r); + KASSERT(err == 0, + ("Unexpected error freeing resource")); + return (ENXIO); + + } + } + sc = malloc (sizeof(struct gif_softc), M_GIF, M_WAITOK); bzero(sc, sizeof(struct gif_softc)); @@ -164,6 +220,7 @@ sc->gif_if.if_softc = sc; sc->gif_if.if_name = GIFNAME; sc->gif_if.if_unit = *unit; + sc->vnet_switch = 0; sc->r_unit = r; gifattach0(sc); @@ -194,6 +251,101 @@ bpfattach(&sc->gif_if, DLT_NULL, sizeof(u_int)); } +/* + * Function to attach an gif interface that is being moved between + * network contexts. This special handling is necessary to retain the + * tunnel outer addresses when a gif is pulled from one network + * context/vimage to another. + */ + +void +gif_move_attach(sc) + struct gif_softc *sc; +{ + struct vnet *vnet = sc->gif_vnet; + struct sockaddr *src = NULL, *dst = NULL; + int error = 0; + + gifattach0(sc); + LIST_INSERT_HEAD(&vnet->gif_softc_list, sc, gif_list); + + /* Now set the addresses back. There is no explicit + * ifconfig. So we need to call set_tunnel so that + * this tunnel gets added to the list of available + * tunnels endpoints. + */ + if (sc->gif_psrc){ src = sc->gif_psrc; sc->gif_psrc = NULL; } + if (sc->gif_pdst){ dst = sc->gif_pdst; sc->gif_pdst = NULL; } + if (src && dst){ + error = gif_set_tunnel(&sc->gif_if, src, dst); + } else { + error = 1; + } + + if (error) { + /* Quite possible that either only one of addresses is set + * in which case cleanup or that addition of the tunnels was + * not successful.Freeup the addresses. + */ + if (src) free((caddr_t)src, M_IFADDR); + if (dst) free((caddr_t)dst, M_IFADDR); + } +} + +/* + * Detaching a network interface before attaching it in a new + * context. This will remove the entry in the encapsulation header + * list. This is gif_clone_destroy without the freeing of data. + * -Venkata June 3/2005 + */ +void +gif_move_detach(ifp) + struct ifnet *ifp; +{ + int err; + struct gif_softc *sc = ifp->if_softc; + struct vnet *vnet = ifp->if_vnet; + struct sockaddr *osrc = NULL, *odst = NULL; + + /* We know that this interface is being moved. So copy the address */ + if (sc->gif_psrc) { + osrc = (struct sockaddr *)malloc(sc->gif_psrc->sa_len, M_IFADDR, M_WAITOK); + bcopy((caddr_t)sc->gif_psrc, (caddr_t)osrc, sc->gif_psrc->sa_len); + } + if (sc->gif_pdst) { + odst = (struct sockaddr *)malloc(sc->gif_pdst->sa_len, M_IFADDR, M_WAITOK); + bcopy((caddr_t)sc->gif_pdst, (caddr_t)odst, sc->gif_pdst->sa_len); + } + + /* cleanup all addresses */ + gif_delete_tunnel(&sc->gif_if); + + /* copy the addresses back. We need to call gif_set_tunnel with + * these addresses. + */ + sc->gif_psrc = osrc; + sc->gif_pdst = odst; + + LIST_REMOVE(sc, gif_list); + +#ifdef INET6 + if (sc->encap_cookie6 != NULL) { + err = encap_detach(sc->encap_cookie6, vnet); + KASSERT(err == 0, ("Unexpected error detaching encap_cookie6")); + } +#endif +#ifdef INET + if (sc->encap_cookie4 != NULL) { + err = encap_detach(sc->encap_cookie4, vnet); + KASSERT(err == 0, ("Unexpected error detaching encap_cookie4")); + } +#endif + + bpfdetach(ifp); + if_detach(ifp); + return; +} + void gif_clone_destroy(ifp) struct ifnet *ifp; @@ -778,7 +930,7 @@ int s; int error = 0; struct vnet *vnet = sc->gif_vnet; - + s = splnet(); LIST_FOREACH(sc2, &vnet->gif_softc_list, gif_list) { @@ -821,6 +973,7 @@ #endif } + osrc = sc->gif_psrc; sa = (struct sockaddr *)malloc(src->sa_len, M_IFADDR, M_WAITOK); bcopy((caddr_t)src, (caddr_t)sa, src->sa_len); @@ -906,3 +1059,13 @@ ifp->if_flags &= ~IFF_RUNNING; splx(s); } + +void gif_setswitch(ifp) + struct ifnet *ifp; +{ + + struct gif_softc *sc = (struct gif_softc *)ifp; + if (!sc) return; + sc->vnet_switch = 1; + return; +} Index: sys/net/if_gif.h =================================================================== RCS file: /home/xbone/CVSROOT/netmerge/4.11-ipv6/sys/net/if_gif.h,v retrieving revision 1.2 retrieving revision 1.4 diff -u -r1.2 -r1.4 --- sys/net/if_gif.h 10 May 2005 20:25:39 -0000 1.2 +++ sys/net/if_gif.h 14 Jun 2005 04:37:29 -0000 1.4 @@ -52,6 +52,8 @@ struct sockaddr *gif_psrc; /* Physical src addr */ struct sockaddr *gif_pdst; /* Physical dst addr */ struct vnet *gif_vnet; /* Physicalvnet */ + int vnet_switch; /* Should this gif be used to "exit" + the stack into parents?*/ union { struct route gifscr_ro; /* xxx */ #ifdef INET6 @@ -84,5 +86,8 @@ void gif_delete_tunnel __P((struct ifnet *)); int gif_encapcheck __P((const struct mbuf *, int, int, void *, struct vnet *)); - +void gif_setswitch __P((struct ifnet *)); +void gif_move_detach __P((struct ifnet *)); +void printgifs __P((char *)); +void gif_move_attach __P((struct gif_softc *)); #endif /* _NET_IF_GIF_H_ */ Index: sys/net/route.c =================================================================== RCS file: /home/xbone/CVSROOT/netmerge/4.11-ipv6/sys/net/route.c,v retrieving revision 1.2 retrieving revision 1.4 diff -u -r1.2 -r1.4 --- sys/net/route.c 10 May 2005 20:25:40 -0000 1.2 +++ sys/net/route.c 29 May 2005 02:05:25 -0000 1.4 @@ -65,9 +65,10 @@ { struct domain *dom; for (dom = domains; dom; dom = dom->dom_next) - if (dom->dom_rtattach) + if (dom->dom_rtattach){ dom->dom_rtattach(&table[dom->dom_family], dom->dom_rtoffset, vnet); + } } void @@ -123,8 +124,7 @@ u_long ignflags; struct vnet *vnet; { - register struct radix_node_head *rnh = - vnet->rt_tables[dst->sa_family]; + register struct radix_node_head *rnh; register struct rtentry *rt; register struct radix_node *rn; struct rtentry *newrt = 0; @@ -132,6 +132,15 @@ u_long nflags; int s = splnet(), err = 0, msgtype = RTM_MISS; + if (!vnet) { + return NULL; + } + + rnh = vnet->rt_tables[dst->sa_family]; + if (!rnh) { + return NULL; + } + /* * Look up the address in the table for that Address Family */ @@ -1133,6 +1142,8 @@ } #endif } + + /* * Do the actual request */ @@ -1167,6 +1178,7 @@ } if (m) (void) m_free(m); + return (error); } Index: sys/net/vnet.h =================================================================== RCS file: /home/xbone/CVSROOT/netmerge/4.11-ipv6/sys/net/vnet.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- sys/net/vnet.h 10 May 2005 20:39:26 -0000 1.1 +++ sys/net/vnet.h 26 May 2005 23:09:34 -0000 1.2 @@ -71,6 +71,11 @@ #include #include +#include +#include +#include +#include +#include #ifdef _KERNEL @@ -406,6 +411,20 @@ struct route ipx_sroute; /* from netipx/ipx_input.c */ struct ipxpcb ipxpcb; /* from netipx/ipx_input.c */ struct ipxpcb ipxrawpcb; /* from netipx/ipx_input.c */ + + /* IPv6 */ + struct llinfo_nd6 llinfo_nd6; /* from netinet6/nd6.c */ + size_t nd_ifinfo_indexlim; /* from netinet6/nd6.c */ + struct nd_ifinfo *nd_ifinfo; /* from netinet6/nd6.c */ + struct nd_drhead nd_defrouter; /* from netinet6/nd6.c */ + struct nd_prhead nd_prefix; /* from netinet6/nd6.c */ + + struct callout nd6_slowtimo_ch; /* from netinet6/nd6.c */ + struct callout nd6_timer_ch; /* from netinet6/nd6.c */ + int nd6_init_done; /* from netinet6/nd6.c */ + + struct callout in6_tmpaddrtimer_ch; /* from netinet6/in6_ifattach.c */ + struct callout in6_rr_timer_ch; /* from netinet6/in6_prefix.c */ }; /* Index: sys/netinet/ip_encap.c =================================================================== RCS file: /home/xbone/CVSROOT/netmerge/4.11-ipv6/sys/netinet/ip_encap.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- sys/netinet/ip_encap.c 10 May 2005 20:25:43 -0000 1.2 +++ sys/netinet/ip_encap.c 14 Jun 2005 04:37:29 -0000 1.3 @@ -137,7 +137,8 @@ struct encaptab *ep, *match; int prio, matchprio; struct vnet *vnet = m->m_pkthdr.rcvif->if_vnet; - + struct vnet *vnet1 = NULL; + struct vimage *vip, *vip1; ip = mtod(m, struct ip *); bzero(&s, sizeof(s)); @@ -151,7 +152,21 @@ match = NULL; matchprio = 0; - for (ep = LIST_FIRST(&vnet->encaptab); ep; ep = LIST_NEXT(ep, chain)) { + + vip = vnet_vip(vnet); + LIST_FOREACH(vnet1, &vnet_head, vnet_le) { + + /* Search this vnet and all the children vimages. This + * would be necessary if the gif is transitioning + * between networks. we cannot use vi_child_of + * because it checks for all ancestors. We need + * only one level. + */ + vip1 = vnet_vip(vnet1); + if (vip != vip1 && vip != vip1->vi_parent) + continue; + + for (ep = LIST_FIRST(&vnet1->encaptab); ep; ep = LIST_NEXT(ep, chain)) { if (ep->af != AF_INET) continue; if (ep->proto >= 0 && ep->proto != proto) @@ -191,7 +206,8 @@ matchprio = prio; match = ep; } - } + } + } /* match for all vnets */ if (match) { /* found a match, "match" has the best one */ @@ -229,6 +245,8 @@ struct encaptab *ep, *match; int prio, matchprio; struct vnet *vnet = m->m_pkthdr.rcvif->if_vnet; + struct vnet *vnet1 = NULL; + struct vimage *vip, *vip1; ip6 = mtod(m, struct ip6_hdr *); @@ -243,7 +261,20 @@ match = NULL; matchprio = 0; - for (ep = LIST_FIRST(&vnet->encaptab); ep; ep = LIST_NEXT(ep, chain)) { + vip = vnet_vip(vnet); + LIST_FOREACH(vnet1, &vnet_head, vnet_le) { + + /* Search this vnet and all the children vimages. This + * would be necessary if the gif is transitioning + * between networks. we cannot use vi_child_of + * because it checks for all ancestors. We need + * only one level. + */ + vip1 = vnet_vip(vnet1); + if (vip != vip1 && vip != vip1->vi_parent) + continue; + + for (ep = LIST_FIRST(&vnet1->encaptab); ep; ep = LIST_NEXT(ep, chain)) { if (ep->af != AF_INET6) continue; if (ep->proto >= 0 && ep->proto != proto) @@ -266,7 +297,8 @@ matchprio = prio; match = ep; } - } + } + } if (match) { /* found a match */ Index: sys/netinet/tcp_input.c =================================================================== RCS file: /home/xbone/CVSROOT/netmerge/4.11-ipv6/sys/netinet/tcp_input.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- sys/netinet/tcp_input.c 10 May 2005 20:25:45 -0000 1.2 +++ sys/netinet/tcp_input.c 26 May 2005 23:09:35 -0000 1.3 @@ -2648,7 +2648,7 @@ mss = rt->rt_rmx.rmx_mtu - min_protoh; else { if (isipv6) { - mss = nd_ifinfo[rt->rt_ifp->if_index].linkmtu - + mss = vnet->nd_ifinfo[rt->rt_ifp->if_index].linkmtu - min_protoh; if (!in6_localaddr(&inp->in6p_faddr, vnet)) mss = min(mss, vnet->tcp_v6mssdflt); Index: sys/netinet6/icmp6.c =================================================================== RCS file: /home/xbone/CVSROOT/netmerge/4.11-ipv6/sys/netinet6/icmp6.c,v retrieving revision 1.2 retrieving revision 1.4 diff -u -r1.2 -r1.4 --- sys/netinet6/icmp6.c 10 May 2005 20:25:46 -0000 1.2 +++ sys/netinet6/icmp6.c 30 May 2005 00:54:09 -0000 1.4 @@ -906,7 +906,7 @@ /* Detect the upper level protocol */ { - void (*ctlfunc) __P((int, struct sockaddr *, void *)); + void (*ctlfunc) __P((int, struct sockaddr *, void *, struct vnet *)); u_int8_t nxt = eip6->ip6_nxt; int eoff = off + sizeof(struct icmp6_hdr) + sizeof(struct ip6_hdr); @@ -1111,11 +1111,11 @@ icmp6_mtudisc_update(&ip6cp, 1, vnet); /*XXX*/ } - ctlfunc = (void (*) __P((int, struct sockaddr *, void *))) + ctlfunc = (void (*) __P((int, struct sockaddr *, void *, struct vnet *))) (inet6sw[ip6_protox[nxt]].pr_ctlinput); if (ctlfunc) { (void) (*ctlfunc)(code, (struct sockaddr *)&icmp6dst, - &ip6cp); + &ip6cp, vnet); } } return(0); @@ -2185,7 +2185,7 @@ 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 = vnet->nd_ifinfo[m->m_pkthdr.rcvif->if_index].chlim; } else ip6->ip6_hlim = ip6_defhlim; Index: sys/netinet6/in6.c =================================================================== RCS file: /home/xbone/CVSROOT/netmerge/4.11-ipv6/sys/netinet6/in6.c,v retrieving revision 1.2 retrieving revision 1.4 diff -u -r1.2 -r1.4 --- sys/netinet6/in6.c 10 May 2005 20:25:46 -0000 1.2 +++ sys/netinet6/in6.c 29 May 2005 01:10:29 -0000 1.4 @@ -901,7 +901,6 @@ * into chains. */ if (ia == NULL) { -printf("in6_update_ifa: new ia!\n"); hostIsNew = 1; /* * When in6_update_ifa() is called in a process of a received @@ -983,12 +982,10 @@ ia->ia_flags &= ~IFA_ROUTE; ia->ia_dstaddr = dst6; } -printf("in6_update_ifa: 11\n"); /* reset the interface and routing table appropriately. */ if ((error = in6_ifinit(ifp, ia, &ifra->ifra_addr, hostIsNew)) != 0) goto unlink; -printf("in6_update_ifa: 12\n"); /* * Beyond this point, we should call in6_purgeaddr upon an error, @@ -1160,11 +1157,9 @@ nd6_dad_start((struct ifaddr *)ia, NULL, vnet); } -printf("in6_update_ifa: 18\n"); return(error); unlink: -printf("in6_update_ifa: 19\n"); /* * XXX: if a change of an existing address failed, keep the entry * anyway. @@ -1633,16 +1628,15 @@ * interface that share a same destination. */ plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL); /* XXX */ -printf("in6_ifinit: 3 plen=%d\n", plen); if (!(ia->ia_flags & IFA_ROUTE) && plen == 128 && ia->ia_dstaddr.sin6_family == AF_INET6) { /* MARKO XXX ovo dolje ne prolazi - zasto !?! */ if ((error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, - RTF_UP | RTF_HOST)) != 0) + RTF_UP | RTF_HOST)) != 0){ return(error); + } ia->ia_flags |= IFA_ROUTE; } -printf("in6_ifinit: 4\n"); if (plen < 128) { /* * The RTF_CLONING flag is necessary for in6_is_ifloop_auto(). @@ -2414,8 +2408,8 @@ for (ifp = TAILQ_FIRST(&vnet->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; + vnet->nd_ifinfo[ifp->if_index].linkmtu > maxmtu) + maxmtu = vnet->nd_ifinfo[ifp->if_index].linkmtu; } if (maxmtu) /* update only when maxmtu is positive */ in6_maxmtu = maxmtu; Index: sys/netinet6/in6_gif.c =================================================================== RCS file: /home/xbone/CVSROOT/netmerge/4.11-ipv6/sys/netinet6/in6_gif.c,v retrieving revision 1.2 retrieving revision 1.5 diff -u -r1.2 -r1.5 --- sys/netinet6/in6_gif.c 10 May 2005 20:25:46 -0000 1.2 +++ sys/netinet6/in6_gif.c 14 Jun 2005 04:37:30 -0000 1.5 @@ -69,7 +69,10 @@ #include #include +#include +#include +extern int debug; /* DEBUG */ static int gif_validate6(const struct ip6_hdr *, struct gif_softc *, struct ifnet *); @@ -99,6 +102,28 @@ int proto, error; u_int8_t itos, otos; + /* + * A tunnel could sit between two vimages. The packets are injected + * in one vimage and the packet emerges in another vimage. + */ + +#ifdef NETCONTEXTSWITCHING + /* Change the outgoing network context if the gif is + * identified as one crossing contexts. Send packets + * out on the parent's vnet. + */ + if (sc->vnet_switch && vnet != vnet0) { + struct vnet *outgoing_vnet = vnet; + struct vimage *outgoing_vip = vnet_vip(vnet); + if (outgoing_vip && + outgoing_vip->vi_parent && + outgoing_vip->vi_parent->v_net){ + outgoing_vnet = outgoing_vip->vi_parent->v_net; + } + vnet = outgoing_vnet; + } +#endif + if (sin6_src == NULL || sin6_dst == NULL || sin6_src->sin6_family != AF_INET6 || sin6_dst->sin6_family != AF_INET6) { @@ -171,20 +196,45 @@ m_freem(m); return ENETUNREACH; } + + /* udp output is embedding the scope. It will be removed in ip6_output.c */ +#ifndef SCOPEDROUTING + { + if (in6_embedscope(&ip6->ip6_dst, sin6_dst, NULL, NULL, vnet)){ + m_freem(m); + return ENETUNREACH; + } + if (in6_embedscope(&ip6->ip6_src, sin6_src, NULL, NULL, vnet)){ + m_freem(m); + return ENETUNREACH; + } + } +#endif + if (ifp->if_flags & IFF_LINK1) ip_ecn_ingress(ECN_ALLOWED, &otos, &itos); else ip_ecn_ingress(ECN_NOCARE, &otos, &itos); ip6->ip6_flow &= ~ntohl(0xff00000); ip6->ip6_flow |= htonl((u_int32_t)otos << 20); - + if (dst->sin6_family != sin6_dst->sin6_family || - !IN6_ARE_ADDR_EQUAL(&dst->sin6_addr, &sin6_dst->sin6_addr)) { + !IN6_ARE_ADDR_EQUAL(&dst->sin6_addr, &sin6_dst->sin6_addr) || + (sc->gif_ro6.ro_rt && + sc->gif_ro6.ro_rt->rt_ifp->if_vnet != vnet)){ /* cache route doesn't match */ bzero(dst, sizeof(*dst)); dst->sin6_family = sin6_dst->sin6_family; dst->sin6_len = sizeof(struct sockaddr_in6); dst->sin6_addr = sin6_dst->sin6_addr; + +#ifndef SCOPEDROUTING + /* add the scope id before you lookup? */ + if (in6_embedscope(&dst->sin6_addr, sin6_dst, NULL, NULL, vnet)){ + m_freem(m); + return ENETUNREACH; + } +#endif if (sc->gif_ro6.ro_rt) { RTFREE(sc->gif_ro6.ro_rt); sc->gif_ro6.ro_rt = NULL; @@ -195,7 +245,7 @@ } if (sc->gif_ro6.ro_rt == NULL) { - rtalloc((struct route *)&sc->gif_ro6, XVIMAGE); + rtalloc((struct route *)&sc->gif_ro6, vnet); if (sc->gif_ro6.ro_rt == NULL) { m_freem(m); return ENETUNREACH; @@ -211,15 +261,15 @@ - sizeof(struct ip6_hdr); #endif } - + #ifdef IPV6_MINMTU /* * force fragmentation to minimum MTU, to avoid path MTU discovery. * it is too painful to ask for resend of inner packet, to achieve * path MTU discovery for encapsulated packets. */ - error = ip6_output(m, 0, &sc->gif_ro6, IPV6_MINMTU, 0, NULL, NULL, - vnet); + error = ip6_output(m, 0, &sc->gif_ro6, IPV6_MINMTU, 0, NULL, NULL, vnet); + #else error = ip6_output(m, 0, &sc->gif_ro6, 0, 0, NULL, NULL, vnet); #endif @@ -300,7 +350,7 @@ m_freem(m); return IPPROTO_DONE; } - + gif_input(m, af, gifp); return IPPROTO_DONE; } @@ -315,19 +365,31 @@ struct ifnet *ifp; { struct sockaddr_in6 *src, *dst; + struct in6_addr gifsrc, gifdst; + struct vnet *vnet = (ifp)? ifp->if_vnet : NULL; src = (struct sockaddr_in6 *)sc->gif_psrc; dst = (struct sockaddr_in6 *)sc->gif_pdst; + gifsrc = src->sin6_addr; + gifdst = dst->sin6_addr; + if (in6_embedscope(&gifsrc, src, NULL, NULL, vnet)){ + return 0; + } + if (in6_embedscope(&gifdst, dst, NULL, NULL, vnet)){ + return 0; + } + /* * Check for address match. Note that the check is for an incoming * packet. We should compare the *source* address in our configuration * and the *destination* address of the packet, and vice versa. */ - if (!IN6_ARE_ADDR_EQUAL(&src->sin6_addr, &ip6->ip6_dst) || - !IN6_ARE_ADDR_EQUAL(&dst->sin6_addr, &ip6->ip6_src)) + if (!IN6_ARE_ADDR_EQUAL(&gifsrc, &ip6->ip6_dst) || + !IN6_ARE_ADDR_EQUAL(&gifdst, &ip6->ip6_src)) return 0; + /* martian filters on outer source - done in ip6_input */ /* ingress filters on outer source */ @@ -394,6 +456,7 @@ (struct protosw *)&in6_gif_protosw, sc, sc->gif_vnet); if (sc->encap_cookie6 == NULL) return EEXIST; + return 0; } Index: sys/netinet6/in6_ifattach.c =================================================================== RCS file: /home/xbone/CVSROOT/netmerge/4.11-ipv6/sys/netinet6/in6_ifattach.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- sys/netinet6/in6_ifattach.c 10 May 2005 20:25:46 -0000 1.2 +++ sys/netinet6/in6_ifattach.c 26 May 2005 23:09:36 -0000 1.3 @@ -73,7 +73,7 @@ int ip6_auto_linklocal = 1; /* enable by default */ #endif -struct callout in6_tmpaddrtimer_ch; +/* struct callout in6_tmpaddrtimer_ch; */ extern struct inpcbinfo udbinfo; extern struct inpcbinfo ripcbinfo; @@ -435,7 +435,7 @@ struct in6_aliasreq ifra; struct nd_prefix pr0; int i, error; - + /* * configure link-local address. */ @@ -832,6 +832,7 @@ return; } + /* * assign loopback address for loopback interface. * XXX multiple loopback interface case. @@ -1002,7 +1003,11 @@ int generate; { u_int8_t nullbuf[8]; - struct nd_ifinfo *ndi = &nd_ifinfo[ifp->if_index]; + struct vnet *vnet; + struct nd_ifinfo *ndi; + + vnet = ifp->if_vnet; + ndi = &vnet->nd_ifinfo[ifp->if_index]; bzero(nullbuf, sizeof(nullbuf)); if (bcmp(ndi->randomid, nullbuf, sizeof(nullbuf)) == 0) { @@ -1021,24 +1026,24 @@ } void -in6_tmpaddrtimer(ignored_arg) - void *ignored_arg; +in6_tmpaddrtimer(arg) + void *arg; { int i; struct nd_ifinfo *ndi; u_int8_t nullbuf[8]; struct vnet *vnet; int s = splnet(); - - callout_reset(&in6_tmpaddrtimer_ch, + + vnet = (struct vnet *)arg; + callout_reset(&vnet->in6_tmpaddrtimer_ch, (ip6_temp_preferred_lifetime - ip6_desync_factor - ip6_temp_regen_advance) * hz, - in6_tmpaddrtimer, NULL); + in6_tmpaddrtimer, vnet); bzero(nullbuf, sizeof(nullbuf)); -LIST_FOREACH(vnet, &vnet_head, vnet_le) for (i = 1; i < vnet->if_index + 1; i++) { - ndi = &nd_ifinfo[i]; + ndi = &vnet->nd_ifinfo[i]; if (bcmp(ndi->randomid, nullbuf, sizeof(nullbuf)) != 0) { /* * We've been generating a random ID on this interface. Index: sys/netinet6/in6_prefix.c =================================================================== RCS file: /home/xbone/CVSROOT/netmerge/4.11-ipv6/sys/netinet6/in6_prefix.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- sys/netinet6/in6_prefix.c 10 May 2005 19:49:47 -0000 1.1.1.1 +++ sys/netinet6/in6_prefix.c 26 May 2005 23:09:36 -0000 1.2 @@ -83,12 +83,14 @@ #include #include +#include + static MALLOC_DEFINE(M_IP6RR, "ip6rr", "IPv6 Router Renumbering Prefix"); static MALLOC_DEFINE(M_RR_ADDR, "rp_addr", "IPv6 Router Renumbering Ifid"); struct rr_prhead rr_prefix; -struct callout in6_rr_timer_ch; +/* struct callout in6_rr_timer_ch;*/ #include @@ -1175,13 +1177,14 @@ } void -in6_rr_timer(void *ignored_arg) +in6_rr_timer(void *arg) { int s; struct rr_prefix *rpp; + struct vnet *vnet = (struct vnet *)arg; - callout_reset(&in6_rr_timer_ch, ip6_rr_prune * hz, - in6_rr_timer, NULL); + callout_reset(&vnet->in6_rr_timer_ch, ip6_rr_prune * hz, + in6_rr_timer, vnet); s = splnet(); /* expire */ Index: sys/netinet6/in6_prefix.h =================================================================== RCS file: /home/xbone/CVSROOT/netmerge/4.11-ipv6/sys/netinet6/in6_prefix.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- sys/netinet6/in6_prefix.h 10 May 2005 19:49:47 -0000 1.1.1.1 +++ sys/netinet6/in6_prefix.h 26 May 2005 23:09:36 -0000 1.2 @@ -87,5 +87,5 @@ extern struct rr_prhead rr_prefix; void in6_rr_timer __P((void *)); -extern struct callout in6_rr_timer_ch; +/* extern struct callout in6_rr_timer_ch; */ int delete_each_prefix __P((struct rr_prefix *rpp, u_char origin)); Index: sys/netinet6/in6_proto.c =================================================================== RCS file: /home/xbone/CVSROOT/netmerge/4.11-ipv6/sys/netinet6/in6_proto.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- sys/netinet6/in6_proto.c 10 May 2005 20:25:46 -0000 1.2 +++ sys/netinet6/in6_proto.c 26 May 2005 23:09:36 -0000 1.3 @@ -105,7 +105,7 @@ #include #include #include -#include +#include #ifdef IPSEC #include Index: sys/netinet6/in6_src.c =================================================================== RCS file: /home/xbone/CVSROOT/netmerge/4.11-ipv6/sys/netinet6/in6_src.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- sys/netinet6/in6_src.c 10 May 2005 20:25:46 -0000 1.2 +++ sys/netinet6/in6_src.c 26 May 2005 23:09:36 -0000 1.3 @@ -321,11 +321,14 @@ struct in6pcb *in6p; struct ifnet *ifp; { + struct vnet *vnet; + if (in6p && in6p->in6p_hops >= 0) return(in6p->in6p_hops); - else if (ifp) - return(nd_ifinfo[ifp->if_index].chlim); - else + else if (ifp){ + vnet = ifp->if_vnet; + return(vnet->nd_ifinfo[ifp->if_index].chlim); + } else return(ip6_defhlim); } Index: sys/netinet6/ip6_input.c =================================================================== RCS file: /home/xbone/CVSROOT/netmerge/4.11-ipv6/sys/netinet6/ip6_input.c,v retrieving revision 1.2 retrieving revision 1.4 diff -u -r1.2 -r1.4 --- sys/netinet6/ip6_input.c 10 May 2005 20:25:47 -0000 1.2 +++ sys/netinet6/ip6_input.c 29 May 2005 01:10:30 -0000 1.4 @@ -105,7 +105,7 @@ #include #include #include -#include +#include #ifdef IPSEC #include @@ -138,7 +138,7 @@ static int ip6qmaxlen = IFQ_MAXLEN; struct in6_ifaddr *in6_ifaddr; -extern struct callout in6_tmpaddrtimer_ch; +/*extern struct callout in6_tmpaddrtimer_ch;*/ int ip6_forward_srcrt; /* XXX */ int ip6_sourcecheck; /* XXX */ @@ -200,7 +200,7 @@ if (vnet == vnet0) { register_netisr(NETISR_IPV6, ip6intr); } - nd6_init(); + nd6_init(vnet); frag6_init(); /* * in many cases, random() here does NOT return random number @@ -223,27 +223,33 @@ * to route local address of p2p link to loopback, * assign loopback address first. */ - in6_ifattach(&vnet->loif, NULL); + /* printf("calling in6_attach from ip6_init2\n"); + * in6_ifattach(&vnet->loif, NULL); + */ /* nd6_timer_init */ - callout_init(&nd6_timer_ch); - callout_reset(&nd6_timer_ch, hz, nd6_timer, NULL); + callout_init(&vnet->nd6_timer_ch); + callout_reset(&vnet->nd6_timer_ch, hz, nd6_timer, vnet); /* router renumbering prefix list maintenance */ - callout_init(&in6_rr_timer_ch); - callout_reset(&in6_rr_timer_ch, hz, in6_rr_timer, NULL); + callout_init(&vnet->in6_rr_timer_ch); + callout_reset(&vnet->in6_rr_timer_ch, hz, in6_rr_timer, vnet); /* timer for regeneranation of temporary addresses randomize ID */ - callout_reset(&in6_tmpaddrtimer_ch, + callout_init(&vnet->in6_tmpaddrtimer_ch); + callout_reset(&vnet->in6_tmpaddrtimer_ch, (ip6_temp_preferred_lifetime - ip6_desync_factor - ip6_temp_regen_advance) * hz, - in6_tmpaddrtimer, NULL); + in6_tmpaddrtimer, vnet); } void ip6_destroy(vnet) struct vnet *vnet; { - /* Do nothing yet - MARKO XXX */ + callout_stop(&vnet->nd6_slowtimo_ch); + callout_stop(&vnet->nd6_timer_ch); + callout_stop(&vnet->in6_rr_timer_ch); + callout_stop(&vnet->in6_tmpaddrtimer_ch); } /* Index: sys/netinet6/ip6_output.c =================================================================== RCS file: /home/xbone/CVSROOT/netmerge/4.11-ipv6/sys/netinet6/ip6_output.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- sys/netinet6/ip6_output.c 10 May 2005 20:25:47 -0000 1.2 +++ sys/netinet6/ip6_output.c 26 May 2005 23:09:36 -0000 1.3 @@ -138,6 +138,8 @@ static int ip6_getpmtu __P((struct route_in6 *, struct route_in6 *, struct ifnet *, struct in6_addr *, u_long *, int *, struct vnet *)); +int debug = 0; + /* * IP6 output. The packet in mbuf chain m contains a skeletal IP6 * header (with pri, len, nxt, hlim, src, dst). @@ -213,6 +215,7 @@ /* Destination options header(2nd part) */ MAKE_EXTHDR(opt->ip6po_dest2, &exthdrs.ip6e_dest2); } + #ifdef IPSEC /* get a security policy for this packet */ @@ -930,7 +933,7 @@ error = EMSGSIZE; goto bad; } - if (dontfrag && tlen > nd_ifinfo[ifp->if_index].linkmtu) { /* case 2-b */ + if (dontfrag && tlen > vnet->nd_ifinfo[ifp->if_index].linkmtu) { /* case 2-b */ /* * Even if the DONTFRAG option is specified, we cannot send the * packet when the data length is larger than the MTU of the @@ -1358,7 +1361,7 @@ if (ifp == NULL) ifp = ro_pmtu->ro_rt->rt_ifp; - ifmtu = nd_ifinfo[ifp->if_index].linkmtu; + ifmtu = vnet->nd_ifinfo[ifp->if_index].linkmtu; mtu = ro_pmtu->ro_rt->rt_rmx.rmx_mtu; if (mtu == 0) mtu = ifmtu; @@ -1387,7 +1390,7 @@ ro_pmtu->ro_rt->rt_rmx.rmx_mtu = mtu; } } else if (ifp) { - mtu = nd_ifinfo[ifp->if_index].linkmtu; + mtu = vnet->nd_ifinfo[ifp->if_index].linkmtu; } else error = EHOSTUNREACH; /* XXX */ Index: sys/netinet6/nd6.c =================================================================== RCS file: /home/xbone/CVSROOT/netmerge/4.11-ipv6/sys/netinet6/nd6.c,v retrieving revision 1.2 retrieving revision 1.4 diff -u -r1.2 -r1.4 --- sys/netinet6/nd6.c 10 May 2005 20:25:47 -0000 1.2 +++ sys/netinet6/nd6.c 29 May 2005 01:10:30 -0000 1.4 @@ -41,6 +41,7 @@ #include "opt_inet.h" #include "opt_inet6.h" + #include #include #include @@ -54,9 +55,11 @@ #include #include #include +#include +#include +#include #include -#include #include #include #include @@ -70,8 +73,8 @@ #include #include #include -#include #include +#include #include "loop.h" @@ -105,11 +108,13 @@ /* for debugging? */ 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 }; +/* + * 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; @@ -117,17 +122,22 @@ static void nd6_slowtimo __P((void *)); static int regen_tmpaddr __P((struct in6_ifaddr *, struct vnet *)); -struct callout nd6_slowtimo_ch; -struct callout nd6_timer_ch; -extern struct callout in6_tmpaddrtimer_ch; +/* + * struct callout nd6_slowtimo_ch; + * struct callout nd6_timer_ch; + */ + +/*extern struct callout in6_tmpaddrtimer_ch;*/ void -nd6_init() +nd6_init(vnet) + struct vnet *vnet; { - static int nd6_init_done = 0; int i; - if (nd6_init_done) { + if (!vnet) return; + + if (vnet->nd6_init_done) { log(LOG_NOTICE, "nd6_init called more than once(ignored)\n"); return; } @@ -137,14 +147,22 @@ for (i = 0; i < sizeof(all1_sa.sin6_addr); i++) all1_sa.sin6_addr.s6_addr[i] = 0xff; + vnet->llinfo_nd6.ln_next = &vnet->llinfo_nd6; + vnet->llinfo_nd6.ln_prev = &vnet->llinfo_nd6; + vnet->nd_ifinfo_indexlim = 8; + vnet->nd_ifinfo = NULL; + memset((char *)&vnet->nd_prefix, '\0', sizeof(nd_prefix)); + /* initialization of the default router list */ - TAILQ_INIT(&nd_defrouter); + TAILQ_INIT(&vnet->nd_defrouter); + + vnet->nd6_init_done = 1; - nd6_init_done = 1; /* start timer */ - callout_reset(&nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz, - nd6_slowtimo, NULL); + callout_init(&vnet->nd6_slowtimo_ch); + callout_reset(&vnet->nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz, + nd6_slowtimo, vnet); } void @@ -157,25 +175,25 @@ * 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 || vnet->if_index >= nd_ifinfo_indexlim) { + if (vnet->nd_ifinfo == NULL || vnet->if_index >= vnet->nd_ifinfo_indexlim) { size_t n; caddr_t q; - while (vnet->if_index >= nd_ifinfo_indexlim) - nd_ifinfo_indexlim <<= 1; + while (vnet->if_index >= vnet->nd_ifinfo_indexlim) + vnet->nd_ifinfo_indexlim <<= 1; /* grow nd_ifinfo */ - n = nd_ifinfo_indexlim * sizeof(struct nd_ifinfo); + n = vnet->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); + if (vnet->nd_ifinfo) { + bcopy((caddr_t)vnet->nd_ifinfo, q, n/2); + free((caddr_t)vnet->nd_ifinfo, M_IP6NDP); } - nd_ifinfo = (struct nd_ifinfo *)q; + vnet->nd_ifinfo = (struct nd_ifinfo *)q; } -#define ND nd_ifinfo[ifp->if_index] +#define ND vnet->nd_ifinfo[ifp->if_index] /* * Don't initialize if called twice. @@ -213,7 +231,7 @@ { #define MIN(a,b) ((a) < (b) ? (a) : (b)) struct vnet *vnet = ifp->if_vnet; - struct nd_ifinfo *ndi = &nd_ifinfo[ifp->if_index]; + struct nd_ifinfo *ndi = &vnet->nd_ifinfo[ifp->if_index]; u_long oldmaxmtu = ndi->maxmtu; u_long oldlinkmtu = ndi->linkmtu; @@ -422,10 +440,9 @@ * ND6 timer routine to expire default route list and prefix list */ void -nd6_timer(ignored_arg) - void *ignored_arg; +nd6_timer(arg) + void *arg; { - struct vnet *vnet = vnet0; /* MARKO XXX */ int s; struct llinfo_nd6 *ln; struct nd_defrouter *dr; @@ -433,13 +450,14 @@ struct ifnet *ifp; struct in6_ifaddr *ia6, *nia6; struct in6_addrlifetime *lt6; + struct vnet *vnet = (struct vnet *)arg; s = splnet(); - callout_reset(&nd6_timer_ch, nd6_prune * hz, - nd6_timer, NULL); + callout_reset(&vnet->nd6_timer_ch, nd6_prune * hz, + nd6_timer, vnet); - ln = llinfo_nd6.ln_next; - while (ln && ln != &llinfo_nd6) { + ln = vnet->llinfo_nd6.ln_next; + while (ln && ln != &vnet->llinfo_nd6) { struct rtentry *rt; struct sockaddr_in6 *dst; struct llinfo_nd6 *next = ln->ln_next; @@ -454,7 +472,7 @@ ln = next; continue; } - ndi = &nd_ifinfo[ifp->if_index]; + ndi = &vnet->nd_ifinfo[ifp->if_index]; dst = (struct sockaddr_in6 *)rt_key(rt); if (ln->ln_expire > time_second) { @@ -476,7 +494,7 @@ if (ln->ln_asked < nd6_mmaxtries) { ln->ln_asked++; ln->ln_expire = time_second + - nd_ifinfo[ifp->if_index].retrans / 1000; + vnet->nd_ifinfo[ifp->if_index].retrans / 1000; nd6_ns_output(ifp, NULL, &dst->sin6_addr, ln, 0, vnet); } else { @@ -531,7 +549,7 @@ if (ln->ln_asked < nd6_umaxtries) { ln->ln_asked++; ln->ln_expire = time_second + - nd_ifinfo[ifp->if_index].retrans / 1000; + vnet->nd_ifinfo[ifp->if_index].retrans / 1000; nd6_ns_output(ifp, &dst->sin6_addr, &dst->sin6_addr, ln, 0, vnet); } else { @@ -543,7 +561,7 @@ } /* expire default router list */ - dr = TAILQ_FIRST(&nd_defrouter); + dr = TAILQ_FIRST(&vnet->nd_defrouter); while (dr) { if (dr->expire && dr->expire < time_second) { struct nd_defrouter *t; @@ -629,7 +647,7 @@ } /* expire prefix list */ - pr = nd_prefix.lh_first; + pr = vnet->nd_prefix.lh_first; while (pr) { /* * check prefix lifetime. @@ -732,7 +750,7 @@ struct nd_prefix *pr, *npr; /* Nuke default router list entries toward ifp */ - if ((dr = TAILQ_FIRST(&nd_defrouter)) != NULL) { + if ((dr = TAILQ_FIRST(&vnet->nd_defrouter)) != NULL) { /* * The first entry of the list may be stored in * the routing table, so we'll delete it later. @@ -742,13 +760,13 @@ if (dr->ifp == ifp) defrtrlist_del(dr, vnet); } - dr = TAILQ_FIRST(&nd_defrouter); + dr = TAILQ_FIRST(&vnet->nd_defrouter); if (dr->ifp == ifp) defrtrlist_del(dr, vnet); } /* Nuke prefix list entries toward ifp */ - for (pr = nd_prefix.lh_first; pr; pr = npr) { + for (pr = vnet->nd_prefix.lh_first; pr; pr = npr) { npr = pr->ndpr_next; if (pr->ndpr_ifp == ifp) { /* @@ -780,8 +798,8 @@ * due to KAME goto ours hack. See RTM_RESOLVE case in * nd6_rtrequest(), and ip6_input(). */ - ln = llinfo_nd6.ln_next; - while (ln && ln != &llinfo_nd6) { + ln = vnet->llinfo_nd6.ln_next; + while (ln && ln != &vnet->llinfo_nd6) { struct rtentry *rt; struct sockaddr_dl *sdl; @@ -1008,7 +1026,7 @@ */ pfxlist_onlink_check(vnet); - if (dr == TAILQ_FIRST(&nd_defrouter)) { + if (dr == TAILQ_FIRST(&vnet->nd_defrouter)) { /* * It is used as the current default router, * so we have to move it to the end of the @@ -1016,8 +1034,8 @@ * XXX: it is not very efficient if this is * the only router. */ - TAILQ_REMOVE(&nd_defrouter, dr, dr_entry); - TAILQ_INSERT_TAIL(&nd_defrouter, dr, dr_entry); + TAILQ_REMOVE(&vnet->nd_defrouter, dr, dr_entry); + TAILQ_INSERT_TAIL(&vnet->nd_defrouter, dr, dr_entry); defrouter_select(vnet); } @@ -1056,6 +1074,7 @@ int force; { struct llinfo_nd6 *ln; + struct vnet *vnet; /* * If the caller specified "rt", use that. Otherwise, resolve the @@ -1068,6 +1087,8 @@ return; } + vnet = rt->rt_vnet; + if ((rt->rt_flags & RTF_GATEWAY) != 0 || (rt->rt_flags & RTF_LLINFO) == 0 || !rt->rt_llinfo || !rt->rt_gateway || @@ -1093,7 +1114,7 @@ ln->ln_state = ND6_LLINFO_REACHABLE; if (ln->ln_expire) ln->ln_expire = time_second + - nd_ifinfo[rt->rt_ifp->if_index].reachable; + vnet->nd_ifinfo[rt->rt_ifp->if_index].reachable; } void @@ -1258,9 +1279,9 @@ ln->ln_expire = time_second; } rt->rt_flags |= RTF_LLINFO; - ln->ln_next = llinfo_nd6.ln_next; - llinfo_nd6.ln_next = ln; - ln->ln_prev = &llinfo_nd6; + ln->ln_next = vnet->llinfo_nd6.ln_next; + vnet->llinfo_nd6.ln_next = ln; + ln->ln_prev = &vnet->llinfo_nd6; ln->ln_next->ln_prev = ln; /* @@ -1377,7 +1398,7 @@ */ bzero(drl, sizeof(*drl)); s = splnet(); - dr = TAILQ_FIRST(&nd_defrouter); + dr = TAILQ_FIRST(&vnet->nd_defrouter); while (dr && i < DRLSTSIZ) { drl->defrouter[i].rtaddr = dr->rtaddr; if (IN6_IS_ADDR_LINKLOCAL(&drl->defrouter[i].rtaddr)) { @@ -1409,7 +1430,7 @@ */ bzero(prl, sizeof(*prl)); s = splnet(); - pr = nd_prefix.lh_first; + pr = vnet->nd_prefix.lh_first; while (pr && i < PRLSTSIZ) { struct nd_pfxrouter *pfr; int j; @@ -1473,35 +1494,35 @@ break; case OSIOCGIFINFO_IN6: - if (!nd_ifinfo || i >= nd_ifinfo_indexlim) { + if (!vnet->nd_ifinfo || i >= vnet->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.linkmtu = vnet->nd_ifinfo[ifp->if_index].linkmtu; + ndi->ndi.maxmtu = vnet->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; + vnet->nd_ifinfo[ifp->if_index].basereachable; + ndi->ndi.reachable = vnet->nd_ifinfo[ifp->if_index].reachable; + ndi->ndi.retrans = vnet->nd_ifinfo[ifp->if_index].retrans; + ndi->ndi.flags = vnet->nd_ifinfo[ifp->if_index].flags; + ndi->ndi.recalctm = vnet->nd_ifinfo[ifp->if_index].recalctm; + ndi->ndi.chlim = vnet->nd_ifinfo[ifp->if_index].chlim; + ndi->ndi.receivedra = vnet->nd_ifinfo[ifp->if_index].receivedra; break; case SIOCGIFINFO_IN6: - if (!nd_ifinfo || i >= nd_ifinfo_indexlim) { + if (!vnet->nd_ifinfo || i >= vnet->nd_ifinfo_indexlim) { error = EINVAL; break; } - ndi->ndi = nd_ifinfo[ifp->if_index]; + ndi->ndi = vnet->nd_ifinfo[ifp->if_index]; break; case SIOCSIFINFO_FLAGS: /* XXX: almost all other fields of ndi->ndi is unused */ - if (!nd_ifinfo || i >= nd_ifinfo_indexlim) { + if (!vnet->nd_ifinfo || i >= vnet->nd_ifinfo_indexlim) { error = EINVAL; break; } - nd_ifinfo[ifp->if_index].flags = ndi->ndi.flags; + vnet->nd_ifinfo[ifp->if_index].flags = ndi->ndi.flags; break; case SIOCSNDFLUSH_IN6: /* XXX: the ioctl name is confusing... */ /* flush default router list */ @@ -1520,7 +1541,7 @@ struct nd_prefix *pr, *next; s = splnet(); - for (pr = nd_prefix.lh_first; pr; pr = next) { + for (pr = vnet->nd_prefix.lh_first; pr; pr = next) { struct in6_ifaddr *ia, *ia_next; next = pr->ndpr_next; @@ -1550,7 +1571,7 @@ struct nd_defrouter *dr, *next; s = splnet(); - if ((dr = TAILQ_FIRST(&nd_defrouter)) != NULL) { + if ((dr = TAILQ_FIRST(&vnet->nd_defrouter)) != NULL) { /* * The first entry of the list may be stored in * the routing table, so we'll delete it later. @@ -1559,7 +1580,7 @@ next = TAILQ_NEXT(dr, dr_entry); defrtrlist_del(dr, vnet); } - defrtrlist_del(TAILQ_FIRST(&nd_defrouter), vnet); + defrtrlist_del(TAILQ_FIRST(&vnet->nd_defrouter), vnet); } splx(s); break; @@ -1843,21 +1864,22 @@ } static void -nd6_slowtimo(ignored_arg) - void *ignored_arg; +nd6_slowtimo(arg) + void *arg; { int s = splnet(); int i; struct nd_ifinfo *nd6if; - struct vnet *vnet; + struct vnet *vnet = (struct vnet *)arg; + + + callout_reset(&vnet->nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz, + nd6_slowtimo, vnet); - callout_reset(&nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz, - nd6_slowtimo, NULL); -LIST_FOREACH(vnet, &vnet_head, vnet_le) for (i = 1; i < vnet->if_index + 1; i++) { - if (!nd_ifinfo || i >= nd_ifinfo_indexlim) + if (!vnet->nd_ifinfo || i >= vnet->nd_ifinfo_indexlim) continue; - nd6if = &nd_ifinfo[i]; + nd6if = &vnet->nd_ifinfo[i]; if (nd6if->basereachable && /* already initialized */ (nd6if->recalctm -= ND6_SLOWTIMER_INTERVAL) <= 0) { /* @@ -1970,7 +1992,7 @@ } if (!ln || !rt) { if ((ifp->if_flags & IFF_POINTOPOINT) == 0 && - !(nd_ifinfo[ifp->if_index].flags & ND6_IFF_PERFORMNUD)) { + !(vnet->nd_ifinfo[ifp->if_index].flags & ND6_IFF_PERFORMNUD)) { log(LOG_DEBUG, "nd6_output: can't allocate llinfo for %s " "(ln=%p, rt=%p)\n", @@ -2028,7 +2050,7 @@ ln->ln_expire < time_second) { ln->ln_asked++; ln->ln_expire = time_second + - nd_ifinfo[ifp->if_index].retrans / 1000; + vnet->nd_ifinfo[ifp->if_index].retrans / 1000; nd6_ns_output(ifp, NULL, &dst->sin6_addr, ln, 0, vnet); } } @@ -2158,13 +2180,14 @@ char buf[1024]; struct in6_defrouter *d, *de; struct nd_defrouter *dr; - struct vnet *vnet = vnet0; /* XXX MARKO */ + struct vimage *vip = req->p->p_vimage; + struct vnet *vnet = vip->v_net; if (req->newptr) return EPERM; error = 0; - for (dr = TAILQ_FIRST(&nd_defrouter); + for (dr = TAILQ_FIRST(&vnet->nd_defrouter); dr; dr = TAILQ_NEXT(dr, dr_entry)) { d = (struct in6_defrouter *)buf; @@ -2201,13 +2224,15 @@ char buf[1024]; struct in6_prefix *p, *pe; struct nd_prefix *pr; - struct vnet *vnet = vnet0; /* XXX MARKO */ + /* struct vnet *vnet = vnet0;*/ /* XXX MARKO */ + struct vimage *vip = req->p->p_vimage; + struct vnet *vnet = vip->v_net; if (req->newptr) return EPERM; error = 0; - for (pr = nd_prefix.lh_first; pr; pr = pr->ndpr_next) { + for (pr = vnet->nd_prefix.lh_first; pr; pr = pr->ndpr_next) { u_short advrtrs; size_t advance; struct sockaddr_in6 *sin6, *s6; Index: sys/netinet6/nd6.h =================================================================== RCS file: /home/xbone/CVSROOT/netmerge/4.11-ipv6/sys/netinet6/nd6.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- sys/netinet6/nd6.h 10 May 2005 20:25:48 -0000 1.2 +++ sys/netinet6/nd6.h 26 May 2005 23:09:36 -0000 1.3 @@ -340,7 +340,7 @@ /* XXX: need nd6_var.h?? */ /* nd6.c */ -void nd6_init __P((void)); +void nd6_init __P((struct vnet *)); void nd6_ifattach __P((struct ifnet *)); int nd6_is_addr_neighbor __P((struct sockaddr_in6 *, struct ifnet *)); void nd6_option_init __P((void *, int, union nd_opts *)); Index: sys/netinet6/nd6_nbr.c =================================================================== RCS file: /home/xbone/CVSROOT/netmerge/4.11-ipv6/sys/netinet6/nd6_nbr.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- sys/netinet6/nd6_nbr.c 10 May 2005 20:25:48 -0000 1.2 +++ sys/netinet6/nd6_nbr.c 26 May 2005 23:09:37 -0000 1.3 @@ -667,7 +667,7 @@ ln->ln_byhint = 0; if (ln->ln_expire) ln->ln_expire = time_second + - nd_ifinfo[rt->rt_ifp->if_index].reachable; + vnet->nd_ifinfo[rt->rt_ifp->if_index].reachable; } else { ln->ln_state = ND6_LLINFO_STALE; ln->ln_expire = time_second + nd6_gctimer; @@ -748,7 +748,7 @@ ln->ln_byhint = 0; if (ln->ln_expire) { ln->ln_expire = time_second + - nd_ifinfo[ifp->if_index].reachable; + vnet->nd_ifinfo[ifp->if_index].reachable; } } else { if (lladdr && llchange) { @@ -1109,7 +1109,7 @@ if (tick == NULL) { nd6_dad_ns_output(dp, ifa, vnet); nd6_dad_starttimer(dp, - nd_ifinfo[ifa->ifa_ifp->if_index].retrans * hz / 1000); + vnet->nd_ifinfo[ifa->ifa_ifp->if_index].retrans * hz / 1000); } else { int ntick; @@ -1202,7 +1202,7 @@ */ nd6_dad_ns_output(dp, ifa, vnet); nd6_dad_starttimer(dp, - nd_ifinfo[ifa->ifa_ifp->if_index].retrans * hz / 1000); + vnet->nd_ifinfo[ifa->ifa_ifp->if_index].retrans * hz / 1000); } else { /* * We have transmitted sufficient number of DAD packets. Index: sys/netinet6/nd6_rtr.c =================================================================== RCS file: /home/xbone/CVSROOT/netmerge/4.11-ipv6/sys/netinet6/nd6_rtr.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- sys/netinet6/nd6_rtr.c 10 May 2005 20:25:48 -0000 1.2 +++ sys/netinet6/nd6_rtr.c 26 May 2005 23:09:37 -0000 1.3 @@ -208,7 +208,7 @@ { struct ifnet *ifp = m->m_pkthdr.rcvif; struct vnet *vnet = ifp->if_vnet; - struct nd_ifinfo *ndi = &nd_ifinfo[ifp->if_index]; + struct nd_ifinfo *ndi = &vnet->nd_ifinfo[ifp->if_index]; struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); struct nd_router_advert *nd_ra; struct in6_addr saddr6 = ip6->ip6_src; @@ -555,8 +555,9 @@ struct ifnet *ifp; { struct nd_defrouter *dr; + struct vnet *vnet = ifp->if_vnet; - for (dr = TAILQ_FIRST(&nd_defrouter); dr; + for (dr = TAILQ_FIRST(&vnet->nd_defrouter); dr; dr = TAILQ_NEXT(dr, dr_entry)) { if (dr->ifp == ifp && IN6_ARE_ADDR_EQUAL(addr, &dr->rtaddr)) return(dr); @@ -620,15 +621,15 @@ rt6_flush(&dr->rtaddr, dr->ifp); } - if (dr == TAILQ_FIRST(&nd_defrouter)) + if (dr == TAILQ_FIRST(&vnet->nd_defrouter)) deldr = dr; /* The router is primary. */ - TAILQ_REMOVE(&nd_defrouter, dr, dr_entry); + TAILQ_REMOVE(&vnet->nd_defrouter, dr, dr_entry); /* * Also delete all the pointers to the router in each prefix lists. */ - for (pr = nd_prefix.lh_first; pr; pr = pr->ndpr_next) { + for (pr = vnet->nd_prefix.lh_first; pr; pr = pr->ndpr_next) { struct nd_pfxrouter *pfxrtr; if ((pfxrtr = pfxrtr_lookup(pr, dr, vnet)) != NULL) pfxrtr_del(pfxrtr, vnet); @@ -668,19 +669,19 @@ /* * Search for a (probably) reachable router from the list. */ - for (dr = TAILQ_FIRST(&nd_defrouter); dr; + for (dr = TAILQ_FIRST(&vnet->nd_defrouter); dr; dr = TAILQ_NEXT(dr, dr_entry)) { if ((rt = nd6_lookup(&dr->rtaddr, 0, dr->ifp)) && (ln = (struct llinfo_nd6 *)rt->rt_llinfo) && ND6_IS_LLINFO_PROBREACH(ln)) { /* Got it, and move it to the head */ - TAILQ_REMOVE(&nd_defrouter, dr, dr_entry); - TAILQ_INSERT_HEAD(&nd_defrouter, dr, dr_entry); + TAILQ_REMOVE(&vnet->nd_defrouter, dr, dr_entry); + TAILQ_INSERT_HEAD(&vnet->nd_defrouter, dr, dr_entry); break; } } - if ((dr = TAILQ_FIRST(&nd_defrouter))) { + if ((dr = TAILQ_FIRST(&vnet->nd_defrouter))) { /* * De-install the previous default gateway and install * a new one. @@ -771,8 +772,8 @@ * If there is no other router, install it anyway. Otherwise, * just continue to use the current default router. */ - TAILQ_INSERT_TAIL(&nd_defrouter, n, dr_entry); - if (TAILQ_FIRST(&nd_defrouter) == n) + TAILQ_INSERT_TAIL(&vnet->nd_defrouter, n, dr_entry); + if (TAILQ_FIRST(&vnet->nd_defrouter) == n) defrouter_select(vnet); splx(s); @@ -830,7 +831,7 @@ { struct nd_prefix *search; - for (search = nd_prefix.lh_first; search; search = search->ndpr_next) { + for (search = vnet->nd_prefix.lh_first; search; search = search->ndpr_next) { if (pr->ndpr_ifp == search->ndpr_ifp && pr->ndpr_plen == search->ndpr_plen && in6_are_prefix_equal(&pr->ndpr_prefix.sin6_addr, @@ -871,7 +872,7 @@ s = splnet(); /* link ndpr_entry to nd_prefix list */ - LIST_INSERT_HEAD(&nd_prefix, new, ndpr_entry); + LIST_INSERT_HEAD(&vnet->nd_prefix, new, ndpr_entry); splx(s); /* ND_OPT_PI_FLAG_ONLINK processing */ @@ -1287,7 +1288,7 @@ * Check if there is a prefix that has a reachable advertising * router. */ - for (pr = nd_prefix.lh_first; pr; pr = pr->ndpr_next) { + for (pr = vnet->nd_prefix.lh_first; pr; pr = pr->ndpr_next) { if (pr->ndpr_raf_onlink && find_pfxlist_reachable_router(pr)) break; } @@ -1298,7 +1299,7 @@ * Detach prefixes which have no reachable advertising * router, and attach other prefixes. */ - for (pr = nd_prefix.lh_first; pr; pr = pr->ndpr_next) { + for (pr = vnet->nd_prefix.lh_first; pr; pr = pr->ndpr_next) { /* XXX: a link-local prefix should never be detached */ if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr)) continue; @@ -1319,7 +1320,7 @@ } } else { /* there is no prefix that has a reachable router */ - for (pr = nd_prefix.lh_first; pr; pr = pr->ndpr_next) { + for (pr = vnet->nd_prefix.lh_first; pr; pr = pr->ndpr_next) { if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr)) continue; @@ -1339,7 +1340,7 @@ * interfaces. Such cases will be handled in nd6_prefix_onlink, * so we don't have to care about them. */ - for (pr = nd_prefix.lh_first; pr; pr = pr->ndpr_next) { + for (pr = vnet->nd_prefix.lh_first; pr; pr = pr->ndpr_next) { int e; if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr)) @@ -1447,7 +1448,7 @@ * Although such a configuration is expected to be rare, we explicitly * allow it. */ - for (opr = nd_prefix.lh_first; opr; opr = opr->ndpr_next) { + for (opr = vnet->nd_prefix.lh_first; opr; opr = opr->ndpr_next) { if (opr == pr) continue; @@ -1577,7 +1578,7 @@ * If there's one, try to make the prefix on-link on the * interface. */ - for (opr = nd_prefix.lh_first; opr; opr = opr->ndpr_next) { + for (opr = vnet->nd_prefix.lh_first; opr; opr = opr->ndpr_next) { if (opr == pr) continue; @@ -1999,7 +2000,7 @@ * we do this here to avoid re-install the default route * if the list is NOT empty. */ - if (TAILQ_FIRST(&nd_defrouter) == NULL) + if (TAILQ_FIRST(&vnet->nd_defrouter) == NULL) defrouter_select(vnet); /* Index: sys/sys/vimage.h =================================================================== RCS file: /home/xbone/CVSROOT/netmerge/4.11-ipv6/sys/sys/vimage.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- sys/sys/vimage.h 10 May 2005 20:39:26 -0000 1.1 +++ sys/sys/vimage.h 3 Jun 2005 20:57:43 -0000 1.2 @@ -55,6 +55,7 @@ int vi_child_of(struct vimage *, struct vimage *); void vi_linker_lookup (struct kld_sym_lookup *, char *, struct vimage *); char *vnet_name(struct vnet *); +struct vimage *vnet_vip(struct vnet *); extern struct vimage *vimage0; LIST_HEAD(vimage_list_head, vimage); @@ -244,6 +245,7 @@ int vi_child_of(struct vimage *, struct vimage *); void vi_linker_lookup (struct kld_sym_lookup *, char *, struct vimage *); char *vnet_name(struct vnet *); +struct vimage *vnet_vip(struct vnet *); extern struct vimage *vimage0; LIST_HEAD(vimage_list_head, vimage);