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 [ "$pfxlen" = "" ]; then 90 ABCMaskLen $ipaddr 91 pfxlen=$? 92 fi 93 pfx="$ipaddr/$pfxlen" 94fi 95 96if [ "$ldev" = "$dev" -a "$ipaddr" != "" ]; then 97 label= 98fi 99 100if [ $deleting -ne 0 ]; then 101 ip addr del $pfx dev $dev $label || exit 1 102 if [ $fwd -eq 0 ]; then RestartRDISC; fi 103 exit 0 104fi 105 106 107if ! ip link set up dev $dev ; then 108 echo "Error: cannot enable interface $dev." 1>&2 109 exit 1 110fi 111if [ "$ipaddr" = "" ]; then exit 0; fi 112 113if ! arping -q -c 2 -w 3 -D -I $dev $ipaddr ; then 114 echo "Error: some host already uses address $ipaddr on $dev." 1>&2 115 exit 1 116fi 117 118if ! ip address add $pfx brd + dev $dev $label; then 119 echo "Error: failed to add $pfx on $dev." 1>&2 120 exit 1 121fi 122 123arping -q -A -c 1 -I $dev $ipaddr 124noarp=$? 125( sleep 2 ; 126 arping -q -U -c 1 -I $dev $ipaddr ) >& /dev/null </dev/null & 127 128ip route add unreachable 224.0.0.0/24 >& /dev/null 129ip route add unreachable 255.255.255.255 >& /dev/null 130if [ `ip link ls $dev | grep -c MULTICAST` -ge 1 ]; then 131 ip route add 224.0.0.0/4 dev $dev scope global >& /dev/null 132fi 133 134if [ $fwd -eq 0 ]; then 135 if [ $noarp -eq 0 ]; then 136 ip ro append default dev $dev metric 30000 scope global 137 elif [ "$peer" != "" ]; then 138 if ping -q -c 2 -w 4 $peer ; then 139 ip ro append default via $peer dev $dev metric 30001 140 fi 141 fi 142 RestartRDISC 143fi 144 145exit 0 146