|
|
- #!/bin/sh /etc/rc.common
- # Copyright (C) 2007-2015 OpenWrt.org
-
- START=70
- STOP=01
-
- USE_PROCD=1
-
- KEEPALIVED_CONF=/tmp/keepalived.conf
-
- INDENT_1=\\t
- INDENT_2=$INDENT_1$INDENT_1
- INDENT_3=$INDENT_1$INDENT_1$INDENT_1
- INDENT_4=$INDENT_1$INDENT_1$INDENT_1$INDENT_1
-
- config_section_open() {
- local tag=$1
- local name=$2
-
- printf "$tag" >> $KEEPALIVED_CONF
- [ -n "$name" ] && printf " $name" >> $KEEPALIVED_CONF
- printf " {\n" >> $KEEPALIVED_CONF
- }
-
- config_section_close() {
- printf "}\n\n" >> $KEEPALIVED_CONF
- }
-
- config_foreach_wrapper() {
- local section=$1
- local function=$1
-
- # Convention is that 'function' and 'section' are the same
- config_foreach $function $section
- }
-
- print_elems_indent() {
- local config=$1
- shift
- local indent=$1
- shift
- [ -z "$indent" ] && indent="$INDENT_1"
- for opt in $*; do
- local $opt
- local no_val=0
- if [ ${opt:0:7} == "no_val_" ]; then
- opt=${opt:7}
- no_val=1
- fi
- config_get $opt $config $opt
- eval optval=\$$opt
- [ -z "$optval" ] && continue
- printf "$indent$opt" >> $KEEPALIVED_CONF
- [ "$no_val" == "0" ] && {
- local words=$(echo "$optval" | wc -w)
- if [ $words -gt 1 ]; then
- printf " \"$optval\"" >> $KEEPALIVED_CONF
- else
- printf " $optval" >> $KEEPALIVED_CONF
- fi
- }
- printf "\n" >> $KEEPALIVED_CONF
- done
- unset optval
- }
-
- print_list_indent() {
- local lst=$1
- local indent=$2
- local lst_elems
- [ -z "$indent" ] && indent=$INDENT_1
-
- eval lst_elems=\$$lst
- [ -z "$lst_elems" ] && return 0
-
- printf "$indent$lst {\n" >> $KEEPALIVED_CONF
- for e in $lst_elems; do
- [ -n "$eval_item_func" ]
- printf "$indent$INDENT_1$e\n" >> $KEEPALIVED_CONF
- done
- printf "$indent}\n" >> $KEEPALIVED_CONF
- }
-
- print_notify() {
- local type=$1
- shift
- local name=$1
- shift
- for notify in $*; do
- printf "$INDENT_1$notify" >> $KEEPALIVED_CONF
- notify=$(echo $notify | tr 'a-z' 'A-Z')
- printf " \"/bin/busybox env -i ACTION=$notify TYPE=$type NAME=$name /sbin/hotplug-call keepalived\"\n" >> $KEEPALIVED_CONF
- done
- }
-
- global_defs() {
- local linkbeat_use_polling notification_email
-
- config_get alt_config_file $1 alt_config_file
- [ -z "$alt_config_file" ] || return 0
-
- config_get_bool linkbeat_use_polling $1 linkbeat_use_polling 0
- [ $linkbeat_use_polling -gt 0 ] && printf "linkbeat_use_polling\n\n" >> $KEEPALIVED_CONF
-
- config_get notification_email $1 notification_email
- print_list_indent notification_email
-
- print_elems_indent $1 $INDENT_1 \
- notification_email_from \
- smtp_server \
- smtp_connect_timeout \
- router_id \
- vrrp_mcast_group4 \
- vrrp_mcast_group6 \
- vrrp_startup_delay
- }
-
- print_ipaddress_indent() {
- local section=$1
- local curr_ipaddr=$2
- local indent=$3
-
- local address device scope name
- config_get name $section name
- [ "$name" != "$curr_ipaddr" ] && return 0
-
- config_get address $section address
- config_get device $section device
- config_get scope $section scope
-
- # Default indent
- [ -z "$indent" ] && indent=$INDENT_1
-
- # If no address exit
- [ -z "$address" ] && return 0
-
- if [ -z "$device" ]; then
- printf "$indent$address" >> $KEEPALIVED_CONF
- else
- # Add IP address/netmask and device
- printf "$indent$address dev $device" >> $KEEPALIVED_CONF
- # Add scope
- [ -n "$scope" ] && printf " scope $scope" >> $KEEPALIVED_CONF
- fi
-
- printf "\n" >> $KEEPALIVED_CONF
- }
-
- static_ipaddress() {
- local address
- config_get address "$1" address
- for a in $address; do
- config_foreach print_ipaddress_indent ipaddress $a
- done
- }
-
- print_route_indent() {
- local section=$1
- local curr_route=$2
- local indent=$3
-
- local name blackhole address src_addr gateway device scope table
-
- config_get name $section name
- [ "$name" != "$curr_route" ] && return 0
-
- config_get_bool blackhole $section blackhole 0
- config_get address $section address
- config_get src_addr $section src_addr
- config_get gateway $section gateway
- config_get device $section device
- config_get table $section table
-
- # If no address exit
- [ -z "$address" ] && return 0
-
- # Default indent
- [ -z "$indent" ] && indent=$INDENT_1
-
- [ $blackhole -gt 0 ] && {
- printf "${indent}blackhole $address\n" >> $KEEPALIVED_CONF
- return 0
- }
- # Add src addr or address
- if [ -n "$src_addr" ]; then
- printf "${indent}src $src_addr $address" >> $KEEPALIVED_CONF
- else
- [ -z "$device" ] && return 0
- printf "$indent$address" >> $KEEPALIVED_CONF
- fi
- # Add route/gateway
- [ -n "$gateway" ] && printf " via $gateway" >> $KEEPALIVED_CONF
- # Add device
- printf " dev $device" >> $KEEPALIVED_CONF
- # Add scope
- [ -n "$scope" ] && printf " scope $scope" >> $KEEPALIVED_CONF
- # Add table
- [ -n "$table" ] && printf " table $table" >> $KEEPALIVED_CONF
- printf "\n" >> $KEEPALIVED_CONF
-
- }
-
- print_track_elem_indent() {
- local section=$1
- local curr_track_elem=$2
- local indent=$3
-
- local script name value
- config_get name $section name
- [ "$name" != "$curr_track_elem" ] && return 0
-
- config_get value $section value
- config_get weight $section weight
-
- [ -z "$value" ] && return 0
-
- printf "$indent$value" >> $KEEPALIVED_CONF
- [ -n "$weight" ] && printf " weight $weight" >> $KEEPALIVED_CONF
- printf "\n" >> $KEEPALIVED_CONF
- }
-
- static_routes() {
- local route
- config_get route "$1" route
- for r in $route; do
- config_foreach print_route_indent route $r
- done
- }
-
- # Count 'vrrp_instance' with the given name ; called by vrrp_instance_check()
- vrrp_instance_name_count() {
- local name
- config_get name $1 name
- [ "$name" == "$2" ] && count=$((count + 1))
- }
-
- # Check if there's a 'vrrp_instance' section with the given name
- vrrp_instance_check() {
- local count=0
- local name=$1
- config_foreach vrrp_instance_name_count vrrp_instance $name
- [ $count -gt 0 ] && return 0 || return 1
- }
-
- vrrp_sync_group() {
- local group name
- local valid_group
-
- # No name for group, exit
- config_get name $1 name
- [ -z "$name" ] && return 0
-
- # No members for group, exit
- config_get group $1 group
- [ -z "$group" ] && return 0
-
- # Check if we have 'vrrp_instance's defined for
- # each member and remove names with not vrrp_instance defined
- for m in $group; do
- vrrp_instance_check $m && valid_group="$valid_group $m"
- done
- [ -z "$valid_group" ] && return 0
-
- config_section_open "vrrp_sync_group" "$name"
-
- group="$valid_group"
- print_list_indent group
-
- print_elems_indent $1 $INDENT_1 no_val_smtp_alert no_val_global_tracking
-
- print_notify "GROUP" "$name" notify_backup notify_master \
- notify_fault notify
-
- config_section_close
- }
-
- vrrp_instance() {
- local name auth_type auth_pass
-
- config_get name $1 name
- [ -z "$name" ] && return 0
-
- config_section_open "vrrp_instance" "$name"
-
- config_get auth_type $1 auth_type
- config_get auth_pass $1 auth_pass
- [ -n "$auth_type" -a -n "$auth_pass" ] && {
- printf "${INDENT_1}authentication {\n" >> $KEEPALIVED_CONF
- printf "${INDENT_2}auth_type $auth_type\n" >> $KEEPALIVED_CONF
- printf "${INDENT_2}auth_pass $auth_pass\n" >> $KEEPALIVED_CONF
- printf "$INDENT_1}\n" >> $KEEPALIVED_CONF
- }
-
- print_elems_indent $1 $INDENT_1 state interface \
- mcast_src_ip unicast_src_ip virtual_router_id version priority \
- advert_int preempt_delay debug \
- lvs_sync_daemon_interface garp_master_delay garp_master_refresh \
- garp_master_repeat garp_master_refresh_repeat \
- no_val_vmac_xmit_base no_val_native_ipv6 no_val_accept \
- no_val_dont_track_primary no_val_smtp_alert no_val_nopreempt \
- no_val_use_vmac
-
- print_notify "INSTANCE" "$name" notify_backup notify_master \
- notify_fault notify_stop
-
- # Handle virtual_ipaddress & virtual_ipaddress_excluded lists
- for opt in virtual_ipaddress virtual_ipaddress_excluded; do
- config_get $opt $1 $opt
- eval optval=\$$opt
- [ -z "$optval" ] && continue
- printf "$INDENT_1$opt {\n" >> $KEEPALIVED_CONF
- for a in $optval; do
- config_foreach print_ipaddress_indent ipaddress $a $INDENT_2
- done
- printf "$INDENT_1}\n" >> $KEEPALIVED_CONF
- done
-
- # Handle virtual_routes
- for opt in virtual_routes; do
- config_get $opt $1 $opt
- eval optval=\$$opt
- [ -z "$optval" ] && continue
- printf "$INDENT_1$opt {\n" >> $KEEPALIVED_CONF
- for r in $optval; do
- config_foreach print_route_indent route $r $INDENT_2
- done
- printf "$INDENT_1}\n" >> $KEEPALIVED_CONF
- done
-
- # Handle track_script lists
- for opt in track_script; do
- config_get $opt $1 $opt
- eval optval=\$$opt
- [ -z "$optval" ] && continue
- printf "$INDENT_1$opt {\n" >> $KEEPALIVED_CONF
- for t in $optval; do
- printf "$INDENT_2$optval\n" >> $KEEPALIVED_CONF
- done
- printf "$INDENT_1}\n" >> $KEEPALIVED_CONF
- done
-
- # Handle track_interface lists
- for opt in track_interface; do
- config_get $opt $1 $opt
- eval optval=\$$opt
- [ -z "$optval" ] && continue
- printf "$INDENT_1$opt {\n" >> $KEEPALIVED_CONF
- for t in $optval; do
- config_foreach print_track_elem_indent track_interface $t $INDENT_2
- done
- printf "$INDENT_1}\n" >> $KEEPALIVED_CONF
- done
-
- # Handle simple lists of strings (with no spaces in between)
- for opt in unicast_peer; do
- config_get $opt $1 $opt
- print_list_indent $opt
- done
- unset optval
-
- config_section_close
- }
-
- vrrp_script() {
- local name
-
- config_get name $1 name
- [ -z "$name" ] && return 0
-
- config_section_open "vrrp_script" "$name"
-
- print_elems_indent $1 $INDENT_1 script interval weight fall rise
-
- config_section_close
- }
-
- url() {
- local url="$2"
-
- local name path digest
-
- config_get name $1 name
- [ "$url" = "$name" ] || return 0
-
- config_get path $1 path
- config_get digest $1 digest
-
- [ -n "$digest" -a -n "$path" ] && {
- printf "${INDENT_3}url {\n" >> $KEEPALIVED_CONF
- printf "${INDENT_4}path "$path"\n" >> $KEEPALIVED_CONF
- printf "${INDENT_4}digest $digest\n" >> $KEEPALIVED_CONF
- printf "${INDENT_3}}\n" >> $KEEPALIVED_CONF
- }
- }
-
- url_list() {
- config_foreach url url "$1"
- }
-
- real_server() {
- local server="$2"
-
- local enabled name weight ipaddr port check
-
- config_get_bool enabled $1 enabled 1
- [ "$enabled" -eq 1 ] || return 0
-
- config_get name $1 name
- [ "$server" = "$name" ] || return 0
-
- config_get weight $1 weight
- [ -n "$weight" ] || return 0
-
- config_get ipaddr $1 ipaddr
- config_get port $1 port
- config_get check $1 check
-
- [ -n "$ipaddr" -a -n "$port" ] && {
- printf "${INDENT_1}real_server $ipaddr $port {\n" >> $KEEPALIVED_CONF
- printf "${INDENT_2}weight $weight\n" >> $KEEPALIVED_CONF
- case "$check" in
- TCP_CHECK)
- printf "${INDENT_2}${check} {\n" >> $KEEPALIVED_CONF
- print_elems_indent $1 $INDENT_3 connect_timeout \
- connect_port
- printf "${INDENT_2}}\n" >> $KEEPALIVED_CONF
- ;;
- MISC_CHECK)
- printf "${INDENT_2}${check} {\n" >> $KEEPALIVED_CONF
- print_elems_indent $1 $INDENT_3 misc_path
- printf "${INDENT_2}}\n" >> $KEEPALIVED_CONF
- ;;
- HTTP_GET | SSL_GET)
- printf "${INDENT_2}${check} {\n" >> $KEEPALIVED_CONF
- print_elems_indent $1 $INDENT_3 connect_timeout \
- connect_port nb_get_retry delay_before_retry
- # Handle url list
- config_list_foreach $1 url url_list
- printf "${INDENT_2}}\n" >> $KEEPALIVED_CONF
- ;;
- esac
- printf "${INDENT_1}}\n" >> $KEEPALIVED_CONF
- }
- }
-
- real_server_list() {
- config_foreach real_server real_server "$1"
- }
-
- virtual_server() {
- local enabled ipaddr port lb_algo sorry_server_ip sorry_server_port
-
- config_get_bool enabled $1 enabled 1
- [ "$enabled" -eq 1 ] || return 0
-
- config_get ipaddr $1 ipaddr
- [ -z "$ipaddr" ] && return 0
- config_get port $1 port
- [ -z "$port" ] && return 0
-
- config_section_open "virtual_server" "$ipaddr $port"
-
- print_elems_indent $1 $INDENT_1 fwmark delay_loop \
- lb_kind persistence_timeout persistence_granularity \
- virtualhost protocol
-
- config_get lb_algo $1 lb_algo
- [ -z "$lb_algo" ] && lb_algo="rr"
- modprobe ip_vs_${lb_algo} 2>&1 1>/dev/null
- printf "${INDENT_1}lb_algo ${lb_algo}\n" >> $KEEPALIVED_CONF
-
- config_get sorry_server_ip $1 sorry_server_ip
- config_get sorry_server_port $1 sorry_server_port
- [ -n "$sorry_server_ip" -a -n "$sorry_server_port" ] && {
- printf "${INDENT_1}sorry_server $sorry_server_ip $sorry_server_port\n" >> $KEEPALIVED_CONF
- }
-
- # Handle real_server list
- config_list_foreach $1 real_server real_server_list
-
- config_section_close
- }
-
- process_config() {
- local alt_config_file
-
- rm -f $KEEPALIVED_CONF
-
- # First line
- printf "! Configuration file for keepalived (autogenerated via init script)\n" > $KEEPALIVED_CONF
- printf "! Written %s\n\n" "$(date +'%c')" >> $KEEPALIVED_CONF
-
- [ -f /etc/config/keepalived ] || return 0
- config_load 'keepalived'
-
- config_section_open "global_defs"
- config_foreach_wrapper global_defs
- config_section_close
-
- # If "alt_config_file" specified, use that instead
- [ -n "$alt_config_file" ] && [ -f "$alt_config_file" ] && {
- rm -f $KEEPALIVED_CONF
- # Symlink "alt_config_file" since it's a bit easier and safer
- ln -s $alt_config_file $KEEPALIVED_CONF
- return 0
- }
-
- config_section_open "static_ipaddress"
- config_foreach_wrapper static_ipaddress
- config_section_close
-
- config_section_open "static_routes"
- config_foreach_wrapper static_routes
- config_section_close
-
- config_foreach_wrapper vrrp_script
- config_foreach_wrapper vrrp_sync_group
- config_foreach_wrapper vrrp_instance
- config_foreach_wrapper virtual_server
- return 0
- }
-
- service_triggers() {
- procd_add_reload_trigger "keepalived"
- }
-
- reload_service() {
- process_config
- #SIGHUP is used by keepalived to do init.d reload
- procd_send_signal keepalived
- }
-
- start_service() {
- procd_open_instance
- procd_set_param command /usr/sbin/keepalived
- procd_append_param command -n # don't daemonize, procd will handle that for us
- procd_append_param command -f "$KEEPALIVED_CONF"
-
- process_config
-
- # set auto respawn behavior
- procd_set_param respawn
- procd_close_instance
- }
-
|