PERFORCE change 111010 for review
Marko Zec
zec at FreeBSD.org
Mon Dec 4 07:10:44 PST 2006
http://perforce.freebsd.org/chv.cgi?CH=111010
Change 111010 by zec at 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 *);
More information about the p4-projects
mailing list