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
|