Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changes between Initial Version and Version 1 of NetworkBridging


Ignore:
Timestamp:
2011-01-10T00:40:19Z (9 years ago)
Author:
Martin Decky
Comment:

Legend:

Unmodified
Added
Removed
Modified
  • NetworkBridging

    v1 v1  
     1== HelenOS on a physical LAN/Internet from QEMU/KVM ==
     2
     3This 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. Please note that the functionality of the HelenOS TCP/IP stack is still severely limited (especially concerning the actual usability of the UDP and TCP protocols), but the situation should improve soon.
     4
     5This 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 expected, your mileage may vary.
     6
     7== Prerequisites ==
     8
     9This checklist assumes that you have an ethernet device called ''eth0'' up and configured with an IP address (the IP address can be static 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'' and friends). The bridges are software-defined ethernet network interface layer interconnections implemented in the Linux kernel, but for any practical purposes you can think about them as the usual ethernet switches or hubs.
     10
     11== Creating a bridge ==
     12
     13Store the following shell script in a convenient location (e.g. ''/etc/kvm/scripts/bridge''):
     14
     15{{{
     16#! /bin/bash
     17
     18function create_bridge() {
     19        local bridge="$1"
     20       
     21        echo -n "$bridge: creating bridge ... "
     22        brctl addbr "$bridge"
     23        echo "OK"
     24       
     25        echo -n "$bridge: setting bridge options ... "
     26        brctl stp "$bridge" off
     27        brctl setfd "$bridge" 0
     28        sysctl -q -w "net.bridge.bridge-nf-call-arptables=0"
     29        sysctl -q -w "net.bridge.bridge-nf-call-ip6tables=0"
     30        sysctl -q -w "net.bridge.bridge-nf-call-iptables=0"
     31        echo "OK"
     32}
     33
     34function transfer_addrs() {
     35        local src="$1"
     36        local dst="$2"
     37       
     38        echo -n "$src: transfering addresses to $dst ... "
     39        local addrs="`ip addr show "$src" | egrep '^ *inet ' | sed -e "s/^ *inet/ip addr add/g;s/$src/dev $dst/g"`"
     40        $addrs
     41        echo "OK"
     42       
     43        echo -n "$dst: removing automatic routes ... "
     44        local routes="`ip route list | sed -ne "/dev $dst\( \|$\)/s/^/ip route del /gp"`"
     45        $routes
     46        echo "OK"
     47}
     48
     49function get_gateway() {
     50        local netdev="$1"
     51       
     52        echo -n "$netdev: storing gateway ... "
     53        gateway="`ip route show dev "$netdev" | fgrep default | sed "s/default via //"`"
     54        echo "OK"
     55}
     56
     57function if_down() {
     58        local netdev="$1"
     59       
     60        echo -n "$netdev: link down ... "
     61        ip link set "$netdev" down
     62        echo "OK"
     63       
     64        echo -n "$netdev: address flush ... "
     65        ip addr flush "$netdev"
     66        echo "OK"
     67}
     68
     69function transfer_name() {
     70        local netdev="$1"
     71        local tmpdev="$2"
     72        local phydev="$3"
     73        local bridge="$4"
     74       
     75        echo -n "$netdev: renaming to $phydev ... "
     76        ip link set "$netdev" name "$phydev"
     77        echo "OK"
     78       
     79        echo -n "$tmpdev: renaming to $bridge ... "
     80        ip link set "$tmpdev" name "$bridge"
     81        echo "OK"
     82}
     83
     84function add_to_bridge() {
     85        local bridge="$1"
     86        local dev="$2"
     87       
     88        echo -n "$bridge: adding $dev ... "
     89        brctl addif "$bridge" "$dev"
     90        echo "OK"
     91}
     92
     93function if_up() {
     94        local netdev="$1"
     95       
     96        echo -n "$netdev: bringing up ... "
     97        ip link set dev "$netdev" up
     98        echo "OK"
     99}
     100
     101function set_gateway() {
     102        local netdev="$1"
     103       
     104        if [ -n "$gateway" ] ; then
     105                echo -n "$netdev: setting default gateway ... "
     106                ip route add default via $gateway
     107                echo "OK"
     108        fi
     109}
     110
     111if [ "$#" -lt "1" ]; then
     112        echo "Syntax: $0 <netdev>"
     113        exit 1
     114fi
     115
     116tmpdev="tmpbr"
     117netdev="$1"
     118phydev="p$netdev"
     119bridge="$netdev"
     120
     121create_bridge "$tmpdev"
     122get_gateway "$netdev"
     123transfer_addrs "$netdev" "$tmpdev"
     124if_down "$netdev"
     125transfer_name "$netdev" "$tmpdev" "$phydev" "$bridge"
     126add_to_bridge "$bridge" "$phydev"
     127if_up "$bridge"
     128set_gateway "$bridge"
     129if_up "$phydev"
     130}}}
     131
     132To 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.
     133
     134{{{
     135/etc/kvm/scripts/bridge eth0
     136}}}
     137
     138The script basically 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 work just as one (network interface layer) port of the bridge.
     139
     140'''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.
     141
     142'''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.
     143
     144== Connecting QEMU/KVM networking to the bridge ==
     145
     146In order for QEMU/KVM to be able to connect network interface of the virtual machine to the virtual bridge, you again need some scripts, but this time the script will be executed by QEMU/KVM itself. First, store the main script into a convenient path (e.g. ''/etc/kvm/scripts/ifup''):
     147
     148{{{
     149#!/bin/sh
     150
     151if [ "$#" -lt "2" ]; then
     152        echo "Syntax: $0 <iface> <bridge>"
     153        exit 1
     154fi
     155
     156iface="$1"
     157bridge="$2"
     158
     159ip link set "$iface" down
     160ip link set "$iface" arp off
     161ip link set "$iface" multicast off
     162ip link set "$iface" addr fe:ff:ff:ff:ff:ff
     163ip addr flush "$iface"
     164
     165brctl addif "$bridge" "$iface"
     166
     167ip link set "$iface" up
     168}}}
     169
     170This script connects the TAP device created by QEMU/KVM when initializing the virtual machine into the bridge.
     171
     172Since 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'':
     173
     174{{{
     175#!/bin/sh
     176
     177/etc/kvm/scripts/ifup "$1" eth0
     178}}}
     179
     180== Configuring HelenOS networking ==
     181
     182HelenOS does not support any dynamic network configuration (e.g. via DHCP) so far. Thus, you need to configure the IP parameters for HelenOS manually prior to running it in QEMU/KVM. Just go to the ''uspace/srv/net/cfg'' directory in the HelenOS source tree and edit the ''ne2k'' configuration file according to your network parameters (you need to reserve an IP address statically for your HelenOS virtual machine). For example in my case I have to change the following values:
     183
     184{{{
     185IP_ADDR=192.168.254.254
     186IP_NETMASK=255.255.255.0
     187IP_BROADCAST=192.168.254.255
     188IP_GATEWAY=192.168.254.1
     189}}}
     190
     191Compile HelenOS for IA-32 in a usual way.
     192
     193== Running HelenOS in QEMU/KVM ==
     194
     195Finally, after all has been successfully configured and HelenOS compiled, you can run it with a command line similar to this one:
     196
     197{{{
     198qemu-kvm \
     199    -name helenos \
     200    -drive index=0,file=/home/user/HelenOS/image.iso,if=ide,media=cdrom,boot=on \
     201    -m 512 \
     202    -device ne2k_isa,irq=5,vlan=0,mac=aa:de:ad:be:ef:fe \
     203    -net tap,script=/etc/kvm/scripts/ifup-eth0 \
     204    -vga std
     205}}}
     206
     207'''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 accidentally more people start playing with this on the same LAN).
     208
     209'''Note 2:''' The ''-device ne2k_isa,irq=5,vlan=0'' and ''-net tap'' options are naturally essential for the correct functionality of the networking, you probably should not mess with them. Also please take note that currently in SMP virtual machines (with more than one CPU) the networking won't work.
     210
     211== Starting up networking in HelenOS ==
     212
     213After HelenOS boots up, just run the following command from ''bdsh'':
     214
     215{{{
     216net
     217}}}
     218
     219You should see some output indicating whether the initialization of the whole networking stack went OK and if it is the case then HelenOS should be ''visible'' on the network.