diff --git a/babeld/Makefile b/babeld/Makefile index d7a9ddc..e939310 100644 --- a/babeld/Makefile +++ b/babeld/Makefile @@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=babeld -PKG_VERSION:=1.5.0 +PKG_VERSION:=1.5.1 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=http://www.pps.univ-paris-diderot.fr/~jch/software/files/ -PKG_MD5SUM:=ac884beb644792bdb79f0042755820ee +PKG_MD5SUM:=20e3284d5ad291d7ba2ad91d5b47de10 include $(INCLUDE_DIR)/package.mk diff --git a/babeld/files/babeld.config b/babeld/files/babeld.config index 88fdf2d..b58270c 100644 --- a/babeld/files/babeld.config +++ b/babeld/files/babeld.config @@ -1,78 +1,67 @@ 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 - # option 'multicast_address' 'ff02:0:0:0:0:0:1:6' - # option 'port' '6696' - # option 'state_file' '/var/lib/babel-state' - # 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 'random_id' 'true' + # option 'debug' '1' + # option 'local_port' '33123' # 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). -# If you use an alias, it must be already defined when babeld starts. -# 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 +config interface + ## Remove this line to enable babeld on this interface option 'ignore' 'true' - # option 'wired' 'auto' - # option 'link_quality' 'auto' - # option 'split_horizon' 'auto' - # The default is 96 for wired interfaces, and 256 for wireless ones - ## option 'rxcost' '256' - # The default is specified with the -h and -H command-line flags. - ## option 'hello_interval' '4' - # This can be set to a fairly large value, unless significant - # 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' + ## You can use aliases (like lan, wlan) or real names (like eth0.0). + ## If you use an alias, it must be already defined when babeld starts. + ## Otherwise, the name is taken literally and the interface can be + ## brought up later (useful for tunnels for instance). + option 'ifname' 'wlan' + ## You can set options, see babeld man page ("Interface configuration") + # option 'rxcost' '256' + # option 'hello_interval' '1' -config interface lan +config interface 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', -# 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 # protocol number is "boot", e.g. when it installed by dhcp. It is # disabled by default. config filter - option 'ignore' 'true' + option 'ignore' 'true' # Type - option 'type' 'redistribute' + option 'type' 'redistribute' # Selectors: ip, eq, le, ge, neigh, id, proto, local, if - option 'ip' '0.0.0.0/0' - option 'le' '0' - option 'proto' '3' + option 'ip' '0.0.0.0/0' + option 'eq' '0' + option 'proto' '3' # 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" diff --git a/babeld/files/babeld.init b/babeld/files/babeld.init index 592d3c8..180fc7e 100755 --- a/babeld/files/babeld.init +++ b/babeld/files/babeld.init @@ -1,18 +1,35 @@ #!/bin/sh /etc/rc.common +. /lib/functions/network.sh + START=70 pidfile='/var/run/babeld.pid' +CONFIGFILE='/var/etc/babeld.conf' +OTHERCONFIGFILE="/etc/babeld.conf" EXTRA_COMMANDS="status" EXTRA_HELP=" status Dump Babel's table to the log file." -listen_ifname() { - local ifname=$(uci_get_state network "$1" ifname "$1") - local switch="$2" - append args "$switch $ifname" - append interfaces "$ifname" +# 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" + +# 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" @@ -21,7 +38,7 @@ append_ifname() { config_get _name "$section" "$option" [ -z "$_name" ] && return 0 local ifname=$(uci_get_state network "$_name" ifname "$_name") - append args "$switch $ifname" + append buffer "$switch $ifname" } append_bool() { @@ -30,13 +47,7 @@ append_bool() { local value="$3" local _loctmp config_get_bool _loctmp "$section" "$option" 0 - [ "$_loctmp" -gt 0 ] && append args "$value" -} - -append_switch() { - local value="$1" - local switch="$2" - append args "$switch $value" + [ "$_loctmp" -gt 0 ] && append buffer "$value" } append_parm() { @@ -46,7 +57,57 @@ append_parm() { local _loctmp config_get _loctmp "$section" "$option" [ -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() { @@ -56,9 +117,8 @@ babel_filter() { local _ignored config_get_bool _ignored "$cfg" 'ignore' 0 [ "$_ignored" -eq 1 ] && return 0 - - append args "-C '" + unset buffer append_parm "$cfg" 'type' '' append_bool "$cfg" 'local' 'local' @@ -75,69 +135,92 @@ babel_filter() { append_parm "$cfg" 'action' '' - append args ' ' "'" + cfg_append "$buffer" } -babel_addif() { - local cfg="$1" - - local _ignored - config_get_bool _ignored "$cfg" 'ignore' 0 - [ "$_ignored" -eq 1 ] && return 0 - - listen_ifname "$cfg" "-C 'interface" - - append_parm "$cfg" 'wired' 'wired' - append_parm "$cfg" 'link_quality' 'link-quality' - append_parm "$cfg" 'split_horizon' 'split-horizon' - append_parm "$cfg" 'rxcost' 'rxcost' - append_parm "$cfg" 'hello_interval' 'hello-interval' - append_parm "$cfg" 'update_interval' 'update-interval' - append_parm "$cfg" 'enable_timestamps' 'enable-timestamps' - append_parm "$cfg" 'max_rtt_penalty' 'max-rtt-penalty' - append_parm "$cfg" 'rtt_decay' 'rtt-decay' - append_parm "$cfg" 'rtt_min' 'rtt-min' - append_parm "$cfg" 'rtt_max' 'rtt-max' - - append args ' ' "'" +# Only one of babeld's options is allowed multiple times, "import-table". +# We just append it multiple times. +list_cb() { + option_cb "$@" } -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' +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 + # 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 + # 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 - unset args - unset interfaces - config_foreach babel_config general - config_foreach babel_addif interface + # 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 - [ -z "$interfaces" ] && return 0 - eval "/usr/sbin/babeld -D -I $pidfile $args $interfaces" + # 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() {