7b25ef48c6b0a5cea6861824b5221ea1e11f64f2
[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 # Append a line to the configuration file
15 cfg_append() {
16 local value="$1"
17 echo "$value" >> "$CONFIGFILE"
18 }
19
20 cfg_append_option() {
21 local section="$1"
22 local option="$2"
23 local value
24 config_get value "$section" "$option"
25 # babeld convention for options is '-', not '_'
26 [ -n "$value" ] && cfg_append "${option//_/-} $value"
27 }
28
29 # Append to the "$buffer" variable
30 append_ifname() {
31 local section="$1"
32 local option="$2"
33 local switch="$3"
34 local _name
35 config_get _name "$section" "$option"
36 [ -z "$_name" ] && return 0
37 local ifname=$(uci_get_state network "$_name" ifname "$_name")
38 append buffer "$switch $ifname"
39 }
40
41 append_bool() {
42 local section="$1"
43 local option="$2"
44 local value="$3"
45 local _loctmp
46 config_get_bool _loctmp "$section" "$option" 0
47 [ "$_loctmp" -gt 0 ] && append buffer "$value"
48 }
49
50 append_parm() {
51 local section="$1"
52 local option="$2"
53 local switch="$3"
54 local _loctmp
55 config_get _loctmp "$section" "$option"
56 [ -z "$_loctmp" ] && return 0
57 append buffer "$switch $_loctmp"
58 }
59
60 babel_filter() {
61 local cfg="$1"
62 local _loctmp
63
64 local _ignored
65 config_get_bool _ignored "$cfg" 'ignore' 0
66 [ "$_ignored" -eq 1 ] && return 0
67
68 unset buffer
69 append_parm "$cfg" 'type' ''
70
71 append_bool "$cfg" 'local' 'local'
72
73 append_parm "$cfg" 'ip' 'ip'
74 append_parm "$cfg" 'eq' 'eq'
75 append_parm "$cfg" 'le' 'le'
76 append_parm "$cfg" 'ge' 'ge'
77 append_parm "$cfg" 'src_ip' 'src-ip'
78 append_parm "$cfg" 'src_eq' 'src-eq'
79 append_parm "$cfg" 'src_le' 'src-le'
80 append_parm "$cfg" 'src_ge' 'src-ge'
81 append_parm "$cfg" 'neigh' 'neigh'
82 append_parm "$cfg" 'id' 'id'
83 append_parm "$cfg" 'proto' 'proto'
84
85 append_ifname "$cfg" 'if' 'if'
86
87 append_parm "$cfg" 'action' ''
88
89 cfg_append "$buffer"
90 }
91
92 # Only one of babeld's options is allowed multiple times, "import-table".
93 # We just append it multiple times.
94 list_cb() {
95 option_cb "$@"
96 }
97
98 babel_config_cb() {
99 local type="$1"
100 local section="$2"
101 case "$type" in
102 "general")
103 option_cb() {
104 local option="$1"
105 local value="$2"
106 # Ignore options that are not supposed to be given to babeld
107 [ "$option" = "conf_file" ] && return
108 [ "$option" = "conf_dir" ] && return
109 # Skip lists. They will be taken care of by list_cb
110 test "${option#*_ITEM}" != "$option" && return
111 test "${option#*_LENGTH}" != "$option" && return
112 cfg_append "${option//_/-} $value"
113 }
114 ;;
115 "interface")
116 local _ifname
117 config_get _ifname "$section" 'ifname'
118 # Try to resolve the logical interface name
119 unset interface
120 network_get_device interface "$_ifname" || interface="$_ifname"
121 option_cb() {
122 local option="$1"
123 local value="$2"
124 local _interface
125 # "option ifname" is a special option, don't actually
126 # generate configuration for it.
127 [ "$option" = "ifname" ] && return
128 [ -n "$interface" ] && _interface="interface $interface" || _interface="default"
129 cfg_append "$_interface ${option//_/-} $value"
130 }
131 # Handle ignore options.
132 local _ignored
133 # This works because we loaded the whole configuration
134 # beforehand (see config_load below).
135 config_get_bool _ignored "$section" 'ignore' 0
136 if [ "$_ignored" -eq 1 ]
137 then
138 option_cb() { return; }
139 else
140 # Also include an empty "interface $interface" statement,
141 # so that babeld operates on this interface.
142 [ -n "$interface" ] && cfg_append "interface $interface"
143 fi
144 ;;
145 *)
146 # Don't use reset_cb, this would also reset config_cb
147 option_cb() { return; }
148 ;;
149 esac
150 }
151
152 # Support for conf_file and conf_dir
153 babel_configpaths() {
154 local cfg="$1"
155 local conf_file
156 config_get conf_file "$cfg" "conf_file"
157 [ -n "$conf_file" ] && OTHERCONFIGFILE="$conf_file"
158 local conf_dir
159 config_get conf_dir "$cfg" "conf_dir"
160 [ -n "$conf_dir" ] && OTHERCONFIGDIR="$conf_dir"
161 }
162
163 start_service() {
164 mkdir -p /var/lib
165 mkdir -p /var/etc
166
167 # First load the whole config file, without callbacks, so that we are
168 # aware of all "ignore" options in the second pass. This also allows
169 # to load the configuration paths (conf_file and conf_dir).
170 config_load babeld
171
172 # Configure alternative configuration file and directory
173 config_foreach babel_configpaths "general"
174
175 # Start by emptying the generated config file
176 >"$CONFIGFILE"
177 # Import dynamic config files
178 mkdir -p "$OTHERCONFIGDIR"
179 for f in "$OTHERCONFIGDIR"/*.conf; do
180 [ -f "$f" ] && cat "$f" >> "$CONFIGFILE"
181 done
182
183 # Parse general and interface sections thanks to the "config_cb()"
184 # callback. This allows to loop over all options without having to
185 # know their name in advance.
186 config_cb() { babel_config_cb "$@"; }
187 config_load babeld
188 # Parse filters separately, since we know which options we expect
189 config_foreach babel_filter filter
190 procd_open_instance
191 # Using multiple config files is supported since babeld 1.5.1
192 procd_set_param command /usr/sbin/babeld -I "" -c "$OTHERCONFIGFILE" -c "$CONFIGFILE"
193 procd_set_param stdout 1
194 procd_set_param stderr 1
195 procd_set_param file "$OTHERCONFIGFILE" "$OTHERCONFIGDIR"/*.conf "$CONFIGFILE"
196 procd_set_param respawn
197 procd_close_instance
198 }
199
200 stop_service() {
201 killall -9 babeld
202 }
203
204 service_triggers() {
205 procd_add_reload_trigger babeld
206 }
207
208 status() {
209 kill -USR1 $(pgrep -P 1 babeld)
210 }