1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
|
#!/sbin/runscript
# Copyright 1999-2004 Gentoo Technologies, Inc.
# Distributed under the terms of the GNU General Public License v2
#NB: Config is in /etc/conf.d/net
if [[ -n $NET_DEBUG ]]; then
set -x
devnull=/dev/stderr
else
devnull=/dev/null
fi
# For pcmcia users. note that pcmcia must be added to the same
# runlevel as the net.* script that needs it.
depend() {
use hotplug pcmcia
}
checkconfig() {
if [[ -z "${ifconfig_IFACE}" ]]; then
eerror "Please make sure that /etc/conf.d/net has \$ifconfig_$IFACE set"
eerror "(or \$iface_$IFACE for old-style configuration)"
return 1
fi
if [[ -n "${vlans_IFACE}" && ! -x /sbin/vconfig ]]; then
eerror "For VLAN (802.1q) support, emerge net-misc/vconfig"
return 1
fi
}
# Fix bug 50039 (init.d/net.eth0 localization)
# Some other commands in this script might need to be wrapped, but
# we'll get them one-by-one. Note that LC_ALL trumps LC_anything_else
# according to locale(7)
ifconfig() {
LC_ALL=C /sbin/ifconfig "$@"
}
# setup_vars: setup variables based on $1 and content of /etc/conf.d/net
# The following variables are set, which should be declared local by
# the calling routine.
# status_IFACE (up or '')
# vlans_IFACE (space-separated list)
# ifconfig_IFACE (array of ifconfig lines, replaces iface_IFACE)
# dhcpcd_IFACE (command-line args for dhcpcd)
# routes_IFACE (array of route lines)
# inet6_IFACE (array of inet6 lines)
# ifconfig_fallback_IFACE (fallback ifconfig if dhcp fails)
setup_vars() {
local i iface="${1//\./_}"
status_IFACE="$(ifconfig ${1} 2>${devnull} | gawk '$1 == "UP" {print "up"}')"
eval vlans_IFACE=\"\$\{iface_${iface}_vlans\}\"
eval ifconfig_IFACE=( \"\$\{ifconfig_$iface\[@\]\}\" )
eval dhcpcd_IFACE=\"\$\{dhcpcd_$iface\}\"
eval routes_IFACE=( \"\$\{routes_$iface\[@\]\}\" )
eval inet6_IFACE=( \"\$\{inet6_$iface\[@\]\}\" )
eval ifconfig_fallback_IFACE=( \"\$\{ifconfig_fallback_$iface\[@\]\}\" )
# BACKWARD COMPATIBILITY: populate the ifconfig_IFACE array
# if iface_IFACE is set (fex. iface_eth0 instead of ifconfig_eth0)
eval local iface_IFACE=\"\$\{iface_$iface\}\"
if [[ -n ${iface_IFACE} && -z ${ifconfig_IFACE} ]]; then
# Make sure these get evaluated as arrays
local -a aliases broadcasts netmasks
# Start with the primary interface
ifconfig_IFACE=( "${iface_IFACE}" )
# ..then add aliases
eval aliases=( \$\{alias_$iface\} )
eval broadcasts=( \$\{broadcast_$iface\} )
eval netmasks=( \$\{netmask_$iface\} )
for ((i = 0; i < ${#aliases[@]}; i = i + 1)); do
ifconfig_IFACE[i+1]="${aliases[i]} ${broadcasts[i]:+broadcast ${broadcasts[i]}} ${netmasks[i]:+netmask ${netmasks[i]}}"
done
fi
# BACKWARD COMPATIBILITY: check for space-separated inet6 addresses
if [[ ${#inet6_IFACE[@]} == 1 && ${inet6_IFACE} == *' '* ]]; then
inet6_IFACE=( ${inet6_IFACE} )
fi
}
iface_start() {
local IFACE=${1} i x retval
checkconfig || return 1
if [[ ${ifconfig_IFACE} != dhcp ]]; then
# Show the address, but catch if this interface will be inet6 only
i=${ifconfig_IFACE%% *}
if [[ ${i} == *.*.*.* ]]; then
ebegin "Bringing ${IFACE} up (${i})"
else
ebegin "Bringing ${IFACE} up"
fi
# ifconfig does not always return failure ..
ifconfig ${IFACE} ${ifconfig_IFACE} >${devnull} && \
ifconfig ${IFACE} up &>${devnull}
eend $? || return $?
else
# Check that eth0 was not brought up by the kernel ...
if [[ ${status_IFACE} == up ]]; then
einfo "Keeping kernel configuration for ${IFACE}"
else
ebegin "Bringing ${IFACE} up via DHCP"
/sbin/dhcpcd ${dhcpcd_IFACE} ${IFACE}
retval=$?
eend $retval
if [[ $retval == 0 ]]; then
# DHCP succeeded, show address retrieved
i=$(ifconfig ${IFACE} | grep -m1 -o 'inet addr:[^ ]*' |
cut -d: -f2)
[[ -n ${i} ]] && einfo " ${IFACE} received address ${i}"
elif [[ -n "${ifconfig_fallback_IFACE}" ]]; then
# DHCP failed, try fallback.
# Show the address, but catch if this interface will be inet6 only
i=${ifconfig_fallback_IFACE%% *}
if [[ ${i} == *.*.*.* ]]; then
ebegin "Using fallback configuration (${i}) for ${IFACE}"
else
ebegin "Using fallback configuration for ${IFACE}"
fi
ifconfig ${IFACE} ${ifconfig_fallback_IFACE} >${devnull} && \
ifconfig ${IFACE} up &>${devnull}
eend $? || return $?
else
return $retval
fi
fi
fi
if [[ ${#ifconfig_IFACE[@]} -gt 1 ]]; then
einfo " Adding aliases"
for ((i = 1; i < ${#ifconfig_IFACE[@]}; i = i + 1)); do
ebegin " ${IFACE}:${i} (${ifconfig_IFACE[i]%% *})"
ifconfig ${IFACE}:${i} ${ifconfig_IFACE[i]}
eend $?
done
fi
if [[ -n ${inet6_IFACE} ]]; then
einfo " Adding inet6 addresses"
for ((i = 0; i < ${#inet6_IFACE[@]}; i = i + 1)); do
ebegin " ${IFACE} inet6 add ${inet6_IFACE[i]}"
ifconfig ${IFACE} inet6 add ${inet6_IFACE[i]} >${devnull}
eend $?
done
fi
# Set static routes
if [[ -n ${routes_IFACE} ]]; then
einfo " Adding routes"
for ((i = 0; i < ${#routes_IFACE[@]}; i = i + 1)); do
ebegin " ${routes_IFACE[i]}"
/sbin/route add ${routes_IFACE[i]}
eend $?
done
fi
# Set default route if applicable to this interface
if [[ ${gateway} == ${IFACE}/* ]]; then
local ogw=$(/bin/netstat -rn | awk '$1 == "0.0.0.0" {print $2}')
local gw=${gateway#*/}
if [[ ${ogw} != ${gw} ]]; then
ebegin " Setting default gateway ($gw)"
# First delete any existing route if it was setup by kernel...
/sbin/route del default dev ${IFACE} &>${devnull}
# Second delete old gateway if it was set...
/sbin/route del default gw ${ogw} &>${devnull}
# Third add our new default gateway
/sbin/route add default gw ${gw} >${devnull}
eend $? || {
true # need to have some command in here
# Note: This originally called stop, which is obviously
# wrong since it's calling with a local version of IFACE.
# The below code works correctly to abort configuration of
# the interface, but is commented because we're assuming
# that default route failure should not cause the interface
# to be unconfigured.
#local error=$?
#ewarn "Aborting configuration of ${IFACE}"
#iface_stop ${IFACE}
#return ${error}
}
fi
fi
# Enabling rp_filter causes wacky packets to be auto-dropped by
# the kernel. Note that we only do this if it is not set via
# /etc/sysctl.conf ...
if [[ -e /proc/sys/net/ipv4/conf/${IFACE}/rp_filter && \
-z "$(grep -s '^[^#]*rp_filter' /etc/sysctl.conf)" ]]; then
echo -n 1 > /proc/sys/net/ipv4/conf/${IFACE}/rp_filter
fi
}
# iface_stop: bring down an interface. Don't trust information in
# /etc/conf.d/net since the configuration might have changed since
# iface_start ran. Instead query for current configuration and bring
# down the interface.
iface_stop() {
local IFACE=${1} i x aliases inet6 count
# Try to do a simple down (no aliases, no inet6, no dhcp)
aliases="$(ifconfig | grep -o "^$IFACE:[0-9]*" | tac)"
inet6="$(ifconfig ${IFACE} | awk '$1 == "inet6" {print $2}')"
if [[ -z ${aliases} && -z ${inet6} && ! -e /var/run/dhcpcd-${IFACE}.pid ]]; then
ebegin "Bringing ${IFACE} down"
ifconfig ${IFACE} down &>/dev/null
eend 0
return 0
fi
einfo "Bringing ${IFACE} down"
# Stop aliases before primary interface.
# Note this must be done in reverse order, since ifconfig eth0:1
# will remove eth0:2, etc. It might be sufficient to simply remove
# the base interface but we're being safe here.
for i in ${aliases} ${IFACE}; do
# Delete all the inet6 addresses for this interface
inet6="$(ifconfig ${i} | awk '$1 == "inet6" {print $3}')"
if [[ -n ${inet6} ]]; then
einfo " Removing inet6 addresses"
for x in ${inet6}; do
ebegin " ${IFACE} inet6 del ${x}"
ifconfig ${i} inet6 del ${x}
eend $?
done
fi
# Stop DHCP (should be N/A for aliases)
# Don't trust current configuration... investigate ourselves
if /sbin/dhcpcd -z ${i} &>${devnull}; then
ebegin " Releasing DHCP lease for ${IFACE}"
for ((count = 0; count < 9; count = count + 1)); do
/sbin/dhcpcd -z ${i} &>${devnull} || break
sleep 1
done
[[ ${count} -lt 9 ]]
eend $? "Timed out"
fi
ebegin " Stopping ${i}"
ifconfig ${i} down &>${devnull}
eend 0
done
return 0
}
start() {
# These variables are set by setup_vars
local status_IFACE vlans_IFACE dhcpcd_IFACE
local -a ifconfig_IFACE routes_IFACE inet6_IFACE
# Call user-defined preup function if it exists
if [[ $(type -t preup) == function ]]; then
einfo "Running preup function"
preup ${IFACE} || {
eerror "preup ${IFACE} failed"
return 1
}
fi
# Start the primary interface and aliases
setup_vars ${IFACE}
iface_start ${IFACE} || return 1
# Start vlans
local vlan
for vlan in ${vlans_IFACE}; do
/sbin/vconfig add ${IFACE} ${vlan} >${devnull}
setup_vars ${IFACE}.${vlan}
iface_start ${IFACE}.${vlan}
done
# Call user-defined postup function if it exists
if [[ $(type -t postup) == function ]]; then
einfo "Running postup function"
postup ${IFACE}
fi
}
stop() {
# Call user-defined predown function if it exists
if [[ $(type -t predown) == function ]]; then
einfo "Running predown function"
predown ${IFACE}
fi
# Don't depend on setup_vars since configuration might have changed.
# Investigate current configuration instead.
local vlan
for vlan in $(ifconfig | grep -o "^${IFACE}\.[^ ]*"); do
iface_stop ${vlan}
/sbin/vconfig rem ${vlan} >${devnull}
done
iface_stop ${IFACE} || return 1 # always succeeds, btw
# Call user-defined postdown function if it exists
if [[ $(type -t postdown) == function ]]; then
einfo "Running postdown function"
postdown ${IFACE}
fi
}
# vim:ts=4
|