ia64/xen-unstable

changeset 8120:e47e953c9e10

Added DHCP server support, configured by a dhcp=yes parameter. This will write
the appropriate entries into dom0's DHCP server configuration file, allowing
that server to provide info for the guest when it starts.

If an IP address is not configured for vif-nat, invent one using the domain
ID and vif ID.

Fix the vif-nat script.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author emellor@leeni.uk.xensource.com
date Tue Nov 29 14:55:48 2005 +0000 (2005-11-29)
parents 85eef527ba74
children e67cfb40411d
files tools/examples/network-nat tools/examples/vif-nat
line diff
     1.1 --- a/tools/examples/network-nat	Mon Nov 28 18:22:02 2005 +0000
     1.2 +++ b/tools/examples/network-nat	Tue Nov 29 14:55:48 2005 +0000
     1.3 @@ -13,35 +13,69 @@
     1.4  #
     1.5  # netdev     The gateway interface (default eth0).
     1.6  # antispoof  Whether to use iptables to prevent spoofing (default no).
     1.7 +# dhcp       Whether to alter the local DHCP configuration (default no).
     1.8  #
     1.9  #============================================================================
    1.10  
    1.11 -
    1.12 -
    1.13 -# Exit if anything goes wrong.
    1.14 -set -e 
    1.15 +dir=$(dirname "$0")
    1.16 +. "$dir/xen-script-common.sh"
    1.17 +. "$dir/xen-network-common.sh"
    1.18  
    1.19 -# First arg is the operation.
    1.20 -OP=$1
    1.21 -shift
    1.22 -
    1.23 -# Pull variables in args in to environment.
    1.24 -for arg ; do export "${arg}" ; done
    1.25 +findCommand "$@"
    1.26 +evalVariables "$@"
    1.27  
    1.28  netdev=${netdev:-eth0}
    1.29  # antispoofing not yet implemented
    1.30  antispoof=${antispoof:-no}
    1.31 +dhcp=${dhcp:-no}
    1.32  
    1.33 -echo "*network-nat $OP netdev=$netdev antispoof=$antispoof" >&2
    1.34 +if [ "$dhcp" != 'no' ]
    1.35 +then
    1.36 +  dhcpd_conf_file=$(find_dhcpd_conf_file)
    1.37 +  dhcpd_init_file=$(find_dhcpd_init_file)
    1.38 +  if [ -z "$dhcpd_conf_file" ] || [ -z "$dhcpd_init_file" ]
    1.39 +  then
    1.40 +    echo 'Failed to find dhcpd configuration or init file.' >&2
    1.41 +    exit 1
    1.42 +  fi
    1.43 +fi
    1.44 +
    1.45 +
    1.46 +function dhcp_start()
    1.47 +{
    1.48 +  if ! grep -q "subnet 10.0.0.0" "$dhcpd_conf_file"
    1.49 +  then
    1.50 +    echo >>"$dhcpd_conf_file" "subnet 10.0.0.0 netmask 255.255.0.0 {}"
    1.51 +  fi
    1.52 +
    1.53 +  "$dhcpd_init_file" restart
    1.54 +}
    1.55 +
    1.56 +
    1.57 +function dhcp_stop()
    1.58 +{
    1.59 +  local tmpfile=$(mktemp)
    1.60 +  grep -v "subnet 10.0.0.0" "$dhcpd_conf_file" >"$tmpfile"
    1.61 +  if diff "$tmpfile" "$dhcpd_conf_file" >&/dev/null
    1.62 +  then
    1.63 +    rm "$tmpfile"
    1.64 +  else
    1.65 +    mv "$tmpfile" "$dhcpd_conf_file"
    1.66 +  fi
    1.67 +
    1.68 +  "$dhcpd_init_file" restart
    1.69 +}
    1.70  
    1.71  
    1.72  op_start() {
    1.73  	echo 1 >/proc/sys/net/ipv4/ip_forward
    1.74  	iptables -t nat -A POSTROUTING -o ${netdev} -j MASQUERADE
    1.75 +        [ "$dhcp" != 'no' ] && dhcp_start
    1.76  }
    1.77  
    1.78  
    1.79  op_stop() {
    1.80 +        [ "$dhcp" != 'no' ] && dhcp_stop
    1.81  	iptables -t nat -D POSTROUTING -o ${netdev} -j MASQUERADE
    1.82  }
    1.83  
    1.84 @@ -57,7 +91,7 @@ show_status() {
    1.85  
    1.86  }
    1.87  
    1.88 -case ${OP} in
    1.89 +case "$command" in
    1.90      start)
    1.91          op_start
    1.92          ;;
    1.93 @@ -71,7 +105,7 @@ case ${OP} in
    1.94         ;;
    1.95  
    1.96      *)
    1.97 -       echo 'Unknown command: ' ${OP} >&2
    1.98 +       echo "Unknown command: $command" >&2
    1.99         echo 'Valid commands are: start, stop, status' >&2
   1.100         exit 1
   1.101  esac
     2.1 --- a/tools/examples/vif-nat	Mon Nov 28 18:22:02 2005 +0000
     2.2 +++ b/tools/examples/vif-nat	Tue Nov 29 14:55:48 2005 +0000
     2.3 @@ -15,43 +15,141 @@
     2.4  # vif         vif interface name (required).
     2.5  # XENBUS_PATH path to this device's details in the XenStore (required).
     2.6  #
     2.7 +# Parameters:
     2.8 +# dhcp        Whether to alter the local DHCP configuration to include this
     2.9 +#             new host (default no).
    2.10 +#
    2.11  # Read from the store:
    2.12  # ip      list of IP networks for the vif, space-separated (default given in
    2.13  #         this script).
    2.14  #============================================================================
    2.15  
    2.16 +
    2.17  dir=$(dirname "$0")
    2.18  . "$dir/vif-common.sh"
    2.19  
    2.20 +dhcp=${dhcp:-no}
    2.21 +
    2.22 +if [ "$dhcp" != 'no' ]
    2.23 +then
    2.24 +  dhcpd_conf_file=$(find_dhcpd_conf_file)
    2.25 +  dhcpd_init_file=$(find_dhcpd_init_file)
    2.26 +  if [ -z "$dhcpd_conf_file" ] || [ -z "$dhcpd_init_file" ]
    2.27 +  then
    2.28 +    echo 'Failed to find dhcpd configuration or init file.' >&2
    2.29 +    exit 1
    2.30 +  fi
    2.31 +fi
    2.32 +
    2.33 +
    2.34 +ip_from_dom()
    2.35 +{
    2.36 +  local domid=$(echo "$XENBUS_PATH" | sed -n 's#.*/\([0-9]*\)/[0-9]*$#\1#p')
    2.37 +  local vifid=$(echo "$XENBUS_PATH" | sed -n 's#.*/[0-9]*/\([0-9]*\)$#\1#p')
    2.38 +
    2.39 +  local domid1=$(( $domid / 256 ))
    2.40 +  local domid2=$(( $domid % 256 ))
    2.41 +  vifid=$(( $vifid + 1 ))
    2.42 +
    2.43 +  echo "10.$domid1.$domid2.$vifid/16"
    2.44 +}
    2.45 +
    2.46 +
    2.47 +routing_ip()
    2.48 +{
    2.49 +  echo $(echo $1 | awk -F. '{print $1"."$2"."$3"."$4 + 127}')
    2.50 +}
    2.51 +
    2.52 +
    2.53 +dotted_quad()
    2.54 +{
    2.55 + echo\
    2.56 + $(( ($1 & 0xFF000000) >> 24))\
    2.57 +.$(( ($1 & 0x00FF0000) >> 16))\
    2.58 +.$(( ($1 & 0x0000FF00) >> 8 ))\
    2.59 +.$((  $1 & 0x000000FF       ))
    2.60 +}
    2.61 +
    2.62 +
    2.63  if [ "$ip" == "" ]
    2.64  then
    2.65 -  ip='169.254.1.1/24'
    2.66 +  ip=$(ip_from_dom)
    2.67  fi
    2.68  
    2.69 -#determine ip address and netmask 
    2.70 +router_ip=$(routing_ip "$ip")
    2.71 +
    2.72 +# Split the given IP/bits pair.
    2.73  vif_ip=`echo ${ip} | awk -F/ '{print $1}'`
    2.74  bits=`echo ${ip} | awk -F/ '{print $2}'`
    2.75 -intmask=$(( ((0xFFFFFFFF << ((32 - $bits)))) & 0xFFFFFFFF ))
    2.76 -netmask=$(( (($intmask & 0xFF000000)) >> 24 ))
    2.77 -netmask=$netmask.$(( (($intmask & 0x00FF0000)) >> 16 ))
    2.78 -netmask=$netmask.$(( (($intmask & 0x0000FF00)) >> 8 ))
    2.79 -netmask=$netmask.$(( $intmask & 0x000000FF ))
    2.80 +
    2.81 +# Convert $bits and $vif_ip to integers, mask appropriately to get a network
    2.82 +# address, and convert them both to dotted quads.
    2.83 +
    2.84 +intmask=$(( (0xFFFFFFFF << (32 - $bits)) & 0xFFFFFFFF ))
    2.85 +vif_int=$(( $(echo "((($vif_ip" | sed -e 's#\.#)\*256\+#g') ))
    2.86 +
    2.87 +netmask=$(dotted_quad $intmask)
    2.88 +network=$(dotted_quad $(( $vif_int & $intmask )) )
    2.89  
    2.90  main_ip=$(dom0_ip)
    2.91  
    2.92 +
    2.93 +dhcp_remove_entry()
    2.94 +{
    2.95 +  local tmpfile=$(mktemp)
    2.96 +  grep -v "host Xen-${vif/./-}" "$dhcpd_conf_file" >"$tmpfile"
    2.97 +  if diff "$tmpfile" "$dhcpd_conf_file" >/dev/null
    2.98 +  then
    2.99 +    rm "$tmpfile"
   2.100 +  else
   2.101 +    mv "$tmpfile" "$dhcpd_conf_file"
   2.102 +  fi
   2.103 +}
   2.104 +
   2.105 +
   2.106 +dhcp_up()
   2.107 +{
   2.108 +  dhcp_remove_entry
   2.109 +  mac=$(xenstore_read "$XENBUS_PATH/mac")
   2.110 +  echo >>"$dhcpd_conf_file" \
   2.111 +"host Xen-${vif/./-} { hardware ethernet $mac; fixed-address $vif_ip; option routers $router_ip; }"
   2.112 +
   2.113 +  "$dhcpd_init_file" restart
   2.114 +}
   2.115 +
   2.116 +
   2.117 +dhcp_down()
   2.118 +{
   2.119 +  dhcp_remove_entry
   2.120 +  "$dhcpd_init_file" restart || true # We need to ignore failure because
   2.121 +                                     # ISC dhcpd 3 borks if there is nothing
   2.122 +                                     # for it to do, which is the case if
   2.123 +                                     # the outgoing interface is not
   2.124 +                                     # configured to offer leases and there
   2.125 +                                     # are no vifs.
   2.126 +}
   2.127 +
   2.128 +
   2.129  case "$command" in
   2.130      online)
   2.131 -        ifconfig ${vif} ${vif_ip} netmask ${netmask} up
   2.132 +        if ip route | grep -q "dev $vif"
   2.133 +        then
   2.134 +          log debug "$vif already up"
   2.135 +          exit 0
   2.136 +        fi
   2.137 +
   2.138 +        do_or_die ip link set "$vif" up arp on
   2.139 +        do_or_die ip addr add "$router_ip" dev "$vif"
   2.140 +        do_or_die ip route add "$vif_ip" dev "$vif" src "$main_ip"
   2.141          echo 1 >/proc/sys/net/ipv4/conf/${vif}/proxy_arp
   2.142 -        ipcmd='a'
   2.143 +        [ "$dhcp" != 'no' ] && dhcp_up
   2.144          ;;
   2.145      offline)
   2.146 -        ifconfig ${vif} down
   2.147 -        ipcmd='d'
   2.148 +        [ "$dhcp" != 'no' ] && dhcp_down
   2.149 +        ifconfig "$vif" down || true
   2.150          ;;
   2.151  esac
   2.152  
   2.153 -ip r ${ipcmd} ${ip} dev ${vif} src ${main_ip}
   2.154  
   2.155  handle_iptable
   2.156