summaryrefslogtreecommitdiffstats
path: root/ctdb
diff options
context:
space:
mode:
authorMartin Schwenke <martin@meltin.net>2014-11-21 14:46:00 +1100
committerMartin Schwenke <martins@samba.org>2014-12-05 21:02:40 +0100
commit6471541d6d2bc9f2af0ff92b280abbd1d933cf88 (patch)
tree17f8f97c8a4d292b3e9df64bd9bad13aa7260509 /ctdb
parentc314ae0b2af4a902cdd003ec6d663fe5b62b003b (diff)
downloadsamba-6471541d6d2bc9f2af0ff92b280abbd1d933cf88.tar.gz
samba-6471541d6d2bc9f2af0ff92b280abbd1d933cf88.tar.xz
samba-6471541d6d2bc9f2af0ff92b280abbd1d933cf88.zip
ctdb-scripts: Make 10.interface IPv6-safe
Add checking to "releaseip" and "updateip" to ensure that the given IP address is really on the given interface with the given netmask. If reality doesn't match the given arguments then believe reality. Use new function iptables_wrapper() instead of calling iptables() directly. Use new function flush_route_cache() instead of doing IPv4-specific /proc magic. Remove setting of otherwise unused variable "failed". Fix a test for which the error message has changed. Signed-off-by: Martin Schwenke <martin@meltin.net> Reviewed-by: Amitay Isaacs <amitay@gmail.com>
Diffstat (limited to 'ctdb')
-rwxr-xr-xctdb/config/events.d/10.interface85
-rwxr-xr-xctdb/config/functions6
-rwxr-xr-xctdb/tests/eventscripts/10.interface.releaseip.002.sh5
3 files changed, 65 insertions, 31 deletions
diff --git a/ctdb/config/events.d/10.interface b/ctdb/config/events.d/10.interface
index 8207fd3b20..51d1b974dc 100755
--- a/ctdb/config/events.d/10.interface
+++ b/ctdb/config/events.d/10.interface
@@ -137,6 +137,34 @@ monitor_interfaces()
return 1
}
+# Sets: iface, ip, maskbits, family
+get_iface_ip_maskbits_family ()
+{
+ _iface_in="$1"
+ ip="$2"
+ _maskbits_in="$3"
+
+ set -- $(ip_maskbits_iface "$ip")
+ if [ -n "$1" ] ; then
+ maskbits="$1"
+ iface="$2"
+ family="$3"
+
+ if [ "$iface" != "$_iface_in" ] ; then
+ printf \
+ 'WARNING: Public IP %s hosted on interface %s but VNN says %s\n' \
+ "$ip" "$iface" "$_iface_in"
+ fi
+ if [ "$maskbits" != "$_maskbits_in" ] ; then
+ printf \
+ 'WARNING: Public IP %s has %s bit netmask but VNN says %s\n' \
+ "$ip" "$maskbits" "$_maskbits_in"
+ fi
+ else
+ die "ERROR: Unable to determine interface for IP ${ip}"
+ fi
+}
+
ctdb_check_args "$@"
case "$1" in
@@ -174,10 +202,13 @@ case "$1" in
}
# cope with the script being killed while we have the interface blocked
- iptables -D INPUT -i $iface -d $ip -j DROP 2> /dev/null
+ case "$ip" in
+ *:*) family="inet6" ;;
+ *) family="inet" ;;
+ esac
+ iptables_wrapper $family -D INPUT -i $iface -d $ip -j DROP 2> /dev/null
- # flush our route cache
- set_proc sys/net/ipv4/route/flush 1
+ flush_route_cache
;;
@@ -194,25 +225,23 @@ case "$1" in
# 2) use netstat -tn to find existing connections, and kill them
# 3) remove the IP from the interface
# 4) remove the firewall rule
- iface=$2
- ip=$3
- maskbits=$4
+ shift
+ get_iface_ip_maskbits_family "$@"
- failed=0
# we do an extra delete to cope with the script being killed
- iptables -D INPUT -i $iface -d $ip -j DROP 2> /dev/null
- iptables -I INPUT -i $iface -d $ip -j DROP
+ iptables_wrapper $family -D INPUT -i $iface -d $ip -j DROP 2> /dev/null
+ iptables_wrapper $family -I INPUT -i $iface -d $ip -j DROP
kill_tcp_connections $ip
delete_ip_from_iface $iface $ip $maskbits || {
- iptables -D INPUT -i $iface -d $ip -j DROP 2> /dev/null
- exit 1;
+ iptables_wrapper $family \
+ -D INPUT -i $iface -d $ip -j DROP 2> /dev/null
+ exit 1
}
- iptables -D INPUT -i $iface -d $ip -j DROP 2> /dev/null
+ iptables_wrapper $family -D INPUT -i $iface -d $ip -j DROP 2> /dev/null
- # flush our route cache
- set_proc sys/net/ipv4/route/flush 1
+ flush_route_cache
;;
##################################################
@@ -224,34 +253,36 @@ case "$1" in
# 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
+ # 2) remove the IP from the old interface (and new interface, to be sure)
+ # 3) add the IP to the new 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
+ _oiface=$2
niface=$3
- ip=$4
- maskbits=$5
+ _ip=$4
+ _maskbits=$5
+
+ get_iface_ip_maskbits_family "$_oiface" "$ip" "$maskbits"
+ oiface="$iface"
- 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
+ iptables_wrapper $family -D INPUT -i $oiface -d $ip -j DROP 2> /dev/null
+ iptables_wrapper $family -I INPUT -i $oiface -d $ip -j DROP
delete_ip_from_iface $oiface $ip $maskbits 2>/dev/null
delete_ip_from_iface $niface $ip $maskbits 2>/dev/null
add_ip_to_iface $niface $ip $maskbits || {
- iptables -D INPUT -i $oiface -d $ip -j DROP 2> /dev/null
- exit 1;
+ iptables_wrapper $family \
+ -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
+ iptables_wrapper $family -D INPUT -i $oiface -d $ip -j DROP 2> /dev/null
- # flush our route cache
- set_proc sys/net/ipv4/route/flush 1
+ flush_route_cache
# propagate the new mac address
ctdb gratiousarp $ip $niface
diff --git a/ctdb/config/functions b/ctdb/config/functions
index 9d91e6a61a..de373d6261 100755
--- a/ctdb/config/functions
+++ b/ctdb/config/functions
@@ -920,6 +920,12 @@ drop_all_public_ips ()
done <"${CTDB_PUBLIC_ADDRESSES:-/dev/null}"
}
+flush_route_cache ()
+{
+ set_proc sys/net/ipv4/route/flush 1
+ set_proc sys/net/ipv6/route/flush 1
+}
+
########################################################
# Simple counters
_ctdb_counter_common () {
diff --git a/ctdb/tests/eventscripts/10.interface.releaseip.002.sh b/ctdb/tests/eventscripts/10.interface.releaseip.002.sh
index 9bcb7f11d6..4b9726cfdc 100755
--- a/ctdb/tests/eventscripts/10.interface.releaseip.002.sh
+++ b/ctdb/tests/eventscripts/10.interface.releaseip.002.sh
@@ -9,9 +9,6 @@ setup_ctdb
public_address=$(ctdb_get_1_public_address)
ip="${public_address% *}" ; ip="${ip#* }"
-required_result 1 <<EOF
-RTNETLINK answers: Cannot assign requested address
-Failed to del ${ip} on dev ${public_address%% *}
-EOF
+required_result 1 "ERROR: Unable to determine interface for IP ${ip}"
simple_test $public_address