Subversion Repositories configs

Rev

Rev 97 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4 - 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
 
62
TEXTDOMAIN=initscripts
63
TEXTDOMAINDIR=/etc/locale
64
 
65
device=$1
66
if [ "$device" = "" ]; then
67
	echo $"usage: ifup-aliases <net-device> [<parent-config>]\n"
68
	exit 1
69
fi
70
 
71
PARENTCONFIG=${2:-ifcfg-$device}
72
parent_device=$device
73
 
74
cd /etc/sysconfig/network-scripts
75
. ./network-functions
76
 
77
# Grab the current configuration of any running aliases, place device info
78
# into variables of the form:
79
# rdev_<index>_addr = <ip address>
80
# rdev_<index>_pb = <prefix>_<broadcast>
81
# rdevip_<ipaddress> = <index>
82
# Example:
83
# rdev_0_addr=192.168.1.1
84
# rdev_0_pb=24_192.16.1.255
85
# rdevip_192_168_1_1=0
86
#
87
# A list of all the devices is created in rdev_LIST.
88
 
89
eval $( ip addr show $device label $device:* | \
90
	awk 'BEGIN { COUNT=0;LAST_DEV="" } /inet / {
91
# Split IP address into address/prefix
92
                split($2,IPADDR,"/");
93
# Create A_B_C_D IP address form
94
                IP_ADDR=IPADDR[1];
95
                gsub(/\./,"_",IP_ADDR);
96
# Split device into device:index
97
                split($NF,DEV,":");
98
# Update last device
99
                LAST_DEV=LAST_DEV " " DEV[2];
100
                printf("rdev_%s_addr=%s\nrdevip_%s=%s\nrdev_%s_pb=%s_%s\nrdev_LIST=\"%s\"\n",
101
	             DEV[2],IPADDR[1],IP_ADDR,DEV[2],DEV[2],IPADDR[2],$4,LAST_DEV);
102
	     } END {
103
	        if(LAST_DEV == "") print "no_devices_are_up=yes"
104
	     }' );
105
 
106
       #
107
       # Store configuration of the parent device and network
108
       #
109
 
110
# read from the /etc/sysconfig/network
111
eval ` (
112
       . /etc/sysconfig/network;
113
       echo network_GATEWAY=$GATEWAY\;;
114
       echo network_GATEWAYDEV=$GATEWAYDEV\;;
115
) `
116
 
117
# read defaults from the parent config file
118
[ -f $PARENTCONFIG ] || {
119
       net_log $"Missing config file $PARENTCONFIG."
120
       exit 1
121
}
122
eval ` (
123
       . ./$PARENTCONFIG;
124
       echo default_PREFIX=$PREFIX\;;
125
       echo default_NETMASK=$NETMASK\;;
126
       echo default_BROADCAST=$BROADCAST\;;
127
       echo default_GATEWAY=$GATEWAY\;;
128
       echo default_NO_ALIASROUTING=$NO_ALIASROUTING\;;
34 - 129
       echo default_ARPCHECK=$ARPCHECK\;;
117 - 130
       echo default_ARPUPDATE=$ARPUPDATE\;;
4 - 131
) `
132
[ -z "$default_GATEWAY" ] && default_GATEWAY=$network_GATEWAY
133
 
134
function ini_env ()
135
{
136
       DEVICE=""
137
       IPADDR=""
138
       PREFIX=$default_PREFIX
139
       NETMASK=$default_NETMASK
140
       BROADCAST=$default_BROADCAST
141
       GATEWAY=$default_GATEWAY
142
       NO_ALIASROUTING=$default_NO_ALIASROUTING
143
       ONPARENT=""
34 - 144
       ARPCHECK=$default_ARPCHECK
117 - 145
       ARPUPDATE=$default_ARPUPDATE
4 - 146
}
147
 
148
function is_default_gateway ()
149
{
150
	LC_ALL=C /sbin/route -n \
151
		| awk '$1 == "0.0.0.0" && $2 == "'"$1"'" { found = 1; }
152
		       END { exit found == 0; }'
153
}
154
 
155
       #
156
       # Read the alias configuration files and enable each aliased
157
       # device using new_interface()
158
       #
159
 
160
function new_interface ()
161
{
162
 
163
       ipa=$IPADDR; ipb=${ipa#*.}; ipc=${ipb#*.};
164
       IPGLOP="${ipa%%.*}_${ipb%%.*}_${ipc%%.*}_${ipc#*.}";
165
       DEVNUM=${DEVICE#*:}
166
 
167
       MATCH='^[0-9A-Za-z_]*$'
168
       if (LC_ALL=C; [[ ! "$DEVNUM" =~ $MATCH ]]); then
169
	      net_log $"error in $FILE: invalid alias number"
170
	      return 1
171
       fi
172
 
173
       eval "
174
              ipseen=\$ipseen_${IPGLOP}; devseen=\$devseen_${DEVNUM};
175
              ipseen_${IPGLOP}=$FILE; devseen_${DEVNUM}=$FILE;
176
       ";
177
 
178
       if [ -n "$ipseen" ]; then
179
              net_log $"error in $FILE: already seen ipaddr $IPADDR in $ipseen"
180
	      return 1
181
       fi
182
 
183
       if [ -n "$devseen" ]; then
184
              net_log $"error in $FILE: already seen device $parent_device:$DEVNUM in $devseen"
185
	      return 1
186
       fi
187
 
188
       if [ -z "$DEVICE" -o -z "$IPADDR" ]; then
189
              net_log $"error in $FILE: didn't specify device or ipaddr"
190
	      return 1
191
       fi
192
 
193
       if [ -z "$NETMASK" -a -z "$PREFIX" ]; then
194
               net_log $"error iN $FILE: didn't specify netmask or prefix"
195
       fi
196
 
197
       if [ -z "$PREFIX" ]; then
198
               eval $(/bin/ipcalc --prefix ${IPADDR} ${NETMASK})
199
       fi
200
 
201
       if [ -z "$BROADCAST" -o "$BROADCAST" = "$default_BROADCAST" ]; then
202
               eval $(/bin/ipcalc --broadcast ${IPADDR}/${PREFIX})
203
       fi
204
 
205
       if [ "$no_devices_are_up" = "yes" ]; then
206
               setup_this=yes
207
       else
208
 
209
               setup_this=""
210
 
211
               eval "
212
                       rdev_addr=\$rdev_${DEVNUM}_addr;
213
                       rdev_pb=\$rdev_${DEVNUM}_pb;
214
                       rdev_mark=\$rdev_${DEVNUM}_mark;
215
                       rdevip=\$rdevip_${IPGLOP};
216
               ";
217
 
218
               if [ -n "$rdev_addr" ]; then
219
                       if [ "$rdev_addr" = "${IPADDR}" ]; then
220
                               newmark=keep
221
                               if [ "$rdev_pb" != "${PREFIX}_${BROADCAST}" ]; then
222
                                       setup_this=freshen
223
                               else
224
                                       setup_this=no
225
                               fi
226
                       else
227
                               if [ "$rdev_mark" != "remove" ]; then
228
                                       /sbin/ip addr flush dev $parent_device label $parent_device:${DEVNUM}
229
                                       do_netreport=yes
230
                               fi
231
                               newmark=remove
232
                               setup_this=yes
233
                       fi
234
                       if [ -n "$rdev_mark" -a "$rdev_mark" != "$newmark" ]; then
235
                               net_log $"error in ifcfg-${parent_device}: files"
236
			       return 1
237
                       fi
238
                       eval " rdev_${DEVNUM}_mark=\$newmark ";
239
               else
240
                       setup_this=yes
241
               fi
242
 
243
               if [ -n "$rdevip" -a "$rdevip" != "${DEVNUM}" ]; then
244
                       eval " mark_remove=\$rdev_${rdevip}_mark ";
245
                       if [ -n "$mark_remove" -a "$mark_remove" != "remove" ]; then
246
                               net_log $"error in ifcfg-${parent_device}: files"
247
			       return 1
248
                       fi
249
                       if [ "$mark_remove" != "remove" ]; then
250
                               eval " rdev_${rdevip}_mark=remove ";
251
                               /sbin/ip addr flush dev $parent_device label $parent_device:$rdevip
252
                               do_netreport=yes
253
                       fi
254
               fi
255
 
256
       fi
257
 
258
       if [ "$setup_this" = "freshen" ] ; then
259
               # we can do the freshen stuff right now
260
               /sbin/ip addr change ${IPADDR}/${PREFIX} brd ${BROADCAST}
261
       fi
262
 
263
       if [ "$setup_this" = "yes" ] ; then
264
               if [ "${parent_device}" != "lo" ] &&  [ "${ARPCHECK}" != "no" ] && \
265
               is_available ${parent_device} && \
9 - 266
               ( grep -qswi "up" /sys/class/net/${parent_device}/operstate ||  grep -qswi "1" /sys/class/net/${parent_device}/carrier ) ; then
267
                   echo $"Determining if ip address ${IPADDR} is already in use for device ${parent_device}..."
4 - 268
 
97 - 269
                    ARPING=$(/sbin/arping -q -c 2 -w ${ARPING_WAIT:-3} -D -I ${parent_device} ${IPADDR})
270
 
271
                    if [ $? = 1 ]; then
272
                        ARPINGMAC=$(echo $ARPING |  sed -ne 's/.*\[\(.*\)\].*/\1/p')
273
                        net_log $"Error, some other host ($ARPINGMAC) already uses address ${IPADDR}."
274
                        return 1
275
                    fi
276
               fi
277
 
4 - 278
               /sbin/ip addr add ${IPADDR}/${PREFIX} brd ${BROADCAST} dev ${parent_device} label ${DEVICE}
279
 
97 - 280
               # update ARP cache of neighboring computers:
117 - 281
               if ! is_false "${ARPUPDATE}" && [ "${REALDEVICE}" != "lo" ]; then
97 - 282
                    /sbin/arping -q -A -c 1 -I ${parent_device} ${IPADDR}
283
                    ( sleep 2; /sbin/arping -q -U -c 1 -I ${parent_device} ${IPADDR} ) > /dev/null 2>&1 < /dev/null &
284
               fi
285
 
4 - 286
               if [ "$NO_ALIASROUTING" != yes ]; then
287
 
288
                       GATEWAYDEV=$network_GATEWAYDEV;
289
 
290
                       if [ -n "${GATEWAY}" -a \
291
			       \( -z "${GATEWAYDEV}" -o "${GATEWAYDEV}" = "${DEVICE}" \) ]; then
292
                               # set up default gateway, if it isn't already there
293
			       if ! is_default_gateway "$GATEWAY"; then
294
				       route add default gw ${GATEWAY} \
295
					   ${METRIC:+metric $METRIC} ${DEVICE}
296
			       fi
297
                       fi
298
 
299
		       /etc/sysconfig/network-scripts/ifup-routes ${DEVICE} ${NAME}
300
 
301
                       do_netreport=yes
302
                       ifuplocal_queue="$ifuplocal_queue $DEVICE"
303
 
304
               fi
305
 
306
	fi
307
 
308
}
309
 
310
if [ "$BASH_VERSINFO" ]; then shopt -s nullglob; else allow_null_glob_expansion=foo; fi
311
 
312
for FILE in ifcfg-${parent_device}:* ; do
313
       is_ignored_file "$FILE" && continue
314
       ini_env;
315
       . ./$FILE;
316
       [ -z "$DEVICE" ] && DEVICE=${FILE##ifcfg-}
317
       [ "$ONPARENT" != "no" -a "$ONPARENT" != "NO" ] && new_interface;
318
       unset DEVICE
319
done
320
 
321
for FILE in ifcfg-${parent_device}-range* ; do
322
       is_ignored_file "$FILE" && continue
323
       ini_env;
324
       . ./$FILE;
325
 
326
       ipaddr_prefix=${IPADDR_START%.*}
327
       ipaddr_startnum=${IPADDR_START##*.}
328
       ipaddr_endnum=${IPADDR_END##*.}
329
 
330
       if [ "${IPADDR_START%.*}" != "${IPADDR_END%.*}" ]; then
331
               net_log $"error in $FILE: IPADDR_START and IPADDR_END don't agree"; continue
332
       fi
333
 
334
       if [ $ipaddr_startnum -gt $ipaddr_endnum ]; then
335
               net_log $"error in $FILE: IPADDR_START greater than IPADDR_END"; continue
336
       fi
337
 
338
       ipaddr_num=$ipaddr_startnum
339
       ipaddr_clonenum=$CLONENUM_START
340
 
341
       while [ $ipaddr_num -le $ipaddr_endnum ]; do
342
               IPADDR="$ipaddr_prefix.$ipaddr_num"
343
               DEVICE="$parent_device:$ipaddr_clonenum"
344
	       [ "$ONPARENT" != "no" -a "$ONPARENT" != "NO" ] && new_interface;
345
               ipaddr_num=$(($ipaddr_num+1))
346
               ipaddr_clonenum=$(($ipaddr_clonenum+1))
347
       done
348
 
349
done
350
 
351
       #
352
       # Remove any devices that should not be around
353
       #
354
	for DEVNUM in $rdev_LIST ; do
355
	       eval " rdev_mark=\$rdev_${DEVNUM}_mark ";
356
	       if [ -z "$rdev_mark" ]; then
357
	               /sbin/ip addr flush dev $parent_device label $parent_device:${DEVNUM}
358
        	       do_netreport=yes
359
	       fi
360
	done
361
       #
362
       # Notify of new device creation
363
       #
364
 
365
if [ -n "$do_netreport" ]; then
366
       do_netreport
367
fi
368
 
369
if [ -x /sbin/ifup-local ]; then
370
       for DEVICE in $ifuplocal_queue ; do
371
               /sbin/ifup-local ${DEVICE}
372
       done
373
fi