FirstServed Homepage FirstServed Web Hosting | Housing | Domain Names Order Hosting and Domain names FirstServed Help | Support FirstServed Company Information
FirstServed Technical Blog
  • Bridging VLAN interfaces in Xen

    The init scripts bundled with Xen offer little or no support for VLANs.  One way to configure VLANs is to do it at the DomU level, but that’s a trick that’s only feasible on Linux guests, since on Windows VLAN support for ethernet cards is implemented by proprietary software of the NIC vendor, and there’s certainly no such thing as Windows software for the Xen Virtual NIC.

    In case the Dom0 doesn’t need active interfaces on the VLAN bridges, you can follow the solution outlined on this page: Bridging domains to tagged VLANs in Xen.

    I found a much simpler solution.  The reason Xen’s network-bridge doesn’t play ball with VLAN interfaces is that at a certain point, /sbin/ifdown is called to bring down the net device - a prerequisite to rename it and reassign it to the bridge.  Ifdown however has the undesirable side effect of removing any configured VLAN’s on the device it’s bringing down, effectively deleting the interface entirely.  So when running the network-bridge script, you’ll get error messages saying the device was not found:

    SIOCSIFNAME: No such device

    I modified xen-network-common.sh so ifdown is no longer called directly.  Instead of it, the ip address of the interface is flushed manually, then the device’s link is brought down, leaving the vlan configured on the interface intact.  The following script is based on Xen 3.0.3’s xen-network-common.sh script.

    if [ -e /etc/SuSE-release ]
    then
      preiftransfer()
      {
        eval `/sbin/getcfg -d /etc/sysconfig/network/ -f ifcfg- — $1`
      }
      ifup()
      {
        /sbin/ifup ${HWD_CONFIG_0} $1
      }
    elif ! which ifup >/dev/null 2>/dev/null
    then
      preiftransfer()
      {
        true
      }
      ifup()
      {
        false
      }
      ifdown()
      {
        false
      }
    else
      preiftransfer()
      {
        true
      }
      # do not call ifdown directly
      ifdown()  {
        ip addr flush $1
        ip link set $1 down
        true
      }

    fi

    first_file()
    {
      t="$1"
      shift
      for file in $@
      do
        if [ "$t" "$file" ]
        then
          echo "$file"
          return
        fi
      done
    }

    find_dhcpd_conf_file()
    {
      first_file -f /etc/dhcp3/dhcpd.conf /etc/dhcpd.conf
    }

    find_dhcpd_init_file()
    {
      first_file -x /etc/init.d/{dhcp3-server,dhcp,dhcpd}
    }

    # configure interfaces which act as pure bridge ports:
    #  - make quiet: no arp, no multicast (ipv6 autoconf)
    #  - set mac address to fe:ff:ff:ff:ff:ff
    setup_bridge_port() {
        local dev="$1"

        # take interface down …
        ip link set ${dev} down

        # … and configure it
        ip link set ${dev} arp off
        ip link set ${dev} multicast off
        ip link set ${dev} addr fe:ff:ff:ff:ff:ff
        ip addr flush ${dev}
    }

    # Usage: create_bridge bridge
    create_bridge () {
        local bridge=$1

        # Don’t create the bridge if it already exists.
        if [ ! -e "/sys/class/net/${bridge}/bridge" ]; then
            brctl addbr ${bridge}
            brctl stp ${bridge} off
            brctl setfd ${bridge} 0
            sysctl -w "net.bridge.bridge-nf-call-arptables=0"
            sysctl -w "net.bridge.bridge-nf-call-ip6tables=0"
            sysctl -w "net.bridge.bridge-nf-call-iptables=0"
            ip link set ${bridge} arp off
            ip link set ${bridge} multicast off
        fi
        # A small MTU disables IPv6 (and therefore IPv6 addrconf).
        mtu=$(ip link show ${bridge} | sed -n ’s/.* mtu \([0-9]\+\).*/\1/p’)
        ip link set ${bridge} mtu 68
        ip link set ${bridge} up
        ip link set ${bridge} mtu ${mtu:-1500}
    }

    # Usage: add_to_bridge bridge dev
    add_to_bridge () {
        local bridge=$1
        local dev=$2

        # Don’t add $dev to $bridge if it’s already on a bridge.
        if [ -e "/sys/class/net/${bridge}/brif/${dev}" ]; then
            ip link set ${dev} up || true
            return
        fi
        brctl addif ${bridge} ${dev}
        ip link set ${dev} up
    }

    You can the start up the needed bridges from within your my-network-bridge script - assuming you change (network-script network-bridge) to (network-script my-network-bridge) in xend-config.sxp:

    #!/bin/sh
    dir=$(dirname "$0")
    "$dir/network-bridge" "$@" vifnum=0 netdev=eth0 bridge=xenbr0
    "$dir/network-bridge" "$@" vifnum=1 netdev=eth1 bridge=xenbr1
    "$dir/network-bridge" "$@" vifnum=2 netdev=eth1.142 bridge=xenbr142
    "$dir/network-bridge" "$@" vifnum=3 netdev=eth1.143 bridge=xenbr143

    The above example gives you the choice of four different bridges for each domU, some of which are transparently bound to a VLAN.

    Published on July 19, 2007 · Filed under: Xen;

Leave a Reply

You must be logged in to post a comment.