1#! /bin/bash 2 3CheckForwarding () { 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 17RestartRDISC () { 18 killall -HUP rdisc || rdisc -fs 19} 20 21ABCMaskLen () { 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 32label="label $1" 33ldev="$1" 34dev=${1%:*} 35if [ "$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 41fi 42shift 43 44CheckForwarding 45fwd=$? 46if [ $fwd -ne 0 ]; then 47 echo "Forwarding is ON or its state is unknown ($fwd). OK, No RDISC." 1>&2 48fi 49 50 51deleting=0 52case "$1" in 53add) shift ;; 54stop) 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 ;; 62del*) 63 deleting=1; shift ;; 64*) 65esac 66 67ipaddr= 68pfxlen= 69if [ "$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 78fi 79shift 80 81peer=$1 82if [ "$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" 88else 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" 98fi 99 100if [ "$ldev" = "$dev" -a "$ipaddr" != "" ]; then 101 label= 102fi 103 104if [ $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 108fi 109 110 111if ! ip link set up dev $dev ; then 112 echo "Error: cannot enable interface $dev." 1>&2 113 exit 1 114fi 115if [ "$ipaddr" = "" ]; then exit 0; fi 116 117if ! 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 120fi 121 122if ! ip address add $pfx brd + dev $dev $label; then 123 echo "Error: failed to add $pfx on $dev." 1>&2 124 exit 1 125fi 126 127arping -q -A -c 1 -I $dev $ipaddr 128noarp=$? 129( sleep 2 ; 130 arping -q -U -c 1 -I $dev $ipaddr ) >& /dev/null </dev/null & 131 132ip route add unreachable 224.0.0.0/24 >& /dev/null 133ip route add unreachable 255.255.255.255 >& /dev/null 134if [ "`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 136fi 137 138if [ $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 147fi 148 149exit 0 150