ia64/xen-unstable

view tools/hotplug/Linux/vif-common.sh @ 19672:fe84a14aacd1

Serialize iptables calls in hotplug scripts

iptables cannot correctly handle situations when more than one command
is trying to set netfilter rules. In such situations, iptables may fail
with EAGAIN, which results in iptables: Unknown error
18446744073709551615.

Such situation can easily happen when multiple network devices are
configured for a domain as vif hotplug scripts are called in parallel
for all of the network devices.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu May 28 11:07:19 2009 +0100 (2009-05-28)
parents e15d30dfb600
children
line source
1 #
2 # Copyright (c) 2005 XenSource Ltd.
3 #
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of version 2.1 of the GNU Lesser General Public
6 # License as published by the Free Software Foundation.
7 #
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 # Lesser General Public License for more details.
12 #
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 #
19 dir=$(dirname "$0")
20 . "$dir/xen-hotplug-common.sh"
21 . "$dir/xen-network-common.sh"
23 findCommand "$@"
25 if [ "$command" != "online" ] &&
26 [ "$command" != "offline" ] &&
27 [ "$command" != "add" ] &&
28 [ "$command" != "remove" ]
29 then
30 log err "Invalid command: $command"
31 exit 1
32 fi
34 case "$command" in
35 add | remove)
36 exit 0
37 ;;
38 esac
41 # Parameters may be read from the environment, the command line arguments, and
42 # the store, with overriding in that order. The environment is given by the
43 # driver, the command line is given by the Xend global configuration, and
44 # store details are given by the per-domain or per-device configuration.
46 evalVariables "$@"
48 ip=${ip:-}
49 ip=$(xenstore_read_default "$XENBUS_PATH/ip" "$ip")
51 # Check presence of compulsory args.
52 XENBUS_PATH="${XENBUS_PATH:?}"
53 vif="${vif:?}"
56 vifname=$(xenstore_read_default "$XENBUS_PATH/vifname" "")
57 if [ "$vifname" ]
58 then
59 if [ "$command" == "online" ] && ! ip link show "$vifname" >&/dev/null
60 then
61 do_or_die ip link set "$vif" name "$vifname"
62 fi
63 vif="$vifname"
64 fi
67 frob_iptable()
68 {
69 if [ "$command" == "online" ]
70 then
71 local c="-I"
72 else
73 local c="-D"
74 fi
76 iptables "$c" FORWARD -m physdev --physdev-in "$vif" "$@" -j ACCEPT \
77 2>/dev/null &&
78 iptables "$c" FORWARD -m state --state RELATED,ESTABLISHED -m physdev \
79 --physdev-out "$vif" -j ACCEPT 2>/dev/null
81 if [ "$command" == "online" ] && [ $? ]
82 then
83 log err "iptables setup failed. This may affect guest networking."
84 fi
85 }
88 ##
89 # Add or remove the appropriate entries in the iptables. With antispoofing
90 # turned on, we have to explicitly allow packets to the interface, regardless
91 # of the ip setting. If ip is set, then we additionally restrict the packets
92 # to those coming from the specified networks, though we allow DHCP requests
93 # as well.
94 #
95 handle_iptable()
96 {
97 # Check for a working iptables installation. Checking for the iptables
98 # binary is not sufficient, because the user may not have the appropriate
99 # modules installed. If iptables is not working, then there's no need to do
100 # anything with it, so we can just return.
101 if ! iptables -L -n >&/dev/null
102 then
103 return
104 fi
106 claim_lock "iptables"
108 if [ "$ip" != "" ]
109 then
110 local addr
111 for addr in $ip
112 do
113 frob_iptable -s "$addr"
114 done
116 # Always allow the domain to talk to a DHCP server.
117 frob_iptable -p udp --sport 68 --dport 67
118 else
119 # No IP addresses have been specified, so allow anything.
120 frob_iptable
121 fi
123 release_lock "iptables"
124 }
127 ##
128 # ip_of interface
129 #
130 # Print the IP address currently in use at the given interface, or nothing if
131 # the interface is not up.
132 #
133 ip_of()
134 {
135 ip addr show "$1" | awk "/^.*inet.*$1\$/{print \$2}" | sed -n '1 s,/.*,,p'
136 }
139 ##
140 # dom0_ip
141 #
142 # Print the IP address of the interface in dom0 through which we are routing.
143 # This is the IP address on the interface specified as "netdev" as a parameter
144 # to these scripts, or eth0 by default. This function will call fatal if no
145 # such interface could be found.
146 #
147 dom0_ip()
148 {
149 local nd=${netdev:-eth0}
150 local result=$(ip_of "$nd")
151 if [ -z "$result" ]
152 then
153 fatal
154 "$netdev is not up. Bring it up or specify another interface with " \
155 "netdev=<if> as a parameter to $0."
156 fi
157 echo "$result"
158 }