Last Update: 2022-05-03

VMM with bridged network

A little example for OpenBSD's virtualization platform, using a private net and NAT for access to the internet.

1  Preconditions

You'll need a computer with amd64 architecture and (activated) hardware virtualization support:
$ uname -m
amd64

$ dmesg | egrep '(VMX/EPT|SVM/RVI)'
vmm0 at mainbus0: VMX/EPT

2  Network

2.1  Topology

The following network topology is used in this tutorial:


        iwm0
          |
       NAT (pf)
          |
       vether0
          |
     +----+----+
     | bridge0 |
     +----+----+
    /     |     \
  tap0   tap1   tap2 ...

The vms are connected via their tapX interfaces to the virtual switch bridge0. The connection to the host system is done via the vether0 interface. Network address translation is done using OpenBSD's packet filter pf. The setup is connected to the internet via the iwm0 interface on the host system, e.g. through your wifi access router. See for more information. The internal layer 3 network will be 172.16.0.0/24.

2.2  Configuration files

First we'll need two configuration files for the vether0 and bridge0 devices:

Start the devices:
# sh /etc/netstart vether0
# sh /etc/netstart bridge0

3  pf

The packet filter is controlled by /etc/pf.conf. Here we implement the network address translation:

ext_if="iwm0"
vmm_if="vether0"

match out on $ext_if from $vmm_if:network to any nat-to ($ext_if)
Activate the configuration:
# pfctl -f /etc/pf.conf

4  dhcpd

We'll need a dhcp daemon for automatic address assignment, which runs on the host system. Configuration file /etc/dhcpd.conf:

option domain-name "vmm.local";
option domain-name-servers 8.8.8.8, 8.8.4.4;

subnet 172.16.0.0 netmask 255.255.255.0 {
  option routers 172.16.0.1;
  range 172.16.0.10 172.16.0.100;

  host openbsd {
    hardware ethernet 00:50:56:00:00:01;
    fixed-address 172.16.0.2;
  }
}
In this example we have one fixed address: the host with the mac address 005056-000001 will always get the ip address 172.16.0.2. Activate and start the DHCP daemon, listening only on interface vether0:
# rcctl enable dhcpd
# rcctl set dhcpd flags vether0
# rcctl start dhcpd

5  vmd

The virtual machine daemon is responsible to start and stop vms on a host system, the configuration is done via the /etc/vm.conf file:

vm "openbsd" {
  disable
  boot device disk
  cdrom /home/vm/isos/install71.iso
  memory 2048M
  disk /home/vm/openbsd.qcow2 format qcow2
  interface tap { 
    switch "uplink" 
    lladdr 00:50:56:00:00:01
  }
}

switch "uplink" {
        interface bridge0
}
Here we configure a vm called openbsd and a switch called uplink. For installation purposes you'll need to change boot device to cdrom. The virtual machine has a fixed mac address, reusing VMware's range: 00:50:56:00:00:00 - 00:50:56:3F:FF:FF. If you prefer using an other range, here is a complete list of assigned MAC prefixes, where some parts are marked as private. Now enable and start vmd:
# rcctl enable vmd
# rcctl start vmd

NOTE: if you change the configuration, you'll need to restart vmd:

# rcctl restart vmd

6  virtual machines

Use vmctl to create an image for a virtual machine:

# vmctl create -s 10G /home/vm/openbsd.qcow2
Once a machine is configured via /etc/vm.conf, you may start and connect to it via serial console:
# vmctl start openbsd
# vmctl console openbsd
To exit the serial console press <ENTER> for a new line and then: ~.

Now you may install the virtual machine and the network configuration should work automaticly via dhcp.

7  Linux

VMM is kind of hard to use at the moment. While OpenBSD works fine as a guest operation system, other OS will most likely not work. Keep in mind that there is no graphical output but a serial console. If you want to install Linux in vmm, I strongly recommend Alpine in the flavor "virtual", which is optimized for virtual systems.

7.1  Alpine Linux

Add the following lines to the /etc/vm.conf file:

vm "alpine" {
        disable
        boot device cdrom
        cdrom /home/vm/isos/alpine.iso
        memory 512M
        disk /home/vm/alpine.qcow2 format qcow2
        interface { switch "uplink" }
}
Restart vmd:
# rcctl restart vmd
Use the Alpine Virtual Image (x86_64):
# ftp -o alpine.iso https://dl-cdn.alpinelinux.org/alpine/v3.15/releases/x86_64/alpine-virt-3.15.4-x86_64.iso
# mv alpine.iso /home/vm/isos
Now start the vm and connect the console:
# vmctl start alpine
# vmctl console alpine
After the installation change boot device to disk, restart vmd and your Linux vm is ready.

7.2  General tips

Just some basic hints if you want to install other Linux distributions:

8  Problems

You'll often see errors like this:

vmx_fault_page: uvm_fault returns 14, GPA=0xfe001818, rip=0xffffffffc0754b96
vmx_fault_page: uvm_fault returns 14, GPA=0xffffca58, rip=0xfbcc3
vmx_fault_page: uvm_fault returns 14, GPA=0xfe001818, rip=0xffffffffb765fb2c
vmx_fault_page: uvm_fault returns 14, GPA=0xfe001818, rip=0xffffffffa465fb2c
vmx_fault_page: uvm_fault returns 14, GPA=0xfe001818, rip=0xffffffffaa65fb2c
vmx_fault_page: uvm_fault returns 14, GPA=0xfe001818, rip=0xffffffff9965fb2c
vmx_fault_page: uvm_fault returns 14, GPA=0xfe001818, rip=0xffffffffac65fb2c
vmx_fault_page: uvm_fault returns 14, GPA=0xfe001818, rip=0xffffffffba65fb2c
vmx_fault_page: uvm_fault returns 14, GPA=0xfe001818, rip=0xffffffffa065fb2c
vmx_fault_page: uvm_fault returns 14, GPA=0xfe001818, rip=0xffffffff9d65fb2c
Most times this is due to stuff that is simply not implemented, often graphical stuff.