1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
|
#!/bin/sh
# Copyright (C) 2000-2009, Parallels, Inc. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#
# Common stuff for vzctl helper scripts
# get the name of the script
SELFNAME="${0##*/}"
# Set the sane umask
umask 022
# Error codes
VZ_INVALID_PARAMETER_SYNTAX=20
VZ_FS_NO_DISK_SPACE=46
VZ_FS_BAD_TMPL=47
VZ_FS_NEW_VE_PRVT=48
VZ_CHANGEPASS=74
VZ_CANT_ADDIP=34
VZ_IP_INUSE=78
# iptables parameters
VE_STATE_DIR="/var/lib/vzctl/veip/"
CONF_DIR="@PKGCONFDIR@/conf/"
ARPSEND_CMD="arpsend -c 1 -w 1"
IP_CMD="ip"
# For 'ip' and 'arpsend' to work,
# make sure these dirs are in $PATH
for d in /sbin /usr/sbin @SBINDIR@; do
case ":${PATH}:" in
*:"${d}":*)
;;
*)
PATH=${d}:$PATH
;;
esac
done
# Prints error message and exits
# Parameters:
# $1 - error message
# $2 - exit code
# Example of usage:
# vzerror "Fatal error" 1
vzerror()
{
# print errors to stderr too
ERR=$?
echo "$SELFNAME ERROR: $1" 1>&2
exit $2
}
# Prints warning message
# Parameters:
# $1 - a message
# Example of usage:
# vzwarning 'Invalid user'
vzwarning()
{
echo "$SELFNAME WARNING: $1" 1>&2
}
# Prints debug message
# Parameters:
# $* - debug message
# Example of usage:
# vzdebug Trying to start ls
vzdebug()
{
echo "$SELFNAME: $*" 1>&2
}
# Checks if environment variable exists,
# and exits with exit code 1 if not
# Parameters:
# $* - option names
# Example:
# vzcheckvar VEID IP_ADDR
vzcheckvar()
{
local var
for var; do
eval test -n "\"\$$var\"" ||
vzerror "Missing parameter: $var" $VZ_INVALID_PARAMETER_SYNTAX
done
}
# This function fills $NETDEVICES with all network interfaces
# You should always call it before calling vzarp
vzgetnetdev()
{
# Get a list of interfaces, excluding ones with LOOPBACK,
# NOARP, or SLAVE flags
NETDEVICES=`${IP_CMD} addr list | awk '
/^[0-9]+: / {
dev="";
}
/^[0-9]+: / && /[^A-Z_]UP[^A-Z_]/ && !/[^A-Z_]LOOPBACK[^A-Z_]/ \
&& !/[^A-Z_]SLAVE[^A-Z_]/ && !/[^A-Z_]NOARP[^A-Z_]/ {
if ($2 !~ /^veth[0-9]+/)
dev=$2;
}
/^[\ \t]+inet6? / && !/ scope link/ {
if (dev != "") print (dev);
dev="";
}' | sed -e 's/:$//' -e 's/@.*$//'`
}
# Find neighbour interfaces for a given CT IP.
# Make sure to source @PKGCONFDIR@/vz.conf before calling this,
# in order to get the value of $NEIGHBOUR_DEVS from it.
vz_get_neighbour_devs()
{
[ -n "$NETDEVICES" ] || vzwarning 'Device list is empty'
[ -n "$1" -a -n "$NETDEVICES" ] || return 1
if [ "$NEIGHBOUR_DEVS" != 'detect' ]; then
echo $NETDEVICES
return 0
fi
local route devs dev netdev
route="$(${IP_CMD} route get "$1" |grep ' dev .* src ')"
# match: $1 ... dev $dev ...
devs="$(echo "$route" |sed -ne '/ via /! s/^.* dev \+\([^ ]\+\) .*$/\1/p;Q')"
[ -n "$devs" ] ||
# match: $1 ... via $1 ... dev $dev ...
devs="$(echo "$route" |sed -ne 's/^\([^ ]\+\) \(.* \)\?via \+\1 \(.* \)\?dev \+\([^ ]\+\) .*$/\4/p;Q')"
[ -n "$devs" ] || return 0
for netdev in $NETDEVICES; do
for dev in $devs; do
if [ "$dev" = "$netdev" ]; then
echo "$dev"
fi
done
done
}
# Adds/deletes public ARP records for given IP for all interfaces
# Parameters:
# $1 - should be either "add" or "del"
# $2 - IP address
# $NETDEVICES - Network devices used to take MAC addresses from
vzarp()
{
local dev
for dev in $(vz_get_neighbour_devs "$2"); do
${IP_CMD} neigh "$1" proxy "$2" dev "$dev" >/dev/null 2>&1
# Send ARP request to update neighbour ARP caches
if [ "$1" = "add" ]; then
${ARPSEND_CMD} -U -i "$2" -e "$2" "$dev" ||
vzwarning "$ARPSEND_CMD -U -i $2 -e $2 $dev FAILED"
fi
done
}
# Send ARP request to detect that somebody already have this IP
vzarpipdetect()
{
[ -n "$1" ] || return
[ "$SKIP_ARPDETECT" = 'yes' ] && return
local errwarn
[ "$ERROR_ON_ARPFAIL" = 'yes' ] && errwarn=vzerror || errwarn=vzwarning
local dev ipm ip
for ipm in $1; do
ip=${ipm%%/*}
for dev in $(vz_get_neighbour_devs "$ip"); do
${ARPSEND_CMD} -D -e "$ip" "$dev" ||
$errwarn "$ARPSEND_CMD -D -e $ip $dev FAILED" 1
done
done
}
vzaddrouting4()
{
local src_addr=
if [ -n "$VE_ROUTE_SRC_DEV" ]; then
src_addr=`${IP_CMD} route list table local dev "$VE_ROUTE_SRC_DEV" |
grep '^local' | cut -d' ' -f2 | grep -v '^127\.' | head -n 1`
[ -n "$src_addr" ] ||
vzerror "Unable to get source ip [${VE_ROUTE_SRC_DEV}]" $VZ_CANT_ADDIP
src_addr="src $src_addr"
fi
${IP_CMD} route add "$1" dev venet0 $src_addr ||
vzerror "Unable to add route ${IP_CMD} route add $1 dev venet0 $src_addr" $VZ_CANT_ADDIP
}
vzaddrouting6()
{
${IP_CMD} route add "$1" dev venet0 ||
vzerror "Unable to add route ${IP_CMD} route add $1 dev venet0" $VZ_CANT_ADDIP
}
# Sets VE0 source routing for given IP
# Parameters:
# $1 - IP address
vzaddrouting()
{
${IP_CMD} route list table all "$1" | fgrep -qs "$1 dev venet0" &&
return 0
if [ "${1#*:}" = "$1" ]; then
vzaddrouting4 "$1"
else
vzaddrouting6 "$1"
fi
}
# Deletes VE0 source routing for given IP
# Parameters:
# $1 - IP address
vzdelrouting()
{
${IP_CMD} route list table all "$1" | fgrep -qs "$1 dev venet0" ||
return 0
local arg
if [ "${1%%:*}" = "$1" ]; then
arg="route del $1 dev venet0"
else
arg="-6 route flush $1 dev venet0"
fi
${IP_CMD} $arg ||
vzwarning "vzdelrouting: ${IP_CMD} $arg failed"
}
|