261 lines
7.4 KiB
Bash
Executable File
261 lines
7.4 KiB
Bash
Executable File
#!/bin/sh /etc/rc.common
|
|
|
|
. $IPKG_INSTROOT/lib/functions/network.sh
|
|
|
|
START=70
|
|
|
|
pidfile='/var/run/babeld.pid'
|
|
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."
|
|
|
|
# Options to ignore for the global section (old options that are translated
|
|
# for backward compatibility with old configuration files)
|
|
ignored_options="carrier_sense assume_wireless no_split_horizon random_router_id multicast_address port hello_interval wired_hello_interval smoothing_half_time duplication_priority local_server conf_file conf_dir"
|
|
|
|
# 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"
|
|
}
|
|
|
|
|
|
# Provides backward compatibility for old option names in the global section.
|
|
translate_option() {
|
|
local section="$1"
|
|
local old_option="$2"
|
|
local new_option="$3"
|
|
local _value
|
|
config_get _value "$section" "$old_option"
|
|
[ -z "$_value" ] && return
|
|
cfg_append "${new_option//_/-} $_value"
|
|
}
|
|
|
|
translate_bool() {
|
|
local section="$1"
|
|
local old_option="$2"
|
|
local new_option="$3"
|
|
local _bool
|
|
local _value
|
|
config_get_bool _bool "$section" "$old_option" 0
|
|
[ "$_bool" -eq 0 ] && return
|
|
cfg_append "${new_option//_/-} true"
|
|
}
|
|
|
|
# Adds a new interface section for setting default interface options.
|
|
add_default_option() {
|
|
local option="$1"
|
|
local value="$2"
|
|
cfg_append "default ${option//_/-} $value"
|
|
}
|
|
|
|
# Global 'hello_interval' and 'wired_hello_interval' options are ignored,
|
|
# because they have no direct equivalent: you should use
|
|
# interface-specific settings.
|
|
parse_old_global_options() {
|
|
local section="$1"
|
|
translate_bool "$section" 'carrier_sense' 'link_detect'
|
|
translate_bool "$section" 'random_router_id' 'random_id'
|
|
translate_option "$section" 'multicast_address' 'protocol_group'
|
|
translate_option "$section" 'port' 'protocol_port'
|
|
translate_option "$section" 'local_server' 'local_port'
|
|
translate_option "$section" 'smoothing_half_time' 'smoothing_half_life'
|
|
translate_option "$section" 'duplication_priority' 'allow_duplicates'
|
|
# These two global options are turned into default interface options.
|
|
local _bool
|
|
config_get_bool _bool "$section" 'assume_wireless' 0
|
|
[ "$_bool" -eq 1 ] && add_default_option "wired" "false"
|
|
config_get_bool _bool "$section" 'no_split_horizon' 0
|
|
[ "$_bool" -eq 1 ] && add_default_option "split_horizon" "false"
|
|
# Configure alternative configuration file and directory
|
|
local conf_file
|
|
config_get conf_file "$section" "conf_file"
|
|
[ -n "$conf_file" ] && OTHERCONFIGFILE="$conf_file"
|
|
local conf_dir
|
|
config_get conf_dir "$section" "conf_dir"
|
|
[ -n "$conf_dir" ] && OTHERCONFIGDIR="$conf_dir"
|
|
}
|
|
|
|
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 old options
|
|
list_contains ignored_options "$option" && 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'
|
|
# Backward compatibility: try to use the section name
|
|
# if no "option ifname" was used.
|
|
[ -z "$_ifname" -a "${section:0:3}" != "cfg" ] && _ifname="$section"
|
|
# 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
|
|
}
|
|
|
|
start() {
|
|
mkdir -p /var/lib
|
|
mkdir -p /var/etc
|
|
mkdir -p $OTHERCONFIGDIR
|
|
|
|
# Start by emptying the generated config file
|
|
>"$CONFIGFILE"
|
|
# Import dynamic config files
|
|
for f in $OTHERCONFIGDIR/*.conf; do
|
|
[ -f "$f" ] && cat $f >> $CONFIGFILE
|
|
done
|
|
# First load the whole config file, without callbacks, so that we are
|
|
# aware of all "ignore" options in the second pass.
|
|
config_load babeld
|
|
# 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
|
|
# Backward compatibility
|
|
config_foreach parse_old_global_options general
|
|
# Parse filters separately, since we know which options we expect
|
|
config_foreach babel_filter filter
|
|
# Using multiple config files is supported since babeld 1.5.1
|
|
/usr/sbin/babeld -D -I "$pidfile" -c "$OTHERCONFIGFILE" -c "$CONFIGFILE"
|
|
# Wait for the pidfile to appear
|
|
for i in 1 2
|
|
do
|
|
[ -f "$pidfile" ] || sleep 1
|
|
done
|
|
[ -f "$pidfile" ] || (echo "Failed to start babeld"; exit 42)
|
|
}
|
|
|
|
stop() {
|
|
[ -f "$pidfile" ] && kill $(cat $pidfile)
|
|
# avoid race-condition on restart: wait for
|
|
# babeld to die for real.
|
|
[ -f "$pidfile" ] && sleep 1
|
|
[ -f "$pidfile" ] && sleep 1
|
|
[ -f "$pidfile" ] && sleep 1
|
|
[ -f "$pidfile" ] && exit 42
|
|
}
|
|
|
|
status() {
|
|
[ -f "$pidfile" ] && kill -USR1 $(cat $pidfile)
|
|
}
|