contrib/package/olsrd-luci: disable icmp redirects on startup and re-enable on stop
[project/luci.git] / contrib / package / olsrd-luci / files / etc / init.d / olsrd
1 #!/bin/sh /etc/rc.common
2 # Copyright (C) 2008 Alina Friedrichsen <x-alina@gmx.net>
3 # Special thanks to bittorf wireless ))
4 START=50
5
6 BIN=/usr/sbin/olsrd
7 CONF=/var/etc/olsrd.conf
8 PID=/var/run/olsrd.pid
9
10 OLSRD_OLSRD_SCHEMA='ignore:internal config_file:internal DebugLevel=0 IpVersion=4 AllowNoInt:bool=1 Pollrate=0.025 TcRedundancy=2 MprCoverage=3 LinkQualityFishEye=1 LinkQualityDijkstraLimit=0+9.0 FIBMetric=flat ClearScreen:bool=1 Willingness=3 LinkQualityAging=0.1 LinkQualityAlgorithm=etx_fpm'
11 OLSRD_IPCCONNECT_SCHEMA='ignore:internal Host:list Net:list2'
12 OLSRD_LOADPLUGIN_SCHEMA='ignore:internal library:internal Host:list Net:list2 Ping:list redistribute:list NonOlsrIf:list name:list lat lon latlon_infile HNA:list2 hosts:list2'
13 OLSRD_INTERFACE_SCHEMA='ignore:internal interface:internal AutoDetectChanges:bool Ip4Broadcast HelloInterval=5.0 HelloValidityTime=40.0 TcInterval=2.0 TcValidityTime=100.0 MidInterval=18.0 MidValidityTime=324.0 HnaInterval=18.0 HnaValidityTime=108.0'
14
15 T=' '
16 N='
17 '
18
19 validate_varname() {
20 local varname=$1
21 [ -z "$varname" -o "$varname" != "${varname%%[!A-Za-z0-9_]*}" ] && return 1
22 return 0
23 }
24
25 validate_ifname() {
26 local ifname=$1
27 [ -z "$ifname" -o "$ifname" != "${ifname%%[!A-Za-z0-9.:_-]*}" ] && return 1
28 return 0
29 }
30
31 validate_olsrd_option() {
32 local str=$1
33 [ -z "$str" -o "$str" != "${str%%[! 0-9A-Za-z./:_-]*}" ] && return 1
34 return 0
35 }
36
37 get_ifname() {
38 IFNAME=
39 local interface=$1
40 validate_varname "$interface" || return 1
41 local ifname
42
43 config_get ifname "$interface" ifname
44 validate_ifname "$ifname" || return 1
45 IFNAME=$ifname
46
47 return 0
48 }
49
50 system_config() {
51 local cfg=$1
52 local cfgt
53 local hostname
54 local latlon
55
56 config_get cfgt "$cfg" TYPE
57
58 if [ "$cfgt" = "system" ]; then
59 config_get hostname "$cfg" hostname
60 hostname=${hostname:-OpenWrt}
61 SYSTEM_HOSTNAME=$hostname
62 fi
63
64 if [ -z "$SYSTEM_LAT" -o -z "$SYSTEM_LON" ]; then
65 config_get latlon "$cfg" latlon
66 IFS=" ${T}${N},"
67 set -- $latlon
68 unset IFS
69 SYSTEM_LAT=$1
70 SYSTEM_LON=$2
71 fi
72 }
73
74 olsrd_find_config_file() {
75 local cfg=$1
76 validate_varname "$cfg" || return 0
77
78 config_get_bool ignore "$cfg" ignore 0
79 [ "$ignore" -ne 0 ] && return 0
80 config_get OLSRD_CONFIG_FILE "$cfg" config_file
81
82 return 0
83 }
84
85 warning_invalid_value() {
86 local package=$1
87 validate_varname "$package" || package=
88 local config=$2
89 validate_varname "$config" || config=
90 local option=$3
91 validate_varname "$option" || option=
92
93 echo -n "Warning: Invalid value" 1>&2
94
95 if [ -n "$package" -a -n "$config" ]; then
96 echo -n " in option '$package.$config${option:+.}$option'" 1>&2
97 fi
98
99 echo ", skipped" 1>&2
100
101 return 0
102 }
103
104 olsrd_write_option() {
105 local param=$1
106 local cfg=$2
107 validate_varname "$cfg" || return 1
108 local option=$3
109 validate_varname "$option" || return 1
110 local value=$4
111 local option_type=$5
112
113 if [ "$option_type" = bool ]; then
114 case "$value" in
115 1|on|true|enabled|yes) value=yes;;
116 0|off|false|disabled|no) value=no;;
117 *) warning_invalid_value olsrd "$cfg" "$option"; return 1;;
118 esac
119 fi
120
121 if ! validate_olsrd_option "$value"; then
122 warning_invalid_value olsrd "$cfg" "$option"
123 return 1
124 fi
125
126 if [ "$value" != "${value%%[G-Zg-z_-]*}" ]; then
127 if [ "$option" != "Ip6AddrType" -a "$value" != "yes" -a "$value" != "no" ]; then
128 value="\"$value\""
129 fi
130 fi
131
132 echo -n "${N}$param$option $value"
133
134 return 0
135 }
136
137 olsrd_write_plparam() {
138 local param=$1
139 local cfg=$2
140 validate_varname "$cfg" || return 1
141 local option=$3
142 validate_varname "$option" || return 1
143 local value=$4
144 local option_type=$5
145 local _option
146
147 if [ "$option_type" = bool ]; then
148 case "$value" in
149 1|on|true|enabled|yes) value=yes;;
150 0|off|false|disabled|no) value=no;;
151 *) warning_invalid_value olsrd "$cfg" "$option"; return 1;;
152 esac
153 fi
154
155 if ! validate_olsrd_option "$value"; then
156 warning_invalid_value olsrd "$cfg" "$option"
157 return 1
158 fi
159
160 IFS='-_'
161 set -- $option
162 option="$*"
163 unset IFS
164 _option="$option"
165 if [ "$option" = 'hosts' ]; then
166 set -- $value
167 option=$1
168 shift
169 value="$*"
170 fi
171
172 echo -n "${N}${param}PlParam \"$option\" \"$value\""
173
174 return 0
175 }
176
177 config_update_schema() {
178 unset IFS
179 local schema_varname=$1
180 validate_varname "$schema_varname" || return 1
181 local command=$2
182 validate_varname "$command" || return 1
183 local option=$3
184 validate_varname "$option" || return 1
185 local value=$4
186 local schema
187 local cur_option
188
189 case "$varname" in
190 *_LENGTH) return 0;;
191 *_ITEM*) return 0;;
192 esac
193
194 eval "export -n -- \"schema=\${$schema_varname}\""
195
196 for cur_option in $schema; do
197 [ "${cur_option%%[:=]*}" = "$option" ] && return 0
198 done
199
200 if [ "$command" = list ]; then
201 set -- $value
202 if [ "$#" -ge "3" ]; then
203 schema_entry="$option:list3"
204 elif [ "$#" -ge "2" ]; then
205 schema_entry="$option:list2"
206 else
207 schema_entry="$option:list"
208 fi
209 else
210 schema_entry="$option"
211 fi
212
213 append "$schema_varname" "$schema_entry"
214
215 return 0
216 }
217
218 config_write_options() {
219 unset IFS
220 local schema=$1
221 local cfg=$2
222 validate_varname "$cfg" || return 1
223 local write_func=$3
224 [ -z "$write_func" ] && output_func=echo
225 local write_param=$4
226 local schema_entry
227 local option
228 local option_length
229 local option_type
230 local default
231 local value
232 local list_size
233 local list_item
234 local list_value
235 local i
236 local position
237
238 for schema_entry in $schema; do
239 default=${schema_entry#*[=]}
240 [ "$default" = "$schema_entry" ] && default=
241 option=${schema_entry%%[=]*}
242 IFS=':'
243 set -- $option
244 unset IFS
245 option=$1
246 option_type=$2
247 validate_varname "$option" || continue
248 [ -z "$option_type" ] || validate_varname "$option_type" || continue
249 [ "$option_type" = internal ] && continue
250 config_get value "$cfg" "$option"
251
252 if [ -z "$value" ]; then
253 IFS='+'
254 set -- $default
255 unset IFS
256 value=$*
257 elif [ "$value" = '-' -a -n "$default" ]; then
258 continue
259 fi
260
261 [ -z "$value" ] && continue
262
263 case "$option_type" in
264 list) list_size=1;;
265 list2) list_size=2;;
266 list3) list_size=3;;
267 *) list_size=0;;
268 esac
269
270 if [ "$list_size" -gt 0 ]; then
271 config_get option_length "$cfg" "${option}_LENGTH"
272 if [ -n "$option_length" ]; then
273 i=1
274 while [ "$i" -le "$option_length" ]; do
275 config_get list_value "$cfg" "${option}_ITEM$i"
276 "$write_func" "$write_param" "$cfg" "$option" "$list_value" "$option_type" || break
277 i=$((i + 1))
278 done
279 else
280 list_value=
281 i=0
282 for list_item in $value; do
283 append "list_value" "$list_item"
284 i=$((i + 1))
285 position=$((i % list_size))
286 if [ "$position" -eq 0 ]; then
287 "$write_func" "$write_param" "$cfg" "$option" "$list_value" "$option_type" || break
288 list_value=
289 fi
290 done
291 [ "$position" -ne 0 ] && "$write_func" "$write_param" "$cfg" "$option" "$list_value" "$option_type"
292 fi
293 else
294 "$write_func" "$write_param" "$cfg" "$option" "$value" "$option_type"
295 fi
296 done
297
298 return 0
299 }
300
301 olsrd_write_olsrd() {
302 local cfg=$1
303 validate_varname "$cfg" || return 0
304 local ignore
305
306 config_get_bool ignore "$cfg" ignore 0
307 [ "$ignore" -ne 0 ] && return 0
308
309 [ "$OLSRD_COUNT" -gt 0 ] && return 0
310
311 config_write_options "$OLSRD_OLSRD_SCHEMA" "$cfg" olsrd_write_option
312 echo
313 OLSRD_COUNT=$((OLSRD_COUNT + 1))
314
315 return 0
316 }
317
318 olsrd_write_ipcconnect() {
319 local cfg=$1
320 validate_varname "$cfg" || return 0
321 local ignore
322
323 config_get_bool ignore "$cfg" ignore 0
324 [ "$ignore" -ne 0 ] && return 0
325
326 [ "$IPCCONNECT_COUNT" -gt 0 ] && return 0
327
328 echo -n "${N}IpcConnect${N}{"
329 config_write_options "$OLSRD_IPCCONNECT_SCHEMA" "$cfg" olsrd_write_option "${T}"
330 echo "${N}}"
331 IPCCONNECT_COUNT=$((IPCCONNECT_COUNT + 1))
332
333 return 0
334 }
335
336 olsrd_write_hna4() {
337 local cfg=$1
338 validate_varname "$cfg" || return 0
339 local ignore
340
341 config_get_bool ignore "$cfg" ignore 0
342 [ "$ignore" -ne 0 ] && return 0
343
344 config_get netaddr "$cfg" netaddr
345 if ! validate_olsrd_option "$netaddr"; then
346 warning_invalid_value olsrd "$cfg" "netaddr"
347 return 0
348 fi
349
350 config_get netmask "$cfg" netmask
351 if ! validate_olsrd_option "$netmask"; then
352 warning_invalid_value olsrd "$cfg" "netmask"
353 return 0
354 fi
355
356 [ "$HNA4_COUNT" -le 0 ] && echo -n "${N}Hna4${N}{"
357 echo -n "${N}${T}$netaddr $netmask"
358 HNA4_COUNT=$((HNA4_COUNT + 1))
359
360 return 0
361 }
362
363 olsrd_write_hna6() {
364 local cfg=$1
365 validate_varname "$cfg" || return 0
366 local ignore
367
368 config_get_bool ignore "$cfg" ignore 0
369 [ "$ignore" -ne 0 ] && return 0
370
371 config_get netaddr "$cfg" netaddr
372 if ! validate_olsrd_option "$netaddr"; then
373 warning_invalid_value olsrd "$cfg" "netaddr"
374 return 0
375 fi
376
377 config_get prefix "$cfg" prefix
378 if ! validate_olsrd_option "$prefix"; then
379 warning_invalid_value olsrd "$cfg" "prefix"
380 return 0
381 fi
382
383 [ "$HNA6_COUNT" -le 0 ] && echo -n "${N}Hna6${N}{"
384 echo -n "${N}${T}$netaddr $prefix"
385 HNA6_COUNT=$((HNA6_COUNT + 1))
386
387 return 0
388 }
389
390 olsrd_write_loadplugin() {
391 local cfg=$1
392 validate_varname "$cfg" || return 0
393 local ignore
394 local name
395 local suffix
396 local lat
397 local lon
398 local latlon_infile
399
400 config_get_bool ignore "$cfg" ignore 0
401 [ "$ignore" -ne 0 ] && return 0
402
403 config_get library "$cfg" library
404 if ! validate_olsrd_option "$library"; then
405 warning_invalid_value olsrd "$cfg" "library"
406 return 0
407 fi
408 if ! [ -x "/lib/$library" -o -x "/usr/lib/$library" -o -x "/usr/local/lib/$library" ]; then
409 echo "Warning: Plugin library '$library' not found, skipped" 1>&2
410 return 0
411 fi
412
413 case "$library" in
414 olsrd_nameservice.*)
415 config_get name "$cfg" name
416 [ -z "$name" ] && config_set "$cfg" name $SYSTEM_HOSTNAME
417
418 config_get suffix "$cfg" suffix
419 [ -z "$suffix" ] && config_set "$cfg" suffix '.olsr'
420
421 config_get lat "$cfg" lat
422 config_get lon "$cfg" lon
423 config_get latlon_infile "$cfg" latlon_infile
424 if [ \( -z "$lat" -o -z "$lat" \) -a -z "$latlon_infile" ]; then
425 if [ -f '/var/run/latlon.txt' ]; then
426 config_set "$cfg" lat ''
427 config_set "$cfg" lon ''
428 config_set "$cfg" latlon_infile '/var/run/latlon.txt'
429 else
430 config_set "$cfg" lat "$SYSTEM_LAT"
431 config_set "$cfg" lon "$SYSTEM_LON"
432 fi
433 fi
434
435 config_get latlon_file "$cfg" latlon_file
436 ;;
437 esac
438
439 echo -n "${N}LoadPlugin \"$library\"${N}{"
440 config_write_options "$OLSRD_LOADPLUGIN_SCHEMA" "$cfg" olsrd_write_plparam "${T}"
441 echo "${N}}"
442
443 return 0
444 }
445
446 olsrd_write_interface() {
447 local cfg=$1
448 validate_varname "$cfg" || return 0
449 local ignore
450 local interfaces
451 local interface
452 local ifnames
453
454 config_get_bool ignore "$cfg" ignore 0
455 [ "$ignore" -ne 0 ] && return 0
456
457 ifnames=
458 config_get interfaces "$cfg" interface
459 for interface in $interfaces; do
460 if validate_varname "$interface"; then
461 if get_ifname "$interface"; then
462 ifnames="$ifnames \"$IFNAME\""
463 else
464 echo "Warning: Interface '$interface' not found, skipped" 1>&2
465 fi
466 else
467 warning_invalid_value olsrd "$cfg" "interface"
468 fi
469 done
470
471 [ -z "$ifnames" ] && return 0
472
473 echo -n "${N}Interface$ifnames${N}{"
474 config_write_options "$OLSRD_INTERFACE_SCHEMA" "$cfg" olsrd_write_option "${T}"
475 echo "${N}}"
476 INTERFACES_COUNT=$((INTERFACES_COUNT + 1))
477
478 return 0
479 }
480
481 olsrd_update_schema() {
482 local command="$1"
483 validate_varname "$command" || return 0
484 local varname="$2"
485 validate_varname "$varname" || return 0
486 local value="$3"
487 local cfg="$CONFIG_SECTION"
488 local cfgt
489 local cur_varname
490
491 config_get cfgt "$cfg" TYPE
492 case "$cfgt" in
493 olsrd) config_update_schema OLSRD_OLSRD_SCHEMA "$command" "$varname" "$value";;
494 IpcConnect) config_update_schema OLSRD_IPCCONNECT_SCHEMA "$command" "$varname" "$value";;
495 LoadPlugin) config_update_schema OLSRD_LOADPLUGIN_SCHEMA "$command" "$varname" "$value";;
496 Interface) config_update_schema OLSRD_INTERFACE_SCHEMA "$command" "$varname" "$value";;
497 esac
498
499 return 0
500 }
501
502 olsrd_write_config() {
503 OLSRD_COUNT=0
504 config_foreach olsrd_write_olsrd olsrd
505 IPCCONNECT_COUNT=0
506 config_foreach olsrd_write_ipcconnect IpcConnect
507 HNA4_COUNT=0
508 config_foreach olsrd_write_hna4 Hna4
509 [ "$HNA4_COUNT" -gt 0 ] && echo "${N}}"
510 HNA6_COUNT=0
511 config_foreach olsrd_write_hna6 Hna6
512 [ "$HNA6_COUNT" -gt 0 ] && echo "${N}}"
513 config_foreach olsrd_write_loadplugin LoadPlugin
514 INTERFACES_COUNT=0
515 config_foreach olsrd_write_interface Interface
516 echo
517
518 return 0
519 }
520
521 start() {
522 ### check for running instance
523 if [ -s $PID ]; then
524 if kill -0 $(cat $PID) 2>&-; then
525 echo "there is already a running instance ($(cat $PID))"
526 return 1
527 fi
528 fi
529
530 ### disable icmp redirects
531 echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects
532
533 SYSTEM_HOSTNAME=
534 SYSTEM_LAT=
535 SYSTEM_LON=
536 config_load system
537 config_foreach system_config system
538
539 option_cb() {
540 olsrd_update_schema "option" "$@"
541 }
542
543 list_cb() {
544 olsrd_update_schema "list" "$@"
545 }
546
547 include /lib/network
548 scan_interfaces
549 config_load olsrd
550 reset_cb
551
552 OLSRD_CONFIG_FILE=
553 config_foreach olsrd_find_config_file olsrd
554
555 if [ -z "$OLSRD_CONFIG_FILE" ]; then
556 ### generate config
557 mkdir -p ${CONF%/*}
558 olsrd_write_config > $CONF
559 if [ "$INTERFACES_COUNT" -gt 0 -a "$OLSRD_COUNT" -gt 0 ]; then
560 OLSRD_CONFIG_FILE=$CONF
561 fi
562 fi
563
564 [ -z "$OLSRD_CONFIG_FILE" ] && return 1
565
566 ### start olsrd
567 start-stop-daemon -q -b -m -p $PID -x $BIN -S -- -f $CONF -nofork
568 }
569
570 stop() {
571 ### stop olsrd
572 start-stop-daemon -q -p $PID -x $BIN -K
573
574 ### re-enable icmp redirects
575 echo 1 > /proc/sys/net/ipv4/conf/all/send_redirects
576 }
577
578 restart() {
579 ### override generic restart because we need some time between stop and start
580 stop; sleep 3; start
581 }