vimage rc.d script released.

FreeBSD-8.x/9.x rc.d script for managing vimages (jails with their own network stack). Distributed as an easy-to-install (and uninstall) FreeBSD package (*.tbz file).

The rc.d script installed by this package allows you to easily setup and use vimages in production on FreeBSD-8.1 or higher (tested). Note, however, that this requires the VIMAGE option enabled in a custom kernel built for your platform (a topic that is beyond the scope of this package introduction).

In configuring each vimage, there are 2 ways to provide multiple network interfaces to a single vimage. Under-the-hood, both are accomplished via the new vnet and -vnet options added to ifconfig(8). The first method simply allows you to move network interfaces out of the host machine's view and into the vimage's view (the host machine will no longer have access to network interfaces configured in the below manner):

vimage_NAME_vnets="em0 em1 fxp0"

The above example moves three network interfaces into the vimage during startup (and correspondingly moves the interfaces back upon stopping of the vimage; usually done automatically, but on rare occasions the kernel doesn't properly return the interface, so this rc.d script relies on ifconfig(8)'s -vnet option to ensure the safe-return of all interfaces).

The second method for configuring multiple network interfaces to a single vimage is shown below (explanation follows):

vimage_NAME_bridges="em0 em1 fxp0"

The above bridges setting does something very different than the vnet setting.

So in the above bridges example, the following network interfaces will be created inside the NAME vimage:

ng0_NAME
ng1_NAME
ng2_NAME

But, unlike vnets, you can specify the same network interface multiple times, creating multiple network interfaces bridged to the same underlying interface:

vimage_NAME_bridges="em0 em0"

Which, after starting the vimage and executing ifconfig(8) within the running vimage, you get the following results:

lo0: flags=8049 metric 0 mtu 16384
        options=3<RXCSUM,TXCSUM>
        inet 127.0.0.1 netmask 0xff000000
ng0_NAME: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        ether 02:00:27:e7:1b:18
ng1_NAME: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        ether 02:00:37:e7:1b:18

To which the final stage of setup would be to add the following lines to rc.conf(5) within the vimage (or /etc/rc.conf if the vimage's rootdir is "/"):

ifconfig_ng0_NAME="inet 192.168.1.1/24"
ifconfig_ng1_NAME="inet 192.168.1.2/24"

NOTE: This allows multiple vimages to use the same rootdir, yet maintain separate configurations for each of their own distinct network interfaces, bridged to whatever.

ASIDE: Unlike if_bridge(4), ng_bridge(4) allows up to 65 530 interfaces to be bridged (actually tested), while if_bridge(4) was not up for the task (note: if you can rely on 802.1Q Hardware VLAN Tagging and have the infrastructure, if_bridge(4) can be made to work well with epair(4) and others, but netgraph(4) provides a superior solution when STP/RSTP and other protocols are not available).

To use these built-in bridging features of the rc.d script you'll need to either recompile your kernel with the NETGRAPH, NETGRAH_ETHER, NETGRAPH_BRIDGE, NETGRAPH_EIFACE, and [suggested] NETGRAPH_SOCKET options OR add the following lines to /boot/loader.conf:

ng_bridge_load="YES"
ng_eiface_load="YES"
ng_ether_load="YES"
ng_socket_load="YES"

ASIDE: routing packets through a vimage requires gateway_enable="YES" on the host machine (or net.inet.ip.forwarding=1 set in sysctl.conf(5)).