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