summaryrefslogtreecommitdiffstats
path: root/heartbeat/IPaddr2
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xheartbeat/IPaddr21357
1 files changed, 1357 insertions, 0 deletions
diff --git a/heartbeat/IPaddr2 b/heartbeat/IPaddr2
new file mode 100755
index 0000000..97a7431
--- /dev/null
+++ b/heartbeat/IPaddr2
@@ -0,0 +1,1357 @@
+#!/bin/sh
+#
+# $Id: IPaddr2.in,v 1.24 2006/08/09 13:01:54 lars Exp $
+#
+# OCF Resource Agent compliant IPaddr2 script.
+#
+# Based on work by Tuomo Soini, ported to the OCF RA API by Lars
+# Marowsky-Brée. Implements Cluster Alias IP functionality too.
+#
+# Cluster Alias IP cleanup, fixes and testing by Michael Schwartzkopff
+#
+#
+# Copyright (c) 2003 Tuomo Soini
+# Copyright (c) 2004-2006 SUSE LINUX AG, Lars Marowsky-Brée
+# All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+#
+
+
+# TODO:
+# - There ought to be an ocf_run_cmd function which does all logging,
+# timeout handling etc for us
+# - Make this the standard IP address agent on Linux; the other
+# platforms simply should ignore the additional parameters OR can use
+# the legacy heartbeat resource script...
+# - Check LVS <-> clusterip incompatibilities.
+#
+# OCF parameters are as below
+# OCF_RESKEY_ip
+# OCF_RESKEY_broadcast
+# OCF_RESKEY_nic
+# OCF_RESKEY_cidr_netmask
+# OCF_RESKEY_iflabel
+# OCF_RESKEY_mac
+# OCF_RESKEY_clusterip_hash
+# OCF_RESKEY_arp_interval
+# OCF_RESKEY_arp_count
+# OCF_RESKEY_arp_bg
+# OCF_RESKEY_preferred_lft
+#
+# OCF_RESKEY_CRM_meta_clone
+# OCF_RESKEY_CRM_meta_clone_max
+
+
+#######################################################################
+# Initialization:
+
+: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
+. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
+. ${OCF_FUNCTIONS_DIR}/findif.sh
+
+# Defaults
+OCF_RESKEY_ip_default=""
+OCF_RESKEY_cidr_netmask_default=""
+OCF_RESKEY_broadcast_default=""
+OCF_RESKEY_iflabel_default=""
+OCF_RESKEY_cidr_netmask_default=""
+OCF_RESKEY_lvs_support_default=false
+OCF_RESKEY_lvs_ipv6_addrlabel_default=false
+OCF_RESKEY_lvs_ipv6_addrlabel_value_default=99
+OCF_RESKEY_clusterip_hash_default="sourceip-sourceport"
+OCF_RESKEY_mac_default=""
+OCF_RESKEY_unique_clone_address_default=false
+OCF_RESKEY_arp_interval_default=200
+OCF_RESKEY_arp_count_default=5
+OCF_RESKEY_arp_count_refresh_default=0
+OCF_RESKEY_arp_bg_default=""
+OCF_RESKEY_arp_sender_default=""
+OCF_RESKEY_send_arp_opts_default=""
+OCF_RESKEY_flush_routes_default="false"
+OCF_RESKEY_run_arping_default=false
+OCF_RESKEY_nodad_default=false
+OCF_RESKEY_noprefixroute_default="false"
+OCF_RESKEY_preferred_lft_default="forever"
+OCF_RESKEY_network_namespace_default=""
+
+: ${OCF_RESKEY_ip=${OCF_RESKEY_ip_default}}
+: ${OCF_RESKEY_cidr_netmask=${OCF_RESKEY_cidr_netmask_default}}
+: ${OCF_RESKEY_broadcast=${OCF_RESKEY_broadcast_default}}
+: ${OCF_RESKEY_iflabel=${OCF_RESKEY_iflabel_default}}
+: ${OCF_RESKEY_lvs_support=${OCF_RESKEY_lvs_support_default}}
+: ${OCF_RESKEY_lvs_ipv6_addrlabel=${OCF_RESKEY_lvs_ipv6_addrlabel_default}}
+: ${OCF_RESKEY_lvs_ipv6_addrlabel_value=${OCF_RESKEY_lvs_ipv6_addrlabel_value_default}}
+: ${OCF_RESKEY_clusterip_hash=${OCF_RESKEY_clusterip_hash_default}}
+: ${OCF_RESKEY_mac=${OCF_RESKEY_mac_default}}
+: ${OCF_RESKEY_unique_clone_address=${OCF_RESKEY_unique_clone_address_default}}
+: ${OCF_RESKEY_arp_interval=${OCF_RESKEY_arp_interval_default}}
+: ${OCF_RESKEY_arp_count=${OCF_RESKEY_arp_count_default}}
+: ${OCF_RESKEY_arp_count_refresh=${OCF_RESKEY_arp_count_refresh_default}}
+: ${OCF_RESKEY_arp_bg=${OCF_RESKEY_arp_bg_default}}
+: ${OCF_RESKEY_arp_sender=${OCF_RESKEY_arp_sender_default}}
+: ${OCF_RESKEY_send_arp_opts=${OCF_RESKEY_send_arp_opts_default}}
+: ${OCF_RESKEY_flush_routes=${OCF_RESKEY_flush_routes_default}}
+: ${OCF_RESKEY_run_arping=${OCF_RESKEY_run_arping_default}}
+: ${OCF_RESKEY_nodad=${OCF_RESKEY_nodad_default}}
+: ${OCF_RESKEY_noprefixroute=${OCF_RESKEY_noprefixroute_default}}
+: ${OCF_RESKEY_preferred_lft=${OCF_RESKEY_preferred_lft_default}}
+: ${OCF_RESKEY_network_namespace=${OCF_RESKEY_network_namespace_default}}
+
+#######################################################################
+
+SENDARP=$HA_BIN/send_arp
+SENDUA=$HA_BIN/send_ua
+FINDIF=findif
+VLDIR=$HA_RSCTMP
+SENDARPPIDDIR=$HA_RSCTMP
+CIP_lockfile=$HA_RSCTMP/IPaddr2-CIP-${OCF_RESKEY_ip}
+
+IPADDR2_CIP_IPTABLES=$IPTABLES
+
+#######################################################################
+
+meta_data() {
+ cat <<END
+<?xml version="1.0"?>
+<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
+<resource-agent name="IPaddr2" version="1.0">
+<version>1.0</version>
+
+<longdesc lang="en">
+This Linux-specific resource manages IP alias IP addresses.
+It can add an IP alias, or remove one.
+In addition, it can implement Cluster Alias IP functionality
+if invoked as a clone resource.
+
+If used as a clone, "shared address with a trivial, stateless
+(autonomous) load-balancing/mutual exclusion on ingress" mode gets
+applied (as opposed to "assume resource uniqueness" mode otherwise).
+For that, Linux firewall (kernel and userspace) is assumed, and since
+recent distributions are ambivalent in plain "iptables" command to
+particular back-end resolution, "iptables-legacy" (when present) gets
+prioritized so as to avoid incompatibilities (note that respective
+ipt_CLUSTERIP firewall extension in use here is, at the same time,
+marked deprecated, yet said "legacy" layer can make it workable,
+literally, to this day) with "netfilter" one (as in "iptables-nft").
+In that case, you should explicitly set clone-node-max &gt;= 2,
+and/or clone-max &lt; number of nodes. In case of node failure,
+clone instances need to be re-allocated on surviving nodes.
+This would not be possible if there is already an instance
+on those nodes, and clone-node-max=1 (which is the default).
+
+When the specified IP address gets assigned to a respective interface, the
+resource agent sends unsolicited ARP (Address Resolution Protocol, IPv4) or NA
+(Neighbor Advertisement, IPv6) packets to inform neighboring machines about the
+change. This functionality is controlled for both IPv4 and IPv6 by shared
+'arp_*' parameters.
+</longdesc>
+
+<shortdesc lang="en">Manages virtual IPv4 and IPv6 addresses (Linux specific version)</shortdesc>
+
+<parameters>
+<parameter name="ip" unique="1" required="1">
+<longdesc lang="en">
+The IPv4 (dotted quad notation) or IPv6 address (colon hexadecimal notation)
+example IPv4 "192.168.1.1".
+example IPv6 "2001:db8:DC28:0:0:FC57:D4C8:1FFF".
+</longdesc>
+<shortdesc lang="en">IPv4 or IPv6 address</shortdesc>
+<content type="string" default="${OCF_RESKEY_ip_default}" />
+</parameter>
+<parameter name="nic" unique="0">
+<longdesc lang="en">
+The base network interface on which the IP address will be brought
+online.
+If left empty, the script will try and determine this from the
+routing table.
+
+Do NOT specify an alias interface in the form eth0:1 or anything here;
+rather, specify the base interface only.
+If you want a label, see the iflabel parameter.
+
+Prerequisite:
+
+There must be at least one static IP address, which is not managed by
+the cluster, assigned to the network interface.
+If you can not assign any static IP address on the interface,
+modify this kernel parameter:
+
+sysctl -w net.ipv4.conf.all.promote_secondaries=1 # (or per device)
+</longdesc>
+<shortdesc lang="en">Network interface</shortdesc>
+<content type="string"/>
+</parameter>
+
+<parameter name="cidr_netmask">
+<longdesc lang="en">
+The netmask for the interface in CIDR format
+(e.g., 24 and not 255.255.255.0)
+
+If unspecified, the script will also try to determine this from the
+routing table.
+</longdesc>
+<shortdesc lang="en">CIDR netmask</shortdesc>
+<content type="string" default="${OCF_RESKEY_cidr_netmask_default}"/>
+</parameter>
+
+<parameter name="broadcast">
+<longdesc lang="en">
+Broadcast address associated with the IP. It is possible to use the
+special symbols '+' and '-' instead of the broadcast address. In this
+case, the broadcast address is derived by setting/resetting the host
+bits of the interface prefix.
+</longdesc>
+<shortdesc lang="en">Broadcast address</shortdesc>
+<content type="string" default="${OCF_RESKEY_broadcast_default}"/>
+</parameter>
+
+<parameter name="iflabel">
+<longdesc lang="en">
+You can specify an additional label for your IP address here.
+This label is appended to your interface name.
+
+The kernel allows alphanumeric labels up to a maximum length of 15
+characters including the interface name and colon (e.g. eth0:foobar1234)
+
+A label can be specified in nic parameter but it is deprecated.
+If a label is specified in nic name, this parameter has no effect.
+</longdesc>
+<shortdesc lang="en">Interface label</shortdesc>
+<content type="string" default="${OCF_RESKEY_iflabel_default}"/>
+</parameter>
+
+<parameter name="lvs_support">
+<longdesc lang="en">
+Enable support for LVS Direct Routing configurations. In case a IP
+address is stopped, only move it to the loopback device to allow the
+local node to continue to service requests, but no longer advertise it
+on the network.
+
+Notes for IPv6:
+It is not necessary to enable this option on IPv6.
+Instead, enable 'lvs_ipv6_addrlabel' option for LVS-DR usage on IPv6.
+</longdesc>
+<shortdesc lang="en">Enable support for LVS DR</shortdesc>
+<content type="boolean" default="${OCF_RESKEY_lvs_support_default}"/>
+</parameter>
+
+<parameter name="lvs_ipv6_addrlabel">
+<longdesc lang="en">
+Enable adding IPv6 address label so IPv6 traffic originating from
+the address's interface does not use this address as the source.
+This is necessary for LVS-DR health checks to realservers to work. Without it,
+the most recently added IPv6 address (probably the address added by IPaddr2)
+will be used as the source address for IPv6 traffic from that interface and
+since that address exists on loopback on the realservers, the realserver
+response to pings/connections will never leave its loopback.
+See RFC3484 for the detail of the source address selection.
+
+See also 'lvs_ipv6_addrlabel_value' parameter.
+</longdesc>
+<shortdesc lang="en">Enable adding IPv6 address label.</shortdesc>
+<content type="boolean" default="${OCF_RESKEY_lvs_ipv6_addrlabel_default}"/>
+</parameter>
+
+<parameter name="lvs_ipv6_addrlabel_value">
+<longdesc lang="en">
+Specify IPv6 address label value used when 'lvs_ipv6_addrlabel' is enabled.
+The value should be an unused label in the policy table
+which is shown by 'ip addrlabel list' command.
+You would rarely need to change this parameter.
+</longdesc>
+<shortdesc lang="en">IPv6 address label value.</shortdesc>
+<content type="integer" default="${OCF_RESKEY_lvs_ipv6_addrlabel_value_default}"/>
+</parameter>
+
+<parameter name="mac">
+<longdesc lang="en">
+Set the interface MAC address explicitly. Currently only used in case of
+the Cluster IP Alias. Leave empty to chose automatically.
+
+</longdesc>
+<shortdesc lang="en">Cluster IP MAC address</shortdesc>
+<content type="string" default="${OCF_RESKEY_mac_default}"/>
+</parameter>
+
+<parameter name="clusterip_hash">
+<longdesc lang="en">
+Specify the hashing algorithm used for the Cluster IP functionality.
+
+</longdesc>
+<shortdesc lang="en">Cluster IP hashing function</shortdesc>
+<content type="string" default="${OCF_RESKEY_clusterip_hash_default}"/>
+</parameter>
+
+<parameter name="unique_clone_address">
+<longdesc lang="en">
+If true, add the clone ID to the supplied value of IP to create
+a unique address to manage
+</longdesc>
+<shortdesc lang="en">Create a unique address for cloned instances</shortdesc>
+<content type="boolean" default="${OCF_RESKEY_unique_clone_address_default}"/>
+</parameter>
+
+<parameter name="arp_interval">
+<longdesc lang="en">
+Specify the interval between unsolicited ARP (IPv4) or NA (IPv6) packets in
+milliseconds.
+
+This parameter is deprecated and used for the backward compatibility only.
+It is effective only for the send_arp binary which is built with libnet,
+and send_ua for IPv6. It has no effect for other arp_sender.
+</longdesc>
+<shortdesc lang="en">ARP/NA packet interval in ms (deprecated)</shortdesc>
+<content type="integer" default="${OCF_RESKEY_arp_interval_default}"/>
+</parameter>
+
+<parameter name="arp_count">
+<longdesc lang="en">
+Number of unsolicited ARP (IPv4) or NA (IPv6) packets to send at resource
+initialization.
+</longdesc>
+<shortdesc lang="en">ARP/NA packet count sent during initialization</shortdesc>
+<content type="integer" default="${OCF_RESKEY_arp_count_default}"/>
+</parameter>
+
+<parameter name="arp_count_refresh">
+<longdesc lang="en">
+For IPv4, number of unsolicited ARP packets to send during resource monitoring.
+Doing so helps mitigate issues of stuck ARP caches resulting from split-brain
+situations.
+</longdesc>
+<shortdesc lang="en">ARP packet count sent during monitoring</shortdesc>
+<content type="integer" default="${OCF_RESKEY_arp_count_refresh_default}"/>
+</parameter>
+
+<parameter name="arp_bg">
+<longdesc lang="en">
+Whether or not to send the ARP (IPv4) or NA (IPv6) packets in the background.
+The default is true for IPv4 and false for IPv6.
+</longdesc>
+<shortdesc lang="en">ARP/NA from background</shortdesc>
+<content type="string" default="${OCF_RESKEY_arp_bg_default}"/>
+</parameter>
+
+<parameter name="arp_sender">
+<longdesc lang="en">
+For IPv4, the program to send ARP packets with on start. Available options are:
+ - send_arp: default
+ - ipoibarping: default for infiniband interfaces if ipoibarping is available
+ - iputils_arping: use arping in iputils package
+ - libnet_arping: use another variant of arping based on libnet
+</longdesc>
+<shortdesc lang="en">ARP sender</shortdesc>
+<content type="string" default="${OCF_RESKEY_arp_sender_default}"/>
+</parameter>
+
+<parameter name="send_arp_opts">
+<longdesc lang="en">
+For IPv4, extra options to pass to the arp_sender program.
+Available options are vary depending on which arp_sender is used.
+
+A typical use case is specifying '-A' for iputils_arping to use
+ARP REPLY instead of ARP REQUEST as Gratuitous ARPs.
+</longdesc>
+<shortdesc lang="en">Options for ARP sender</shortdesc>
+<content type="string" default="${OCF_RESKEY_send_arp_opts_default}"/>
+</parameter>
+
+<parameter name="flush_routes">
+<longdesc lang="en">
+Flush the routing table on stop. This is for
+applications which use the cluster IP address
+and which run on the same physical host that the
+IP address lives on. The Linux kernel may force that
+application to take a shortcut to the local loopback
+interface, instead of the interface the address
+is really bound to. Under those circumstances, an
+application may, somewhat unexpectedly, continue
+to use connections for some time even after the
+IP address is deconfigured. Set this parameter in
+order to immediately disable said shortcut when the
+IP address goes away.
+</longdesc>
+<shortdesc lang="en">Flush kernel routing table on stop</shortdesc>
+<content type="boolean" default="${OCF_RESKEY_flush_routes_default}"/>
+</parameter>
+
+<parameter name="run_arping">
+<longdesc lang="en">
+For IPv4, whether or not to run arping for collision detection check.
+</longdesc>
+<shortdesc lang="en">Run arping for IPv4 collision detection check</shortdesc>
+<content type="string" default="${OCF_RESKEY_run_arping_default}"/>
+</parameter>
+
+<parameter name="nodad">
+<longdesc lang="en">
+For IPv6, do not perform Duplicate Address Detection when adding the address.
+</longdesc>
+<shortdesc lang="en">Use nodad flag</shortdesc>
+<content type="string" default="${OCF_RESKEY_nodad_default}"/>
+</parameter>
+
+<parameter name="noprefixroute">
+<longdesc lang="en">
+Use noprefixroute flag (see 'man ip-address').
+</longdesc>
+<shortdesc lang="en">Use noprefixroute flag</shortdesc>
+<content type="string" default="${OCF_RESKEY_noprefixroute_default}"/>
+</parameter>
+
+<parameter name="preferred_lft">
+<longdesc lang="en">
+For IPv6, set the preferred lifetime of the IP address.
+This can be used to ensure that the created IP address will not
+be used as a source address for routing.
+Expects a value as specified in section 5.5.4 of RFC 4862.
+</longdesc>
+<shortdesc lang="en">IPv6 preferred lifetime</shortdesc>
+<content type="string" default="${OCF_RESKEY_preferred_lft_default}"/>
+</parameter>
+
+<parameter name="network_namespace">
+<longdesc lang="en">
+Specifies the network namespace to operate within.
+The namespace must already exist, and the interface to be used must be within
+the namespace.
+</longdesc>
+<shortdesc lang="en">Network namespace to use</shortdesc>
+<content type="string" default="${OCF_RESKEY_network_namespace_default}"/>
+</parameter>
+</parameters>
+
+<actions>
+<action name="start" timeout="20s" />
+<action name="stop" timeout="20s" />
+<action name="status" depth="0" timeout="20s" interval="10s" />
+<action name="monitor" depth="0" timeout="20s" interval="10s" />
+<action name="meta-data" timeout="5s" />
+<action name="validate-all" timeout="20s" />
+</actions>
+</resource-agent>
+END
+
+ exit $OCF_SUCCESS
+}
+
+ip_init() {
+ local rc
+
+ if [ X`uname -s` != "XLinux" ]; then
+ ocf_exit_reason "IPaddr2 only supported Linux."
+ exit $OCF_ERR_INSTALLED
+ fi
+
+ if [ X"$OCF_RESKEY_ip" = "X" ] && [ "$__OCF_ACTION" != "stop" ]; then
+ ocf_exit_reason "IP address (the ip parameter) is mandatory"
+ exit $OCF_ERR_CONFIGURED
+ fi
+
+ if
+ case $__OCF_ACTION in
+ start|stop) ocf_is_root;;
+ *) true;;
+ esac
+ then
+ : YAY!
+ else
+ ocf_exit_reason "You must be root for $__OCF_ACTION operation."
+ exit $OCF_ERR_PERM
+ fi
+
+ BASEIP="$OCF_RESKEY_ip"
+ BRDCAST="$OCF_RESKEY_broadcast"
+ NIC="$OCF_RESKEY_nic"
+ # Note: We had a version out there for a while which used
+ # netmask instead of cidr_netmask. Don't remove this aliasing code!
+ if
+ [ ! -z "$OCF_RESKEY_netmask" -a -z "$OCF_RESKEY_cidr_netmask" ]
+ then
+ OCF_RESKEY_cidr_netmask=$OCF_RESKEY_netmask
+ export OCF_RESKEY_cidr_netmask
+ fi
+ NETMASK="$OCF_RESKEY_cidr_netmask"
+ IFLABEL="$OCF_RESKEY_iflabel"
+ IF_MAC="$OCF_RESKEY_mac"
+
+ IP_INC_GLOBAL=${OCF_RESKEY_CRM_meta_clone_max:-1}
+ IP_INC_NO=`expr ${OCF_RESKEY_CRM_meta_clone:-0} + 1`
+
+ if ocf_is_true ${OCF_RESKEY_lvs_support} && [ $IP_INC_GLOBAL -gt 1 ]; then
+ ocf_exit_reason "LVS and load sharing do not go together well"
+ exit $OCF_ERR_CONFIGURED
+ fi
+
+ if ocf_is_decimal "$IP_INC_GLOBAL" && [ $IP_INC_GLOBAL -gt 0 ]; then
+ :
+ else
+ ocf_exit_reason "Invalid meta-attribute clone_max [$IP_INC_GLOBAL], should be positive integer"
+ exit $OCF_ERR_CONFIGURED
+ fi
+
+ echo $OCF_RESKEY_ip | grep -qs ":"
+ if [ $? -ne 0 ];then
+ FAMILY=inet
+ if ocf_is_true $OCF_RESKEY_lvs_ipv6_addrlabel ;then
+ ocf_exit_reason "IPv4 does not support lvs_ipv6_addrlabel"
+ exit $OCF_ERR_CONFIGURED
+ fi
+ if [ -z "$OCF_RESKEY_arp_bg" ]; then
+ OCF_RESKEY_arp_bg=true
+ fi
+ else
+ FAMILY=inet6
+ # address sanitization defined in RFC5952
+ SANITIZED_IP=$($IP2UTIL route get $OCF_RESKEY_ip 2> /dev/null | awk '$1~/:/ {print $1} $2~/:/ {print $2}')
+ if [ -n "$SANITIZED_IP" ]; then
+ OCF_RESKEY_ip="$SANITIZED_IP"
+ fi
+
+ if ocf_is_true $OCF_RESKEY_lvs_support ;then
+ ocf_exit_reason "The IPv6 does not support lvs_support"
+ exit $OCF_ERR_CONFIGURED
+ fi
+ if ocf_is_true $OCF_RESKEY_lvs_ipv6_addrlabel ;then
+ if ocf_is_decimal "$OCF_RESKEY_lvs_ipv6_addrlabel_value" && [ $OCF_RESKEY_lvs_ipv6_addrlabel_value -ge 0 ]; then
+ :
+ else
+ ocf_exit_reason "Invalid lvs_ipv6_addrlabel_value [$OCF_RESKEY_lvs_ipv6_addrlabel_value], should be positive integer"
+ exit $OCF_ERR_CONFIGURED
+ fi
+ fi
+ if [ -z "$OCF_RESKEY_arp_bg" ]; then
+ OCF_RESKEY_arp_bg=false
+ fi
+ fi
+
+ # support nic:iflabel format in nic parameter
+ case $NIC in
+ *:*)
+ IFLABEL=`echo $NIC | sed 's/[^:]*://'`
+ NIC=`echo $NIC | sed 's/:.*//'`
+ # only the base name should be passed to findif
+ OCF_RESKEY_nic=$NIC
+ ;;
+ esac
+
+ # $FINDIF takes its parameters from the environment
+ #
+ NICINFO=`$FINDIF`
+ rc=$?
+ if
+ [ $rc -eq 0 ]
+ then
+ NICINFO=`echo "$NICINFO" | sed -e 's/netmask\ //;s/broadcast\ //'`
+ NIC=`echo "$NICINFO" | cut -d" " -f1`
+ NETMASK=`echo "$NICINFO" | cut -d" " -f2`
+ BRDCAST=`echo "$NICINFO" | cut -d" " -f3`
+ else
+ # findif couldn't find the interface
+ if ocf_is_probe; then
+ ocf_log info "[$FINDIF] failed"
+ exit $OCF_NOT_RUNNING
+ elif [ "$__OCF_ACTION" = stop ]; then
+ ocf_log warn "[$FINDIF] failed"
+ exit $OCF_SUCCESS
+ else
+ ocf_exit_reason "[$FINDIF] failed"
+ exit $rc
+ fi
+ fi
+
+ SENDARPPIDFILE="$SENDARPPIDDIR/send_arp-$OCF_RESKEY_ip"
+
+ if [ -n "$IFLABEL" ]; then
+ IFLABEL=${NIC}:${IFLABEL}
+ if [ ${#IFLABEL} -gt 15 ]; then
+ ocf_exit_reason "Interface label [$IFLABEL] exceeds maximum character limit of 15"
+ exit $OCF_ERR_CONFIGURED
+ fi
+ fi
+
+ if [ "$IP_INC_GLOBAL" -gt 1 ] && ! ocf_is_true "$OCF_RESKEY_unique_clone_address"; then
+ IP_CIP="yes"
+ IP_CIP_HASH="${OCF_RESKEY_clusterip_hash}"
+ if [ -z "$IF_MAC" ]; then
+ # Choose a MAC
+ # 1. Concatenate some input together
+ # 2. This doesn't need to be a cryptographically
+ # secure hash.
+ # 3. Drop everything after the first 6 octets (12 chars)
+ # 4. Delimit the octets with ':'
+ # 5. Make sure the first octet is odd,
+ # so the result is a multicast MAC
+ IF_MAC=`echo $OCF_RESKEY_ip $NETMASK $BRDCAST | \
+ md5sum | \
+ sed -e 's#\(............\).*#\1#' \
+ -e 's#..#&:#g; s#:$##' \
+ -e 's#^\(.\)[02468aAcCeE]#\11#'`
+ fi
+ IP_CIP_FILE="/proc/net/ipt_CLUSTERIP/$OCF_RESKEY_ip"
+ fi
+}
+
+#
+# Find out which interfaces serve the given IP address and netmask.
+# The arguments are an IP address and a netmask.
+# Its output are interface names devided by spaces (e.g., "eth0 eth1").
+#
+find_interface() {
+ local ipaddr="$1"
+ local netmask="$2"
+
+ #
+ # List interfaces but exclude FreeS/WAN ipsecN virtual interfaces
+ #
+ local iface="`$IP2UTIL -o -f $FAMILY addr show \
+ | grep "\ $ipaddr/$netmask" \
+ | cut -d ' ' -f2 \
+ | grep -v '^ipsec[0-9][0-9]*$'`"
+
+ echo "$iface"
+ return 0
+}
+
+#
+# Delete an interface
+#
+delete_interface () {
+ ipaddr="$1"
+ iface="$2"
+ netmask="$3"
+
+ CMD="$IP2UTIL -f $FAMILY addr delete $ipaddr/$netmask dev $iface"
+
+ ocf_run $CMD || return $OCF_ERR_GENERIC
+
+ if ocf_is_true $OCF_RESKEY_flush_routes; then
+ ocf_run $IP2UTIL route flush cache
+ fi
+
+ if [ "$FAMILY" = "inet6" ] && ocf_is_true $OCF_RESKEY_lvs_ipv6_addrlabel ;then
+ delete_ipv6_addrlabel $ipaddr
+ fi
+
+ return $OCF_SUCCESS
+}
+
+#
+# Add an interface
+#
+add_interface () {
+ local cmd msg extra_opts ipaddr netmask broadcast iface label
+
+ ipaddr="$1"
+ netmask="$2"
+ broadcast="$3"
+ iface="$4"
+ label="$5"
+
+ if [ "$FAMILY" = "inet" ] && ocf_is_true $OCF_RESKEY_run_arping &&
+ check_binary arping; then
+ arping -q -c 2 -w 3 -D -I $iface $ipaddr
+ if [ $? = 1 ]; then
+ ocf_log err "IPv4 address collision $ipaddr [DAD]"
+ return $OCF_ERR_GENERIC
+ fi
+ fi
+
+ if [ "$FAMILY" = "inet6" ] && ocf_is_true $OCF_RESKEY_lvs_ipv6_addrlabel ;then
+ add_ipv6_addrlabel $ipaddr
+ fi
+
+ cmd="$IP2UTIL -f $FAMILY addr add $ipaddr/$netmask dev $iface"
+ msg="Adding $FAMILY address $ipaddr/$netmask to device $iface"
+ if [ "$broadcast" != "none" ]; then
+ cmd="$IP2UTIL -f $FAMILY addr add $ipaddr/$netmask brd $broadcast dev $iface"
+ msg="Adding $FAMILY address $ipaddr/$netmask with broadcast address $broadcast to device $iface"
+ fi
+
+ extra_opts=""
+ if [ "$FAMILY" = "inet6" ] && ocf_is_true "${OCF_RESKEY_nodad}"; then
+ extra_opts="$extra_opts nodad"
+ fi
+
+ if ocf_is_true "${OCF_RESKEY_noprefixroute}"; then
+ extra_opts="$extra_opts noprefixroute"
+ fi
+
+ if [ ! -z "$label" ]; then
+ extra_opts="$extra_opts label $label"
+ fi
+ if [ "$FAMILY" = "inet6" ] ;then
+ extra_opts="$extra_opts preferred_lft $OCF_RESKEY_preferred_lft"
+ fi
+ if [ -n "$extra_opts" ]; then
+ cmd="$cmd$extra_opts"
+ msg="$msg (with$extra_opts)"
+ fi
+
+ ocf_log info "$msg"
+ ocf_run $cmd || return $OCF_ERR_GENERIC
+
+ msg="Bringing device $iface up"
+ cmd="$IP2UTIL link set $iface up"
+ ocf_log info "$msg"
+ ocf_run $cmd || return $OCF_ERR_GENERIC
+
+ return $OCF_SUCCESS
+}
+
+#
+# Delete a route
+#
+delete_route () {
+ prefix="$1"
+ iface="$2"
+
+ CMD="$IP2UTIL route delete $prefix dev $iface"
+
+ ocf_log info "$CMD"
+ $CMD
+
+ return $?
+}
+
+# On Linux systems the (hidden) loopback interface may
+# conflict with the requested IP address. If so, this
+# unoriginal code will remove the offending loopback address
+# and save it in VLDIR so it can be added back in later
+# when the IPaddr is released.
+#
+# TODO: This is very ugly and should be controlled by an additional
+# instance parameter. Or even: multi-state, with the IP only being
+# "active" on the master!?
+#
+remove_conflicting_loopback() {
+ ipaddr="$1"
+ netmask="$2"
+ broadcast="$3"
+ ifname="$4"
+
+ ocf_log info "Removing conflicting loopback $ifname."
+ if
+ echo "$ipaddr $netmask $broadcast $ifname" > "$VLDIR/$ipaddr"
+ then
+ : Saved loopback information in $VLDIR/$ipaddr
+ else
+ ocf_log err "Could not save conflicting loopback $ifname." \
+ "it will not be restored."
+ fi
+ delete_interface "$ipaddr" "$ifname" "$netmask"
+ # Forcibly remove the route (if it exists) to the loopback.
+ delete_route "$ipaddr" "$ifname"
+}
+
+#
+# On Linux systems the (hidden) loopback interface may
+# need to be restored if it has been taken down previously
+# by remove_conflicting_loopback()
+#
+restore_loopback() {
+ ipaddr="$1"
+
+ if [ -s "$VLDIR/$ipaddr" ]; then
+ ifinfo=`cat "$VLDIR/$ipaddr"`
+ ocf_log info "Restoring loopback IP Address " \
+ "$ifinfo."
+ add_interface $ifinfo
+ rm -f "$VLDIR/$ipaddr"
+ fi
+}
+
+add_ipv6_addrlabel() {
+ local cmd ipaddr value
+ ipaddr="$1"
+ value="$OCF_RESKEY_lvs_ipv6_addrlabel_value"
+
+ cmd="$IP2UTIL addrlabel add prefix $ipaddr label $value"
+ ocf_log info "Adding IPv6 address label prefix $ipaddr label $value"
+ ocf_run $cmd || ocf_log warn "$cmd failed."
+}
+
+delete_ipv6_addrlabel() {
+ local cmd ipaddr value
+ ipaddr="$1"
+ value="$OCF_RESKEY_lvs_ipv6_addrlabel_value"
+
+ cmd="$IP2UTIL addrlabel del prefix $ipaddr label $value"
+ ocf_run $cmd # an error can be ignored
+}
+
+is_infiniband() {
+ $IP2UTIL link show $NIC | grep link/infiniband >/dev/null
+}
+
+log_arp_sender() {
+ local cmdline
+ local output
+ local rc
+ cmdline="$@"
+
+ output=$($cmdline 2>&1)
+ rc=$?
+ if [ $rc -ne 0 ] && \
+ [ "$ARP_SENDER" != "libnet_arping" ] ; then
+ # libnet_arping always return an error as no answers
+ ocf_log err "Could not send gratuitous arps: rc=$rc"
+ fi
+ ocf_log $LOGLEVEL "$output"
+}
+
+# wrapper function to manage PID file to run arping in background
+run_with_pidfile() {
+ local cmdline
+ local pid
+ local rc
+
+ cmdline="$@"
+
+ $cmdline &
+ pid=$!
+ echo "$pid" > $SENDARPPIDFILE
+ wait $pid
+ rc=$?
+ rm -f $SENDARPPIDFILE
+ return $rc
+}
+
+build_arp_sender_cmd() {
+ case "$ARP_SENDER" in
+ send_arp)
+ if [ "x$IP_CIP" = "xyes" ] ; then
+ if [ x = "x$IF_MAC" ] ; then
+ MY_MAC=auto
+ else
+ # send_arp.linux should return without doing anything in this case
+ MY_MAC=`echo ${IF_MAC} | sed -e 's/://g'`
+ fi
+ else
+ MY_MAC=auto
+ fi
+
+ ARGS="$OCF_RESKEY_send_arp_opts -i $OCF_RESKEY_arp_interval -r $ARP_COUNT -p $SENDARPPIDFILE $NIC $OCF_RESKEY_ip $MY_MAC not_used not_used"
+ ARP_SENDER_CMD="$SENDARP $ARGS"
+ ;;
+ iputils_arping)
+ ARGS="$OCF_RESKEY_send_arp_opts -U -c $ARP_COUNT -I $NIC $OCF_RESKEY_ip"
+ ARP_SENDER_CMD="run_with_pidfile arping $ARGS"
+ ;;
+ libnet_arping)
+ ARGS="$OCF_RESKEY_send_arp_opts -U -c $ARP_COUNT -i $NIC -S $OCF_RESKEY_ip $OCF_RESKEY_ip"
+ ARP_SENDER_CMD="run_with_pidfile arping $ARGS"
+ ;;
+ ipoibarping)
+ ARGS="-q -c $ARP_COUNT -U -I $NIC $OCF_RESKEY_ip"
+ ARP_SENDER_CMD="ipoibarping $ARGS"
+ ;;
+ *)
+ # should not occur
+ ocf_exit_reason "unrecognized arp_sender value: $ARP_SENDER"
+ exit $OCF_ERR_GENERIC
+ ;;
+ esac
+}
+
+#
+# Send Unsolicited ARPs to update neighbor's ARP cache
+#
+run_arp_sender() {
+ if [ "x$1" = "xrefresh" ] ; then
+ ARP_COUNT=$OCF_RESKEY_arp_count_refresh
+ LOGLEVEL=debug
+ else
+ ARP_COUNT=$OCF_RESKEY_arp_count
+ LOGLEVEL=info
+ fi
+ if [ $ARP_COUNT -eq 0 ] ; then
+ return
+ fi
+
+ # do not need to send Gratuitous ARPs in the Cluster IP configuration
+ # except send_arp.libnet binary to retain the old behavior
+ if [ "x$IP_CIP" = "xyes" ] && \
+ [ "x$ARP_SENDER" != "xsend_arp" ] ; then
+ ocf_log info "Gratuitous ARPs are not sent in the Cluster IP configuration"
+ return
+ fi
+
+ # prepare arguments for each arp sender program
+ # $ARP_SENDER_CMD should be set
+ build_arp_sender_cmd
+
+ ocf_log $LOGLEVEL "$ARP_SENDER_CMD"
+
+ if ocf_is_true $OCF_RESKEY_arp_bg; then
+ log_arp_sender $ARP_SENDER_CMD &
+ else
+ log_arp_sender $ARP_SENDER_CMD
+ fi
+}
+
+log_send_ua() {
+ local cmdline
+ local output
+ local rc
+
+ cmdline="$@"
+ output=$($cmdline 2>&1)
+ rc=$?
+ if [ $rc -ne 0 ] ; then
+ ocf_log err "Could not send ICMPv6 Unsolicited Neighbor Advertisements: rc=$rc"
+ fi
+ ocf_log info "$output"
+ return $rc
+}
+
+#
+# Run send_ua to note send ICMPv6 Unsolicited Neighbor Advertisements.
+#
+run_send_ua() {
+ local i
+
+ # Duplicate Address Detection [DAD]
+ # Kernel will flag the IP as 'tentative' until it ensured that
+ # there is no duplicates.
+ # If there is, it will flag it as 'dadfailed'
+ for i in $(seq 1 10); do
+ ipstatus=$($IP2UTIL -o -f $FAMILY addr show dev $NIC to $OCF_RESKEY_ip/$NETMASK)
+ case "$ipstatus" in
+ *dadfailed*)
+ ocf_log err "IPv6 address collision $OCF_RESKEY_ip [DAD]"
+ $IP2UTIL -f $FAMILY addr del dev $NIC $OCF_RESKEY_ip/$NETMASK
+ if [ $? -ne 0 ]; then
+ ocf_log err "Could not delete IPv6 address"
+ fi
+ return $OCF_ERR_GENERIC
+ ;;
+ *tentative*)
+ if [ $i -eq 10 ]; then
+ ocf_log warn "IPv6 address : DAD is still in tentative"
+ fi
+ ;;
+ *)
+ break
+ ;;
+ esac
+ sleep 1
+ done
+ # Now the address should be usable
+
+ ARGS="-i $OCF_RESKEY_arp_interval -c $OCF_RESKEY_arp_count $OCF_RESKEY_ip $NETMASK $NIC"
+ ocf_log info "$SENDUA $ARGS"
+ if ocf_is_true $OCF_RESKEY_arp_bg; then
+ log_send_ua $SENDUA $ARGS &
+ else
+ log_send_ua $SENDUA $ARGS
+ fi
+}
+
+# Do we already serve this IP address on the given $NIC?
+#
+# returns:
+# ok = served (for CIP: + hash bucket)
+# partial = served and no hash bucket (CIP only)
+# partial2 = served and no CIP iptables rule
+# no = nothing
+#
+ip_served() {
+ if [ -z "$NIC" ]; then # no nic found or specified
+ echo "no"
+ return 0
+ fi
+
+ cur_nic="`find_interface $OCF_RESKEY_ip $NETMASK`"
+
+ if [ -z "$cur_nic" ]; then
+ echo "no"
+ return 0
+ fi
+
+ if [ -z "$IP_CIP" ]; then
+ for i in $cur_nic; do
+ # only mark as served when on the same interfaces as $NIC
+ [ "$i" = "$NIC" ] || continue
+ echo "ok"
+ return 0
+ done
+ # There used to be logic here to pretend "not served",
+ # if ${OCF_RESKEY_lvs_support} was enabled, and the IP was
+ # found active on "lo*" only. With lvs_support on, you should
+ # have NIC != lo, so thats already filtered
+ # by the continue above.
+
+ echo "no"
+ return 0
+ fi
+
+ # Special handling for the CIP:
+ if [ ! -e $IP_CIP_FILE ]; then
+ echo "partial2"
+ return 0
+ fi
+ if egrep -q "(^|,)${IP_INC_NO}(,|$)" $IP_CIP_FILE ; then
+ echo "ok"
+ return 0
+ else
+ echo "partial"
+ return 0
+ fi
+
+ exit $OCF_ERR_GENERIC
+}
+
+#######################################################################
+
+ip_usage() {
+ cat <<END
+usage: $0 {start|stop|status|monitor|validate-all|meta-data}
+
+Expects to have a fully populated OCF RA-compliant environment set.
+END
+}
+
+ip_start() {
+ if [ -z "$NIC" ]; then
+ ocf_exit_reason "No nic found or specified"
+ exit $OCF_ERR_CONFIGURED
+ fi
+
+ if [ -n "$IP_CIP" ]; then
+ # Cluster IPs need special processing when the first bucket
+ # is added to the node... take a lock to make sure only one
+ # process executes that code
+ ocf_take_lock $CIP_lockfile
+ ocf_release_lock_on_exit $CIP_lockfile
+ fi
+
+ #
+ # Do we already service this IP address on $NIC?
+ #
+ local ip_status=`ip_served`
+
+ if [ "$ip_status" = "ok" ]; then
+ exit $OCF_SUCCESS
+ fi
+
+ if [ -n "$IP_CIP" ] && ([ $ip_status = "no" ] || [ $ip_status = "partial2" ]); then
+ $MODPROBE ip_conntrack
+ $IPADDR2_CIP_IPTABLES -I INPUT -d $OCF_RESKEY_ip -i $NIC -j CLUSTERIP \
+ --new \
+ --clustermac $IF_MAC \
+ --total-nodes $IP_INC_GLOBAL \
+ --local-node $IP_INC_NO \
+ --hashmode $IP_CIP_HASH
+ if [ $? -ne 0 ]; then
+ ocf_exit_reason "iptables failed"
+ exit $OCF_ERR_GENERIC
+ fi
+ fi
+
+ if [ -n "$IP_CIP" ] && [ $ip_status = "partial" ]; then
+ echo "+$IP_INC_NO" >$IP_CIP_FILE
+ fi
+
+ if [ "$ip_status" = "no" ]; then
+ if ocf_is_true ${OCF_RESKEY_lvs_support}; then
+ for i in `find_interface $OCF_RESKEY_ip 32`; do
+ case $i in
+ lo*)
+ remove_conflicting_loopback $OCF_RESKEY_ip 32 255.255.255.255 lo
+ ;;
+ esac
+ done
+ fi
+
+ add_interface $OCF_RESKEY_ip $NETMASK ${BRDCAST:-none} $NIC $IFLABEL
+ rc=$?
+
+ if [ $rc -ne $OCF_SUCCESS ]; then
+ ocf_exit_reason "Failed to add $OCF_RESKEY_ip"
+ exit $rc
+ fi
+ fi
+
+ case $NIC in
+ lo*)
+ : no need to run send_arp on loopback
+ ;;
+ *)
+ if [ $FAMILY = "inet" ];then
+ run_arp_sender
+ else
+ if [ -x $SENDUA ]; then
+ run_send_ua
+ if [ $? -ne 0 ]; then
+ ocf_exit_reason "run_send_ua failed."
+ exit $OCF_ERR_GENERIC
+ fi
+ fi
+ fi
+ ;;
+ esac
+ exit $OCF_SUCCESS
+}
+
+ip_stop() {
+ local ip_del_if="yes"
+ if [ -n "$IP_CIP" ]; then
+ # Cluster IPs need special processing when the last bucket
+ # is removed from the node... take a lock to make sure only one
+ # process executes that code
+ ocf_take_lock $CIP_lockfile
+ ocf_release_lock_on_exit $CIP_lockfile
+ fi
+
+ if [ -f "$SENDARPPIDFILE" ] ; then
+ kill `cat "$SENDARPPIDFILE"`
+ if [ $? -ne 0 ]; then
+ ocf_log warn "Could not kill previously running send_arp for $OCF_RESKEY_ip"
+ else
+ ocf_log info "killed previously running send_arp for $OCF_RESKEY_ip"
+ fi
+ rm -f "$SENDARPPIDFILE"
+ fi
+ local ip_status=`ip_served`
+ ocf_log info "IP status = $ip_status, IP_CIP=$IP_CIP"
+
+ if [ $ip_status = "no" ]; then
+ : Requested interface not in use
+ exit $OCF_SUCCESS
+ fi
+
+ if [ -n "$IP_CIP" ] && [ $ip_status != "partial2" ]; then
+ if [ $ip_status = "partial" ]; then
+ exit $OCF_SUCCESS
+ fi
+ echo "-$IP_INC_NO" >$IP_CIP_FILE
+ if [ "x$(cat $IP_CIP_FILE)" = "x" ]; then
+ ocf_log info $OCF_RESKEY_ip, $IP_CIP_HASH
+ i=1
+ while [ $i -le $IP_INC_GLOBAL ]; do
+ ocf_log info $i
+ $IPADDR2_CIP_IPTABLES -D INPUT -d $OCF_RESKEY_ip -i $NIC -j CLUSTERIP \
+ --new \
+ --clustermac $IF_MAC \
+ --total-nodes $IP_INC_GLOBAL \
+ --local-node $i \
+ --hashmode $IP_CIP_HASH
+ i=`expr $i + 1`
+ done
+ else
+ ip_del_if="no"
+ fi
+ fi
+
+ if [ "$ip_del_if" = "yes" ]; then
+ delete_interface $OCF_RESKEY_ip $NIC $NETMASK
+ if [ $? -ne 0 ]; then
+ ocf_exit_reason "Unable to remove IP [${OCF_RESKEY_ip} from interface [ $NIC ]"
+ exit $OCF_ERR_GENERIC
+ fi
+
+ if ocf_is_true ${OCF_RESKEY_lvs_support}; then
+ restore_loopback "$OCF_RESKEY_ip"
+ fi
+ fi
+
+ exit $OCF_SUCCESS
+}
+
+ip_monitor() {
+ # TODO: Implement more elaborate monitoring like checking for
+ # interface health maybe via a daemon like FailSafe etc...
+
+ local ip_status=`ip_served`
+ case $ip_status in
+ ok)
+ run_arp_sender refresh
+ return $OCF_SUCCESS
+ ;;
+ partial|no|partial2)
+ exit $OCF_NOT_RUNNING
+ ;;
+ *)
+ # Errors on this interface?
+ return $OCF_ERR_GENERIC
+ ;;
+ esac
+}
+
+# make sure that we have something to send ARPs with
+set_send_arp_program() {
+ ARP_SENDER=send_arp
+ if [ -n "$OCF_RESKEY_arp_sender" ]; then
+ case "$OCF_RESKEY_arp_sender" in
+ send_arp)
+ check_binary $SENDARP
+ ;;
+ iputils_arping)
+ check_binary arping
+ ;;
+ libnet_arping)
+ check_binary arping
+ ;;
+ ipoibarping)
+ check_binary ipoibarping
+ ;;
+ *)
+ ocf_exit_reason "unrecognized arp_sender value: $OCF_RESKEY_arp_sender"
+ exit $OCF_ERR_CONFIGURED
+ ;;
+ esac
+ ARP_SENDER="$OCF_RESKEY_arp_sender"
+ else
+ if is_infiniband; then
+ ARP_SENDER=ipoibarping
+ if ! have_binary ipoibarping; then
+ [ "$__OCF_ACTION" = start ] &&
+ ocf_log warn "using send_arp for infiniband because ipoibarping is not available (set arp_sender to \"send_arp\" to suppress this message)"
+ check_binary $SENDARP
+ ARP_SENDER=send_arp
+ fi
+ fi
+ fi
+}
+
+ip_validate() {
+ check_binary $IP2UTIL
+ IP_CIP=
+
+ if [ -n "$OCF_RESKEY_network_namespace" ]; then
+ OCF_RESKEY_network_namespace= exec $IP2UTIL netns exec "$OCF_RESKEY_network_namespace" "$0" "$__OCF_ACTION"
+ fi
+
+ ip_init
+
+ set_send_arp_program
+
+ if [ -n "$IP_CIP" ]; then
+ if have_binary "$IPTABLES_LEGACY"; then
+ IPADDR2_CIP_IPTABLES="$IPTABLES_LEGACY"
+ fi
+ check_binary "$IPADDR2_CIP_IPTABLES"
+ check_binary $MODPROBE
+ fi
+
+# $BASEIP, $NETMASK, $NIC , $IP_INC_GLOBAL, and $BRDCAST have been checked within ip_init,
+# do not bother here.
+
+ if ocf_is_true "$OCF_RESKEY_unique_clone_address" &&
+ ! ocf_is_true "$OCF_RESKEY_CRM_meta_globally_unique"; then
+ ocf_exit_reason "unique_clone_address makes sense only with meta globally_unique set"
+ exit $OCF_ERR_CONFIGURED
+ fi
+
+ if ocf_is_decimal "$OCF_RESKEY_arp_interval" && [ $OCF_RESKEY_arp_interval -gt 0 ]; then
+ :
+ else
+ ocf_exit_reason "Invalid OCF_RESKEY_arp_interval [$OCF_RESKEY_arp_interval]"
+ exit $OCF_ERR_CONFIGURED
+ fi
+
+ if ocf_is_decimal "$OCF_RESKEY_arp_count" && [ $OCF_RESKEY_arp_count -gt 0 ]; then
+ :
+ else
+ ocf_exit_reason "Invalid OCF_RESKEY_arp_count [$OCF_RESKEY_arp_count]"
+ exit $OCF_ERR_CONFIGURED
+ fi
+
+ if [ -z "$OCF_RESKEY_preferred_lft" ]; then
+ ocf_exit_reason "Empty value is invalid for OCF_RESKEY_preferred_lft"
+ exit $OCF_ERR_CONFIGURED
+ fi
+
+ if [ -n "$IP_CIP" ]; then
+
+ local valid=1
+
+ case $IP_CIP_HASH in
+ sourceip|sourceip-sourceport|sourceip-sourceport-destport)
+ ;;
+ *)
+ ocf_exit_reason "Invalid OCF_RESKEY_clusterip_hash [$IP_CIP_HASH]"
+ exit $OCF_ERR_CONFIGURED
+ ;;
+ esac
+
+ if ocf_is_true ${OCF_RESKEY_lvs_support}; then
+ ocf_exit_reason "LVS and load sharing not advised to try"
+ exit $OCF_ERR_CONFIGURED
+ fi
+
+ case $IF_MAC in
+ [0-9a-zA-Z][13579bBdDfF][!0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z][!0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z][!0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z][!0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z][!0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z])
+ ;;
+ *)
+ valid=0
+ ;;
+ esac
+
+ if [ $valid -eq 0 ]; then
+ ocf_exit_reason "Invalid IF_MAC [$IF_MAC]"
+ exit $OCF_ERR_CONFIGURED
+ fi
+
+ fi
+}
+
+if ocf_is_true "$OCF_RESKEY_unique_clone_address"; then
+ prefix=`echo $OCF_RESKEY_ip | awk -F. '{print $1"."$2"."$3}'`
+ suffix=`echo $OCF_RESKEY_ip | awk -F. '{print $4}'`
+ suffix=`expr ${OCF_RESKEY_CRM_meta_clone:-0} + $suffix`
+ OCF_RESKEY_ip="$prefix.$suffix"
+fi
+
+case $__OCF_ACTION in
+meta-data) meta_data
+ ;;
+usage|help) ip_usage
+ exit $OCF_SUCCESS
+ ;;
+esac
+
+ip_validate
+
+case $__OCF_ACTION in
+start) ip_start
+ ;;
+stop) ip_stop
+ ;;
+status) ip_status=`ip_served`
+ if [ $ip_status = "ok" ]; then
+ echo "running"
+ exit $OCF_SUCCESS
+ else
+ echo "stopped"
+ exit $OCF_NOT_RUNNING
+ fi
+ ;;
+monitor) ip_monitor
+ ;;
+validate-all) ;;
+*) ip_usage
+ exit $OCF_ERR_UNIMPLEMENTED
+ ;;
+esac
+# vi:sw=4:ts=8: