CVE-2016-0771: tests/dns: Remove dependencies on env variables
[Samba.git] / ctdb / config / events.d / 10.interface
blob4fb352454b0156d99b6b24196ea1fe1b1e5b05c4
1 #!/bin/sh
3 #################################
4 # interface event script for ctdb
5 # this adds/removes IPs from your
6 # public interface
8 [ -n "$CTDB_BASE" ] || \
9 export CTDB_BASE=$(cd -P $(dirname "$0") ; dirname "$PWD")
11 . $CTDB_BASE/functions
12 loadconfig
14 [ -z "$CTDB_PUBLIC_ADDRESSES" ] && {
15 CTDB_PUBLIC_ADDRESSES=$CTDB_BASE/public_addresses
18 [ ! -f "$CTDB_PUBLIC_ADDRESSES" ] && {
19 if [ "$1" = "init" ]; then
20 echo "No public addresses file found. Nothing to do for 10.interfaces"
22 exit 0
25 # This sets $all_interfaces as a side-effect.
26 get_all_interfaces ()
28 # Get all the interfaces listed in the public_addresses file
29 all_interfaces=$(sed -e "s/^[^\t ]*[\t ]*//" -e "s/,/ /g" -e "s/[\t ]*$//" $CTDB_PUBLIC_ADDRESSES)
31 # Add some special interfaces if they're defined
32 [ "$CTDB_PUBLIC_INTERFACE" ] && all_interfaces="$CTDB_PUBLIC_INTERFACE $all_interfaces"
34 # Get the interfaces for which CTDB has public IPs configured.
35 # That is, for all but the 1st line, get the 1st field.
36 ctdb_ifaces=$(ctdb -X ifaces | sed -e '1d' -e 's@^|@@' -e 's@|.*@@')
38 # Add $ctdb_interfaces and uniquify
39 all_interfaces=$(echo $all_interfaces $ctdb_ifaces | tr ' ' '\n' | sort -u)
42 monitor_interfaces()
44 get_all_interfaces
46 down_interfaces_found=false
47 up_interfaces_found=false
49 # Note that this loop must not exit early. It must process
50 # all interfaces so that the correct state for each interface
51 # is set in CTDB using setifacelink.
52 for _iface in $all_interfaces ; do
53 if interface_monitor "$_iface" ; then
54 up_interfaces_found=true
55 ctdb setifacelink "$_iface" up >/dev/null 2>&1
56 else
57 down_interfaces_found=true
58 ctdb setifacelink "$_iface" down >/dev/null 2>&1
60 done
62 if ! $down_interfaces_found ; then
63 return 0
66 if ! $up_interfaces_found ; then
67 return 1
70 if [ "$CTDB_PARTIALLY_ONLINE_INTERFACES" != "yes" ]; then
71 return 1
74 return 0
77 # Sets: iface, ip, maskbits, family
78 get_iface_ip_maskbits_family ()
80 _iface_in="$1"
81 ip="$2"
82 _maskbits_in="$3"
84 set -- $(ip_maskbits_iface "$ip")
85 if [ -n "$1" ] ; then
86 maskbits="$1"
87 iface="$2"
88 family="$3"
90 if [ "$iface" != "$_iface_in" ] ; then
91 printf \
92 'WARNING: Public IP %s hosted on interface %s but VNN says %s\n' \
93 "$ip" "$iface" "$_iface_in"
95 if [ "$maskbits" != "$_maskbits_in" ] ; then
96 printf \
97 'WARNING: Public IP %s has %s bit netmask but VNN says %s\n' \
98 "$ip" "$maskbits" "$_maskbits_in"
100 else
101 die "ERROR: Unable to determine interface for IP ${ip}"
105 ctdb_check_args "$@"
107 case "$1" in
108 init)
109 # make sure that we only respond to ARP messages from the NIC where
110 # a particular ip address is associated.
111 get_proc sys/net/ipv4/conf/all/arp_filter >/dev/null 2>&1 && {
112 set_proc sys/net/ipv4/conf/all/arp_filter 1
115 _promote="sys/net/ipv4/conf/all/promote_secondaries"
116 get_proc "$_promote" >/dev/null 2>&1 || \
117 die "Public IPs only supported if promote_secondaries is available"
119 # make sure we drop any ips that might still be held if
120 # previous instance of ctdb got killed with -9 or similar
121 drop_all_public_ips
124 startup)
125 monitor_interfaces
128 takeip)
129 iface=$2
130 ip=$3
131 maskbits=$4
133 add_ip_to_iface $iface $ip $maskbits || {
134 exit 1;
137 # cope with the script being killed while we have the interface blocked
138 case "$ip" in
139 *:*) family="inet6" ;;
140 *) family="inet" ;;
141 esac
142 iptables_wrapper $family -D INPUT -i $iface -d $ip -j DROP 2> /dev/null
144 flush_route_cache
147 releaseip)
148 # releasing an IP is a bit more complex than it seems. Once the IP
149 # is released, any open tcp connections to that IP on this host will end
150 # up being stuck. Some of them (such as NFS connections) will be unkillable
151 # so we need to use the killtcp ctdb function to kill them off. We also
152 # need to make sure that no new connections get established while we are
153 # doing this! So what we do is this:
154 # 1) firewall this IP, so no new external packets arrive for it
155 # 2) use netstat -tn to find existing connections, and kill them
156 # 3) remove the IP from the interface
157 # 4) remove the firewall rule
158 shift
159 get_iface_ip_maskbits_family "$@"
161 # we do an extra delete to cope with the script being killed
162 iptables_wrapper $family -D INPUT -i $iface -d $ip -j DROP 2> /dev/null
163 iptables_wrapper $family -I INPUT -i $iface -d $ip -j DROP
164 kill_tcp_connections $ip
166 delete_ip_from_iface $iface $ip $maskbits || {
167 iptables_wrapper $family \
168 -D INPUT -i $iface -d $ip -j DROP 2> /dev/null
169 exit 1
172 iptables_wrapper $family -D INPUT -i $iface -d $ip -j DROP 2> /dev/null
174 flush_route_cache
177 updateip)
178 # moving an IP is a bit more complex than it seems.
179 # First we drop all traffic on the old interface.
180 # Then we try to add the ip to the new interface and before
181 # we finally remove it from the old interface.
183 # 1) firewall this IP, so no new external packets arrive for it
184 # 2) remove the IP from the old interface (and new interface, to be sure)
185 # 3) add the IP to the new interface
186 # 4) remove the firewall rule
187 # 5) use ctdb gratiousarp to propagate the new mac address
188 # 6) use netstat -tn to find existing connections, and tickle them
189 _oiface=$2
190 niface=$3
191 _ip=$4
192 _maskbits=$5
194 get_iface_ip_maskbits_family "$_oiface" "$_ip" "$_maskbits"
195 oiface="$iface"
197 # we do an extra delete to cope with the script being killed
198 iptables_wrapper $family -D INPUT -i $oiface -d $ip -j DROP 2> /dev/null
199 iptables_wrapper $family -I INPUT -i $oiface -d $ip -j DROP
201 delete_ip_from_iface $oiface $ip $maskbits 2>/dev/null
202 delete_ip_from_iface $niface $ip $maskbits 2>/dev/null
204 add_ip_to_iface $niface $ip $maskbits || {
205 iptables_wrapper $family \
206 -D INPUT -i $oiface -d $ip -j DROP 2> /dev/null
207 exit 1
210 # cope with the script being killed while we have the interface blocked
211 iptables_wrapper $family -D INPUT -i $oiface -d $ip -j DROP 2> /dev/null
213 flush_route_cache
215 # propagate the new mac address
216 ctdb gratiousarp $ip $niface
218 # tickle all existing connections, so that dropped packets
219 # are retransmited and the tcp streams work
220 tickle_tcp_connections $ip
223 monitor)
224 monitor_interfaces || exit 1
227 ctdb_standard_event_handler "$@"
229 esac
231 exit 0