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