Contents of /trunk/initscripts/systemd/units/scripts/network.sh
Parent Directory | Revision Log
Revision 2305 -
(show annotations)
(download)
(as text)
Thu Jan 2 13:28:42 2014 UTC (10 years, 8 months ago) by niro
File MIME type: application/x-sh
File size: 12200 byte(s)
Thu Jan 2 13:28:42 2014 UTC (10 years, 8 months ago) by niro
File MIME type: application/x-sh
File size: 12200 byte(s)
-network: wait for interface to come up and removed udev-settle dependency from systemd service, which is not needed anymore. this speeds things up and make networking more fail-safe
1 | #!/bin/bash |
2 | # $Id$ |
3 | # Magellan network configuration script for systemd |
4 | |
5 | # get default settings |
6 | source /etc/conf.d/network |
7 | |
8 | wait_online() |
9 | { |
10 | local timeout="1" |
11 | local iface="$2" |
12 | |
13 | (( timeout *= 10 )) |
14 | |
15 | while [ ! -e /sys/class/net/${iface} ] |
16 | do |
17 | (( timeout-- > 0 )) || return 1 |
18 | sleep 0.1 |
19 | done |
20 | |
21 | return 0 |
22 | } |
23 | |
24 | # read values from files |
25 | read_value() |
26 | { |
27 | local var="$1" |
28 | local file="$2" |
29 | local value |
30 | |
31 | # local all possible vars |
32 | # global |
33 | local ONBOOT |
34 | local NETWORKING |
35 | |
36 | # static |
37 | local IP |
38 | local NETMASK |
39 | local BROADCAST |
40 | local NETWORKING |
41 | local FORCE_MAC_TO |
42 | |
43 | # dhcp |
44 | local DHCP_PROG |
45 | local DHCP_START |
46 | local DHCP_STOP |
47 | |
48 | # default gw |
49 | local GATEWAY |
50 | local GATEWAY_IF |
51 | |
52 | # wireless extensions |
53 | local WIRELESS_AP |
54 | local WIRELESS_AUTH_MODE |
55 | local WIRELESS_BITRATE |
56 | local WIRELESS_CHANNEL |
57 | local WIRELESS_DEFAULT_KEY |
58 | local WIRELESS_ESSID |
59 | local WIRELESS_FREQUENCY |
60 | local WIRELESS_KEY |
61 | local WIRELESS_KEY_ASCII |
62 | local WIRELESS_KEY_0 |
63 | local WIRELESS_KEY_1 |
64 | local WIRELESS_KEY_2 |
65 | local WIRELESS_KEY_3 |
66 | local WIRELESS_KEY_LENGTH |
67 | local WIRELESS_MODE |
68 | local WIRELESS_NICK |
69 | local WIRELESS_NWID |
70 | local WIRELESS_POWER |
71 | local WIRELESS_WPA_DRIVER |
72 | |
73 | local BRIDGE_INTERFACES |
74 | local BRIDGE_STP |
75 | local BRIDGE_AGEING_TIME |
76 | local BRIDGE_PRIORITY |
77 | local BRIDGE_FORWARD_DELAY |
78 | local BRIDGE_HELLO_TIME |
79 | local BRIDGE_MAX_MESSAGE_AGE |
80 | local BRIDGE_PATH_COST |
81 | local BRIDGE_PORT_PRIORITY |
82 | |
83 | source ${file} |
84 | eval value=\$$(echo ${var}) |
85 | echo "${value}" |
86 | } |
87 | |
88 | checkconfig() |
89 | { |
90 | if [[ -z ${NETWORKING} ]] |
91 | then |
92 | echo "NETWORKING missing in net.${iface}, aborted" |
93 | exit 1 |
94 | fi |
95 | |
96 | case "${NETWORKING}" in |
97 | static) |
98 | if [[ -z ${IP} ]] |
99 | then |
100 | echo "IP missing in net.${iface}, aborted" |
101 | exit 1 |
102 | fi |
103 | |
104 | if [[ -z ${NETMASK} ]] |
105 | then |
106 | echo -n "NETMASK missing in net.${iface}, " |
107 | echo "using ${DEFAULT_NETMASK}" |
108 | NETMASK="${DEFAULT_NETMASK}" |
109 | fi |
110 | |
111 | if [[ -z ${BROADCAST} ]] |
112 | then |
113 | echo -n "BROADCAST missing in net.${iface}, " |
114 | echo "using default address" |
115 | fi |
116 | ;; |
117 | |
118 | dhcp) |
119 | if [[ -z ${DHCP_PROG} ]] |
120 | then |
121 | echo -n "DHCP_PROG missing in net.${iface}," |
122 | echo "using default programm ${DEFAULT_DHCP_PROG}" |
123 | DHCP_PROG="${DEFAULT_DHCP_PROG}" |
124 | fi |
125 | [[ -z ${DHCP_START} ]] && DHCP_START="${DEFAULT_DHCP_START}" |
126 | [[ -z ${DHCP_STOP} ]] && DHCP_STOP="${DEFAULT_DHCP_STOP}" |
127 | ;; |
128 | |
129 | esac |
130 | } |
131 | |
132 | # onboot_interface_list /path/to/files* |
133 | onboot_interface_list() |
134 | { |
135 | local file |
136 | local devices |
137 | local iface |
138 | |
139 | # get list of all devices |
140 | for file in $@ |
141 | do |
142 | iface="$(basename ${file} | sed s/net.//)" |
143 | |
144 | # exclude backup files and exclude net.routes and net.sample too |
145 | case "${iface}" in |
146 | *~) continue ;; |
147 | routes) continue ;; |
148 | sample) continue ;; |
149 | esac |
150 | |
151 | if [[ $(read_value ONBOOT ${file}) = yes ]] |
152 | then |
153 | devices="${devices} ${iface}" |
154 | fi |
155 | done |
156 | |
157 | echo "${devices}" |
158 | } |
159 | |
160 | config_wireless_wep() |
161 | { |
162 | local iface="$1" |
163 | |
164 | if [[ -z ${iface} ]] |
165 | then |
166 | echo "WEP: no \$iface given. Aborting setup." |
167 | return 1 |
168 | fi |
169 | |
170 | iwconfig "${iface}" enc on |
171 | [[ -n ${WIRELESS_KEY_LENGTH} ]] && iwconfig "${iface}" enc "${WIRELESS_KEY_LENGTH}" |
172 | [[ -n ${WIRELESS_KEY} ]] && iwconfig "${iface}" key "${WIRELESS_KEY}" |
173 | [[ -n ${WIRELESS_KEY_ASCII} ]] && iwconfig "${iface}" key s:"${WIRELESS_KEY_ASCII}" |
174 | } |
175 | |
176 | config_wireless_wpa() |
177 | { |
178 | local iface="$1" |
179 | |
180 | if [[ -z ${iface} ]] |
181 | then |
182 | echo "WPA: no \$iface given. Aborting setup." |
183 | return 1 |
184 | fi |
185 | |
186 | if [ ! -x $(type -P wpa_supplicant) ] |
187 | then |
188 | echo "WPA: wpa_supplicant not installed. Aborting setup." |
189 | return 1 |
190 | fi |
191 | |
192 | # get default settings |
193 | [[ -f /etc/conf.d/wpa_supplicant ]] && source /etc/conf.d/wpa_supplicant |
194 | |
195 | # check the configuration |
196 | [[ -z ${WIRELESS_WPA_CONFIG} ]] && WIRELESS_WPA_CONFIG=/etc/wpa_supplicant/wpa_supplicant.auto |
197 | [[ -z ${WIRELESS_WPA_SKEL} ]] && WIRELESS_WPA_SKEL=/etc/conf.d/wpa_supplicant.skel |
198 | |
199 | # use wext as default driver, do not abort here anymore |
200 | [[ -z ${WIRELESS_WPA_DRIVER} ]] && WIRELESS_WPA_DRIVER=wext |
201 | |
202 | # write a config with the settings from net.${iface} |
203 | # only wpa-psk ! all other needs manual setup |
204 | if [[ ${WIRELESS_WPA_AUTOCONF} = true ]] |
205 | then |
206 | # write default cfg from skeleton |
207 | cat ${WIRELESS_WPA_SKEL} > ${WIRELESS_WPA_CONFIG} |
208 | |
209 | local wpa_proto |
210 | case ${WIRELESS_AUTH_MODE} in |
211 | wpa) wpa_proto="WPA" ;; |
212 | wpa2) wpa_proto="WPA2" ;; |
213 | esac |
214 | |
215 | # setup the network entry |
216 | sed -i -e "s:@WIRELESS_ESSID@:${WIRELESS_ESSID}:g" \ |
217 | -e "s:@WIRELESS_KEY@:${WIRELESS_KEY_ASCII}:g" \ |
218 | -e "s:@WIRELESS_AUTH_MODE@:${wpa_proto}:g" \ |
219 | ${WIRELESS_WPA_CONFIG} |
220 | fi |
221 | |
222 | # remove old state dir |
223 | [ -d /run/wpa_supplicant ] && rm -rf /run/wpa_supplicant |
224 | |
225 | # now run the wpa_supplicant dameon |
226 | wpa_supplicant -B \ |
227 | -D"${WIRELESS_WPA_DRIVER}" \ |
228 | -c"${WIRELESS_WPA_CONFIG}" \ |
229 | -i"${iface}" \ |
230 | ${WIRELESS_WPA_OPTS} |
231 | |
232 | # echo wait 5 seconds |
233 | echo " Waiting 5 seconds to retrieve authentification reply ... " |
234 | sleep 5 |
235 | } |
236 | |
237 | setup_wireless_extensions() |
238 | { |
239 | local iface="$1" |
240 | |
241 | if [[ -z ${iface} ]] |
242 | then |
243 | echo "WIRELESS_EXTENSIONS: no \$iface given. Aborting setup." |
244 | return 1 |
245 | fi |
246 | |
247 | [[ -n ${WIRELESS_BITRATE} ]] && iwconfig "${iface}" rate "${WIRELESS_BITRATE}" |
248 | [[ -n ${WIRELESS_CHANNEL} ]] && iwconfig "${iface}" channel "${WIRELESS_CHANNEL}" |
249 | [[ -n ${WIRELESS_ESSID} ]] && iwconfig "${iface}" essid "${WIRELESS_ESSID}" |
250 | [[ -n ${WIRELESS_FREQUENCY} ]] && iwconfig "${iface}" freq "${WIRELESS_FREQUENCY}" |
251 | [[ -n ${WIRELESS_MODE} ]] && iwconfig "${iface}" mode "${WIRELESS_MODE}" |
252 | [[ -n ${WIRELESS_NICK} ]] && iwconfig "${iface}" nick "${WIRELESS_NICK}" |
253 | |
254 | case "${WIRELESS_AUTH_MODE}" in |
255 | wpa|wpa2) config_wireless_wpa "${iface}" ;; |
256 | wep|on) config_wireless_wep "${iface}" ;; |
257 | off) iwconfig "${iface}" enc off ;; |
258 | esac |
259 | } |
260 | |
261 | config_bridge_options() |
262 | { |
263 | local iface="$1" |
264 | local i |
265 | local port |
266 | local cost |
267 | local prio |
268 | |
269 | # enable spanning-tree protocol |
270 | case ${BRIDGE_STP} in |
271 | on|off) brctl stp "${iface}" "${BRIDGE_STP}" ;; |
272 | *) echo "BRIDGE: unkown value \$BRIDGE_STP='$BRIDGE_STP'."; return 1 ;; |
273 | esac |
274 | |
275 | # configure ageing time |
276 | if [[ ! -z ${BRIDGE_AGEING_TIME} ]] |
277 | then |
278 | brctl setageing "${iface}" "${BRIDGE_AGEING_TIME}" |
279 | fi |
280 | |
281 | # configure bridge priority |
282 | if [[ ! -z ${BRIDGE_PRIORITY} ]] |
283 | then |
284 | brctl setbridgeprio "${iface}" "${BRIDGE_PRIORITY}" |
285 | fi |
286 | |
287 | # configure forward delay |
288 | if [[ ! -z ${BRIDGE_FORWARD_DELAY} ]] |
289 | then |
290 | brctl setfd "${iface}" "${BRIDGE_FORWARD_DELAY}" |
291 | fi |
292 | |
293 | # configure hello time |
294 | if [[ ! -z ${BRIDGE_HELLO_TIME} ]] |
295 | then |
296 | brctl sethello "${iface}" "${BRIDGE_HELLO_TIME}" |
297 | fi |
298 | |
299 | # configure maximal message age |
300 | if [[ ! -z ${BRIDGE_MAX_MESSAGE_AGE} ]] |
301 | then |
302 | brctl setmaxage "${iface}" "${BRIDGE_MAX_MESSAGE_AGE}" |
303 | fi |
304 | |
305 | # configure path cost for every port |
306 | if [[ ! -z ${BRIDGE_PATH_COST} ]] |
307 | then |
308 | for i in ${BRIDGE_PATH_COST} |
309 | do |
310 | port="${i%=*}" |
311 | cost="${i#*=}" |
312 | [[ ! -z ${port} ]] && brctl pathcost "${iface}" "${port}" "${cost}" |
313 | done |
314 | fi |
315 | |
316 | # configure port priority for every port |
317 | if [[ ! -z ${BRIDGE_PORT_PRIORITY} ]] |
318 | then |
319 | for i in ${BRIDGE_PORT_PRIORITY} |
320 | do |
321 | port="${i%=*}" |
322 | prio="${i#*=}" |
323 | [[ ! -z ${port} ]] && brctl setportprio "${iface}" "${port}" "${prio}" |
324 | done |
325 | fi |
326 | } |
327 | |
328 | config_bridge_devices() |
329 | { |
330 | local iface="$1" |
331 | local method="$2" |
332 | local bport |
333 | |
334 | if [[ -z ${iface} ]] |
335 | then |
336 | echo "BRIDGE: no \$iface given. Aborting setup." |
337 | return 1 |
338 | fi |
339 | |
340 | if [[ -z ${method} ]] |
341 | then |
342 | echo "BRIDGE: no \$method given. Aborting setup." |
343 | return 1 |
344 | fi |
345 | |
346 | # first check for brctl |
347 | if [[ -z $(type -P brctl) ]] |
348 | then |
349 | echo "brctl not found! Please install 'net-misc/bridge-utils'." |
350 | return 1 |
351 | fi |
352 | |
353 | # check the config |
354 | if [[ -z ${BRIDGE_INTERFACES} ]] |
355 | then |
356 | echo "BRIDGE: no \$BRIDGE_INTERFACES given. Aborting setup." |
357 | return 1 |
358 | fi |
359 | |
360 | case ${method} in |
361 | add) |
362 | # setup the bridge device |
363 | brctl addbr "${iface}" |
364 | for bport in ${BRIDGE_INTERFACES} |
365 | do |
366 | # enter promiscous mode |
367 | ifconfig "${bport}" 0.0.0.0 promisc |
368 | # now setup the bridge |
369 | brctl addif "${iface}" "${bport}" |
370 | done |
371 | # configure all other options |
372 | config_bridge_options "${iface}" |
373 | ;; |
374 | |
375 | remove) |
376 | for bport in ${BRIDGE_INTERFACE} |
377 | do |
378 | # bring the interface down |
379 | ifconfig "${bport}" down |
380 | # remove the interface from the bridge |
381 | brctl delif "${iface}" "${bport}" |
382 | done |
383 | # bring the bridge down |
384 | brctl delbr "${iface}" |
385 | ;; |
386 | esac |
387 | |
388 | # unset the bridge variable to be safe |
389 | unset BRIDGE_INTERFACES |
390 | # continue to setup generic networking |
391 | } |
392 | |
393 | config_routes() |
394 | { |
395 | local method="$1" |
396 | local message |
397 | |
398 | # only add and del are allowed |
399 | case ${method} in |
400 | add) message="Adding" ;; |
401 | del) message="Removing" ;; |
402 | *) |
403 | echo "config_routes: unsupported \$method '${method}'." |
404 | exit 1 |
405 | ;; |
406 | esac |
407 | |
408 | # adds/delete user routes |
409 | if [[ -f /etc/conf.d/net.routes ]] |
410 | then |
411 | ( cat /etc/conf.d/net.routes; echo ) | # make sure there is a LF at the end |
412 | while read route |
413 | do |
414 | case "${route}" in |
415 | \#*|"") continue ;; |
416 | esac |
417 | # do not esacpe ${route} or it breaks! |
418 | route "${method}" ${route} |
419 | done |
420 | fi |
421 | } |
422 | |
423 | networking_start() |
424 | { |
425 | local iface dns routes ALL_INTERFACES |
426 | |
427 | if [[ -z $1 ]] |
428 | then |
429 | ALL_INTERFACES=$(onboot_interface_list /etc/conf.d/net.*) |
430 | else |
431 | if [[ -e /etc/conf.d/net.$1 ]] |
432 | then |
433 | ALL_INTERFACES="$1" |
434 | else |
435 | echo "Interface $1 does not exist. Aborting" |
436 | exit 1 |
437 | fi |
438 | fi |
439 | |
440 | # get list of all devices |
441 | for iface in ${ALL_INTERFACES} |
442 | do |
443 | # checkconfig |
444 | source /etc/conf.d/net.${iface} || exit 1 |
445 | checkconfig |
446 | |
447 | # wait until the device is created |
448 | wait_online 5 "${iface}" || { echo "device '${iface}' does not exist"; continue; } |
449 | |
450 | # setup mac |
451 | if [[ -n ${FORCE_MAC_TO} ]] |
452 | then |
453 | ifconfig "${iface}" hw ether "${FORCE_MAC_TO}" |
454 | fi |
455 | |
456 | # setup bridges |
457 | if [[ ${iface} = br[0-9]* ]] |
458 | then |
459 | config_bridge_devices "${iface}" add |
460 | fi |
461 | |
462 | # now configure wireless_extensions |
463 | [ -x $(type -P iwconfig) ] && setup_wireless_extensions "${iface}" |
464 | |
465 | # activate the interface |
466 | ifconfig "${iface}" up |
467 | |
468 | # setup static or dhcp |
469 | case ${NETWORKING} in |
470 | dhcp|DHCP) |
471 | ${DHCP_PROG} ${DHCP_START} "${iface}" ;; |
472 | static|STATIC) |
473 | ifconfig "${iface}" "${IP}" netmask "${NETMASK}" broadcast "${BROADCAST}" ;; |
474 | esac |
475 | |
476 | # setup def gw |
477 | if [[ -n ${GATEWAY} ]] |
478 | then |
479 | route add default gateway "${GATEWAY}" metric 1 dev "${iface}" |
480 | unset GATEWAY |
481 | fi |
482 | |
483 | # setup /etc/resolv.conf |
484 | # add given nameserver |
485 | if [[ -n ${NAMESERVER} ]] |
486 | then |
487 | # whipe out the old one |
488 | echo "# Generated by the magellan-initscripts for ${iface}" > /etc/resolv.conf |
489 | # include head |
490 | if [ -f /etc/resolv.conf.head ] |
491 | then |
492 | cat /etc/resolv.conf.head >> /etc/resolv.conf |
493 | else |
494 | echo "# /etc/resolv.conf.head can replace this line" >> /etc/resolv.conf |
495 | fi |
496 | |
497 | for dns in ${NAMESERVER} |
498 | do |
499 | echo "nameserver ${dns}" >> /etc/resolv.conf |
500 | done |
501 | |
502 | # include tail |
503 | if [ -f /etc/resolv.conf.tail ] |
504 | then |
505 | cat /etc/resolv.conf.tail >> /etc/resolv.conf |
506 | else |
507 | echo "# /etc/resolv.conf.tail can replace this line" >> /etc/resolv.conf |
508 | fi |
509 | |
510 | unset NAMESERVER |
511 | fi |
512 | done |
513 | |
514 | # setup user routes |
515 | config_routes add |
516 | } |
517 | |
518 | networking_stop() |
519 | { |
520 | if [[ -z $1 ]] |
521 | then |
522 | ALL_INTERFACES=$(onboot_interface_list /etc/conf.d/net.*) |
523 | else |
524 | if [[ -e /etc/conf.d/net.$1 ]] |
525 | then |
526 | ALL_INTERFACES="$1" |
527 | else |
528 | echo "Interface $1 does not exist. Aborting" |
529 | exit 1 |
530 | fi |
531 | fi |
532 | |
533 | # get list of all devices |
534 | for iface in ${ALL_INTERFACES} |
535 | do |
536 | source /etc/conf.d/net.${iface} || exit 1 |
537 | checkconfig |
538 | |
539 | if [[ -n ${GATEWAY} ]] |
540 | then |
541 | route del -net default |
542 | fi |
543 | |
544 | ifconfig "${iface}" down |
545 | |
546 | # remove bridges |
547 | if [[ ${iface} = br[0-9]* ]] |
548 | then |
549 | config_bridge_devices "${iface}" remove |
550 | fi |
551 | |
552 | # shutdown dhcp-daemon |
553 | if [[ ${NETWORKING} = dhcp ]] && [[ -n $(pidof $(basename ${DHCP_PROG})) ]] |
554 | then |
555 | if [[ -z ${DHCP_STOP} ]] |
556 | then |
557 | killall -15 ${DHCP_PROG} |
558 | sleep 1 |
559 | # try harder |
560 | if [[ -n $(pidof $(basename ${DHCP_PROG})) ]] |
561 | then |
562 | killall -9 ${DHCP_PROG} |
563 | fi |
564 | else |
565 | ${DHCP_PROG} ${DHCP_STOP} "${iface}" |
566 | fi |
567 | fi |
568 | |
569 | # shutdown wpa_supplicant daemon |
570 | if [[ -n $(pidof wpa_supplicant) ]] |
571 | then |
572 | killall wpa_supplicant |
573 | fi |
574 | done |
575 | |
576 | # remove state dir |
577 | if [ -d /run/wpa_supplicant ] |
578 | then |
579 | rm -rf /run/wpa_supplicant |
580 | fi |
581 | |
582 | # delete user routes |
583 | config_routes del |
584 | } |
585 | |
586 | case $1 in |
587 | start) |
588 | networking_start $2 ;; |
589 | |
590 | stop) |
591 | networking_stop $2 ;; |
592 | |
593 | restart) |
594 | $0 stop |
595 | sleep 1 |
596 | $0 start |
597 | ;; |
598 | |
599 | *) |
600 | echo "Usage: $0 {start|stop|restart} [interface]" |
601 | exit 1 |
602 | ;; |
603 | esac |