Date: Mon, 4 Dec 2006 15:10:41 GMT From: Marko Zec <zec@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 111010 for review Message-ID: <200612041510.kB4FAflj042257@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=111010 Change 111010 by zec@zec_tca51 on 2006/12/04 15:09:44 Initial attempt at implementing interface moving from one vnet to another. So far this works only for IFT_ETHER type devices, and as long as none of the devfs methods gets triggered on an interface in a non-default vnet. Affected files ... .. //depot/projects/vimage/src/sys/kern/kern_vimage.c#3 edit .. //depot/projects/vimage/src/sys/net/if.c#3 edit .. //depot/projects/vimage/src/sys/net/if_var.h#3 edit Differences ... ==== //depot/projects/vimage/src/sys/kern/kern_vimage.c#3 (text+ko) ==== @@ -50,6 +50,7 @@ #include <sys/vimage.h> #include <sys/vmmeter.h> +#include <net/vnet.h> #include <net/bpf.h> #include <net/if_types.h> #include <net/if_dl.h> @@ -174,6 +175,7 @@ { struct vimage *new_vip; struct vnet_base *new_vnetb = NULL; + u_char eaddr[6]; if (vi_req == NULL || strcmp(vi_req->vi_name, "-") == 0) { if (vip == &vimage_0) @@ -192,17 +194,23 @@ if (new_vnetb == NULL) return (ENXIO); -#if 0 /* XXX deal with this later (tm) */ if (ifp == NULL) - ifp = ifunit(vi_req->vi_chroot, cur_vnetb); + ifp = ifunit(vi_req->vi_chroot); if (ifp == NULL) return (ENXIO); - if (vi_req != NULL && ifunit(vi_req->vi_parent_name, new_vnetb) != NULL) - return (EEXIST); + if (vi_req != NULL) { + struct ifnet *t_ifp; + + CURVNETB_SET(new_vnetb); + t_ifp = ifunit(vi_req->vi_parent_name); + CURVNETB_RESTORE(); + if (t_ifp != NULL) + return (EEXIST); + } /* Loopback interfaces cannot be moved across network stacks */ - if (ifp == &cur_vnetb->loif) + if (ifp->if_flags & IFF_LOOPBACK) return (EPERM); /* @@ -212,89 +220,53 @@ * in the target vnetb. */ switch (ifp->if_type) { - case IFT_ETHER: /* all these types use struct arpcom */ - case IFT_FDDI: - case IFT_XETHER: - case IFT_ISO88025: - case IFT_L2VLAN: - ether_ifdetach(ifp, ETHER_BPF_SUPPORTED); + case IFT_ETHER: + bcopy(IF_LLADDR(ifp), eaddr, 6); + ether_ifdetach(ifp); break; default: - if_detach(ifp); + panic("don't know yet how to handle iftype %d", ifp->if_type); + /* if_detach(ifp); */ } + ifp->if_bpf = NULL; - ifp->if_vnetb = new_vnetb; - - if (ifp->if_rname == NULL) { - ifp->if_rname = ifp->if_name; - ifp->if_runit = ifp->if_unit; + CURVNETB_SET(new_vnetb); + INIT_VNET_NET(new_vnetb); + /* + * Try to find an empty slot below if_index. If we fail, take + * the next slot. + * + * XXX: should be locked! + */ + for (ifp->if_index = 1; ifp->if_index <= V_if_index; ifp->if_index++) { + if (ifnet_byindex(ifp->if_index) == NULL) + break; } + /* Catch if_index overflow. */ + if (ifp->if_index < 1) + panic("vi_if_move: if_index overflow"); - unit = 0; - if (vip->vi_parent != NULL && - new_vnetb == vip->vi_parent->v_vnetb && - ifp->if_rname != NULL) { - ifp->if_name = ifp->if_rname; - unit = ifp->if_runit; - } - - if (vi_req != NULL && strlen(vi_req->vi_parent_name) && unit == 0 ) { - char c; - const char *cp; - unsigned len, m; + if (ifp->if_index > V_if_index) + V_if_index = ifp->if_index; + if (V_if_index >= V_if_indexlim) + if_grow(); + ifnet_byindex(ifp->if_index) = ifp; - len = strlen(vi_req->vi_parent_name); - if (len < 2 || len > IFNAMSIZ) - return (EINVAL); - cp = vi_req->vi_parent_name + len - 1; - c = *cp; - if (c < '0' || c > '9') - return (EINVAL); /* trailing garbage */ - m = 1; - do { - if (cp == vi_req->vi_parent_name) - return (EINVAL); /* no interface name */ - unit += (c - '0') * m; - if (unit > 1000000) - return (EINVAL); /* number is unreasonable */ - m *= 10; - c = *--cp; - } while (c >= '0' && c <= '9'); - len = cp - vi_req->vi_parent_name + 1; - bcopy(vi_req->vi_parent_name, ifp->if_fname, len); - ifp->if_fname[len] = '\0'; - ifp->if_name = ifp->if_fname; - } else { - do { - TAILQ_FOREACH(ifp1, &new_vnetb->ifnet, if_link) { - if (strcmp(ifp->if_name, ifp1->if_name)) - continue; - if (unit == ifp1->if_unit) - break; - } - unit++; - } while (ifp1); - unit--; - } - - ifp->if_unit = unit; switch (ifp->if_type) { - case IFT_ETHER: /* all these types use struct arpcom */ - case IFT_FDDI: - case IFT_XETHER: - case IFT_ISO88025: - case IFT_L2VLAN: - ether_ifattach(ifp, ETHER_BPF_SUPPORTED); + case IFT_ETHER: + ether_ifattach(ifp, eaddr); break; default: - if_attach(ifp); + panic("don't know yet how to handle iftype %d", ifp->if_type); + /* if_attach(ifp); */ } getmicrotime(&ifp->if_lastchange); if (vi_req != NULL) - sprintf(vi_req->vi_chroot, "%s%d", ifp->if_name, ifp->if_unit); + sprintf(vi_req->vi_chroot, "%s%d", + ifp->if_dname, ifp->if_dunit); -#endif + CURVNETB_RESTORE(); return (0); } @@ -518,17 +490,19 @@ struct vnet_base *vnetb = vip->v_vnetb; struct vprocg *vprocg = vip->v_procg; struct vcpu *vcpu = vip->v_cpu; + struct ifnet *ifp; + INIT_VNET_NET(vnetb); -#if 0 /* return all interfaces to the parent vnetb */ - while ((ifp = TAILQ_FIRST(&vnetb->ifnet)) != NULL) { - if (ifp == &vnet->loif) { + while ((ifp = TAILQ_FIRST(&V_ifnet)) != NULL) { + if (ifp->if_flags & IFF_LOOPBACK) { bpfdetach(ifp); if_detach(ifp); } else vi_if_move(NULL, ifp, vip); } +#if 0 /* * Call all domain destroy routines - those basically have to free * the allocated memory and stop all the pending timers. ==== //depot/projects/vimage/src/sys/net/if.c#3 (text+ko) ==== @@ -106,7 +106,6 @@ 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 *); static void if_check(void *); static void if_qflush(struct ifaltq *); @@ -357,7 +356,7 @@ return 0; } -static void +void if_grow(void) { INIT_VNET_NET(curvnetb); @@ -1511,26 +1510,19 @@ static void if_slowtimo(void *arg) { -#ifdef VIMAGE - struct vnet_base *vnetb; -#endif struct ifnet *ifp; int s = splimp(); IFNET_RLOCK(); -#ifdef VIMAGE - LIST_FOREACH(vnetb, &vnetb_head, vnetb_le) { - INIT_VNET_NET(vnetb); -#endif + VNETB_ITERLOOP_BEGIN(); + INIT_VNET_NET(curvnetb); TAILQ_FOREACH(ifp, &V_ifnet, if_link) { if (ifp->if_timer == 0 || --ifp->if_timer) continue; if (ifp->if_watchdog) (*ifp->if_watchdog)(ifp); } -#ifdef VIMAGE - } -#endif + VNETB_ITERLOOP_END(); IFNET_RUNLOCK(); splx(s); timeout(if_slowtimo, (void *)0, hz / IFNET_SLOWHZ); ==== //depot/projects/vimage/src/sys/net/if_var.h#3 (text+ko) ==== @@ -669,6 +669,7 @@ int if_allmulti(struct ifnet *, int); struct ifnet* if_alloc(u_char); void if_attach(struct ifnet *); +void if_grow(void); int if_delmulti(struct ifnet *, struct sockaddr *); void if_detach(struct ifnet *); void if_purgeaddrs(struct ifnet *);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200612041510.kB4FAflj042257>