1#!/usr/local/bin/bash 2# 3# $Id: IPaddr2.in,v 1.24 2006/08/09 13:01:54 lars Exp $ 4# 5# OCF Resource Agent compliant IPaddr2 script. 6# 7# Based on work by Tuomo Soini, ported to the OCF RA API by Lars 8# Marowsky-Brée. Implements Cluster Alias IP functionality too. 9# 10# Cluster Alias IP cleanup, fixes and testing by Michael Schwartzkopff 11# 12# 13# Copyright (c) 2003 Tuomo Soini 14# Copyright (c) 2004-2006 SUSE LINUX AG, Lars Marowsky-Brée 15# All Rights Reserved. 16# 17# This program is free software; you can redistribute it and/or modify 18# it under the terms of version 2 of the GNU General Public License as 19# published by the Free Software Foundation. 20# 21# This program is distributed in the hope that it would be useful, but 22# WITHOUT ANY WARRANTY; without even the implied warranty of 23# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 24# 25# Further, this software is distributed without any warranty that it is 26# free of the rightful claim of any third person regarding infringement 27# or the like. Any license provided herein, whether implied or 28# otherwise, applies only to this software file. Patent licenses, if 29# any, provided herein do not apply to combinations of this program with 30# other software, or any other product whatsoever. 31# 32# You should have received a copy of the GNU General Public License 33# along with this program; if not, write the Free Software Foundation, 34# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 35# 36# 37 38 39# TODO: 40# - There ought to be an ocf_run_cmd function which does all logging, 41# timeout handling etc for us 42# - Make this the standard IP address agent on Linux; the other 43# platforms simply should ignore the additional parameters OR can use 44# the legacy heartbeat resource script... 45# - Check LVS <-> clusterip incompatibilities. 46# 47# OCF parameters are as below 48# OCF_RESKEY_ip 49# OCF_RESKEY_broadcast 50# OCF_RESKEY_nic 51# OCF_RESKEY_cidr_netmask 52# OCF_RESKEY_iflabel 53# OCF_RESKEY_mac 54# OCF_RESKEY_clusterip_hash 55# OCF_RESKEY_arp_interval 56# OCF_RESKEY_arp_count 57# OCF_RESKEY_arp_bg 58# OCF_RESKEY_preferred_lft 59# 60# OCF_RESKEY_CRM_meta_clone 61# OCF_RESKEY_CRM_meta_clone_max 62 63 64####################################################################### 65# Initialization: 66 67: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} 68. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs 69. ${OCF_FUNCTIONS_DIR}/findif.sh 70 71# Defaults 72OCF_RESKEY_ip_default="" 73OCF_RESKEY_cidr_netmask_default="" 74OCF_RESKEY_broadcast_default="" 75OCF_RESKEY_iflabel_default="" 76OCF_RESKEY_cidr_netmask_default="" 77OCF_RESKEY_lvs_support_default=false 78OCF_RESKEY_lvs_ipv6_addrlabel_default=false 79OCF_RESKEY_lvs_ipv6_addrlabel_value_default=99 80OCF_RESKEY_clusterip_hash_default="sourceip-sourceport" 81OCF_RESKEY_mac_default="" 82OCF_RESKEY_unique_clone_address_default=false 83OCF_RESKEY_arp_interval_default=200 84OCF_RESKEY_arp_count_default=5 85OCF_RESKEY_arp_count_refresh_default=0 86OCF_RESKEY_arp_bg_default=true 87OCF_RESKEY_arp_sender_default="" 88OCF_RESKEY_send_arp_opts_default="" 89OCF_RESKEY_flush_routes_default="false" 90OCF_RESKEY_run_arping_default=false 91OCF_RESKEY_noprefixroute_default="false" 92OCF_RESKEY_preferred_lft_default="forever" 93OCF_RESKEY_network_namespace_default="" 94 95: ${OCF_RESKEY_ip=${OCF_RESKEY_ip_default}} 96: ${OCF_RESKEY_cidr_netmask=${OCF_RESKEY_cidr_netmask_default}} 97: ${OCF_RESKEY_broadcast=${OCF_RESKEY_broadcast_default}} 98: ${OCF_RESKEY_iflabel=${OCF_RESKEY_iflabel_default}} 99: ${OCF_RESKEY_lvs_support=${OCF_RESKEY_lvs_support_default}} 100: ${OCF_RESKEY_lvs_ipv6_addrlabel=${OCF_RESKEY_lvs_ipv6_addrlabel_default}} 101: ${OCF_RESKEY_lvs_ipv6_addrlabel_value=${OCF_RESKEY_lvs_ipv6_addrlabel_value_default}} 102: ${OCF_RESKEY_clusterip_hash=${OCF_RESKEY_clusterip_hash_default}} 103: ${OCF_RESKEY_mac=${OCF_RESKEY_mac_default}} 104: ${OCF_RESKEY_unique_clone_address=${OCF_RESKEY_unique_clone_address_default}} 105: ${OCF_RESKEY_arp_interval=${OCF_RESKEY_arp_interval_default}} 106: ${OCF_RESKEY_arp_count=${OCF_RESKEY_arp_count_default}} 107: ${OCF_RESKEY_arp_count_refresh=${OCF_RESKEY_arp_count_refresh_default}} 108: ${OCF_RESKEY_arp_bg=${OCF_RESKEY_arp_bg_default}} 109: ${OCF_RESKEY_arp_sender=${OCF_RESKEY_arp_sender_default}} 110: ${OCF_RESKEY_send_arp_opts=${OCF_RESKEY_send_arp_opts_default}} 111: ${OCF_RESKEY_flush_routes=${OCF_RESKEY_flush_routes_default}} 112: ${OCF_RESKEY_run_arping=${OCF_RESKEY_run_arping_default}} 113: ${OCF_RESKEY_noprefixroute=${OCF_RESKEY_noprefixroute_default}} 114: ${OCF_RESKEY_preferred_lft=${OCF_RESKEY_preferred_lft_default}} 115: ${OCF_RESKEY_network_namespace=${OCF_RESKEY_network_namespace_default}} 116 117####################################################################### 118 119SENDARP=$HA_BIN/send_arp 120SENDUA=$HA_BIN/send_ua 121FINDIF=findif 122VLDIR=$HA_RSCTMP 123SENDARPPIDDIR=$HA_RSCTMP 124CIP_lockfile=$HA_RSCTMP/IPaddr2-CIP-${OCF_RESKEY_ip} 125 126IPADDR2_CIP_IPTABLES=$IPTABLES 127 128####################################################################### 129 130meta_data() { 131 cat <<END 132<?xml version="1.0"?> 133<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd"> 134<resource-agent name="IPaddr2"> 135<version>1.0</version> 136 137<longdesc lang="en"> 138This Linux-specific resource manages IP alias IP addresses. 139It can add an IP alias, or remove one. 140In addition, it can implement Cluster Alias IP functionality 141if invoked as a clone resource. 142 143If used as a clone, "shared address with a trivial, stateless 144(autonomous) load-balancing/mutual exclusion on ingress" mode gets 145applied (as opposed to "assume resource uniqueness" mode otherwise). 146For that, Linux firewall (kernel and userspace) is assumed, and since 147recent distributions are ambivalent in plain "iptables" command to 148particular back-end resolution, "iptables-legacy" (when present) gets 149prioritized so as to avoid incompatibilities (note that respective 150ipt_CLUSTERIP firewall extension in use here is, at the same time, 151marked deprecated, yet said "legacy" layer can make it workable, 152literally, to this day) with "netfilter" one (as in "iptables-nft"). 153In that case, you should explicitly set clone-node-max >= 2, 154and/or clone-max < number of nodes. In case of node failure, 155clone instances need to be re-allocated on surviving nodes. 156This would not be possible if there is already an instance 157on those nodes, and clone-node-max=1 (which is the default). 158</longdesc> 159 160<shortdesc lang="en">Manages virtual IPv4 and IPv6 addresses (Linux specific version)</shortdesc> 161 162<parameters> 163<parameter name="ip" unique="1" required="1"> 164<longdesc lang="en"> 165The IPv4 (dotted quad notation) or IPv6 address (colon hexadecimal notation) 166example IPv4 "192.168.1.1". 167example IPv6 "2001:db8:DC28:0:0:FC57:D4C8:1FFF". 168</longdesc> 169<shortdesc lang="en">IPv4 or IPv6 address</shortdesc> 170<content type="string" default="${OCF_RESKEY_ip_default}" /> 171</parameter> 172<parameter name="nic" unique="0"> 173<longdesc lang="en"> 174The base network interface on which the IP address will be brought 175online. 176If left empty, the script will try and determine this from the 177routing table. 178 179Do NOT specify an alias interface in the form eth0:1 or anything here; 180rather, specify the base interface only. 181If you want a label, see the iflabel parameter. 182 183Prerequisite: 184 185There must be at least one static IP address, which is not managed by 186the cluster, assigned to the network interface. 187If you can not assign any static IP address on the interface, 188modify this kernel parameter: 189 190sysctl -w net.ipv4.conf.all.promote_secondaries=1 # (or per device) 191</longdesc> 192<shortdesc lang="en">Network interface</shortdesc> 193<content type="string"/> 194</parameter> 195 196<parameter name="cidr_netmask"> 197<longdesc lang="en"> 198The netmask for the interface in CIDR format 199(e.g., 24 and not 255.255.255.0) 200 201If unspecified, the script will also try to determine this from the 202routing table. 203</longdesc> 204<shortdesc lang="en">CIDR netmask</shortdesc> 205<content type="string" default="${OCF_RESKEY_cidr_netmask_default}"/> 206</parameter> 207 208<parameter name="broadcast"> 209<longdesc lang="en"> 210Broadcast address associated with the IP. It is possible to use the 211special symbols '+' and '-' instead of the broadcast address. In this 212case, the broadcast address is derived by setting/resetting the host 213bits of the interface prefix. 214</longdesc> 215<shortdesc lang="en">Broadcast address</shortdesc> 216<content type="string" default="${OCF_RESKEY_broadcast_default}"/> 217</parameter> 218 219<parameter name="iflabel"> 220<longdesc lang="en"> 221You can specify an additional label for your IP address here. 222This label is appended to your interface name. 223 224The kernel allows alphanumeric labels up to a maximum length of 15 225characters including the interface name and colon (e.g. eth0:foobar1234) 226 227A label can be specified in nic parameter but it is deprecated. 228If a label is specified in nic name, this parameter has no effect. 229</longdesc> 230<shortdesc lang="en">Interface label</shortdesc> 231<content type="string" default="${OCF_RESKEY_iflabel_default}"/> 232</parameter> 233 234<parameter name="lvs_support"> 235<longdesc lang="en"> 236Enable support for LVS Direct Routing configurations. In case a IP 237address is stopped, only move it to the loopback device to allow the 238local node to continue to service requests, but no longer advertise it 239on the network. 240 241Notes for IPv6: 242It is not necessary to enable this option on IPv6. 243Instead, enable 'lvs_ipv6_addrlabel' option for LVS-DR usage on IPv6. 244</longdesc> 245<shortdesc lang="en">Enable support for LVS DR</shortdesc> 246<content type="boolean" default="${OCF_RESKEY_lvs_support_default}"/> 247</parameter> 248 249<parameter name="lvs_ipv6_addrlabel"> 250<longdesc lang="en"> 251Enable adding IPv6 address label so IPv6 traffic originating from 252the address's interface does not use this address as the source. 253This is necessary for LVS-DR health checks to realservers to work. Without it, 254the most recently added IPv6 address (probably the address added by IPaddr2) 255will be used as the source address for IPv6 traffic from that interface and 256since that address exists on loopback on the realservers, the realserver 257response to pings/connections will never leave its loopback. 258See RFC3484 for the detail of the source address selection. 259 260See also 'lvs_ipv6_addrlabel_value' parameter. 261</longdesc> 262<shortdesc lang="en">Enable adding IPv6 address label.</shortdesc> 263<content type="boolean" default="${OCF_RESKEY_lvs_ipv6_addrlabel_default}"/> 264</parameter> 265 266<parameter name="lvs_ipv6_addrlabel_value"> 267<longdesc lang="en"> 268Specify IPv6 address label value used when 'lvs_ipv6_addrlabel' is enabled. 269The value should be an unused label in the policy table 270which is shown by 'ip addrlabel list' command. 271You would rarely need to change this parameter. 272</longdesc> 273<shortdesc lang="en">IPv6 address label value.</shortdesc> 274<content type="integer" default="${OCF_RESKEY_lvs_ipv6_addrlabel_value_default}"/> 275</parameter> 276 277<parameter name="mac"> 278<longdesc lang="en"> 279Set the interface MAC address explicitly. Currently only used in case of 280the Cluster IP Alias. Leave empty to chose automatically. 281 282</longdesc> 283<shortdesc lang="en">Cluster IP MAC address</shortdesc> 284<content type="string" default="${OCF_RESKEY_mac_default}"/> 285</parameter> 286 287<parameter name="clusterip_hash"> 288<longdesc lang="en"> 289Specify the hashing algorithm used for the Cluster IP functionality. 290 291</longdesc> 292<shortdesc lang="en">Cluster IP hashing function</shortdesc> 293<content type="string" default="${OCF_RESKEY_clusterip_hash_default}"/> 294</parameter> 295 296<parameter name="unique_clone_address"> 297<longdesc lang="en"> 298If true, add the clone ID to the supplied value of IP to create 299a unique address to manage 300</longdesc> 301<shortdesc lang="en">Create a unique address for cloned instances</shortdesc> 302<content type="boolean" default="${OCF_RESKEY_unique_clone_address_default}"/> 303</parameter> 304 305<parameter name="arp_interval"> 306<longdesc lang="en"> 307Specify the interval between unsolicited ARP packets in milliseconds. 308 309This parameter is deprecated and used for the backward compatibility only. 310It is effective only for the send_arp binary which is built with libnet, 311and send_ua for IPv6. It has no effect for other arp_sender. 312</longdesc> 313<shortdesc lang="en">ARP packet interval in ms (deprecated)</shortdesc> 314<content type="integer" default="${OCF_RESKEY_arp_interval_default}"/> 315</parameter> 316 317<parameter name="arp_count"> 318<longdesc lang="en"> 319Number of unsolicited ARP packets to send at resource initialization. 320</longdesc> 321<shortdesc lang="en">ARP packet count sent during initialization</shortdesc> 322<content type="integer" default="${OCF_RESKEY_arp_count_default}"/> 323</parameter> 324 325<parameter name="arp_count_refresh"> 326<longdesc lang="en"> 327Number of unsolicited ARP packets to send during resource monitoring. Doing 328so helps mitigate issues of stuck ARP caches resulting from split-brain 329situations. 330</longdesc> 331<shortdesc lang="en">ARP packet count sent during monitoring</shortdesc> 332<content type="integer" default="${OCF_RESKEY_arp_count_refresh_default}"/> 333</parameter> 334 335<parameter name="arp_bg"> 336<longdesc lang="en"> 337Whether or not to send the ARP packets in the background. 338</longdesc> 339<shortdesc lang="en">ARP from background</shortdesc> 340<content type="string" default="${OCF_RESKEY_arp_bg_default}"/> 341</parameter> 342 343<parameter name="arp_sender"> 344<longdesc lang="en"> 345The program to send ARP packets with on start. Available options are: 346 - send_arp: default 347 - ipoibarping: default for infiniband interfaces if ipoibarping is available 348 - iputils_arping: use arping in iputils package 349 - libnet_arping: use another variant of arping based on libnet 350</longdesc> 351<shortdesc lang="en">ARP sender</shortdesc> 352<content type="string" default="${OCF_RESKEY_arp_sender_default}"/> 353</parameter> 354 355<parameter name="send_arp_opts"> 356<longdesc lang="en"> 357Extra options to pass to the arp_sender program. 358Available options are vary depending on which arp_sender is used. 359 360A typical use case is specifying '-A' for iputils_arping to use 361ARP REPLY instead of ARP REQUEST as Gratuitous ARPs. 362</longdesc> 363<shortdesc lang="en">Options for ARP sender</shortdesc> 364<content type="string" default="${OCF_RESKEY_send_arp_opts_default}"/> 365</parameter> 366 367<parameter name="flush_routes"> 368<longdesc lang="en"> 369Flush the routing table on stop. This is for 370applications which use the cluster IP address 371and which run on the same physical host that the 372IP address lives on. The Linux kernel may force that 373application to take a shortcut to the local loopback 374interface, instead of the interface the address 375is really bound to. Under those circumstances, an 376application may, somewhat unexpectedly, continue 377to use connections for some time even after the 378IP address is deconfigured. Set this parameter in 379order to immediately disable said shortcut when the 380IP address goes away. 381</longdesc> 382<shortdesc lang="en">Flush kernel routing table on stop</shortdesc> 383<content type="boolean" default="${OCF_RESKEY_flush_routes_default}"/> 384</parameter> 385 386<parameter name="run_arping"> 387<longdesc lang="en"> 388Whether or not to run arping for IPv4 collision detection check. 389</longdesc> 390<shortdesc lang="en">Run arping for IPv4 collision detection check</shortdesc> 391<content type="string" default="${OCF_RESKEY_run_arping_default}"/> 392</parameter> 393 394<parameter name="noprefixroute"> 395<longdesc lang="en"> 396Use noprefixroute flag (see 'man ip-address'). 397</longdesc> 398<shortdesc lang="en">Use noprefixroute flag</shortdesc> 399<content type="string" default="${OCF_RESKEY_noprefixroute_default}"/> 400</parameter> 401 402<parameter name="preferred_lft"> 403<longdesc lang="en"> 404For IPv6, set the preferred lifetime of the IP address. 405This can be used to ensure that the created IP address will not 406be used as a source address for routing. 407Expects a value as specified in section 5.5.4 of RFC 4862. 408</longdesc> 409<shortdesc lang="en">IPv6 preferred lifetime</shortdesc> 410<content type="string" default="${OCF_RESKEY_preferred_lft_default}"/> 411</parameter> 412 413<parameter name="network_namespace"> 414<longdesc lang="en"> 415Specifies the network namespace to operate within. 416The namespace must already exist, and the interface to be used must be within 417the namespace. 418</longdesc> 419<shortdesc lang="en">Network namespace to use</shortdesc> 420<content type="string" default="${OCF_RESKEY_network_namespace_default}"/> 421</parameter> 422</parameters> 423 424<actions> 425<action name="start" timeout="20s" /> 426<action name="stop" timeout="20s" /> 427<action name="status" depth="0" timeout="20s" interval="10s" /> 428<action name="monitor" depth="0" timeout="20s" interval="10s" /> 429<action name="meta-data" timeout="5s" /> 430<action name="validate-all" timeout="20s" /> 431</actions> 432</resource-agent> 433END 434 435 exit $OCF_SUCCESS 436} 437 438ip_init() { 439 local rc 440 441 if [ X`uname -s` != "XLinux" ]; then 442 ocf_exit_reason "IPaddr2 only supported Linux." 443 exit $OCF_ERR_INSTALLED 444 fi 445 446 if [ X"$OCF_RESKEY_ip" = "X" ] && [ "$__OCF_ACTION" != "stop" ]; then 447 ocf_exit_reason "IP address (the ip parameter) is mandatory" 448 exit $OCF_ERR_CONFIGURED 449 fi 450 451 if 452 case $__OCF_ACTION in 453 start|stop) ocf_is_root;; 454 *) true;; 455 esac 456 then 457 : YAY! 458 else 459 ocf_exit_reason "You must be root for $__OCF_ACTION operation." 460 exit $OCF_ERR_PERM 461 fi 462 463 BASEIP="$OCF_RESKEY_ip" 464 BRDCAST="$OCF_RESKEY_broadcast" 465 NIC="$OCF_RESKEY_nic" 466 # Note: We had a version out there for a while which used 467 # netmask instead of cidr_netmask. Don't remove this aliasing code! 468 if 469 [ ! -z "$OCF_RESKEY_netmask" -a -z "$OCF_RESKEY_cidr_netmask" ] 470 then 471 OCF_RESKEY_cidr_netmask=$OCF_RESKEY_netmask 472 export OCF_RESKEY_cidr_netmask 473 fi 474 NETMASK="$OCF_RESKEY_cidr_netmask" 475 IFLABEL="$OCF_RESKEY_iflabel" 476 IF_MAC="$OCF_RESKEY_mac" 477 478 IP_INC_GLOBAL=${OCF_RESKEY_CRM_meta_clone_max:-1} 479 IP_INC_NO=`expr ${OCF_RESKEY_CRM_meta_clone:-0} + 1` 480 481 if ocf_is_true ${OCF_RESKEY_lvs_support} && [ $IP_INC_GLOBAL -gt 1 ]; then 482 ocf_exit_reason "LVS and load sharing do not go together well" 483 exit $OCF_ERR_CONFIGURED 484 fi 485 486 if ocf_is_decimal "$IP_INC_GLOBAL" && [ $IP_INC_GLOBAL -gt 0 ]; then 487 : 488 else 489 ocf_exit_reason "Invalid meta-attribute clone_max [$IP_INC_GLOBAL], should be positive integer" 490 exit $OCF_ERR_CONFIGURED 491 fi 492 493 echo $OCF_RESKEY_ip | grep -qs ":" 494 if [ $? -ne 0 ];then 495 FAMILY=inet 496 if ocf_is_true $OCF_RESKEY_lvs_ipv6_addrlabel ;then 497 ocf_exit_reason "IPv4 does not support lvs_ipv6_addrlabel" 498 exit $OCF_ERR_CONFIGURED 499 fi 500 else 501 FAMILY=inet6 502 # address sanitization defined in RFC5952 503 SANITIZED_IP=$($IP2UTIL route get $OCF_RESKEY_ip 2> /dev/null | awk '$1~/:/ {print $1} $2~/:/ {print $2}') 504 if [ -n "$SANITIZED_IP" ]; then 505 OCF_RESKEY_ip="$SANITIZED_IP" 506 fi 507 508 if ocf_is_true $OCF_RESKEY_lvs_support ;then 509 ocf_exit_reason "The IPv6 does not support lvs_support" 510 exit $OCF_ERR_CONFIGURED 511 fi 512 if ocf_is_true $OCF_RESKEY_lvs_ipv6_addrlabel ;then 513 if ocf_is_decimal "$OCF_RESKEY_lvs_ipv6_addrlabel_value" && [ $OCF_RESKEY_lvs_ipv6_addrlabel_value -ge 0 ]; then 514 : 515 else 516 ocf_exit_reason "Invalid lvs_ipv6_addrlabel_value [$OCF_RESKEY_lvs_ipv6_addrlabel_value], should be positive integer" 517 exit $OCF_ERR_CONFIGURED 518 fi 519 fi 520 fi 521 522 # support nic:iflabel format in nic parameter 523 case $NIC in 524 *:*) 525 IFLABEL=`echo $NIC | sed 's/[^:]*://'` 526 NIC=`echo $NIC | sed 's/:.*//'` 527 # only the base name should be passed to findif 528 OCF_RESKEY_nic=$NIC 529 ;; 530 esac 531 532 # $FINDIF takes its parameters from the environment 533 # 534 NICINFO=`$FINDIF` 535 rc=$? 536 if 537 [ $rc -eq 0 ] 538 then 539 NICINFO=`echo "$NICINFO" | sed -e 's/netmask\ //;s/broadcast\ //'` 540 NIC=`echo "$NICINFO" | cut -d" " -f1` 541 NETMASK=`echo "$NICINFO" | cut -d" " -f2` 542 BRDCAST=`echo "$NICINFO" | cut -d" " -f3` 543 else 544 # findif couldn't find the interface 545 if ocf_is_probe; then 546 ocf_log info "[$FINDIF] failed" 547 exit $OCF_NOT_RUNNING 548 elif [ "$__OCF_ACTION" = stop ]; then 549 ocf_log warn "[$FINDIF] failed" 550 exit $OCF_SUCCESS 551 else 552 ocf_exit_reason "[$FINDIF] failed" 553 exit $rc 554 fi 555 fi 556 557 SENDARPPIDFILE="$SENDARPPIDDIR/send_arp-$OCF_RESKEY_ip" 558 559 if [ -n "$IFLABEL" ]; then 560 IFLABEL=${NIC}:${IFLABEL} 561 if [ ${#IFLABEL} -gt 15 ]; then 562 ocf_exit_reason "Interface label [$IFLABEL] exceeds maximum character limit of 15" 563 exit $OCF_ERR_CONFIGURED 564 fi 565 fi 566 567 if [ "$IP_INC_GLOBAL" -gt 1 ] && ! ocf_is_true "$OCF_RESKEY_unique_clone_address"; then 568 IP_CIP="yes" 569 IP_CIP_HASH="${OCF_RESKEY_clusterip_hash}" 570 if [ -z "$IF_MAC" ]; then 571 # Choose a MAC 572 # 1. Concatenate some input together 573 # 2. This doesn't need to be a cryptographically 574 # secure hash. 575 # 3. Drop everything after the first 6 octets (12 chars) 576 # 4. Delimit the octets with ':' 577 # 5. Make sure the first octet is odd, 578 # so the result is a multicast MAC 579 IF_MAC=`echo $OCF_RESKEY_ip $NETMASK $BRDCAST | \ 580 md5 | \ 581 sed -e 's#\(............\).*#\1#' \ 582 -e 's#..#&:#g; s#:$##' \ 583 -e 's#^\(.\)[02468aAcCeE]#\11#'` 584 fi 585 IP_CIP_FILE="/proc/net/ipt_CLUSTERIP/$OCF_RESKEY_ip" 586 fi 587} 588 589# 590# Find out which interfaces serve the given IP address and netmask. 591# The arguments are an IP address and a netmask. 592# Its output are interface names devided by spaces (e.g., "eth0 eth1"). 593# 594find_interface() { 595 local ipaddr="$1" 596 local netmask="$2" 597 598 # 599 # List interfaces but exclude FreeS/WAN ipsecN virtual interfaces 600 # 601 local iface="`$IP2UTIL -o -f $FAMILY addr show \ 602 | grep "\ $ipaddr/$netmask" \ 603 | cut -d ' ' -f2 \ 604 | grep -v '^ipsec[0-9][0-9]*$'`" 605 606 echo "$iface" 607 return 0 608} 609 610# 611# Delete an interface 612# 613delete_interface () { 614 ipaddr="$1" 615 iface="$2" 616 netmask="$3" 617 618 CMD="$IP2UTIL -f $FAMILY addr delete $ipaddr/$netmask dev $iface" 619 620 ocf_run $CMD || return $OCF_ERR_GENERIC 621 622 if ocf_is_true $OCF_RESKEY_flush_routes; then 623 ocf_run $IP2UTIL route flush cache 624 fi 625 626 if [ "$FAMILY" = "inet6" ] && ocf_is_true $OCF_RESKEY_lvs_ipv6_addrlabel ;then 627 delete_ipv6_addrlabel $ipaddr 628 fi 629 630 return $OCF_SUCCESS 631} 632 633# 634# Add an interface 635# 636add_interface () { 637 local cmd msg ipaddr netmask broadcast iface label 638 639 ipaddr="$1" 640 netmask="$2" 641 broadcast="$3" 642 iface="$4" 643 label="$5" 644 645 if [ "$FAMILY" = "inet" ] && ocf_is_true $OCF_RESKEY_run_arping && 646 check_binary arping; then 647 arping -q -c 2 -w 3 -D -I $iface $ipaddr 648 if [ $? = 1 ]; then 649 ocf_log err "IPv4 address collision $ipaddr [DAD]" 650 return $OCF_ERR_GENERIC 651 fi 652 fi 653 654 if [ "$FAMILY" = "inet6" ] && ocf_is_true $OCF_RESKEY_lvs_ipv6_addrlabel ;then 655 add_ipv6_addrlabel $ipaddr 656 fi 657 658 cmd="$IP2UTIL -f $FAMILY addr add $ipaddr/$netmask dev $iface" 659 msg="Adding $FAMILY address $ipaddr/$netmask to device $iface" 660 if [ "$broadcast" != "none" ]; then 661 cmd="$IP2UTIL -f $FAMILY addr add $ipaddr/$netmask brd $broadcast dev $iface" 662 msg="Adding $FAMILY address $ipaddr/$netmask with broadcast address $broadcast to device $iface" 663 fi 664 665 if ocf_is_true "${OCF_RESKEY_noprefixroute}"; then 666 cmd="$cmd noprefixroute" 667 msg="${msg} (with noprefixroute)" 668 fi 669 670 if [ ! -z "$label" ]; then 671 cmd="$cmd label $label" 672 msg="${msg} (with label $label)" 673 fi 674 if [ "$FAMILY" = "inet6" ] ;then 675 cmd="$cmd preferred_lft $OCF_RESKEY_preferred_lft" 676 msg="${msg} (with preferred_lft $OCF_RESKEY_preferred_lft)" 677 fi 678 679 ocf_log info "$msg" 680 ocf_run $cmd || return $OCF_ERR_GENERIC 681 682 msg="Bringing device $iface up" 683 cmd="$IP2UTIL link set $iface up" 684 ocf_log info "$msg" 685 ocf_run $cmd || return $OCF_ERR_GENERIC 686 687 return $OCF_SUCCESS 688} 689 690# 691# Delete a route 692# 693delete_route () { 694 prefix="$1" 695 iface="$2" 696 697 CMD="$IP2UTIL route delete $prefix dev $iface" 698 699 ocf_log info "$CMD" 700 $CMD 701 702 return $? 703} 704 705# On Linux systems the (hidden) loopback interface may 706# conflict with the requested IP address. If so, this 707# unoriginal code will remove the offending loopback address 708# and save it in VLDIR so it can be added back in later 709# when the IPaddr is released. 710# 711# TODO: This is very ugly and should be controlled by an additional 712# instance parameter. Or even: multi-state, with the IP only being 713# "active" on the master!? 714# 715remove_conflicting_loopback() { 716 ipaddr="$1" 717 netmask="$2" 718 broadcast="$3" 719 ifname="$4" 720 721 ocf_log info "Removing conflicting loopback $ifname." 722 if 723 echo "$ipaddr $netmask $broadcast $ifname" > "$VLDIR/$ipaddr" 724 then 725 : Saved loopback information in $VLDIR/$ipaddr 726 else 727 ocf_log err "Could not save conflicting loopback $ifname." \ 728 "it will not be restored." 729 fi 730 delete_interface "$ipaddr" "$ifname" "$netmask" 731 # Forcibly remove the route (if it exists) to the loopback. 732 delete_route "$ipaddr" "$ifname" 733} 734 735# 736# On Linux systems the (hidden) loopback interface may 737# need to be restored if it has been taken down previously 738# by remove_conflicting_loopback() 739# 740restore_loopback() { 741 ipaddr="$1" 742 743 if [ -s "$VLDIR/$ipaddr" ]; then 744 ifinfo=`cat "$VLDIR/$ipaddr"` 745 ocf_log info "Restoring loopback IP Address " \ 746 "$ifinfo." 747 add_interface $ifinfo 748 rm -f "$VLDIR/$ipaddr" 749 fi 750} 751 752add_ipv6_addrlabel() { 753 local cmd ipaddr value 754 ipaddr="$1" 755 value="$OCF_RESKEY_lvs_ipv6_addrlabel_value" 756 757 cmd="$IP2UTIL addrlabel add prefix $ipaddr label $value" 758 ocf_log info "Adding IPv6 address label prefix $ipaddr label $value" 759 ocf_run $cmd || ocf_log warn "$cmd failed." 760} 761 762delete_ipv6_addrlabel() { 763 local cmd ipaddr value 764 ipaddr="$1" 765 value="$OCF_RESKEY_lvs_ipv6_addrlabel_value" 766 767 cmd="$IP2UTIL addrlabel del prefix $ipaddr label $value" 768 ocf_run $cmd # an error can be ignored 769} 770 771is_infiniband() { 772 $IP2UTIL link show $NIC | grep link/infiniband >/dev/null 773} 774 775log_arp_sender() { 776 local cmdline 777 local output 778 local rc 779 cmdline="$@" 780 781 output=$($cmdline 2>&1) 782 rc=$? 783 if [ $rc -ne 0 ] && \ 784 [ "$ARP_SENDER" != "libnet_arping" ] ; then 785 # libnet_arping always return an error as no answers 786 ocf_log err "Could not send gratuitous arps: rc=$rc" 787 fi 788 ocf_log $LOGLEVEL "$output" 789} 790 791# wrapper function to manage PID file to run arping in background 792run_with_pidfile() { 793 local cmdline 794 local pid 795 local rc 796 797 cmdline="$@" 798 799 $cmdline & 800 pid=$! 801 echo "$pid" > $SENDARPPIDFILE 802 wait $pid 803 rc=$? 804 rm -f $SENDARPPIDFILE 805 return $rc 806} 807 808build_arp_sender_cmd() { 809 case "$ARP_SENDER" in 810 send_arp) 811 if [ "x$IP_CIP" = "xyes" ] ; then 812 if [ x = "x$IF_MAC" ] ; then 813 MY_MAC=auto 814 else 815 # send_arp.linux should return without doing anything in this case 816 MY_MAC=`echo ${IF_MAC} | sed -e 's/://g'` 817 fi 818 else 819 MY_MAC=auto 820 fi 821 822 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" 823 ARP_SENDER_CMD="$SENDARP $ARGS" 824 ;; 825 iputils_arping) 826 ARGS="$OCF_RESKEY_send_arp_opts -U -c $ARP_COUNT -I $NIC $OCF_RESKEY_ip" 827 ARP_SENDER_CMD="run_with_pidfile arping $ARGS" 828 ;; 829 libnet_arping) 830 ARGS="$OCF_RESKEY_send_arp_opts -U -c $ARP_COUNT -i $NIC -S $OCF_RESKEY_ip $OCF_RESKEY_ip" 831 ARP_SENDER_CMD="run_with_pidfile arping $ARGS" 832 ;; 833 ipoibarping) 834 ARGS="-q -c $ARP_COUNT -U -I $NIC $OCF_RESKEY_ip" 835 ARP_SENDER_CMD="ipoibarping $ARGS" 836 ;; 837 *) 838 # should not occur 839 ocf_exit_reason "unrecognized arp_sender value: $ARP_SENDER" 840 exit $OCF_ERR_GENERIC 841 ;; 842 esac 843} 844 845# 846# Send Unsolicited ARPs to update neighbor's ARP cache 847# 848run_arp_sender() { 849 if [ "x$1" = "xrefresh" ] ; then 850 ARP_COUNT=$OCF_RESKEY_arp_count_refresh 851 LOGLEVEL=debug 852 else 853 ARP_COUNT=$OCF_RESKEY_arp_count 854 LOGLEVEL=info 855 fi 856 if [ $ARP_COUNT -eq 0 ] ; then 857 return 858 fi 859 860 # do not need to send Gratuitous ARPs in the Cluster IP configuration 861 # except send_arp.libnet binary to retain the old behavior 862 if [ "x$IP_CIP" = "xyes" ] && \ 863 [ "x$ARP_SENDER" != "xsend_arp" ] ; then 864 ocf_log info "Gratuitous ARPs are not sent in the Cluster IP configuration" 865 return 866 fi 867 868 # prepare arguments for each arp sender program 869 # $ARP_SENDER_CMD should be set 870 build_arp_sender_cmd 871 872 ocf_log $LOGLEVEL "$ARP_SENDER_CMD" 873 874 if ocf_is_true $OCF_RESKEY_arp_bg; then 875 log_arp_sender $ARP_SENDER_CMD & 876 else 877 log_arp_sender $ARP_SENDER_CMD 878 fi 879} 880 881 882# 883# Run send_ua to note send ICMPv6 Unsolicited Neighbor Advertisements. 884# 885run_send_ua() { 886 local i 887 888 # Duplicate Address Detection [DAD] 889 # Kernel will flag the IP as 'tentative' until it ensured that 890 # there is no duplicates. 891 # If there is, it will flag it as 'dadfailed' 892 for i in $(seq 1 10); do 893 ipstatus=$($IP2UTIL -o -f $FAMILY addr show dev $NIC to $OCF_RESKEY_ip/$NETMASK) 894 case "$ipstatus" in 895 *dadfailed*) 896 ocf_log err "IPv6 address collision $OCF_RESKEY_ip [DAD]" 897 $IP2UTIL -f $FAMILY addr del dev $NIC $OCF_RESKEY_ip/$NETMASK 898 if [ $? -ne 0 ]; then 899 ocf_log err "Could not delete IPv6 address" 900 fi 901 return $OCF_ERR_GENERIC 902 ;; 903 *tentative*) 904 if [ $i -eq 10 ]; then 905 ocf_log warn "IPv6 address : DAD is still in tentative" 906 fi 907 ;; 908 *) 909 break 910 ;; 911 esac 912 sleep 1 913 done 914 # Now the address should be usable 915 916 ARGS="-i $OCF_RESKEY_arp_interval -c $OCF_RESKEY_arp_count $OCF_RESKEY_ip $NETMASK $NIC" 917 ocf_log info "$SENDUA $ARGS" 918 $SENDUA $ARGS || ocf_log err "Could not send ICMPv6 Unsolicited Neighbor Advertisements." 919} 920 921# Do we already serve this IP address on the given $NIC? 922# 923# returns: 924# ok = served (for CIP: + hash bucket) 925# partial = served and no hash bucket (CIP only) 926# partial2 = served and no CIP iptables rule 927# no = nothing 928# 929ip_served() { 930 if [ -z "$NIC" ]; then # no nic found or specified 931 echo "no" 932 return 0 933 fi 934 935 cur_nic="`find_interface $OCF_RESKEY_ip $NETMASK`" 936 937 if [ -z "$cur_nic" ]; then 938 echo "no" 939 return 0 940 fi 941 942 if [ -z "$IP_CIP" ]; then 943 for i in $cur_nic; do 944 # only mark as served when on the same interfaces as $NIC 945 [ "$i" = "$NIC" ] || continue 946 echo "ok" 947 return 0 948 done 949 # There used to be logic here to pretend "not served", 950 # if ${OCF_RESKEY_lvs_support} was enabled, and the IP was 951 # found active on "lo*" only. With lvs_support on, you should 952 # have NIC != lo, so thats already filtered 953 # by the continue above. 954 955 echo "no" 956 return 0 957 fi 958 959 # Special handling for the CIP: 960 if [ ! -e $IP_CIP_FILE ]; then 961 echo "partial2" 962 return 0 963 fi 964 if egrep -q "(^|,)${IP_INC_NO}(,|$)" $IP_CIP_FILE ; then 965 echo "ok" 966 return 0 967 else 968 echo "partial" 969 return 0 970 fi 971 972 exit $OCF_ERR_GENERIC 973} 974 975####################################################################### 976 977ip_usage() { 978 cat <<END 979usage: $0 {start|stop|status|monitor|validate-all|meta-data} 980 981Expects to have a fully populated OCF RA-compliant environment set. 982END 983} 984 985ip_start() { 986 if [ -z "$NIC" ]; then 987 ocf_exit_reason "No nic found or specified" 988 exit $OCF_ERR_CONFIGURED 989 fi 990 991 if [ -n "$IP_CIP" ]; then 992 # Cluster IPs need special processing when the first bucket 993 # is added to the node... take a lock to make sure only one 994 # process executes that code 995 ocf_take_lock $CIP_lockfile 996 ocf_release_lock_on_exit $CIP_lockfile 997 fi 998 999 # 1000 # Do we already service this IP address on $NIC? 1001 # 1002 local ip_status=`ip_served` 1003 1004 if [ "$ip_status" = "ok" ]; then 1005 exit $OCF_SUCCESS 1006 fi 1007 1008 if [ -n "$IP_CIP" ] && ([ $ip_status = "no" ] || [ $ip_status = "partial2" ]); then 1009 $MODPROBE ip_conntrack 1010 $IPADDR2_CIP_IPTABLES -I INPUT -d $OCF_RESKEY_ip -i $NIC -j CLUSTERIP \ 1011 --new \ 1012 --clustermac $IF_MAC \ 1013 --total-nodes $IP_INC_GLOBAL \ 1014 --local-node $IP_INC_NO \ 1015 --hashmode $IP_CIP_HASH 1016 if [ $? -ne 0 ]; then 1017 ocf_exit_reason "iptables failed" 1018 exit $OCF_ERR_GENERIC 1019 fi 1020 fi 1021 1022 if [ -n "$IP_CIP" ] && [ $ip_status = "partial" ]; then 1023 echo "+$IP_INC_NO" >$IP_CIP_FILE 1024 fi 1025 1026 if [ "$ip_status" = "no" ]; then 1027 if ocf_is_true ${OCF_RESKEY_lvs_support}; then 1028 for i in `find_interface $OCF_RESKEY_ip 32`; do 1029 case $i in 1030 lo*) 1031 remove_conflicting_loopback $OCF_RESKEY_ip 32 255.255.255.255 lo 1032 ;; 1033 esac 1034 done 1035 fi 1036 1037 add_interface $OCF_RESKEY_ip $NETMASK ${BRDCAST:-none} $NIC $IFLABEL 1038 rc=$? 1039 1040 if [ $rc -ne $OCF_SUCCESS ]; then 1041 ocf_exit_reason "Failed to add $OCF_RESKEY_ip" 1042 exit $rc 1043 fi 1044 fi 1045 1046 case $NIC in 1047 lo*) 1048 : no need to run send_arp on loopback 1049 ;; 1050 *) 1051 if [ $FAMILY = "inet" ];then 1052 run_arp_sender 1053 else 1054 if [ -x $SENDUA ]; then 1055 run_send_ua 1056 if [ $? -ne 0 ]; then 1057 ocf_exit_reason "run_send_ua failed." 1058 exit $OCF_ERR_GENERIC 1059 fi 1060 fi 1061 fi 1062 ;; 1063 esac 1064 exit $OCF_SUCCESS 1065} 1066 1067ip_stop() { 1068 local ip_del_if="yes" 1069 if [ -n "$IP_CIP" ]; then 1070 # Cluster IPs need special processing when the last bucket 1071 # is removed from the node... take a lock to make sure only one 1072 # process executes that code 1073 ocf_take_lock $CIP_lockfile 1074 ocf_release_lock_on_exit $CIP_lockfile 1075 fi 1076 1077 if [ -f "$SENDARPPIDFILE" ] ; then 1078 kill `cat "$SENDARPPIDFILE"` 1079 if [ $? -ne 0 ]; then 1080 ocf_log warn "Could not kill previously running send_arp for $OCF_RESKEY_ip" 1081 else 1082 ocf_log info "killed previously running send_arp for $OCF_RESKEY_ip" 1083 fi 1084 rm -f "$SENDARPPIDFILE" 1085 fi 1086 local ip_status=`ip_served` 1087 ocf_log info "IP status = $ip_status, IP_CIP=$IP_CIP" 1088 1089 if [ $ip_status = "no" ]; then 1090 : Requested interface not in use 1091 exit $OCF_SUCCESS 1092 fi 1093 1094 if [ -n "$IP_CIP" ] && [ $ip_status != "partial2" ]; then 1095 if [ $ip_status = "partial" ]; then 1096 exit $OCF_SUCCESS 1097 fi 1098 echo "-$IP_INC_NO" >$IP_CIP_FILE 1099 if [ "x$(cat $IP_CIP_FILE)" = "x" ]; then 1100 ocf_log info $OCF_RESKEY_ip, $IP_CIP_HASH 1101 i=1 1102 while [ $i -le $IP_INC_GLOBAL ]; do 1103 ocf_log info $i 1104 $IPADDR2_CIP_IPTABLES -D INPUT -d $OCF_RESKEY_ip -i $NIC -j CLUSTERIP \ 1105 --new \ 1106 --clustermac $IF_MAC \ 1107 --total-nodes $IP_INC_GLOBAL \ 1108 --local-node $i \ 1109 --hashmode $IP_CIP_HASH 1110 i=`expr $i + 1` 1111 done 1112 else 1113 ip_del_if="no" 1114 fi 1115 fi 1116 1117 if [ "$ip_del_if" = "yes" ]; then 1118 delete_interface $OCF_RESKEY_ip $NIC $NETMASK 1119 if [ $? -ne 0 ]; then 1120 ocf_exit_reason "Unable to remove IP [${OCF_RESKEY_ip} from interface [ $NIC ]" 1121 exit $OCF_ERR_GENERIC 1122 fi 1123 1124 if ocf_is_true ${OCF_RESKEY_lvs_support}; then 1125 restore_loopback "$OCF_RESKEY_ip" 1126 fi 1127 fi 1128 1129 exit $OCF_SUCCESS 1130} 1131 1132ip_monitor() { 1133 # TODO: Implement more elaborate monitoring like checking for 1134 # interface health maybe via a daemon like FailSafe etc... 1135 1136 local ip_status=`ip_served` 1137 case $ip_status in 1138 ok) 1139 run_arp_sender refresh 1140 return $OCF_SUCCESS 1141 ;; 1142 partial|no|partial2) 1143 exit $OCF_NOT_RUNNING 1144 ;; 1145 *) 1146 # Errors on this interface? 1147 return $OCF_ERR_GENERIC 1148 ;; 1149 esac 1150} 1151 1152# make sure that we have something to send ARPs with 1153set_send_arp_program() { 1154 ARP_SENDER=send_arp 1155 if [ -n "$OCF_RESKEY_arp_sender" ]; then 1156 case "$OCF_RESKEY_arp_sender" in 1157 send_arp) 1158 check_binary $SENDARP 1159 ;; 1160 iputils_arping) 1161 check_binary arping 1162 ;; 1163 libnet_arping) 1164 check_binary arping 1165 ;; 1166 ipoibarping) 1167 check_binary ipoibarping 1168 ;; 1169 *) 1170 ocf_exit_reason "unrecognized arp_sender value: $OCF_RESKEY_arp_sender" 1171 exit $OCF_ERR_CONFIGURED 1172 ;; 1173 esac 1174 ARP_SENDER="$OCF_RESKEY_arp_sender" 1175 else 1176 if is_infiniband; then 1177 ARP_SENDER=ipoibarping 1178 if ! have_binary ipoibarping; then 1179 [ "$__OCF_ACTION" = start ] && 1180 ocf_log warn "using send_arp for infiniband because ipoibarping is not available (set arp_sender to \"send_arp\" to suppress this message)" 1181 check_binary $SENDARP 1182 ARP_SENDER=send_arp 1183 fi 1184 fi 1185 fi 1186} 1187 1188ip_validate() { 1189 check_binary $IP2UTIL 1190 IP_CIP= 1191 1192 if [ -n "$OCF_RESKEY_network_namespace" ]; then 1193 OCF_RESKEY_network_namespace= exec $IP2UTIL netns exec "$OCF_RESKEY_network_namespace" "$0" "$__OCF_ACTION" 1194 fi 1195 1196 ip_init 1197 1198 set_send_arp_program 1199 1200 if [ -n "$IP_CIP" ]; then 1201 if have_binary "$IPTABLES_LEGACY"; then 1202 IPADDR2_CIP_IPTABLES="$IPTABLES_LEGACY" 1203 fi 1204 check_binary "$IPADDR2_CIP_IPTABLES" 1205 check_binary $MODPROBE 1206 fi 1207 1208# $BASEIP, $NETMASK, $NIC , $IP_INC_GLOBAL, and $BRDCAST have been checked within ip_init, 1209# do not bother here. 1210 1211 if ocf_is_true "$OCF_RESKEY_unique_clone_address" && 1212 ! ocf_is_true "$OCF_RESKEY_CRM_meta_globally_unique"; then 1213 ocf_exit_reason "unique_clone_address makes sense only with meta globally_unique set" 1214 exit $OCF_ERR_CONFIGURED 1215 fi 1216 1217 if ocf_is_decimal "$OCF_RESKEY_arp_interval" && [ $OCF_RESKEY_arp_interval -gt 0 ]; then 1218 : 1219 else 1220 ocf_exit_reason "Invalid OCF_RESKEY_arp_interval [$OCF_RESKEY_arp_interval]" 1221 exit $OCF_ERR_CONFIGURED 1222 fi 1223 1224 if ocf_is_decimal "$OCF_RESKEY_arp_count" && [ $OCF_RESKEY_arp_count -gt 0 ]; then 1225 : 1226 else 1227 ocf_exit_reason "Invalid OCF_RESKEY_arp_count [$OCF_RESKEY_arp_count]" 1228 exit $OCF_ERR_CONFIGURED 1229 fi 1230 1231 if [ -z "$OCF_RESKEY_preferred_lft" ]; then 1232 ocf_exit_reason "Empty value is invalid for OCF_RESKEY_preferred_lft" 1233 exit $OCF_ERR_CONFIGURED 1234 fi 1235 1236 if [ -n "$IP_CIP" ]; then 1237 1238 local valid=1 1239 1240 case $IP_CIP_HASH in 1241 sourceip|sourceip-sourceport|sourceip-sourceport-destport) 1242 ;; 1243 *) 1244 ocf_exit_reason "Invalid OCF_RESKEY_clusterip_hash [$IP_CIP_HASH]" 1245 exit $OCF_ERR_CONFIGURED 1246 ;; 1247 esac 1248 1249 if ocf_is_true ${OCF_RESKEY_lvs_support}; then 1250 ocf_exit_reason "LVS and load sharing not advised to try" 1251 exit $OCF_ERR_CONFIGURED 1252 fi 1253 1254 case $IF_MAC in 1255 [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]) 1256 ;; 1257 *) 1258 valid=0 1259 ;; 1260 esac 1261 1262 if [ $valid -eq 0 ]; then 1263 ocf_exit_reason "Invalid IF_MAC [$IF_MAC]" 1264 exit $OCF_ERR_CONFIGURED 1265 fi 1266 1267 fi 1268} 1269 1270if ocf_is_true "$OCF_RESKEY_unique_clone_address"; then 1271 prefix=`echo $OCF_RESKEY_ip | awk -F. '{print $1"."$2"."$3}'` 1272 suffix=`echo $OCF_RESKEY_ip | awk -F. '{print $4}'` 1273 suffix=`expr ${OCF_RESKEY_CRM_meta_clone:-0} + $suffix` 1274 OCF_RESKEY_ip="$prefix.$suffix" 1275fi 1276 1277case $__OCF_ACTION in 1278meta-data) meta_data 1279 ;; 1280usage|help) ip_usage 1281 exit $OCF_SUCCESS 1282 ;; 1283esac 1284 1285ip_validate 1286 1287case $__OCF_ACTION in 1288start) ip_start 1289 ;; 1290stop) ip_stop 1291 ;; 1292status) ip_status=`ip_served` 1293 if [ $ip_status = "ok" ]; then 1294 echo "running" 1295 exit $OCF_SUCCESS 1296 else 1297 echo "stopped" 1298 exit $OCF_NOT_RUNNING 1299 fi 1300 ;; 1301monitor) ip_monitor 1302 ;; 1303validate-all) ;; 1304*) ip_usage 1305 exit $OCF_ERR_UNIMPLEMENTED 1306 ;; 1307esac 1308# vi:sw=4:ts=8: 1309