fixes OLSR 6and4 mode does not work if HNA entries are configured, closes #4803
[openwrt/svn-archive/archive.git] / net / olsrd / 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 IpVersion=4 AllowNoInt:bool=1 Pollrate=0.025 TcRedundancy=2 MprCoverage=3 LinkQualityFishEye=1 LinkQualityWinSize=100 LinkQualityDijkstraLimit=0+9.0 LinkQualityLevel=2 UseHysteresis:bool=0 FIBMetric=flat ClearScreen:bool=1 Willingness=3 LinkQualityAging=0.1 LinkQualityAlgorithm=etx_fpm'
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 Ip4Broadcast=255.255.255.255 HelloInterval=2.0 HelloValidityTime=40.0 TcInterval=5.0 TcValidityTime=100.0 MidInterval=18.0 MidValidityTime=324.0 HnaInterval=18.0 HnaValidityTime=108.0'
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
175 echo -n "${N}${param}PlParam \"$option\" \"$value\""
176
177 return 0
178 }
179
180 config_update_schema() {
181 unset IFS
182 local schema_varname="$1"
183 validate_varname "$schema_varname" || return 1
184 local command="$2"
185 validate_varname "$command" || return 1
186 local option="$3"
187 validate_varname "$option" || return 1
188 local value="$4"
189 local schema
190 local cur_option
191
192 case "$varname" in
193 *_LENGTH) return 0;;
194 *_ITEM*) return 0;;
195 esac
196
197 eval "export -n -- \"schema=\${$schema_varname}\""
198
199 for cur_option in $schema; do
200 [ "${cur_option%%[:=]*}" = "$option" ] && return 0
201 done
202
203 if [ "$command" = list ]; then
204 set -- $value
205 if [ "$#" -ge "3" ]; then
206 schema_entry="$option:list3"
207 elif [ "$#" -ge "2" ]; then
208 schema_entry="$option:list2"
209 else
210 schema_entry="$option:list"
211 fi
212 else
213 schema_entry="$option"
214 fi
215
216 append "$schema_varname" "$schema_entry"
217
218 return 0
219 }
220
221 config_write_options() {
222 unset IFS
223 local schema="$1"
224 local cfg="$2"
225 validate_varname "$cfg" || return 1
226 local write_func="$3"
227 [ -z "$write_func" ] && output_func=echo
228 local write_param="$4"
229 local schema_entry
230 local option
231 local option_length
232 local option_type
233 local default
234 local value
235 local list_size
236 local list_item
237 local list_value
238 local i
239 local position
240
241 for schema_entry in $schema; do
242 default="${schema_entry#*[=]}"
243 [ "$default" = "$schema_entry" ] && default=
244 option="${schema_entry%%[=]*}"
245 IFS=':'
246 set -- $option
247 unset IFS
248 option="$1"
249 option_type="$2"
250 validate_varname "$option" || continue
251 [ -z "$option_type" ] || validate_varname "$option_type" || continue
252 [ "$option_type" = internal ] && continue
253 config_get value "$cfg" "$option"
254
255 if [ -z "$value" ]; then
256 IFS='+'
257 set -- $default
258 unset IFS
259 value=$*
260 elif [ "$value" = '-' -a -n "$default" ]; then
261 continue
262 fi
263
264 [ -z "$value" ] && continue
265
266 case "$option_type" in
267 list) list_size=1;;
268 list2) list_size=2;;
269 list3) list_size=3;;
270 *) list_size=0;;
271 esac
272
273 if [ "$list_size" -gt 0 ]; then
274 config_get option_length "$cfg" "${option}_LENGTH"
275 if [ -n "$option_length" ]; then
276 i=1
277 while [ "$i" -le "$option_length" ]; do
278 config_get list_value "$cfg" "${option}_ITEM$i"
279 "$write_func" "$write_param" "$cfg" "$option" "$list_value" "$option_type" || break
280 i=$((i + 1))
281 done
282 else
283 list_value=
284 i=0
285 for list_item in $value; do
286 append "list_value" "$list_item"
287 i=$((i + 1))
288 position=$((i % list_size))
289 if [ "$position" -eq 0 ]; then
290 "$write_func" "$write_param" "$cfg" "$option" "$list_value" "$option_type" || break
291 list_value=
292 fi
293 done
294 [ "$position" -ne 0 ] && "$write_func" "$write_param" "$cfg" "$option" "$list_value" "$option_type"
295 fi
296 else
297 "$write_func" "$write_param" "$cfg" "$option" "$value" "$option_type"
298 fi
299 done
300
301 return 0
302 }
303
304 olsrd_write_olsrd() {
305 local cfg="$1"
306 validate_varname "$cfg" || return 0
307 local ignore
308 local ipversion
309
310 config_get_bool ignore "$cfg" ignore 0
311 [ "$ignore" -ne 0 ] && return 0
312
313 [ "$OLSRD_COUNT" -gt 0 ] && return 0
314
315 config_get ipversion "$cfg" IpVersion
316 if [ "$ipversion" = "6and4" ]; then
317 OLSRD_IPVERSION_6AND4=1
318 config_set "$cfg" IpVersion '6'
319 fi
320
321 config_write_options "$OLSRD_OLSRD_SCHEMA" "$cfg" olsrd_write_option
322 echo
323 OLSRD_COUNT=$((OLSRD_COUNT + 1))
324
325 return 0
326 }
327
328 olsrd_write_ipcconnect() {
329 local cfg="$1"
330 validate_varname "$cfg" || return 0
331 local ignore
332
333 config_get_bool ignore "$cfg" ignore 0
334 [ "$ignore" -ne 0 ] && return 0
335
336 [ "$IPCCONNECT_COUNT" -gt 0 ] && return 0
337
338 echo -n "${N}IpcConnect${N}{"
339 config_write_options "$OLSRD_IPCCONNECT_SCHEMA" "$cfg" olsrd_write_option "${T}"
340 echo "${N}}"
341 IPCCONNECT_COUNT=$((IPCCONNECT_COUNT + 1))
342
343 return 0
344 }
345
346 olsrd_write_hna4() {
347 local cfg="$1"
348 validate_varname "$cfg" || return 0
349 local ignore
350
351 config_get_bool ignore "$cfg" ignore 0
352 [ "$ignore" -ne 0 ] && return 0
353
354 config_get netaddr "$cfg" netaddr
355 if ! validate_olsrd_option "$netaddr"; then
356 warning_invalid_value olsrd "$cfg" "netaddr"
357 return 0
358 fi
359
360 config_get netmask "$cfg" netmask
361 if ! validate_olsrd_option "$netmask"; then
362 warning_invalid_value olsrd "$cfg" "netmask"
363 return 0
364 fi
365
366 [ "$HNA4_COUNT" -le 0 ] && echo -n "${N}Hna4${N}{"
367 echo -n "${N}${T}${T}$netaddr $netmask"
368 HNA4_COUNT=$((HNA4_COUNT + 1))
369
370 return 0
371 }
372
373 olsrd_write_hna6() {
374 local cfg="$1"
375 validate_varname "$cfg" || return 0
376 local ignore
377
378 config_get_bool ignore "$cfg" ignore 0
379 [ "$ignore" -ne 0 ] && return 0
380
381 config_get netaddr "$cfg" netaddr
382 if ! validate_olsrd_option "$netaddr"; then
383 warning_invalid_value olsrd "$cfg" "netaddr"
384 return 0
385 fi
386
387 config_get prefix "$cfg" prefix
388 if ! validate_olsrd_option "$prefix"; then
389 warning_invalid_value olsrd "$cfg" "prefix"
390 return 0
391 fi
392
393 [ "$HNA6_COUNT" -le 0 ] && echo -n "${N}Hna6${N}{"
394 echo -n "${N}${T}${T}$netaddr $prefix"
395 HNA6_COUNT=$((HNA6_COUNT + 1))
396
397 return 0
398 }
399
400 olsrd_write_loadplugin() {
401 local cfg="$1"
402 validate_varname "$cfg" || return 0
403 local ignore
404 local name
405 local suffix
406 local lat
407 local lon
408 local latlon_infile
409
410 config_get_bool ignore "$cfg" ignore 0
411 [ "$ignore" -ne 0 ] && return 0
412
413 config_get library "$cfg" library
414 if ! validate_olsrd_option "$library"; then
415 warning_invalid_value olsrd "$cfg" "library"
416 return 0
417 fi
418 if ! [ -x "/lib/$library" -o -x "/usr/lib/$library" -o -x "/usr/local/lib/$library" ]; then
419 echo "Warning: Plugin library '$library' not found, skipped" 1>&2
420 return 0
421 fi
422
423 case "$library" in
424 olsrd_nameservice.*)
425 config_get name "$cfg" name
426 [ -z "$name" ] && config_set "$cfg" name $SYSTEM_HOSTNAME
427
428 config_get suffix "$cfg" suffix
429 [ -z "$suffix" ] && config_set "$cfg" suffix '.olsr'
430
431 config_get lat "$cfg" lat
432 config_get lon "$cfg" lon
433 config_get latlon_infile "$cfg" latlon_infile
434 if [ \( -z "$lat" -o -z "$lat" \) -a -z "$latlon_infile" ]; then
435 if [ -f '/var/run/latlon.txt' ]; then
436 config_set "$cfg" lat ''
437 config_set "$cfg" lon ''
438 config_set "$cfg" latlon_infile '/var/run/latlon.txt'
439 else
440 config_set "$cfg" lat "$SYSTEM_LAT"
441 config_set "$cfg" lon "$SYSTEM_LON"
442 fi
443 fi
444
445 config_get latlon_file "$cfg" latlon_file
446 [ -z "$latlon_file" ] && config_set "$cfg" latlon_file '/var/run/latlon.js'
447 ;;
448 esac
449
450 echo -n "${N}LoadPlugin \"$library\"${N}{"
451 config_write_options "$OLSRD_LOADPLUGIN_SCHEMA" "$cfg" olsrd_write_plparam "${T}"
452 echo "${N}}"
453
454 return 0
455 }
456
457 olsrd_write_interface() {
458 local cfg="$1"
459 validate_varname "$cfg" || return 0
460 local ignore
461 local interfaces
462 local interface
463 local ifnames
464
465 config_get_bool ignore "$cfg" ignore 0
466 [ "$ignore" -ne 0 ] && return 0
467
468 ifnames=
469 config_get interfaces "$cfg" interface
470 for interface in $interfaces; do
471 if validate_varname "$interface"; then
472 if get_ifname "$interface"; then
473 ifnames="$ifnames \"$IFNAME\""
474 else
475 echo "Warning: Interface '$interface' not found, skipped" 1>&2
476 fi
477 else
478 warning_invalid_value olsrd "$cfg" "interface"
479 fi
480 done
481
482 [ -z "$ifnames" ] && return 0
483
484 echo -n "${N}Interface$ifnames${N}{"
485 config_write_options "$OLSRD_INTERFACE_SCHEMA" "$cfg" olsrd_write_option "${T}"
486 echo "${N}}"
487 INTERFACES_COUNT=$((INTERFACES_COUNT + 1))
488
489 return 0
490 }
491
492 olsrd_update_schema() {
493 local command="$1"
494 validate_varname "$command" || return 0
495 local varname="$2"
496 validate_varname "$varname" || return 0
497 local value="$3"
498 local cfg="$CONFIG_SECTION"
499 local cfgt
500 local cur_varname
501
502 config_get cfgt "$cfg" TYPE
503 case "$cfgt" in
504 olsrd) config_update_schema OLSRD_OLSRD_SCHEMA "$command" "$varname" "$value";;
505 IpcConnect) config_update_schema OLSRD_IPCCONNECT_SCHEMA "$command" "$varname" "$value";;
506 LoadPlugin) config_update_schema OLSRD_LOADPLUGIN_SCHEMA "$command" "$varname" "$value";;
507 Interface) config_update_schema OLSRD_INTERFACE_SCHEMA "$command" "$varname" "$value";;
508 esac
509
510 return 0
511 }
512
513 olsrd_write_config() {
514 OLSRD_IPVERSION_6AND4=0
515 OLSRD_COUNT=0
516 config_foreach olsrd_write_olsrd olsrd
517 IPCCONNECT_COUNT=0
518 config_foreach olsrd_write_ipcconnect IpcConnect
519 HNA4_COUNT=0
520 config_foreach olsrd_write_hna4 Hna4
521 [ "$HNA4_COUNT" -gt 0 ] && echo "${N}}"
522 HNA6_COUNT=0
523 config_foreach olsrd_write_hna6 Hna6
524 [ "$HNA6_COUNT" -gt 0 ] && echo "${N}}"
525 config_foreach olsrd_write_loadplugin LoadPlugin
526 INTERFACES_COUNT=0
527 config_foreach olsrd_write_interface Interface
528 echo
529
530 return 0
531 }
532
533 start() {
534 SYSTEM_HOSTNAME=
535 SYSTEM_LAT=
536 SYSTEM_LON=
537 config_load system
538 config_foreach system_config system
539
540 option_cb() {
541 olsrd_update_schema "option" "$@"
542 }
543
544 list_cb() {
545 olsrd_update_schema "list" "$@"
546 }
547
548 include /lib/network
549 scan_interfaces
550 config_load olsrd
551 reset_cb
552
553 OLSRD_CONFIG_FILE=
554 config_foreach olsrd_find_config_file olsrd
555
556 if [ -z "$OLSRD_CONFIG_FILE" ]; then
557 mkdir -p -- /var/etc/
558 olsrd_write_config > /var/etc/olsrd.conf
559 if [ "$INTERFACES_COUNT" -gt 0 -a "$OLSRD_COUNT" -gt 0 ]; then
560 OLSRD_CONFIG_FILE=/var/etc/olsrd.conf
561 fi
562 fi
563
564 [ -z "$OLSRD_CONFIG_FILE" ] && return 1
565
566 local bindv6only='0'
567 if [ "$OLSRD_IPVERSION_6AND4" -ne 0 ]; then
568 bindv6only="$(sysctl -n net.ipv6.bindv6only)"
569 sysctl -w net.ipv6.bindv6only=1
570 sed -e 's/^\t\t[0-9.]*[ ][0-9.]*$//' < "$OLSRD_CONFIG_FILE" > /var/etc/olsrd.conf.ipv6
571 olsrd -f /var/etc/olsrd.conf.ipv6 -nofork < /dev/null > /dev/null &
572
573 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
574 olsrd -f /var/etc/olsrd.conf.ipv4 -nofork < /dev/null > /dev/null &
575 sleep 3
576 sysctl -w net.ipv6.bindv6only="$bindv6only"
577 else
578 olsrd -f "$OLSRD_CONFIG_FILE" -nofork < /dev/null > /dev/null &
579 fi
580 }
581
582 stop() {
583 killall olsrd
584 }