babeld: tweak configuration for source-specific features
[feed/routing.git] / babeld / files / babeld.init
1 #!/bin/sh /etc/rc.common
2
3 . /lib/functions/network.sh
4
5 START=70
6
7 pidfile='/var/run/babeld.pid'
8 CONFIGFILE='/var/etc/babeld.conf'
9 OTHERCONFIGFILE="/etc/babeld.conf"
10 EXTRA_COMMANDS="status"
11 EXTRA_HELP=" status Dump Babel's table to the log file."
12
13 # Options to ignore for the global section (old options that are translated
14 # for backward compatibility with old configuration files)
15 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"
16
17 # Append a line to the configuration file
18 cfg_append() {
19 local value="$1"
20 echo "$value" >> $CONFIGFILE
21 }
22
23 cfg_append_option() {
24 local section="$1"
25 local option="$2"
26 local value
27 config_get value "$section" "$option"
28 # babeld convention for options is '-', not '_'
29 [ -n "$value" ] && cfg_append "${option//_/-} $value"
30 }
31
32 # Append to the "$buffer" variable
33 append_ifname() {
34 local section="$1"
35 local option="$2"
36 local switch="$3"
37 local _name
38 config_get _name "$section" "$option"
39 [ -z "$_name" ] && return 0
40 local ifname=$(uci_get_state network "$_name" ifname "$_name")
41 append buffer "$switch $ifname"
42 }
43
44 append_bool() {
45 local section="$1"
46 local option="$2"
47 local value="$3"
48 local _loctmp
49 config_get_bool _loctmp "$section" "$option" 0
50 [ "$_loctmp" -gt 0 ] && append buffer "$value"
51 }
52
53 append_parm() {
54 local section="$1"
55 local option="$2"
56 local switch="$3"
57 local _loctmp
58 config_get _loctmp "$section" "$option"
59 [ -z "$_loctmp" ] && return 0
60 append buffer "$switch $_loctmp"
61 }
62
63
64 # Provides backward compatibility for old option names in the global section.
65 translate_option() {
66 local section="$1"
67 local old_option="$2"
68 local new_option="$3"
69 local _value
70 config_get _value "$section" "$old_option"
71 [ -z "$_value" ] && return
72 cfg_append "${new_option//_/-} $_value"
73 }
74
75 translate_bool() {
76 local section="$1"
77 local old_option="$2"
78 local new_option="$3"
79 local _bool
80 local _value
81 config_get_bool _bool "$section" "$old_option" 0
82 [ "$_bool" -eq 0 ] && return
83 cfg_append "${new_option//_/-} true"
84 }
85
86 # Adds a new interface section for setting default interface options.
87 add_default_option() {
88 local option="$1"
89 local value="$2"
90 cfg_append "default ${option//_/-} $value"
91 }
92
93 # Global 'hello_interval' and 'wired_hello_interval' options are ignored,
94 # because they have no direct equivalent: you should use
95 # interface-specific settings.
96 parse_old_global_options() {
97 local section="$1"
98 translate_bool "$section" 'carrier_sense' 'link_detect'
99 translate_bool "$section" 'random_router_id' 'random_id'
100 translate_option "$section" 'multicast_address' 'protocol_group'
101 translate_option "$section" 'port' 'protocol_port'
102 translate_option "$section" 'local_server' 'local_port'
103 translate_option "$section" 'smoothing_half_time' 'smoothing_half_life'
104 translate_option "$section" 'duplication_priority' 'allow_duplicates'
105 # These two global options are turned into default interface options.
106 local _bool
107 config_get_bool _bool "$section" 'assume_wireless' 0
108 [ "$_bool" -eq 1 ] && add_default_option "wired" "false"
109 config_get_bool _bool "$section" 'no_split_horizon' 0
110 [ "$_bool" -eq 1 ] && add_default_option "split_horizon" "false"
111 }
112
113 babel_filter() {
114 local cfg="$1"
115 local _loctmp
116
117 local _ignored
118 config_get_bool _ignored "$cfg" 'ignore' 0
119 [ "$_ignored" -eq 1 ] && return 0
120
121 unset buffer
122 append_parm "$cfg" 'type' ''
123
124 append_bool "$cfg" 'local' 'local'
125
126 append_parm "$cfg" 'ip' 'ip'
127 append_parm "$cfg" 'eq' 'eq'
128 append_parm "$cfg" 'le' 'le'
129 append_parm "$cfg" 'ge' 'ge'
130 append_parm "$cfg" 'src_ip' 'src-ip'
131 append_parm "$cfg" 'src_eq' 'src-eq'
132 append_parm "$cfg" 'src_le' 'src-le'
133 append_parm "$cfg" 'src_ge' 'src-ge'
134 append_parm "$cfg" 'neigh' 'neigh'
135 append_parm "$cfg" 'id' 'id'
136 append_parm "$cfg" 'proto' 'proto'
137
138 append_ifname "$cfg" 'if' 'if'
139
140 append_parm "$cfg" 'action' ''
141
142 cfg_append "$buffer"
143 }
144
145 # Only one of babeld's options is allowed multiple times, "import-table".
146 # We just append it multiple times.
147 list_cb() {
148 option_cb "$@"
149 }
150
151 babel_config_cb() {
152 local type="$1"
153 local section="$2"
154 case "$type" in
155 "general")
156 option_cb() {
157 local option="$1"
158 local value="$2"
159 # Ignore old options
160 list_contains ignored_options "$option" && return
161 cfg_append "${option//_/-} $value"
162 }
163 ;;
164 "interface")
165 local _ifname
166 config_get _ifname "$section" 'ifname'
167 # Backward compatibility: try to use the section name
168 # if no "option ifname" was used.
169 [ -z "$_ifname" -a "${section:0:3}" != "cfg" ] && _ifname="$section"
170 # Try to resolve the logical interface name
171 unset interface
172 network_get_device interface "$_ifname" || interface="$_ifname"
173 option_cb() {
174 local option="$1"
175 local value="$2"
176 local _interface
177 # "option ifname" is a special option, don't actually
178 # generate configuration for it.
179 [ "$option" = "ifname" ] && return
180 [ -n "$interface" ] && _interface="interface $interface" || _interface="default"
181 cfg_append "$_interface ${option//_/-} $value"
182 }
183 # Handle ignore options.
184 local _ignored
185 # This works because we loaded the whole configuration
186 # beforehand (see config_load below).
187 config_get_bool _ignored "$section" 'ignore' 0
188 if [ "$_ignored" -eq 1 ]
189 then
190 option_cb() { return; }
191 else
192 # Also include an empty "interface $interface" statement,
193 # so that babeld operates on this interface.
194 [ -n "$interface" ] && cfg_append "interface $interface"
195 fi
196 ;;
197 *)
198 # Don't use reset_cb, this would also reset config_cb
199 option_cb() { return; }
200 ;;
201 esac
202 }
203
204 start() {
205 mkdir -p /var/lib
206 mkdir -p /var/etc
207 # Start by emptying the generated config file
208 >"$CONFIGFILE"
209 # First load the whole config file, without callbacks, so that we are
210 # aware of all "ignore" options in the second pass.
211 config_load babeld
212 # Parse general and interface sections thanks to the "config_cb()"
213 # callback. This allows to loop over all options without having to
214 # know their name in advance.
215 config_cb() { babel_config_cb "$@"; }
216 config_load babeld
217 # Backward compatibility
218 config_foreach parse_old_global_options general
219 # Parse filters separately, since we know which options we expect
220 config_foreach babel_filter filter
221 # Using multiple config files is supported since babeld 1.5.1
222 /usr/sbin/babeld -D -I "$pidfile" -c "$OTHERCONFIGFILE" -c "$CONFIGFILE"
223 # Wait for the pidfile to appear
224 for i in 1 2
225 do
226 [ -f "$pidfile" ] || sleep 1
227 done
228 [ -f "$pidfile" ] || (echo "Failed to start babeld"; exit 42)
229 }
230
231 stop() {
232 [ -f "$pidfile" ] && kill $(cat $pidfile)
233 # avoid race-condition on restart: wait for
234 # babeld to die for real.
235 [ -f "$pidfile" ] && sleep 1
236 [ -f "$pidfile" ] && sleep 1
237 [ -f "$pidfile" ] && sleep 1
238 [ -f "$pidfile" ] && exit 42
239 }
240
241 status() {
242 [ -f "$pidfile" ] && kill -USR1 $(cat $pidfile)
243 }