#!/bin/ksh93 # ALTRAN_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # Copyright (C) Altran ACT S.A.S. 2017,2018,2019,2021. All rights reserved. # # ALTRAN_PROLOG_END_TAG # # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # 61haes_r714 src/43haes/usr/sbin/cluster/events/utils/cl_swap_IPv6_address.sh 1.9.1.2 # # Licensed Materials - Property of IBM # # COPYRIGHT International Business Machines Corp. 2008,2013 # All Rights Reserved # # US Government Users Restricted Rights - Use, duplication or # disclosure restricted by GSA ADP Schedule Contract with IBM Corp. # # IBM_PROLOG_END_TAG # @(#) 20c8e9d 43haes/usr/sbin/cluster/events/utils/cl_swap_IPv6_address.sh, 726, 2147A_aha726, Oct 30 2021 04:20 PM ############################################################################### # # COMPONENT_NAME: EVENTUTILS # # FUNCTIONS: flush_ndp_cache # configure_linklocal_routes # get_standby_for_service # check_ifconfig_status # check_alias_status # alias_replace_route # ############################################################################### ############################################################################### # # Name: cl_swap_IPv6_address # # This script is used to handle IPv6 service IP labels/addresses, adapter swap and IP address takeover. # The first form, the specified interface is set from the old address # to the new address # cl_swap_IPv6_address cascading/rotating acquire/release interface \ # new_address old_address # i.e cl_swap_IPv6_address cascading acquire en0 2001::1 1.1.1.1 # # The second form sets two interfaces in a single call. This is sometimes # necessary due to AIX routing quirks where an existing route gets # spuriously deleted. An example where this is required is the case of # swapping two interfaces. # cl_swap_IP_address swap_adapter swap \ # interface1 address1 interface2 address2 # i.e cl_swap_IPv6_address swap_adapter swap \ # en0 2001::1 en1 2.2.2.2 # # Returns: 0 - success # 1 - ifconfig failure # 2 - bad number of arguments # 3 - Hardware swap failure # Environment: VERBOSE_LOGGING,PATH ############################################################################### ############################################################################### # Name: flush_ndp_cache # # Flushes entire ndp cache # # Returns: None. ############################################################################### flush_ndp_cache () { typeset PS4_FUNC="flush_ndp_cache" [[ "$VERBOSE_LOGGING" == "high" ]] && set -x ndp -an | grep "\?" | tr -d '()' | (while read host addr other ; do ndp -d $addr done) return 0 } ############################################################################### # Name: add_rc_check # # Add an exit code check, message and error exit to a file. # # Arguments: # $1 - filename # $2 - function name (for message) # # Returns: N/A ############################################################################### add_rc_check() { typeset PS4_FUNC="add_rc_check" [[ "$VERBOSE_LOGGING" == "high" ]] && set -x RR=$1 FUNC=$2 cat >>$RR<<-EOF rc=\$? if [[ \$rc != 0 ]] then echo "ERROR: $FUNC failed with code \$rc" exit \$rc fi EOF } ############################################################################### # Name: configure_linklocal_routes # # On configuration of IPv6 address on a link, it creates static routes for # routing nw traffic to destination ffx2::/16, be routed via gateway # (=link local address of that link). # # Arguments: old interface name (example: en0, en1 etc.) # new interface # # Returns: nothing # ############################################################################### configure_linklocal_routes() { typeset PS4_FUNC="configure_linklocal_routes" [[ "$VERBOSE_LOGGING" == "high" ]] && set -x old_intf=$1 new_intf=$2 new_gateway=$(netstat -in | awk -v intf=$new_intf '(($1==intf) && \ ($3 ~ /^fe80::*/)) {print $3}' | head -1) route delete -inet6 -net ff02::/16 -if $old_intf route delete -inet6 -net ff12::/16 -if $old_intf route add -inet6 -net ff02::/16 $new_gateway -if $new_intf -static route add -inet6 -net ff12::/16 $new_gateway -if $new_intf -static } ############################################################################### # Name: get_standby_for_service # # This routines returns a standby address to be placed on the adapter # where a takeover service is being released. This is not a simple lookup: # because of all the potential combinations of service and standby swaps, # we rely on rsct to tell us which standby it thinks should be put back # on the adapter. # This logic used to be in release_takeover_addr but has been moved here to # account for the new "monitoirng of takeover service labels" function. # # Arguments: # Interface currently holding the takeover service # IP address of the takeover service # # Returns: # IP address of the standby # ############################################################################### get_standby_for_service () { typeset PS4_FUNC="get_standby_for_service" [[ "$VERBOSE_LOGGING" == "high" ]] && set -x CH_INTERFACE=$1 CH_ADDRESS=$2 STBY_IP_ADDR="" NETWORK=$(cllsif -J "$OP_SEP" -Sn $CH_ADDRESS | cut -d"$OP_SEP" -f3 | uniq) NET_TYPE=$(cllsif -J "$OP_SEP" -Sn $CH_ADDRESS | cut -d"$OP_SEP" -f4 | uniq) IF_ALIAS=$(cllsif -J "$OP_SEP" -Si $LOCALNODENAME | grep "${OP_SEP}$NETWORK${OP_SEP}" | \ grep "${OP_SEP}$CH_INTERFACE${OP_SEP}" | cut -d"$OP_SEP" -f12) # if this network is using hb via aliasing, simply lookup # the interface from odm if [[ -n "$IF_ALIAS" ]]; then STBY_IP_ADDR=$(cllsif -J "$OP_SEP" -Si $LOCALNODENAME | \ grep "${OP_SEP}$NETWORK${OP_SEP}" | grep \ "${OP_SEP}$CH_INTERFACE${OP_SEP}" | cut -d"$OP_SEP" -f7) echo "$STBY_IP_ADDR" return fi echo "$STBY_IP_ADDR" return } ############################################################################### # Name: check_ifconfig_status # # This modification has been made because of change of behavior # of 'ifconfig' on AIX 4.1. If we want to add a route which is # already in the routing table, 'ifconfig' DOES change the # address on the adapter BUT the return code IS 1 (error). The # error is accompanied with a message : # # "ifconfig: ioctl (SIOCAIFADDR): Do not specify an existing file." # # Since the adapter does get the new address, we do a 'netstat' on # that adapter and get the current address. If the current address # is the same as the address that we want to put on the adapter, # then everything is fine. Otherwise, we give an error. # # Arguments: # Interface to check # IP address in dotted-decimal format # Netmask in dotted-decimal format # # Returns: # 0 Interface has a proper entry # 1 Interface does not have a proper entry # ############################################################################### check_ifconfig_status () { typeset PS4_FUNC="check_ifconfig_status" [[ "$VERBOSE_LOGGING" == "high" ]] && set -x CH_INTERFACE=$1 CH_ADDRESS=$2 CH_NETMASK=$3 CUR_ADDR=$(clifconfig $CH_INTERFACE | (read ; read a b c ; print $b)) [[ "$CUR_ADDR" != "$CH_ADDRESS" ]] && { cl_log 59 "$PROGNAME: Failed ifconfig $CH_INTERFACE inet $CH_ADDRESS netmask $CH_NETMASK up." $PROGNAME $CH_INTERFACE $CH_ADDRESS $CH_NETMASK return 1 } return 0 } # IP_ALIASING_SUPPORT ############################################################################### # Name: check_alias_status # # This modification to check_ifconfig_status, added for IP aliasing support # because ifconfig displays aliased addresses on additional lines. # # Arguments: # Interface to check # IP address in dotted-decimal format # Netmask in dotted-decimal format # # Returns: # 0 Interface has a proper entry # 1 Interface does not have a proper entry # ############################################################################### check_alias_status () { typeset PS4_FUNC="check_alias_status" [[ "$VERBOSE_LOGGING" == "high" ]] && set -x CH_INTERFACE=$1 CH_ADDRESS=$2 CH_ACQ_OR_RLSE=$3 CUR_ADDR=$(clifconfig $CH_INTERFACE inet6 | fgrep -w $CH_ADDRESS | awk -F"/| " '{print $2}') if [[ "$CH_ACQ_OR_RLSE" == "acquire" ]] then # if acquiring, make sure the alias IS on the interface [[ "$CUR_ADDR" != "$CH_ADDRESS" ]] && { cl_log 7324 "$PROGNAME: Failed to ifconfig alias $CH_ADDRESS on interface $CH_INTERFACE" $PROGNAME $CH_ADDRESS $CH_INTERFACE return 1 } else # if releasing, make sure the alias IS NOT on the interface [[ "$CUR_ADDR" == "$CH_ADDRESS" ]] && { cl_log 7325 "$PROGNAME: Failed ifconfig delete alias $CH_ADDRESS from interface $CH_INTERFACE." $PROGNAME $CH_ADDRESS $CH_INTERFACE return 1 } fi return 0 } ############################################################################### # Name: alias_replace_routes # # For the list of interfaces given on command line, moves each route # to 127.1 (lo0) and writes a file (name in $1) containing a shell # script that will restore the original routing table # # Arguments: # $1 - filename # $2 - failing interface name # Also makes use of following variables, global or set in main routine # LOCALNODENAME, NET, NETMASK, ADDR1, INVOCATION_FLAG, PERSISTENT, # ACQ_OR_RLSE # # Returns: Any error from cl_route_change, otherwise 0 ############################################################################### alias_replace_routes() { typeset PS4_FUNC="alias_replace_routes" [[ "$VERBOSE_LOGGING" == "high" ]] && set -x RR=$1 shift interfaces="$*" RC=0 cp /dev/null $RR cat >$RR<<-EOF #!/bin/ksh # # Script created by $PROGNAME on $(date) # PATH=$PATH PS4='$PS4' export VERBOSE_LOGGING=\${VERBOSE_LOGGING:-"high"} [[ "\$VERBOSE_LOGGING" == "high" ]] && set -x : Starting \$0 at \$(date) # EOF LOCADDRS=$(netstat -in | awk '$3 ~ ":" && $3 !~ "Network" {print $3}') netstat -rnC # according to the netstat command man page: # U = Up # c = Access to this route creates a cloned route # H = route to a host (use -host instead of -net) # W = the route is a cloned route # b = the route broadcast route for ifce in $interfaces ; do integer I=1 NXTSVC="" IFADDRS=$(ifconfig $ifce | grep "inet6" | awk '{print $2}') IFADDRS_CNT=$(netstat -rnf inet6 | awk '($6 == "$ifce") {print $1}' | wc -l) SVCADDRS=$(cllsif -J "$OP_SEP" -Spi $LOCALNODENAME | \ grep "$OP_SEP$NET$OP_SEP" | grep -E "${OP_SEP}service${OP_SEP}" |\ cut -d"$OP_SEP" -f7 | sort -u) PERSISTENT_IP=$(cllsif -J "$OP_SEP" -Spi $LOCALNODENAME | \ grep "$OP_SEP$NET$OP_SEP" | \ grep -E "${OP_SEP}persistent${OP_SEP}" | cut -d"$OP_SEP" -f7) ADDR1_PREFIXLEN=$(cllsif -J "$OP_SEP" -Sn $ADDR1 | awk -F"$OP_SEP" '{print $14}') routeaddr="" for ifaddr in $IFADDRS do ifaddr_nw=$(clgetnet $(echo $ifaddr | sed 's/\// /')) ifaddr_prefixlength=$(echo $ifaddr | awk -F"/" '{print $2}') for svcaddr in $SVCADDRS do svcaddr_prefixlen=$(cllsif -J "$OP_SEP" -Sn $svcaddr | awk -F"$OP_SEP" '{print $14}') svcaddr_nw=$(clgetnet $svcaddr $svcaddr_prefixlen) # It is not sufficient to "only" compare the dest network. if [[ "$ifaddr" == "$svcaddr/$svcaddr_prefixlen" ]] then if [[ -z "$routeaddr" ]] then routeaddr=$(echo $ifaddr | awk -F"/" '{print $1}') fi if [[ "$ifaddr" == "$svcaddr/$svcaddr_prefixlen" && "$ifaddr" != "$ADDR1/$ADDR1_PREFIXLEN" && ("$ADDR1" != "$PERSISTENT_IP" || ( ${INVOCATION_FLAG:-0} != 0 && $INVOCATION_FLAG == "USER_REQUESTED" && "$ADDR1" == "$PERSISTENT_IP")) ]] then NXTSVC=$(echo $svcaddr) break fi fi done if [[ -n $NXTSVC ]] then break fi done swaproute=0 NETSTAT_FLAGS="-nrf inet6" if [[ "$ADDR1" == "$routeaddr" ]] then # swapping addr has net route swaproute=1 fi netstat $NETSTAT_FLAGS | fgrep -w $ifce | while read DEST GW FLAGS REFS USE INTF OTHER; do LOOPBACK="::$I" case $FLAGS in U|UC*) # Unless the route is specified as route to a host (H), its a # network route in which case DEST is in addr/prefixlen format. ADDR1_PREFIXLEN=$(cllsif -J "$OP_SEP" -Sn $ADDR1 | awk -F"$OP_SEP" '{print $14}') ADDR1_NET=$(clgetnet $ADDR1 $ADDR1_PREFIXLEN) if [[ "$ADDR1_NET/$ADDR1_PREFIXLEN" == "$DEST" ]] then # For v6 routes (with flag U|UC*), GW is "link#N". Hence # compare the correct link with the gateway. ifc_link=$(netstat -in | fgrep -w $ifce | awk '($3 ~ "[Ll]ink") {print $3}') if [[ "$ifc_link" == "$GW" ]] then if [[ ($PERSISTENT != "" || "$ifc_link" == "$GW") || ( ${INVOCATION_FLAG:-0} == 0 || $INVOCATION_FLAG != "USER_REQUESTED") ]] then # cloned net (network of failing service IP)routes # whose GW is failing serviceIP are stale route delete -inet6 -net $DEST -if $ifce fi fi fi ;; U*S) # On auto-configuration of link local address on an interface, # routes to "ff02::/16" and "ff12::/16" are automatically configured # enabling the link to join respective multicast groups. # When an interface, through which the nw traffic for this multicast # groups is routed, goes down, the gateway for these routes is # updated with link local address of another interface belonging to # same HACMP network. In case, there is no alternate link local address # available, leave the routing table as is. Failure to comply this # behavior causes unreachability to respective networks. [[ ($DEST == "ff02::/16" || $DEST == "ff12::/16") && ("$INTF" == "$ifce") ]] && { INTF_ON_NET=$(cllsif -J "$OP_SEP" -Spi $LOCALNODENAME | \ grep "$OP_SEP$NET$OP_SEP" | cut -d"$OP_SEP" -f9) for intf in $INTF_ON_NET do [[ "$intf" != "$ifce" ]] && { stdby_intf=$intf } done [[ -n $stdby_intf ]] && { configure_linklocal_routes $ifce $stdby_intf } } ;; U*W*) # all routes created by cloning are evil # Do NOT specify gw here. $DEST is the necessary and sufficient arg. # as gw could be mac address aswell. route delete -inet6 -host $DEST -if $ifce ;; U*H*) # If $DEST is a locally configured address, do # nothing with this route since it may interfere # with netmon logic. found=0 for addr in $LOCADDRS do if [[ "$addr" == "$DEST" ]] then found=1 break fi done if [[ $found == 0 ]] then if [[ "$(clgetnet $ADDR1 $ADDR1_PREFIXLEN)" == \ "$(clgetnet $GW $ADDR1_PREFIXLEN)" ]] then if [[ (${INVOCATION_FLAG:-0} == 0 || $INVOCATION_FLAG != "USER_REQUESTED") || $swaproute == 1 ]] then # into RR we put the route command: if [[ -z $ACQ_OR_RLSE || "$routeaddr" == "$PERSISTENT_IP" ]] then print "cl_route_change -if$routeaddr $DEST $LOOPBACK $GW inet6" >>$RR add_rc_check $RR "cl_route_change" else print "cl_route_change $DEST $LOOPBACK $GW inet6" >>$RR add_rc_check $RR "cl_route_change" fi # which will undo: cl_route_change $DEST $GW $LOOPBACK inet6 RC=$? : cl_route_change completed with $RC I=I+1 fi fi fi ;; U*) ADDR1_PREFIXLEN=$(cllsif -J "$OP_SEP" -Sn $ADDR1 | awk -F"$OP_SEP" '{print $14}') if [[ "$(clgetnet $ADDR1 $ADDR1_PREFIXLEN)" == "$(clgetnet $GW $ADDR1_PREFIXLEN)" ]] then [[ (${INVOCATION_FLAG:-0} == 0) || ($INVOCATION_FLAG != "USER_REQUESTED") || $swaproute == 1 ]] && { if [[ -z $ACQ_OR_RLSE || "$routeaddr" == "$PERSISTENT_IP" ]] then print "cl_route_change -if$routeaddr $DEST $LOOPBACK $GW inet6" >>$RR add_rc_check $RR "cl_route_change" else print "cl_route_change $DEST $LOOPBACK $GW inet6" >>$RR add_rc_check $RR "cl_route_change" fi # which will undo: cl_route_change $DEST $GW $LOOPBACK inet6 RC=$? : cl_route_change completed with $RC I=I+1 } fi ;; esac done done chmod +x $RR return $RC } ############################################################################### # Name: disable_pmtu_gated # # Disable PMTU discovery and the gated daemon temporarily. # Global variables DISABLE_TCP_PMTU, DISABLE_UDP_PMTU and DISABLE_GATED # are set to retain current values. # # Arguments: 0 # # Returns: N/A ############################################################################### disable_pmtu_gated() { typeset PS4_FUNC="disable_pmtu_gated" DISABLE_TCP_PMTU=0 DISABLE_UDP_PMTU=0 DISABLE_TCP_PMTU=$(no -o tcp_pmtu_discover | cut -f3,3 -d" ") DISABLE_UDP_PMTU=$(no -o udp_pmtu_discover | cut -f3,3 -d" ") no -o tcp_pmtu_discover=0 no -o udp_pmtu_discover=0 # Note that running gated is not presently supported by HACMP. # The user may experience side effects if gated is not implemented # properly. HACMP does at least attempt to stop gated: ps -eo "pid,comm" | grep -w gated 2> /dev/null DISABLE_GATED=$? if [ $DISABLE_GATED == 0 ] then # This loop waits for gated to exit before continuing on. # The counter is set to 10 which means we will loop for # a maximum of 10 seconds before continuing on. This # counter can be increased however if it is increased # it might be wise to also increase the nim grace period # to prevent false fail_adapter events from occuring. typeset -i GATED_COUNT=10; /usr/bin/stopsrc -s gated 2> /dev/null while (( GATED_COUNT > 0 )) do ps -eo "pid,comm" | grep -w gated 2> /dev/null if (( $? == 1 )) then break; fi (( GATED_COUNT-- )) sleep 1 done fi return 0 } ############################################################################### # Name: enable_pmtu_gated # # Reenable PMTU discovery and restart gated daemon. # Global variables DISABLE_TCP_PMTU, DISABLE_UDP_PMTU and DISABLE_GATED # hold values previously set in the disable_pmtu_gated subroutine. # # Arguments: 0 # # Returns: N/A ############################################################################### enable_pmtu_gated() { typeset PS4_FUNC="enable_pmtu_gated" # if PMTU discovery was disabled, then reenable it. no -o tcp_pmtu_discover=$DISABLE_TCP_PMTU no -o udp_pmtu_discover=$DISABLE_UDP_PMTU # if gated was on when we entered this script, start it back [[ $DISABLE_GATED == 0 ]] && { startsrc -s gated; sleep 5; } return 0 } restore_ipignoreredirects() { typeset PS4_FUNC="restore_ipignoreredirects" /usr/sbin/no -o ipignoreredirects=$PRIOR_IPIGNORE_REDIRECTS_VALUE } set_ipignoreredirects() { typeset PS4_FUNC="set_ipignoreredirects" PRIOR_IPIGNORE_REDIRECTS_VALUE=$(no -a | grep ipignoreredirects | awk '{ print $3 }') /usr/sbin/no -o ipignoreredirects=1 } ############################################################################### # # Name: non_alias # # Arguments: ip address # # Returns: 1 if non-alias address, 0 if alias address # ############################################################################### non_alias() { typeset PS4_FUNC="non_alias" typeset addr="$1" typeset net=$(cllsif -J "$OP_SEP" -Sw -n $addr | cut -f3 -d"$OP_SEP") typeset alias=$(cllsnw -J "$OP_SEP" -Sw -n $net | cut -f3 -d"$OP_SEP") if [[ "$alias" == "true" ]] ; then return 0 else return 1 fi } ############################################################################### # Name: get_MTU # # Gets the MTU size from netstat for the specified interface. # # Arguments: # $1 Interface name, e.g. en0 # # Returns: prints MTU size in standard output ############################################################################### get_MTU () { typeset PS4_FUNC="get_MTU" [[ "$VERBOSE_LOGGING" == "high" ]] && set -x IF=$1 MTUSIZE="" MTUSIZE=$(netstat -nI $IF | awk 'NR == 2 {print $2}') print $MTUSIZE } ############################################################################### # # Main entry point # ############################################################################### PROGNAME=$(basename ${0}) export PATH="$(/usr/es/sbin/cluster/utilities/cl_get_path all)" [[ "$VERBOSE_LOGGING" == "high" ]] && set -x [[ "$VERBOSE_LOGGING" == "high" ]] && version='1.9.1.2' OP_SEP="$(cl_get_path -S)" export LC_ALL=C RESTORE_ROUTES=/usr/es/sbin/cluster/.restore_routes # # setup for rsct hats adapter call # export HA_DOMAIN_NAME=$(cldomain) export HB_SERVER_SOCKET=/var/ha/soc/topsvcs/server_socket BINDIR=/usr/sbin/rsct/bin RC=0 # Check the runtime level MIXVER=$(clmixver) MIXVERRC=$? cl_echo 33 "Starting execution of $0 with parameters $*" $0 "$*" date # If PMTU discovery is enabled, we need to disable it temporarily. # If gated is running , disable it temporarily # Will routes be changing? if (( $# == 5 )) ; then non_alias $4 if (( $? == 1 )) ; then disable_pmtu_gated fi else disable_pmtu_gated fi set_ipignoreredirects PROC_RES=false # if JOB_TYPE is set, and it doesn't equal to "GROUP", then # we are processing for process_resources if [[ ${JOB_TYPE:-0} != 0 && $JOB_TYPE != "GROUP" ]]; then PROC_RES=true fi set -u case $# in # # This form changes a single interface, e.g. acquiring or releasing # 5) netstat -in netstat -rnC CASC_OR_ROT=$1 # rg relationship which owns the label ACQ_OR_RLSE=$2 # action IF=$3 # this is the interface (adapter) ADDR=$4 # address to be acquired or released OLD_ADDR=$5 # current address on the interface MTUSIZE=$(get_MTU $IF) PREFIX_LEN=$(cllsif -J "$OP_SEP" -Sn $ADDR | awk -F"$OP_SEP" '{print $14}') # For cascading release, need to get the standby to put back if [[ "$CASC_OR_ROT" == "cascading" && "$ACQ_OR_RLSE" == "release" ]] then STBY_IP_ADDR=$(get_standby_for_service $IF $OLD_ADDR) [[ -n $STBY_IP_ADDR ]] && ADDR="$STBY_IP_ADDR" fi NET=$(cllsif -J "$OP_SEP" -Sw -n $ADDR | cut -f3 -d"$OP_SEP") ALIAS=$(cllsnw -J "$OP_SEP" -Sw -n $NET | cut -f3 -d"$OP_SEP") NET_TYPE=$(cllsif -J "$OP_SEP" -Sw -n $ADDR | cut -f4 -d"$OP_SEP") # done with interface and network specific actions # once the service IP is an ipv6 address, possible way of doing things is # ALIASED. ALIAS_FIRST=$(clodmget -n -q"function = shared AND identifier=$ADDR" -f max_aliases HACMPadapter ) if [[ "$ACQ_OR_RLSE" == "acquire" ]] then # Format for consumption by cl_am utility amlog_trace $AM_SERVICEIP_ALIAS_BEGIN "Aliasing Service IP|$ADDR" cl_echo 7310 "$PROGNAME: Configuring network interface $IF with aliased IP address $ADDR" $PROGNAME $IF $ADDR # alias add the specified address to the specified interface # Before aliasing the address, Check the IPv6 Link-local address configuration on the interface # if the interface is not having any LL address then run autoconf6 on the same interface. # Note: All the link-local addresses starts with "fe80::" LL_ADDR=$(ifconfig $IF inet6 | awk '($2 ~ /^fe80::*/){print $2}') if [[ -z "$LL_ADDR" ]] then autoconf6 -i $IF fi case $ALIAS_FIRST in 1027|771|1539|1283) #The user has chosen this address to be the first Address. clifconfig $IF inet6 alias $ADDR/$PREFIX_LEN up firstalias ;; 0|1|2) #Find if other service addresses are present on this adapter. # if not then this will be the first address. clifconfig $IF inet6 alias $ADDR/$PREFIX_LEN up firstalias ;; 515) #If persistent is on this adapter it will stay as First #If not the service will be first. PERSIST_IF="" PERSISTON=$(cllsif -J "$OP_SEP" -Sp $LOCALNODENAME | \ awk -F"$OP_SEP" -v NET="$NET" '{if ($2 == "persistent" \ && $3 == NET) print $1}' | sort) if [[ -n "$PERSISTON" ]] then PERSIST_IF=$(LC_ALL=C clgetif -a $PERSISTON 2>/dev/null) fi if [[ -n "$PERSIST_IF" && $IF == $PERSIST_IF ]] then clifconfig $IF inet6 alias $ADDR/$PREFIX_LEN up else clifconfig $IF inet6 alias $ADDR/$PREFIX_LEN up firstalias fi ;; *) clifconfig $IF inet6 alias $ADDR/$PREFIX_LEN up ;; esac # tell the clstrmgr to start monitoring this alias cl_hats_adapter $IF -e $ADDR alias check_alias_status $IF $ADDR $ACQ_OR_RLSE RC=$? # Format for consumption by cl_am utility if [[ $RC != 0 ]] then amlog_err $AM_SERVICEIP_ALIAS_FAILURE "Aliasing Service IP|$ADDR" else amlog_trace $AM_SERVICEIP_ALIAS_END "Aliasing Service IP|$ADDR" fi else cl_echo 7320 "$PROGNAME: Removing aliased IP address $OLD_ADDR from adapter $IF" $PROGNAME $OLD_ADDR $IF # Format for consumption by cl_am utility amlog_trace $AM_SERVICEIP_DEALIAS_BEGIN "Deliasing Service IP|$OLD_ADDR" PERSISTENT="" ADDR1=$OLD_ADDR disable_pmtu_gated alias_replace_routes $RESTORE_ROUTES $IF RC=$? : completed alias_replace_routes with return code $RC # delete the alias for the specified address clifconfig $IF inet6 delete $OLD_ADDR if [[ -n $NXTSVC && $swaproute == 1 ]] then PREFIX_LEN=$(cllsif -J "$OP_SEP" -Sn $NXTSVC | awk -F"$OP_SEP" '{print $14}') # Before aliasing the address, Check the IPv6 Link-local address configuration on the interface # if the interface is not having any LL address then run autoconf6 on the same interface. # Note: All the link-local addresses starts with "fe80::" LL_ADDR=$(ifconfig $IF inet6 | awk '($2 ~ /^fe80::*/){print $2}') if [[ -z "$LL_ADDR" ]] then autoconf6 -i $IF fi clifconfig $IF inet6 alias $NXTSVC/$PREFIX_LEN up fi $RESTORE_ROUTES RC=$? : Completed $RESTORE_ROUTES with return code $RC enable_pmtu_gated # Reset pmtu and restart gated # tell the clstrmgr not to monitor this alias cl_hats_adapter $IF -d $OLD_ADDR alias check_alias_status $IF $OLD_ADDR $ACQ_OR_RLSE RC=$? # Format for consumption by cl_am utility if [[ $RC != 0 ]] then amlog_err $AM_SERVICEIP_DEALIAS_FAILURE "Dealiasing Service IP|$OLD_ADDR" else amlog_trace $AM_SERVICEIP_DEALIAS_END "Deliasing Service IP|$OLD_ADDR" fi fi (( $RC != 0 )) && { # tell the resource manager the results cl_RMupdate resource_error $ADDR $PROGNAME if [[ $PROC_RES == false ]]; then exit 1 else exit 11 fi } flush_ndp_cache netstat -in netstat -rnC ;; # # this form for changing two address e.g. swap_adapter # 6) UNUSED_1=$1 UNUSED_2=$2 IF1=$3 # interface currently holding the standby address ADDR1=$4 # the address to be recovered (service) IF2=$5 # interface currently holding the service ADDR2=$6 # the standby address ACQ_OR_RLSE="" MTUSIZE=$(get_MTU $IF1) NET=$(cllsif -SwJ "$OP_SEP" -n $ADDR2 | cut -f3 -d"$OP_SEP") NET_TYPE=$(cllsif -SwJ "$OP_SEP" -n $ADDR2 | cut -f4 -d"$OP_SEP") PERSISTENT=$(odmget -q "function=persistent and nodename=$LOCALNODENAME and identifier=$ADDR1" HACMPadapter | grep ip_label) if [[ $PERSISTENT != "" ]]; then # The label passed in as the "service" label is actually # a persistent label, and it should be swapped to the # selected boot. So just do that then exit. cl_configure_persistent_address swap -n $NET -a $IF1 -f $IF2 RC=$? netstat -in netstat -rnC flush_ndp_cache enable_pmtu_gated #Reset pmtu and restart gated restore_ipignoreredirects exit $RC fi alias_replace_routes $RESTORE_ROUTES $IF2 RC=$? : Completed alias_replace_routes with return code $RC if [[ (${INVOCATION_FLAG:-0} == 0) || ($INVOCATION_FLAG != "USER_REQUESTED") ]] then cl_configure_persistent_address swap -n $NET -a $IF1 -f $IF2 netstat -in netstat -rnC fi # Delete the alias service from the current interface clifconfig $IF2 inet6 $ADDR1 delete # add the alias service to the target interface PREFIX_LEN=$(cllsif -J "$OP_SEP" -Sn $ADDR1 | awk -F"$OP_SEP" '{print $14}') # Before aliasing the address, Check the IPv6 Link-local address configuration on the interface # if the interface is not having any LL address then run autoconf6 on the same interface. # Note: All the link-local addresses starts with "fe80::" LL_ADDR=$(ifconfig $IF1 inet6 | awk '($2 ~ /^fe80::*/){print $2}') if [[ -z "$LL_ADDR" ]] then autoconf6 -i $IF1 fi NET=$(cllsif -SwJ "$OP_SEP" -n $ADDR1 | cut -f3 -d"$OP_SEP") ALIAS_FIRST=$(clodmget -n -q"function = shared AND identifier=$ADDR" -f max_aliases HACMPadapter ) case $ALIAS_FIRST in 1027|771|1539|1283) #The user has chosen this address to be the first Address. clifconfig $IF1 inet6 alias $ADDR1/$PREFIX_LEN up firstalias ;; 0|1|2) #Find if other service addresses are present on this adapter. # if not then this will be the first address. clifconfig $IF1 inet6 alias $ADDR1/$PREFIX_LEN up firstalias ;; 515) #If persistent is on this adapter it will stay as First #If not the service will be first. PERSIST_IF="" PERSISTON=$(cllsif -J "$OP_SEP" -Sp $LOCALNODENAME | \ awk -F"$OP_SEP" -v NET="$NET" '{if ($2 == "persistent" \ && $3 == NET) print $1}' | sort) if [[ -n "$PERSISTON" ]] then PERSIST_IF=$(LC_ALL=C clgetif -a $PERSISTON 2>/dev/null) fi if [[ -n "$PERSIST_IF" && $IF1 == $PERSIST_IF ]] then clifconfig $IF1 inet6 alias $ADDR1/$PREFIX_LEN up else clifconfig $IF1 inet6 alias $ADDR1/$PREFIX_LEN up firstalias fi ;; *) clifconfig $IF1 inet6 alias $ADDR1/$PREFIX_LEN up ;; esac $RESTORE_ROUTES RC=$? : Completed $RESTORE_ROUTES with return code $RC netstat -in netstat -rnC flush_ndp_cache enable_pmtu_gated # Tell the cluster manager to start monitoring this alias cl_hats_adapter $IF1 -e $ADDR1 alias check_alias_status $IF1 $ADDR1 "acquire" (( $? != 0 )) && { # tell clstrmgr to stop monitoring # cl_hats_adapter $IF1 -d $ADDR1 alias ?? # tell the resource manager the results cl_RMupdate resource_error $ADDR1 $PROGNAME if [[ $PROC_RES == false ]]; then exit 1 else exit 11 fi } enable_pmtu_gated ;; *) # bad arg count cl_echo 62 "usage: $PROGNAME cascading/rotating acquire/release interface new_address old_address" $PROGNAME cl_echo 63 " or $PROGNAME swap_adapter swap interface1 address1 interface2 address2" $PROGNAME exit 2 esac restore_ipignoreredirects cl_echo 32 "Completed execution of $0 with parameters $*. Exit status = $RC" $0 "$*" $RC date exit $RC