source: projects/initscripts/tags/initscripts-8.91.0/sysconfig/network-scripts/ifup-aliases @ 2576

Revision 2576, 13.2 KB checked in by daisuke, 13 years ago (diff)

tagging as initscripts-8.91.0

Line 
1#!/bin/bash
2
3#
4# configures aliases of device $1
5#
6# This script goes out of its way to arrive at the configuration of ip
7# aliases described in the ifcfg-$DEV:* and ifcfg-$DEV-range* files from
8# whatever existing configuration it may be given: existing aliases not
9# specified in the configuration will be removed, netmasks and broadcast
10# addrs will be updated on existing aliases, and new aliases will be setup.
11#
12#   range specification files:
13#
14# One can specify ranges of alised ipaddress using ifcfg-$DEV-range* files.
15# Specify multiple ranges using multiple files, such as ifcfg-eth0-range0 and
16# ifcfg-eth0-range1, etc. In these files, the following configuration variables
17# specify the range:
18#
19#    IPADDR_START    -- ipaddr to start range at. eg "192.168.30.1"
20#    IPADDR_END      -- ipaddr to end range at. eg "192.168.30.254"
21#    CLONENUM_START  -- interface clone number to start using for this range. eg "0"
22#
23# The above example values create the interfaces eth0:0 through eth0:253 using
24# ipaddrs 192.168.30.1 through 192.168.30.254, inclusive.
25#
26# Other configuration variables such as NETMASK and BROADCAST may be specified
27# in the range file and will apply to all of the ipaddresses in the range. Range
28# files also inherit configuration from the ifcfg-$DEV file just like normal.
29#
30# Note that IPADDR_START and IPADR_END are required to be in the same class-c
31# block. I.e. IPADDR_START=192.168.30.1 and IPADDR_END=192.168.31.255 is
32# not valid.
33#
34#   speed with large sets of interfaces:
35#
36# Considerable effort was spent making this script fast. It can efficiently
37# handle a thousand ip aliases on one interface.
38#
39# With large sets of ipaddresses the NO_ALIASROUTING=yes configuration is
40# highly recommended. (This can be specified in ifcfg-$DEV and inherited.) This
41# prevents this script from setting up routing details for the virtual
42# interfaces, which I don't think is needed, because outgoing traffic can use the
43# main interface. However, make your own conclusions on what you need.
44#
45# My test setup of four class C address blocks on a P166 took 25 seconds of
46# which 16 seconds of this was spent in the ifcconfig calls. Without the
47# NO_ALIASROUTING=yes config an additional 12 seconds is spent in route calls.
48#
49#   notes on internals:
50#
51# This script uses the bash "eval" command to lookup shell variables with names
52# which are generated from other shell variables. This allows us to, in effect,
53# create hashes using the shell variable namesspace by just including the hash
54# key in the name of the variable.
55#
56# This script originally written by: David Harris <dharris@drh.net>
57#                                    Principal Engineer, DRH Internet
58#                                    June 30, 1999
59#
60#            modified by: Bill Nottingham <notting@redhat.com>
61
62TEXTDOMAIN=initscripts
63TEXTDOMAINDIR=/etc/locale
64
65device=$1
66if [ "$device" = "" ]; then
67        echo $"usage: ifup-aliases <net-device> [<parent-config>]\n"
68        exit 1
69fi
70
71PARENTCONFIG=${2:-ifcfg-$device}
72parent_device=$device
73
74cd /etc/sysconfig/network-scripts 
75. /etc/sysconfig/network-scripts/network-functions
76
77# Grab the current configuration of any running aliases device info is placed
78# into variables in the form: rdev_$DEVICE_addr, dev_$DEVICE_mb and
79# rdevip_$IPGLOP.  A list of all the devices is created in rdev_LIST.
80
81eval $(LC_ALL= LANG= /sbin/ifconfig | LC_ALL=C sed -n '
82# Alias name: store the number in TMP, ignore the following address if the
83# device name does not match.  This may leave a hanging ||, so dummy X=x
84# comands are used to ignore a possible previous condition.
85/^[^[:space:]]*:[0-9A-Za-z_]*/ {
86        s|^\([^:]*\):\([0-9A-Za-z_]*\).*$|X=x; TMP="\2"; [ "$device" != "\1" ] \|\| |p
87        b
88}
89# Non-alias device: always ignore the following address
90/^[^[:space:]]/ {
91        s|^.*$|X=x; true \|\| |p
92        b
93}
94# Address: Preceded by a device name, which was converted into
95#       condition ||
96# So this triggers only for $device.
97# Add a trailing || (which will be swallowed by X=x) to keep the syntax
98# correct.
99/inet addr:[0-9]*\.[0-9]*\.[0-9]*\.[0-9]* *Bcast:[0-9.]* *Mask:[0-9.]*/ {
100        s|^.*inet addr:\(\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)\) *Bcast:\([0-9.]*\) *Mask:\([0-9.]*\).*$|eval "rdev_${TMP}_addr=\1; rdev_${TMP}_mb=\7_\6; rdevip_\2_\3_\4_\5=${TMP}; rdev_LIST=\\"\\$rdev_LIST \\${TMP}\\"; " \|\| |p
101        b
102}') X=x
103
104if [ -z "$rdev_LIST" ]; then
105       no_devices_are_up=yes
106fi
107
108##for DEVNUM in $rdev_LIST ; do
109##eval "
110##echo \"rdev_${DEVNUM}_addr = \$rdev_${DEVNUM}_addr\"
111##echo \"rdev_${DEVNUM}_mb = \$rdev_${DEVNUM}_mb\" ";
112##done
113##echo ""; echo "-----"; echo ""
114
115       #
116       # Store configuration of the parent device and network
117       #
118
119# read from the /etc/sysconfig/network
120eval ` (
121       . /etc/sysconfig/network;
122       echo network_GATEWAY=$GATEWAY\;;
123       echo network_GATEWAYDEV=$GATEWAYDEV\;;
124) `
125
126# read defaults from the parent config file
127[ -f $PARENTCONFIG ] || {
128       echo $"Missing config file $PARENTCONFIG." >&2
129       exit 1
130}
131eval ` (
132       . $PARENTCONFIG;
133       echo default_NETMASK=$NETMASK\;;
134       echo default_BROADCAST=$BROADCAST\;;
135       echo default_GATEWAY=$GATEWAY\;;
136       echo default_NO_ALIASROUTING=$NO_ALIASROUTING\;;
137) `
138[ -z "$default_GATEWAY" ] && default_GATEWAY=$network_GATEWAY
139
140function ini_env ()
141{
142       DEVICE=""
143       IPADDR=""
144       NETMASK=$default_NETMASK
145       BROADCAST=$default_BROADCAST
146       GATEWAY=$default_GATEWAY
147       NO_ALIASROUTING=$default_NO_ALIASROUTING
148       ONPARENT=""
149}
150
151function is_default_gateway ()
152{
153        LC_ALL=C /sbin/route -n \
154                | awk '$1 == "0.0.0.0" && $2 == "'"$1"'" { found = 1; }
155                       END { exit found == 0; }'
156}
157
158       #
159       # Read the alias configuration files and enable each aliased
160       # device using new_interface()
161       #
162
163function new_interface ()
164{
165
166       ipa=$IPADDR; ipb=${ipa#*.}; ipc=${ipb#*.};
167       IPGLOP="${ipa%%.*}_${ipb%%.*}_${ipc%%.*}_${ipc#*.}";
168       DEVNUM=${DEVICE#*:}
169
170       MATCH='^[0-9A-Za-z_]*$'
171       if (LC_ALL=C; [[ ! "$DEVNUM" =~ $MATCH ]]); then
172              echo $"error in $FILE: invalid alias number" >&2
173              return 1
174       fi
175
176       eval "
177              ipseen=\$ipseen_${IPGLOP}; devseen=\$devseen_${DEVNUM};
178              ipseen_${IPGLOP}=$FILE; devseen_${DEVNUM}=$FILE;
179       ";
180
181       if [ -n "$ipseen" ]; then
182              echo $"error in $FILE: already seen ipaddr $IPADDR in $ipseen" >&2
183              return 1
184       fi
185
186       if [ -n "$devseen" ]; then
187              echo $"error in $FILE: already seen device $parent_device:$DEVNUM in $devseen" >&2
188              return 1
189       fi
190
191       if [ -z "$DEVICE" -o -z "$IPADDR" ]; then
192              echo $"error in $FILE: didn't specify device or ipaddr" >&2
193              return 1
194       fi
195
196       if [ -z "$NETMASK" ]; then
197               eval `/bin/ipcalc --netmask ${IPADDR}`
198       fi
199
200       if [ -z "$BROADCAST" -o "$BROADCAST" = "$default_BROADCAST" ]; then
201               eval `/bin/ipcalc --broadcast ${IPADDR} ${NETMASK}`
202               nma=$NETMASK; nmb=${nma#*.}; nmc=${nmb#*.};
203               NMGLOP="${nma%%.*}_${nmb%%.*}_${nmc%%.*}_${nmc#*.}";
204               if [ ${nma%%.*} -eq 0 ]; then ipnm_a=0; else ipnm_a=${ipa%%.*}; fi
205               if [ ${nmb%%.*} -eq 0 ]; then ipnm_b=0; else ipnm_b=${ipb%%.*}; fi
206               if [ ${nmc%%.*} -eq 0 ]; then ipnm_c=0; else ipnm_c=${ipc%%.*}; fi
207               if [ ${nmc#*.}  -eq 0 ]; then ipnm_d=0; else ipnm_d=${ipc#*.};  fi
208               CACHENAME="${NMGLOP}_${ipnm_a}_${ipnm_b}_${ipnm_c}_${ipnm_d}"
209               eval "
210                       if [ -z \"\$bcastcache_${CACHENAME}\" ]; then
211                               eval `/bin/ipcalc --broadcast \$IPADDR \$NETMASK`
212                               bcastcache_${CACHENAME}=\$BROADCAST
213                       else
214                               BROADCAST=\$bcastcache_${CACHENAME}
215                       fi
216               ";
217       fi
218
219##echo "";
220##echo "----------------------------"
221##echo "device = $DEVICE"
222##echo "ipaddr = $IPADDR"
223##echo "netmask = $NETMASK"
224##echo "broadcast = $BROADCAST"
225##echo "devnum = $DEVNUM";
226##echo "";
227
228       if [ "$no_devices_are_up" = "yes" ]; then
229               setup_this=yes
230       else
231
232               setup_this=""
233
234               eval "
235                       rdev_addr=\$rdev_${DEVNUM}_addr;
236                       rdev_mb=\$rdev_${DEVNUM}_mb;
237                       rdev_mark=\$rdev_${DEVNUM}_mark;
238                       rdevip=\$rdevip_${IPGLOP};
239               ";
240
241               if [ -n "$rdev_addr" ]; then
242                       if [ "$rdev_addr" = "${IPADDR}" ]; then
243                               newmark=keep
244                               if [ "$rdev_mb" != "${NETMASK}_${BROADCAST}" ]; then
245                                       setup_this=freshen
246                               else
247                                       setup_this=no
248                               fi
249                       else
250                               if [ "$rdev_mark" != "remove" ]; then
251##echo "removing device $parent_device:${DEVNUM} (devnum conflict)"
252                                       /sbin/ifconfig $parent_device:${DEVNUM} down
253                                       do_netreport=yes
254                               fi
255                               newmark=remove
256                               setup_this=yes
257                       fi
258                       if [ -n "$rdev_mark" -a "$rdev_mark" != "$newmark" ]; then
259                               echo $"error in ifcfg-${parent_device}: files" >&2
260                               return 1
261                       fi
262                       eval " rdev_${DEVNUM}_mark=\$newmark ";
263               else
264                       setup_this=yes
265               fi
266
267               if [ -n "$rdevip" -a "$rdevip" != "${DEVNUM}" ]; then
268                       eval " mark_remove=\$rdev_${rdevip}_mark ";
269                       if [ -n "$mark_remove" -a "$mark_remove" != "remove" ]; then
270                               echo $"error in ifcfg-${parent_device}: files" >&2
271                               return 1
272                       fi
273                       if [ "$mark_remove" != "remove" ]; then
274                               eval " rdev_${rdevip}_mark=remove ";
275##echo "removing device $parent_device:$rdevip (ipaddr conflict)"
276                               /sbin/ifconfig $parent_device:$rdevip down
277                               do_netreport=yes
278                       fi
279               fi
280
281       fi
282
283       if [ "$setup_this" = "freshen" ] ; then
284               # we can do the freshen stuff right now
285##echo "freshening device $DEVICE"
286               /sbin/ifconfig $DEVICE netmask $NETMASK broadcast $BROADCAST;
287       fi
288
289       if [ "$setup_this" = "yes" ] ; then
290
291##echo "setting up device $DEVICE"
292
293               /sbin/ifconfig ${DEVICE} ${IPADDR} netmask ${NETMASK} broadcast ${BROADCAST}
294
295               if [ "$NO_ALIASROUTING" != yes ]; then
296
297                       GATEWAYDEV=$network_GATEWAYDEV;
298
299                       if [ -n "${GATEWAY}" -a \
300                               \( -z "${GATEWAYDEV}" -o "${GATEWAYDEV}" = "${DEVICE}" \) ]; then
301                               # set up default gateway, if it isn't already there
302                               if ! is_default_gateway "$GATEWAY"; then
303                                       route add default gw ${GATEWAY} \
304                                           ${METRIC:+metric $METRIC} ${DEVICE}
305                               fi
306                       fi
307
308                       /etc/sysconfig/network-scripts/ifup-routes ${DEVICE} ${NAME}
309
310                       do_netreport=yes
311                       ifuplocal_queue="$ifuplocal_queue $DEVICE"
312
313               fi
314
315        fi
316
317}
318
319if [ "$BASH_VERSINFO" ]; then shopt -s nullglob; else allow_null_glob_expansion=foo; fi
320
321for FILE in ifcfg-${parent_device}:* ; do
322       is_ignored_file "$FILE" && continue
323       ini_env;
324       . $FILE;
325       [ -z "$DEVICE" ] && DEVICE=${FILE##ifcfg-}
326       [ "$ONPARENT" != "no" -a "$ONPARENT" != "NO" ] && new_interface;
327       unset DEVICE
328done
329
330for FILE in ifcfg-${parent_device}-range* ; do
331       is_ignored_file "$FILE" && continue
332       ini_env;
333       . $FILE;
334
335       ipaddr_prefix=${IPADDR_START%.*}
336       ipaddr_startnum=${IPADDR_START##*.}
337       ipaddr_endnum=${IPADDR_END##*.}
338
339       if [ "${IPADDR_START%.*}" != "${IPADDR_END%.*}" ]; then
340               echo $"error in $FILE: IPADDR_START and IPADDR_END don't agree" >&2; continue
341       fi
342
343       if [ $ipaddr_startnum -gt $ipaddr_endnum ]; then
344               echo $"error in $FILE: IPADDR_START greater than IPADDR_END" >&2; continue
345       fi
346
347       ipaddr_num=$ipaddr_startnum
348       ipaddr_clonenum=$CLONENUM_START
349
350       while [ $ipaddr_num -le $ipaddr_endnum ]; do
351               IPADDR="$ipaddr_prefix.$ipaddr_num"
352               DEVICE="$parent_device:$ipaddr_clonenum"
353               [ "$ONPARENT" != "no" -a "$ONPARENT" != "NO" ] && new_interface;
354               let 'ipaddr_num=ipaddr_num+1'
355               let 'ipaddr_clonenum=ipaddr_clonenum+1'
356       done
357       
358done
359
360       #
361       # Remove any devices that should not be around
362       #
363        for DEVNUM in $rdev_LIST ; do
364               eval " rdev_mark=\$rdev_${DEVNUM}_mark ";
365               if [ -z "$rdev_mark" ]; then
366        ##echo "removing device $parent_device:${DEVNUM} (lingering)"
367                       /sbin/ifconfig $parent_device:${DEVNUM} down
368                       do_netreport=yes
369               fi
370        done
371       #
372       # Notify of new device creation
373       #
374
375if [ -n "$do_netreport" ]; then
376       do_netreport
377fi
378
379if [ -x /sbin/ifup-local ]; then
380       for DEVICE in $ifuplocal_queue ; do
381               /sbin/ifup-local ${DEVICE}
382       done
383fi
Note: See TracBrowser for help on using the repository browser.