5 # Start/Stop the FRR Routing daemons
6 # <any general comments about this init script>
8 # chkconfig: 2345 15 85
10 # description: FRRouting (FRR) is a routing suite for IP routing protocols
11 # like BGP, OSPF, RIP and others. This script contols the main
12 # daemon "frr" as well as the individual protocol daemons.
16 # Required-Start: $local_fs $network $syslog
17 # Required-Stop: $local_fs $syslog
18 # Should-Start: $syslog
19 # Should-Stop: $network $syslog
20 # Default-Start: 2 3 4 5
22 # Short-Description: Start/Stop the FRR Routing daemons
23 # Description: FRRouting (FRR) is a routing suite for IP routing protocols
24 # like BGP, OSPF, RIP and others. This script contols the main
25 # daemon "frr" as well as the individual protocol daemons.
28 PATH
=/bin
:/usr
/bin
:/sbin
:/usr
/sbin
33 # Local Daemon selection may be done by using /etc/frr/daemons.
34 # See /usr/share/doc/frr/README.Debian.gz for further information.
35 # Keep zebra first and do not list watchfrr!
36 DAEMONS
="zebra bgpd ripd ripngd ospfd ospf6d isisd pimd ldpd nhrpd eigrpd babeld"
38 RELOAD_SCRIPT
=/usr
/lib
/frr
/frr-reload.py
40 .
/etc
/init.d
/functions
42 # Print the name of the pidfile.
48 # Print the name of the vtysh.
54 # Check if daemon is started by using the pidfile.
57 [ ! -e `pidfile $1` ] && return 3
58 if [ -n "$2" ] && [ "$2" == "log" ]; then
59 status
-p `pidfile $1` $1 && return 0 ||
return $?
61 kill -0 `cat \`pidfile
$1\
`` 2> /dev
/null ||
return 1
66 # Loads the config via vtysh -b if configured to do so.
69 # Rember, that all variables have been incremented by 1 in convert_daemon_prios()
70 if [ "$vtysh_enable" = 2 -a -f $C_PATH/frr.conf
]; then
75 # Check if the daemon is activated and if its executable and config files
78 # returns: 0=ok, 1=error
81 # If the integrated config file is used the others are not checked.
82 if [ -r "$C_PATH/frr.conf" ]; then
86 # vtysh_enable has no config file nor binary so skip check.
87 # (Not sure why vtysh_enable is in this list but does not hurt)
88 if [ $1 != "watchfrr" -a $1 != "vtysh_enable" ]; then
89 # check for daemon binary
90 if [ ! -x "$D_PATH/$1" ]; then return 1; fi
92 # check for config file
94 if [ ! -r "$C_PATH/$1-$2.conf" ]; then
95 touch "$C_PATH/$1-$2.conf"
96 chown frr
:frr
"$C_PATH/$1-$2.conf"
98 elif [ ! -r "$C_PATH/$1.conf" ]; then
99 touch "$C_PATH/$1.conf"
100 chown frr
:frr
"$C_PATH/$1.conf"
106 # Starts the server if it's not already running according to the pid file.
107 # The Frr daemons creates the pidfile when starting.
110 ulimit -n $MAX_FDS > /dev
/null
2> /dev
/null
111 if [ "$1" = "watchfrr" ]; then
113 # We may need to restart watchfrr if new daemons are added and/or
115 if started
"$1" ; then
118 # Echo only once. watchfrr is printed in the stop above
122 if [ -e /var
/run
/frr
/watchfrr.started
] ; then
123 rm /var
/run
/frr
/watchfrr.started
125 daemon
--pidfile=`pidfile $1` "$D_PATH/$1" -d "${watchfrr_options[@]}"
127 [ $RETVAL -ne 0 ] && break
130 if [ -e /var
/run
/frr
/watchfrr.started
] ; then
138 elif [ -n "$2" ]; then
140 if ! check_daemon
$1 $2 ; then
141 echo -n " (binary does not exist)"
144 daemon
--pidfile=`pidfile $1-$2` "$D_PATH/$1" -d `eval echo "$""$1""_options"` -n "$2"
148 if ! check_daemon
$1; then
149 echo " (binary does not exist)"
152 daemon
--pidfile=`pidfile $1` "$D_PATH/$1" -d `eval echo "$""$1""_options"`
156 [ $RETVAL -eq 0 ] && touch /var
/lock
/subsys
/$1
160 # Stop the daemon given in the parameter, printing its name to the terminal.
171 if ! started
"$inst" ; then
176 PIDFILE
=`pidfile $inst`
177 PID
=`cat $PIDFILE 2>/dev/null`
178 killproc
-p "$PIDFILE" "$D_PATH/$1"
180 [ $RETVAL -eq 0 ] && rm -f $lockfile
181 rm -f `pidfile $inst`
182 rm -f `vtyfile $inst`
188 # Converts values from /etc/frr/daemons to all-numeric values.
189 convert_daemon_prios
()
191 for name
in $DAEMONS zebra vtysh_enable watchfrr_enable
; do
192 # First, assign the value set by the user to $value
193 eval value
=\
${${name}:0:3}
195 # Daemon not activated or entry missing?
196 if [ "$value" = "no" -o "$value" = "" ]; then value
=0; fi
198 # These strings parsed for backwards compatibility.
199 if [ "$value" = "yes" -o "$value" = "true" ]; then
203 # Zebra is threatened special. It must be between 0=off and the first
204 # user assigned value "1" so we increase all other enabled daemons' values.
205 if [ "$name" != "zebra" -a "$value" -gt 0 ]; then value
=`expr "$value" + 1`; fi
207 # If e.g. name is zebra then we set "zebra=yes".
212 # Starts watchfrr for all wanted daemons.
220 # Start the monitor daemon only if desired.
221 if [ 0 -eq "$watchfrr_enable" ]; then
225 # Check variable type
226 if ! declare -p watchfrr_options |
grep -q '^declare \-a'; then
228 echo "ERROR: The variable watchfrr_options from /etc/frr/daemons must be a BASH array!"
229 echo "ERROR: Please convert config file and restart!"
233 # Which daemons have been started?
235 for daemon_name
in $DAEMONS; do
236 eval daemon_prio
=\$
$daemon_name
237 if [ "$daemon_prio" -gt 0 ]; then
238 eval "daemon_inst=\${${daemon_name}_instances//,/ }"
239 if [ -n "$daemon_inst" ]; then
240 for inst
in ${daemon_inst}; do
241 eval "inst_disable=\${${daemon_name}_${inst}}"
242 if [ -z ${inst_disable} ] ||
[ ${inst_disable} != 0 ]; then
243 if check_daemon
$daemon_name $inst; then
244 watchfrr_options
+=("${daemon_name}-${inst}")
249 if check_daemon
$daemon_name; then
250 watchfrr_options
+=($daemon_name)
257 # Start if at least one daemon is activated.
258 if [ $found_one -eq 1 ]; then
259 echo "Starting FRRouting monitor daemon:"
267 echo "Stopping FRRouting monitor daemon:"
271 # Stops all daemons that have a lower level of priority than the given.
272 # (technically if daemon_prio >= wanted_prio)
281 if [ -n "$2" ] && [[ "$2" =~
(.
*)-(.
*) ]]; then
282 daemon
=${BASH_REMATCH[1]}
283 inst
=${BASH_REMATCH[2]}
289 daemon_list
=${daemon:-$DAEMONS}
291 echo "Stopping FRRouting daemons (prio:$wanted_prio):"
293 for prio_i
in `seq 10 -1 $wanted_prio`; do
294 for daemon_name
in $daemon_list; do
295 eval daemon_prio
=\
${${daemon_name}:0:3}
297 if [ $daemon_prio -eq $prio_i ]; then
298 eval "daemon_inst=\${${daemon_name}_instances//,/ }"
299 if [ -n "$daemon_inst" ]; then
300 for i
in ${daemon_inst}; do
301 if [ -n "$inst" ] && [ "$i" == "$inst" ]; then
302 stop
"$daemon_name" "$inst"
303 elif [ x
"$inst" == x
]; then
304 stop
"$daemon_name" "$i"
314 if [ -z "$inst" ]; then
315 # Now stop other daemons that're prowling, coz the daemons file changed
316 echo "Stopping other FRRouting daemons"
317 if [ -n "$daemon" ]; then
318 eval "file_list_suffix="$V_PATH"/"$daemon*""
320 eval "file_list_suffix="$V_PATH/*""
322 for pidfile
in $file_list_suffix.pid
; do
323 if [ -f "$pidfile" ]; then
324 filename
=${pidfile##*/}
325 daemon
=${filename%.*}
327 killproc
-p "$pidfile" "$daemon"
329 [ $RETVAL -eq 0 ] && rm -f $lockfile
334 echo -n "Removing remaining .vty files"
335 for vtyfile
in $file_list_suffix.vty
; do
342 # Starts all daemons that have a higher level of priority than the given.
343 # (technically if daemon_prio <= wanted_prio)
353 if [ -n "$2" ] && [[ "$2" =~
(.
*)-(.
*) ]]; then
354 daemon
=${BASH_REMATCH[1]}
355 inst
=${BASH_REMATCH[2]}
361 daemon_list
=${daemon:-$DAEMONS}
363 echo "Starting FRRouting daemons (prio:$wanted_prio):"
365 for prio_i
in `seq 1 $wanted_prio`; do
366 for daemon_name
in $daemon_list; do
367 eval daemon_prio
=\$
${daemon_name}
369 if [ $daemon_prio -eq $prio_i ]; then
370 eval "daemon_inst=\${${daemon_name}_instances//,/ }"
371 if [ -n "$daemon_inst" ]; then
372 if [ `echo "$daemon_inst" | wc -w` -gt ${MAX_INSTANCES} ]; then
373 echo "Max instances supported is ${MAX_INSTANCES}. Aborting"
376 # Check if we're starting again by switching from single instance
378 if started
"$daemon_name"; then
379 PIDFILE
=`pidfile $daemon_name`
380 killproc
-p "$PIDFILE" "$daemon_name"
385 for i
in ${daemon_inst}; do
386 if [ -n "$inst" ] && [ "$i" == "$inst" ]; then
387 start
"$daemon_name" "$inst"
388 elif [ x
"$inst" == x
]; then
389 start
"$daemon_name" "$i"
393 # Check if we're starting again by switching from
394 # single instance to MI version
395 eval "file_list_suffix="$V_PATH"/"$daemon_name-*""
396 for pidfile
in $file_list_suffix.pid
; do
397 if [ -f "$pidfile" ]; then
398 killproc
-p "$pidfile" "$daemon_name"
402 for vtyfile
in $file_list_suffix.vty
; do
418 local failed_status
=0
420 if [ -n "$1" ] && [[ "$1" =~
(.
*)-(.
*) ]]; then
421 daemon
=${BASH_REMATCH[1]}
422 inst
=${BASH_REMATCH[2]}
427 daemon_list
=${daemon:-$DAEMONS}
429 # Which daemons have been started?
430 for daemon_name
in $daemon_list; do
431 eval daemon_prio
=\$
$daemon_name
432 if [ "$daemon_prio" -gt 0 ]; then
433 eval "daemon_inst=\${${daemon_name}_instances//,/ }"
434 if [ -n "$daemon_inst" ]; then
435 for i
in ${daemon_inst}; do
436 if [ -n "$inst" -a "$inst" = "$i" ]; then
437 started
"$1" "log" || failed_status
=$?
438 elif [ -z "$inst" ]; then
439 started
"$daemon_name-$i" "log" || failed_status
=$?
443 started
"$daemon_name" "log" || failed_status
=$?
448 # All daemons that need to have been started are up and running
449 return $failed_status
452 #########################################################
454 #########################################################
456 # Config broken but script must exit silently.
457 [ ! -r "$C_PATH/daemons" ] && exit 0
462 # Read configuration variable file if it is present
463 [ -r /etc
/sysconfig
/frr
] && .
/etc
/sysconfig
/frr
465 MAX_INSTANCES
=${MAX_INSTANCES:=5}
467 # Set priority of un-startable daemons to 'no' and substitute 'yes' to '0'
470 if [ ! -d $V_PATH ]; then
471 echo "Creating $V_PATH"
473 chown frr
:frr
$V_PATH
477 if [ -n "$3" ] && [ "$3" != "all" ]; then
479 elif [ -n "$2" ] && [ "$2" != "all" ]; then
485 # Try to load this necessary (at least for 2.6) module.
486 if [ -d /lib
/modules
/`uname -r` ] ; then
487 echo "Loading capability module if not yet done."
488 LC_ALL
=C modprobe
-a capability
2>&1 |
egrep -v "(not found|Can't locate)"
493 if [ "$2" != "watchfrr" ]; then
500 1|
2|
3|
4|
5|
6|
7|
8|
9|
10)
501 # Stop/start daemons for the appropriate priority level
508 # Stop all daemons at level '0' or 'stop'
510 if [ "$dmn" != "watchfrr" ]; then
511 [ -n "${dmn}" ] && eval "${dmn/-/_}=0"
515 if [ -z "$dmn" -o "$dmn" = "zebra" ]; then
516 echo "Removing all routes made by zebra."
517 ip route flush proto zebra
519 [ -n "$dmn" ] && eval "${dmn/-/_}=0"
525 # Just apply the commands that have changed, no restart necessary
526 if [ ! -x "$RELOAD_SCRIPT" ]; then
527 echo "frr-reload - reload not supported. Use restart or install frr-pythontools package"
530 NEW_CONFIG_FILE
="${2:-$C_PATH/frr.conf}"
531 if [ ! -r $NEW_CONFIG_FILE ]; then
532 echo "Unable to read configuration file $NEW_CONFIG_FILE. Only supporting integrated config"
535 echo "Applying only incremental changes to running configuration from frr.conf"
536 "$RELOAD_SCRIPT" --reload /etc
/frr
/frr.conf
545 restart|force-reload
)
552 echo "Usage: /etc/init.d/frr {start|stop|status|reload|restart|force-reload|<priority>} [daemon]"
553 echo " E.g. '/etc/init.d/frr 5' would start all daemons with a prio 1-5."
554 echo " reload applies only modifications from the running config to all daemons."
555 echo " reload neither restarts starts any daemon nor starts any new ones."
556 echo " Read /usr/share/doc/frr/README.Debian for details."