events: 10.interface handle updateip event
authorStefan Metzmacher <metze@samba.org>
Mon, 21 Dec 2009 07:40:50 +0000 (08:40 +0100)
committerStefan Metzmacher <metze@samba.org>
Wed, 20 Jan 2010 10:11:02 +0000 (11:11 +0100)
metze

config/events.d/10.interface

index 806354921c10c7dd33f6c92b5d17e5e733e4fa0e..4f7e8de84e431b839e72fdabf586bedd0936fc6d 100755 (executable)
@@ -212,6 +212,63 @@ case "$1" in
        echo 1 > /proc/sys/net/ipv4/route/flush
        ;;
 
+     ##################################################
+     # called when ctdbd wants to update an IP address
+     updateip)
+       if [ $# != 5 ]; then
+          echo "must supply old interface, new interface, IP and maskbits"
+          exit 1
+       fi
+
+       # moving an IP is a bit more complex than it seems.
+       # First we drop all traffic on the old interface.
+       # Then we try to add the ip to the new interface and before
+       # we finally remove it from the old interface.
+       #
+       # 1) firewall this IP, so no new external packets arrive for it
+       # 2) add the IP to the new interface
+       # 3) remove the IP from the old interface
+       # 4) remove the firewall rule
+       # 5) use ctdb gratiousarp to propagate the new mac address
+       # 6) use netstat -tn to find existing connections, and tickle them
+       oiface=$2
+       niface=$3
+       ip=$4
+       maskbits=$5
+
+       failed=0
+       # we do an extra delete to cope with the script being killed
+       iptables -D INPUT -i $oiface -d $ip -j DROP 2> /dev/null
+       iptables -I INPUT -i $oiface -d $ip -j DROP
+
+       # we make sure the interface is up first
+       add_ip_to_iface $niface $ip $maskbits || {
+               iptables -D INPUT -i $oiface -d $ip -j DROP 2> /dev/null
+               exit 1;
+       }
+
+       delete_ip_from_iface $oiface $ip $maskbits || {
+               delete_ip_from_iface $niface $ip $maskbits
+               iptables -D INPUT -i $oiface -d $ip -j DROP 2> /dev/null
+               exit 1;
+       }
+
+       # cope with the script being killed while we have the interface blocked
+       iptables -D INPUT -i $oiface -d $ip -j DROP 2> /dev/null
+
+       # flush our route cache
+       echo 1 > /proc/sys/net/ipv4/route/flush
+
+       # propagate the new mac address
+       ctdb gratiousarp $ip $niface
+
+       # tickle all existing connections, so that dropped packets
+       # are retransmited and the tcp streams work
+
+       tickle_tcp_connections $ip
+
+       ;;
+
 
      ###########################################
      # called when ctdbd has finished a recovery