1#!/bin/bash 2#============================================================================ 3# ${XEN_SCRIPT_DIR}/vif-nat 4# 5# Script for configuring a vif in routed-nat mode. 6# 7# Usage: 8# vif-nat (add|remove|online|offline) 9# 10# Environment vars: 11# dev vif interface name (required). 12# XENBUS_PATH path to this device's details in the XenStore (required). 13# 14# Parameters: 15# dhcp Whether to alter the local DHCP configuration to include this 16# new host (default no). 17# 18# Read from the store: 19# ip list of IP networks for the vif, space-separated (default given in 20# this script). 21#============================================================================ 22 23 24dir=$(dirname "$0") 25. "$dir/vif-common.sh" 26 27# turn on dhcp feature by default if dhcpd is installed 28if [ -f /etc/dhcpd.conf ] 29then 30 dhcp=${dhcp:-yes} 31else 32 dhcp=${dhcp:-no} 33fi 34 35if [ "$dhcp" != 'no' ] 36then 37 dhcpd_conf_file=$(find_dhcpd_conf_file) 38 dhcpd_init_file=$(find_dhcpd_init_file) 39 dhcpd_arg_file=$(find_dhcpd_arg_file) 40 if [ -z "$dhcpd_conf_file" ] || [ -z "$dhcpd_init_file" ] || [ -z "$dhcpd_arg_file" ] 41 then 42 echo 'Failed to find dhcpd configuration or init or args file.' >&2 43 exit 1 44 fi 45fi 46 47 48domid=$(xenstore_read "$XENBUS_PATH/frontend-id") 49vifid=$(xenstore_read "$XENBUS_PATH/handle") 50vifid=$(( $vifid + 1 )) 51 52 53ip_from_dom() 54{ 55 local domid1=$(( $domid / 256 )) 56 local domid2=$(( $domid % 256 )) 57 58 echo "10.$domid1.$domid2.$vifid/16" 59} 60 61 62routing_ip() 63{ 64 echo $(echo $1 | awk -F. '{print $1"."$2"."$3"."$4 + 127}') 65} 66 67 68dotted_quad() 69{ 70 echo\ 71 $(( ($1 & 0xFF000000) >> 24))\ 72.$(( ($1 & 0x00FF0000) >> 16))\ 73.$(( ($1 & 0x0000FF00) >> 8 ))\ 74.$(( $1 & 0x000000FF )) 75} 76 77 78if [ "$ip" = "" ] 79then 80 ip=$(ip_from_dom) 81fi 82 83router_ip=$(routing_ip "$ip") 84 85# Split the given IP/bits pair. 86vif_ip=`echo ${ip} | awk -F/ '{print $1}'` 87 88hostname=$(xenstore_read "$XENBUS_PATH/domain" | tr -- '_.:/+' '-----') 89if [ "$vifid" != "1" ] 90then 91 hostname="$hostname-$vifid" 92fi 93 94dhcparg_remove_entry() 95{ 96 local tmpfile=$(mktemp) 97 sed -e "s/${dev} //" "$dhcpd_arg_file" >"$tmpfile" 98 if diff "$tmpfile" "$dhcpd_arg_file" >/dev/null 99 then 100 rm "$tmpfile" 101 else 102 mv "$tmpfile" "$dhcpd_arg_file" 103 fi 104} 105 106dhcparg_add_entry() 107{ 108 dhcparg_remove_entry 109 local tmpfile=$(mktemp) 110 # handle Red Hat, SUSE, and Debian styles, with or without quotes 111 sed -e 's/^DHCPDARGS="*\([^"]*\)"*/DHCPDARGS="\1'"${dev} "'"/' \ 112 "$dhcpd_arg_file" >"$tmpfile" && mv "$tmpfile" "$dhcpd_arg_file" 113 sed -e 's/^DHCPD_INTERFACE="*\([^"]*\)"*/DHCPD_INTERFACE="\1'"${dev} "'"/' \ 114 "$dhcpd_arg_file" >"$tmpfile" && mv "$tmpfile" "$dhcpd_arg_file" 115 sed -e 's/^INTERFACES="*\([^"]*\)"*/INTERFACES="\1'"${dev} "'"/' \ 116 "$dhcpd_arg_file" >"$tmpfile" && mv "$tmpfile" "$dhcpd_arg_file" 117 rm -f "$tmpfile" 118} 119 120dhcp_remove_entry() 121{ 122 local tmpfile=$(mktemp) 123 grep -v "host $hostname" "$dhcpd_conf_file" >"$tmpfile" 124 if diff "$tmpfile" "$dhcpd_conf_file" >/dev/null 125 then 126 rm "$tmpfile" 127 else 128 mv "$tmpfile" "$dhcpd_conf_file" 129 fi 130 dhcparg_remove_entry 131} 132 133 134dhcp_up() 135{ 136 claim_lock "vif-nat-dhcp" 137 dhcp_remove_entry 138 mac=$(xenstore_read "$XENBUS_PATH/mac") 139 echo >>"$dhcpd_conf_file" \ 140"host $hostname { hardware ethernet $mac; fixed-address $vif_ip; option routers $router_ip; option host-name \"$hostname\"; }" 141 dhcparg_add_entry 142 release_lock "vif-nat-dhcp" 143 "$dhcpd_init_file" restart || true 144} 145 146 147dhcp_down() 148{ 149 claim_lock "vif-nat-dhcp" 150 dhcp_remove_entry 151 release_lock "vif-nat-dhcp" 152 "$dhcpd_init_file" restart || true # We need to ignore failure because 153 # ISC dhcpd 3 borks if there is nothing 154 # for it to do, which is the case if 155 # the outgoing interface is not 156 # configured to offer leases and there 157 # are no vifs. 158} 159 160 161case "$command" in 162 online) 163 if ip route | grep -q "dev ${dev}" 164 then 165 log debug "${dev} already up" 166 exit 0 167 fi 168 169 do_or_die ip link set dev "${dev}" up arp on 170 do_or_die ip addr add "$router_ip" dev "${dev}" 171 do_or_die ip route add "$vif_ip" dev "${dev}" src "$router_ip" 172 echo 1 >/proc/sys/net/ipv4/conf/${dev}/proxy_arp 173 [ "$dhcp" != 'no' ] && dhcp_up 174 ;; 175 offline) 176 [ "$dhcp" != 'no' ] && dhcp_down 177 do_without_error ifconfig "${dev}" down 178 ;; 179esac 180 181 182handle_iptable 183 184call_hooks vif post 185 186log debug "Successful vif-nat $command for ${dev}." 187if [ "$command" = "online" ] 188then 189 success 190fi 191