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