Skip site navigation (1)Skip section navigation (2)
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>