| #!/bin/bash |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| PATH=/bin:/usr/bin:/sbin:/usr/sbin |
| D_PATH="@CFG_SBIN@" |
| C_PATH="@CFG_SYSCONF@" |
| V_PATH="@CFG_STATE@" |
| VTYSH="@vtysh_bin@" |
| FRR_USER="@enable_user@" |
| FRR_GROUP="@enable_group@" |
| FRR_VTY_GROUP="@enable_vty_group@" |
| FRR_CONFIG_MODE="@enable_configfile_mask@" |
| FRR_DEFAULT_PROFILE="@DFLT_NAME@" |
| |
| |
| |
| |
| DAEMONS="zebra bgpd ripd ripngd ospfd ospf6d isisd babeld pimd ldpd nhrpd eigrpd sharpd pbrd staticd bfdd fabricd vrrpd" |
| MAX_INSTANCES=5 |
| RELOAD_SCRIPT="$D_PATH/frr-reload.py" |
| |
| if [ -e /lib/lsb/init-functions ]; then |
| . /lib/lsb/init-functions |
| fi |
| |
| if [ -f $D_PATH/ssd ]; then |
| SSD=$D_PATH/ssd |
| else |
| SSD=`which start-stop-daemon` |
| fi |
| |
| |
| pidfile() |
| { |
| echo "$V_PATH/$1.pid" |
| } |
| |
| |
| vtyfile() |
| { |
| echo "$V_PATH/$1.vty" |
| } |
| |
| chownfrr() |
| { |
| test -n "$FRR_USER" && chown "$FRR_USER" "$1" |
| test -n "$FRR_GROUP" && chgrp "$FRR_GROUP" "$1" |
| test -n "$FRR_CONFIG_MODE" && chmod "$FRR_CONFIG_MODE" "$1" |
| } |
| |
| |
| started() |
| { |
| [ ! -e `pidfile $1` ] && return 3 |
| if [ -n "$2" ] && [ "$2" == "log" ]; then |
| status_of_proc -p `pidfile $1` $1 $1 && return 0 || return $? |
| else |
| kill -0 `cat \`pidfile $1\`` 2> /dev/null || return 1 |
| return 0 |
| fi |
| } |
| |
| |
| vtysh_b () |
| { |
| |
| if [ "$vtysh_enable" = 2 -a -f $C_PATH/frr.conf ]; then |
| $VTYSH -b |
| fi |
| } |
| |
| |
| |
| |
| |
| check_daemon() |
| { |
| if [ $1 != "watchfrr" -a $1 != "vtysh_enable" ]; then |
| |
| if [ ! -x "$D_PATH/$1" ]; then return 1; fi |
| fi |
| |
| |
| if [ -r "$C_PATH/frr.conf" ]; then |
| return 0 |
| fi |
| |
| |
| |
| if [ $1 != "watchfrr" -a $1 != "vtysh_enable" ]; then |
| |
| if [ -n "$2" ]; then |
| if [ ! -r "$C_PATH/$1-$2.conf" ]; then |
| touch "$C_PATH/$1-$2.conf" |
| chownfrr "$C_PATH/$1-$2.conf" |
| fi |
| elif [ ! -r "$C_PATH/$1.conf" ]; then |
| touch "$C_PATH/$1.conf" |
| chownfrr "$C_PATH/$1.conf" |
| fi |
| fi |
| return 0 |
| } |
| |
| |
| |
| start() |
| { |
| local dmn inst |
| dmn="$1" |
| inst="$2" |
| |
| ulimit -n $MAX_FDS > /dev/null 2> /dev/null |
| if [ "$dmn" = "watchfrr" ]; then |
| |
| |
| |
| if started "$dmn" ; then |
| stop watchfrr |
| else |
| |
| echo -n " $dmn" |
| fi |
| |
| eval "set - $watchfrr_options" |
| ${SSD} \ |
| --start \ |
| --pidfile=`pidfile $dmn` \ |
| --exec "$D_PATH/$dmn" \ |
| -- \ |
| "$@" |
| |
| elif [ -n "$inst" ]; then |
| echo -n " $dmn-$inst" |
| if ! check_daemon $dmn $inst ; then |
| echo -n " (binary does not exist)" |
| return; |
| fi |
| |
| ${SSD} \ |
| --start \ |
| --pidfile=`pidfile $dmn-$inst` \ |
| --exec "$D_PATH/$dmn" \ |
| -- \ |
| `eval echo "$""$dmn""_options"` $frr_global_options -n "$inst" |
| else |
| if ! check_daemon $dmn; then |
| echo -n " (binary does not exist)" |
| return; |
| fi |
| |
| if [ "$valgrind_enable" = "yes" ]; then |
| ${SSD} \ |
| --start \ |
| --pidfile=`pidfile $dmn` \ |
| --exec "$valgrind" \ |
| -- --trace-children=no --leak-check=full --log-file=/var/log/frr/$dmn-valgrind.log $D_PATH/$dmn \ |
| `eval echo "$""$dmn""_options"` $frr_global_options |
| else |
| ${SSD} \ |
| --start \ |
| --pidfile=`pidfile $dmn` \ |
| --exec "$D_PATH/$dmn" \ |
| -- \ |
| `eval echo "$""$dmn""_options"` $frr_global_options |
| fi |
| fi |
| |
| |
| if [ "$dmn" = "zebra" ]; then |
| echo -n "starting staticd since zebra is running" |
| if ! check_daemon staticd ; then |
| echo -n " (binary does not exist)" |
| return; |
| fi |
| |
| ${SSD} \ |
| --start \ |
| --pidfile=`pidfile staticd` \ |
| --exec "$D_PATH/staticd" \ |
| -- \ |
| `eval echo "$"staticd"_options"` $frr_global_options |
| fi |
| } |
| |
| |
| stop() |
| { |
| local inst |
| |
| if [ -n "$2" ]; then |
| inst="$1-$2" |
| else |
| inst="$1" |
| fi |
| |
| if ! started "$inst" ; then |
| echo -n " ($inst)" |
| return 0 |
| else |
| PIDFILE=`pidfile $inst` |
| PID=`cat $PIDFILE 2>/dev/null` |
| kill -2 $PID 2>/dev/null |
| |
| |
| |
| if test -n "$PID" && kill -0 $PID 2>/dev/null; then |
| cnt=0 |
| while kill -0 $PID 2>/dev/null; do |
| cnt=`expr $cnt + 1` |
| if [ $cnt -gt 60 ]; then |
| |
| echo -n "Failed.. " |
| break |
| fi |
| sleep 2 |
| done |
| fi |
| rm -f `pidfile $inst` |
| rm -f `vtyfile $inst` |
| |
| if [ "$1" = "zebra" ]; then |
| echo -n "Stopping staticd since zebra is running" |
| stop staticd |
| fi |
| fi |
| } |
| |
| |
| convert_daemon_prios() |
| { |
| for name in $DAEMONS zebra vtysh_enable watchfrr_enable; do |
| |
| eval value=\${${name}:0:3} |
| |
| |
| if [ "$value" = "no" -o "$value" = "" ]; then value=0; fi |
| |
| |
| if [ "$value" = "yes" -o "$value" = "true" ]; then |
| value=1; |
| fi |
| |
| |
| |
| if [ "$name" != "zebra" -a "$value" -gt 0 ]; then value=`expr "$value" + 1`; fi |
| |
| |
| eval $name=$value |
| done |
| } |
| |
| |
| start_watchfrr() |
| { |
| local daemon_name |
| local daemon_prio |
| local found_one |
| local daemon_inst |
| |
| |
| if [ 0 -eq "$watchfrr_enable" ]; then |
| return |
| fi |
| |
| |
| if declare -p watchfrr_options | grep -q '^declare \-a'; then |
| |
| watchfrr_options="${watchfrr_options[@]}" |
| fi |
| |
| |
| found_one=0 |
| for daemon_name in $DAEMONS; do |
| eval daemon_prio=\$$daemon_name |
| if [ "$daemon_prio" -gt 0 ]; then |
| eval "daemon_inst=\${${daemon_name}_instances//,/ }" |
| if [ -n "$daemon_inst" ]; then |
| for inst in ${daemon_inst}; do |
| eval "inst_disable=\${${daemon_name}_${inst}}" |
| if [ -z ${inst_disable} ] || [ ${inst_disable} != 0 ]; then |
| if check_daemon $daemon_name $inst; then |
| watchfrr_options="$watchfrr_options ${daemon_name}-${inst}" |
| fi |
| fi |
| done |
| else |
| if check_daemon $daemon_name; then |
| watchfrr_options="$watchfrr_options $daemon_name" |
| fi |
| fi |
| found_one=1 |
| fi |
| done |
| |
| |
| if [ $found_one -eq 1 ]; then |
| start watchfrr |
| echo "." |
| fi |
| } |
| |
| |
| stop_watchfrr() |
| { |
| echo -n "Stopping Frr monitor daemon:" |
| stop watchfrr |
| echo "." |
| } |
| |
| |
| |
| stop_prio() |
| { |
| local wanted_prio |
| local daemon_prio |
| local daemon_list |
| local daemon_inst |
| local inst |
| |
| if [ -n "$2" ] && [[ "$2" =~ (.*)-(.*) ]]; then |
| daemon=${BASH_REMATCH[1]} |
| inst=${BASH_REMATCH[2]} |
| else |
| daemon="$2" |
| fi |
| |
| wanted_prio=$1 |
| daemon_list=${daemon:-$DAEMONS} |
| |
| echo -n "Stopping Frr daemons (prio:$wanted_prio):" |
| |
| for prio_i in `seq 10 -1 $wanted_prio`; do |
| for daemon_name in $daemon_list; do |
| eval daemon_prio=\${${daemon_name}:0:3} |
| daemon_inst="" |
| if [ $daemon_prio -eq $prio_i ]; then |
| eval "daemon_inst=\${${daemon_name}_instances//,/ }" |
| if [ -n "$daemon_inst" ]; then |
| for i in ${daemon_inst}; do |
| if [ -n "$inst" ] && [ "$i" == "$inst" ]; then |
| stop "$daemon_name" "$inst" |
| elif [ x"$inst" == x ]; then |
| stop "$daemon_name" "$i" |
| fi |
| done |
| else |
| stop "$daemon_name" |
| fi |
| fi |
| done |
| done |
| |
| echo "." |
| if [ -z "$inst" ]; then |
| |
| echo -n "Stopping other frr daemons" |
| if [ -n "$daemon" ]; then |
| eval "file_list_suffix="$V_PATH"/"$daemon*"" |
| else |
| eval "file_list_suffix="$V_PATH/*"" |
| fi |
| for pidfile in $file_list_suffix.pid; do |
| PID=`cat $pidfile 2>/dev/null` |
| ${SSD} --stop --quiet --oknodo --pidfile "$pidfile" |
| echo -n "." |
| rm -rf "$pidfile" |
| done |
| echo "." |
| |
| echo -n "Removing remaining .vty files" |
| for vtyfile in $file_list_suffix.vty; do |
| rm -rf "$vtyfile" |
| done |
| echo "." |
| fi |
| } |
| |
| |
| |
| start_prio() |
| { |
| local wanted_prio |
| local daemon_prio |
| local daemon_list |
| local daemon_name |
| local daemon_inst |
| local inst |
| |
| if [ -n "$2" ] && [[ "$2" =~ (.*)-(.*) ]]; then |
| daemon=${BASH_REMATCH[1]} |
| inst=${BASH_REMATCH[2]} |
| else |
| daemon="$2" |
| fi |
| |
| wanted_prio=$1 |
| daemon_list=${daemon:-$DAEMONS} |
| |
| for prio_i in `seq 1 $wanted_prio`; do |
| for daemon_name in $daemon_list; do |
| eval daemon_prio=\$${daemon_name} |
| daemon_inst="" |
| if [ $daemon_prio -eq $prio_i ]; then |
| eval "daemon_inst=\${${daemon_name}_instances//,/ }" |
| if [ -n "$daemon_inst" ]; then |
| if [ `echo "$daemon_inst" | wc -w` -gt ${MAX_INSTANCES} ]; then |
| echo "Max instances supported is ${MAX_INSTANCES}. Aborting" |
| exit 1 |
| fi |
| |
| |
| if started "$daemon_name"; then |
| PIDFILE=`pidfile $daemon_name` |
| ${SSD} \ |
| --stop --quiet --oknodo \ |
| --pidfile "$PIDFILE" \ |
| --exec "$D_PATH/$daemon_name" |
| |
| rm -f `pidfile $1` |
| rm -f `vtyfile $1` |
| fi |
| |
| for i in ${daemon_inst}; do |
| if [ -n "$inst" ] && [ "$i" == "$inst" ]; then |
| start "$daemon_name" "$inst" |
| elif [ x"$inst" == x ]; then |
| start "$daemon_name" "$i" |
| fi |
| done |
| else |
| |
| |
| eval "file_list_suffix="$V_PATH"/"$daemon_name-*"" |
| for pidfile in $file_list_suffix.pid; do |
| ${SSD} --stop --quiet --oknodo --pidfile "$pidfile" |
| rm -rf "$pidfile" |
| done |
| for vtyfile in $file_list_suffix.vty; do |
| rm -rf "$vtyfile" |
| done |
| |
| start "$daemon_name" |
| fi |
| fi |
| done |
| done |
| } |
| |
| check_status() |
| { |
| local daemon_name |
| local daemon_prio |
| local daemon_inst |
| local failed_status=0 |
| |
| if [ -n "$1" ] && [[ "$1" =~ (.*)-(.*) ]]; then |
| daemon=${BASH_REMATCH[1]} |
| inst=${BASH_REMATCH[2]} |
| else |
| daemon="$1" |
| fi |
| |
| daemon_list=${daemon:-$DAEMONS} |
| |
| |
| for daemon_name in $daemon_list; do |
| eval daemon_prio=\$$daemon_name |
| if [ "$daemon_prio" -gt 0 ]; then |
| eval "daemon_inst=\${${daemon_name}_instances//,/ }" |
| if [ -n "$daemon_inst" ]; then |
| for i in ${daemon_inst}; do |
| if [ -n "$inst" -a "$inst" = "$i" ]; then |
| started "$1" "log" || failed_status=$? |
| elif [ -z "$inst" ]; then |
| started "$daemon_name-$i" "log" || failed_status=$? |
| fi |
| done |
| else |
| started "$daemon_name" "log" || failed_status=$? |
| fi |
| fi |
| done |
| |
| |
| return $failed_status |
| } |
| |
| |
| |
| |
| |
| |
| [ ! -r "$C_PATH/daemons" ] && exit 0 |
| |
| |
| . "$C_PATH/daemons" |
| if [ -e "$C_PATH/daemons.conf" ]; then |
| . "$C_PATH/daemons.conf" |
| fi |
| |
| |
| [ -r /etc/default/frr ] && . /etc/default/frr |
| |
| if test -z "$frr_profile"; then |
| |
| if test -d /etc/cumulus; then |
| frr_profile=datacenter |
| |
| |
| elif test -n "$FRR_DEFAULT_PROFILE"; then |
| frr_profile="$FRR_DEFAULT_PROFILE" |
| fi |
| fi |
| test -n "$frr_profile" && frr_global_options="$frr_global_options -F $frr_profile" |
| |
| MAX_INSTANCES=${MAX_INSTANCES:=5} |
| |
| |
| convert_daemon_prios |
| |
| if [ ! -d $V_PATH ]; then |
| echo "Creating $V_PATH" |
| mkdir -p $V_PATH |
| chownfrr $V_PATH |
| chmod 755 /$V_PATH |
| fi |
| |
| if [ -n "$3" ] && [ "$3" != "all" ]; then |
| dmn="$2"-"$3" |
| elif [ -n "$2" ] && [ "$2" != "all" ]; then |
| dmn="$2" |
| fi |
| |
| case "$1" in |
| start) |
| |
| if [ -d /lib/modules/`uname -r` ] ; then |
| echo "Loading capability module if not yet done." |
| set +e; LC_ALL=C modprobe -a capability 2>&1 | egrep -v "(not found|Can't locate)"; set -e |
| fi |
| |
| |
| cd $C_PATH/ |
| if [ "$2" != "watchfrr" ]; then |
| start_prio 10 $dmn |
| fi |
| start_watchfrr |
| vtysh_b |
| ;; |
| |
| 1|2|3|4|5|6|7|8|9|10) |
| |
| stop_prio $1 |
| start_prio $1 |
| vtysh_b |
| ;; |
| |
| stop|0) |
| |
| stop_watchfrr |
| if [ "$dmn" != "watchfrr" ]; then |
| [ -n "${dmn}" ] && eval "${dmn/-/_}=0" |
| stop_prio 0 $dmn |
| fi |
| |
| if [ -n "$dmn" -a "$dmn" != "zebra" ]; then |
| [ -n "$dmn" ] && eval "${dmn/-/_}=0" |
| start_watchfrr |
| fi |
| ;; |
| |
| reload) |
| |
| if [ ! -x "$RELOAD_SCRIPT" ]; then |
| echo "Please install frr-pythontools package. Required for reload" |
| exit 0 |
| fi |
| |
| NEW_CONFIG_FILE="${2:-$C_PATH/frr.conf}" |
| [ ! -r $NEW_CONFIG_FILE ] && echo "Unable to read new configuration file $NEW_CONFIG_FILE" && exit 1 |
| echo "Applying only incremental changes to running configuration from frr.conf" |
| "$RELOAD_SCRIPT" --reload $C_PATH/frr.conf |
| exit $? |
| ;; |
| |
| status) |
| check_status $dmn |
| exit $? |
| ;; |
| |
| restart|force-reload) |
| $0 stop $dmn |
| sleep 1 |
| $0 start $dmn |
| ;; |
| |
| *) |
| echo "Usage: /etc/init.d/frr {start|stop|status|reload|restart|force-reload|<priority>} [daemon]" |
| echo " E.g. '/etc/init.d/frr 5' would start all daemons with a prio 1-5." |
| echo " reload applies only modifications from the running config to all daemons." |
| echo " reload neither restarts starts any daemon nor starts any new ones." |
| echo " Read /usr/share/doc/frr/README.Debian for details." |
| exit 1 |
| ;; |
| esac |
| |
| echo "Exiting from the script" |
| exit 0 |