| #!/bin/sh /etc/rc.common |
| |
| . $IPKG_INSTROOT/lib/functions/network.sh |
| |
| USE_PROCD=1 |
| START=70 |
| |
| CONFIGFILE='/var/etc/babeld.conf' |
| OTHERCONFIGFILE="/etc/babeld.conf" |
| OTHERCONFIGDIR="/tmp/babeld.d/" |
| EXTRA_COMMANDS="status" |
| EXTRA_HELP=" status Dump Babel's table to the log file." |
| |
| # Append a line to the configuration file |
| cfg_append() { |
| local value="$1" |
| echo "$value" >> "$CONFIGFILE" |
| } |
| |
| cfg_append_option() { |
| local section="$1" |
| local option="$2" |
| local value |
| config_get value "$section" "$option" |
| # babeld convention for options is '-', not '_' |
| [ -n "$value" ] && cfg_append "${option//_/-} $value" |
| } |
| |
| # Append to the "$buffer" variable |
| append_ifname() { |
| local section="$1" |
| local option="$2" |
| local switch="$3" |
| local _name |
| config_get _name "$section" "$option" |
| [ -z "$_name" ] && return 0 |
| local ifname=$(uci_get_state network "$_name" ifname "$_name") |
| append buffer "$switch $ifname" |
| } |
| |
| append_bool() { |
| local section="$1" |
| local option="$2" |
| local value="$3" |
| local _loctmp |
| config_get_bool _loctmp "$section" "$option" 0 |
| [ "$_loctmp" -gt 0 ] && append buffer "$value" |
| } |
| |
| append_parm() { |
| local section="$1" |
| local option="$2" |
| local switch="$3" |
| local _loctmp |
| config_get _loctmp "$section" "$option" |
| [ -z "$_loctmp" ] && return 0 |
| append buffer "$switch $_loctmp" |
| } |
| |
| babel_filter() { |
| local cfg="$1" |
| local _loctmp |
| |
| local _ignored |
| config_get_bool _ignored "$cfg" 'ignore' 0 |
| [ "$_ignored" -eq 1 ] && return 0 |
| |
| unset buffer |
| append_parm "$cfg" 'type' '' |
| |
| append_bool "$cfg" 'local' 'local' |
| |
| append_parm "$cfg" 'ip' 'ip' |
| append_parm "$cfg" 'eq' 'eq' |
| append_parm "$cfg" 'le' 'le' |
| append_parm "$cfg" 'ge' 'ge' |
| append_parm "$cfg" 'src_ip' 'src-ip' |
| append_parm "$cfg" 'src_eq' 'src-eq' |
| append_parm "$cfg" 'src_le' 'src-le' |
| append_parm "$cfg" 'src_ge' 'src-ge' |
| append_parm "$cfg" 'neigh' 'neigh' |
| append_parm "$cfg" 'id' 'id' |
| append_parm "$cfg" 'proto' 'proto' |
| |
| append_ifname "$cfg" 'if' 'if' |
| |
| append_parm "$cfg" 'action' '' |
| |
| cfg_append "$buffer" |
| } |
| |
| # Only one of babeld's options is allowed multiple times, "import-table". |
| # We just append it multiple times. |
| list_cb() { |
| option_cb "$@" |
| } |
| |
| babel_config_cb() { |
| local type="$1" |
| local section="$2" |
| case "$type" in |
| "general") |
| option_cb() { |
| local option="$1" |
| local value="$2" |
| # Ignore options that are not supposed to be given to babeld |
| [ "$option" = "conf_file" ] && return |
| [ "$option" = "conf_dir" ] && return |
| # Skip lists. They will be taken care of by list_cb |
| test "${option#*_ITEM}" != "$option" && return |
| test "${option#*_LENGTH}" != "$option" && return |
| cfg_append "${option//_/-} $value" |
| } |
| ;; |
| "interface") |
| local _ifname |
| config_get _ifname "$section" 'ifname' |
| # Try to resolve the logical interface name |
| unset interface |
| network_get_device interface "$_ifname" || interface="$_ifname" |
| option_cb() { |
| local option="$1" |
| local value="$2" |
| local _interface |
| # "option ifname" is a special option, don't actually |
| # generate configuration for it. |
| [ "$option" = "ifname" ] && return |
| [ -n "$interface" ] && _interface="interface $interface" || _interface="default" |
| cfg_append "$_interface ${option//_/-} $value" |
| } |
| # Handle ignore options. |
| local _ignored |
| # This works because we loaded the whole configuration |
| # beforehand (see config_load below). |
| config_get_bool _ignored "$section" 'ignore' 0 |
| if [ "$_ignored" -eq 1 ] |
| then |
| option_cb() { return; } |
| else |
| # Also include an empty "interface $interface" statement, |
| # so that babeld operates on this interface. |
| [ -n "$interface" ] && cfg_append "interface $interface" |
| fi |
| ;; |
| *) |
| # Don't use reset_cb, this would also reset config_cb |
| option_cb() { return; } |
| ;; |
| esac |
| } |
| |
| # Support for conf_file and conf_dir |
| babel_configpaths() { |
| local cfg="$1" |
| local conf_file |
| config_get conf_file "$cfg" "conf_file" |
| [ -n "$conf_file" ] && OTHERCONFIGFILE="$conf_file" |
| local conf_dir |
| config_get conf_dir "$cfg" "conf_dir" |
| [ -n "$conf_dir" ] && OTHERCONFIGDIR="$conf_dir" |
| } |
| |
| start_service() { |
| mkdir -p /var/lib |
| mkdir -p /var/etc |
| |
| # First load the whole config file, without callbacks, so that we are |
| # aware of all "ignore" options in the second pass. This also allows |
| # to load the configuration paths (conf_file and conf_dir). |
| config_load babeld |
| |
| # Configure alternative configuration file and directory |
| config_foreach babel_configpaths "general" |
| |
| # Start by emptying the generated config file |
| >"$CONFIGFILE" |
| # Import dynamic config files |
| mkdir -p "$OTHERCONFIGDIR" |
| for f in "$OTHERCONFIGDIR"/*.conf; do |
| [ -f "$f" ] && cat "$f" >> "$CONFIGFILE" |
| done |
| |
| # Parse general and interface sections thanks to the "config_cb()" |
| # callback. This allows to loop over all options without having to |
| # know their name in advance. |
| config_cb() { babel_config_cb "$@"; } |
| config_load babeld |
| # Parse filters separately, since we know which options we expect |
| config_foreach babel_filter filter |
| procd_open_instance |
| # Using multiple config files is supported since babeld 1.5.1 |
| procd_set_param command /usr/sbin/babeld -I "" -c "$OTHERCONFIGFILE" -c "$CONFIGFILE" |
| procd_set_param stdout 1 |
| procd_set_param stderr 1 |
| procd_set_param file "$OTHERCONFIGFILE" "$OTHERCONFIGDIR"/*.conf "$CONFIGFILE" |
| procd_set_param respawn |
| procd_close_instance |
| } |
| |
| service_triggers() { |
| procd_add_reload_trigger babeld |
| } |
| |
| status() { |
| kill -USR1 $(pgrep -P 1 babeld) |
| } |