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