bird1: rename get_bool() to get_a_bool() in bird{4,6}-lib.sh
[feed/routing.git] / bird1-openwrt / bird1-ipv4-openwrt / src / init.d / bird4-lib.sh
1 # Bird4-OpenWRT Library - Functions used in /etc/init.d/bird4 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 and write the $1 string into $BIRD_CONFIG file.
43 # Example: local N=0; write_bool $N
44 write_bool() {
45 [ "$2" == 1 ] && writeToConfig " $1;"
46 }
47
48
49 # Function: get $1 $2
50 # $1 string. $2 string
51 # This function uses the external UCI function "config_get $result $section $option" to obtain a string value from UCI config file.
52 # To use this function, use the same name of the UCI option for the variable.
53 # Example: UCI (option id 'abcd'); local id; get id $section
54 get() {
55 config_get $1 $2 $1
56 }
57
58
59 # Function: get_a_bool $1 $2
60 # $1 boolean. $2 string
61 # This function uses the external UCI function "config_get_bool $result $section $option" to obtain a boolean value from UCI config file.
62 # To use this function, use the same name of the UCI option for the variable $1.
63 # Example: UCI (option use_ipv6 '1'); local use_ipv6; get use_ipv6 $section
64 # Note: this function was originally called get_bool(), but it collided with
65 # the get_bool() function provided by /lib/functions.sh. Read more at
66 # https://github.com/openwrt/routing/issues/920.
67 get_a_bool() {
68 config_get_bool $1 $2 $1
69 }
70
71
72 # Function: multipath_list $1
73 # $1 string
74 # This function writes the $1 string in the multipath routes.
75 multipath_list() {
76 write " via $1" $1
77 }
78
79
80 # Function: range_list $1
81 # $1 string
82 # This function writes the $1 string in the OSPF networks.
83 range_list(){
84 write " $1;" $1
85 }
86
87
88 # Function: hidden_range_list $1
89 # $1 string
90 # This function writes the $1 string in the OSPF networks as hidden.
91 hidden_range_list(){
92 write " $1 hidden;" $1
93 }
94
95
96 # Function: prepare_tables $1
97 # $1 string
98 # This function gets each "table" section in the UCI configuration and sets each option in the bird4.conf file.
99 # $1 is set as the ID of the current UCI table section
100 prepare_tables() {
101 local section="$1"; local name
102
103 get name ${section}
104
105 write "table ${name};" ${name}
106 }
107
108
109 # Function: prepare_global $1
110 # $1 string
111 # This function gets each "global" section in the UCI configuration and sets each option in the bird4.conf file.
112 # $1 is set as the ID of the current UCI global section. prepare_global is the first configuration set in the bird4.conf and removes the old file.
113 prepare_global () {
114 local section="$1"
115 local log_file; local log; local debug; local router_id; local table
116
117 # Remove old configuration file
118 rm -f "${BIRD_CONFIG}"
119
120 get log_file ${section}
121 get log ${section}
122 get debug ${section}
123 get router_id ${section}
124 get table ${section}
125
126 # First line of the NEW configuration file
127 echo "#Bird4 configuration using UCI:" > ${BIRD_CONFIG}
128 writeToConfig " "
129 #TODO: Set Syslog as receiver if empty
130 # LOGF="${log_file:-syslog]}"
131 #TODO: If $log/$debug are empty, set to off
132 if [ -n "${log_file}" -a -n "${log}" ]; then
133 firstEntry="${log:0:3}"
134 if [ "${firstEntry}" = "all" -o "${firstEntry}" = "off" ]; then
135 writeToConfig 'log "'${log_file}'" '${firstEntry}';'
136 else
137 logEntries=$(echo ${log} | tr " " ",")
138 writeToConfig "log \"${log_file}\" { ${logEntries} };"
139 fi
140 fi
141
142 if [ -n "${debug}" ]; then
143 firstEntry="${debug:0:3}"
144 if [ "${firstEntry}" = "all" -o "${firstEntry}" = "off" ]; then
145 writeToConfig "debug protocols ${firstEntry};"
146 else
147 debugEntries=$(echo ${debug} | tr " " ",")
148 writeToConfig "debug protocols { ${debugEntries} };"
149 fi
150 fi
151 writeToConfig " "
152 writeToConfig "#Router ID"
153 write "router id ${router_id};" ${router_id}
154 writeToConfig " "
155 writeToConfig "#Secondary tables"
156 config_foreach prepare_tables 'table'
157 writeToConfig " "
158 }
159
160
161 # Function: prepare_routes $1
162 # $1 string
163 # This function gets each "route" section in the UCI configuration and sets each option in the bird4.conf file.
164 # $1 is set as the ID of the current UCI route section. Each type of route has its own treatment.
165 prepare_routes() {
166 local instance; local prefix; local via; local type; local attribute; local iface
167 local section="$1"
168 local protoInstance="$2"
169
170 get instance ${section}
171 get type ${section}
172 get prefix ${section}
173
174 if [ "${instance}" = "${protoInstance}" ]; then
175 case "${type}" in
176 "router")
177 get via ${section}
178 [ -n "${prefix}" -a -n "${via}" ] && writeToConfig " route ${prefix} via ${via};"
179 ;;
180 "special")
181 get attribute ${section}
182 [ -n "${prefix}" -a -n "${attribute}" ] && writeToConfig " route ${prefix} ${attribute};"
183 ;;
184 "iface")
185 get iface ${section}
186 [ -n "${prefix}" -a -n "${iface}" ] && writeToConfig ' route '${prefix}' via "'${iface}'";'
187 ;;
188 "multipath")
189 write " route ${prefix} multipath" ${prefix}
190 config_list_foreach ${section} l_via multipath_list
191 writeToConfig " ;"
192 ;;
193 esac
194 fi
195 }
196
197
198 # Function: prepare_kernel $1
199 # $1 string
200 # This function gets each "kernel" protocol section in the UCI configuration and sets each option in the bird4.conf file.
201 # $1 is set as the ID of the current UCI kernel section.
202 prepare_kernel() {
203 local section="$1"
204 local disabled; local table; local kernel_table; local import; local export
205 local scan_time; local persist; local learn
206
207 get_a_bool disabled ${section}
208 get table ${section}
209 get import ${section}
210 get export ${section}
211 get scan_time ${section}
212 get kernel_table ${section}
213 get learn ${section}
214 get persist ${section}
215
216 write "#${section} configuration:" ${section}
217 writeToConfig "protocol kernel ${section} {" ${section}
218 write_bool disabled ${disabled}
219 write " table ${table};" ${table}
220 write " kernel table ${kernel_table};" ${kernel_table}
221 write_bool learn ${learn}
222 write_bool persist ${persist}
223 write " scan time ${scan_time};" ${scan_time}
224 write " import ${import};" ${import}
225 write " export ${export};" ${export}
226 writeToConfig "}"
227 writeToConfig " "
228 }
229
230
231 # Function: prepare_static $1
232 # $1 string
233 # This function gets each "static" protocol section in the UCI configuration and sets each option in the bird4.conf file.
234 # $1 is set as the ID of the current UCI static section.
235 prepare_static() {
236 local section="$1"
237 local disabled; local table
238
239 get disabled ${section}
240 get table ${section}
241
242 if [ "${disabled}" -eq 0 ]; then
243 writeToConfig "#${section} configration:" ${section}
244 writeToConfig "protocol static {"
245 write " table ${table};" ${table}
246 config_foreach prepare_routes 'route' ${section}
247 writeToConfig "}"
248 writeToConfig " "
249 fi
250 }
251
252
253 # Function: prepare_direct $1
254 # $1 string
255 # This function gets each "direct" protocol section in the UCI configuration and sets each option in the bird4.conf file.
256 # $1 is set as the ID of the current UCI direct section.
257 prepare_direct() {
258 local section="$1"
259 local disabled; local interface
260
261 get disabled ${section}
262 get interface ${section}
263
264 write "#${section} configuration:" ${section}
265 writeToConfig "protocol direct {"
266 write_bool disabled ${disabled}
267 write " interface ${interface};" ${interface}
268 writeToConfig "}"
269 writeToConfig " "
270 }
271
272
273 # Function: prepare_pipe $1
274 # $1 string
275 # This function gets each "pipe" protocol section in the UCI configuration an
276 # $1 is set as the ID of the current UCI direct section.
277 prepare_pipe() {
278 local section="$1"
279 local disabled; local table; local peer_table; local mode; local import; local export
280
281 get disabled $section
282 get peer_table $section
283 get mode $section
284 get table $section
285 get import $section
286 get export $section
287
288 write "#$section configuration:" $section
289 writeToConfig "protocol pipe $section {" $section
290 write_bool disabled $disabled
291 write " table $table;" $table
292 write " peer table $peer_table;" $peer_table
293 write " mode $mode;" $mode
294 write " import $import;" $import
295 write " export $export;" $export
296 writeToConfig "}"
297 writeToConfig " "
298 }
299
300
301 # Function: prepare_device $1
302 # $1 string
303 # This function gets each "device" protocol section in the UCI configuration and sets each option in the bird4.conf file.
304 # $1 is set as the ID of the current UCI device section.
305 prepare_device() {
306 local section="$1"
307 local disabled; local scan_time
308
309 get disabled ${section}
310 get scan_time ${section}
311
312 write "#${section} configuration:" ${section}
313 writeToConfig "protocol device {"
314 write_bool disabled ${disabled}
315 write " scan time ${scan_time};" ${scan_time}
316 writeToConfig "}"
317 writeToConfig " "
318 }
319
320
321 # Function: prepare_bgp_template $1
322 # $1 string
323 # This function gets each "bgp_template" protocol section in the UCI configuration and sets each option in the bird4.conf file.
324 # $1 is set as the ID of the current UCI bgp_template section.
325 # Careful! Template options will be replaced by "instance" options if there is any match.
326 prepare_bgp_template() {
327 local section="$1"
328 local disabled; local table; local import; local export
329 local local_as; local neighbor_address; local neighbor_as; local source_address
330 local next_hop_self; local next_hop_keep; local rr_client; local rr_cluster_id
331 local import_limit; local import_limit_action; local export_limit; local export_limit_action
332 local receive_limit; local receive_limit_action; local igp_table
333
334 get_a_bool disabled ${section}
335 get table ${section}
336 get import ${section}
337 get export ${section}
338 get source_address ${section}
339
340 get local_as ${section}
341 get neighbor_address ${section}
342 get neighbor_as ${section}
343
344 get_a_bool next_hop_self ${section}
345 get_a_bool next_hop_keep ${section}
346 get rr_client ${section}
347 get rr_cluster_id ${section}
348
349 get import_limit ${section}
350 get import_limit_action ${section}
351 get export_limit ${section}
352 get export_limit_action ${section}
353
354 get receive_limit ${section}
355 get receive_limit_action ${section}
356 get igp_table ${section}
357
358 writeToConfig "#${section} template:"
359 writeToConfig "template bgp ${section} {"
360 [ -n "${disabled}" ] && write_bool disabled ${disabled}
361 [ -n "${table}" ] && writeToConfig " table ${table};"
362 [ -n "${igp_table}" ] && writeToConfig " igp table ${igp_table};"
363 [ -n "${local_as}" ] && writeToConfig " local as ${local_as};"
364 [ -n "${source_address}" ] && writeToConfig " source address ${source_address};"
365 [ -n "${import}" ] && writeToConfig " import ${import};"
366 [ -n "${export}" ] && writeToConfig " export ${export};"
367 [ -n "${neighbor_address}" -a -n "${neighbor_as}" ] && writeToConfig " neighbor ${neighbor_address} as ${neighbor_as};"
368 if [ -n "${import_limit}" -a "${import_limit}" > "0" ]; then
369 [ -z "${import_limit_action}" ] && ${import_limit_action} = "warn"
370 writeToConfig " import limit ${import_limit} action ${import_limit_action};"
371 fi
372 if [ -n "${export_limit}" -a "${export_limit}" > "0" ]; then
373 [ -z "${export_limit_action}" ] && ${export_limit_action} = "warn"
374 writeToConfig " export limit ${export_limit} action ${export_limit_action};"
375 fi
376 if [ -n "${receive_limit}" -a "${receive_limit}" > "0" ]; then
377 [ -z "${receive_limit_action}" ] && ${receive_limit_action} = "warn"
378 writeToConfig " receive limit ${receive_limit} action ${receive_limit_action};"
379 fi
380 [ -n "${next_hop_self}" ] && write_bool " next hop self;" ${next_hop_self}
381 [ -n "${next_hop_keep}" ] && write_bool " next hop keep;" ${next_hop_keep}
382 [ -n "${rr_client}" ] && write_bool " rr client;" ${rr_client}
383 [ -n "${rr_cluster_id}" ] && writeToConfig " rr cluster id ${rr_cluster_id};"
384 writeToConfig "}"
385 writeToConfig " "
386 }
387
388
389 # Function: prepare_bgp $1
390 # $1 string
391 # This function gets each "bgp" protocol section in the UCI configuration and sets each option in the bird4.conf file.
392 # $1 is set as the ID of the current UCI bgp section.
393 # Careful! The options set in bgp instances overlap bgp_template ones.
394 prepare_bgp() {
395 local section="$1"
396 local disabled; local table; local template; local description; local igp_table; local passive
397 local import; local export; local source_address; local local_as; local neighbor_address
398 local neighbor_as; local rr_client; local rr_cluster_id; local import_limit
399 local import_limit_action; local export_limit; local export_limit_action
400 local receive_limit; local receive_limit_action; local igp_table
401
402 get disabled ${section}
403 get table ${section}
404 get igp_table ${section}
405 get template ${section}
406 get description ${section}
407 get passive ${section}
408
409 get import ${section}
410 get export ${section}
411 get source_address ${section}
412 get local_as ${section}
413 get neighbor_address ${section}
414
415 get neighbor_as ${section}
416 get import_limit ${section}
417 get import_limit_action ${section}
418 get export_limit ${section}
419 get export_limit_action ${section}
420
421 get receive_limit ${section}
422 get receive_limit_action ${section}
423 get_a_bool next_hop_self ${section}
424 get_a_bool next_hop_keep ${section}
425 get rr_client ${section}
426 get rr_cluster_id ${section}
427
428 writeToConfig "#${section} configuration:"
429 [ -n "${template}" ] && writeToConfig "protocol bgp ${section} from ${template} {" \
430 || writeToConfig "protocol bgp ${section} {"
431 [ -n "${disabled}" ] && write_bool disabled ${disabled}
432 [ -n "${table}" ] && writeToConfig " table ${table};"
433 [ -n "${igp_table}" ] && writeToConfig " igp table ${igp_table};"
434 [ -n "${passive}" ] && writeToConfig " passive;" ${passive}
435 [ -n "${local_as}" ] && writeToConfig " local as ${local_as};"
436 [ -n "${source_address}" ] && writeToConfig " source address ${source_address};"
437 [ -n "${import}" ] && writeToConfig " import ${import};"
438 [ -n "${export}" ] && writeToConfig " export ${export};"
439 [ -n "${neighbor_address}" -a -n "${neighbor_as}" ] && writeToConfig " neighbor ${neighbor_address} as ${neighbor_as};"
440 if [ -n "${import_limit}" -a "${import_limit}" > "0" ]; then
441 [ -z "${import_limit_action}" ] && ${import_limit_action} = "warn"
442 writeToConfig " import limit ${import_limit} action ${import_limit_action};"
443 fi
444 if [ -n "${export_limit}" -a "${export_limit}" > "0" ]; then
445 [ -z "${export_limit_action}" ] && ${export_limit_action} = "warn"
446 writeToConfig " export limit ${export_limit} action ${export_limit_action};"
447 fi
448 if [ -n "${receive_limit}" -a "${receive_limit}" > "0" ]; then
449 [ -z "${receive_limit_action}" ] && ${receive_limit_action} = "warn"
450 writeToConfig " receive limit ${receive_limit} action ${receive_limit_action};"
451 fi
452 [ -n "${next_hop_self}" ] && write_bool " next hop self;" ${next_hop_self}
453 [ -n "${next_hop_keep}" ] && write_bool " next hop keep;" ${next_hop_keep}
454 [ -n "${rr_client}" ] && write_bool " rr client;" ${rr_client}
455 [ -n "${rr_cluster_id}" ] && writeToConfig " rr cluster id ${rr_cluster_id};"
456 writeToConfig "}"
457 writeToConfig " "
458 }
459
460
461 #Function: prepare_ospf_network $1
462 # $1 string $2 string
463 # This function gets each "ospf_network" protocol section in the UCI configuration, checks if its Area ID is the same as the one
464 # being configurated and finally sets the list of network ranges to be propagated, or not, by the OSPF protocol
465 # $1 is set as the ID of the action area of the internal networks.
466 # $2 is set as the ID of the current area being configurated.
467 prepare_ospf_networks() {
468 local section="$1"
469 local current_area="$2"
470
471 if [ "${section}" = "${current_area}" ]; then
472 writeToConfig " networks {"
473 config_list_foreach ${section} range range_list
474 config_list_foreach ${section} hidden_range hidden_range_list
475 writeToConfig " };"
476 fi
477 }
478
479
480 # Function: prepare_ospf_password $1 $2
481 prepare_ospf_passwords() {
482 local section="$1"
483 local current_interface="$2"
484 local interface; local passphrase
485
486 get interface $section
487 get passphrase $section
488
489 [ "current_interface" = "${interface}" ] && write ' password "$passphrase";' ${passphrase}
490 }
491
492
493 # Function: prepare_ospf_neighbors $1 $2
494 #prepare_ospf_neighbors() {
495 #}
496
497
498 # Function: prepare_ospf_interface $1 $2
499 prepare_ospf_interface() {
500 local section="$1"
501 local current_area="$2"
502 local area; local cost; local type; local hello; local priority; local retransmit; local authentication
503
504 get area ${section}
505 get cost ${section}
506 get type ${section}
507 get hello ${section}
508 get priority ${section}
509 get retransmit ${section}
510
511 if [ "${current_area}" = "${area}" ]; then
512 writeToConfig ' interface "$section" {'
513 write " cost ${cost};" ${cost}
514 write " hello ${hello};" ${hello}
515 write " type ${type};" ${type}
516 write " retransmit ${retransmit};" ${retransmit}
517 write " authentication ${authentication};" ${authentication}
518 config_foreach prepare_ospf_passwords "ospf_password" ${section}
519 # config_foreach prepare_ospf_neighbors "ospf_neighbor" $section
520 writeToConfig " };"
521 fi
522 }
523
524
525 # Function: prepare_ospf_area $1
526 prepare_ospf_area() {
527 local section="$1"
528 local instance; local stub; local default_cost
529
530 get instance ${section}
531 get stub ${section}
532 get default_cost ${section}
533
534 writeToConfig " area ${section} {"
535 if [ -n "${instance}" -a "${instance}" = "${section}" ]; then
536 [ -n "${stub}" -a "${stub}" = "1" ] && writeToConfig " stub yes;"
537 [ -n "${default_cost}" ] && writeToConfig " default cost ${default_cost};"
538 config_foreach prepare_ospf_networks "ospf_networks" ${section}
539 config_foreach prepare_ospf_interface "ospf_interface" ${section}
540 writeToConfig " };"
541 fi
542 }
543
544
545 # Function: prepare_ospf_instance $1
546 # $1 string
547 # This function gets each "ospf_area" protocol section in the UCI configuration and sets each option in the bird4.conf file.
548 # $1 is set as the ID of the current UCI ospf_area section.
549 prepare_ospf_instance() {
550 local section="$1"
551 local cfg1583compat; local tick
552
553 get cfg1583compat ${section}
554 get tick ${section}
555
556 writeToConfig "protocol ospf ${section} {"
557 [ -n "${cfg1583compat}" ] && cfg1583State="yes" || cfg1583State="no"
558 writeToConfig " rfc1583compat ${cfg1583State};"
559 [ -n "${tick}" ] && writeToConfig " tick ${tick};"
560 config_foreach prepare_ospf_area 'ospf_area'
561 writeToConfig "}"
562 }
563
564
565 # Function: gather_filters
566 # This function gets all the FILES under /filters folder and adds
567 # them into the config as %include elements on top of the file
568 # If there are no filters, the section will remain empty.
569 gather_filters() {
570 writeToConfig "#Filters Section:"
571 for filter in $(find /etc/${BIRD}/filters -type f); do
572 writeToConfig "include \"${filter}\";"
573 done
574 writeToConfig "#End of Filters --"
575 writeToConfig " "
576 }
577
578
579 # Function: gather_functions
580 # This function gets all the FILES under /functions folder and adds
581 # them into the config as %include elements on top of the file
582 # If there are no filters, the section will remain empty.
583 gather_functions() {
584 writeToConfig "#Functions Section:"
585 for func in $(find /etc/${BIRD}/functions -type f); do
586 writeToConfig "include \"${func}\";"
587 done
588 writeToConfig "#End of Functions --"
589 writeToConfig " "
590 }