]> git.ipfire.org Git - thirdparty/dracut.git/blob - modules.d/40network/ifup.sh
Merge pull request #199 from lnykryn/bz1416958
[thirdparty/dracut.git] / modules.d / 40network / ifup.sh
1 #!/bin/sh
2 #
3 # We don't need to check for ip= errors here, that is handled by the
4 # cmdline parser script
5 #
6 # without $2 means this is for real netroot case
7 # or it is for manually bring up network ie. for kdump scp vmcore
8 PATH=/usr/sbin:/usr/bin:/sbin:/bin
9
10 type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
11 type ip_to_var >/dev/null 2>&1 || . /lib/net-lib.sh
12
13 # Huh? No $1?
14 [ -z "$1" ] && exit 1
15
16 # $netif reads easier than $1
17 netif=$1
18
19 # loopback is always handled the same way
20 if [ "$netif" = "lo" ] ; then
21 ip link set lo up
22 ip addr add 127.0.0.1/8 dev lo
23 exit 0
24 fi
25
26 # Run dhclient
27 do_dhcp() {
28 # dhclient-script will mark the netif up and generate the online
29 # event for nfsroot
30 # XXX add -V vendor class and option parsing per kernel
31
32 local _COUNT=0
33 local _timeout=$(getargs rd.net.timeout.dhcp=)
34 local _DHCPRETRY=$(getargs rd.net.dhcp.retry=)
35 _DHCPRETRY=${_DHCPRETRY:-1}
36
37 [ -e /tmp/dhclient.$netif.pid ] && return 0
38
39 if ! iface_has_carrier $netif; then
40 warn "No carrier detected on interface $netif"
41 return 1
42 fi
43
44 while [ $_COUNT -lt $_DHCPRETRY ]; do
45 info "Starting dhcp for interface $netif"
46 dhclient "$@" \
47 ${_timeout:+-timeout $_timeout} \
48 -q \
49 -cf /etc/dhclient.conf \
50 -pf /tmp/dhclient.$netif.pid \
51 -lf /tmp/dhclient.$netif.lease \
52 $netif \
53 && return 0
54 _COUNT=$(($_COUNT+1))
55 [ $_COUNT -lt $_DHCPRETRY ] && sleep 1
56 done
57 warn "dhcp for interface $netif failed"
58 return 1
59 }
60
61 load_ipv6() {
62 [ -d /proc/sys/net/ipv6 ] && return
63 modprobe ipv6
64 i=0
65 while [ ! -d /proc/sys/net/ipv6 ]; do
66 i=$(($i+1))
67 [ $i -gt 10 ] && break
68 sleep 0.1
69 done
70 }
71
72 do_ipv6auto() {
73 load_ipv6
74 echo 0 > /proc/sys/net/ipv6/conf/$netif/forwarding
75 echo 1 > /proc/sys/net/ipv6/conf/$netif/accept_ra
76 echo 1 > /proc/sys/net/ipv6/conf/$netif/accept_redirects
77 linkup $netif
78 wait_for_ipv6_auto $netif
79
80 [ -n "$hostname" ] && echo "echo $hostname > /proc/sys/kernel/hostname" > /tmp/net.$netif.hostname
81
82 return 0
83 }
84
85 # Handle static ip configuration
86 do_static() {
87 strglobin $ip '*:*:*' && load_ipv6
88
89 if [ -z "$dev" ] && ! iface_has_carrier "$netif"; then
90 warn "No carrier detected on interface $netif"
91 return 1
92 elif ! linkup "$netif"; then
93 warn "Could not bring interface $netif up!"
94 return 1
95 fi
96
97 ip route get "$ip" | {
98 read a rest
99 if [ "$a" = "local" ]; then
100 warn "Not assigning $ip to interface $netif, cause it is already assigned!"
101 return 1
102 fi
103 return 0
104 } || return 1
105
106 [ -n "$macaddr" ] && ip link set address $macaddr dev $netif
107 [ -n "$mtu" ] && ip link set mtu $mtu dev $netif
108 if strglobin $ip '*:*:*'; then
109 # note no ip addr flush for ipv6
110 ip addr add $ip/$mask ${srv:+peer $srv} dev $netif
111 wait_for_ipv6_dad $netif
112 else
113 if command -v arping2 >/dev/null; then
114 if arping2 -q -C 1 -c 2 -I $netif -0 $ip ; then
115 warn "Duplicate address detected for $ip for interface $netif."
116 return 1
117 fi
118 else
119 if ! arping -f -q -D -c 2 -I $netif $ip ; then
120 warn "Duplicate address detected for $ip for interface $netif."
121 return 1
122 fi
123 fi
124 ip addr flush dev $netif
125 ip addr add $ip/$mask ${srv:+peer $srv} brd + dev $netif
126 fi
127
128 [ -n "$gw" ] && echo ip route replace default via $gw dev $netif > /tmp/net.$netif.gw
129 [ -n "$hostname" ] && echo "echo $hostname > /proc/sys/kernel/hostname" > /tmp/net.$netif.hostname
130
131 return 0
132 }
133
134 get_vid() {
135 case "$1" in
136 vlan*)
137 echo ${1#vlan}
138 ;;
139 *.*)
140 echo ${1##*.}
141 ;;
142 esac
143 }
144
145 # check, if we need VLAN's for this interface
146 if [ -z "$DO_VLAN_PHY" ] && [ -e /tmp/vlan.${netif}.phy ]; then
147 unset DO_VLAN
148 NO_AUTO_DHCP=yes DO_VLAN_PHY=yes ifup "$netif"
149 modprobe -b -q 8021q
150
151 for i in /tmp/vlan.*.${netif}; do
152 [ -e "$i" ] || continue
153 unset vlanname
154 unset phydevice
155 . "$i"
156 if [ -n "$vlanname" ]; then
157 linkup "$phydevice"
158 ip link add dev "$vlanname" link "$phydevice" type vlan id "$(get_vid $vlanname)"
159 ifup "$vlanname"
160 fi
161 done
162 exit 0
163 fi
164
165 # Check, if interface is VLAN interface
166 if ! [ -e /tmp/vlan.${netif}.phy ]; then
167 for i in /tmp/vlan.${netif}.*; do
168 [ -e "$i" ] || continue
169 export DO_VLAN=yes
170 break
171 done
172 fi
173
174
175 # bridge this interface?
176 if [ -z "$NO_BRIDGE_MASTER" ]; then
177 for i in /tmp/bridge.*.info; do
178 [ -e "$i" ] || continue
179 unset bridgeslaves
180 unset bridgename
181 . "$i"
182 for ethname in $bridgeslaves ; do
183 [ "$netif" != "$ethname" ] && continue
184
185 NO_BRIDGE_MASTER=yes NO_AUTO_DHCP=yes ifup $ethname
186 linkup $ethname
187 if [ ! -e /tmp/bridge.$bridgename.up ]; then
188 brctl addbr $bridgename
189 brctl setfd $bridgename 0
190 > /tmp/bridge.$bridgename.up
191 fi
192 brctl addif $bridgename $ethname
193 ifup $bridgename
194 exit 0
195 done
196 done
197 fi
198
199 # enslave this interface to bond?
200 if [ -z "$NO_BOND_MASTER" ]; then
201 for i in /tmp/bond.*.info; do
202 [ -e "$i" ] || continue
203 unset bondslaves
204 unset bondname
205 . "$i"
206 for slave in $bondslaves ; do
207 [ "$netif" != "$slave" ] && continue
208
209 # already setup
210 [ -e /tmp/bond.$bondname.up ] && exit 0
211
212 # wait for all slaves to show up
213 for slave in $bondslaves ; do
214 # try to create the slave (maybe vlan or bridge)
215 NO_BOND_MASTER=yes NO_AUTO_DHCP=yes ifup $slave
216
217 if ! ip link show dev $slave >/dev/null 2>&1; then
218 # wait for the last slave to show up
219 exit 0
220 fi
221 done
222
223 modprobe -q -b bonding
224 echo "+$bondname" > /sys/class/net/bonding_masters 2>/dev/null
225 ip link set $bondname down
226
227 # Stolen from ifup-eth
228 # add the bits to setup driver parameters here
229 for arg in $bondoptions ; do
230 key=${arg%%=*};
231 value=${arg##*=};
232 # %{value:0:1} is replaced with non-bash specific construct
233 if [ "${key}" = "arp_ip_target" -a "${#value}" != "0" -a "+${value%%+*}" != "+" ]; then
234 OLDIFS=$IFS;
235 IFS=',';
236 for arp_ip in $value; do
237 echo +$arp_ip > /sys/class/net/${bondname}/bonding/$key
238 done
239 IFS=$OLDIFS;
240 else
241 echo $value > /sys/class/net/${bondname}/bonding/$key
242 fi
243 done
244
245 linkup $bondname
246
247 for slave in $bondslaves ; do
248 cat /sys/class/net/$slave/address > /tmp/net.${bondname}.${slave}.hwaddr
249 ip link set $slave down
250 echo "+$slave" > /sys/class/net/$bondname/bonding/slaves
251 linkup $slave
252 done
253
254 # add the bits to setup the needed post enslavement parameters
255 for arg in $bondoptions ; do
256 key=${arg%%=*};
257 value=${arg##*=};
258 if [ "${key}" = "primary" ]; then
259 echo $value > /sys/class/net/${bondname}/bonding/$key
260 fi
261 done
262
263 > /tmp/bond.$bondname.up
264
265 NO_BOND_MASTER=yes ifup $bondname
266 exit $?
267 done
268 done
269 fi
270
271 if [ -z "$NO_TEAM_MASTER" ]; then
272 for i in /tmp/team.*.info; do
273 [ -e "$i" ] || continue
274 unset teammaster
275 unset teamslaves
276 . "$i"
277 for slave in $teamslaves ; do
278 [ "$netif" != "$slave" ] && continue
279
280 [ -e /tmp/team.$teammaster.up ] && exit 0
281
282 # wait for all slaves to show up
283 for slave in $teamslaves ; do
284 # try to create the slave (maybe vlan or bridge)
285 NO_TEAM_MASTER=yes NO_AUTO_DHCP=yes ifup $slave
286
287 if ! ip link show dev $slave >/dev/null 2>&1; then
288 # wait for the last slave to show up
289 exit 0
290 fi
291 done
292
293 if [ ! -e /tmp/team.$teammaster.up ] ; then
294 # We shall only bring up those _can_ come up
295 # in case of some slave is gone in active-backup mode
296 working_slaves=""
297 for slave in $teamslaves ; do
298 ip link set $slave up 2>/dev/null
299 if wait_for_if_up $slave; then
300 working_slaves="$working_slaves$slave "
301 fi
302 done
303 # Do not add slaves now
304 teamd -d -U -n -N -t $teammaster -f /etc/teamd/$teammaster.conf
305 for slave in $working_slaves; do
306 # team requires the slaves to be down before joining team
307 ip link set $slave down
308 teamdctl $teammaster port add $slave
309 done
310
311 ip link set $teammaster up
312
313 > /tmp/team.$teammaster.up
314 NO_TEAM_MASTER=yes ifup $teammaster
315 exit $?
316 fi
317 done
318 done
319 fi
320
321 # all synthetic interfaces done.. now check if the interface is available
322 if ! ip link show dev $netif >/dev/null 2>&1; then
323 exit 1
324 fi
325
326 # disable manual ifup while netroot is set for simplifying our logic
327 # in netroot case we prefer netroot to bringup $netif automaticlly
328 [ -n "$2" -a "$2" = "-m" ] && [ -z "$netroot" ] && manualup="$2"
329
330 if [ -n "$manualup" ]; then
331 >/tmp/net.$netif.manualup
332 rm -f /tmp/net.${netif}.did-setup
333 else
334 [ -e /tmp/net.${netif}.did-setup ] && exit 0
335 [ -z "$DO_VLAN" ] && \
336 [ -e /sys/class/net/$netif/address ] && \
337 [ -e /tmp/net.$(cat /sys/class/net/$netif/address).did-setup ] && exit 0
338 fi
339
340
341 # No ip lines default to dhcp
342 ip=$(getarg ip)
343
344 if [ -z "$NO_AUTO_DHCP" ] && [ -z "$ip" ]; then
345 if [ "$netroot" = "dhcp6" ]; then
346 do_dhcp -6
347 else
348 do_dhcp -4
349 fi
350
351 for s in $(getargs nameserver); do
352 [ -n "$s" ] || continue
353 echo nameserver $s >> /tmp/net.$netif.resolv.conf
354 done
355 fi
356
357
358 # Specific configuration, spin through the kernel command line
359 # looking for ip= lines
360 for p in $(getargs ip=); do
361 ip_to_var $p
362 # skip ibft
363 [ "$autoconf" = "ibft" ] && continue
364
365 case "$dev" in
366 ??:??:??:??:??:??) # MAC address
367 _dev=$(iface_for_mac $dev)
368 [ -n "$_dev" ] && dev="$_dev"
369 ;;
370 ??-??-??-??-??-??) # MAC address in BOOTIF form
371 _dev=$(iface_for_mac $(fix_bootif $dev))
372 [ -n "$_dev" ] && dev="$_dev"
373 ;;
374 esac
375
376 # If this option isn't directed at our interface, skip it
377 [ -n "$dev" ] && [ "$dev" != "$netif" ] && continue
378
379 # Store config for later use
380 for i in ip srv gw mask hostname macaddr mtu dns1 dns2; do
381 eval '[ "$'$i'" ] && echo '$i'="$'$i'"'
382 done > /tmp/net.$netif.override
383
384 for autoopt in $(str_replace "$autoconf" "," " "); do
385 case $autoopt in
386 dhcp|on|any)
387 do_dhcp -4 ;;
388 dhcp6)
389 load_ipv6
390 do_dhcp -6 ;;
391 auto6)
392 do_ipv6auto ;;
393 *)
394 do_static ;;
395 esac
396 done
397 ret=$?
398
399 # setup nameserver
400 for s in "$dns1" "$dns2" $(getargs nameserver); do
401 [ -n "$s" ] || continue
402 echo nameserver $s >> /tmp/net.$netif.resolv.conf
403 done
404
405 if [ $ret -eq 0 ]; then
406 > /tmp/net.${netif}.up
407
408 if [ -z "$DO_VLAN" ] && [ -e /sys/class/net/${netif}/address ]; then
409 > /tmp/net.$(cat /sys/class/net/${netif}/address).up
410 fi
411
412 case $autoconf in
413 dhcp|on|any|dhcp6)
414 ;;
415 *)
416 if [ $ret -eq 0 ]; then
417 setup_net $netif
418 source_hook initqueue/online $netif
419 if [ -z "$manualup" ]; then
420 /sbin/netroot $netif
421 fi
422 fi
423 ;;
424 esac
425 exit $ret
426 fi
427 done
428
429 # no ip option directed at our interface?
430 if [ -z "$NO_AUTO_DHCP" ] && [ ! -e /tmp/net.${netif}.up ]; then
431 if [ -e /tmp/net.bootdev ]; then
432 BOOTDEV=$(cat /tmp/net.bootdev)
433 if [ "$netif" = "$BOOTDEV" ] || [ "$BOOTDEV" = "$(cat /sys/class/net/${netif}/address)" ]; then
434 load_ipv6
435 do_dhcp
436 fi
437 else
438 if getargs 'ip=dhcp6'; then
439 load_ipv6
440 do_dhcp -6
441 fi
442 if getargs 'ip=dhcp'; then
443 do_dhcp -4
444 fi
445 fi
446 fi
447
448 exit 0