wiki:NetworkBridging

HelenOS on a physical LAN/Internet from QEMU/KVM

This is a simple DIY checklist for running HelenOS in QEMU/KVM and connecting its TCP/IP networking stack to a real physical ethernet LAN and possibly to the public Internet via this LAN.

This checklist should work reasonably well with any recent GNU/Linux (2.6) distribution and QEMU/KVM 0.13.x on a IA-32 or AMD64 host system with a physical ethernet network card. Without any special arrangements you also need to have a root access on the host machine. If you have a substantially different software or hardware configuration than assumed by this checklist, you have to do the proper adjustments to the checklist.

Warning: Your mileage may vary! This checklist should not be just followed blindly. If you don't have a reasonable knowledge of your system and networking configuration, if you lack the basic understanding of the essential network technologies (i.e. terms such as MAC, IP, ethernet, bridge, etc.), if you are unfamiliar with the command line or if you are unable to understand shell scripts, then you can easily render your machine or (in the worst case) even your entire local network non-functional. The script examples presented here are in no way fail-safe and won't adapt on your environment if it substantially different than expected.

Just try not to be ignorant. If you end up stuck in a dead end, ask somebody who knows your local network environment (perhaps your network or systems administrator) for assistance.

Prerequisites

This checklist assumes that you have an ethernet device called eth0 up and configured with an IP address (the IP address can be statically assigned or configured by a DHCP). You also need the brctl tool for creating and configuring virtual ethernet bridges (it usually comes in a package called bridge-utils or similar) as well as the usual Linux network management utilities (e.g. ip, route and friends). The bridges are software-defined ethernet network interface layer interconnections implemented in the Linux kernel, for most practical purposes you can think about them as usual ethernet switches or hubs.

Creating a bridge

Store the following shell script in a convenient location (e.g. /etc/kvm/scripts/bridge):

#! /bin/bash

function create_bridge() {
	local bridge="$1"
	
	echo -n "$bridge: creating bridge ... "
	brctl addbr "$bridge"
	echo "OK"
	
	echo -n "$bridge: setting bridge options ... "
	brctl stp "$bridge" off
	brctl setfd "$bridge" 0
	sysctl -q -w "net.bridge.bridge-nf-call-arptables=0"
	sysctl -q -w "net.bridge.bridge-nf-call-ip6tables=0"
	sysctl -q -w "net.bridge.bridge-nf-call-iptables=0"
	echo "OK"
}

function transfer_addrs() {
	local src="$1"
	local dst="$2"
	
	echo -n "$src: transfering addresses to $dst ... "
	local addrs="`ip addr show "$src" | egrep '^ *inet ' | sed -e "s/^ *inet/ip addr add/g;s/$src/dev $dst/g"`"
	$addrs
	echo "OK"
	
	echo -n "$dst: removing automatic routes ... "
	local routes="`ip route list | sed -ne "/dev $dst\( \|$\)/s/^/ip route del /gp"`"
	$routes
	echo "OK"
}

function get_gateway() {
	local netdev="$1"
	
	echo -n "$netdev: storing gateway ... "
	gateway="`ip route show dev "$netdev" | fgrep default | sed "s/default via //"`"
	echo "OK"
}

function if_down() {
	local netdev="$1"
	
	echo -n "$netdev: link down ... "
	ip link set "$netdev" down
	echo "OK"
	
	echo -n "$netdev: address flush ... "
	ip addr flush "$netdev"
	echo "OK"
}

function transfer_name() {
	local netdev="$1"
	local tmpdev="$2"
	local phydev="$3"
	local bridge="$4"
	
	echo -n "$netdev: renaming to $phydev ... "
	ip link set "$netdev" name "$phydev"
	echo "OK"
	
	echo -n "$tmpdev: renaming to $bridge ... "
	ip link set "$tmpdev" name "$bridge"
	echo "OK"
}

function add_to_bridge() {
	local bridge="$1"
	local dev="$2"
	
	echo -n "$bridge: adding $dev ... "
	brctl addif "$bridge" "$dev"
	echo "OK"
}

function if_up() {
	local netdev="$1"
	
	echo -n "$netdev: bringing up ... "
	ip link set dev "$netdev" up
	echo "OK"
}

function set_gateway() {
	local netdev="$1"
	
	if [ -n "$gateway" ] ; then
		echo -n "$netdev: setting default gateway ... "
		ip route add default via $gateway
		echo "OK"
	fi
}

if [ "$#" -lt "1" ]; then
	echo "Syntax: $0 <netdev>"
	exit 1
fi

tmpdev="tmpbr"
netdev="$1"
phydev="p$netdev"
bridge="$netdev"

create_bridge "$tmpdev"
get_gateway "$netdev"
transfer_addrs "$netdev" "$tmpdev"
if_down "$netdev"
transfer_name "$netdev" "$tmpdev" "$phydev" "$bridge"
add_to_bridge "$bridge" "$phydev"
if_up "$bridge"
set_gateway "$bridge"
if_up "$phydev"

To create a bridge, just run manually this script and use the name of your physical ethernet device (which you want to be connected initially to the bridge) as the argument, e.g.:

/etc/kvm/scripts/bridge eth0

The script renames your physical ethernet device eth0 to peth0, creates a bridge device called eth0 and moves all the usual IP configuration from peth0 to eth0. By doing this your host system is still going to have IP connectivity via a network device with the original name, but the physical ethernet device is going to behave like one port of the bridge (on the network interface layer).

Note 1: The creation of the bridge is a manual process (since you probably don't want to have this around all the time) and its configuration won't be stored persistently during reboots (unless you have some crazy AI-driven Linux distribution). But typically the existence of the bridge should be transparent to any networking applications you run on your host. If your Linux distribution has a good support for configuring the bridges persistently, you can certainly use your distribution's means and avoid this one-time script.

Note 2: The script has been tested only on IPv4 networks. It should work similarly with IPv6 or any other network protocol, but the script might require some tweaking.

Connecting QEMU/KVM networking to the bridge

In order for QEMU/KVM to be able to connect the network interface of the virtual machine to the virtual bridge, you again need some shell scripts. But this time the scripts will be executed by QEMU/KVM itself. First, store the main script into a convenient path (e.g. /etc/kvm/scripts/ifup):

#!/bin/sh

if [ "$#" -lt "2" ]; then
	echo "Syntax: $0 <iface> <bridge>"
	exit 1
fi

iface="$1"
bridge="$2"

ip link set "$iface" down
ip link set "$iface" arp off
ip link set "$iface" multicast off
ip link set "$iface" addr fe:ff:ff:ff:ff:ff
ip addr flush "$iface"

brctl addif "$bridge" "$iface"

ip link set "$iface" up

This script connects the TAP device created by QEMU/KVM when initializing the virtual machine into the bridge.

Since the scripting interface of QEMU/KVM only provides means for a single script argument (merely the TAP device name), you also need a small wrapper script, again stored say in /etc/kvm/scripts/ifup-eth0:

#!/bin/sh

/etc/kvm/scripts/ifup "$1" eth0

Configuring HelenOS networking

HelenOS does not support dynamic network configuration (e.g. via DHCP) so far. Thus, you need to configure the IP parameters for HelenOS manually. After HelenOS boots up, use the inetcfg to configure the networking stack. For example:

/ # inetcfg create 192.168.254.254/24 net/eth1 myaddr
/ # inetcfg add-sr 0.0.0.0/0 192.168.254.1 default

See the User's Guide for more information on how to use networking in HelenOS.

Running HelenOS in QEMU/KVM

Start HelenOS with a command line similar to this one:

qemu-kvm \
    -name helenos \
    -drive index=0,file=/home/user/HelenOS/image.iso,if=ide,media=cdrom,boot=on \
    -m 512 \
    -device ne2k_isa,irq=5,vlan=0,mac=aa:de:ad:be:ef:fe \
    -net tap,script=/etc/kvm/scripts/ifup-eth0 \
    -vga std

Note 1: Please modify any of the QEMU/KVM options for your specific configuration (paths, etc.). It is probably also a good idea to change the MAC address of the virtual NE2000 card to a different value (just for the case that more people accidentally start playing with this on the same LAN).

Note 2: The -device ne2k_isa,irq=5,vlan=0 and -net tap options are essential for the correct functionality of the networking, you probably should not mess with them. Also please take note that the networking won't currently work in SMP virtual machines (with more than one CPU).

More Info

Last modified 13 years ago Last modified on 2012-04-20T14:48:50Z
Note: See TracWiki for help on using the wiki.