b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame^] | 1 | #!/bin/sh /etc/rc.common |
| 2 | # Copyright (C) 2008-2017 OpenWrt.org |
| 3 | |
| 4 | OLSRD_OLSRD_SCHEMA='ignore:internal config_file:internal DebugLevel=0 AllowNoInt=yes' |
| 5 | OLSRD_IPCCONNECT_SCHEMA='ignore:internal Host:list Net:list2' |
| 6 | 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 ipv6only:bool' |
| 7 | OLSRD_INTERFACE_SCHEMA='ignore:internal interface:internal AutoDetectChanges:bool LinkQualityMult:list2' |
| 8 | OLSRD_INTERFACE_DEFAULTS_SCHEMA='AutoDetectChanges:bool' |
| 9 | |
| 10 | T=' ' |
| 11 | N=' |
| 12 | ' |
| 13 | |
| 14 | log() { |
| 15 | logger -t olsrd -p daemon.info -s "${initscript}: $*" |
| 16 | } |
| 17 | |
| 18 | error() { |
| 19 | logger -t olsrd -p daemon.err -s "${initscript}: ERROR: $*" |
| 20 | } |
| 21 | |
| 22 | warn() { |
| 23 | logger -t olsrd -p daemon.warn -s "${initscript}: WARNING: $*" |
| 24 | } |
| 25 | |
| 26 | validate_varname() { |
| 27 | local varname="$1" |
| 28 | [ -z "$varname" -o "$varname" != "${varname%%[!A-Za-z0-9_]*}" ] && return 1 |
| 29 | return 0 |
| 30 | } |
| 31 | |
| 32 | olsrd_list_configured_interfaces() |
| 33 | { |
| 34 | local i=0 |
| 35 | local interface |
| 36 | |
| 37 | while interface="$( uci -q get $OLSRD.@Interface[$i].interface )"; do { |
| 38 | case "$( uci -q get $OLSRD.@Interface[$i].ignore )" in |
| 39 | 1|on|true|enabled|yes) |
| 40 | # is disabled |
| 41 | ;; |
| 42 | *) |
| 43 | echo "$interface" # e.g. 'lan' |
| 44 | ;; |
| 45 | esac |
| 46 | |
| 47 | i=$(( i + 1 )) |
| 48 | } done |
| 49 | } |
| 50 | |
| 51 | olsrd_interface_already_in_config() |
| 52 | { |
| 53 | # e.g.: 'Interface "eth0.1" "eth0.2" "wlan0"' |
| 54 | if grep -s ^'Interface ' "/var/etc/$OLSRD.conf" | grep -q "\"$DEVICE\""; then |
| 55 | logger -t olsrd_hotplug -p daemon.debug "[OK] already_active: '$INTERFACE' => '$DEVICE'" |
| 56 | return 0 |
| 57 | else |
| 58 | logger -t olsrd_hotplug -p daemon.info "[OK] ifup: '$INTERFACE' => '$DEVICE'" |
| 59 | return 1 |
| 60 | fi |
| 61 | } |
| 62 | |
| 63 | olsrd_interface_needs_adding() |
| 64 | { |
| 65 | local interface |
| 66 | |
| 67 | # likely and cheap operation: |
| 68 | olsrd_interface_already_in_config && return 1 |
| 69 | |
| 70 | for interface in $(olsrd_list_configured_interfaces); do { |
| 71 | [ "$interface" = "$INTERFACE" ] && { |
| 72 | olsrd_interface_already_in_config || return 0 |
| 73 | } |
| 74 | } done |
| 75 | |
| 76 | logger -t olsrd_hotplug -p daemon.debug "[OK] interface '$INTERFACE' => '$DEVICE' not used for $OLSRD" |
| 77 | return 1 |
| 78 | } |
| 79 | |
| 80 | validate_olsrd_option() { |
| 81 | local str="$1" |
| 82 | [ -z "$str" -o "$str" != "${str%%[! 0-9A-Za-z.%/|:_-]*}" ] && return 1 |
| 83 | return 0 |
| 84 | } |
| 85 | |
| 86 | system_config() { |
| 87 | local cfg="$1" |
| 88 | local cfgt hostname latlon oldIFS |
| 89 | |
| 90 | config_get cfgt "$cfg" TYPE |
| 91 | |
| 92 | if [ "$cfgt" = "system" ]; then |
| 93 | config_get hostname "$cfg" hostname |
| 94 | hostname="${hostname:-OpenWrt}" |
| 95 | SYSTEM_HOSTNAME="$hostname" |
| 96 | fi |
| 97 | |
| 98 | if [ -z "$SYSTEM_LAT" -o -z "$SYSTEM_LON" ]; then |
| 99 | config_get latlon "$cfg" latlon |
| 100 | oldIFS="$IFS"; IFS=" ${T}${N},"; set -- $latlon; IFS="$oldIFS" |
| 101 | SYSTEM_LAT="$1" |
| 102 | SYSTEM_LON="$2" |
| 103 | fi |
| 104 | |
| 105 | if [ -z "$SYSTEM_LAT" -o -z "$SYSTEM_LON" ]; then |
| 106 | config_get latlon "$cfg" latitude |
| 107 | SYSTEM_LAT="$latlon" |
| 108 | config_get latlon "$cfg" longitude |
| 109 | SYSTEM_LON="$latlon" |
| 110 | fi |
| 111 | } |
| 112 | |
| 113 | olsrd_find_config_file() { |
| 114 | local cfg="$1" |
| 115 | validate_varname "$cfg" || return 0 |
| 116 | |
| 117 | config_get_bool ignore "$cfg" ignore 0 |
| 118 | [ "$ignore" -ne 0 ] && return 0 |
| 119 | config_get OLSRD_CONFIG_FILE "$cfg" config_file |
| 120 | |
| 121 | return 0 |
| 122 | } |
| 123 | |
| 124 | warning_invalid_value() { |
| 125 | local funcname="warning_invalid_value" |
| 126 | local package="$1" |
| 127 | validate_varname "$package" || package= |
| 128 | local config="$2" |
| 129 | validate_varname "$config" || config= |
| 130 | local option="$3" |
| 131 | validate_varname "$option" || option= |
| 132 | |
| 133 | if [ -n "$package" -a -n "$config" ]; then |
| 134 | log "$funcname() in option '$package.$config${option:+.}$option', skipped" |
| 135 | else |
| 136 | log "$funcname() skipped" |
| 137 | fi |
| 138 | |
| 139 | return 0 |
| 140 | } |
| 141 | |
| 142 | olsrd_write_option() { |
| 143 | local param="$1" |
| 144 | local cfg="$2" |
| 145 | validate_varname "$cfg" || return 1 |
| 146 | local option="$3" |
| 147 | validate_varname "$option" || return 1 |
| 148 | local value="$4" |
| 149 | local option_type="$5" |
| 150 | |
| 151 | if [ "$option_type" = bool ]; then |
| 152 | case "$value" in |
| 153 | 1|on|true|enabled|yes) value=yes;; |
| 154 | 0|off|false|disabled|no) value=no;; |
| 155 | *) warning_invalid_value olsrd "$cfg" "$option"; return 1;; |
| 156 | esac |
| 157 | fi |
| 158 | |
| 159 | if ! validate_olsrd_option "$value"; then |
| 160 | warning_invalid_value olsrd "$cfg" "$option" |
| 161 | return 1 |
| 162 | fi |
| 163 | |
| 164 | if [ "$value" != "${value%%[G-Zg-z_-]*}" ]; then |
| 165 | if [ "$option" != "Ip6AddrType" -a "$option" != "LinkQualityMult" -a "$value" != "yes" -a "$value" != "no" ]; then |
| 166 | value="\"$value\"" |
| 167 | fi |
| 168 | fi |
| 169 | |
| 170 | printf '%s' "${N}$param$option $value" |
| 171 | } |
| 172 | |
| 173 | olsrd_write_plparam() { |
| 174 | local funcname="olsrd_write_plparam" |
| 175 | local param="$1" |
| 176 | local cfg="$2" |
| 177 | local option="$3" |
| 178 | local value="$4" |
| 179 | local option_type="$5" |
| 180 | local _option oldIFS |
| 181 | |
| 182 | validate_varname "$cfg" || return 1 |
| 183 | validate_varname "$option" || return 1 |
| 184 | |
| 185 | if [ "$option_type" = bool ]; then |
| 186 | case "$value" in |
| 187 | 1|on|true|enabled|yes) value=yes;; |
| 188 | 0|off|false|disabled|no) value=no;; |
| 189 | *) warning_invalid_value olsrd "$cfg" "$option"; return 1;; |
| 190 | esac |
| 191 | fi |
| 192 | |
| 193 | if ! validate_olsrd_option "$value"; then |
| 194 | warning_invalid_value olsrd "$cfg" "$option" |
| 195 | return 1 |
| 196 | fi |
| 197 | |
| 198 | oldIFS="$IFS" |
| 199 | IFS='-_' |
| 200 | set -- $option |
| 201 | option="$*" |
| 202 | IFS="$oldIFS" |
| 203 | _option="$option" |
| 204 | |
| 205 | if [ "$option" = 'hosts' ]; then |
| 206 | set -- $value |
| 207 | option="$1" |
| 208 | shift |
| 209 | value="$*" |
| 210 | fi |
| 211 | |
| 212 | if [ "$option" = 'NonOlsrIf' ]; then |
| 213 | if validate_varname "$value"; then |
| 214 | if network_get_device ifname "$value"; then |
| 215 | log "$funcname() Info: mdns Interface '$value' ifname '$ifname' found" |
| 216 | else |
| 217 | log "$funcname() Warning: mdns Interface '$value' not found, skipped" |
| 218 | fi |
| 219 | else |
| 220 | warning_invalid_value olsrd "$cfg" "NonOlsrIf" |
| 221 | fi |
| 222 | |
| 223 | [ -z "$ifname" ] || value=$ifname |
| 224 | fi |
| 225 | |
| 226 | printf '%s' "${N}${param}PlParam \"$option\" \"$value\"" |
| 227 | } |
| 228 | |
| 229 | config_update_schema() { |
| 230 | local schema_varname="$1" |
| 231 | local command="$2" |
| 232 | local option="$3" |
| 233 | local value="$4" |
| 234 | local schema |
| 235 | local cur_option |
| 236 | |
| 237 | validate_varname "$schema_varname" || return 1 |
| 238 | validate_varname "$command" || return 1 |
| 239 | validate_varname "$option" || return 1 |
| 240 | |
| 241 | case "$varname" in |
| 242 | *_LENGTH) return 0;; |
| 243 | *_ITEM*) return 0;; |
| 244 | esac |
| 245 | |
| 246 | eval "export -n -- \"schema=\${$schema_varname}\"" |
| 247 | |
| 248 | for cur_option in $schema; do |
| 249 | [ "${cur_option%%[:=]*}" = "$option" ] && return 0 |
| 250 | done |
| 251 | |
| 252 | if [ "$command" = list ]; then |
| 253 | set -- $value |
| 254 | if [ "$#" -ge "3" ]; then |
| 255 | schema_entry="$option:list3" |
| 256 | elif [ "$#" -ge "2" ]; then |
| 257 | schema_entry="$option:list2" |
| 258 | else |
| 259 | schema_entry="$option:list" |
| 260 | fi |
| 261 | else |
| 262 | schema_entry="$option" |
| 263 | fi |
| 264 | |
| 265 | append "$schema_varname" "$schema_entry" |
| 266 | |
| 267 | return 0 |
| 268 | } |
| 269 | |
| 270 | config_write_options() { |
| 271 | local funcname="config_write_options" |
| 272 | local schema="$1" |
| 273 | local cfg="$2" |
| 274 | validate_varname "$cfg" || return 1 |
| 275 | local write_func="$3" |
| 276 | [ -z "$write_func" ] && output_func=echo |
| 277 | local write_param="$4" |
| 278 | |
| 279 | local schema_entry option option_length option_type default value list_size list_item list_value i position speed oldIFS |
| 280 | local list_speed_vars="HelloInterval HelloValidityTime TcInterval TcValidityTime MidInterval MidValidityTime HnaInterval HnaValidityTime" |
| 281 | |
| 282 | get_value_for_entry() |
| 283 | { |
| 284 | local schema_entry="$1" |
| 285 | |
| 286 | default="${schema_entry#*[=]}" |
| 287 | [ "$default" = "$schema_entry" ] && default= |
| 288 | option="${schema_entry%%[=]*}" |
| 289 | |
| 290 | oldIFS="$IFS"; IFS=':'; set -- $option; IFS="$oldIFS" |
| 291 | option="$1" |
| 292 | option_type="$2" |
| 293 | |
| 294 | validate_varname "$option" || return 1 |
| 295 | [ -z "$option_type" ] || validate_varname "$option_type" || return 1 |
| 296 | [ "$option_type" = internal ] && return 1 |
| 297 | |
| 298 | config_get value "$cfg" "$option" |
| 299 | [ "$option" = "speed" ] && return 1 |
| 300 | |
| 301 | return 0 |
| 302 | } |
| 303 | |
| 304 | already_in_schema() |
| 305 | { |
| 306 | case " $schema " in |
| 307 | *" $1 "*) |
| 308 | return 0 |
| 309 | ;; |
| 310 | *) |
| 311 | return 1 |
| 312 | ;; |
| 313 | esac |
| 314 | } |
| 315 | |
| 316 | already_in_schema "speed" && { |
| 317 | get_value_for_entry "speed" |
| 318 | |
| 319 | if test 2>/dev/null "$value" -gt 0 -a "$value" -le 20 ; then |
| 320 | speed="$value" |
| 321 | else |
| 322 | log "$funcname() Warning: invalid speed-value: '$value' - allowed integers: 1...20, fallback to 6" |
| 323 | speed=6 |
| 324 | fi |
| 325 | |
| 326 | for schema_entry in $list_speed_vars; do { |
| 327 | already_in_schema "$schema_entry" || schema="$schema $schema_entry" |
| 328 | } done |
| 329 | } |
| 330 | |
| 331 | for schema_entry in $schema; do |
| 332 | if [ -n "$speed" ]; then # like sven-ola freifunk firmware fff-1.7.4 |
| 333 | case "$schema_entry" in |
| 334 | HelloInterval) |
| 335 | value="$(( speed / 2 + 1 )).0" |
| 336 | ;; |
| 337 | HelloValidityTime) |
| 338 | value="$(( speed * 25 )).0" |
| 339 | ;; |
| 340 | TcInterval) # todo: not fisheye? -> $(( speed * 2 )) |
| 341 | value=$(( speed / 2 )) |
| 342 | [ $value -eq 0 ] && value=1 |
| 343 | value="$value.0" |
| 344 | ;; |
| 345 | TcValidityTime) |
| 346 | value="$(( speed * 100 )).0" |
| 347 | ;; |
| 348 | MidInterval) |
| 349 | value="$(( speed * 5 )).0" |
| 350 | ;; |
| 351 | MidValidityTime) |
| 352 | value="$(( speed * 100 )).0" |
| 353 | ;; |
| 354 | HnaInterval) |
| 355 | value="$(( speed * 2 )).0" |
| 356 | ;; |
| 357 | HnaValidityTime) |
| 358 | value="$(( speed * 25 )).0" |
| 359 | ;; |
| 360 | *) |
| 361 | get_value_for_entry "$schema_entry" || continue |
| 362 | ;; |
| 363 | esac |
| 364 | |
| 365 | is_speed_var() |
| 366 | { |
| 367 | case " $list_speed_vars " in |
| 368 | *" $1 "*) |
| 369 | return 0 |
| 370 | ;; |
| 371 | *) |
| 372 | return 1 |
| 373 | ;; |
| 374 | esac |
| 375 | } |
| 376 | |
| 377 | is_speed_var "$schema_entry" && option="$schema_entry" |
| 378 | else |
| 379 | get_value_for_entry "$schema_entry" || continue |
| 380 | fi |
| 381 | |
| 382 | if [ -z "$value" ]; then |
| 383 | oldIFS="$IFS"; IFS='+'; set -- $default; IFS="$oldIFS" |
| 384 | value=$* |
| 385 | elif [ "$value" = '-' -a -n "$default" ]; then |
| 386 | continue |
| 387 | fi |
| 388 | |
| 389 | [ -z "$value" ] && continue |
| 390 | |
| 391 | case "$option_type" in |
| 392 | list) list_size=1;; |
| 393 | list2) list_size=2;; |
| 394 | list3) list_size=3;; |
| 395 | *) list_size=0;; |
| 396 | esac |
| 397 | |
| 398 | if [ "$list_size" -gt 0 ]; then |
| 399 | config_get option_length "$cfg" "${option}_LENGTH" |
| 400 | if [ -n "$option_length" ]; then |
| 401 | i=1 |
| 402 | while [ "$i" -le "$option_length" ]; do |
| 403 | config_get list_value "$cfg" "${option}_ITEM$i" |
| 404 | "$write_func" "$write_param" "$cfg" "$option" "$list_value" "$option_type" || break |
| 405 | i=$((i + 1)) |
| 406 | done |
| 407 | else |
| 408 | list_value= |
| 409 | i=0 |
| 410 | for list_item in $value; do |
| 411 | append "list_value" "$list_item" |
| 412 | i=$((i + 1)) |
| 413 | position=$((i % list_size)) |
| 414 | if [ "$position" -eq 0 ]; then |
| 415 | "$write_func" "$write_param" "$cfg" "$option" "$list_value" "$option_type" || break |
| 416 | list_value= |
| 417 | fi |
| 418 | done |
| 419 | [ "$position" -ne 0 ] && "$write_func" "$write_param" "$cfg" "$option" "$list_value" "$option_type" |
| 420 | fi |
| 421 | else |
| 422 | "$write_func" "$write_param" "$cfg" "$option" "$value" "$option_type" |
| 423 | fi |
| 424 | done |
| 425 | |
| 426 | return 0 |
| 427 | } |
| 428 | |
| 429 | olsrd_write_olsrd() { |
| 430 | local cfg="$1" |
| 431 | validate_varname "$cfg" || return 0 |
| 432 | local ignore |
| 433 | |
| 434 | config_get_bool ignore "$cfg" ignore 0 |
| 435 | [ "$ignore" -ne 0 ] && return 0 |
| 436 | |
| 437 | [ "$OLSRD_COUNT" -gt 0 ] && return 0 |
| 438 | |
| 439 | config_get smartgateway "$cfg" SmartGateway |
| 440 | config_get smartgatewayuplink "$cfg" SmartGatewayUplink |
| 441 | export smartgateway |
| 442 | export smartgatewayuplink |
| 443 | |
| 444 | config_write_options "$OLSRD_OLSRD_SCHEMA" "$cfg" olsrd_write_option |
| 445 | echo |
| 446 | OLSRD_COUNT=$((OLSRD_COUNT + 1)) |
| 447 | return 0 |
| 448 | } |
| 449 | |
| 450 | olsrd_write_ipcconnect() { |
| 451 | local cfg="$1" |
| 452 | validate_varname "$cfg" || return 0 |
| 453 | local ignore |
| 454 | |
| 455 | config_get_bool ignore "$cfg" ignore 0 |
| 456 | [ "$ignore" -ne 0 ] && return 0 |
| 457 | |
| 458 | [ "$IPCCONNECT_COUNT" -gt 0 ] && return 0 |
| 459 | |
| 460 | printf '%s' "${N}IpcConnect${N}{" |
| 461 | config_write_options "$OLSRD_IPCCONNECT_SCHEMA" "$cfg" olsrd_write_option "${T}" |
| 462 | echo "${N}}" |
| 463 | IPCCONNECT_COUNT=$((IPCCONNECT_COUNT + 1)) |
| 464 | } |
| 465 | |
| 466 | olsrd_write_hna4() { |
| 467 | local cfg="$1" |
| 468 | validate_varname "$cfg" || return 0 |
| 469 | local ignore |
| 470 | |
| 471 | config_get_bool ignore "$cfg" ignore 0 |
| 472 | [ "$ignore" -ne 0 ] && return 0 |
| 473 | |
| 474 | config_get netaddr "$cfg" netaddr |
| 475 | if ! validate_olsrd_option "$netaddr"; then |
| 476 | warning_invalid_value olsrd "$cfg" "netaddr" |
| 477 | return 0 |
| 478 | fi |
| 479 | |
| 480 | config_get netmask "$cfg" netmask |
| 481 | if ! validate_olsrd_option "$netmask"; then |
| 482 | warning_invalid_value olsrd "$cfg" "netmask" |
| 483 | return 0 |
| 484 | fi |
| 485 | |
| 486 | [ "$HNA4_COUNT" -le 0 ] && printf '%s' "${N}Hna4${N}{" |
| 487 | printf '%s' "${N}${T}${T}$netaddr $netmask" |
| 488 | HNA4_COUNT=$((HNA4_COUNT + 1)) |
| 489 | } |
| 490 | |
| 491 | olsrd_write_hna6() { |
| 492 | local cfg="$1" |
| 493 | validate_varname "$cfg" || return 0 |
| 494 | local ignore |
| 495 | |
| 496 | config_get_bool ignore "$cfg" ignore 0 |
| 497 | [ "$ignore" -ne 0 ] && return 0 |
| 498 | |
| 499 | config_get netaddr "$cfg" netaddr |
| 500 | if ! validate_olsrd_option "$netaddr"; then |
| 501 | warning_invalid_value olsrd "$cfg" "netaddr" |
| 502 | return 0 |
| 503 | fi |
| 504 | |
| 505 | config_get prefix "$cfg" prefix |
| 506 | if ! validate_olsrd_option "$prefix"; then |
| 507 | warning_invalid_value olsrd "$cfg" "prefix" |
| 508 | return 0 |
| 509 | fi |
| 510 | |
| 511 | [ "$HNA6_COUNT" -le 0 ] && printf '%s' "${N}Hna6${N}{" |
| 512 | printf '%s' "${N}${T}${T}$netaddr $prefix" |
| 513 | HNA6_COUNT=$((HNA6_COUNT + 1)) |
| 514 | } |
| 515 | |
| 516 | find_most_recent_plugin_libary() |
| 517 | { |
| 518 | local library="$1" # e.g. 'olsrd_dyn_gw' or 'olsrd_txtinfo.so.1.1' |
| 519 | local file file_fullpath unixtime |
| 520 | |
| 521 | for file in "/lib/$library"* "/usr/lib/$library"* "/usr/local/lib/$library"*; do { |
| 522 | [ -f "$file" ] && { |
| 523 | file_fullpath="$file" |
| 524 | file="$( basename "$file" )" |
| 525 | # make sure that we do not select |
| 526 | # 'olsrd_dyn_gw_plain.so.0.4' if user wants |
| 527 | # 'olsrd_dyn_gw.so.0.5' -> compare part before 1st dot |
| 528 | [ "${library%%.*}" = "${file%%.*}" ] && { |
| 529 | unixtime="$( date +%s -r "$file_fullpath" )" |
| 530 | echo "$unixtime $file" |
| 531 | } |
| 532 | } |
| 533 | } done | sort -n | tail -n1 | cut -d' ' -f2 |
| 534 | } |
| 535 | |
| 536 | olsrd_write_loadplugin() |
| 537 | { |
| 538 | local funcname='olsrd_write_loadplugin' |
| 539 | local cfg="$1" |
| 540 | local ignore name suffix lat lon latlon_infile |
| 541 | |
| 542 | validate_varname "$cfg" || return 0 |
| 543 | |
| 544 | config_get_bool ignore "$cfg" ignore 0 |
| 545 | [ "$ignore" -ne 0 ] && return 0 |
| 546 | |
| 547 | # e.g. olsrd_txtinfo.so.1.1 or 'olsrd_txtinfo' |
| 548 | config_get library "$cfg" library |
| 549 | |
| 550 | library="$( find_most_recent_plugin_libary "$library" )" |
| 551 | if [ -z "$library" ]; then |
| 552 | log "$funcname() Warning: Plugin library '$library' not found, skipped" |
| 553 | return 0 |
| 554 | else |
| 555 | library="$( basename "$library" )" |
| 556 | fi |
| 557 | |
| 558 | validate_olsrd_option "$library" || { |
| 559 | warning_invalid_value olsrd "$cfg" 'library' |
| 560 | return 0 |
| 561 | } |
| 562 | |
| 563 | case "$library" in |
| 564 | 'olsrd_nameservice.'*) |
| 565 | config_get name "$cfg" name |
| 566 | [ -z "$name" ] && config_set "$cfg" name $SYSTEM_HOSTNAME |
| 567 | |
| 568 | config_get suffix "$cfg" suffix |
| 569 | [ -z "$suffix" ] && config_set "$cfg" suffix '.olsr' |
| 570 | |
| 571 | config_get lat "$cfg" lat |
| 572 | config_get lon "$cfg" lon |
| 573 | config_get latlon_infile "$cfg" latlon_infile |
| 574 | if [ \( -z "$lat" -o -z "$lat" \) -a -z "$latlon_infile" ]; then |
| 575 | if [ -f '/var/run/latlon.txt' ]; then |
| 576 | config_set "$cfg" lat '' |
| 577 | config_set "$cfg" lon '' |
| 578 | config_set "$cfg" latlon_infile '/var/run/latlon.txt' |
| 579 | else |
| 580 | config_set "$cfg" lat "$SYSTEM_LAT" |
| 581 | config_set "$cfg" lon "$SYSTEM_LON" |
| 582 | fi |
| 583 | fi |
| 584 | |
| 585 | for f in latlon_file hosts_file services_file resolv_file macs_file; do |
| 586 | config_get $f "$cfg" $f |
| 587 | done |
| 588 | |
| 589 | [ -z "$latlon_file" ] && config_set "$cfg" latlon_file '/var/run/latlon.js' |
| 590 | ;; |
| 591 | 'olsrd_watchdog.'*) |
| 592 | config_get wd_file "$cfg" file |
| 593 | ;; |
| 594 | esac |
| 595 | |
| 596 | printf '%s' "${N}LoadPlugin \"$library\"${N}{" |
| 597 | config_write_options "$OLSRD_LOADPLUGIN_SCHEMA" "$cfg" olsrd_write_plparam "${T}" |
| 598 | echo "${N}}" |
| 599 | } |
| 600 | |
| 601 | olsrd_write_interface() { |
| 602 | local funcname="olsrd_write_interface" |
| 603 | local cfg="$1" |
| 604 | validate_varname "$cfg" || return 0 |
| 605 | local ignore |
| 606 | local interfaces |
| 607 | local interface |
| 608 | local ifnames |
| 609 | |
| 610 | config_get_bool ignore "$cfg" ignore 0 |
| 611 | [ "$ignore" -ne 0 ] && return 0 |
| 612 | |
| 613 | ifnames= |
| 614 | config_get interfaces "$cfg" interface |
| 615 | |
| 616 | for interface in $interfaces; do |
| 617 | if validate_varname "$interface"; then |
| 618 | if network_get_device IFNAME "$interface"; then |
| 619 | ifnames="$ifnames \"$IFNAME\"" |
| 620 | ifsglobal="$ifsglobal $IFNAME" |
| 621 | elif network_get_physdev IFNAME "$interface"; then |
| 622 | local proto="$(uci -q get network.${interface}.proto)" |
| 623 | if [ "$proto" = "static" -o "$proto" = "none" ]; then |
| 624 | ifnames="$ifnames \"$IFNAME\"" |
| 625 | ifsglobal="$ifsglobal $IFNAME" |
| 626 | fi |
| 627 | elif [[ "$(ip -details link show dev $interface)" == *"wireguard"* ]]; then |
| 628 | # wireguard interface |
| 629 | ifnames="$ifnames \"$interface\"" |
| 630 | ifsglobal="$ifsglobal $interface" |
| 631 | else |
| 632 | log "$funcname() Warning: Interface '$interface' not found, skipped" |
| 633 | fi |
| 634 | else |
| 635 | warning_invalid_value olsrd "$cfg" "interface" |
| 636 | fi |
| 637 | done |
| 638 | |
| 639 | [ -z "$ifnames" ] && return 0 |
| 640 | |
| 641 | printf '%s' "${N}Interface$ifnames${N}{" |
| 642 | config_write_options "$OLSRD_INTERFACE_SCHEMA" "$cfg" olsrd_write_option "${T}" |
| 643 | echo "${N}}" |
| 644 | INTERFACES_COUNT=$((INTERFACES_COUNT + 1)) |
| 645 | } |
| 646 | |
| 647 | olsrd_write_interface_defaults() { |
| 648 | local cfg="$1" |
| 649 | validate_varname "$cfg" || return 0 |
| 650 | |
| 651 | printf '%s' "${N}InterfaceDefaults$ifnames${N}{" |
| 652 | config_write_options "$OLSRD_INTERFACE_DEFAULTS_SCHEMA" "$cfg" olsrd_write_option "${T}" |
| 653 | echo "${N}}" |
| 654 | |
| 655 | return 1 |
| 656 | } |
| 657 | |
| 658 | olsrd_update_schema() { |
| 659 | local command="$1" |
| 660 | local varname="$2" |
| 661 | local value="$3" |
| 662 | local cfg="$CONFIG_SECTION" |
| 663 | local cfgt |
| 664 | |
| 665 | validate_varname "$command" || return 0 |
| 666 | validate_varname "$varname" || return 0 |
| 667 | |
| 668 | config_get cfgt "$cfg" TYPE |
| 669 | case "$cfgt" in |
| 670 | olsrd) config_update_schema OLSRD_OLSRD_SCHEMA "$command" "$varname" "$value";; |
| 671 | IpcConnect) config_update_schema OLSRD_IPCCONNECT_SCHEMA "$command" "$varname" "$value";; |
| 672 | LoadPlugin) config_update_schema OLSRD_LOADPLUGIN_SCHEMA "$command" "$varname" "$value";; |
| 673 | Interface) config_update_schema OLSRD_INTERFACE_SCHEMA "$command" "$varname" "$value";; |
| 674 | InterfaceDefaults) config_update_schema OLSRD_INTERFACE_DEFAULTS_SCHEMA "$command" "$varname" "$value";; |
| 675 | esac |
| 676 | |
| 677 | return 0 |
| 678 | } |
| 679 | |
| 680 | olsrd_write_config() { |
| 681 | OLSRD_COUNT=0 |
| 682 | config_foreach olsrd_write_olsrd olsrd |
| 683 | IPCCONNECT_COUNT=0 |
| 684 | config_foreach olsrd_write_ipcconnect IpcConnect |
| 685 | HNA4_COUNT=0 |
| 686 | config_foreach olsrd_write_hna4 Hna4 |
| 687 | [ "$HNA4_COUNT" -gt 0 ] && echo "${N}}" |
| 688 | HNA6_COUNT=0 |
| 689 | config_foreach olsrd_write_hna6 Hna6 |
| 690 | [ "$HNA6_COUNT" -gt 0 ] && echo "${N}}" |
| 691 | config_foreach olsrd_write_loadplugin LoadPlugin |
| 692 | INTERFACES_COUNT=0 |
| 693 | config_foreach olsrd_write_interface_defaults InterfaceDefaults |
| 694 | config_foreach olsrd_write_interface Interface |
| 695 | echo |
| 696 | |
| 697 | return 0 |
| 698 | } |
| 699 | |
| 700 | get_wan_ifnames() |
| 701 | { |
| 702 | local wanifnames word catch_next |
| 703 | |
| 704 | command -v ip >/dev/null || return 1 |
| 705 | |
| 706 | set -- $( ip route list exact 0.0.0.0/0 table all ) |
| 707 | for word in $*; do |
| 708 | case "$word" in |
| 709 | dev) |
| 710 | catch_next="true" |
| 711 | ;; |
| 712 | *) |
| 713 | [ -n "$catch_next" ] && { |
| 714 | case "$wanifnames" in |
| 715 | *" $word "*) |
| 716 | ;; |
| 717 | *) |
| 718 | wanifnames="$wanifnames $word " |
| 719 | ;; |
| 720 | esac |
| 721 | |
| 722 | catch_next= |
| 723 | } |
| 724 | ;; |
| 725 | esac |
| 726 | done |
| 727 | |
| 728 | echo "$wanifnames" |
| 729 | } |
| 730 | |
| 731 | olsrd_setup_smartgw_rules() { |
| 732 | local funcname="olsrd_setup_smartgw_rules" |
| 733 | local file= |
| 734 | |
| 735 | for file in /etc/modules.d/[0-9]*-ipip; do :; done |
| 736 | [ -e "$file" ] || { |
| 737 | log "$funcname() Warning: kmod-ipip is missing. SmartGateway will not work until you install it." |
| 738 | return 1 |
| 739 | } |
| 740 | |
| 741 | local wanifnames="$( get_wan_ifnames )" |
| 742 | |
| 743 | if [ -z "$wanifnames" ]; then |
| 744 | nowan=1 |
| 745 | else |
| 746 | nowan=0 |
| 747 | fi |
| 748 | |
| 749 | IP4T="$( command -v iptables )" |
| 750 | IP6T="$( command -v ip6tables )" |
| 751 | |
| 752 | # Delete smartgw firewall rules first |
| 753 | if [ "$UCI_CONF_NAME" = "olsrd6" ]; then |
| 754 | while $IP6T -D forwarding_rule -o tnl_+ -j ACCEPT 2> /dev/null; do :;done |
| 755 | for IFACE in $wanifnames; do |
| 756 | while $IP6T -D forwarding_rule -i tunl0 -o $IFACE -j ACCEPT 2> /dev/null; do :; done |
| 757 | done |
| 758 | for IFACE in $ifsglobal; do |
| 759 | while $IP6T -D input_rule -i $IFACE -p 4 -j ACCEPT 2> /dev/null; do :; done |
| 760 | done |
| 761 | else |
| 762 | while $IP4T -D forwarding_rule -o tnl_+ -j ACCEPT 2> /dev/null; do :;done |
| 763 | for IFACE in $wanifnames; do |
| 764 | while $IP4T -D forwarding_rule -i tunl0 -o $IFACE -j ACCEPT 2> /dev/null; do :; done |
| 765 | done |
| 766 | for IFACE in $ifsglobal; do |
| 767 | while $IP4T -D input_rule -i $IFACE -p 4 -j ACCEPT 2> /dev/null; do :; done |
| 768 | done |
| 769 | while $IP4T -t nat -D postrouting_rule -o tnl_+ -j MASQUERADE 2> /dev/null; do :;done |
| 770 | fi |
| 771 | |
| 772 | # var 'smartgateway' + 'smartgatewayuplink' build in olsrd_write_olsrd() |
| 773 | if [ "$smartgateway" = "yes" ]; then |
| 774 | log "$funcname() Notice: Inserting firewall rules for SmartGateway" |
| 775 | |
| 776 | if [ ! "$smartgatewayuplink" = "none" ]; then |
| 777 | if [ "$smartgatewayuplink" = "ipv4" ]; then |
| 778 | # Allow everything to be forwarded to tnl_+ and use NAT for it |
| 779 | $IP4T -I forwarding_rule -o tnl_+ -j ACCEPT |
| 780 | $IP4T -t nat -I postrouting_rule -o tnl_+ -j MASQUERADE |
| 781 | # Allow forwarding from tunl0 to (all) wan-interfaces |
| 782 | if [ "$nowan" = '0' ]; then |
| 783 | for IFACE in $wanifnames; do |
| 784 | $IP4T -A forwarding_rule -i tunl0 -o $IFACE -j ACCEPT |
| 785 | done |
| 786 | fi |
| 787 | # Allow incoming ipip on all olsr-interfaces |
| 788 | for IFACE in $ifsglobal; do |
| 789 | $IP4T -I input_rule -i $IFACE -p 4 -j ACCEPT |
| 790 | done |
| 791 | elif [ "$smartgatewayuplink" = "ipv6" ]; then |
| 792 | $IP6T -I forwarding_rule -o tnl_+ -j ACCEPT |
| 793 | if [ "$nowan" = '0' ]; then |
| 794 | for IFACE in $wanifnames; do |
| 795 | $IP6T -A forwarding_rule -i tunl0 -o $IFACE -j ACCEPT |
| 796 | done |
| 797 | fi |
| 798 | for IFACE in $ifsglobal; do |
| 799 | $IP6T -I input_rule -i $IFACE -p 4 -j ACCEPT |
| 800 | done |
| 801 | else |
| 802 | $IP4T -t nat -I postrouting_rule -o tnl_+ -j MASQUERADE |
| 803 | for IPT in $IP4T $IP6T; do |
| 804 | $IPT -I forwarding_rule -o tnl_+ -j ACCEPT |
| 805 | if [ "$nowan" = '0' ]; then |
| 806 | for IFACE in $wanifnames; do |
| 807 | $IPT -A forwarding_rule -i tunl0 -o $IFACE -j ACCEPT |
| 808 | done |
| 809 | fi |
| 810 | for IFACE in $ifsglobal; do |
| 811 | $IPT -I input_rule -i $IFACE -p 4 -j ACCEPT |
| 812 | done |
| 813 | done |
| 814 | fi |
| 815 | fi |
| 816 | fi |
| 817 | } |
| 818 | |
| 819 | olsrd_generate_config() { |
| 820 | UCI_CONF_NAME="$1" |
| 821 | SYSTEM_HOSTNAME= |
| 822 | SYSTEM_LAT= |
| 823 | SYSTEM_LON= |
| 824 | config_load system |
| 825 | config_foreach system_config system |
| 826 | |
| 827 | option_cb() { |
| 828 | olsrd_update_schema "option" "$@" |
| 829 | } |
| 830 | |
| 831 | list_cb() { |
| 832 | olsrd_update_schema "list" "$@" |
| 833 | } |
| 834 | |
| 835 | . /lib/functions/network.sh |
| 836 | |
| 837 | config_load $UCI_CONF_NAME |
| 838 | reset_cb |
| 839 | |
| 840 | OLSRD_CONFIG_FILE= |
| 841 | config_foreach olsrd_find_config_file olsrd |
| 842 | |
| 843 | if [ -z "$OLSRD_CONFIG_FILE" ]; then |
| 844 | mkdir -p -- /var/etc/ |
| 845 | olsrd_write_config > /var/etc/$UCI_CONF_NAME.conf || return 1 |
| 846 | if [ "$INTERFACES_COUNT" -gt 0 -a "$OLSRD_COUNT" -gt 0 ]; then |
| 847 | OLSRD_CONFIG_FILE=/var/etc/$UCI_CONF_NAME.conf |
| 848 | fi |
| 849 | fi |
| 850 | |
| 851 | [ -z "$OLSRD_CONFIG_FILE" ] && return 1 |
| 852 | } |