ia64/xen-unstable

changeset 1723:23258a8bad48

bitkeeper revision 1.1053.1.1 (40ee75a9YghVZFFolzFjyJngpxAbKg)

Move to new model of network and vif control using shell scripts.
author mjw@wray-m-3.hpl.hp.com
date Fri Jul 09 10:38:33 2004 +0000 (2004-07-09)
parents 3b98f6df869f
children e04e40b4615f
files .rootkeys tools/examples/Makefile tools/examples/network tools/examples/vif-bridge tools/examples/vifctl tools/examples/xend-config.sxp tools/examples/xmdefaults tools/examples/xmnetbsd tools/misc/netfix tools/python/xen/util/ip.py tools/python/xen/xend/Vifctl.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/XendRoot.py tools/python/xen/xend/server/SrvDaemon.py tools/python/xen/xend/server/SrvServer.py tools/python/xen/xend/server/netif.py tools/python/xen/xm/create.py
line diff
     1.1 --- a/.rootkeys	Thu Jul 08 12:49:34 2004 +0000
     1.2 +++ b/.rootkeys	Fri Jul 09 10:38:33 2004 +0000
     1.3 @@ -156,7 +156,10 @@ 3f776bd1Hy9rn69ntXBhPReUFw9IEA tools/Mak
     1.4  401d7e160vaxMBAUSLSicuZ7AQjJ3w tools/examples/Makefile
     1.5  401d7e16UgeqroJQTIhwkrDVkoWgZQ tools/examples/README
     1.6  405ff55dawQyCHFEnJ067ChPRoXBBA tools/examples/init.d/xend
     1.7 +40ee75a9xFz6S05sDKu-JCLqyVTkDA tools/examples/network
     1.8 +40ee75a967sxgcRY4Q7zXoVUaJ4flA tools/examples/vif-bridge
     1.9  40e15b7edWEtBf_oe3eBwGKuh1dyzQ tools/examples/vifctl
    1.10 +40ee75a93cqxHp6MiYXxxwR5j2_8QQ tools/examples/xend-config.sxp
    1.11  40cf2937oKlROYOJTN8GWwWM5AmjBg tools/examples/xmdefaults
    1.12  40dfd40auJwNnb8NoiSnRkvZaaXkUg tools/examples/xmnetbsd
    1.13  3fbba6dbDfYvJSsw9500b4SZyUhxjQ tools/libxc/Makefile
     2.1 --- a/tools/examples/Makefile	Thu Jul 08 12:49:34 2004 +0000
     2.2 +++ b/tools/examples/Makefile	Fri Jul 09 10:38:33 2004 +0000
     2.3 @@ -1,35 +1,35 @@
     2.4  
     2.5  INSTALL  = $(wildcard *.py)
     2.6  
     2.7 -ETC	 = xmdefaults
     2.8 -ETCDIR   = /etc/xen
     2.9 -
    2.10  INITD    = init.d/xend
    2.11  
    2.12 -XEND     = vifctl
    2.13 -XEND_DIR = $(ETCDIR)/xend
    2.14 +XEN_CONFIG_DIR  = /etc/xen
    2.15 +XEN_CONFIGS = xmdefaults xmnetbsd xend-config.sxp
    2.16 +
    2.17 +XEN_SCRIPT_DIR = /etc/xen
    2.18 +XEN_SCRIPTS = vifctl network vif-bridge
    2.19  
    2.20  all: 
    2.21  
    2.22 -install: all install-initd install-etc install-xend
    2.23 +install: all install-initd install-configs install-scripts
    2.24  
    2.25  install-initd:
    2.26  	mkdir -p $(prefix)/etc/init.d
    2.27  	install -m0755 $(INITD) $(prefix)/etc/init.d
    2.28  
    2.29 -install-etc:
    2.30 -	mkdir -p $(prefix)$(ETCDIR)
    2.31 -	mkdir -p $(prefix)$(ETCDIR)/auto
    2.32 -	for i in $(ETC); \
    2.33 -	    do [ -a $(prefix)/$(ETCDIR)/$$i ] || \
    2.34 -	    install -m0644 $$i $(prefix)$(ETCDIR); \
    2.35 +install-configs:
    2.36 +	mkdir -p $(prefix)$(XEN_CONFIG_DIR)
    2.37 +	mkdir -p $(prefix)$(XEN_CONFIG_DIR)/auto
    2.38 +	for i in $(XEN_CONFIGS); \
    2.39 +	    do [ -a $(prefix)/$(XEN_CONFIG_DIR)/$$i ] || \
    2.40 +	    install -m0644 $$i $(prefix)$(XEN_CONFIG_DIR); \
    2.41  	done
    2.42  
    2.43 -install-xend:
    2.44 -	mkdir -p $(prefix)$(XEND_DIR)
    2.45 -	for i in $(XEND); \
    2.46 -	    do [ -a $(prefix)/$(XEND_DIR)/$$i ] || \
    2.47 -	    install -m0755 $$i $(prefix)$(XEND_DIR); \
    2.48 +install-scripts:
    2.49 +	mkdir -p $(prefix)$(XEN_SCRIPT_DIR)
    2.50 +	for i in $(XEN_SCRIPTS); \
    2.51 +	    do [ -a $(prefix)/$()/$$i ] || \
    2.52 +	    install -m0755 $$i $(prefix)$(XEN_SCRIPT_DIR); \
    2.53  	done
    2.54  
    2.55  clean:
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/tools/examples/network	Fri Jul 09 10:38:33 2004 +0000
     3.3 @@ -0,0 +1,165 @@
     3.4 +#!/bin/sh
     3.5 +#============================================================================
     3.6 +# Example Xen network start/stop script.
     3.7 +# Xend calls a network script when it starts.
     3.8 +# This is the default script.
     3.9 +#
    3.10 +# /etc/xen/network (start|stop|status) {VAR=VAL}*
    3.11 +#
    3.12 +# Vars:
    3.13 +#
    3.14 +# bridge     The bridge to use (default xen-br0).
    3.15 +# netdev     The interface to add to the bridge (default eth0).
    3.16 +# antispoof  Whether to use iptables to prevent spoofing (default yes).
    3.17 +#
    3.18 +# start:
    3.19 +# Creates the bridge and enslaves netdev to it.
    3.20 +# Copies the IP addresses from netdev to the bridge.
    3.21 +# Deletes the routes to netdev and adds them on bridge.
    3.22 +#
    3.23 +# stop:
    3.24 +# Removes netdev from the bridge.
    3.25 +# Deletes the routes to bridge and adds them to netdev.
    3.26 +#
    3.27 +# status:
    3.28 +# Print ifconfig for netdev and bridge.
    3.29 +# Print routes.
    3.30 +#
    3.31 +#============================================================================
    3.32 +
    3.33 +# Exit if anything goes wrong.
    3.34 +set -e 
    3.35 +
    3.36 +# First arg is the operation.
    3.37 +OP=$1
    3.38 +shift
    3.39 +
    3.40 +# Pull variables in args in to environment.
    3.41 +for arg ; do export "${arg}" ; done
    3.42 +
    3.43 +bridge=${bridge:-xen-br0}
    3.44 +netdev=${netdev:-eth0}
    3.45 +antispoof=${antispoof:-yes}
    3.46 +
    3.47 +echo "network $OP bridge=$bridge netdev=$netdev antispoof=$antispoof"
    3.48 +
    3.49 +# Usage: transfer_addrs src dst
    3.50 +# Copy all IP addresses (including aliases) from device $src to device $dst.
    3.51 +transfer_addrs () {
    3.52 +    local src=$1
    3.53 +    local dst=$2
    3.54 +    # Don't bother if $dst already has IP addresses.
    3.55 +    if ip addr show dev ${dst} | egrep -q '^ *inet' ; then
    3.56 +        return
    3.57 +    fi
    3.58 +    # Address lines start with 'inet' and have the device in them.
    3.59 +    # Replace 'inet' with 'ip addr add' and change the device name $src
    3.60 +    # to 'dev $src'.
    3.61 +    ip addr show dev ${src} | egrep '^ *inet' | sed -e "
    3.62 +s/inet/ip addr add/
    3.63 +s/${src}/dev ${dst}/
    3.64 +" | sh -e
    3.65 +}
    3.66 +
    3.67 +# Usage: transfer_routes src dst
    3.68 +# Get all IP routes to device $src, delete them, and
    3.69 +# add the same routes to device $dst.
    3.70 +# The original routes have to be deleted, otherwise adding them
    3.71 +# for $dst fails (duplicate routes).
    3.72 +transfer_routes () {
    3.73 +    local src=$1
    3.74 +    local dst=$2
    3.75 +    # List all routes and grep the ones with $src in.
    3.76 +    # Stick 'ip route del' on the front to delete.
    3.77 +    # Change $src to $dst and use 'ip route add' to add.
    3.78 +    ip route list | grep ${src} | sed -e "
    3.79 +h
    3.80 +s/^/ip route del /
    3.81 +P
    3.82 +g
    3.83 +s/${src}/${dst}/
    3.84 +s/^/ip route add /
    3.85 +P
    3.86 +d
    3.87 +" | sh -e
    3.88 +}
    3.89 +
    3.90 +# Usage: create_bridge dev bridge
    3.91 +# Create bridge $bridge and add device $dev to it.
    3.92 +create_bridge () {
    3.93 +    local dev=$1
    3.94 +    local bridge=$2
    3.95 +
    3.96 +    # Don't create the bridge if it already exists.
    3.97 +    if ! brctl show | grep -q ${bridge} ; then
    3.98 +        brctl addbr ${bridge}
    3.99 +        brctl stp ${bridge} off
   3.100 +        brctl setfd ${bridge} 0
   3.101 +        brctl sethello ${bridge} 0
   3.102 +    fi
   3.103 +    ifconfig ${bridge} up
   3.104 +    # Don't add $dev to $bridge if it's already on a bridge.
   3.105 +    if ! brctl show | grep -q ${dev} ; then
   3.106 +        brctl addif ${bridge} ${dev}
   3.107 +    fi
   3.108 +}
   3.109 +
   3.110 +# Usage: antispoofing dev bridge
   3.111 +# Set the default forwarding policy for $dev to drop.
   3.112 +# Allow forwarding to the bridge.
   3.113 +antispoofing () {
   3.114 +    local dev=$1
   3.115 +    local bridge=$2
   3.116 +
   3.117 +    iptables -P FORWARD DROP
   3.118 +    iptables -A FORWARD -m physdev --physdev-in ${dev} -j ACCEPT
   3.119 +}
   3.120 +
   3.121 +# Usage: show_status dev bridge
   3.122 +# Print ifconfig and routes.
   3.123 +show_status () {
   3.124 +    local dev=$1
   3.125 +    local bridge=$2
   3.126 +    
   3.127 +    echo '============================================================'
   3.128 +    ifconfig ${dev}
   3.129 +    ifconfig ${bridge}
   3.130 +    echo ' '
   3.131 +    ip route list
   3.132 +    echo ' '
   3.133 +    route -n
   3.134 +    echo '============================================================'
   3.135 +}
   3.136 +
   3.137 +case ${OP} in
   3.138 +    start)
   3.139 +        # Create the bridge and give it the interface IP addresses.
   3.140 +        # Move the interface routes onto the bridge.
   3.141 +        create_bridge ${netdev} ${bridge}
   3.142 +        transfer_addrs ${netdev} ${bridge}
   3.143 +        transfer_routes ${netdev} ${bridge}
   3.144 +        
   3.145 +        if [ ${antispoof} == 'yes' ] ; then
   3.146 +            antispoofing ${netdev} ${bridge}
   3.147 +        fi
   3.148 +        
   3.149 +        ;;
   3.150 +    
   3.151 +    stop)
   3.152 +        # Remove the interface from the bridge.
   3.153 +        # Move the routes back to the interface.
   3.154 +        brctl delif ${bridge} ${netdev}
   3.155 +        transfer_routes ${bridge} ${netdev}
   3.156 +
   3.157 +        # It's not our place to be enabling forwarding...
   3.158 +        ;;
   3.159 +
   3.160 +    status)
   3.161 +        show_status ${netdev} ${bridge}
   3.162 +       ;;
   3.163 +
   3.164 +    *)
   3.165 +       echo 'Unknown command: ' ${OP}
   3.166 +       echo 'Valid commands are: start, stop, status'
   3.167 +       exit 1
   3.168 +esac
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tools/examples/vif-bridge	Fri Jul 09 10:38:33 2004 +0000
     4.3 @@ -0,0 +1,85 @@
     4.4 +#!/bin/sh
     4.5 +#============================================================================
     4.6 +# /etc/xen/vif-bridge
     4.7 +#
     4.8 +# Script for configuring a vif in bridged mode.
     4.9 +# Xend calls a vif script when bringing a vif up or down.
    4.10 +# This script is the default - but it can be configured for each vif.
    4.11 +#
    4.12 +# Example invocation:
    4.13 +#
    4.14 +# vif-bridge up domain=VM1 vif=vif1.0 bridge=xen-br0 ip="128.232.38.45/28 10.10.10.55/24"
    4.15 +#
    4.16 +#
    4.17 +# Usage:
    4.18 +# vif-bridge (up|down) {VAR=VAL}*
    4.19 +#
    4.20 +# Vars:
    4.21 +#
    4.22 +# domain  name of the domain the interface is on (required).
    4.23 +# vif     vif interface name (required).
    4.24 +# mac     vif MAC address (required).
    4.25 +# bridge  bridge to add the vif to (required).
    4.26 +# ip      list of IP networks for the vif, space-separated (optional).
    4.27 +#
    4.28 +# up:
    4.29 +# Enslaves the vif interface to the bridge and adds iptables rules
    4.30 +# for its ip addresses (if any).
    4.31 +#
    4.32 +# down:
    4.33 +# Removes the vif interface from the bridge and removes the iptables
    4.34 +# rules for its ip addresses (if any).
    4.35 +#============================================================================
    4.36 +
    4.37 +# Exit if anything goes wrong
    4.38 +set -e 
    4.39 +
    4.40 +echo "vif-bridge $*"
    4.41 +
    4.42 +# Operation name.
    4.43 +OP=$1
    4.44 +shift
    4.45 +
    4.46 +# Pull variables in args into environment
    4.47 +for arg ; do export "${arg}" ; done
    4.48 +
    4.49 +# Required parameters. Fail if not set.
    4.50 +domain=${domain:?}
    4.51 +vif=${vif:?}
    4.52 +mac=${mac:?}
    4.53 +bridge=${bridge:?}
    4.54 +
    4.55 +# Optional parameters. Set defaults.
    4.56 +ip=${ip:-''}   # default to null (do nothing)
    4.57 +
    4.58 +# Are we going up or down?
    4.59 +case $OP in
    4.60 +    up)
    4.61 +        brcmd='addif'
    4.62 +        iptcmd='-A'
    4.63 +        ;;
    4.64 +    down)
    4.65 +        brcmd='delif'
    4.66 +        iptcmd='-D'
    4.67 +        ;;
    4.68 +    *)
    4.69 +        echo 'Invalid command: ' $OP
    4.70 +        echo 'Valid commands are: up, down'
    4.71 +        exit 1
    4.72 +        ;;
    4.73 +esac
    4.74 +
    4.75 +# Add/remove vif to/from bridge.
    4.76 +brctl ${brcmd} ${bridge} ${vif}
    4.77 +
    4.78 +if [ ${ip} ] ; then
    4.79 +
    4.80 +    # If we've been given a list of IP networks, allow pkts with these src addrs.
    4.81 +    for addr in ${ip} ; do
    4.82 +        iptables ${iptcmd} FORWARD -m physdev --physdev-in ${vif} -s ${addr} -j ACCEPT
    4.83 +    done 
    4.84 +
    4.85 +    # Always allow us to talk to a DHCP server anyhow.
    4.86 +    iptables ${iptcmd} FORWARD -m physdev --physdev-in ${vif} -p udp --sport 68 --dport 67 -j ACCEPT
    4.87 +fi
    4.88 +
     5.1 --- a/tools/examples/vifctl	Thu Jul 08 12:49:34 2004 +0000
     5.2 +++ b/tools/examples/vifctl	Fri Jul 09 10:38:33 2004 +0000
     5.3 @@ -16,7 +16,7 @@
     5.4  #    added on up and removed on down. The bridge a vif is added to can
     5.5  #    be set in the vm config.
     5.6  #
     5.7 -# The default bridge is nbe-br.
     5.8 +# The default bridge is xen-br0.
     5.9  # The default interface is eth0.
    5.10  #
    5.11  #============================================================================
    5.12 @@ -33,7 +33,7 @@ class VifControl:
    5.13  
    5.14      prefix = 'vifctl_'
    5.15  
    5.16 -    DEFAULT_BRIDGE = 'nbe-br'
    5.17 +    DEFAULT_BRIDGE = 'xen-br0'
    5.18      DEFAULT_INTERFACE = 'eth0'
    5.19  
    5.20      def __init__(self):
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/tools/examples/xend-config.sxp	Fri Jul 09 10:38:33 2004 +0000
     6.3 @@ -0,0 +1,23 @@
     6.4 +# Xend configuration file.
     6.5 +
     6.6 +# Port xend should use for the HTTP interface.
     6.7 +(xend-port         8000)
     6.8 +
     6.9 +# Address xend should listen on.
    6.10 +# Specifying 'localhost' prevents remote connections.
    6.11 +# Specifying the empty string '' allows all connections.
    6.12 +(xend-address      '')
    6.13 +
    6.14 +# The script used to start/stop networking for xend.
    6.15 +(network-script    network)
    6.16 +
    6.17 +# The default bridge that virtual interfaces should be connected to.
    6.18 +(vif-bridge        xen-br0)
    6.19 +
    6.20 +# The default script used to control virtual interfaces.
    6.21 +(vif-script        vif-bridge)
    6.22 +
    6.23 +# Whether iptables should be set up to prevent IP spoofing for
    6.24 +# virtual interfaces. Specify 'yes' or 'no'.
    6.25 +(vif-antispoof     no)
    6.26 +
     7.1 --- a/tools/examples/xmdefaults	Thu Jul 08 12:49:34 2004 +0000
     7.2 +++ b/tools/examples/xmdefaults	Fri Jul 09 10:38:33 2004 +0000
     7.3 @@ -49,7 +49,7 @@ cpu = vmid  # set based on vmid (mod num
     7.4  
     7.5  # Optionally define mac and/or bridge for the network interfaces.
     7.6  # Random MACs are assigned if not given.
     7.7 -#vif = [ 'mac=aa:00:00:00:00:11, bridge=nbe-br' ]
     7.8 +#vif = [ 'mac=aa:00:00:00:00:11, bridge=xen-br0' ]
     7.9  
    7.10  #----------------------------------------------------------------------------
    7.11  # Define the disk devices you want the domain to have access to, and
     8.1 --- a/tools/examples/xmnetbsd	Thu Jul 08 12:49:34 2004 +0000
     8.2 +++ b/tools/examples/xmnetbsd	Fri Jul 09 10:38:33 2004 +0000
     8.3 @@ -41,7 +41,7 @@ name = "NetBSD VM %d" % vmid
     8.4  
     8.5  # Optionally define mac and/or bridge for the network interfaces.
     8.6  # Random MACs are assigned if not given.
     8.7 -#vif = [ 'mac=aa:00:00:00:00:11, bridge=nbe-br' ]
     8.8 +#vif = [ 'mac=aa:00:00:00:00:11, bridge=xen-br0' ]
     8.9  
    8.10  # Specify IP address(es), for the new domain.  You need to
    8.11  # configure IP addrs within the domain just as you do normally.  This
     9.1 --- a/tools/misc/netfix	Thu Jul 08 12:49:34 2004 +0000
     9.2 +++ b/tools/misc/netfix	Fri Jul 09 10:38:33 2004 +0000
     9.3 @@ -3,7 +3,7 @@
     9.4  #============================================================================
     9.5  # Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
     9.6  #============================================================================
     9.7 -# Move the IP address from eth0 onto the Xen bridge (nbe-br).
     9.8 +# Move the IP address from eth0 onto the Xen bridge (xen-br0).
     9.9  # Only works if the bridge control utils (brctl) have been installed.
    9.10  #============================================================================
    9.11  
    9.12 @@ -14,6 +14,9 @@ short_options = 'hvqni:b:c'
    9.13  long_options  = ['help', 'verbose', 'quiet',
    9.14                   'interface=', 'bridge=', 'create']
    9.15  
    9.16 +defaults['interface'] = 'eth0'
    9.17 +defaults['bridge'] = 'xen-br0'
    9.18 +
    9.19  def usage():
    9.20      print """Usage:
    9.21      %s [options]
    10.1 --- a/tools/python/xen/util/ip.py	Thu Jul 08 12:49:34 2004 +0000
    10.2 +++ b/tools/python/xen/util/ip.py	Fri Jul 09 10:38:33 2004 +0000
    10.3 @@ -39,7 +39,7 @@ def _readline(fd):
    10.4  When bridging is used, eth0 may not have an IP address,
    10.5  as it may have been moved onto the bridge.
    10.6  """
    10.7 -NBE_BRIDGE = 'nbe-br'
    10.8 +NBE_BRIDGE = 'xen-br0'
    10.9  
   10.10  def get_current_ipaddr(dev='eth0'):
   10.11      """Get the primary IP address for the given network interface.
    11.1 --- a/tools/python/xen/xend/Vifctl.py	Thu Jul 08 12:49:34 2004 +0000
    11.2 +++ b/tools/python/xen/xend/Vifctl.py	Fri Jul 09 10:38:33 2004 +0000
    11.3 @@ -1,36 +1,70 @@
    11.4 -"""Xend interface to the vifctl script.
    11.5 +"""Xend interface to networking control scripts.
    11.6  """
    11.7  import os
    11.8  import os.path
    11.9  import sys
   11.10  
   11.11 -VIFCTL = '/etc/xen/xend/vifctl'
   11.12 +from xen.xend import XendRoot
   11.13 +xroot = XendRoot.instance()
   11.14  
   11.15 -def init():
   11.16 -    """Call 'vifctl init'. Called when xend starts.
   11.17 -    """
   11.18 -    os.system(VIFCTL + ' init ')
   11.19 +"""Where network control scripts live."""
   11.20 +SCRIPT_DIR = xroot.network_script_dir
   11.21 +
   11.22 +def network(op, script=None, bridge=None, antispoof=None):
   11.23 +    """Call a network control script.
   11.24 +    Xend calls this with op 'start' when it starts.
   11.25  
   11.26 -def vifctl_args(vif, mac=None, bridge=None, ipaddr=[]):
   11.27 -    """Construct the argument list for vifctl.
   11.28 +    @param op:        operation (start, stop, status)
   11.29 +    @param script:    network script name
   11.30 +    @param bridge:    xen bridge
   11.31 +    @param antispoof: whether to enable IP antispoofing rules
   11.32      """
   11.33 -    args = ['vif=%s' % vif]
   11.34 -    if mac:
   11.35 -        args.append('mac=%s' % mac)
   11.36 +    if op not in ['start', 'stop', 'status']:
   11.37 +        raise ValueError('Invalid operation:' + op)
   11.38 +    if script is None:
   11.39 +        script = xroot.get_network_script()
   11.40 +    if bridge is None:
   11.41 +        bridge = xroot.get_vif_bridge()
   11.42 +    if antispoof is None:
   11.43 +        antispoof = xroot.get_vif_antispoof()
   11.44 +    script = os.path.join(SCRIPT_DIR, script)
   11.45 +    args = [op]
   11.46 +    args.append("bridge='%s'" % bridge)
   11.47 +    if antispoof:
   11.48 +        args.append("antispoof=yes")
   11.49 +    else:
   11.50 +        args.append("antispoof=no")
   11.51 +    args = ' '.join(args)
   11.52 +    os.system(script + ' ' + args)
   11.53 +
   11.54 +def vifctl(op, vif=None, script=None, domain=None, mac=None, bridge=None, ipaddr=[]):
   11.55 +    """Call a vif control script.
   11.56 +    Xend calls this when bringing vifs up or down.
   11.57 +
   11.58 +    @param op:     vif operation (up, down)
   11.59 +    @param vif:    vif name
   11.60 +    @param script: name of control script
   11.61 +    @param domain: name of domain the vif is on
   11.62 +    @param mac:    vif MAC address
   11.63 +    @param bridge: bridge to add the vif to
   11.64 +    @param ipaddr: list of ipaddrs the vif may use
   11.65 +    """
   11.66 +    if op not in ['up', 'down']:
   11.67 +        raise ValueError('Invalid operation:' + op)
   11.68 +    if script is None:
   11.69 +        script = xroot.get_vif_script()
   11.70 +    if bridge is None:
   11.71 +        bridge = xroot.get_vif_bridge()
   11.72 +    script = os.path.join(SCRIPT_DIR, script)
   11.73 +    args = [op]
   11.74 +    args.append("vif='%s'" % vif)
   11.75 +    args.append("domain='%s'" % domain)
   11.76 +    args.append("mac='%s'" % mac)
   11.77      if bridge:
   11.78 -        args.append('bridge=%s' % bridge)
   11.79 -    for ip in ipaddr:
   11.80 -        args.append('ipaddr=%s' % ip)
   11.81 -    return ' '.join(args)
   11.82 -    
   11.83 -def up(vif, **kwds):
   11.84 -    """Call 'vifctl up' for a vif. Called when a vif is created.
   11.85 -    """
   11.86 -    args = vifctl_args(vif, **kwds)
   11.87 -    os.system(VIFCTL + ' up ' + args)
   11.88 +        args.append("bridge='%s'" % bridge)
   11.89 +    if ipaddr:
   11.90 +        ips = ' '.join(ipaddr)
   11.91 +        args.append("ip='%s'" % ips)
   11.92 +    args = ' '.join(args)
   11.93 +    os.system(script + ' ' + args)
   11.94  
   11.95 -def down(vif, **kwds):
   11.96 -    """Call 'vifctl down' for a vif. Called when a vif is destroyed.
   11.97 -    """
   11.98 -    args = vifctl_args(vif, **kwds)
   11.99 -    os.system(VIFCTL + ' down ' + args)
    12.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Thu Jul 08 12:49:34 2004 +0000
    12.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Fri Jul 09 10:38:33 2004 +0000
    12.3 @@ -146,16 +146,6 @@ def make_disk(dom, uname, dev, mode, rec
    12.4      ctrl.addCallback(fn)
    12.5      return ctrl
    12.6          
    12.7 -def make_vif(dom, vif, vmac, recreate=0):
    12.8 -    """Create a virtual network device for a domain.
    12.9 -
   12.10 -    
   12.11 -    @returns Deferred
   12.12 -    """
   12.13 -    xend.netif_create(dom, recreate=recreate)
   12.14 -    d = xend.netif_dev_create(dom, vif, vmac, recreate=recreate)
   12.15 -    return d
   12.16 -
   12.17  def vif_up(iplist):
   12.18      """send an unsolicited ARP reply for all non link-local IP addresses.
   12.19  
   12.20 @@ -312,28 +302,28 @@ def append_deferred(dlist, v):
   12.21  
   12.22  def _vm_configure1(val, vm):
   12.23      d = vm.create_devices()
   12.24 -    print '_vm_configure1> made devices...'
   12.25 +    #print '_vm_configure1> made devices...'
   12.26      def cbok(x):
   12.27 -        print '_vm_configure1> cbok', x
   12.28 +        #print '_vm_configure1> cbok', x
   12.29          return x
   12.30      d.addCallback(cbok)
   12.31      d.addCallback(_vm_configure2, vm)
   12.32 -    print '_vm_configure1<'
   12.33 +    #print '_vm_configure1<'
   12.34      return d
   12.35  
   12.36  def _vm_configure2(val, vm):
   12.37 -    print '>callback _vm_configure2...'
   12.38 +    #print '>callback _vm_configure2...'
   12.39      d = vm.configure_fields()
   12.40      def cbok(results):
   12.41 -        print '_vm_configure2> cbok', results
   12.42 +        #print '_vm_configure2> cbok', results
   12.43          return vm
   12.44      def cberr(err):
   12.45 -        print '_vm_configure2> cberr', err
   12.46 +        #print '_vm_configure2> cberr', err
   12.47          vm.destroy()
   12.48          return err
   12.49      d.addCallback(cbok)
   12.50      d.addErrback(cberr)
   12.51 -    print '<_vm_configure2'
   12.52 +    #print '<_vm_configure2'
   12.53      return d
   12.54  
   12.55  class XendDomainInfo:
   12.56 @@ -803,14 +793,11 @@ def vm_dev_vif(vm, val, index):
   12.57          raise VmError('vif: vif in netif backend domain')
   12.58      vif = index #todo
   12.59      vmac = sxp.child_value(val, "mac")
   12.60 -    defer = make_vif(vm.dom, vif, vmac, vm.recreate)
   12.61 +    xend.netif_create(vm.dom, recreate=vm.recreate)
   12.62 +    defer = xend.netif_dev_create(vm.dom, vif, val, recreate=vm.recreate)
   12.63      def fn(id):
   12.64          dev = xend.netif_dev(vm.dom, vif)
   12.65 -        devid = sxp.attribute(val, 'id')
   12.66 -        if devid:
   12.67 -            dev.setprop('id', devid)
   12.68 -        bridge = sxp.child_value(val, "bridge")
   12.69 -        dev.up(bridge)
   12.70 +        dev.vifctl('up')
   12.71          vm.add_device('vif', dev)
   12.72          print 'vm_dev_vif> created', dev
   12.73          return id
    13.1 --- a/tools/python/xen/xend/XendRoot.py	Thu Jul 08 12:49:34 2004 +0000
    13.2 +++ b/tools/python/xen/xend/XendRoot.py	Fri Jul 09 10:38:33 2004 +0000
    13.3 @@ -41,6 +41,9 @@ class XendRoot:
    13.4      """Environment variable used to override config_default."""
    13.5      config_var     = "XEND_CONFIG"
    13.6  
    13.7 +    """Where network control scripts live."""
    13.8 +    network_script_dir = "/etc/xen"
    13.9 +
   13.10      def __init__(self):
   13.11          self.rebooted = 0
   13.12          self.last_reboot = None
   13.13 @@ -99,6 +102,7 @@ class XendRoot:
   13.14          return self.rebooted
   13.15  
   13.16      def configure(self):
   13.17 +        print 'XendRoot>configure>'
   13.18          self.set_config()
   13.19          self.dbroot = self.get_config_value("dbroot", self.dbroot_default)
   13.20          self.lastboot = self.get_config_value("lastboot", self.lastboot_default)
   13.21 @@ -114,23 +118,27 @@ class XendRoot:
   13.22          The config file is a sequence of sxp forms.
   13.23          """
   13.24          self.config_path = os.getenv(self.config_var, self.config_default)
   13.25 +        print 'XendRoot>set_config> config_path=', self.config_path
   13.26          if os.path.exists(self.config_path):
   13.27 +            print 'XendRoot>set_config> loading'
   13.28              fin = file(self.config_path, 'rb')
   13.29              try:
   13.30                  config = sxp.parse(fin)
   13.31 -                config.insert(0, 'config')
   13.32 +                config.insert(0, 'xend-config')
   13.33                  self.config = config
   13.34              finally:
   13.35                  fin.close()
   13.36          else:
   13.37 -            self.config = ['config']
   13.38 +            print 'XendRoot>set_config> not found'
   13.39 +            self.config = ['xend-config']
   13.40 +        print 'XendRoot> config=', self.config
   13.41  
   13.42      def get_config(self, name=None):
   13.43          """Get the configuration element with the given name, or
   13.44          the whole configuration if no name is given.
   13.45  
   13.46 -        name	element name (optional)
   13.47 -        returns config or none
   13.48 +        @param name: element name (optional)
   13.49 +        @return: config or none
   13.50          """
   13.51          if name is None:
   13.52              val = self.config
   13.53 @@ -141,12 +149,31 @@ class XendRoot:
   13.54      def get_config_value(self, name, val=None):
   13.55          """Get the value of an atomic configuration element.
   13.56  
   13.57 -        name	element name
   13.58 -        val	default value (optional, defaults to None)
   13.59 -        returns value
   13.60 +        @param name: element name
   13.61 +        @param val:  default value (optional, defaults to None)
   13.62 +        @return: value
   13.63          """
   13.64          return sxp.child_value(self.config, name, val=val)
   13.65  
   13.66 +    def get_xend_port(self):
   13.67 +        return int(self.get_config_value('xend-port', '8000'))
   13.68 +
   13.69 +    def get_xend_address(self):
   13.70 +        return self.get_config_value('xend-address', '')
   13.71 +
   13.72 +    def get_network_script(self):
   13.73 +        return self.get_config_value('network-script', 'network')
   13.74 +
   13.75 +    def get_vif_bridge(self):
   13.76 +        return self.get_config_value('vif-bridge', 'xen-br0')
   13.77 +
   13.78 +    def get_vif_script(self):
   13.79 +        return self.get_config_value('vif-script', 'vif-bridge')
   13.80 +
   13.81 +    def get_vif_antispoof(self):
   13.82 +        v = self.get_config_value('vif-antispoof', 'yes')
   13.83 +        return v in ['yes', '1', 'on']
   13.84 +
   13.85  def instance():
   13.86      global inst
   13.87      try:
    14.1 --- a/tools/python/xen/xend/server/SrvDaemon.py	Thu Jul 08 12:49:34 2004 +0000
    14.2 +++ b/tools/python/xen/xend/server/SrvDaemon.py	Fri Jul 09 10:38:33 2004 +0000
    14.3 @@ -734,15 +734,14 @@ class Daemon:
    14.4      def netif_get(self, dom):
    14.5          return self.netifCF.getInstanceByDom(dom)
    14.6  
    14.7 -    def netif_dev_create(self, dom, vif, vmac, recreate=0):
    14.8 +    def netif_dev_create(self, dom, vif, config, recreate=0):
    14.9          """Create a network device.
   14.10  
   14.11 -        todo
   14.12          """
   14.13          ctrl = self.netifCF.getInstanceByDom(dom)
   14.14          if not ctrl:
   14.15              raise ValueError('No netif controller: %d' % dom)
   14.16 -        d = ctrl.attachDevice(vif, vmac, recreate=recreate)
   14.17 +        d = ctrl.attachDevice(vif, config, recreate=recreate)
   14.18          return d
   14.19  
   14.20      def netif_dev(self, dom, vif):
    15.1 --- a/tools/python/xen/xend/server/SrvServer.py	Thu Jul 08 12:49:34 2004 +0000
    15.2 +++ b/tools/python/xen/xend/server/SrvServer.py	Fri Jul 09 10:38:33 2004 +0000
    15.3 @@ -37,19 +37,18 @@ from xen.xend import Vifctl
    15.4  from SrvRoot import SrvRoot
    15.5  
    15.6  def create(port=None, interface=None, bridge=0):
    15.7 -    if port is None: port = 8000
    15.8 -    if interface is None: interface = ''
    15.9 +    if port is None:
   15.10 +        port = xroot.get_xend_port()
   15.11 +    if interface is None:
   15.12 +        interface = xroot.get_xend_address()
   15.13      if bridge or xroot.rebooted:
   15.14 -        init_bridge()
   15.15 +        Vifctl.network('start')
   15.16      root = resource.Resource()
   15.17      xend = SrvRoot()
   15.18      root.putChild('xend', xend)
   15.19      site = server.Site(root)
   15.20      reactor.listenTCP(port, site, interface=interface)
   15.21  
   15.22 -def init_bridge():
   15.23 -    Vifctl.init()
   15.24 -
   15.25  def main(port=None, interface=None):
   15.26      create(port, interface)
   15.27      reactor.run()
    16.1 --- a/tools/python/xen/xend/server/netif.py	Thu Jul 08 12:49:34 2004 +0000
    16.2 +++ b/tools/python/xen/xend/server/netif.py	Fri Jul 09 10:38:33 2004 +0000
    16.3 @@ -109,20 +109,42 @@ class NetDev(controller.Dev):
    16.4      """Info record for a network device.
    16.5      """
    16.6  
    16.7 -    def __init__(self, ctrl, vif, mac):
    16.8 +    def __init__(self, ctrl, vif, config):
    16.9          controller.Dev.__init__(self, ctrl)
   16.10          self.vif = vif
   16.11 -        self.mac = mac
   16.12          self.evtchn = None
   16.13 +        self.configure(config)
   16.14 +
   16.15 +    def configure(self, config):
   16.16 +        self.config = config
   16.17 +        self.mac = None
   16.18          self.bridge = None
   16.19 -        self.ipaddr = []
   16.20 +        self.script = None
   16.21 +        self.ipaddr = None
   16.22 +        
   16.23 +        vmac = sxp.child_value(config, 'mac')
   16.24 +        if not vmac: raise ValueError("invalid mac")
   16.25 +        mac = [ int(x, 16) for x in vmac.split(':') ]
   16.26 +        if len(mac) != 6: raise ValueError("invalid mac")
   16.27 +        self.mac = mac
   16.28  
   16.29 +        self.bridge = sxp.child_value(config, 'bridge')
   16.30 +        self.script = sxp.child_value(config, 'script')
   16.31 +
   16.32 +        ipaddrs = sxp.children(config, elt='ip')
   16.33 +        for ipaddr in ipaddrs:
   16.34 +            self.ipaddr.append(sxp.child0(ipaddr))
   16.35 +        
   16.36      def sxpr(self):
   16.37          vif = str(self.vif)
   16.38          mac = self.get_mac()
   16.39 -        val = ['netdev', ['vif', vif], ['mac', mac]]
   16.40 +        val = ['vif', ['idx', vif], ['mac', mac]]
   16.41          if self.bridge:
   16.42              val.append(['bridge', self.bridge])
   16.43 +        if self.script:
   16.44 +            val.append(['script', self.script])
   16.45 +        for ip in self.ipaddr:
   16.46 +            val.append(['ip', ip])
   16.47          if self.evtchn:
   16.48              val.append(['evtchn',
   16.49                          self.evtchn['port1'],
   16.50 @@ -140,24 +162,22 @@ class NetDev(controller.Dev):
   16.51          return ':'.join(map(lambda x: "%x" % x, self.mac))
   16.52  
   16.53      def vifctl_params(self):
   16.54 -        return { 'mac'   : self.get_mac(),
   16.55 +        from xen.xend import XendDomain
   16.56 +        xd = XendDomain.instance()
   16.57 +        dom = self.controller.dom
   16.58 +        dominfo = xd.domain_get(dom)
   16.59 +        name = (dominfo and dominfo.name) or ('DOM%d' % dom)
   16.60 +        return { 'domain': name,
   16.61 +                 'vif'   : self.get_vifname(), 
   16.62 +                 'mac'   : self.get_mac(),
   16.63                   'bridge': self.bridge,
   16.64 -                 'ipaddr': self.ipaddr }
   16.65 -
   16.66 -    def up(self, bridge=None, ipaddr=[]):
   16.67 -        """Bring the device up.
   16.68 +                 'script': self.script,
   16.69 +                 'ipaddr': self.ipaddr, }
   16.70  
   16.71 -        bridge ethernet bridge to connect to
   16.72 -        ipaddr list of ipaddrs to filter using iptables
   16.73 +    def vifctl(self, op):
   16.74 +        """Bring the device up or down.
   16.75          """
   16.76 -        self.bridge = bridge
   16.77 -        self.ipaddr = ipaddr
   16.78 -        Vifctl.up(self.get_vifname(), **self.vifctl_params())
   16.79 -
   16.80 -    def down(self):
   16.81 -        """Bring the device down.
   16.82 -        """
   16.83 -        Vifctl.down(self.get_vifname(), **self.vifctl_params())
   16.84 +        Vifctl.vifctl(op, **self.vifctl_params())
   16.85  
   16.86      def destroy(self):
   16.87          """Destroy the device's resources and disconnect from the back-end
   16.88 @@ -165,7 +185,7 @@ class NetDev(controller.Dev):
   16.89          """
   16.90          def cb_destroy(val):
   16.91              self.controller.send_be_destroy(self.vif)
   16.92 -        self.down()
   16.93 +        self.vifctl('down')
   16.94          #d = self.controller.factory.addDeferred()
   16.95          d = defer.Deferred()
   16.96          d.addCallback(cb_destroy)
   16.97 @@ -194,24 +214,6 @@ class NetifController(controller.Control
   16.98          val = ['netif', ['dom', self.dom]]
   16.99          return val
  16.100      
  16.101 -    def randomMAC(self):
  16.102 -        """Generate a random MAC address.
  16.103 -
  16.104 -        Uses OUI (Organizationally Unique Identifier) AA:00:00, an
  16.105 -        unassigned one that used to belong to DEC. The OUI list is
  16.106 -        available at 'standards.ieee.org'.
  16.107 -
  16.108 -        The remaining 3 fields are random, with the first bit of the first
  16.109 -        random field set 0.
  16.110 -
  16.111 -        returns array of 6 ints
  16.112 -        """
  16.113 -        mac = [ 0xaa, 0x00, 0x00,
  16.114 -                random.randint(0x00, 0x7f),
  16.115 -                random.randint(0x00, 0xff),
  16.116 -                random.randint(0x00, 0xff) ]
  16.117 -        return mac
  16.118 -
  16.119      def lostChannel(self):
  16.120          """Method called when the channel has been lost.
  16.121          """
  16.122 @@ -231,22 +233,15 @@ class NetifController(controller.Control
  16.123          """
  16.124          return self.devices.get(vif)
  16.125  
  16.126 -    def addDevice(self, vif, vmac):
  16.127 -        """Add a network interface. If vmac is None a random MAC is
  16.128 -        assigned. If specified, vmac must be a string of the form
  16.129 -        XX:XX:XX:XX:XX where X is hex digit.
  16.130 +    def addDevice(self, vif, config):
  16.131 +        """Add a network interface.
  16.132  
  16.133          vif device index
  16.134 -        vmac device MAC 
  16.135 +        config device configuration 
  16.136  
  16.137          returns device
  16.138          """
  16.139 -        if vmac is None:
  16.140 -            mac = self.randomMAC()
  16.141 -        else:
  16.142 -            mac = [ int(x, 16) for x in vmac.split(':') ]
  16.143 -        if len(mac) != 6: raise ValueError("invalid mac")
  16.144 -        dev = NetDev(self, vif, mac)
  16.145 +        dev = NetDev(self, vif, config)
  16.146          self.devices[vif] = dev
  16.147          return dev
  16.148  
  16.149 @@ -259,14 +254,14 @@ class NetifController(controller.Control
  16.150          for dev in self.getDevices():
  16.151              dev.destroy()
  16.152  
  16.153 -    def attachDevice(self, vif, vmac, recreate=0):
  16.154 +    def attachDevice(self, vif, config, recreate=0):
  16.155          """Attach a network device.
  16.156          If vmac is None a random mac address is assigned.
  16.157  
  16.158          @param vif interface index
  16.159          @param vmac mac address (string)
  16.160          """
  16.161 -        self.addDevice(vif, vmac)
  16.162 +        self.addDevice(vif, config)
  16.163          d = defer.Deferred()
  16.164          if recreate:
  16.165              d.callback(self)
    17.1 --- a/tools/python/xen/xm/create.py	Thu Jul 08 12:49:34 2004 +0000
    17.2 +++ b/tools/python/xen/xm/create.py	Fri Jul 09 10:38:33 2004 +0000
    17.3 @@ -2,6 +2,7 @@
    17.4  
    17.5  """Domain creation.
    17.6  """
    17.7 +import random
    17.8  import string
    17.9  import sys
   17.10  
   17.11 @@ -127,11 +128,13 @@ gopts.var('ipaddr', val="IPADDR",
   17.12           fn=append_value, default=[],
   17.13           use="Add an IP address to the domain.")
   17.14  
   17.15 -gopts.var('vif', val="mac=MAC,bridge=BRIDGE",
   17.16 +gopts.var('vif', val="mac=MAC,bridge=BRIDGE,script=SCRIPT",
   17.17           fn=append_value, default=[],
   17.18           use="""Add a network interface with the given MAC address and bridge.
   17.19 +         The vif is configured by calling the given configuration script.
   17.20           If mac is not specified a random MAC address is used.
   17.21           If bridge is not specified the default bridge is used.
   17.22 +         If script is not specified the default script is used.
   17.23           This option may be repeated to add more than one vif.
   17.24           Specifying vifs will increase the number of interfaces as needed.
   17.25           """)
   17.26 @@ -227,6 +230,24 @@ def configure_pci(config_devs, vals):
   17.27          config_pci = ['pci', ['bus', bus], ['dev', dev], ['func', func]]
   17.28          config_devs.append(['device', config_pci])
   17.29  
   17.30 +def randomMAC():
   17.31 +    """Generate a random MAC address.
   17.32 +
   17.33 +    Uses OUI (Organizationally Unique Identifier) AA:00:00, an
   17.34 +    unassigned one that used to belong to DEC. The OUI list is
   17.35 +    available at 'standards.ieee.org'.
   17.36 +
   17.37 +    The remaining 3 fields are random, with the first bit of the first
   17.38 +    random field set 0.
   17.39 +
   17.40 +    returns array of 6 ints
   17.41 +    """
   17.42 +    mac = [ 0xaa, 0x00, 0x00,
   17.43 +            random.randint(0x00, 0x7f),
   17.44 +            random.randint(0x00, 0xff),
   17.45 +            random.randint(0x00, 0xff) ]
   17.46 +    return ':'.join(map(lambda x: "%x" % x, mac))
   17.47 +
   17.48  def configure_vifs(config_devs, vals):
   17.49      """Create the config for virtual network interfaces.
   17.50      """
   17.51 @@ -238,14 +259,17 @@ def configure_vifs(config_devs, vals):
   17.52              d = vifs[idx]
   17.53              mac = d.get('mac')
   17.54              bridge = d.get('bridge')
   17.55 +            script = d.get('script')
   17.56          else:
   17.57 -            mac = None
   17.58 +            mac = randomMAC()
   17.59              bridge = None
   17.60 +            script = None
   17.61          config_vif = ['vif']
   17.62 -        if mac:
   17.63 -            config_vif.append(['mac', mac])
   17.64 +        config_vif.append(['mac', mac])
   17.65          if bridge:
   17.66              config_vif.append(['bridge', bridge])
   17.67 +        if script:
   17.68 +            config_vif.append(['script', script])
   17.69          config_devs.append(['device', config_vif])
   17.70  
   17.71  def configure_vfr(config, vals):