#!/bin/sh # IBM(c) 2011EPL license http://www.eclipse.org/legal/epl-v10.html #------------------------------------------------------------------------------- #=head1 routeop #=head2 routeop is called by makeroutes command and setuproutes postscript to # setup a route on a node. # The syntax is: # routeop add/delete net mask gateway ifname # routeop replace net mask gateway ifname #NOTE: it only works for sles so far # net - IP of net like 192.168.1.0. The keyword # 'default' is used to set the default route. # mask - The length of the netmask # gatewasy - The next hop. It could be set to "" or 0.0.0.0 # ifname - The interface to route to the next hop # example: routeop replace default 0 10.1.0.209 eth0 #=cut #------------------------------------------------------------------------------- op=$1 net=$2 mask=$3 gw=$4 if [ -n "$5" ]; then ifname=$5 fi # use nummask to know whether the netmask format is 255.255.255.0 or 24 (a number) nummask=0 echo $mask | grep '\.' > /dev/null if [ $? -ne 0 ]; then nummask=1 # the netmask is the length of network mask. fi function debianpreconf(){ #create the config sub dir if [ ! -d "/etc/network/interfaces.d" ];then mkdir -p "/etc/network/interfaces.d" fi #search xcat flag XCATFLAG=`grep "#XCAT_CONFIG" /etc/network/interfaces` if [ -n "$XCATFLAG" ];then return fi #back up the old interface configure if [ ! -e "/etc/network/interfaces.bak" ];then mv /etc/network/interfaces /etc/network/interfaces.bak fi #create the new config file echo "#XCAT_CONFIG" > /etc/network/interfaces echo "source /etc/network/interfaces.d/*" >> /etc/network/interfaces CONFFILE='' #read the backfile cat /etc/network/interfaces.bak | while read LINE do if [ ! "$LINE" ];then continue fi FIRSTCHAR=${LINE:0:1} if [ $FIRSTCHAR = '#' ];then continue fi CONFTYPE=`echo $LINE | cut -d" " -f1` if [ $CONFTYPE = 'auto' -o $CONFTYPE = 'allow-hotplug' ];then LINE=${LINE#$CONFTYPE} for NICNAME in $LINE; do echo "$CONFTYPE $NICNAME" > "/etc/network/interfaces.d/$NICNAME" done elif [ $CONFTYPE = 'iface' -o $CONFTYPE = 'mapping' ];then #find out the nic name, should think about the eth0:1 NICNAME=`echo $LINE | cut -d" " -f 2 | cut -d":" -f 1` CONFFILE="/etc/network/interfaces.d/$NICNAME" if [ ! -e $CONFFILE ];then echo "auto $NICNAME" > $CONFFILE fi #write lines into the conffile echo $LINE >> $CONFFILE else echo $LINE >> $CONFFILE fi done } route_exists() { net=$1 mask=$2 gw=$3 ret=0 if [ -n "$4" ]; then ifname=$4 fi os_type=$(uname -s) # ipv6 if echo $net | grep : 2>&1 1>/dev/null then result=`ip -6 route show $net/$mask` if [ $? -ne 0 ] || [ -z "$result" ] then ret=0 else ret=1 fi else result=`netstat -nr|grep $net`; if [ $? -eq 0 ] && [ -n "$result" ]; then for x in `echo "$result"|tr -s " " ","` do if [ "$os_type" = "Linux" ]; then net1=`echo $x|cut -d',' -f1` gw1=`echo $x|cut -d',' -f2` mask1=`echo $x|cut -d',' -f3` ifname1=`echo $x|cut -d',' -f8` if [ "$net" = "$net1" ] && [ "$mask" = "$mask1" ] && [ "$gw" = "$gw1" ] && [ "$ifname" = "$ifname1" ]; then ret=1 break fi else tmp1=`echo $x|cut -d',' -f1` gw1=`echo $x|cut -d',' -f2` n1=`echo $net |cut -d'.' -f1` n2=`echo $net |cut -d'.' -f2` n3=`echo $net |cut -d'.' -f3` n4=`echo $net |cut -d'.' -f4` netnum="$(( ($n1 << 24) + ($n2 << 16) + ($n3 << 8) + $n4 ))" bits=32 while [ `expr $netnum % 2` -eq 0 ] do bits="$(( $bits - 1 ))" netnum="$(( $netnum >> 1 ))" done tmp2="$net/$bits"; #echo "$tmp2=$tmp2" if [ "$tmp1" = "$tmp2" ] && [ "$gw" = "$gw1" ]; then ret=1 break fi fi done fi fi echo $ret } # handle the route add/replace operation that adding the setting to configuration file add_persistent_route() { net=$1; mask=$2; gw=$3; if [ -n "$4" ]; then ifname=$4 fi xcat_config_start="# xCAT_CONFIG_START"; xcat_config_end="# xCAT_CONFIG_END"; if [ "$(uname -s)" = "Linux" ]; then #determine the os name OS_name="something" if [ -f /etc/redhat-release ] then OS_name="redhat" #it can be RedHatFerdora or CentOS elif [ -f /etc/SuSE-release ] then OS_name="sles" else OS_name="debian" fi # The replace operation does not support redhat and debain so far if [ "$op" = "replace" ]; then if [ "$OS_name" = "redhat" -o "$OS_name" = "debain" ]; then echo "Warning: replace operation only supports to add persistent route for sles by now." return fi fi case $OS_name in sles) #echo "sles" # ipv6 net filename="/etc/sysconfig/network/routes"; if echo $net | grep : 2>&1 1>/dev/null then if [ "$gw" = "" -o "$gw" = "::" ] ; then route="$net/$mask :: - $ifname" route1="$net\/$mask :: - $ifname"; else route="$net/$mask $gw - -" route1="$net\/$mask $gw - -"; fi else if [ "$gw" = "" -o "$gw" = "0.0.0.0" ] ; then if [ $nummask -eq 1 ]; then if [ "$net" = "default" ]; then route="default - - $ifname"; route1="default - - $ifname"; else route="$net/$mask - - $ifname"; route1="$net\/$mask - - $ifname"; fi else route="$net 0.0.0.0 $mask $ifname"; route1="$net 0.0.0.0 $mask $ifname"; fi else if [ $nummask -eq 1 ]; then if [ "$net" = "default" ]; then route="default $gw - $ifname"; route1="default $gw - $ifname"; else route="$net/$mask $gw - $ifname"; route1="$net\/$mask $gw - $ifname"; fi else route="$net $gw $mask $ifname"; route1="$net $gw $mask $ifname"; fi fi fi if [ -f $filename ]; then grep "$route" $filename 2>&1 1>/dev/null if [ $? -ne 0 ]; then #route does not exist grep "$xcat_config_start" $filename 2>&1 1>/dev/null if [ $? -ne 0 ]; then #no xCAT section echo $xcat_config_start >> $filename echo $route >> $filename echo $xcat_config_end >> $filename else sed -i -e s/"$xcat_config_end"/"$route1\n$xcat_config_end"/g $filename fi echo "Persistent route \"$route\" added in $filename." else echo "Persistent route \"$route\" already exists in $filename." fi else #echo "got here" echo "$xcat_config_start" > $filename echo "$route" >> $filename echo "$xcat_config_end" >> $filename echo "Route \"$route\" added in $filename." fi ;; debian) debianpreconf matchstr="" v6flag=0 #on debian/ubuntu need the network device name if [ ! $ifname ];then ifname=`netstat -nr | grep "$net" | awk '{print $8}' | head -1` fi filename="/etc/network/interfaces.d/$ifname" if [ ! -f $filename ];then echo "auto $ifname" > $filename echo "iface $ifname inet dhcp" >> $filename fi echo $net | grep : 2>&1 1>/dev/null #ipv6 if [ $? -eq 0 ];then if [ "$gw" = "" -o "$gw" = "::" ] ; then matchstr="$net/$mask dev $ifname" else matchstr="$net/$mask gw $gw" fi v6flag=1 else if [ "$gw" = "" -o "$gw" = "0.0.0.0" ] ; then matchstr="net $net netmask $mask dev $ifname" else matchstr="net $net netmask $mask gw $gw" fi fi grep "$matchstr" $filename 2>&1 1>/dev/null if [ $? -ne 0 ];then foundflag=0 tempfile="/etc/network/interfaces.d/tmp" while read LINE do echo $LINE | grep "iface" 2>&1 1>/dev/null if [ $? -eq 0 -a $foundflag -eq 1 ];then foundflag=0 if [ $v6flag -eq 1 ];then if [ "$gw" = "" -o "$gw" = "::" ] ; then echo " up route -A inet6 add $net/$mask dev $ifname" >> $tempfile echo " down route -A inet6 del $net/$mask dev $ifname" >> $tempfile else echo " up route -A inet6 add $net/$mask gw $gw" >> $tempfile echo " down route -A inet6 del $net/$mask gw $gw" >> $tempfile fi else if [ "$gw" = "" -o "$gw" = "0.0.0.0" ] ; then echo " up route add -net $net netmask $mask dev $ifname" >> $tempfile echo " down route del -net $net netmask $mask dev $ifname" >> $tempfile else echo " up route add -net $net netmask $mask gw $gw" >> $tempfile echo " down route del -net $net netmask $mask gw $gw" >> $tempfile fi fi fi echo $LINE | grep "iface $ifname " 2>&1 1>/dev/null #this is the last line of the device if [ $? -eq 0 ];then foundflag=1 fi echo $LINE >> $tempfile done < $filename #the insert place is the last line of the config file if [ $foundflag -eq 1 ];then if [ $v6flag -eq 1 ];then if [ "$gw" = "" -o "$gw" = "::" ] ; then echo " up route -A inet6 add $net/$mask dev $ifname" >> $tempfile echo " down route -A inet6 del $net/$mask dev $ifname" >> $tempfile else echo " up route -A inet6 add $net/$mask gw $gw" >> $tempfile echo " down route -A inet6 del $net/$mask gw $gw" >> $tempfile fi else if [ "$gw" = "" -o "$gw" = "0.0.0.0" ] ; then echo " up route add -net $net netmask $mask dev $ifname" >> $tempfile echo " down route del -net $net netmask $mask dev $ifname" >> $tempfile else echo " up route add -net $net netmask $mask gw $gw" >> $tempfile echo " down route del -net $net netmask $mask gw $gw" >> $tempfile fi fi fi mv -f $tempfile $filename echo "Persistent route \"$matchstr\" added in $filename." else echo "Persisten route \"$match\" already exists in $filename" fi ;; redhat) #echo "rh/fedora/centos" # ipv6 net if echo $net | grep : 2>&1 1>/dev/null then if [ "$gw" = "" ] ; then $gw = "::"; fi filename="/etc/sysconfig/static-routes-ipv6"; route="$ifname $net/$mask $gw"; # $net/mask does not work with sed cmd route1="$ifname $net\/$mask $gw"; else filename="/etc/sysconfig/static-routes"; if [ "$gw" = "" -o "$gw" = "0.0.0.0" ] ; then route="any net $net netmask $mask dev $ifname"; route1="any net $net netmask $mask dev $ifname"; else route="any net $net netmask $mask gw $gw $ifname"; route1="any net $net netmask $mask gw $gw $ifname"; fi fi if [ -f $filename ]; then grep "$route" $filename 2>&1 1>/dev/null if [ $? -ne 0 ]; then #route does not exist grep "$xcat_config_start" $filename 2>&1 1>/dev/null if [ $? -ne 0 ]; then #no xCAT section echo $xcat_config_start >> $filename echo $route >> $filename echo $xcat_config_end >> $filename else sed -i -e s/"$xcat_config_end"/"$route1\n$xcat_config_end"/g $filename fi echo "Persistent route \"$route\" added in $filename." else echo "Persistent route \"$route\" already exists in $filename." fi else #echo "got here" echo "$xcat_config_start" > $filename echo "$route" >> $filename echo "$xcat_config_end" >> $filename echo "Persistent route \"$route\" added in $filename." fi ;; esac else #AIX echo "Adding persistent route on AIX is not supported yet." fi } rm_persistent_route() { net=$1; mask=$2; gw=$3; if [ -n "$4" ]; then ifname=$4 fi if [ "$(uname -s)" = "Linux" ]; then #determine the os name OS_name="something" if [ -f /etc/redhat-release ] then OS_name="redhat" #it can be RedHatFerdora or CentOS elif [ -f /etc/SuSE-release ] then OS_name="sles" else OS_name="debian" fi case $OS_name in sles) #echo "sles" filename="/etc/sysconfig/network/routes"; # ipv6 net if echo $net | grep : 2>&1 1>/dev/null then if [ $gw = "" -o $gw = "::" ] ; then route="$net/$mask :: - $ifname"; route1="$net\/$mask :: - $ifname"; else route="$net/$mask $gw - -"; route1="$net\/$mask $gw - -"; fi else if [ $gw = "" ] ; then $gw = "0.0.0.0"; fi if [ -n "$ifname" ]; then route="$net $gw $mask $ifname"; route1="$net $gw $mask $ifname"; else route="$net $gw $mask -"; route1="$net $gw $mask -"; fi fi if [ -f $filename ]; then grep "$route" $filename 2>&1 1>/dev/null if [ $? -ne 0 ]; then # Does not exist in file echo "Persistent route \"$route\" does not exist in $filename." else sed -i -e s/"$route1"//g $filename echo "Persistent route \"$route\" removed from $filename." fi else echo "Persistent route file $filename does not exist." fi ;; debian) debianpreconf matchstr="" v6flag=0 #on debian/ubuntu need the network device name if [ ! $ifname ];then ifname=`netstat -nr | grep "$net" | awk '{print $8}'` fi filename="/etc/network/interfaces.d/$ifname" echo $net | grep : 2>&1 1>/dev/null #ipv6 if [ $? -eq 0 ];then if [ $gw = "" -o $gw = "::" ] ; then matchstr="$net/$mask dev $ifname" else matchstr="$net/$mask gw $gw" fi v6flag=1 else if [ $gw = "" -o $gw = "0.0.0.0" ] ; then matchstr="net $net netmask $mask dev $ifname" else matchstr="net $net netmask $mask gw $gw" fi fi grep "$matchstr" $filename if [ $? -eq 0 ];then sed -i -e "/$matchstr/d" $filename echo "Persistent route \"$matchstr\" removed from $filename." else echo "Persistent route \"$matchstr\" does not exist in $filename." fi ;; redhat) #echo "rh/fedora/centos" #ipv6 if echo $net | grep : 2>&1 1>/dev/null then filename="/etc/sysconfig/static-routes-ipv6"; # $net/$mask does not work with sed if [ "$gw" = "" -o "$gw" = "::" ] ; then route="$ifname $net\/$mask ::" route1="$ifname $net/$mask ::" else route="$ifname $net\/$mask $gw" route1="$ifname $net/$mask $gw" fi else filename="/etc/sysconfig/static-routes"; if [ "$gw" = "" -o "$gw" = "0.0.0.0" ] ; then route="any net $net netmask $mask dev $ifname"; route1="any net $net netmask $mask dev $ifname"; else route="any net $net netmask $mask gw $gw $ifname"; route1="any net $net netmask $mask gw $gw $ifname"; fi fi if [ -f $filename ]; then grep "$route" $filename 2>&1 1>/dev/null if [ $? -ne 0 ]; then # Does not exist in file echo "Persistent route \"$route1\" does not exist in $filename." else sed -i -e s/"$route"//g $filename echo "Persistent route \"$route1\" removed from $filename." fi else echo "Persistent route file $filename does not exist." fi ;; esac else #AIX echo "Removing persistent route on AIX is not supported yet." fi } if [ "$op" = "add" ]; then result=$(route_exists $net $mask $gw) if [ "$result" = "0" ]; then #ipv6 if echo $net | grep : 2>&1 1>/dev/null then if [ "$(uname -s)" = "Linux" ]; then if [ "$gw" = "" -o "$gw" = "::" ] ; then cmd="ip -6 route add $net/$mask dev $ifname" else cmd="ip -6 route add $net/$mask via $gw" fi else # AIX TODO cmd="ip -6 route add $net/$mask via $gw" fi else if [ "$(uname -s)" = "Linux" ]; then if [ "$gw" = "" -o "$gw" = "0.0.0.0" ] ; then cmd="route add -net $net netmask $mask dev $ifname" else cmd="route add -net $net netmask $mask gw $gw" fi else cmd="route add -net $net -netmask $mask $gw" fi fi echo "Adding temporary route: $cmd" result=`$cmd 2>&1` code=$? if [ $code -ne 0 ]; then logger -t xCAT -p local4.err "$cmd\nerror code=$code, result=$result." echo " error code=$code, result=$result." if [ -f "/etc/debian_version" ];then exit 1; fi fi else #ipv6 if echo $net | grep : 2>&1 1>/dev/null then echo "The temporary route ($net/$mask $gw) already exists." else echo "The temporary route ($net $mask $gw) already exists." fi fi #add persistent route add_persistent_route $net $mask $gw $ifname elif [ "$op" = "delete" ]; then result=$(route_exists $net $mask $gw) if [ "$result" = "1" ]; then # ipv6 if echo $net | grep : 2>&1 1>/dev/null then if [ "$(uname -s)" = "Linux" ]; then if [ "$gw" = "" -o "$gw" = "::" ] ; then cmd="ip -6 route delete $net/$mask dev $ifname" else cmd="ip -6 route delete $net/$mask via $gw" fi else # AIX TODO cmd="ip -6 route delete $net/$mask via $gw" fi else if [ "$(uname -s)" = "Linux" ]; then if [ "$gw" = "" -o "$gw" = "0.0.0.0" ] ; then cmd="route delete -net $net netmask $mask dev $ifname" else cmd="route delete -net $net netmask $mask gw $gw" fi else cmd="route delete -net $net -netmask $mask $gw" fi fi echo "Removing temporary route: $cmd" result=`$cmd 2>&1` code=$? if [ $code -ne 0 ]; then logger -t xCAT -p local4.err "$cmd\nerror code=$code, result=$result." echo " error code=$code, result=$result." fi else echo "The temporary route ($net $mask $gw) does not exist." fi #remove the persistent route rm_persistent_route $net $mask $gw $ifname elif [ "$op" = "replace" ]; then if echo $net | grep : 2>&1 1>/dev/null then # ipv6 if [ "$(uname -s)" = "Linux" ]; then if [ "$gw" = "" -o "$gw" = "::" ] ; then if [ "$net" = "default" ]; then cmd="ip -6 route replace default dev $ifname" else cmd="ip -6 route replace $net/$mask dev $ifname" fi else if [ "$net" = "default" ]; then cmd="ip -6 route replace default via $gw" else cmd="ip -6 route replace $net/$mask via $gw" fi fi fi else #ipv4 if [ "$(uname -s)" = "Linux" ]; then if [ "$gw" = "" -o "$gw" = "0.0.0.0" ] ; then if [ "$net" = "default" ]; then cmd="ip route replace default dev $ifname" else cmd="ip route replace $net/$mask dev $ifname" fi else if [ "$net" = "default" ]; then cmd="ip route replace default via $gw" else cmd="ip route replace $net/$mask via $gw" fi fi fi fi echo "Adding temporary route: $cmd" result=`$cmd 2>&1` code=$? if [ $code -ne 0 ]; then logger -t xCAT -p local4.err "$cmd\nerror code=$code, result=$result." echo " error code=$code, result=$result." if [ -f "/etc/debian_version" ];then exit 1; fi fi #replace the persistent route add_persistent_route $net $mask $gw $ifname fi exit 0