Subversion Repositories configs

Rev

Rev 34 | Rev 97 | Go to most recent revision | 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\;;
4 - 130
) `
131
[ -z "$default_GATEWAY" ] && default_GATEWAY=$network_GATEWAY
132
 
133
function ini_env ()
134
{
135
       DEVICE=""
136
       IPADDR=""
137
       PREFIX=$default_PREFIX
138
       NETMASK=$default_NETMASK
139
       BROADCAST=$default_BROADCAST
140
       GATEWAY=$default_GATEWAY
141
       NO_ALIASROUTING=$default_NO_ALIASROUTING
142
       ONPARENT=""
34 - 143
       ARPCHECK=$default_ARPCHECK
4 - 144
}
145
 
146
function is_default_gateway ()
147
{
148
	LC_ALL=C /sbin/route -n \
149
		| awk '$1 == "0.0.0.0" && $2 == "'"$1"'" { found = 1; }
150
		       END { exit found == 0; }'
151
}
152
 
153
       #
154
       # Read the alias configuration files and enable each aliased
155
       # device using new_interface()
156
       #
157
 
158
function new_interface ()
159
{
160
 
161
       ipa=$IPADDR; ipb=${ipa#*.}; ipc=${ipb#*.};
162
       IPGLOP="${ipa%%.*}_${ipb%%.*}_${ipc%%.*}_${ipc#*.}";
163
       DEVNUM=${DEVICE#*:}
164
 
165
       MATCH='^[0-9A-Za-z_]*$'
166
       if (LC_ALL=C; [[ ! "$DEVNUM" =~ $MATCH ]]); then
167
	      net_log $"error in $FILE: invalid alias number"
168
	      return 1
169
       fi
170
 
171
       eval "
172
              ipseen=\$ipseen_${IPGLOP}; devseen=\$devseen_${DEVNUM};
173
              ipseen_${IPGLOP}=$FILE; devseen_${DEVNUM}=$FILE;
174
       ";
175
 
176
       if [ -n "$ipseen" ]; then
177
              net_log $"error in $FILE: already seen ipaddr $IPADDR in $ipseen"
178
	      return 1
179
       fi
180
 
181
       if [ -n "$devseen" ]; then
182
              net_log $"error in $FILE: already seen device $parent_device:$DEVNUM in $devseen"
183
	      return 1
184
       fi
185
 
186
       if [ -z "$DEVICE" -o -z "$IPADDR" ]; then
187
              net_log $"error in $FILE: didn't specify device or ipaddr"
188
	      return 1
189
       fi
190
 
191
       if [ -z "$NETMASK" -a -z "$PREFIX" ]; then
192
               net_log $"error iN $FILE: didn't specify netmask or prefix"
193
       fi
194
 
195
       if [ -z "$PREFIX" ]; then
196
               eval $(/bin/ipcalc --prefix ${IPADDR} ${NETMASK})
197
       fi
198
 
199
       if [ -z "$BROADCAST" -o "$BROADCAST" = "$default_BROADCAST" ]; then
200
               eval $(/bin/ipcalc --broadcast ${IPADDR}/${PREFIX})
201
       fi
202
 
203
       if [ "$no_devices_are_up" = "yes" ]; then
204
               setup_this=yes
205
       else
206
 
207
               setup_this=""
208
 
209
               eval "
210
                       rdev_addr=\$rdev_${DEVNUM}_addr;
211
                       rdev_pb=\$rdev_${DEVNUM}_pb;
212
                       rdev_mark=\$rdev_${DEVNUM}_mark;
213
                       rdevip=\$rdevip_${IPGLOP};
214
               ";
215
 
216
               if [ -n "$rdev_addr" ]; then
217
                       if [ "$rdev_addr" = "${IPADDR}" ]; then
218
                               newmark=keep
219
                               if [ "$rdev_pb" != "${PREFIX}_${BROADCAST}" ]; then
220
                                       setup_this=freshen
221
                               else
222
                                       setup_this=no
223
                               fi
224
                       else
225
                               if [ "$rdev_mark" != "remove" ]; then
226
                                       /sbin/ip addr flush dev $parent_device label $parent_device:${DEVNUM}
227
                                       do_netreport=yes
228
                               fi
229
                               newmark=remove
230
                               setup_this=yes
231
                       fi
232
                       if [ -n "$rdev_mark" -a "$rdev_mark" != "$newmark" ]; then
233
                               net_log $"error in ifcfg-${parent_device}: files"
234
			       return 1
235
                       fi
236
                       eval " rdev_${DEVNUM}_mark=\$newmark ";
237
               else
238
                       setup_this=yes
239
               fi
240
 
241
               if [ -n "$rdevip" -a "$rdevip" != "${DEVNUM}" ]; then
242
                       eval " mark_remove=\$rdev_${rdevip}_mark ";
243
                       if [ -n "$mark_remove" -a "$mark_remove" != "remove" ]; then
244
                               net_log $"error in ifcfg-${parent_device}: files"
245
			       return 1
246
                       fi
247
                       if [ "$mark_remove" != "remove" ]; then
248
                               eval " rdev_${rdevip}_mark=remove ";
249
                               /sbin/ip addr flush dev $parent_device label $parent_device:$rdevip
250
                               do_netreport=yes
251
                       fi
252
               fi
253
 
254
       fi
255
 
256
       if [ "$setup_this" = "freshen" ] ; then
257
               # we can do the freshen stuff right now
258
               /sbin/ip addr change ${IPADDR}/${PREFIX} brd ${BROADCAST}
259
       fi
260
 
261
       if [ "$setup_this" = "yes" ] ; then
262
               if [ "${parent_device}" != "lo" ] &&  [ "${ARPCHECK}" != "no" ] && \
263
               is_available ${parent_device} && \
9 - 264
               ( grep -qswi "up" /sys/class/net/${parent_device}/operstate ||  grep -qswi "1" /sys/class/net/${parent_device}/carrier ) ; then
265
                   echo $"Determining if ip address ${IPADDR} is already in use for device ${parent_device}..."
58 - 266
                   if ! ARPING=$(/sbin/arping -c 2 -w ${ARPING_WAIT:-3} -D -I ${parent_device} ${IPADDR}) ; then
267
                                           ARPINGMAC=$(echo $ARPING |  sed -ne 's/.*\[\(.*\)\].*/\1/p')
268
                                           net_log $"Error, some other host ($ARPINGMAC) already uses address ${IPADDR}."
4 - 269
					   return 1
270
				   fi
271
			   fi
272
 
273
               /sbin/ip addr add ${IPADDR}/${PREFIX} brd ${BROADCAST} dev ${parent_device} label ${DEVICE}
274
 
275
               if [ "$NO_ALIASROUTING" != yes ]; then
276
 
277
                       GATEWAYDEV=$network_GATEWAYDEV;
278
 
279
                       if [ -n "${GATEWAY}" -a \
280
			       \( -z "${GATEWAYDEV}" -o "${GATEWAYDEV}" = "${DEVICE}" \) ]; then
281
                               # set up default gateway, if it isn't already there
282
			       if ! is_default_gateway "$GATEWAY"; then
283
				       route add default gw ${GATEWAY} \
284
					   ${METRIC:+metric $METRIC} ${DEVICE}
285
			       fi
286
                       fi
287
 
288
		       /etc/sysconfig/network-scripts/ifup-routes ${DEVICE} ${NAME}
289
 
290
                       do_netreport=yes
291
                       ifuplocal_queue="$ifuplocal_queue $DEVICE"
292
 
293
               fi
294
 
295
	fi
296
 
297
}
298
 
299
if [ "$BASH_VERSINFO" ]; then shopt -s nullglob; else allow_null_glob_expansion=foo; fi
300
 
301
for FILE in ifcfg-${parent_device}:* ; do
302
       is_ignored_file "$FILE" && continue
303
       ini_env;
304
       . ./$FILE;
305
       [ -z "$DEVICE" ] && DEVICE=${FILE##ifcfg-}
306
       [ "$ONPARENT" != "no" -a "$ONPARENT" != "NO" ] && new_interface;
307
       unset DEVICE
308
done
309
 
310
for FILE in ifcfg-${parent_device}-range* ; do
311
       is_ignored_file "$FILE" && continue
312
       ini_env;
313
       . ./$FILE;
314
 
315
       ipaddr_prefix=${IPADDR_START%.*}
316
       ipaddr_startnum=${IPADDR_START##*.}
317
       ipaddr_endnum=${IPADDR_END##*.}
318
 
319
       if [ "${IPADDR_START%.*}" != "${IPADDR_END%.*}" ]; then
320
               net_log $"error in $FILE: IPADDR_START and IPADDR_END don't agree"; continue
321
       fi
322
 
323
       if [ $ipaddr_startnum -gt $ipaddr_endnum ]; then
324
               net_log $"error in $FILE: IPADDR_START greater than IPADDR_END"; continue
325
       fi
326
 
327
       ipaddr_num=$ipaddr_startnum
328
       ipaddr_clonenum=$CLONENUM_START
329
 
330
       while [ $ipaddr_num -le $ipaddr_endnum ]; do
331
               IPADDR="$ipaddr_prefix.$ipaddr_num"
332
               DEVICE="$parent_device:$ipaddr_clonenum"
333
	       [ "$ONPARENT" != "no" -a "$ONPARENT" != "NO" ] && new_interface;
334
               ipaddr_num=$(($ipaddr_num+1))
335
               ipaddr_clonenum=$(($ipaddr_clonenum+1))
336
       done
337
 
338
done
339
 
340
       #
341
       # Remove any devices that should not be around
342
       #
343
	for DEVNUM in $rdev_LIST ; do
344
	       eval " rdev_mark=\$rdev_${DEVNUM}_mark ";
345
	       if [ -z "$rdev_mark" ]; then
346
	               /sbin/ip addr flush dev $parent_device label $parent_device:${DEVNUM}
347
        	       do_netreport=yes
348
	       fi
349
	done
350
       #
351
       # Notify of new device creation
352
       #
353
 
354
if [ -n "$do_netreport" ]; then
355
       do_netreport
356
fi
357
 
358
if [ -x /sbin/ifup-local ]; then
359
       for DEVICE in $ifuplocal_queue ; do
360
               /sbin/ifup-local ${DEVICE}
361
       done
362
fi