Files
xen/tools/hotplug/Linux/vif-nat
T
Ian Jackson cd98e00714 tools/hotplug/Linux: Use correct device name for vifs in setup scripts
In vif-common.sh, set the shell variable "dev" to the new interface
name when interfaces are renamed, and consistently use this variable
in all the vif scripts.

This fixes hotplug of renamed interfaces.

From: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
From: Patrick Scharrenberg <pittipatti@web.de>
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
Signed-off-by: Patrick Scharrenberg <pittipatti@web.de>
Committed-by: Ian Jackson <ian.jackson@eu.citrix.com>
2011-02-11 18:21:35 +00:00

193 lines
4.8 KiB
Bash

#!/bin/bash
#============================================================================
# ${XEN_SCRIPT_DIR}/vif-nat
#
# Script for configuring a vif in routed-nat mode.
# The hotplugging system will call this script if it is specified either in
# the device configuration given to Xend, or the default Xend configuration
# in ${XEN_CONFIG_DIR}/xend-config.sxp. If the script is specified in
# neither of those places, then vif-bridge is the default.
#
# Usage:
# vif-nat (add|remove|online|offline)
#
# Environment vars:
# dev vif interface name (required).
# XENBUS_PATH path to this device's details in the XenStore (required).
#
# Parameters:
# dhcp Whether to alter the local DHCP configuration to include this
# new host (default no).
#
# Read from the store:
# ip list of IP networks for the vif, space-separated (default given in
# this script).
#============================================================================
dir=$(dirname "$0")
. "$dir/vif-common.sh"
# turn on dhcp feature by default if dhcpd is installed
if [ -f /etc/dhcpd.conf ]
then
dhcp=${dhcp:-yes}
else
dhcp=${dhcp:-no}
fi
if [ "$dhcp" != 'no' ]
then
dhcpd_conf_file=$(find_dhcpd_conf_file)
dhcpd_init_file=$(find_dhcpd_init_file)
dhcpd_arg_file=$(find_dhcpd_arg_file)
if [ -z "$dhcpd_conf_file" ] || [ -z "$dhcpd_init_file" ] || [ -z "$dhcpd_arg_file" ]
then
echo 'Failed to find dhcpd configuration or init or args file.' >&2
exit 1
fi
fi
domid=$(xenstore_read "$XENBUS_PATH/frontend-id")
vifid=$(xenstore_read "$XENBUS_PATH/handle")
vifid=$(( $vifid + 1 ))
ip_from_dom()
{
local domid1=$(( $domid / 256 ))
local domid2=$(( $domid % 256 ))
echo "10.$domid1.$domid2.$vifid/16"
}
routing_ip()
{
echo $(echo $1 | awk -F. '{print $1"."$2"."$3"."$4 + 127}')
}
dotted_quad()
{
echo\
$(( ($1 & 0xFF000000) >> 24))\
.$(( ($1 & 0x00FF0000) >> 16))\
.$(( ($1 & 0x0000FF00) >> 8 ))\
.$(( $1 & 0x000000FF ))
}
if [ "$ip" = "" ]
then
ip=$(ip_from_dom)
fi
router_ip=$(routing_ip "$ip")
# Split the given IP/bits pair.
vif_ip=`echo ${ip} | awk -F/ '{print $1}'`
hostname=$(xenstore_read "$XENBUS_PATH/domain" | tr -- '_.:/+' '-----')
if [ "$vifid" != "1" ]
then
hostname="$hostname-$vifid"
fi
dhcparg_remove_entry()
{
local tmpfile=$(mktemp)
sed -e "s/${dev} //" "$dhcpd_arg_file" >"$tmpfile"
if diff "$tmpfile" "$dhcpd_arg_file" >/dev/null
then
rm "$tmpfile"
else
mv "$tmpfile" "$dhcpd_arg_file"
fi
}
dhcparg_add_entry()
{
dhcparg_remove_entry
local tmpfile=$(mktemp)
# handle Red Hat, SUSE, and Debian styles, with or without quotes
sed -e 's/^DHCPDARGS="*\([^"]*\)"*/DHCPDARGS="\1'"${dev} "'"/' \
"$dhcpd_arg_file" >"$tmpfile" && mv "$tmpfile" "$dhcpd_arg_file"
sed -e 's/^DHCPD_INTERFACE="*\([^"]*\)"*/DHCPD_INTERFACE="\1'"${dev} "'"/' \
"$dhcpd_arg_file" >"$tmpfile" && mv "$tmpfile" "$dhcpd_arg_file"
sed -e 's/^INTERFACES="*\([^"]*\)"*/INTERFACES="\1'"${dev} "'"/' \
"$dhcpd_arg_file" >"$tmpfile" && mv "$tmpfile" "$dhcpd_arg_file"
rm -f "$tmpfile"
}
dhcp_remove_entry()
{
local tmpfile=$(mktemp)
grep -v "host $hostname" "$dhcpd_conf_file" >"$tmpfile"
if diff "$tmpfile" "$dhcpd_conf_file" >/dev/null
then
rm "$tmpfile"
else
mv "$tmpfile" "$dhcpd_conf_file"
fi
dhcparg_remove_entry
}
dhcp_up()
{
claim_lock "vif-nat-dhcp"
dhcp_remove_entry
mac=$(xenstore_read "$XENBUS_PATH/mac")
echo >>"$dhcpd_conf_file" \
"host $hostname { hardware ethernet $mac; fixed-address $vif_ip; option routers $router_ip; option host-name \"$hostname\"; }"
dhcparg_add_entry
release_lock "vif-nat-dhcp"
"$dhcpd_init_file" restart || true
}
dhcp_down()
{
claim_lock "vif-nat-dhcp"
dhcp_remove_entry
release_lock "vif-nat-dhcp"
"$dhcpd_init_file" restart || true # We need to ignore failure because
# ISC dhcpd 3 borks if there is nothing
# for it to do, which is the case if
# the outgoing interface is not
# configured to offer leases and there
# are no vifs.
}
case "$command" in
online)
if ip route | grep -q "dev ${dev}"
then
log debug "${dev} already up"
exit 0
fi
do_or_die ip link set "${dev}" up arp on
do_or_die ip addr add "$router_ip" dev "${dev}"
do_or_die ip route add "$vif_ip" dev "${dev}" src "$router_ip"
echo 1 >/proc/sys/net/ipv4/conf/${dev}/proxy_arp
[ "$dhcp" != 'no' ] && dhcp_up
;;
offline)
[ "$dhcp" != 'no' ] && dhcp_down
do_without_error ifconfig "${dev}" down
;;
esac
handle_iptable
log debug "Successful vif-nat $command for ${dev}."
if [ "$command" = "online" ]
then
success
fi