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