[packages] olsrd: init: for better reuse, make a function out of a procedure get_valu...
[feed/routing.git] / files / olsrd.init
index dd82bb5619eca09eebdeff76d9d3e21ee0fa682b..6ed369fc473ece892417b1e81c81436537976896 100644 (file)
@@ -1,8 +1,15 @@
 #!/bin/sh /etc/rc.common
-# Copyright (C) 2008  Alina Friedrichsen <x-alina@gmx.net>
-# Special thanks to bittorf wireless ))
+# Copyright (C) 2008-2012 OpenWrt.org
+
 START=65
 
+SERVICE_DAEMONIZE=1
+SERVICE_WRITE_PID=1
+
+CONF=/var/etc/olsrd.conf
+PID=/var/run/olsrd.pid
+PID6=/var/run/olsrd.ipv6.pid
+
 OLSRD_OLSRD_SCHEMA='ignore:internal config_file:internal DebugLevel=0 AllowNoInt=yes'
 OLSRD_IPCCONNECT_SCHEMA='ignore:internal Host:list Net:list2'
 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'
@@ -13,37 +20,23 @@ T=' '
 N='
 '
 
+log()
+{
+       logger -t olsrd -p daemon.info -s "$1"
+}
+
 validate_varname() {
        local varname="$1"
        [ -z "$varname" -o "$varname" != "${varname%%[!A-Za-z0-9_]*}" ] && return 1
        return 0
 }
 
-validate_ifname() {
-       local ifname="$1"
-       [ -z "$ifname" -o "$ifname" != "${ifname%%[!A-Za-z0-9.:_-]*}" ] && return 1
-       return 0
-}
-
 validate_olsrd_option() {
        local str="$1"
        [ -z "$str" -o "$str" != "${str%%[!     0-9A-Za-z./|:_-]*}" ] && return 1
        return 0
 }
 
-get_ifname() {
-       IFNAME=
-       local interface="$1"
-       validate_varname "$interface" || return 1
-       local ifname
-
-       config_get ifname "$interface" ifname
-       validate_ifname "$ifname" || return 1
-       IFNAME="$ifname"
-
-       return 0
-}
-
 system_config() {
        local cfg="$1"
        local cfgt
@@ -87,6 +80,7 @@ olsrd_find_config_file() {
 }
 
 warning_invalid_value() {
+       local funcname="warning_invalid_value"
        local package="$1"
        validate_varname "$package" || package=
        local config="$2"
@@ -94,14 +88,12 @@ warning_invalid_value() {
        local option="$3"
        validate_varname "$option" || option=
 
-       echo -n "Warning: Invalid value" 1>&2
-
        if [ -n "$package" -a -n "$config" ]; then
-               echo -n " in option '$package.$config${option:+.}$option'" 1>&2
+               log "$funcname() in option '$package.$config${option:+.}$option', skipped"
+       else
+               log "$funcname() skipped"
        fi
 
-       echo ", skipped" 1>&2
-
        return 0
 }
 
@@ -139,6 +131,7 @@ olsrd_write_option() {
 }
 
 olsrd_write_plparam() {
+       local funcname="olsrd_write_plparam"
        local param="$1"
        local cfg="$2"
        validate_varname "$cfg" || return 1
@@ -174,11 +167,10 @@ olsrd_write_plparam() {
        fi
        if [ "$option" = 'NonOlsrIf' ]; then
                if validate_varname "$value"; then
-                       if get_ifname "$value"; then
-                               ifname="$IFNAME"
-                               echo "Info: mdns Interface '$value' ifname '$ifname' found" 1>&2
+                       if network_get_device ifname "$value"; then
+                               log "$funcname() Info: mdns Interface '$value' ifname '$ifname' found"
                        else
-                               echo "Warning: mdns Interface '$value' not found, skipped" 1>&2
+                               log "$funcname() Warning: mdns Interface '$value' not found, skipped"
                        fi
                else
                        warning_invalid_value olsrd "$cfg" "NonOlsrIf"
@@ -240,6 +232,7 @@ config_write_options() {
        local write_func="$3"
        [ -z "$write_func" ] && output_func=echo
        local write_param="$4"
+
        local schema_entry
        local option
        local option_length
@@ -252,20 +245,30 @@ config_write_options() {
        local i
        local position
 
-       for schema_entry in $schema; do
+       get_value_for_entry()
+       {
+               local schema_entry="$1"
+
                default="${schema_entry#*[=]}"
                [ "$default" = "$schema_entry" ] && default=
                option="${schema_entry%%[=]*}"
-               IFS=':'
-               set -- $option
-               unset IFS
+
+               IFS=':'; set -- $option; unset IFS
                option="$1"
                option_type="$2"
-               validate_varname "$option" || continue
-               [ -z "$option_type" ] || validate_varname "$option_type" || continue
-               [ "$option_type" = internal ] && continue
+
+               validate_varname "$option" || return 1
+               [ -z "$option_type" ] || validate_varname "$option_type" || return 1
+               [ "$option_type" = internal ] && return 1
+
                config_get value "$cfg" "$option"
 
+               return 0
+       }
+
+       for schema_entry in $schema; do
+               get_value_for_entry "$schema_entry" || continue
+
                if [ -z "$value" ]; then
                        IFS='+'
                        set -- $default
@@ -319,7 +322,6 @@ olsrd_write_olsrd() {
        local cfg="$1"
        validate_varname "$cfg" || return 0
        local ignore
-       local ipversion
 
        config_get_bool ignore "$cfg" ignore 0
        [ "$ignore" -ne 0 ] && return 0
@@ -331,11 +333,12 @@ olsrd_write_olsrd() {
                OLSRD_IPVERSION_6AND4=1
                config_set "$cfg" IpVersion '6'
        fi
+       config_get smartgateway "$cfg" SmartGateway
+       config_get smartgatewayuplink "$cfg" SmartGatewayUplink
 
        config_write_options "$OLSRD_OLSRD_SCHEMA" "$cfg" olsrd_write_option
        echo
        OLSRD_COUNT=$((OLSRD_COUNT + 1))
-
        return 0
 }
 
@@ -412,6 +415,7 @@ olsrd_write_hna6() {
 }
 
 olsrd_write_loadplugin() {
+       local funcname="olsrd_write_loadplugin"
        local cfg="$1"
        validate_varname "$cfg" || return 0
        local ignore
@@ -430,7 +434,7 @@ olsrd_write_loadplugin() {
                return 0
        fi
        if ! [ -x "/lib/$library" -o -x "/usr/lib/$library" -o -x "/usr/local/lib/$library" ]; then
-               echo "Warning: Plugin library '$library' not found, skipped" 1>&2
+               log "$funcname() Warning: Plugin library '$library' not found, skipped"
                return 0
        fi
 
@@ -456,9 +460,15 @@ olsrd_write_loadplugin() {
                                fi
                        fi
 
-                       config_get latlon_file "$cfg" latlon_file
+                       for f in latlon_file hosts_file services_file resolv_file macs_file; do
+                               config_get $f "$cfg" $f
+                       done
+
                        [ -z "$latlon_file" ] && config_set "$cfg" latlon_file '/var/run/latlon.js'
                ;;
+               olsrd_watchdog.*)
+                       config_get wd_file "$cfg" file
+               ;;
        esac
 
        echo -n "${N}LoadPlugin \"$library\"${N}{"
@@ -469,6 +479,7 @@ olsrd_write_loadplugin() {
 }
 
 olsrd_write_interface() {
+       local funcname="olsrd_write_interface"
        local cfg="$1"
        validate_varname "$cfg" || return 0
        local ignore
@@ -481,12 +492,14 @@ olsrd_write_interface() {
 
        ifnames=
        config_get interfaces "$cfg" interface
+
        for interface in $interfaces; do
                if validate_varname "$interface"; then
-                       if get_ifname "$interface"; then
+                       if network_get_device IFNAME "$interface"; then
                                ifnames="$ifnames \"$IFNAME\""
+                               ifsglobal="$ifsglobal $IFNAME"
                        else
-                               echo "Warning: Interface '$interface' not found, skipped" 1>&2
+                               log "$funcname() Warning: Interface '$interface' not found, skipped"
                        fi
                else
                        warning_invalid_value olsrd "$cfg" "interface"
@@ -557,6 +570,117 @@ olsrd_write_config() {
        return 0
 }
 
+get_wan_ifnames()
+{
+       local wanifnames word catch_next
+
+       which ip >/dev/null || return 1
+
+       set -- $( ip route list exact 0.0.0.0/0 table all )
+       for word in $*; do
+               case "$word" in
+                       dev)
+                               catch_next="true"
+                       ;;
+                       *)
+                               [ -n "$catch_next" ] && {
+                                       case "$wanifnames" in
+                                               *" $word "*)
+                                               ;;
+                                               *)
+                                                       wanifnames="$wanifnames $word "
+                                               ;;
+                                       esac
+
+                                       catch_next=
+                               }
+                       ;;
+               esac
+       done
+
+       echo "$wanifnames"
+}
+
+olsrd_setup_smartgw_rules() {
+       local funcname="olsrd_setup_smartgw_rules"
+       # Check if ipip is installed
+       [ -e /etc/modules.d/[0-9]*-ipip ] || {
+               log "$funcname() Warning: kmod-ipip is missing. SmartGateway will not work until you install it."
+               return 1
+       }
+
+       local wanifnames="$( get_wan_ifnames )"
+
+       if [ -z "$wanifnames" ]; then
+               nowan=1
+       else
+               nowan=0
+       fi
+
+       IP4T=$(which iptables)
+       IP6T=$(which ip6tables)
+
+       # Delete smartgw firewall rules first
+       for IPT in $IP4T $IP6T; do
+               while $IPT -D forwarding_rule -o tnl_+ -j ACCEPT 2> /dev/null; do :;done
+               for IFACE in $wanifnames; do
+                       while $IPT -D forwarding_rule -i tunl0 -o $IFACE -j ACCEPT 2> /dev/null; do :; done
+               done
+               for IFACE in $ifsglobal; do
+                       while $IPT -D input_rule -i $IFACE -p 4 -j ACCEPT 2> /dev/null; do :; done
+               done
+       done
+       while $IP4T -t nat -D postrouting_rule -o tnl_+ -j MASQUERADE 2> /dev/null; do :;done
+
+       if [ "$smartgateway" == "yes" ]; then
+               log "$funcname() Notice: Inserting firewall rules for SmartGateway"
+               if [ ! "$smartgatewayuplink" == "none" ]; then
+                       if [ "$smartgatewayuplink" == "ipv4" ]; then
+                               # Allow everything to be forwarded to tnl_+ and use NAT for it
+                               $IP4T -I forwarding_rule -o tnl_+ -j ACCEPT
+                               $IP4T -t nat -I postrouting_rule -o tnl_+ -j MASQUERADE
+                               # Allow forwarding from tunl0 to (all) wan-interfaces
+                               if [ "$nowan"="0" ]; then
+                                       for IFACE in $wanifnames; do
+                                               $IP4T -A forwarding_rule -i tunl0 -o $IFACE -j ACCEPT
+                                       done
+                               fi
+                               # Allow incoming ipip on all olsr-interfaces
+                               for IFACE in $ifsglobal; do
+                                       $IP4T -I input_rule -i $IFACE -p 4 -j ACCEPT
+                               done
+                       elif [ "$smartgatewayuplink" == "ipv6" ]; then
+                               $IP6T -I forwarding_rule -o tnl_+ -j ACCEPT
+                               if [ "$nowan"="0" ]; then
+                                       for IFACE in $wanifnames; do
+                                               $IP6T -A forwarding_rule -i tunl0 -o $IFACE -j ACCEPT
+                                       done
+                               fi
+                               for IFACE in $ifsglobal; do
+                                       $IP6T -I input_rule -i $IFACE -p 4 -j ACCEPT
+                               done
+                       else
+                               for IPT in $IP4T $IP6T; do
+                                       $IPT -I forwarding_rule -o tnl_+ -j ACCEPT
+                                       $IPT -t nat -I postrouting_rule -o tnl_+ -j MASQUERADE
+                                       if [ "$nowan"="0" ]; then
+                                               for IFACE in $wanifnames; do
+                                                       $IPT -A forwarding_rule -i tunl0 -o $IFACE -j ACCEPT
+                                               done
+                                       fi
+                                       for IFACE in $ifsglobal; do
+                                               $IPT -I input_rule -i $IFACE -p 4 -j ACCEPT
+                                       done
+                               done
+                       fi
+               fi
+       fi
+}
+
+error() {
+       log "error() ${initscript}: $@"
+}
+
 start() {
        SYSTEM_HOSTNAME=
        SYSTEM_LAT=
@@ -572,8 +696,8 @@ start() {
                olsrd_update_schema "list" "$@"
        }
 
-       include /lib/network
-       scan_interfaces
+       . /lib/functions/network.sh
+
        config_load olsrd
        reset_cb
 
@@ -593,20 +717,55 @@ start() {
        local bindv6only='0'
        if [ "$OLSRD_IPVERSION_6AND4" -ne 0 ]; then
                bindv6only="$(sysctl -n net.ipv6.bindv6only)"
-               sysctl -w net.ipv6.bindv6only=1
-               sed -e 's/^\t\t[0-9.]*[ ][0-9.]*$//' < "$OLSRD_CONFIG_FILE" > /var/etc/olsrd.conf.ipv6
-               sed -i '/[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/d' /var/etc/olsrd.conf.ipv6
-               olsrd -f /var/etc/olsrd.conf.ipv6 -nofork < /dev/null > /dev/null &
-
+               sysctl -w net.ipv6.bindv6only=1 > /dev/null
+               sed -e '/[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/d' < "$OLSRD_CONFIG_FILE" > /var/etc/olsrd.conf.ipv6
                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
-               olsrd -f /var/etc/olsrd.conf.ipv4 -nofork < /dev/null > /dev/null &
+               rm $OLSRD_CONFIG_FILE
+
+               # some filenames should get the suffix .ipv6
+               for file in $latlon_file $hosts_file $services_file $resolv_file $macs_file $wd_file;do
+                       f=$(echo $file|sed 's/\//\\\//g')
+                       sed -i "s/$f/$f.ipv6/g" /var/etc/olsrd.conf.ipv6
+               done
+
+               SERVICE_PID_FILE="$PID6"
+               if service_check /usr/sbin/olsrd; then
+                       error "there is already an IPv6 instance of olsrd running (pid: '$(cat $PID6)'), not starting."
+               else
+                       service_start /usr/sbin/olsrd -f /var/etc/olsrd.conf.ipv6 -nofork
+               fi
+
+               SERVICE_PID_FILE="$PID"
+               if service_check /usr/sbin/olsrd; then
+                       error "there is already an IPv4 instance of olsrd running (pid: '$(cat $PID)'), not starting."
+               else
+                       service_start /usr/sbin/olsrd -f /var/etc/olsrd.conf.ipv4 -nofork
+               fi
+
                sleep 3
-               sysctl -w net.ipv6.bindv6only="$bindv6only"
+               sysctl -w net.ipv6.bindv6only="$bindv6only" > /dev/null
+
        else
-               olsrd -f "$OLSRD_CONFIG_FILE" -nofork < /dev/null > /dev/null &
+
+               if [ "$ipversion" = "6" ]; then
+                       sed -i '/[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/d' "$OLSRD_CONFIG_FILE"
+               fi
+
+               SERVICE_PID_FILE="$PID"
+               if service_check /usr/sbin/olsrd; then
+                       error "there is already an IPv4 instance of olsrd running (pid: '$(cat $PID)'), not starting."
+                       return 1
+               else
+                       service_start /usr/sbin/olsrd -f "$OLSRD_CONFIG_FILE" -nofork
+               fi
        fi
+       olsrd_setup_smartgw_rules
 }
 
 stop() {
-       killall olsrd
+       SERVICE_PID_FILE="$PID"
+       service_stop /usr/sbin/olsrd
+
+       SERVICE_PID_FILE="$PID6"
+       service_stop /usr/sbin/olsrd
 }