1 #! /bin/bash 2 3 CheckForwarding () { 4 local sbase fwd 5 sbase=/proc/sys/net/ipv4/conf 6 fwd=0 7 if [ -d $sbase ]; then 8 for dir in $sbase/*/forwarding; do 9 fwd=$[$fwd + `cat $dir`] 10 done 11 else 12 fwd=2 13 fi 14 return $fwd 15 } 16 17 RestartRDISC () { 18 killall -HUP rdisc || rdisc -fs 19 } 20 21 ABCMaskLen () { 22 local class; 23 24 class=${1%%.*} 25 if [ "$1" = "" -o $class -eq 0 -o $class -ge 224 ]; then return 0 26 elif [ $class -ge 224 ]; then return 0 27 elif [ $class -ge 192 ]; then return 24 28 elif [ $class -ge 128 ]; then return 16 29 else return 8; fi 30 } 31 32 label="label $1" 33 ldev="$1" 34 dev=${1%:*} 35 if [ "$dev" = "" -o "$1" = "help" ]; then 36 echo "Usage: ifcfg DEV [[add|del [ADDR[/LEN]] [PEER] | stop]" 1>&2 37 echo " add - add new address" 1>&2 38 echo " del - delete address" 1>&2 39 echo " stop - completely disable IP" 1>&2 40 exit 1 41 fi 42 shift 43 44 CheckForwarding 45 fwd=$? 46 if [ $fwd -ne 0 ]; then 47 echo "Forwarding is ON or its state is unknown ($fwd). OK, No RDISC." 1>&2 48 fi 49 50 51 deleting=0 52 case "$1" in 53 add) shift ;; 54 stop) 55 if [ "$ldev" != "$dev" ]; then 56 echo "Cannot stop alias $ldev" 1>&2 57 exit 1; 58 fi 59 ip -4 addr flush dev $dev $label || exit 1 60 if [ $fwd -eq 0 ]; then RestartRDISC; fi 61 exit 0 ;; 62 del*) 63 deleting=1; shift ;; 64 *) 65 esac 66 67 ipaddr= 68 pfxlen= 69 if [ "$1" != "" ]; then 70 ipaddr=${1%/*} 71 if [ "$1" != "$ipaddr" ]; then 72 pfxlen=${1#*/} 73 fi 74 if [ "$ipaddr" = "" ]; then 75 echo "$1 is bad IP address." 1>&2 76 exit 1 77 fi 78 fi 79 shift 80 81 peer=$1 82 if [ "$peer" != "" ]; then 83 if [ "$pfxlen" != "" -a "$pfxlen" != "32" ]; then 84 echo "Peer address with non-trivial netmask." 1>&2 85 exit 1 86 fi 87 pfx="$ipaddr peer $peer" 88 else 89 if [ "$ipaddr" = "" ]; then 90 echo "Missing IP address argument." 1>&2 91 exit 1 92 fi 93 if [ "$pfxlen" = "" ]; then 94 ABCMaskLen $ipaddr 95 pfxlen=$? 96 fi 97 pfx="$ipaddr/$pfxlen" 98 fi 99 100 if [ "$ldev" = "$dev" -a "$ipaddr" != "" ]; then 101 label= 102 fi 103 104 if [ $deleting -ne 0 ]; then 105 ip addr del $pfx dev $dev $label || exit 1 106 if [ $fwd -eq 0 ]; then RestartRDISC; fi 107 exit 0 108 fi 109 110 111 if ! ip link set up dev $dev ; then 112 echo "Error: cannot enable interface $dev." 1>&2 113 exit 1 114 fi 115 if [ "$ipaddr" = "" ]; then exit 0; fi 116 117 if ! arping -q -c 2 -w 3 -D -I $dev $ipaddr ; then 118 echo "Error: some host already uses address $ipaddr on $dev." 1>&2 119 exit 1 120 fi 121 122 if ! ip address add $pfx brd + dev $dev $label; then 123 echo "Error: failed to add $pfx on $dev." 1>&2 124 exit 1 125 fi 126 127 arping -q -A -c 1 -I $dev $ipaddr 128 noarp=$? 129 ( sleep 2 ; 130 arping -q -U -c 1 -I $dev $ipaddr ) >& /dev/null </dev/null & 131 132 ip route add unreachable 224.0.0.0/24 >& /dev/null 133 ip route add unreachable 255.255.255.255 >& /dev/null 134 if [ `ip link ls $dev | grep -c MULTICAST` -ge 1 ]; then 135 ip route add 224.0.0.0/4 dev $dev scope global >& /dev/null 136 fi 137 138 if [ $fwd -eq 0 ]; then 139 if [ $noarp -eq 0 ]; then 140 ip ro append default dev $dev metric 30000 scope global 141 elif [ "$peer" != "" ]; then 142 if ping -q -c 2 -w 4 $peer ; then 143 ip ro append default via $peer dev $dev metric 30001 144 fi 145 fi 146 RestartRDISC 147 fi 148 149 exit 0 150