[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-users] custom network script for SuSE boxes



Hello all,
This is a custom network script I have been working on, mainly
for a SuSE 9.3 box, but I am hoping other people may find it
useful.

It is based on the existing network script in /etc/xen/scripts/ .

The existing script, by default, uses eth0 and xen-br0 for the
device and bridge respectively.

The custom script just takes one parameter, say eth0. It move
eth0 to one side by renaming it to eth0slv (eth0 slave) . Then
it create a bridge with the name eth0. Thus eth0 is magicallly
changed from an oridinary network device to a bridge.

This idea is shamelessly stolen from the /usr/lib/YaST2/bin/start-uml .
(I used the names eth0 / eth0slv . This might have been a mistake.
The start-uml script used eth0 / hweth0 . )


Doing things this way means that your firewall and routing settings
work both before and after the script is run. The network devices
continue to get configured with the info in /etc/sysconfig/network/
as usual.

To use it, you need to edit /etc/xen/xend-config.sxp . Set the
variable network-script to point to this script. Set the
variable vif-bridge to be the name of an existing network device
(probably eth0).

The script is a still a bit rough. I haven't finished commenting it.
There is still debugging stuff left in place. Feedback, both good
and bad, is welcomed.

#!/bin/sh
#============================================================================
# Default Xen network start/stop script.
# Xend calls a network script when it starts.
# The script name to use is defined in /etc/xen/xend-config.sxp
# in the network-script field.
#
# This script replaces a network device with a bridge by renaming
# the network device and creating a new bridge with the old name
# of the renamed device. The renamed device is enslaved to the
# bridge.
# 
# The general idea is that names of devices given in  Firewall and
# routing rules can remain the same before/after the script is
# run.
#
# If all goes well, this should ensure that networking stays up.
# However, some configurations are upset by this, especially
# NFS roots. If the bridged setup does not meet your needs,
# configure a different script, for example using routing instead.
#
# Usage:
#
# network (start|stop|status) {VAR=VAL}*
#
# Vars:
#
# bridge     The bridge to use. (defaults to xen-br0: this proably isn't
#            what you want. Remember to edit variable vif-bridge in
#             file /etc/xen/xend-config.sxp. )
# netdev     (now unused)
# antispoof  Whether to use iptables to prevent spoofing (default yes).
#
# start:
# Renames the network device ${bridge} as ${bridge}slv
# Creates a new bridge device named ${bridge} that takes
# the place of the renamed device.
# Enslaves the the renamed network device to the new bridge device.
# Deletes the routing information for the network device and
# adds new routing information for the new bridge device using ifup
#
# stop:
# Removes netdev from the bridge.
# Deletes the routes to bridge and adds them to netdev.
#
# status:
# Print ifconfig for ${bridge}and ${bridge}slv.
# Print routes.
#
#============================================================================

# Exit if anything goes wrong.
#set -e 

#DEBUG=""
#DEBUG="echo"

BRCTL="$DEBUG brctl"
IFUP="$DEBUG ifup"
IFDOWN="$DEBUG ifdown"
IP="$DEBUG ip"
IPTABLES="$DEBUG iptables"
#PATH="/sbin:/usr/sbin:$PATH"

# debugging sleep to fix posible races?
SLEEP="true "
#SLEEP="sleep "

# First arg is the operation.
OP=$1
shift

# Pull variables in args in to environment.
for arg ; do export "${arg}" ; done

bridge=${bridge:-xen-br0}
netdev=${netdev:-eth0}
antispoof=${antispoof:-yes}

echo "# network $OP bridge=$bridge netdev=$netdev antispoof=$antispoof"

# takes 1 arg, the name of a network device
# exit status of 0 or 1
is_netdev() {
    local netdev=$1

    [ $# == 1 ] && ifconfig $netdev >/dev/null 2>&1 || false
}

# takes 1 arg, the name of a network device
# exit status of 0 or 1
is_bridge() {
    local netdev=$1
    
    [ $# == 1 ] && brctl showmacs $netdev >/dev/null 2>&1 || false
}


# Usage: create_bridge bridge
# Create bridge $bridge and set bridge parameters.
# Does not add slave devices.
# Does not assign an IP address.
create_bridge() {
    local netdev=$1

    if [ $# != 1 ] ; then
            false
            return
    fi
    # Don't create the bridge if it already exists.
   echo create_bridge $netdev
   if ! is_netdev ${netdev} && ! is_bridge ${netdev} ; then
        $BRCTL addbr ${netdev}
        $BRCTL stp ${netdev} off
        $BRCTL setfd ${netdev} 0
   fi
}

# Return the MAC address of the network device
# given as an argument.
get_mac_addr() {
    local netdev
    local ret

    if [ $# != 1 ] ; then
            false
            return
    fi
    netdev=$1

    ip link show $netdev \
        | grep -e 'link/ether' \
        | sed -e 's#^[   ]*link/ether[ ]\(\([0-9a-f]\+:\)\+[0-9a-f]\+\).*#\1#'
    return
}


# Usage: antispoofing dev bridge
# Set the default forwarding policy for $dev to drop.
# Allow forwarding to the bridge.
antispoofing() {
    local dev=$1
    local bridge=$2

    $IPTABLES -P FORWARD DROP

    # XXX . OUCH! This looks horribly permissive.
    # I am not sure that firewall rules belong here.
    $IPTABLES -A FORWARD -m physdev --physdev-in ${dev} -j ACCEPT
}

#Usage: show_status dev bridge
#Print ifconfig and routes.
show_status() {
    local bridge=$1
    
    echo '============================================================'
    ifconfig ${bridge}
    ifconfig ${bridge}slv
    echo ' '
    ip route list
    echo ' '
    route -n
    echo '============================================================'
}

#    start       \   ${bridge}
#                 \    is_br  is_dev  missing
# ${bridge}slv     \
#                   +-------+-------+-------+
#          is_br    |  (1)  |  (3)  |  (1)  |
#                   +-------+-------+-------+
#          is_dev   |  (2)  |  (1)  |  (4)  |
#                   +-------+-------+-------+
#          missing  |  (1)  |  (5)  |  (1)  |
#                   +-------+-------+-------+

# (1) Error: bail out leaving things as is.
# (2) Do nothing: bridge already started
# (3) create bridge called ${bridge}slv (if it doesn't already exist)
#     ifdown ${bridge}
#     rename ${bridge} -> ${bridge}tmp
#     rename ${bridge}slv -> ${bridge}
#     rename ${bridge}tmp -> ${bridge}slv
#     enslave ${bridge}slv to ${bridge} (and make sure slave it is up.)
#     ifup ${bridge}
# (4) 

op_start () {
    local real_mac_addr

    if [ "${bridge}" == "null" ] ; then
        return
    fi

    if is_bridge ${bridge}slv ; then
        # row 1 in table above
        if is_bridge ${bridge} || ! is_netdev ${bridge} ; then  
            # (1)
            echo 'case #1'
            # bail out with error
            false
            return
        else
            #(3)
            echo '# case #3'
            real_mac_addr="eth-id-$(get_mac_addr ${bridge})"
            $IFDOWN $real_mac_addr $bridge 
            $IP link set ${bridge}slv down
            $IP link set ${bridge}slv name ${bridge}tmp
            $SLEEP 1
            $IP link set ${bridge} name ${bridge}slv
            $SLEEP 1
            $IP link set ${bridge}tmp name ${bridge}
            $SLEEP 1
            $BRCTL addif ${bridge} ${bridge}slv
            $SLEEP 1
            # Use the mac addr of the enslaved device to find
            # configuration for the bridge.
            $IFUP $real_mac_addr ${bridge} 
            $IP link set ${bridge}slv up
            return
        fi
    elif is_netdev ${bridge}slv ; then
        # row 2 in table above
        if is_bridge ${bridge} ; then
            # (2)
            echo '# case #2'
            # nothing to do, return success
            true
            return
        elif is_netdev ${bridge} ; then
            # (1)
            # bailout with error
            false
            return
        else
            # (4)
            echo '# case #4'
            real_mac_addr="eth-id-$(get_mac_addr ${bridge}slv)"
            # create a bridge named ${bridge} and enslave
            # ${bridge}slv to it.
            # Make sure both interfaces are up.
            create_bridge ${bridge}
            $BRCTL addif ${bridge} ${bridge}slv
            $IP link set ${bridge}slv up
            $SLEEP 1
            # Use the mac addr of the enslaved device to find
            # configuration for the bridge.
            $IFUP $real_mac_addr ${bridge}
            return
        fi
    else
        # row 3 in table above
        if is_bridge ${bridge} ; then
            # (1)
            # bail out with error
            false
            return
        elif is_netdev ${bridge} ; then
            # (5)
            echo '# case #5'
            real_mac_addr="eth-id-$(get_mac_addr ${bridge})"
            $IFDOWN $real_mac_addr $bridge
            $IP link set ${bridge} name ${bridge}slv
            $BRCTL addbr ${bridge}
            $BRCTL addif ${bridge} ${bridge}slv
            $SLEEP 1
            # Use the mac addr of the enslaved device to find
            # configuration for the bridge.
            $IFUP $real_mac_addr ${bridge}
            $IP link set ${bridge}slv up
            return          
        else
            # (1)
            # bail out with error
            false
            return
        fi
    fi

    # Create the bridge and give it the interface IP addresses.
    # Move the interface routes onto the bridge.
    #create_bridge ${bridge}
    # Don't add $dev to $bridge if it's already on a bridge.
    #if ! brctl show | grep -q ${netdev} ; then
    #    brctl addif ${bridge} ${netdev}
    #fi
    
    #if [ ${antispoof} == 'yes' ] ; then
    #    antispoofing ${bridge}slv ${bridge}
    #fi
}

op_stop () {
    if [ "${bridge}" == "null" ] ; then
        return
    fi
    # Remove the interface from the bridge.
    # Move the routes back to the interface.
    if is_netdev ${bridge} && is_bridge ${bridge} ; then
        $IFDOWN ${bridge}
        $IP link set ${bridge}slv down
        $BRCTL delif ${bridge} ${bridge}slv
        $IP link set ${bridge} name ${bridge}tmp
        $SLEEP 1
        $IP link set ${bridge}slv name ${bridge}
        $SLEEP 1
        $IP link set ${bridge}tmp name ${bridge}slv
        $SLEEP 1
        $IFUP "eth-id-$(get_mac_addr ${bridge})" ${bridge}
        return
    fi

   # It's not our place to be enabling forwarding...
}

case ${OP} in
   start)
       op_start
       ;;
   
   stop)
       op_stop
       ;;

   status)
       show_status ${bridge}
      ;;

   *)
      echo 'Unknown command: ' ${OP}
      echo 'Valid commands are: start, stop, status'
      exit 1
esac
_______________________________________________
Xen-users mailing list
Xen-users@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-users

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.