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
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

View File

@ -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"

View File

@ -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() {