Merge pull request #47 from zorun/babeld_configfile

Updates to babeld



This patchset:
- fixes #33 by generating a configuration file for babeld
- introduces a slightly different syntax for specfiying interfaces (backward-compatible)
- allows to use any option, as long as it's supported by babeld (i.e. valid options are not hardcoded in the init script anymore, all options are simply passed to babeld)

It is mostly backward-compatible, with a few caveats.

Thanks to Baptiste Jonglez.
This commit is contained in:
Gabriel Kerneis 2014-09-01 09:55:32 +02:00
commit cda939baea
3 changed files with 203 additions and 131 deletions

View file

@ -8,12 +8,12 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=babeld PKG_NAME:=babeld
PKG_VERSION:=1.5.0 PKG_VERSION:=1.5.1
PKG_RELEASE:=1 PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=http://www.pps.univ-paris-diderot.fr/~jch/software/files/ PKG_SOURCE_URL:=http://www.pps.univ-paris-diderot.fr/~jch/software/files/
PKG_MD5SUM:=ac884beb644792bdb79f0042755820ee PKG_MD5SUM:=20e3284d5ad291d7ba2ad91d5b47de10
include $(INCLUDE_DIR)/package.mk include $(INCLUDE_DIR)/package.mk

View file

@ -1,67 +1,50 @@
package babeld package babeld
# Configuration set in this file ends up in /var/etc/babeld.conf
# Babeld is told to use both /etc/babeld.conf and /var/etc/babeld.conf,
# so you can use one or the other, or even both at the same time.
# See "man babeld" for all available options ("Global options").
# Important: remember to use '_' instead of '-' in option names.
config general config general
# option 'multicast_address' 'ff02:0:0:0:0:0:1:6' # option 'random_id' 'true'
# option 'port' '6696' # option 'debug' '1'
# option 'state_file' '/var/lib/babel-state' # option 'local_port' '33123'
# option 'hello_interval' '4'
# option 'wired_hello_interval' '20'
# option 'diversity' '0,128'
# option 'smoothing_half_time' '4'
# option 'kernel_priority' '0'
# Do not use this option unless you know what you are doing, as it can
# cause persistent route flapping.
## option 'duplication_priority' '0'
# option 'carrier_sense' 'false'
# option 'assume_wireless' 'false'
# option 'no_split_horizon' 'false'
# option 'debug' '0'
# Listen for connections from a front-end, e.g. on port 33123.
## option 'local_server' '33123'
# option 'random_router_id' 'false'
# Keep unfeasible routes
## option 'keep_unfeasible' 'false'
# Use the given kernel routing table for routes inserted by babeld.
## option 'export_table' '0'
# Export routes from the given kernel routing tables.
## list 'import_table' '0'
## list 'import_table' '42'
# The configuration file is not necessary since you can do everything
# from this file.
# option 'conf_file' '/etc/babeld.conf'
# option 'log_file' '/var/log/babeld.log' # option 'log_file' '/var/log/babeld.log'
## This seems somewhat buggy on BB. If you need only one
## import-table statement, "option import_table 42" should work.
# list 'import_table' '42'
# list 'import_table' '100'
# You can use aliases (like lan, wlan) or real names (like eth0.0). config interface
# If you use an alias, it must be already defined when babeld starts. ## Remove this line to enable babeld on this interface
# Otherwise, the name is taken literally and the interface can be
# brought up later (useful for tunnels for instance).
config interface wlan
# Remove this line to enable babeld on this interface
option 'ignore' 'true' option 'ignore' 'true'
# option 'wired' 'auto' ## You can use aliases (like lan, wlan) or real names (like eth0.0).
# option 'link_quality' 'auto' ## If you use an alias, it must be already defined when babeld starts.
# option 'split_horizon' 'auto' ## Otherwise, the name is taken literally and the interface can be
# The default is 96 for wired interfaces, and 256 for wireless ones ## brought up later (useful for tunnels for instance).
## option 'rxcost' '256' option 'ifname' 'wlan'
# The default is specified with the -h and -H command-line flags. ## You can set options, see babeld man page ("Interface configuration")
## option 'hello_interval' '4' # option 'rxcost' '256'
# This can be set to a fairly large value, unless significant # option 'hello_interval' '1'
# packet loss is expected. The default is four times the hello
# interval.
## option 'update_interval' '16'
# Options to enable and configure RTT-based metric
## option 'enable_timestamps' 'false'
## option 'max_rtt_penalty' '0'
## option 'rtt_decay' '42'
## option 'rtt_min' '10'
## option 'rtt_max' '120'
config interface lan config interface
option 'ignore' 'true' option 'ignore' 'true'
## Physical interface name
option 'ifname' 'tun-example'
# option 'max_rtt_penalty' '90'
# A filter consists in a type ('in', 'out' or 'redistribute'), an action # A config interface without "option ifname" will set default options
# for all interfaces. Interface-specific configuration always overrides
# default configuration.
config interface
# option 'enable_timestamps' 'true'
# option 'update_interval' '30'
# A filter consists of a type ('in', 'out' or 'redistribute'), an action
# ('allow', 'deny' or 'metric xxx') and a set of selectors ('ip', 'eq', # ('allow', 'deny' or 'metric xxx') and a set of selectors ('ip', 'eq',
# etc.). See /etc/babeld.conf for more details. # etc.). See babeld man page ("Filtering rules") for more details.
# Here is a sample filter wich redistributes the default route if its # Here is a sample filter wich redistributes the default route if its
# protocol number is "boot", e.g. when it installed by dhcp. It is # protocol number is "boot", e.g. when it installed by dhcp. It is
# disabled by default. # disabled by default.
@ -71,8 +54,14 @@ config filter
option 'type' 'redistribute' option 'type' 'redistribute'
# Selectors: ip, eq, le, ge, neigh, id, proto, local, if # Selectors: ip, eq, le, ge, neigh, id, proto, local, if
option 'ip' '0.0.0.0/0' option 'ip' '0.0.0.0/0'
option 'le' '0' option 'eq' '0'
option 'proto' '3' option 'proto' '3'
# Action # Action
option 'action' 'metric 128' option 'action' 'metric 128'
# Notice that the 'local' selector is a boolean.
config filter
option 'ignore' 'true'
option 'type' 'redistribute'
option 'local' 'true'
# No action means "allow"

View file

@ -1,18 +1,35 @@
#!/bin/sh /etc/rc.common #!/bin/sh /etc/rc.common
. /lib/functions/network.sh
START=70 START=70
pidfile='/var/run/babeld.pid' pidfile='/var/run/babeld.pid'
CONFIGFILE='/var/etc/babeld.conf'
OTHERCONFIGFILE="/etc/babeld.conf"
EXTRA_COMMANDS="status" EXTRA_COMMANDS="status"
EXTRA_HELP=" status Dump Babel's table to the log file." EXTRA_HELP=" status Dump Babel's table to the log file."
listen_ifname() { # Options to ignore for the global section (old options that are translated
local ifname=$(uci_get_state network "$1" ifname "$1") # for backward compatibility with old configuration files)
local switch="$2" 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"
append args "$switch $ifname"
append interfaces "$ifname" # 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() { append_ifname() {
local section="$1" local section="$1"
local option="$2" local option="$2"
@ -21,7 +38,7 @@ append_ifname() {
config_get _name "$section" "$option" config_get _name "$section" "$option"
[ -z "$_name" ] && return 0 [ -z "$_name" ] && return 0
local ifname=$(uci_get_state network "$_name" ifname "$_name") local ifname=$(uci_get_state network "$_name" ifname "$_name")
append args "$switch $ifname" append buffer "$switch $ifname"
} }
append_bool() { append_bool() {
@ -30,13 +47,7 @@ append_bool() {
local value="$3" local value="$3"
local _loctmp local _loctmp
config_get_bool _loctmp "$section" "$option" 0 config_get_bool _loctmp "$section" "$option" 0
[ "$_loctmp" -gt 0 ] && append args "$value" [ "$_loctmp" -gt 0 ] && append buffer "$value"
}
append_switch() {
local value="$1"
local switch="$2"
append args "$switch $value"
} }
append_parm() { append_parm() {
@ -46,7 +57,57 @@ append_parm() {
local _loctmp local _loctmp
config_get _loctmp "$section" "$option" config_get _loctmp "$section" "$option"
[ -z "$_loctmp" ] && return 0 [ -z "$_loctmp" ] && return 0
append args "$switch $_loctmp" 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"
} }
babel_filter() { babel_filter() {
@ -57,8 +118,7 @@ babel_filter() {
config_get_bool _ignored "$cfg" 'ignore' 0 config_get_bool _ignored "$cfg" 'ignore' 0
[ "$_ignored" -eq 1 ] && return 0 [ "$_ignored" -eq 1 ] && return 0
append args "-C '" unset buffer
append_parm "$cfg" 'type' '' append_parm "$cfg" 'type' ''
append_bool "$cfg" 'local' 'local' append_bool "$cfg" 'local' 'local'
@ -75,69 +135,92 @@ babel_filter() {
append_parm "$cfg" 'action' '' append_parm "$cfg" 'action' ''
append args ' ' "'" cfg_append "$buffer"
} }
babel_addif() { # Only one of babeld's options is allowed multiple times, "import-table".
local cfg="$1" # 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
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 local _ignored
config_get_bool _ignored "$cfg" 'ignore' 0 # This works because we loaded the whole configuration
[ "$_ignored" -eq 1 ] && return 0 # beforehand (see config_load below).
config_get_bool _ignored "$section" 'ignore' 0
listen_ifname "$cfg" "-C 'interface" if [ "$_ignored" -eq 1 ]
then
append_parm "$cfg" 'wired' 'wired' option_cb() { return; }
append_parm "$cfg" 'link_quality' 'link-quality' else
append_parm "$cfg" 'split_horizon' 'split-horizon' # Also include an empty "interface $interface" statement,
append_parm "$cfg" 'rxcost' 'rxcost' # so that babeld operates on this interface.
append_parm "$cfg" 'hello_interval' 'hello-interval' [ -n "$interface" ] && cfg_append "interface $interface"
append_parm "$cfg" 'update_interval' 'update-interval' fi
append_parm "$cfg" 'enable_timestamps' 'enable-timestamps' ;;
append_parm "$cfg" 'max_rtt_penalty' 'max-rtt-penalty' *)
append_parm "$cfg" 'rtt_decay' 'rtt-decay' # Don't use reset_cb, this would also reset config_cb
append_parm "$cfg" 'rtt_min' 'rtt-min' option_cb() { return; }
append_parm "$cfg" 'rtt_max' 'rtt-max' ;;
esac
append args ' ' "'"
}
babel_config() {
local cfg="$1"
append_bool "$cfg" 'carrier_sense' '-l'
append_bool "$cfg" 'assume_wireless' '-w'
append_bool "$cfg" 'no_split_horizon' '-s'
append_bool "$cfg" 'keep_unfeasible' '-u'
append_bool "$cfg" 'random_router_id' '-r'
append_parm "$cfg" 'multicast_address' '-m'
append_parm "$cfg" 'port' '-p'
append_parm "$cfg" 'state_file' '-S'
append_parm "$cfg" 'hello_interval' '-h'
append_parm "$cfg" 'wired_hello_interval' '-H'
append_parm "$cfg" 'diversity' '-z'
append_parm "$cfg" 'smoothing_half_time' '-M'
append_parm "$cfg" 'kernel_priority' '-k'
append_parm "$cfg" 'duplication_priority' '-A'
append_parm "$cfg" 'debug' '-d'
append_parm "$cfg" 'local_server' '-g'
append_parm "$cfg" 'export_table' '-t'
config_list_foreach "$cfg" 'import_table' append_switch '-T'
append_parm "$cfg" 'conf_file' '-c'
append_parm "$cfg" 'log_file' '-L'
} }
start() { start() {
mkdir -p /var/lib mkdir -p /var/lib
# Start by emptying the generated config file
>"$CONFIGFILE"
# First load the whole config file, without callbacks, so that we are
# aware of all "ignore" options in the second pass.
config_load babeld config_load babeld
unset args # Parse general and interface sections thanks to the "config_cb()"
unset interfaces # callback. This allows to loop over all options without having to
config_foreach babel_config general # know their name in advance.
config_foreach babel_addif interface 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 config_foreach babel_filter filter
[ -z "$interfaces" ] && return 0 # Using multiple config files is supported since babeld 1.5.1
eval "/usr/sbin/babeld -D -I $pidfile $args $interfaces" /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() { stop() {