1 #!/bin/sh /etc/rc.common
2 # Copyright (C) 2007-2015 OpenWrt.org
9 KEEPALIVED_CONF
=/tmp
/keepalived.conf
12 INDENT_2
="${INDENT_1}${INDENT_1}"
13 INDENT_3
="${INDENT_1}${INDENT_1}${INDENT_1}"
14 INDENT_4
="${INDENT_1}${INDENT_1}${INDENT_1}${INDENT_1}"
16 config_section_open
() {
20 printf '%s' "$tag" >> "$KEEPALIVED_CONF"
21 [ -n "$name" ] && printf ' %s' "$name" >> "$KEEPALIVED_CONF"
22 printf ' {\n' >> "$KEEPALIVED_CONF"
25 config_section_close
() {
26 printf '}\n\n' >> "$KEEPALIVED_CONF"
29 config_foreach_wrapper
() {
33 # Convention is that 'function' and 'section' are the same
34 config_foreach
"$function" "$section"
37 print_elems_indent
() {
43 [ -z "$indent" ] && indent
="$INDENT_1"
48 if [ "${opt:0:7}" = "no_val_" ]; then
52 config_get
"$opt" "$config" "$opt"
54 [ -z "$optval" ] && continue
55 printf '%b%s' "$indent" "$opt" >> "$KEEPALIVED_CONF"
56 [ "$no_val" = "0" ] && {
58 words
="$(echo "$optval" | wc -w)"
59 if [ "$words" -gt 1 ]; then
60 printf ' "%s"' "$optval" >> "$KEEPALIVED_CONF"
62 printf ' %s' "$optval" >> "$KEEPALIVED_CONF"
65 printf '\n' >> "$KEEPALIVED_CONF"
74 [ -z "$indent" ] && indent
="$INDENT_1"
76 eval lst_elems
=\$
"$lst"
77 [ -z "$lst_elems" ] && return 0
79 printf '%b%s {\n' "$indent" "$lst" >> "$KEEPALIVED_CONF"
80 for e
in $lst_elems; do
81 printf '%b%s\n' "${indent}${INDENT_1}" "$e">> "$KEEPALIVED_CONF"
83 printf '%b}\n' "$indent" >> "$KEEPALIVED_CONF"
91 for notify
in "$@"; do
92 printf '%b%s' "${INDENT_1}" "$notify">> "$KEEPALIVED_CONF"
93 notify
="$(echo "$notify" | tr 'a-z' 'A-Z')"
94 printf ' "/bin/busybox env -i ACTION=%s TYPE=%s NAME=%s /sbin/hotplug-call keepalived"\n' "$notify" "$type" "$name" >> "$KEEPALIVED_CONF"
99 local linkbeat_use_polling notification_email
101 config_get alt_config_file
"$1" alt_config_file
102 [ -z "$alt_config_file" ] ||
return 0
104 config_get_bool linkbeat_use_polling
"$1" linkbeat_use_polling
0
105 [ "$linkbeat_use_polling" -gt 0 ] && printf 'linkbeat_use_polling\n\n' >> "$KEEPALIVED_CONF"
107 config_get notification_email
"$1" notification_email
108 print_list_indent notification_email
110 print_elems_indent
"$1" "$INDENT_1" \
111 notification_email_from \
113 smtp_connect_timeout \
120 print_ipaddress_indent
() {
122 local curr_ipaddr
="$2"
125 local address device scope name
126 config_get name
"$section" name
127 [ "$name" != "$curr_ipaddr" ] && return 0
129 config_get address
"$section" address
130 config_get device
"$section" device
131 config_get scope
"$section" scope
134 [ -z "$indent" ] && indent
="$INDENT_1"
137 [ -z "$address" ] && return 0
139 if [ -z "$device" ]; then
140 printf '%b%s' "$indent" "$address" >> "$KEEPALIVED_CONF"
142 # Add IP address/netmask and device
143 printf '%b%s dev %s' "$indent" "$address" "$device">> "$KEEPALIVED_CONF"
145 [ -n "$scope" ] && printf ' scope %s' "$scope" >> "$KEEPALIVED_CONF"
148 printf '\n' >> "$KEEPALIVED_CONF"
153 config_get address
"$1" address
154 for a
in $address; do
155 config_foreach print_ipaddress_indent ipaddress
"$a"
159 print_route_indent
() {
161 local curr_route
="$2"
164 local name blackhole address src_addr gateway device scope table
166 config_get name
"$section" name
167 [ "$name" != "$curr_route" ] && return 0
169 config_get_bool blackhole
"$section" blackhole
0
170 config_get address
"$section" address
171 config_get src_addr
"$section" src_addr
172 config_get gateway
"$section" gateway
173 config_get device
"$section" device
174 config_get table
"$section" table
177 [ -z "$address" ] && return 0
180 [ -z "$indent" ] && indent
="$INDENT_1"
182 [ "$blackhole" -gt 0 ] && {
183 printf '%bblackhole %s\n' "$indent" "$address" >> "$KEEPALIVED_CONF"
186 # Add src addr or address
187 if [ -n "$src_addr" ]; then
188 printf '%bsrc %s %s' "$indent" "$src_addr" "$address" >> "$KEEPALIVED_CONF"
190 [ -z "$device" ] && return 0
191 printf '%b%s' "$indent" "$address" >> "$KEEPALIVED_CONF"
194 [ -n "$gateway" ] && printf ' via %s' "$gateway" >> "$KEEPALIVED_CONF"
196 printf ' dev %s' "$device" >> "$KEEPALIVED_CONF"
198 [ -n "$scope" ] && printf ' scope %s' "$scope" >> "$KEEPALIVED_CONF"
200 [ -n "$table" ] && printf ' table %s' "$table" >> "$KEEPALIVED_CONF"
201 printf '\n' >> "$KEEPALIVED_CONF"
205 print_track_elem_indent
() {
207 local curr_track_elem
="$2"
211 config_get name
"$section" name
212 [ "$name" != "$curr_track_elem" ] && return 0
214 config_get value
"$section" value
215 config_get weight
"$section" weight
217 [ -z "$value" ] && return 0
219 printf '%b%s' "$indent" "$value" >> "$KEEPALIVED_CONF"
220 [ -n "$weight" ] && printf ' weight %s' "$weight" >> "$KEEPALIVED_CONF"
221 printf '\n' >> "$KEEPALIVED_CONF"
226 config_get route
"$1" route
228 config_foreach print_route_indent route
"$r"
232 # Count 'vrrp_instance' with the given name ; called by vrrp_instance_check()
233 vrrp_instance_name_count
() {
235 config_get name
"$1" name
236 [ "$name" = "$2" ] && count
="$((count + 1))"
239 # Check if there's a 'vrrp_instance' section with the given name
240 vrrp_instance_check
() {
243 config_foreach vrrp_instance_name_count vrrp_instance
"$name"
244 [ $count -gt 0 ] && return 0 ||
return 1
251 # No name for group, exit
252 config_get name
"$1" name
253 [ -z "$name" ] && return 0
255 # No members for group, exit
256 config_get group
"$1" group
257 [ -z "$group" ] && return 0
259 # Check if we have 'vrrp_instance's defined for
260 # each member and remove names with not vrrp_instance defined
262 vrrp_instance_check
"$m" && valid_group
="$valid_group $m"
264 [ -z "$valid_group" ] && return 0
266 config_section_open
"vrrp_sync_group" "$name"
269 print_list_indent group
271 print_elems_indent
"$1" "$INDENT_1" no_val_smtp_alert no_val_global_tracking
273 print_notify
"GROUP" "$name" notify_backup notify_master \
280 local name auth_type auth_pass
282 config_get name
"$1" name
283 [ -z "$name" ] && return 0
285 config_section_open
"vrrp_instance" "$name"
287 config_get auth_type
"$1" auth_type
288 config_get auth_pass
"$1" auth_pass
289 [ -n "$auth_type" ] && [ -n "$auth_pass" ] && {
290 printf '%bauthentication {\n' "${INDENT_1}" >> "$KEEPALIVED_CONF"
291 printf '%bauth_type %s\n' "${INDENT_2}" "$auth_type" >> "$KEEPALIVED_CONF"
292 printf '%bauth_pass %s\n' "${INDENT_2}" "$auth_pass" >> "$KEEPALIVED_CONF"
293 printf '%b}\n' "${INDENT_1}" >> "$KEEPALIVED_CONF"
296 print_elems_indent
"$1" "$INDENT_1" state interface \
297 mcast_src_ip unicast_src_ip virtual_router_id version priority \
298 advert_int preempt_delay debug \
299 lvs_sync_daemon_interface garp_master_delay garp_master_refresh \
300 garp_master_repeat garp_master_refresh_repeat \
301 no_val_vmac_xmit_base no_val_native_ipv6 no_val_accept \
302 no_val_dont_track_primary no_val_smtp_alert no_val_nopreempt \
305 print_notify
"INSTANCE" "$name" notify_backup notify_master \
306 notify_fault notify_stop
308 # Handle virtual_ipaddress & virtual_ipaddress_excluded lists
309 for opt
in virtual_ipaddress virtual_ipaddress_excluded
; do
310 config_get
"$opt" "$1" "$opt"
312 [ -z "$optval" ] && continue
313 printf '%b%s {\n' "${INDENT_1}" "$opt" >> "$KEEPALIVED_CONF"
315 config_foreach print_ipaddress_indent ipaddress
"$a" "$INDENT_2"
317 printf '%b}\n' "${INDENT_1}" >> "$KEEPALIVED_CONF"
320 # Handle virtual_routes
321 for opt
in virtual_routes
; do
322 config_get
"$opt" "$1" "$opt"
324 [ -z "$optval" ] && continue
325 printf '%b%s {\n' "${INDENT_1}" "$opt" >> "$KEEPALIVED_CONF"
327 config_foreach print_route_indent route
"$r" "$INDENT_2"
329 printf '%b}\n' "${INDENT_1}" >> "$KEEPALIVED_CONF"
332 # Handle track_script lists
333 for opt
in track_script
; do
334 config_get
"$opt" "$1" "$opt"
336 [ -z "$optval" ] && continue
337 printf '%b%s {\n' "${INDENT_1}" "$opt" >> "$KEEPALIVED_CONF"
339 printf '%b%s\n' "${INDENT_2}" "$optval" >> "$KEEPALIVED_CONF"
341 printf '%b}\n' "${INDENT_1}" >> "$KEEPALIVED_CONF"
344 # Handle track_interface lists
345 for opt
in track_interface
; do
346 config_get
"$opt" "$1" "$opt"
348 [ -z "$optval" ] && continue
349 printf '%b%s {\n' "${INDENT_1}" "$opt" >> "$KEEPALIVED_CONF"
351 config_foreach print_track_elem_indent track_interface
"$t" "$INDENT_2"
353 printf '%b}\n' "${INDENT_1}" >> "$KEEPALIVED_CONF"
356 # Handle simple lists of strings (with no spaces in between)
357 for opt
in unicast_peer
; do
358 config_get
"$opt" "$1" "$opt"
359 print_list_indent
"$opt"
369 config_get name
"$1" name
370 [ -z "$name" ] && return 0
372 config_section_open
"vrrp_script" "$name"
374 print_elems_indent
"$1" "$INDENT_1" script interval weight fall rise
382 local name path digest
384 config_get name
"$1" name
385 [ "$url" = "$name" ] ||
return 0
387 config_get path
"$1" path
388 config_get digest
"$1" digest
390 [ -n "$digest" ] && [ -n "$path" ] && {
391 printf '%burl {\n' "${INDENT_3}" >> "$KEEPALIVED_CONF"
392 printf '%bpath %s\n' "${INDENT_4}" "$path" >> "$KEEPALIVED_CONF"
393 printf '%bdigest %s\n' "${INDENT_4}" "$digest" >> "$KEEPALIVED_CONF"
394 printf '%b}\n' "${INDENT_3}" >> "$KEEPALIVED_CONF"
399 config_foreach url url
"$1"
405 local enabled name weight ipaddr port check
407 config_get_bool enabled
"$1" enabled
1
408 [ "$enabled" -eq 1 ] ||
return 0
410 config_get name
"$1" name
411 [ "$server" = "$name" ] ||
return 0
413 config_get weight
"$1" weight
414 [ -n "$weight" ] ||
return 0
416 config_get ipaddr
"$1" ipaddr
417 config_get port
"$1" port
418 config_get check
"$1" check
420 [ -n "$ipaddr" ] && [ -n "$port" ] && {
421 printf '%breal_server %s %d {\n' "${INDENT_1}" "$ipaddr" "$port" >> "$KEEPALIVED_CONF"
422 printf '%bweight %d\n' "${INDENT_2}" "$weight" >> "$KEEPALIVED_CONF"
425 printf '%b%s {\n' "${INDENT_2}" "$check" >> "$KEEPALIVED_CONF"
426 print_elems_indent
"$1" "$INDENT_3" connect_timeout \
428 printf '%b}\n' "${INDENT_2}" >> "$KEEPALIVED_CONF"
431 printf '%b%s {\n' "${INDENT_2}" "$check" >> "$KEEPALIVED_CONF"
432 print_elems_indent
"$1" "$INDENT_3" misc_path
433 printf '%b}\n' "${INDENT_2}" >> "$KEEPALIVED_CONF"
436 printf '%b%s {\n' "${INDENT_2}" "$check" >> "$KEEPALIVED_CONF"
437 print_elems_indent
"$1" "$INDENT_3" connect_timeout \
438 connect_port nb_get_retry delay_before_retry
440 config_list_foreach
"$1" url url_list
441 printf '%b}\n' "${INDENT_2}" >> "$KEEPALIVED_CONF"
444 printf '%b}\n' "${INDENT_1}" >> "$KEEPALIVED_CONF"
449 config_foreach real_server real_server
"$1"
453 local enabled ipaddr port lb_algo sorry_server_ip sorry_server_port
455 config_get_bool enabled
"$1" enabled
1
456 [ "$enabled" -eq 1 ] ||
return 0
458 config_get ipaddr
"$1" ipaddr
459 [ -z "$ipaddr" ] && return 0
460 config_get port
"$1" port
461 [ -z "$port" ] && return 0
463 config_section_open
"virtual_server" "$ipaddr $port"
465 print_elems_indent
"$1" "$INDENT_1" fwmark delay_loop \
466 lb_kind persistence_timeout persistence_granularity \
469 config_get lb_algo
"$1" lb_algo
470 [ -z "$lb_algo" ] && lb_algo
="rr"
471 modprobe ip_vs_
${lb_algo} 1>/dev
/null
2>&1
472 printf '%blb_algo %s\n' "${INDENT_1}" "${lb_algo}" >> "$KEEPALIVED_CONF"
474 config_get sorry_server_ip
"$1" sorry_server_ip
475 config_get sorry_server_port
"$1" sorry_server_port
476 [ -n "$sorry_server_ip" ] && [ -n "$sorry_server_port" ] && {
477 printf '%bsorry_server %s %s\n' "${INDENT_1}" "$sorry_server_ip" "$sorry_server_port" >> "$KEEPALIVED_CONF"
480 # Handle real_server list
481 config_list_foreach
"$1" real_server real_server_list
487 local alt_config_file
489 rm -f "$KEEPALIVED_CONF"
492 printf '! Configuration file for keepalived (autogenerated via init script)\n' > "$KEEPALIVED_CONF"
493 printf '! Written %s\n\n' "$(date +'%c')" >> "$KEEPALIVED_CONF"
495 [ -f /etc
/config
/keepalived
] ||
return 0
496 config_load
'keepalived'
498 config_section_open
"global_defs"
499 config_foreach_wrapper global_defs
502 # If "alt_config_file" specified, use that instead
503 [ -n "$alt_config_file" ] && [ -f "$alt_config_file" ] && {
504 rm -f "$KEEPALIVED_CONF"
505 # Symlink "alt_config_file" since it's a bit easier and safer
506 ln -s "$alt_config_file" "$KEEPALIVED_CONF"
510 config_section_open
"static_ipaddress"
511 config_foreach_wrapper static_ipaddress
514 config_section_open
"static_routes"
515 config_foreach_wrapper static_routes
518 config_foreach_wrapper vrrp_script
519 config_foreach_wrapper vrrp_sync_group
520 config_foreach_wrapper vrrp_instance
521 config_foreach_wrapper virtual_server
526 procd_add_reload_trigger
"keepalived"
531 #SIGHUP is used by keepalived to do init.d reload
532 procd_send_signal keepalived
537 procd_set_param
command /usr
/sbin
/keepalived
538 procd_append_param
command -n # don't daemonize, procd will handle that for us
539 procd_append_param
command -f "$KEEPALIVED_CONF"
543 # set auto respawn behavior
544 procd_set_param respawn