initial import (Boeing r1752, NRL r878)

This commit is contained in:
ahrenholz 2013-08-29 14:21:13 +00:00
commit f8f46d28be
394 changed files with 99738 additions and 0 deletions

File diff suppressed because it is too large Load diff

24
kernel/freebsd/README.txt Normal file
View file

@ -0,0 +1,24 @@
CORE kernel patches
For information on the kernel modules ng_pipe and ng_wlan, see the README files in their respective directories. You should run the make && make install from
the module directories for CORE to work properly.
FreeBSD 8.x requires the small patches to allow per-node directories.
The FreeBSD 7.x version of CORE does not require the patch included here.
Instead you should download the latest vimage_7 kernel from:
http://imunes.net/virtnet/
The FreeBSD 4.11 version of CORE requires the included patch to work. See the
CORE manual for patching details.
ng_pipe module you should install with FreeBSD 4.11 or 7.x
ng_wlan module you should install with FreeBSD 4.11 or 7.x
4.11-R-CORE.diff patch you should use with FreeBSD 4.11
freebsd7-config-CORE config that you may use with vimage_7 kernels
freebsd7-config-COREDEBUG debugging config for use with vimage_7 kernels
vimage_7-CORE.diff patch to add multicast routing to vimage_7_20081015
imunes-8.0-RELEASE.diff per-node directories, persistent hub/switch, and
traffic snopping for wireshark for FreeBSD 8.0
symlinks-8.1-RELEASE.diff per-node directories for FreeBSD 8.1

View file

@ -0,0 +1,20 @@
#
# VIMAGE - sample kernel configuration file with a virtualized network stack
# configure.
#
# $FreeBSD$
#
include GENERIC
ident CORE
options IPSEC
device crypto
options VIMAGE
options IPFIREWALL
options IPFIREWALL_DEFAULT_TO_ACCEPT #allow everything by default
#
# Some kernel subsystems and functions don't yet compile with VIMAGE. Remove
# from the configuration for now.
#
nooptions SCTP

View file

@ -0,0 +1,22 @@
#
# VIMAGE - sample kernel configuration file with a virtualized network stack
# configure.
#
# $FreeBSD$
#
include GENERIC
ident COREDEBUG
device crypto
options IPSEC
options VIMAGE
options DDB
options GDB
options KDB
options KDB_TRACE
#
# Some kernel subsystems and functions don't yet compile with VIMAGE. Remove
# from the configuration for now.
#
nooptions SCTP

View file

@ -0,0 +1,11 @@
# this is the FreeBSD 8.x kernel configuration file for CORE
include GENERIC
ident CORE
options VIMAGE
nooptions SCTP
options IPSEC
device crypto
options IPFIREWALL
options IPFIREWALL_DEFAULT_TO_ACCEPT

View file

@ -0,0 +1,372 @@
# This patch is from http://imunes.net/imunes-8.0-RC3.diff
#
# This patch enables per-node directories, persistent hub/switch nodes, traffic
# snooping for wireshark, and disallows vlan interfaces within a jail.
diff -drup src-org/sys/kern/vfs_lookup.c src/sys/kern/vfs_lookup.c
--- src-org/sys/kern/vfs_lookup.c 2009-10-25 01:10:29.000000000 +0000
+++ src/sys/kern/vfs_lookup.c 2009-11-11 12:46:02.000000000 +0000
@@ -59,6 +59,8 @@ __FBSDID("$FreeBSD: src/sys/kern/vfs_loo
#include <sys/ktrace.h>
#endif
+#include <net/vnet.h>
+
#include <security/audit/audit.h>
#include <security/mac/mac_framework.h>
@@ -72,6 +74,19 @@ SDT_PROBE_DEFINE3(vfs, namei, lookup, en
"unsigned long");
SDT_PROBE_DEFINE2(vfs, namei, lookup, return, "int", "struct vnode *");
+#ifdef VIMAGE
+#define IMUNES_SYMLINK_HACK
+#endif
+
+#ifdef IMUNES_SYMLINK_HACK
+static VNET_DEFINE(int, morphing_symlinks);
+#define V_morphing_symlinks VNET(morphing_symlinks)
+
+SYSCTL_VNET_INT(_vfs, OID_AUTO, morphing_symlinks, CTLFLAG_RW,
+ &VNET_NAME(morphing_symlinks), 0,
+ "Resolve @ to vimage name in symlinks");
+#endif
+
/*
* Allocation zone for namei
*/
@@ -333,6 +348,44 @@ namei(struct nameidata *ndp)
error = ENOENT;
break;
}
+#ifdef IMUNES_SYMLINK_HACK
+ /*
+ * If the symbolic link includes a special character '@',
+ * and V_morphing_symlinks is set, substitute the first
+ * occurence of '@' with full path to jail / vimage name.
+ * If the full path includes subhierarchies, s/./\// when
+ * expanding '@' to jail / vimage name.
+ *
+ * XXX revisit buffer length checking.
+ */
+ CURVNET_SET_QUIET(TD_TO_VNET(curthread));
+ if (V_morphing_symlinks) {
+ char *sp = strchr(cp, '@');
+
+ if (sp) {
+ char *vname = td->td_ucred->cr_prison->pr_name;
+ int vnamelen = strlen(vname);
+ int i;
+
+ if (vnamelen >= auio.uio_resid) {
+ if (ndp->ni_pathlen > 1)
+ uma_zfree(namei_zone, cp);
+ error = ENAMETOOLONG;
+ CURVNET_RESTORE();
+ break;
+ }
+ bcopy(sp + 1, sp + vnamelen,
+ linklen - (sp - cp));
+ bcopy(td->td_ucred->cr_prison->pr_name,
+ sp, vnamelen);
+ linklen += (vnamelen - 1);
+ for (i = 0; i < vnamelen; i++)
+ if (sp[i] == '.')
+ sp[i] = '/';
+ }
+ }
+ CURVNET_RESTORE();
+#endif
if (linklen + ndp->ni_pathlen >= MAXPATHLEN) {
if (ndp->ni_pathlen > 1)
uma_zfree(namei_zone, cp);
diff -drup src-org/sys/net/bpf.c src/sys/net/bpf.c
--- src-org/sys/net/bpf.c 2009-10-25 01:10:29.000000000 +0000
+++ src/sys/net/bpf.c 2009-11-11 12:46:02.000000000 +0000
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD: src/sys/net/bpf.c,v
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
+#include <sys/ctype.h>
#include <sys/fcntl.h>
#include <sys/jail.h>
#include <sys/malloc.h>
@@ -1435,9 +1436,34 @@ bpf_setif(struct bpf_d *d, struct ifreq
struct bpf_if *bp;
struct ifnet *theywant;
+#define XVNET_BPF_SNOOPING
+#if defined(VIMAGE) && defined(XVNET_BPF_SNOOPING)
+ struct vnet *target_vnet = curvnet;
+ char *c;
+
+ /* Attempt to attach to an ifnet in a foreign vnet, specified as @ */
+ c = rindex(ifr->ifr_name, '@');
+ if ( c != NULL ) {
+ struct prison *target_pr;
+
+ *c++ = 0;
+ if (!isascii(*c) && !isdigit(*c))
+ return ENXIO;
+ target_pr = prison_find_name(curthread->td_ucred->cr_prison, c);
+ if (target_pr == NULL)
+ return ENXIO;
+ target_vnet = target_pr->pr_vnet;
+ }
+ CURVNET_SET_QUIET(target_vnet);
+#endif
+
theywant = ifunit(ifr->ifr_name);
- if (theywant == NULL || theywant->if_bpf == NULL)
+ if (theywant == NULL || theywant->if_bpf == NULL) {
+#if defined(VIMAGE) && defined(XVNET_BPF_SNOOPING)
+ CURVNET_RESTORE();
+#endif
return (ENXIO);
+ }
bp = theywant->if_bpf;
@@ -1477,6 +1503,9 @@ bpf_setif(struct bpf_d *d, struct ifreq
BPFD_LOCK(d);
reset_d(d);
BPFD_UNLOCK(d);
+#if defined(VIMAGE) && defined(XVNET_BPF_SNOOPING)
+ CURVNET_RESTORE();
+#endif
return (0);
}
diff -drup src-org/sys/net/if.c src/sys/net/if.c
--- src-org/sys/net/if.c 2009-10-25 01:10:29.000000000 +0000
+++ src/sys/net/if.c 2009-11-11 12:46:02.000000000 +0000
@@ -813,6 +813,14 @@ if_detach_internal(struct ifnet *ifp, in
struct ifnet *iter;
int found = 0;
+ /*
+ * Detach from any vlan, bridge or lagg ifnets linked to us.
+ * A small though unlikely window for a race from here to ifp
+ * unlinking from ifnet list is possible, hence we repeat the
+ * procedure once again further bellow. XXX.
+ */
+ EVENTHANDLER_INVOKE(ifnet_departure_event, ifp);
+
IFNET_WLOCK();
TAILQ_FOREACH(iter, &V_ifnet, if_link)
if (iter == ifp) {
diff -drup src-org/sys/net/if_llatbl.c src/sys/net/if_llatbl.c
--- src-org/sys/net/if_llatbl.c 2009-10-25 01:10:29.000000000 +0000
+++ src/sys/net/if_llatbl.c 2009-11-11 12:53:49.000000000 +0000
@@ -57,11 +57,14 @@ __FBSDID("$FreeBSD: src/sys/net/if_llatb
MALLOC_DEFINE(M_LLTABLE, "lltable", "link level address tables");
-static SLIST_HEAD(, lltable) lltables = SLIST_HEAD_INITIALIZER(lltables);
+static VNET_DEFINE(SLIST_HEAD(, lltable), lltables);
+#define V_lltables VNET(lltables)
extern void arprequest(struct ifnet *, struct in_addr *, struct in_addr *,
u_char *);
+static void vnet_lltable_init(void);
+
struct rwlock lltable_rwlock;
RW_SYSINIT(lltable_rwlock, &lltable_rwlock, "lltable_rwlock");
@@ -75,7 +78,7 @@ lltable_sysctl_dumparp(int af, struct sy
int error = 0;
LLTABLE_RLOCK();
- SLIST_FOREACH(llt, &lltables, llt_link) {
+ SLIST_FOREACH(llt, &V_lltables, llt_link) {
if (llt->llt_af == af) {
error = llt->llt_dump(llt, wr);
if (error != 0)
@@ -157,7 +160,7 @@ lltable_free(struct lltable *llt)
KASSERT(llt != NULL, ("%s: llt is NULL", __func__));
LLTABLE_WLOCK();
- SLIST_REMOVE(&lltables, llt, lltable, llt_link);
+ SLIST_REMOVE(&V_lltables, llt, lltable, llt_link);
LLTABLE_WUNLOCK();
for (i=0; i < LLTBL_HASHTBL_SIZE; i++) {
@@ -180,7 +183,7 @@ lltable_drain(int af)
register int i;
LLTABLE_RLOCK();
- SLIST_FOREACH(llt, &lltables, llt_link) {
+ SLIST_FOREACH(llt, &V_lltables, llt_link) {
if (llt->llt_af != af)
continue;
@@ -202,7 +205,7 @@ lltable_prefix_free(int af, struct socka
struct lltable *llt;
LLTABLE_RLOCK();
- SLIST_FOREACH(llt, &lltables, llt_link) {
+ SLIST_FOREACH(llt, &V_lltables, llt_link) {
if (llt->llt_af != af)
continue;
@@ -232,7 +235,7 @@ lltable_init(struct ifnet *ifp, int af)
LIST_INIT(&llt->lle_head[i]);
LLTABLE_WLOCK();
- SLIST_INSERT_HEAD(&lltables, llt, llt_link);
+ SLIST_INSERT_HEAD(&V_lltables, llt, llt_link);
LLTABLE_WUNLOCK();
return (llt);
@@ -302,7 +305,7 @@ lla_rt_output(struct rt_msghdr *rtm, str
/* XXX linked list may be too expensive */
LLTABLE_RLOCK();
- SLIST_FOREACH(llt, &lltables, llt_link) {
+ SLIST_FOREACH(llt, &V_lltables, llt_link) {
if (llt->llt_af == dst->sa_family &&
llt->llt_ifp == ifp)
break;
@@ -367,3 +370,12 @@ lla_rt_output(struct rt_msghdr *rtm, str
return (error);
}
+
+static void
+vnet_lltable_init()
+{
+
+ SLIST_INIT(&V_lltables);
+}
+VNET_SYSINIT(vnet_lltable_init, SI_SUB_PSEUDO, SI_ORDER_FIRST, vnet_lltable_init, NULL);
+
diff -drup src-org/sys/net/if_vlan.c src/sys/net/if_vlan.c
--- src-org/sys/net/if_vlan.c 2009-10-25 01:10:29.000000000 +0000
+++ src/sys/net/if_vlan.c 2009-11-11 12:46:02.000000000 +0000
@@ -1359,6 +1359,12 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd
error = copyin(ifr->ifr_data, &vlr, sizeof(vlr));
if (error)
break;
+#ifdef VIMAGE
+ if (ifp->if_home_vnet != ifp->if_vnet) {
+ error = EPERM;
+ break;
+ }
+#endif
if (vlr.vlr_parent[0] == '\0') {
vlan_unconfig(ifp);
break;
@@ -1386,6 +1392,12 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd
case SIOCGETVLAN:
bzero(&vlr, sizeof(vlr));
+#ifdef VIMAGE
+ if (ifp->if_home_vnet != ifp->if_vnet) {
+ error = EPERM;
+ break;
+ }
+#endif
VLAN_LOCK();
if (TRUNK(ifv) != NULL) {
strlcpy(vlr.vlr_parent, PARENT(ifv)->if_xname,
diff -drup src-org/sys/netgraph/ng_bridge.c src/sys/netgraph/ng_bridge.c
--- src-org/sys/netgraph/ng_bridge.c 2009-10-25 01:10:29.000000000 +0000
+++ src/sys/netgraph/ng_bridge.c 2009-11-11 12:46:02.000000000 +0000
@@ -105,6 +105,7 @@ struct ng_bridge_private {
u_int numBuckets; /* num buckets in table */
u_int hashMask; /* numBuckets - 1 */
int numLinks; /* num connected links */
+ int persistent; /* can exist w/o any hooks */
struct callout timer; /* one second periodic timer */
};
typedef struct ng_bridge_private *priv_p;
@@ -345,13 +346,13 @@ static int
ng_bridge_newhook(node_p node, hook_p hook, const char *name)
{
const priv_p priv = NG_NODE_PRIVATE(node);
+ int linkNum = -1;
/* Check for a link hook */
if (strncmp(name, NG_BRIDGE_HOOK_LINK_PREFIX,
strlen(NG_BRIDGE_HOOK_LINK_PREFIX)) == 0) {
const char *cp;
char *eptr;
- u_long linkNum;
cp = name + strlen(NG_BRIDGE_HOOK_LINK_PREFIX);
if (!isdigit(*cp) || (cp[0] == '0' && cp[1] != '\0'))
@@ -359,6 +360,12 @@ ng_bridge_newhook(node_p node, hook_p ho
linkNum = strtoul(cp, &eptr, 10);
if (*eptr != '\0' || linkNum >= NG_BRIDGE_MAX_LINKS)
return (EINVAL);
+ } else if (strcmp(name, "anchor") == 0) {
+ linkNum = 0;
+ priv->persistent = 1;
+ }
+
+ if (linkNum >= 0 ) {
if (priv->links[linkNum] != NULL)
return (EISCONN);
priv->links[linkNum] = malloc(sizeof(*priv->links[linkNum]),
@@ -366,7 +373,7 @@ ng_bridge_newhook(node_p node, hook_p ho
if (priv->links[linkNum] == NULL)
return (ENOMEM);
priv->links[linkNum]->hook = hook;
- NG_HOOK_SET_PRIVATE(hook, (void *)linkNum);
+ NG_HOOK_SET_PRIVATE(hook, (void *)(intptr_t)linkNum);
priv->numLinks++;
return (0);
}
@@ -799,7 +806,8 @@ ng_bridge_disconnect(hook_p hook)
/* If no more hooks, go away */
if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0)
- && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))) {
+ && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))
+ && !priv->persistent) {
ng_rmnode_self(NG_HOOK_NODE(hook));
}
return (0);
diff -drup src-org/sys/netgraph/ng_hub.c src/sys/netgraph/ng_hub.c
--- src-org/sys/netgraph/ng_hub.c 2009-10-25 01:10:29.000000000 +0000
+++ src/sys/netgraph/ng_hub.c 2009-11-11 12:46:02.000000000 +0000
@@ -37,6 +37,7 @@
#include <netgraph/netgraph.h>
static ng_constructor_t ng_hub_constructor;
+static ng_newhook_t ng_hub_newhook;
static ng_rcvdata_t ng_hub_rcvdata;
static ng_disconnect_t ng_hub_disconnect;
@@ -44,6 +45,7 @@ static struct ng_type ng_hub_typestruct
.version = NG_ABI_VERSION,
.name = NG_HUB_NODE_TYPE,
.constructor = ng_hub_constructor,
+ .newhook = ng_hub_newhook,
.rcvdata = ng_hub_rcvdata,
.disconnect = ng_hub_disconnect,
};
@@ -57,6 +59,14 @@ ng_hub_constructor(node_p node)
return (0);
}
+static int
+ng_hub_newhook(node_p node, hook_p hook, const char *name)
+{
+ if (strcmp(name, "anchor") == 0)
+ node->nd_private = (void *) 1;
+ return (0);
+}
+
static int
ng_hub_rcvdata(hook_p hook, item_p item)
{
@@ -94,7 +104,7 @@ ng_hub_disconnect(hook_p hook)
{
if (NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0 &&
- NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))
+ NG_NODE_IS_VALID(NG_HOOK_NODE(hook)) && !hook->hk_node->nd_private)
ng_rmnode_self(NG_HOOK_NODE(hook));
return (0);
}

View file

@ -0,0 +1,27 @@
#
# (c)2008 the Boeing Company
#
# modified ng_pipe node
#
.if !defined(PLATFORM)
#PLATFORM=i386
PLATFORM=amd64
.endif
CFLAGS=-DBOEING_WLAN -I/usr/src/sys/${PLATFORM}/compile/CORE
KMOD= ng_pipe
SRCS= ng_pipe.c
#MAN= ng_pipe.4
# FreeBSD 4.11 is "FreeBSD" and 7.0 is "freebsd7.0"
#.if defined(OSTYPE)
#.if (${OSTYPE} == "FreeBSD")
#CFLAGS+=-DFREEBSD411
#SRCS= ng_pipe_freebsd4.c
#.endif
#.endif
.include <bsd.kmod.mk>

View file

@ -0,0 +1,21 @@
ng_pipe FreeBSD kernel module
See the copyright statement at the top of the source file.
Copyright (c) 2004, 2005, 2007 University of Zagreb
Copyright (c) 2007 FreeBSD Foundation
(c) 2008 the Boeing Company
modifications: Jeff Ahrenholz <jeffrey.m.ahrenholz@boeing.com>
More complete documentation is available in the ng_pipe(4) man page.
This version of ng_pipe has been modified as follows:
- added burst rate (or burstiness) which is the probability that the next packet
will be dropped given an error with the current packet, 0 to 100
- added jitter effect, which randomizes the delay an additional amount from
0 to jitter microseconds
- ng_wlan support added, to remove and read mbuf tags containing wlan link
effect information
- bugfix: random number generation improved from defective modulo algorithm
- bugfix: fixed mbuf dangling pointer reference when ng_pipe has both duplicates
and errors configured

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,171 @@
/*
* Copyright (c) 2004, 2007 University of Zagreb
* Copyright (c) 2007 FreeBSD Foundation
*
* This software was developed by the University of Zagreb and the
* FreeBSD Foundation under sponsorship by the Stichting NLnet and the
* FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _NETGRAPH_PIPE_H_
#define _NETGRAPH_PIPE_H_
/* Node type name and magic cookie */
#define NG_PIPE_NODE_TYPE "pipe"
#define NGM_PIPE_COOKIE 200708191
/* Hook names */
#define NG_PIPE_HOOK_UPPER "upper"
#define NG_PIPE_HOOK_LOWER "lower"
#define MAX_FSIZE 16384 /* Largest supported frame size, in bytes, for BER */
#define MAX_OHSIZE 256 /* Largest supported dummy-framing size, in bytes */
/* Statistics structure for one hook */
struct ng_pipe_hookstat {
u_int64_t fwd_octets;
u_int64_t fwd_frames;
u_int64_t in_disc_octets;
u_int64_t in_disc_frames;
u_int64_t out_disc_octets;
u_int64_t out_disc_frames;
};
/* Keep this in sync with the above structure definition */
#define NG_PIPE_HOOKSTAT_INFO { \
{ "FwdOctets", &ng_parse_uint64_type }, \
{ "FwdFrames", &ng_parse_uint64_type }, \
{ "queueDropOctets", &ng_parse_uint64_type }, \
{ "queueDropFrames", &ng_parse_uint64_type }, \
{ "delayDropOctets", &ng_parse_uint64_type }, \
{ "delayDropFrames", &ng_parse_uint64_type }, \
{ NULL }, \
}
/* Statistics structure returned by NGM_PIPE_GET_STATS */
struct ng_pipe_stats {
struct ng_pipe_hookstat downstream;
struct ng_pipe_hookstat upstream;
};
/* Keep this in sync with the above structure definition */
#define NG_PIPE_STATS_INFO(hstype) { \
{ "downstream", (hstype) }, \
{ "upstream", (hstype) }, \
{ NULL }, \
}
/* Runtime structure for one hook */
struct ng_pipe_hookrun {
u_int32_t fifo_queues;
u_int32_t qin_octets;
u_int32_t qin_frames;
u_int32_t qout_octets;
u_int32_t qout_frames;
};
/* Keep this in sync with the above structure definition */
#define NG_PIPE_HOOKRUN_INFO { \
{ "queues", &ng_parse_uint32_type }, \
{ "queuedOctets", &ng_parse_uint32_type }, \
{ "queuedFrames", &ng_parse_uint32_type }, \
{ "delayedOctets", &ng_parse_uint32_type }, \
{ "delayedFrames", &ng_parse_uint32_type }, \
{ NULL }, \
}
/* Runtime structure returned by NGM_PIPE_GET_RUN */
struct ng_pipe_run {
struct ng_pipe_hookrun downstream;
struct ng_pipe_hookrun upstream;
};
/* Keep this in sync with the above structure definition */
#define NG_PIPE_RUN_INFO(hstype) { \
{ "downstream", (hstype) }, \
{ "upstream", (hstype) }, \
{ NULL }, \
}
/* Config structure for one hook */
struct ng_pipe_hookcfg {
u_int64_t bandwidth;
u_int64_t ber;
u_int32_t qin_size_limit;
u_int32_t qout_size_limit;
u_int32_t duplicate;
u_int32_t fifo;
u_int32_t drr;
u_int32_t wfq;
u_int32_t droptail;
u_int32_t drophead;
};
/* Keep this in sync with the above structure definition */
#define NG_PIPE_HOOKCFG_INFO { \
{ "bandwidth", &ng_parse_uint64_type }, \
{ "BER", &ng_parse_uint64_type }, \
{ "queuelen", &ng_parse_uint32_type }, \
{ "delaylen", &ng_parse_uint32_type }, \
{ "duplicate", &ng_parse_uint32_type }, \
{ "fifo", &ng_parse_uint32_type }, \
{ "drr", &ng_parse_uint32_type }, \
{ "wfq", &ng_parse_uint32_type }, \
{ "droptail", &ng_parse_uint32_type }, \
{ "drophead", &ng_parse_uint32_type }, \
{ NULL }, \
}
/* Config structure returned by NGM_PIPE_GET_CFG */
struct ng_pipe_cfg {
u_int64_t bandwidth;
u_int64_t delay;
u_int32_t header_offset;
u_int32_t overhead;
struct ng_pipe_hookcfg downstream;
struct ng_pipe_hookcfg upstream;
};
/* Keep this in sync with the above structure definition */
#define NG_PIPE_CFG_INFO(hstype) { \
{ "bandwidth", &ng_parse_uint64_type }, \
{ "delay", &ng_parse_uint64_type }, \
{ "header_offset", &ng_parse_uint32_type }, \
{ "overhead", &ng_parse_uint32_type }, \
{ "downstream", (hstype) }, \
{ "upstream", (hstype) }, \
{ NULL }, \
}
/* Netgraph commands */
enum {
NGM_PIPE_GET_STATS=1, /* get stats */
NGM_PIPE_CLR_STATS, /* clear stats */
NGM_PIPE_GETCLR_STATS, /* atomically get and clear stats */
NGM_PIPE_GET_RUN, /* get current runtime status */
NGM_PIPE_GET_CFG, /* get configurable parameters */
NGM_PIPE_SET_CFG, /* set configurable parameters */
};
#endif /* _NETGRAPH_PIPE_H_ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,27 @@
#
# (c)2006-2011 the Boeing Company
#
# ng_wlan
#
.if !defined(PLATFORM)
#PLATFORM=i386
PLATFORM=amd64
.endif
CFLAGS+=-I/usr/src/sys/${PLATFORM}/compile/CORE -DMULTICAST_LOOKUPS
# FreeBSD 4.11 is "FreeBSD" and 7.0 is "freebsd7.0"
#.if defined(OSTYPE)
#.if (${OSTYPE} == "FreeBSD")
#CFLAGS+=-DFREEBSD411
#.endif
#.endif
KMOD= ng_wlan
SRCS= ng_wlan.c
#MAN= ng_wlan.4
.include <bsd.kmod.mk>

View file

@ -0,0 +1,50 @@
ng_wlan FreeBSD kernel module
(c) 2006-2011 the Boeing Company
author: Jeff Ahrenholz <jeffrey.m.ahrenholz@boeing.com>
The ng_wlan modules implements a netgraph node that models wireless
LAN connectivity. ng_wlan extends the ng_hub node, only instead of sending
packets to each connected peer, maintains a hash table of node connectivity,
and sends packets between two nodes only when they are linked. By default all
nodes are unlinked. Nodes can be linked and unlinked using "link" and
"unlink" messages:
ngctl msg e0_n2: link { node1=0x23 node2=0x0c }
The node IDs of the two nodes are the parameters, as depicted above.
Link effects between can also be specified for each node pair. If two nodes
are linked and parameters are specified, an mbuf tag will be added to each data
packet mbuf that specifies the effects. For FreeBSD 4.11, the metadata parameter
is used instead of mbuf tags. Delay (microseconds), bandwidth
(bits per second), PER (% packet errors), duplicates (%), jitter
(microseconds), and burst (% burst errors) are supported. This tag is then
removed by the ng_pipe node and the appropriate effects are applied. Link
effects are specified with "set" and "unset" messages:
ngctl msg e0_n2: set { node1=0x23 node2=0x0c delay=50000 bandwidth=54000000 per=0 duplicate=0 jitter=5000 burst=30 }
ngctl msg e0_n2: unset { node1=0x23 node2=0x0c }
Note that a special ng_pipe module is needed (the default one does not support
the mbuf tags and some effects.)
A separate error rate and burst rate affecting all multicast packets may be
defined. Use the "mer" message:
ngctl msg e0_n2: mer { mer=20 mburst=35 }
The above example sets the multicast error rate to drop 20% of all multicast
packets, with 35% burst errors.
When MULTICAST_LOOKUPS is defined, a second lookup table is defined for each
WLAN where multicast group, source, and node pair tuples can be linked or
unlinked. This causes different forwarding behavior for multicast packets,
where non-local groups are only forwarded if the node pair has been linked
together for that group (and the normal node pair has been linked).
Usage:
ngctl msg e0_n2: mcastset { node1=0x23 node2=0x0c group=0xEF020364 source=0x0a000002 }
ngctl msg e0_n2: mcastset { node1=0x23 node2=0x0c group=0xEF020364 source=0}
ngctl msg e0_n2: mcastunset { node1=0x23 node2=0x0c group=0xEF020364 source=0 }
Once the first mcastset/mcastunset message is received, that ng_wlan will drop
all non-local multicast packets that do not have a matching source, group,
node pair entry. The source address of zero matches any IP source.

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,109 @@
/*
* Copyright (c) 2006-2011 the Boeing Company
* ng_wlan is based on ng_hub, which is:
* Copyright (c) 2004 Ruslan Ermilov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#ifndef _NETGRAPH_NG_WLAN_H_
#define _NETGRAPH_NG_WLAN_H_
/* Node type name and magic cookie. */
#define NG_WLAN_NODE_TYPE "wlan"
#define NGM_WLAN_COOKIE 1146673193
/* Control message parse info */
struct ng_wlan_config {
u_int32_t node1;
u_int32_t node2;
};
#define NG_WLAN_CONFIG_TYPE_INFO { \
{ "node1", &ng_parse_uint32_type }, \
{ "node2", &ng_parse_uint32_type }, \
{ NULL } \
}
struct ng_wlan_set_data {
u_int32_t node1;
u_int32_t node2;
u_int64_t delay; /* keep these aligned with struct ng_wlan_tag */
u_int64_t bandwidth;
u_int16_t per;
u_int16_t duplicate;
u_int32_t jitter;
u_int16_t burst;
};
#define NG_WLAN_SET_DATA_TYPE_INFO { \
{ "node1", &ng_parse_uint32_type }, \
{ "node2", &ng_parse_uint32_type }, \
{ "delay", &ng_parse_uint64_type }, \
{ "bandwidth", &ng_parse_uint64_type }, \
{ "per", &ng_parse_uint16_type }, \
{ "duplicate", &ng_parse_uint16_type }, \
{ "jitter", &ng_parse_uint32_type }, \
{ "burst", &ng_parse_uint16_type }, \
{ NULL } \
}
struct ng_wlan_mer {
uint16_t mer;
uint16_t mburst;
};
#define NG_WLAN_MER_TYPE_INFO { \
{ "mer", &ng_parse_uint16_type }, \
{ "mburst", &ng_parse_uint16_type }, \
{ NULL } \
}
#ifdef MULTICAST_LOOKUPS
struct ng_wlan_multicast_set_data {
u_int32_t node1;
u_int32_t node2;
u_int32_t group;
u_int32_t source;
};
#define NG_WLAN_MULTICAST_SET_DATA_TYPE_INFO { \
{ "node1", &ng_parse_uint32_type }, \
{ "node2", &ng_parse_uint32_type }, \
{ "group", &ng_parse_uint32_type }, \
{ "source", &ng_parse_uint32_type }, \
{ NULL } \
}
#endif /* MULTICAST_LOOKUPS */
/* List of supported Netgraph control messages */
enum {
NGM_WLAN_LINK_NODES = 1,
NGM_WLAN_UNLINK_NODES,
NGM_WLAN_NODES_SET,
NGM_WLAN_NODES_UNSET,
NGM_WLAN_NODES_GET,
NGM_WLAN_MER, /* MULTICAST_ERR */
NGM_WLAN_MULTICAST_SET, /* MULTICAST_LOOKUPS */
NGM_WLAN_MULTICAST_UNSET, /* MULTICAST_LOOKUPS */
NGM_WLAN_MULTICAST_GET, /* MULTICAST_LOOKUPS */
};
#endif /* _NETGRAPH_NG_WLAN_H_ */

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2006-2011 the Boeing Company
* All rights reserved.
*
* author: Jeff Ahrenholz <jeffrey.m.ahrenholz@boeing.com>
*/
#define NG_TAG_WLAN 0x01
#ifdef FREEBSD411
#define WLAN_META_SIZE (sizeof(struct ng_meta))+(sizeof(struct ng_wlan_tag))
#define WLAN_META_PRIORITY 0x01
#define TAGSIZE (sizeof(struct ng_wlan_tag) - sizeof(struct meta_field_header))
#else
#define TAGSIZE (sizeof(struct ng_wlan_tag) - sizeof(struct m_tag))
#endif
#define NG_WLAN_MAX_DELAY 2000000 /* 2,000,000us = 2s */
#define NG_WLAN_MAX_BW 1000000000 /* 1,000,000,000bps = 1000M */
#define NG_WLAN_MAX_PER 100 /* 100% */
#define NG_WLAN_MAX_DUP 50 /* 50% */
#define NG_WLAN_MAX_JITTER NG_WLAN_MAX_DELAY
#define NG_WLAN_MAX_BURST NG_WLAN_MAX_PER
/* Tag data that is prepended to packets passing through the WLAN node.
*/
struct ng_wlan_tag {
#ifdef FREEBSD411
struct meta_field_header meta_hdr;
#else
struct m_tag tag;
#endif
u_int64_t delay;
u_int64_t bandwidth;
u_int16_t per;
u_int16_t duplicate;
u_int32_t jitter;
u_int16_t burst;
};
#define TAG_HAS_DATA(t) (t->delay || t->bandwidth || t->per || t->duplicate \
|| t->jitter || t->burst )
#define WLAN_TAG_ZERO(t) do { \
t->delay = 0; \
t->bandwidth = 0; \
t->per = 0; \
t->duplicate = 0; \
t->jitter = 0; \
t->burst = 0; \
} while(0);
#define WLAN_TAG_COPY(a, b) do { \
a->delay = ((struct ng_wlan_tag*)b)->delay; \
a->bandwidth = ((struct ng_wlan_tag*)b)->bandwidth; \
a->per = ((struct ng_wlan_tag*)b)->per; \
a->duplicate = ((struct ng_wlan_tag*)b)->duplicate; \
a->jitter = ((struct ng_wlan_tag*)b)->jitter; \
a->burst = ((struct ng_wlan_tag*)b)->burst; \
} while(0);

View file

@ -0,0 +1,78 @@
Index: sys/kern/vfs_lookup.c
===========================================================================
--- sys/kern/vfs_lookup.c 2010/06/17 19:18:00 #3
+++ sys/kern/vfs_lookup.c 2010/06/17 19:18:00
@@ -59,6 +59,8 @@
#include <sys/ktrace.h>
#endif
+#include <net/vnet.h>
+
#include <security/audit/audit.h>
#include <security/mac/mac_framework.h>
@@ -72,6 +74,19 @@
"unsigned long");
SDT_PROBE_DEFINE2(vfs, namei, lookup, return, "int", "struct vnode *");
+#ifdef VIMAGE
+#define IMUNES_SYMLINK_HACK
+#endif
+
+#ifdef IMUNES_SYMLINK_HACK
+static VNET_DEFINE(int, morphing_symlinks);
+#define V_morphing_symlinks VNET(morphing_symlinks)
+
+SYSCTL_VNET_INT(_vfs, OID_AUTO, morphing_symlinks, CTLFLAG_RW,
+ &VNET_NAME(morphing_symlinks), 0,
+ "Resolve @ to vimage name in symlinks");
+#endif
+
/*
* Allocation zone for namei
*/
@@ -333,6 +348,44 @@
error = ENOENT;
break;
}
+#ifdef IMUNES_SYMLINK_HACK
+ /*
+ * If the symbolic link includes a special character '@',
+ * and V_morphing_symlinks is set, substitute the first
+ * occurence of '@' with full path to jail / vimage name.
+ * If the full path includes subhierarchies, s/./\// when
+ * expanding '@' to jail / vimage name.
+ *
+ * XXX revisit buffer length checking.
+ */
+ CURVNET_SET_QUIET(TD_TO_VNET(curthread));
+ if (V_morphing_symlinks) {
+ char *sp = strchr(cp, '@');
+
+ if (sp) {
+ char *vname = td->td_ucred->cr_prison->pr_name;
+ int vnamelen = strlen(vname);
+ int i;
+
+ if (vnamelen >= auio.uio_resid) {
+ if (ndp->ni_pathlen > 1)
+ uma_zfree(namei_zone, cp);
+ error = ENAMETOOLONG;
+ CURVNET_RESTORE();
+ break;
+ }
+ bcopy(sp + 1, sp + vnamelen,
+ linklen - (sp - cp));
+ bcopy(td->td_ucred->cr_prison->pr_name,
+ sp, vnamelen);
+ linklen += (vnamelen - 1);
+ for (i = 0; i < vnamelen; i++)
+ if (sp[i] == '.')
+ sp[i] = '/';
+ }
+ }
+ CURVNET_RESTORE();
+#endif
if (linklen + ndp->ni_pathlen >= MAXPATHLEN) {
if (ndp->ni_pathlen > 1)
uma_zfree(namei_zone, cp);

View file

@ -0,0 +1,14 @@
# $FreeBSD$
PROG= vimage
LDADD= -ljail
DPADD= ${LIBJAIL}
WARNS?= 2
CFLAGS+= -I../../../sys
MAN= vimage.8
BINDIR?= /usr/sbin
.include <bsd.prog.mk>

View file

@ -0,0 +1,195 @@
.\" Copyright (c) 2002, 2003 Marko Zec <zec@fer.hr>
.\" Copyright (c) 2009 University of Zagreb
.\" Copyright (c) 2009 FreeBSD Foundation
.\"
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD$
.\"
.Dd August 25, 2009
.Dt VIMAGE 8
.Os
.Sh NAME
.Nm vimage
.Nd manage virtual network stacks
.Sh SYNOPSIS
.Nm
.Op Fl c | m
.Ar vname
.Op Ar param=value ...
.Nm
.Fl d
.Ar vname
.Nm
.Fl l
.Op Fl rvj
.Op Ar vname
.Nm
.Fl i
.Ar vname ifname
.Op Ar newifname
.Nm
.Ar vi_name
.Op command ...
.Sh DESCRIPTION
The
.Nm
utility is an alternative user interface for controlling virtual network
stacks in FreeBSD, aimed primarily at supporting legacy applications
which are not yet converted to using
.Xr jail 8 ,
.Xr jexec 8 ,
and
.Xr jls 8 .
.
.Ss Overview
A virtual image or vimage is a jail with its own independent network
stack instance. Every process, socket and network interface present
in the system is always attached to one, and only one, virtual network
stack instance (vnet).
During system bootup sequence a default vnet
is created to which all the configured interfaces and user processes
are initially attached.
Assuming that enough system resources are
are available, a user with sufficient privileges can create and manage
a hierarchy of subordinated virtual images.
The
.Nm
command allows for creation, deletion and monitoring of virtual images,
as well as for execution of arbitrary processes in a targeted virtual
image.
.Ss Invocation
If invoked with no modifiers, the
.Nm
command spawns a new interactive shell in virtual image
.Ar vname .
If optional additional arguments following
.Ar vname
are provided, the first of those will be executed in place of the
interactive shell, and the rest of the arguments will be passed as
arguments to the executed command.
.Pp
The following modifiers are available:
.Bl -tag -width indent
.It Fl c
Create a new virtual image named
.Ar vname .
Additional arguments, if provided, may be used to specify operating
parameters different from defaults, in format
.Ar param=value .
See
.Xr jail 8
for an extensive list of available parameters.
.It Fl m
Modify the parameters of a virtual image named
.Ar vname ,
using the same syntax as with the -c form of the command.
.It Fl d
Delete the virtual image
.Ar vname .
No processes and/or sockets should exist in the target virtual image
in order for the delete request to succeed. Non-loopback interfaces
residing in the target virtual image will be reassigned to the virtual
image's parent.
.It Fl l
List the properties and statistics for virtual images one level
below the current one in the hierarchy. If an optional argument
.Ar vname
is provided, only the information regarding the target virtual image
.Ar vname
is displayed.
With the optional
.Op Ar -r
switch enabled the list will include all virtual images below the
current level in the vimage hierarchy.
Enabling the optional
.Op Ar -v
or
.Op Ar -j
switches results in a more detailed output.
.It Fl i
Move interface
.Ar ifname
to the target virtual image
.Ar vname .
Interfaces will be automatically renamed to
.So
ethXX
.Sc ,
unless an optional argument specifying the desired interface name
.Op Ar newifname
is provided.
.El
.Sh EXAMPLES
Create a new virtual image named
.So v1
.Sc ,
which is allowed to create and manage an own subhierarchy of vimages:
.Pp
.Dl vimage -c v1 children.max=100
.Pp
Execute the
.So ifconfig
.Sc command in the virtual image
.So v1
.Sc :
.Pp
.Dl vimage v1 ifconfig
.Pp
Move the interface
.So vlan0
.Sc to the virtual image
.So v1
.Sc while renaming the interface as
.So
ve0
.Sc :
.Pp
.Dl vimage -i v1 vlan0 ve0
.Pp
Show the status information for virtual image
.So v1
.Sc :
.Pp
.Dl vimage -lv v1
.Sh DIAGNOSTICS
The
.Nm
command exits 0 on success, and >0 if an error occurs.
.Sh SEE ALSO
.Xr jail 8
.Xr jexec 8
.Xr jls 8
.Sh HISTORY
Network stack virtualization framework first appeared as a patchset
against the FreeBSD 4.7 kernel in 2002, and was maintained outside
of the main FreeBSD tree.
As a result of a project sponsored by the FreeBSD Foundation and
Stiching NLNet, integrated virtualized network stack first appeared
in FreeBSD 8.0.
.Sh BUGS
Deletion of vimages / vnets is known to leak kernel memory and fail at
stopping various timers, hence may lead to system crashes.
.Sh AUTHOR
.An "Marko Zec" Aq zec@fer.hr

View file

@ -0,0 +1,390 @@
/*
* Copyright (c) 2002-2004 Marko Zec <zec@fer.hr>
* Copyright (c) 2009 University of Zagreb
* Copyright (c) 2009 FreeBSD Foundation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/jail.h>
#include <sys/socket.h>
#include <net/if.h>
#include <ctype.h>
#include <jail.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
typedef enum {
VI_SWITCHTO,
VI_CREATE,
VI_MODIFY,
VI_DESTROY,
VI_IFMOVE,
VI_GET
} vi_cmd_t;
typedef struct vimage_status {
char name[MAXPATHLEN]; /* Must be first field for strcmp(). */
char path[MAXPATHLEN];
char hostname[MAXPATHLEN];
char domainname[MAXPATHLEN];
int jid;
int parentjid;
int vnet;
int childcnt;
int childmax;
int cpuset;
int rawsock;
int socket_af;
int mount;
} vstat_t;
#define VST_SIZE_STEP 1024
#define MAXPARAMS 32
static int getjail(vstat_t *, int, int);
static char *invocname;
static void
usage(void)
{
fprintf(stderr,
"usage: %s [-c | -m] vname [param=value ...]\n"
" %s -d vname\n"
" %s -l[rvj] [vname]\n"
" %s -i vname ifname [newifname]\n"
" %s vname [command ...]\n",
invocname, invocname, invocname, invocname, invocname);
exit(1);
}
int
main(int argc, char **argv)
{
struct jailparam params[MAXPARAMS];
char ifname[IFNAMSIZ];
struct ifreq ifreq;
vi_cmd_t newcmd, cmd;
int recurse = 0;
int verbose = 0;
int jid, i, s, namelen;
int vst_size, vst_last;
vstat_t *vst;
char *str;
char ch;
invocname = argv[0];
newcmd = cmd = VI_SWITCHTO; /* Default if no modifiers specified. */
while ((ch = getopt(argc, argv, "cdijlmrv")) != -1) {
switch (ch) {
case 'c':
newcmd = VI_CREATE;
break;
case 'm':
newcmd = VI_MODIFY;
break;
case 'd':
newcmd = VI_DESTROY;
break;
case 'l':
newcmd = VI_GET;
break;
case 'i':
newcmd = VI_IFMOVE;
break;
case 'r':
recurse = 1;
break;
case 'v':
verbose++;
break;
case 'j':
verbose = 2;
break;
default:
usage();
}
if (cmd == VI_SWITCHTO || cmd == newcmd)
cmd = newcmd;
else
usage();
}
argc -= optind;
argv += optind;
if ((cmd != VI_GET && (argc == 0 || recurse != 0 || verbose != 0)) ||
(cmd == VI_IFMOVE && (argc < 2 || argc > 3)) ||
(cmd == VI_MODIFY && argc < 2) || argc >= MAXPARAMS)
usage();
switch (cmd) {
case VI_GET:
vst_last = 0;
vst_size = VST_SIZE_STEP;
if ((vst = malloc(vst_size * sizeof(*vst))) == NULL)
break;
if (argc == 1)
namelen = strlen(argv[0]);
else
namelen = 0;
jid = 0;
while ((jid = getjail(&vst[vst_last], jid, verbose)) > 0) {
/* Skip jails which do not own vnets. */
if (vst[vst_last].vnet != 1)
continue;
/* Skip non-matching vnames / hierarchies. */
if (namelen &&
((strlen(vst[vst_last].name) < namelen ||
strncmp(vst[vst_last].name, argv[0], namelen) != 0)
|| (strlen(vst[vst_last].name) > namelen &&
vst[vst_last].name[namelen] != '.')))
continue;
/* Skip any sub-trees if -r not requested. */
if (!recurse &&
(strlen(vst[vst_last].name) < namelen ||
strchr(&vst[vst_last].name[namelen], '.') != NULL))
continue;
/* Grow vst table if necessary. */
if (++vst_last == vst_size) {
vst_size += VST_SIZE_STEP;
vst = realloc(vst, vst_size * sizeof(*vst));
if (vst == NULL)
break;
}
}
if (vst == NULL)
break;
/* Sort: the key is the 1st field in *vst, i.e. vimage name. */
qsort(vst, vst_last, sizeof(*vst), (void *) strcmp);
for (i = 0; i < vst_last; i++) {
if (!verbose) {
printf("%s\n", vst[i].name);
continue;
}
printf("%s:\n", vst[i].name);
printf(" Path: %s\n", vst[i].path);
printf(" Hostname: %s\n", vst[i].hostname);
printf(" Domainname: %s\n", vst[i].domainname);
printf(" Children: %d\n", vst[i].childcnt);
if (verbose < 2)
continue;
printf(" Children limit: %d\n", vst[i].childmax);
printf(" CPUsetID: %d\n", vst[i].cpuset);
printf(" JID: %d\n", vst[i].jid);
printf(" PJID: %d\n", vst[i].parentjid);
printf(" Raw sockets allowed: %d\n", vst[i].rawsock);
printf(" All AF allowed: %d\n", vst[i].socket_af);
printf(" Mount allowed: %d\n", vst[i].mount);
}
free(vst);
exit(0);
case VI_IFMOVE:
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
break;
if ((jid = jail_getid(argv[0])) < 0)
break;
ifreq.ifr_jid = jid;
strncpy(ifreq.ifr_name, argv[1], sizeof(ifreq.ifr_name));
if (ioctl(s, SIOCSIFVNET, (caddr_t)&ifreq) < 0)
break;
close(s);
if (argc == 3)
snprintf(ifname, sizeof(ifname), "%s", argv[2]);
else
snprintf(ifname, sizeof(ifname), "eth0");
ifreq.ifr_data = ifname;
/* Do we need to rename the ifnet? */
if (strcmp(ifreq.ifr_name, ifname) != 0) {
/* Switch to the context of the target vimage. */
if (jail_attach(jid) < 0)
break;
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
break;
for (namelen = 0; isalpha(ifname[namelen]); namelen++);
i = 0;
/* Search for a free ifunit in target vnet. Unsafe. */
while (ioctl(s, SIOCSIFNAME, (caddr_t)&ifreq) < 0) {
snprintf(&ifname[namelen],
sizeof(ifname) - namelen, "%d", i);
/* Emergency brake. */
if (i++ == IF_MAXUNIT)
break;
}
}
if (i < IF_MAXUNIT)
printf("%s@%s\n", ifname, argv[0]);
else
printf("%s@%s\n", ifreq.ifr_name, argv[0]);
exit(0);
case VI_CREATE:
if (jail_setv(JAIL_CREATE,
"name", argv[0],
"vnet", NULL,
"host", NULL,
"persist", NULL,
"allow.raw_sockets", "true",
"allow.socket_af", "true",
"allow.mount", "true",
NULL) < 0)
break;
if (argc == 1)
exit(0);
/* Not done yet, proceed to apply non-default parameters. */
case VI_MODIFY:
jailparam_init(&params[0], "name");
jailparam_import(&params[0], argv[0]);
for (i = 1; i < argc; i++) {
for (str = argv[i]; *str != '=' && *str != 0; str++) {
/* Do nothing - search for '=' delimeter. */
}
if (*str == 0)
break;
*str++ = 0;
if (*str == 0)
break;
jailparam_init(&params[i], argv[i]);
jailparam_import(&params[i], str);
}
if (i != argc)
break;
if (jailparam_set(params, i, JAIL_UPDATE) < 0)
break;
exit(0);
case VI_DESTROY:
if ((jid = jail_getid(argv[0])) < 0)
break;
if (jail_remove(jid) < 0)
break;
exit(0);
case VI_SWITCHTO:
if ((jid = jail_getid(argv[0])) < 0)
break;
if (jail_attach(jid) < 0)
break;
if (argc == 1) {
printf("Switched to vimage %s\n", argv[0]);
if ((str = getenv("SHELL")) == NULL)
execlp("/bin/sh", invocname, NULL);
else
execlp(str, invocname, NULL);
} else
execvp(argv[1], &argv[1]);
break;
default:
/* Should be unreachable. */
break;
}
if (jail_errmsg[0])
fprintf(stderr, "Error: %s\n", jail_errmsg);
else
perror("Error");
exit(1);
}
static int
getjail(vstat_t *vs, int lastjid, int verbose)
{
struct jailparam params[32]; /* Must be > max(psize). */
int psize = 0;
bzero(params, sizeof(params));
bzero(vs, sizeof(*vs));
jailparam_init(&params[psize], "lastjid");
jailparam_import_raw(&params[psize++], &lastjid, sizeof lastjid);
jailparam_init(&params[psize], "vnet");
jailparam_import_raw(&params[psize++], &vs->vnet, sizeof(vs->vnet));
jailparam_init(&params[psize], "name");
jailparam_import_raw(&params[psize++], &vs->name, sizeof(vs->name));
if (verbose == 0)
goto done;
jailparam_init(&params[psize], "path");
jailparam_import_raw(&params[psize++], &vs->path, sizeof(vs->path));
jailparam_init(&params[psize], "host.hostname");
jailparam_import_raw(&params[psize++], &vs->hostname,
sizeof(vs->hostname));
jailparam_init(&params[psize], "host.domainname");
jailparam_import_raw(&params[psize++], &vs->domainname,
sizeof(vs->domainname));
jailparam_init(&params[psize], "children.cur");
jailparam_import_raw(&params[psize++], &vs->childcnt,
sizeof(vs->childcnt));
if (verbose == 1)
goto done;
jailparam_init(&params[psize], "children.max");
jailparam_import_raw(&params[psize++], &vs->childmax,
sizeof(vs->childmax));
jailparam_init(&params[psize], "cpuset.id");
jailparam_import_raw(&params[psize++], &vs->cpuset,
sizeof(vs->cpuset));
jailparam_init(&params[psize], "parent");
jailparam_import_raw(&params[psize++], &vs->parentjid,
sizeof(vs->parentjid));
jailparam_init(&params[psize], "allow.raw_sockets");
jailparam_import_raw(&params[psize++], &vs->rawsock,
sizeof(vs->rawsock));
jailparam_init(&params[psize], "allow.socket_af");
jailparam_import_raw(&params[psize++], &vs->socket_af,
sizeof(vs->socket_af));
jailparam_init(&params[psize], "allow.mount");
jailparam_import_raw(&params[psize++], &vs->mount, sizeof(vs->mount));
done:
vs->jid = jailparam_get(params, psize, 0);
jailparam_free(params, psize);
return (vs->jid);
}

File diff suppressed because it is too large Load diff