PERFORCE change 42778 for review

Chris Vance cvance at FreeBSD.org
Wed Nov 19 10:48:55 PST 2003


http://perforce.freebsd.org/chv.cgi?CH=42778

Change 42778 by cvance at cvance_g4 on 2003/11/19 10:48:30

	Update extattr support:
	- Added entry points for managing mount point labels
	- Immplement setlabel for HFS
	- Remove duplicate copy of vn_setlabel()
	- Correct type of size arguments to copyinstr
	- Fix implementation of mac_set_file & mac_set_link

Affected files ...

.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/SEDARWIN-NOTES#2 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/hfs/hfs_extattr.c#5 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/hfs/hfs_vnops.c#4 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/kern/kern_mac.c#29 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/sys/extattr.h#4 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/vfs/vfs_subr.c#3 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/vfs/vfs_syscalls.c#10 edit
.. //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/sebsd.c#14 edit

Differences ...

==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/SEDARWIN-NOTES#2 (text+ko) ====

@@ -51,9 +51,17 @@
 				vfs_syscalls.c:vn_truncate()
 				vfs_syscalls.c:vn_ftruncate()
 				kern_ktrace.c:ktrwrite()
+mac_init_mount			vfs_syscalls.c:mount()
+				vfs_rootmountalloc()
+mac_create_mount		vfs_syscalls.c:mount()
+				vfs_rootmountalloc()
+mac_destroy_mount		vfs_syscalls.c:dounmount()
+				vfs_syscalls.c:mount()
 
+
 mac_check_vnode_stat
 
+
 mac_init_vnode: called in kern_exec.c
 mac_init_vnode: called in kern_exec.c
 mpo_copy_vnode_label: called in kern_exec.c

==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/hfs/hfs_extattr.c#5 (text+ko) ====

@@ -288,6 +288,7 @@
     const char *attrname, struct vnode *backing_vnode, struct proc *p)
 {
 	struct hfs_extattr_list_entry	*attribute;
+	struct mount	*mp = HFSTOVFS(hfsmp);
 	struct iovec	aiov;
 	struct uio	auio;
 	int	error = 0;
@@ -357,6 +358,12 @@
 	LIST_INSERT_HEAD(&hfsmp->hfs_extattr.uepm_list, attribute,
 	    uele_entries);
 
+	/*
+	 * Since at least one attribute is on, set the mount flags
+	 * to indicate that this filesystem provides multilabel support
+	 */
+	mp->mnt_flag |= MNT_MULTILABEL;
+
 	VOP_UNLOCK(backing_vnode, 0, p);
 	return (0);
 

==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/hfs/hfs_vnops.c#4 (text+ko) ====

@@ -28,6 +28,7 @@
 #include <sys/buf.h>
 #include <sys/mount.h>
 #include <sys/vnode.h>
+#include <sys/mac.h>
 #include <sys/malloc.h>
 #include <sys/namei.h>
 #include <sys/ubc.h>
@@ -3745,6 +3746,9 @@
     { &vop_blktooff_desc, (VOPFUNC)hfs_blktooff },		/* blktooff */
     { &vop_offtoblk_desc, (VOPFUNC)hfs_offtoblk },		/* offtoblk */
     { &vop_cmap_desc, (VOPFUNC)hfs_cmap },			/* cmap */
+#ifdef MAC
+	{ &vop_setlabel_desc, (VOPFUNC) vop_stdsetlabel_ea },	/* MAC label */
+#endif
 #ifdef HFS_EXTATTR
     { &vop_getextattr_desc, (VOPFUNC)hfs_getextattr },
     { &vop_deleteextattr_desc, (VOPFUNC)hfs_deleteextattr },
@@ -3808,6 +3812,9 @@
         { &vop_copyfile_desc, (VOPFUNC)err_copyfile },		/* copyfile */
 	{ &vop_blktooff_desc, (VOPFUNC)hfs_blktooff },		/* blktooff */
 	{ &vop_offtoblk_desc, (VOPFUNC)hfs_offtoblk },		/* offtoblk */
+#ifdef MAC
+	{ &vop_setlabel_desc, (VOPFUNC) vop_stdsetlabel_ea },	/* MAC label */
+#endif
 #ifdef HFS_EXTATTR
 	{ &vop_getextattr_desc, (VOPFUNC)hfs_getextattr },
 	{ &vop_deleteextattr_desc, (VOPFUNC)hfs_deleteextattr },
@@ -3871,6 +3878,9 @@
 	{ &vop_blktooff_desc, (VOPFUNC)hfs_blktooff },		/* blktooff */
 	{ &vop_offtoblk_desc, (VOPFUNC)hfs_offtoblk },		/* offtoblk */
   	{ &vop_cmap_desc, (VOPFUNC)hfs_cmap },			/* cmap */
+#ifdef MAC
+	{ &vop_setlabel_desc, (VOPFUNC) vop_stdsetlabel_ea },	/* MAC label */
+#endif
 #ifdef HFS_EXTATTR
 	{ &vop_getextattr_desc, (VOPFUNC)hfs_getextattr },
 	{ &vop_deleteextattr_desc, (VOPFUNC)hfs_deleteextattr },

==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/kern/kern_mac.c#29 (text+ko) ====

@@ -466,7 +466,7 @@
 		} else if (claimed != 1) {				\
 			error = ENOENT;	/* XXX: ENOLABEL? */		\
 			break;						\
-		}							\
+		} 							\
 	}								\
 	sbuf_finish(&sb);						\
 } while (0)
@@ -1520,6 +1520,7 @@
 
 	return (error);
 }
+#endif
 
 static int
 mac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
@@ -1554,7 +1555,6 @@
 
 	return (error);
 }
-#endif
 
 int
 mac_execve_enter(struct mac *mac_p, struct label *execlabelstorage)
@@ -3389,7 +3389,6 @@
 	return (error);
 }
 
-#if 0 /* TBD/CDV */
 /*
  * Implementation of VOP_SETLABEL() that relies on extended attributes
  * to store label data.  Can be referenced by filesystems supporting
@@ -3399,7 +3398,7 @@
 vop_stdsetlabel_ea(struct vop_setlabel_args *ap)
 {
 	struct vnode *vp = ap->a_vp;
-	struct label *intlabel = ap->a_label;
+	struct label *intlabel = ap->a_vl;
 	int error;
 
 	ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea");
@@ -3416,50 +3415,6 @@
 	return (0);
 }
 
-static int
-vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred)
-{
-	int error;
-
-	if (vp->v_mount == NULL) {
-		/* printf("vn_setlabel: null v_mount\n"); */
-		if (vp->v_type != VNON)
-			printf("vn_setlabel: null v_mount with non-VNON\n");
-		return (EBADF);
-	}
-
-	if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
-		return (EOPNOTSUPP);
-
-	/*
-	 * Multi-phase commit.  First check the policies to confirm the
-	 * change is OK.  Then commit via the filesystem.  Finally,
-	 * update the actual vnode label.  Question: maybe the filesystem
-	 * should update the vnode at the end as part of VOP_SETLABEL()?
-	 */
-	error = mac_check_vnode_relabel(cred, vp, intlabel);
-	if (error)
-		return (error);
-
-	/*
-	 * VADMIN provides the opportunity for the filesystem to make
-	 * decisions about who is and is not able to modify labels
-	 * and protections on files.  This might not be right.  We can't
-	 * assume VOP_SETLABEL() will do it, because we might implement
-	 * that as part of vop_stdsetlabel_ea().
-	 */
-	error = VOP_ACCESS(vp, VADMIN, cred, current_proc());
-	if (error)
-		return (error);
-
-	error = VOP_SETLABEL(vp, intlabel, cred, current_proc());
-	if (error)
-		return (error);
-
-	return (0);
-}
-#endif
-
 struct __mac_get_pid_args
 {
   pid_t       pid;
@@ -3473,7 +3428,8 @@
 	struct mac mac;
 	struct proc *tproc;
 	struct ucred *tcred;
-	int error, ulen;
+	int error;
+	size_t ulen;
 
 	error = copyin(uap->mac_p, &mac, sizeof(mac));
 	if (error)
@@ -3523,6 +3479,19 @@
 {
 	int error;
 
+
+#if 0
+	/* TBD/XXX - We don' have multilabel vs. singlelabel semantics yet */
+	if (vp->v_mount == NULL) {
+		/* printf("vn_setlabel: null v_mount\n"); */
+		if (vp->v_type != VNON)
+			printf("vn_setlabel: null v_mount with non-VNON\n");
+		return (EBADF);
+	}
+
+	if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
+		return (EOPNOTSUPP);
+#endif
 	/*
 	 * Multi-phase commit.  First check the policies to confirm the
 	 * change is OK.  Then commit via the filesystem.  Finally,
@@ -3541,12 +3510,16 @@
 	 * that as part of vop_stdsetlabel_ea().
 	 */
 	error = VOP_ACCESS(vp, VADMIN, cred, p);
-	if (error)
+	if (error) {
+		printf("vn_setlabel: vop access failed %d\n", error);
 		return (error);
+	}
 
 	error = VOP_SETLABEL(vp, intlabel, cred, p);
-	if (error)
+	if (error) {
+		printf("vn_setlabel: vop setlabel failed %d\n", error);
 		return (error);
+	}
 
 	return (0);
 }
@@ -3565,7 +3538,8 @@
 	char *elements, *buffer;
 	struct mac mac;
 	struct ucred *cr;
-	int error, ulen;
+	int error;
+	size_t ulen;
 
 	error = copyin(uap->mac_p, &mac, sizeof(mac));
 	if (error)
@@ -3699,7 +3673,8 @@
 	struct pipe *pipe;
 #endif
 	short label_type;
-	int error, ulen;
+	int error;
+	size_t ulen;
 
 	error = copyin(uap->mac_p, &mac, sizeof(mac));
 	if (error)
@@ -3802,13 +3777,14 @@
 };
 
 int
-__mac_get_file(struct proc *td, struct __mac_get_file_args *uap, register_t *ret)
+__mac_get_file(struct proc *p, struct __mac_get_file_args *uap, register_t *ret)
 {
 	char *elements, *buffer;
 	struct nameidata nd;
 	struct label intlabel;
 	struct mac mac;
-	int error, ulen;
+	int error;
+	size_t ulen;
 
 	error = copyin(uap->mac_p, &mac, sizeof(mac));
 	if (error)
@@ -3830,7 +3806,7 @@
 	mutex_lock(&Giant);				/* VFS */ /* XXX FUNNEL? */
 #endif
 	NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p,
-	    td);
+	    p);
 	error = namei(&nd);
 	if (error)
 		goto out;
@@ -3867,13 +3843,14 @@
 };
 
 int
-__mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
+__mac_get_link(struct proc *p, struct __mac_get_link_args *uap)
 {
 	char *elements, *buffer;
 	struct nameidata nd;
 	struct label intlabel;
 	struct mac mac;
-	int error, ulen;
+	int error;
+	size_t ulen;
 
 	error = copyin(uap->mac_p, &mac, sizeof(mac));
 	if (error)
@@ -3895,7 +3872,7 @@
 	mutex_lock(&Giant);				/* VFS */ /* XXX FUNNEL? */
 #endif
 	NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p,
-	    td);
+	    p);
 	error = namei(&nd);
 	if (error)
 		goto out;
@@ -4033,22 +4010,25 @@
 };
 
 int
-__mac_set_file(struct proc *td, struct __mac_set_file_args *uap, register_t *ret)
+__mac_set_file(struct proc *p, struct __mac_set_file_args *uap, register_t *ret)
 {
 	struct label intlabel;
 	struct nameidata nd;
 	struct mount *mp;
 	struct mac mac;
 	char *buffer;
-	int error, dummy;
+	int error;
+	size_t dummy;
 
 	error = copyin(uap->mac_p, &mac, sizeof(mac));
 	if (error)
 		return (error);
 
 	error = mac_check_structmac_consistent(&mac);
-	if (error)
+	if (error) {
+		printf("mac_set_file: failed structure consistency check\n");
 		return (error);
+	}
 
 	MALLOC(buffer, char *, mac.m_buflen, M_MACTEMP, M_WAITOK);
 	error = copyinstr(mac.m_string, buffer, mac.m_buflen, &dummy);
@@ -4065,16 +4045,15 @@
 		return (error);
 	}
 
-	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path_p,
-	    td);
+	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path_p, p);
 	error = namei(&nd);
 	if (error == 0)
 	  {
 	    struct vnode *vp = nd.ni_vp;
 
-	    VOP_LEASE(vp, td, td->p_ucred, LEASE_WRITE);
-	    vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
-	    error = vn_setlabel (vp, &intlabel, td->p_ucred, td);
+	    VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
+	    vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
+	    error = vn_setlabel (vp, &intlabel, p->p_ucred, p);
 
 	    vput (nd.ni_vp);
 	}
@@ -4086,14 +4065,15 @@
  * MPSAFE
  */
 int
-__mac_set_link(struct proc *td, struct __mac_set_file_args *uap)
+__mac_set_link(struct proc *p, struct __mac_set_file_args *uap)
 {
 	struct label intlabel;
 	struct nameidata nd;
 	struct mount *mp;
 	struct mac mac;
 	char *buffer;
-	int error, dummy;
+	int error;
+	size_t dummy;
 
 	error = copyin(uap->mac_p, &mac, sizeof(mac));
 	if (error)
@@ -4118,17 +4098,16 @@
 		return (error);
 	}
 
-	NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, uap->path_p,
-	    td);
+	NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, uap->path_p, p);
 
 	error = namei(&nd);
 	if (error == 0)
 	  {
 	    struct vnode *vp = nd.ni_vp;
 
-	    VOP_LEASE(vp, td, td->p_ucred, LEASE_WRITE);
-	    vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
-	    error = vn_setlabel (vp, &intlabel, td->p_ucred, td);
+	    VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
+	    vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
+	    error = vn_setlabel (vp, &intlabel, p->p_ucred, p);
 
 	    vput (nd.ni_vp);
 	}
@@ -4147,7 +4126,7 @@
 };
 
 int
-mac_syscall(struct proc *td, struct mac_syscall_args *uap, register_t *retv)
+mac_syscall(struct proc *p, struct mac_syscall_args *uap, register_t *retv)
 {
 	struct mac_policy_conf *mpc;
 	char target[MAC_MAX_POLICY_NAME];
@@ -4162,7 +4141,7 @@
 	LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) {
 		if (strcmp(mpc->mpc_name, target) == 0 &&
 		    mpc->mpc_ops->mpo_syscall != NULL) {
-			error = mpc->mpc_ops->mpo_syscall(td,
+			error = mpc->mpc_ops->mpo_syscall(p,
 			    uap->call, uap->arg);
 			goto out;
 		}
@@ -4172,7 +4151,7 @@
 		LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {
 			if (strcmp(mpc->mpc_name, target) == 0 &&
 			    mpc->mpc_ops->mpo_syscall != NULL) {
-				error = mpc->mpc_ops->mpo_syscall(td,
+				error = mpc->mpc_ops->mpo_syscall(p,
 				    uap->call, uap->arg);
 				break;
 			}

==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/sys/extattr.h#4 (text+ko) ====

@@ -43,11 +43,10 @@
 #ifdef KERNEL
 
 #define	EXTATTR_MAXNAMELEN	NAME_MAX
-struct thread;
 struct ucred;
 struct vnode;
 int	extattr_check_cred(struct vnode *vp, int attrnamespace,
-	    struct ucred *cred, struct thread *td, int access);
+	    struct ucred *cred, struct proc *p, int access);
 
 #else
 #include <sys/cdefs.h>

==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/vfs/vfs_subr.c#3 (text+ko) ====

@@ -353,6 +353,10 @@
 	strncpy(mp->mnt_stat.f_fstypename, vfsp->vfc_name, MFSNAMELEN);
 	mp->mnt_stat.f_mntonname[0] = '/';
 	(void) copystr(devname, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, 0);
+#ifdef MAC
+	mac_init_mount(mp);
+	mac_create_mount(p->p_ucred, mp);
+#endif
 	*mpp = mp;
 	return (0);
 }

==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/bsd/vfs/vfs_syscalls.c#10 (text+ko) ====

@@ -284,6 +284,10 @@
 	strncpy(mp->mnt_stat.f_fstypename, vfsp->vfc_name, MFSNAMELEN);
 	mp->mnt_vnodecovered = vp;
 	mp->mnt_stat.f_owner = p->p_ucred->cr_uid;
+#ifdef MAC
+	mac_init_mount(mp);
+	mac_create_mount(p->p_ucred, mp);
+#endif
 	VOP_UNLOCK(vp, 0, p);
 
 update:
@@ -352,6 +356,9 @@
 		CLR(vp->v_flag, VMOUNT);
 		simple_unlock(&vp->v_interlock);
 		mp->mnt_vfc->vfc_refcount--;
+#ifdef MAC
+		mac_destroy_mount(mp);
+#endif
 		vfs_unbusy(mp, p);
 		_FREE_ZONE((caddr_t)mp, sizeof (struct mount), M_MOUNT);
 		if (err2)
@@ -566,6 +573,9 @@
 	if (mp->mnt_vnodelist.lh_first != NULL) {
 		 panic("unmount: dangling vnode"); 
 	}
+#ifdef MAC
+	mac_destroy_mount(mp);
+#endif
 	lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK, &mountlist_slock, p);
 out:
 	if (mp->mnt_kern_flag & MNTK_MWAIT)
@@ -4220,6 +4230,7 @@
 	size_t size, *sizep;
 	int error;
 
+#if 0
 	/*
 	 * XXX: Temporary API compatibility for applications that know
 	 * about this hack ("" means list), but haven't been updated
@@ -4228,6 +4239,7 @@
 	 */
 	if (strlen(attrname) == 0)
 		return (extattr_list_vp(vp, attrnamespace, data, nbytes, p, retval));
+#endif
 
 	VOP_LEASE(vp, p, p->p_ucred, LEASE_READ);
 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);

==== //depot/projects/trustedbsd/sedarwin/apsl/xnu/security/sebsd/sebsd.c#14 (text+ko) ====

@@ -457,7 +457,22 @@
   sebsd_free (SLOT(label), sizeof (struct vnode_security_struct));
   SLOT(label) = NULL;
 }
+
+static void
+sebsd_destroy_mount_label(struct label *label)
+{
+  sebsd_free (SLOT(label), sizeof (struct mount_security_struct));
+  SLOT(label) = NULL;
+}
+
 static void
+sebsd_destroy_mount_fs_label(struct label *label)
+{
+  sebsd_free (SLOT(label), sizeof (struct mount_fs_security_struct));
+  SLOT(label) = NULL;
+}
+
+static void
 sebsd_relabel_cred(struct ucred *cred, struct label *newlabel)
 {
   struct task_security_struct *task = SLOT(&cred->cr_label);
@@ -791,7 +806,7 @@
 
 static void
 sebsd_create_mount(struct ucred *cred, struct mount *mp,
-    struct label *mntlabel, struct label *fslabel, struct label *mount_arg_label)
+    struct label *mntlabel, struct label *fslabel)
 {
 	struct mount_security_struct *sbsec, *mntsec;
 	struct mount_fs_security_struct *sbfssec;
@@ -859,10 +874,15 @@
 		break;
 	}
 
+#if 0
+	/*
+	 * TBD/XXX - if we eventually allow /sbin/mount to pass a label
+	 */
 	if (mount_arg_label) {
 		mntsec = SLOT(mount_arg_label);
 		sbsec->sid = mntsec->sid;
 	}
+#endif
 }
 
 /*
@@ -1684,7 +1704,7 @@
 
 	task = SLOT(&cred->cr_label);
 	old = SLOT(oldlabel);
-	new = SLOT(oldlabel);
+	new = SLOT(newlabel);
 
 	AVC_AUDIT_DATA_INIT(&ad, FS);
 	ad.u.fs.vp = vp;
@@ -2134,7 +2154,7 @@
 	    FD__USE, NULL));
 }
 
-extern int sebsd_syscall(struct thread *td, int call, void *args);
+extern int sebsd_syscall(struct proc *p, int call, void *args);
 
 static struct mac_policy_ops sebsd_ops = {
   .mpo_init = sebsd_init,
@@ -2215,6 +2235,13 @@
   .mpo_check_vnode_stat = sebsd_check_vnode_stat,
   .mpo_check_vnode_write = sebsd_check_vnode_write,
 
+  /* Mount Points */
+  .mpo_init_mount_label = sebsd_init_mount_label,
+  .mpo_init_mount_fs_label = sebsd_init_mount_fs_label,
+  .mpo_create_mount = sebsd_create_mount,
+  .mpo_destroy_mount_label = sebsd_destroy_mount_label,
+  .mpo_destroy_mount_fs_label = sebsd_destroy_mount_fs_label,
+
   .mpo_syscall = sebsd_syscall
 };
 
@@ -2230,8 +2257,6 @@
 	.mpo_init_ifnet_label = sebsd_init_network_label,
 	.mpo_init_ipq_label = sebsd_init_network_label_waitcheck,
 	.mpo_init_mbuf_label = sebsd_init_network_label_waitcheck,
-	.mpo_init_mount_label = sebsd_init_mount_label,
-	.mpo_init_mount_fs_label = sebsd_init_mount_fs_label,
 #ifdef HAS_PIPES
 	.mpo_init_pipe_label = sebsd_init_vnode_label,
 #endif
@@ -2252,8 +2277,6 @@
 #if 0
 	.mpo_destroy_file_label = sebsd_destroy_label,
 #endif
-	.mpo_destroy_mount_label = sebsd_destroy_label,
-	.mpo_destroy_mount_fs_label = sebsd_destroy_label,
 #ifdef HAS_PIPES
 	.mpo_destroy_pipe_label = sebsd_destroy_label,
 #endif
@@ -2322,7 +2345,6 @@
 	.mpo_create_file = sebsd_create_file,
 #endif
 	/* .mpo_create_mbuf_from_socket = sebsd_create_mbuf_from_socket, */
-	.mpo_create_mount = sebsd_create_mount,
 #ifdef HAS_PIPES
 	.mpo_create_pipe = sebsd_create_pipe,
 #endif


More information about the p4-projects mailing list