7a4b00f702b80391706827a156921292758191b7
[feed/routing.git] / bird1-openwrt / bird1-ipv6-openwrt / src / init.d / bird6-lib.sh
1 # Bird6-OpenWRT Library - Functions used in /etc/init.d/bird6 script.
2 #
3 #
4 # Copyright (C) 2014-2017 - Eloi Carbo
5 #
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #
19
20
21 # Function: writeToConfig $1
22 # $1 string.
23 # Allows to write in the $BIRD_CONFIG file, the string $1. This function does not check the $1 string.
24 # Example: writeToConfig "value: $N"
25 writeToConfig() {
26 echo "$1" >> ${BIRD_CONFIG}
27 }
28
29
30 # Function: write $1 $2
31 # $1 string. $2 string.
32 # This function checks if $2 is empty. If not, it writes the string $1 in the $BIRD_CONFIG file.
33 # Use write function to check if $1, value found inside $2, is not empty and can be written in the configuration file.
34 # Example: N=""; write "value: $N" $N;
35 write() {
36 [ -n "$2" ] && writeToConfig "$1"
37 }
38
39
40 #Function: write_bool $1 $2
41 # $1 string; $2 boolean
42 # This function checks if $2 is true or false and write the $1 string into $BIRD_CONFIG file.
43 # The function writes a # before the $2 string if its false.
44 # Example: local N=0; write_bool $N
45 write_bool() {
46 [ "$2" == 0 ] && writeToConfig "# $1;" || writeToConfig " $1;"
47 }
48
49
50 # Function: get $1 $2
51 # $1 string. $2 string
52 # This function uses the external UCI function "config_get $result $section $option" to obtain a string value from UCI config file.
53 # To use this function, use the same name of the UCI option for the variable.
54 # Example: UCI (option id 'abcd'); local id; get id $section
55 get() {
56 config_get $1 $2 $1
57 }
58
59
60 # Function: get_a_bool $1 $2
61 # $1 boolean. $2 string
62 # This function uses the external UCI function "config_get_bool $result $section $option" to obtain a boolean value from UCI config file.
63 # To use this function, use the same name of the UCI option for the variable $1.
64 # Example: UCI (option use_ipv6 '1'); local use_ipv6; get use_ipv6 $section
65 # Note: this function was originally called get_bool(), but it collided with
66 # the get_bool() function provided by /lib/functions.sh. Read more at
67 # https://github.com/openwrt/routing/issues/920.
68 get_a_bool() {
69 config_get_bool $1 $2 $1
70 }
71
72
73 # Function: multipath_list $1
74 # $1 string
75 # This function writes the $1 string in the multipath routes.
76 multipath_list() {
77 write " via $1" $1
78 }
79
80
81 # Function: prepare_tables $1
82 # $1 string
83 # This function gets each "table" section in the UCI configuration and sets each option in the bird6.conf file.
84 # $1 is set as the ID of the current UCI table section
85 prepare_tables() {
86 local section="$1"; local name
87
88 get name ${section}
89
90 write "table ${name};" ${name}
91 }
92
93
94 # Function: prepare_global $1
95 # $1 string
96 # This function gets each "global" section in the UCI configuration and sets each option in the bird6.conf file.
97 # $1 is set as the ID of the current UCI global section. prepare_global is the first configuration set in the bird6.conf and removes the old file.
98 prepare_global () {
99 local section="$1"
100 local log_file; local log; local debug; local router_id; local table
101 local listen_bgp_addr; local listen_bgp_port; local listen_bgp_dual
102
103 # Remove old configuration file
104 rm -f "${BIRD_CONFIG}"
105
106 get log_file ${section}
107 get log ${section}
108 get debug ${section}
109 get router_id ${section}
110 get table ${section}
111 get listen_bgp_addr ${section}
112 get listen_bgp_port ${section}
113 get listen_bgp_dual ${section}
114
115 # First line of the NEW configuration file
116 echo "#Bird6 configuration using UCI:" > ${BIRD_CONFIG}
117 writeToConfig " "
118 #TODO: Set Syslog as receiver if empty
119 # LOGF="${log_file:-syslog]}"
120 #TODO: If $log/$debug are empty, set to off
121 if [ -n "${log_file}" -a -n "${log}" ]; then
122 firstEntry="${log:0:3}"
123 if [ "${firstEntry}" = "all" -o "${firstEntry}" = "off" ]; then
124 writeToConfig 'log "'${log_file}'" '${firstEntry}';'
125 else
126 logEntries=$(echo ${log} | tr " " ",")
127 writeToConfig "log \"${log_file}\" { ${logEntries} };"
128 fi
129 fi
130
131 if [ -n "${debug}" ]; then
132 firstEntry="${debug:0:3}"
133 if [ "${firstEntry}" = "all" -o "${firstEntry}" = "off" ]; then
134 writeToConfig "debug protocols ${firstEntry};"
135 else
136 debugEntries=$(echo ${debug} | tr " " ",")
137 writeToConfig "debug protocols { ${debugEntries} };"
138 fi
139 fi
140 writeToConfig " "
141 writeToConfig "#Router ID"
142 write "router id ${router_id};" ${router_id}
143 writeToConfig " "
144 writeToConfig "#Secondary tables"
145 config_foreach prepare_tables 'table'
146 if [ -n "${listen_bgp_dual}" -o "${listen_bgp_dual}" = "0" ]; then
147 writeToConfig "listen bgp ${listen_bgp_addr} ${listen_bgp_port} v6only;"
148 else
149 writeToConfig "listen bgp ${listen_bgp_addr} ${listen_bgp_port} dual;"
150 fi
151 writeToConfig " "
152 }
153
154
155 # Function: prepare_routes $1
156 # $1 string
157 # This function gets each "route" section in the UCI configuration and sets each option in the bird6.conf file.
158 # $1 is set as the ID of the current UCI route section. Each type of route has its own treatment.
159 prepare_routes() {
160 local instance; local prefix; local via; local type
161 local section="$1"
162 local protoInstance="$2"
163
164 get instance ${section}
165 get type ${section}
166 get prefix ${section}
167
168 if [ "${instance}" = "${protoInstance}" ]; then
169 case "${type}" in
170 "router")
171 get via ${section}
172 [ -n "${prefix}" -a -n "${via}" ] && writeToConfig " route ${prefix} via ${via};"
173 ;;
174 "special")
175 get attribute ${section}
176 [ -n "${prefix}" -a -n "${attribute}" ] && writeToConfig " route ${prefix} ${attribute};"
177 ;;
178 "iface")
179 get iface ${section}
180 [ -n "${prefix}" -a -n "${iface}" ] && writeToConfig ' route '${prefix}' via "'${iface}'";'
181 ;;
182 "multipath")
183 write " route ${prefix} multipath" ${prefix}
184 config_list_foreach ${section} l_via multipath_list
185 writeToConfig " ;"
186 ;;
187 esac
188 fi
189 }
190
191
192 # Function: prepare_kernel $1
193 # $1 string
194 # This function gets each "kernel" protocol section in the UCI configuration and sets each option in the bird6.conf file.
195 # $1 is set as the ID of the current UCI kernel section.
196 prepare_kernel() {
197 local section="$1"
198 local disabled; local table; local kernel_table; local import; local export
199 local scan_time; local persist; local learn
200
201 get_a_bool disabled ${section}
202 get table ${section}
203 get import ${section}
204 get export ${section}
205 get scan_time ${section}
206 get kernel_table ${section}
207 get learn ${section}
208 get persist ${section}
209
210 write "#${section} configuration:" ${section}
211 writeToConfig "protocol kernel ${section} {" ${section}
212 write_bool disabled ${disabled}
213 write " table ${table};" ${table}
214 write " kernel table ${kernel_table};" ${kernel_table}
215 write_bool learn ${learn}
216 write_bool persist ${persist}
217 write " scan time ${scan_time};" ${scan_time}
218 write " import ${import};" ${import}
219 write " export ${export};" ${export}
220 writeToConfig "}"
221 writeToConfig " "
222 }
223
224
225 # Function: prepare_static $1
226 # $1 string
227 # This function gets each "static" protocol section in the UCI configuration and sets each option in the bird6.conf file.
228 # $1 is set as the ID of the current UCI static section.
229 prepare_static() {
230 local section="$1"
231 local disabled; local table
232
233 get disabled ${section}
234 get table ${section}
235
236 if [ "${disabled}" -eq 0 ]; then
237 writeToConfig "#${section} configration:" ${section}
238 writeToConfig "protocol static {"
239 write " table ${table};" ${table}
240 config_foreach prepare_routes 'route' ${section}
241 writeToConfig "}"
242 writeToConfig " "
243 fi
244 }
245
246
247 # Function: prepare_direct $1
248 # $1 string
249 # This function gets each "direct" protocol section in the UCI configuration and sets each option in the bird6.conf file.
250 # $1 is set as the ID of the current UCI direct section.
251 prepare_direct() {
252 local section="$1"
253 local disabled; local interface
254
255 get disabled ${section}
256 get interface ${section}
257
258 write "#${section} configuration:" ${section}
259 writeToConfig "protocol direct {"
260 write_bool disabled ${disabled}
261 write " interface ${interface};" ${interface}
262 writeToConfig "}"
263 writeToConfig " "
264 }
265
266
267 # Function: prepare_pipe $1
268 # $1 string
269 # This function gets each "pipe" protocol section in the UCI configuration and sets each option in the bird6.conf file.
270 # $1 is set as the ID of the current UCI direct section.
271 prepare_pipe() {
272 local section="$1"
273 local disabled; local table; local peer_table; local mode; local import; local export
274
275 get disabled ${section}
276 get peer_table ${section}
277 get mode ${section}
278 get table ${section}
279 get import ${section}
280 get export ${section}
281
282 write "#${section} configuration:" ${section}
283 writeToConfig "protocol pipe ${section} {" ${section}
284 write_bool disabled ${disabled}
285 write " table ${table};" ${table}
286 write " peer table ${peer_table};" ${peer_table}
287 write " mode ${mode};" ${mode}
288 write " import ${import};" ${import}
289 write " export ${export};" ${export}
290 writeToConfig "}"
291 writeToConfig " "
292 }
293
294
295 # Function: prepare_device $1
296 # $1 string
297 # This function gets each "device" protocol section in the UCI configuration and sets each option in the bird6.conf file.
298 # $1 is set as the ID of the current UCI device section.
299 prepare_device() {
300 local section="$1"
301 local disabled; local scan_time
302
303 get disabled ${section}
304 get scan_time ${section}
305
306 write "#${section} configuration:" ${section}
307 writeToConfig "protocol device {"
308 write_bool disabled ${disabled}
309 write " scan time ${scan_time};" ${scan_time}
310 writeToConfig "}"
311 writeToConfig " "
312 }
313
314
315 # Function: prepare_bgp_template $1
316 # $1 string
317 # This function gets each "bgp_template" protocol section in the UCI configuration and sets each option in the bird6.conf file.
318 # $1 is set as the ID of the current UCI bgp_template section.
319 # Careful! Template options will be replaced by "instance" options if there is any match.
320 prepare_bgp_template() {
321 local section="$1"
322 local disabled; local table; local import; local export; local local_address
323 local local_as; local neighbor_address; local neighbor_as; local source_address
324 local next_hop_self; local next_hop_keep; local rr_client; local rr_cluster_id
325 local import_limit; local import_limit_action; local export_limit; local export_limit_action
326 local receive_limit; local receive_limit_action; local igp_table
327
328 get_a_bool disabled ${section}
329 get_a_bool next_hop_self ${section}
330 get_a_bool next_hop_keep ${section}
331 get table ${section}
332 get import ${section}
333 get export ${section}
334 get local_address ${section}
335 get local_as ${section}
336 get igp_table ${section}
337 get rr_client ${section}
338 get rr_cluster_id ${section}
339 get import_limit ${section}
340 get import_limit_action ${section}
341 get export_limit ${section}
342 get export_limit_action ${section}
343 get receive_limit ${section}
344 get receive_limit_action ${section}
345 get neighbor_address ${section}
346 get neighbor_as ${section}
347
348 writeToConfig "#${section} template:"
349 writeToConfig "template bgp ${section} {"
350 [ -n "${disabled}" ] && write_bool disabled ${disabled}
351 write " table ${table};" ${table}
352 write " local as ${local_as};" ${local_as}
353 write " source address ${local_address};" ${local_address}
354 write " import ${import};" ${import}
355 write " export ${export};" ${export}
356 if [ -n "${next_hop_self}" ]; then
357 [ "${next_hop_self}" = "1" ] && writeToConfig " next hop self;" || writeToConfig "# next hop self;"
358 fi
359 if [ -n "${next_hop_keep}" ]; then
360 [ "${next_hop_keep}" = "1" ] && writeToConfig " next hop keep;" || writeToConfig "# next hop keep;"
361 fi
362 [ -n "${igp_table}" ] && writeToConfig " igp table ${igp_table};"
363 [ "${rr_client}" = "1" ] && writeToConfig " rr client;" || writeToConfig "# rr client;"
364 write " rr cluster id ${rr_cluster_id};" ${rr_cluster_id}
365 if [ -n "${import_limit}" -a "${import_limit}" > "0" ]; then
366 [ -z "${import_limit_action}" ] && ${import_limit_action} = "warn"
367 writeToConfig " import limit ${import_limit} action ${import_limit_action};"
368 fi
369 if [ -n "${export_limit}" -a "${export_limit}" > "0" ]; then
370 [ -z "${export_limit_action}" ] && ${export_limit_action} = "warn"
371 writeToConfig " export limit ${export_limit} action ${export_limit_action};"
372 fi
373 if [ -n "${receive_limit}" -a "${receive_limit}" > "0" ]; then
374 [ -z "${receive_limit_action}" ] && ${receive_limit_action} = "warn"
375 writeToConfig " receive limit ${receive_limit} action ${receive_limit_action};"
376 fi
377 [ -n "${neighbor_address}" -a -n "${neighbor_as}" ] && writeToConfig " neighbor ${neighbor_address} as ${neighbor_as};"
378 writeToConfig "}"
379 writeToConfig " "
380 }
381
382
383 # Function: prepare_bgp $1
384 # $1 string
385 # This function gets each "bgp" protocol section in the UCI configuration and sets each option in the bird6.conf file.
386 # $1 is set as the ID of the current UCI bgp section.
387 # Careful! The options set in bgp instances overlap bgp_template ones.
388 prepare_bgp() {
389 local section="$1"
390 local disabled; local table; local template; local description; local import
391 local export; local local_address; local local_as; local neighbor_address
392 local neighbor_as; local rr_client; local rr_cluster_id; local import_limit
393 local import_limit_action; local export_limit; local export_limit_action
394 local receive_limit; local receive_limit_action; local igp_table
395
396 get disabled ${section}
397 get table ${section}
398 get template ${section}
399 get description ${section}
400 get import ${section}
401 get export ${section}
402 get local_address ${section}
403 get local_as ${section}
404 get igp_table ${section}
405 get rr_client ${section}
406 get rr_cluster_id ${section}
407 get import_limit ${section}
408 get import_limit_action ${section}
409 get export_limit ${section}
410 get export_limit_action ${section}
411 get receive_limit ${section}
412 get receive_limit_action ${section}
413 get neighbor_address ${section}
414 get neighbor_as ${section}
415
416 writeToConfig "#${section} configuration:"
417 [ -n "${template}" ] && writeToConfig "protocol bgp ${section} from ${template} {" || writeToConfig "protocol bgp ${section} {"
418 [ -n "${disabled}" ] && write_bool disabled ${disabled}
419 write " table ${table};" ${table}
420 write " local as ${local_as};" ${local_as}
421 write " source address ${local_address};" ${local_address}
422 write " import ${import};" ${import}
423 write " export ${export};" ${export}
424 if [ -n "${next_hop_self}" ]; then
425 [ "${next_hop_self}" = "1" ] && writeToConfig " next hop self;" || writeToConfig "# next hop self;"
426 fi
427 if [ -n "${next_hop_keep}" ]; then
428 [ "${next_hop_keep}" = "1" ] && writeToConfig " next hop keep;" || writeToConfig "# next hop keep;"
429 fi
430 [ -n "${igp_table}" ] && writeToConfig " igp table ${igp_table};"
431 [ "${rr_client}" = "1" ] && writeToConfig " rr client;" || writeToConfig "# rr client;"
432 write " rr cluster id ${rr_cluster_id};" ${rr_cluster_id}
433 if [ -n "${import_limit}" -a "${import_limit}" > "0" ]; then
434 [ -z "${import_limit_action}" ] && ${import_limit_action} = "warn"
435 writeToConfig " import limit ${import_limit} action ${import_limit_action};"
436 fi
437 if [ -n "${export_limit}" -a "${export_limit}" > "0" ]; then
438 [ -z "${export_limit_action}" ] && ${export_limit_action} = "warn"
439 writeToConfig " export limit ${export_limit} action ${export_limit_action};"
440 fi
441 if [ -n "${receive_limit}" -a "${receive_limit}" > "0" ]; then
442 [ -z "${receive_limit_action}" ] && ${receive_limit_action} = "warn"
443 writeToConfig " receive limit ${receive_limit} action ${receive_limit_action};"
444 fi
445 [ -n "${neighbor_address}" -a -n "${neighbor_as}" ] && writeToConfig " neighbor ${neighbor_address} as ${neighbor_as};"
446 writeToConfig "}"
447 writeToConfig " "
448 }
449
450
451 # Function: gather_filters
452 # This function gets all the FILES under /filters folder and adds
453 # them into the config as %include elements on top of the file
454 # If there are no filters, the section will remain empty.
455 gather_filters() {
456 writeToConfig "#Filters Section:"
457 for filter in $(find /etc/${BIRD}/filters -type f); do
458 writeToConfig "include \"${filter}\";"
459 done
460 writeToConfig "#End of Filters --"
461 writeToConfig " "
462 }
463
464
465 # Function: gather_functions
466 # This function gets all the FILES under /functions folder and adds
467 # them into the config as %include elements on top of the file
468 # If there are no filters, the section will remain empty.
469 gather_functions() {
470 writeToConfig "#Functions Section:"
471 for func in $(find /etc/${BIRD}/functions -type f); do
472 writeToConfig "include \"${func}\";"
473 done
474 writeToConfig "#End of Functions --"
475 writeToConfig " "
476 }