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 pbrd ldpd nhrpd eigrpd babeld staticd sharpd bfdd fabricd"
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.
114 ulimit -n $MAX_FDS > /dev
/null
2> /dev
/null
115 if [ "$dmn" = "watchfrr" ]; then
117 # We may need to restart watchfrr if new daemons are added and/or
119 if started
"$dmn" ; then
122 # Echo only once. watchfrr is printed in the stop above
126 if [ -e /var
/run
/frr
/watchfrr.started
] ; then
127 rm /var
/run
/frr
/watchfrr.started
129 # redhat /etc/init.d/functions daemon() re-expands args :(
130 # eval "set - $watchfrr_options"
131 daemon
--pidfile=`pidfile $dmn` "$D_PATH/$dmn" -d "$watchfrr_options"
133 [ $RETVAL -ne 0 ] && break
136 if [ -e /var
/run
/frr
/watchfrr.started
] ; then
144 elif [ -n "$inst" ]; then
145 echo -n " $dmn-$inst"
146 if ! check_daemon
$dmn $inst ; then
147 echo -n " (binary does not exist)"
150 daemon
--pidfile=`pidfile $dmn-$inst` "$D_PATH/$dmn" -d `eval echo "$""$dmn""_options"` -n "$inst"
154 if ! check_daemon
$dmn; then
155 echo " (binary does not exist)"
158 daemon
--pidfile=`pidfile $dmn` "$D_PATH/$dmn" -d `eval echo "$""$dmn""_options"`
162 [ $RETVAL -eq 0 ] && touch /var
/lock
/subsys
/$dmn
166 # Stop the daemon given in the parameter, printing its name to the terminal.
177 if ! started
"$inst" ; then
182 PIDFILE
=`pidfile $inst`
183 PID
=`cat $PIDFILE 2>/dev/null`
184 killproc
-p "$PIDFILE" "$D_PATH/$1"
186 [ $RETVAL -eq 0 ] && rm -f $lockfile
187 rm -f `pidfile $inst`
188 rm -f `vtyfile $inst`
194 # Converts values from /etc/frr/daemons to all-numeric values.
195 convert_daemon_prios
()
197 for name
in $DAEMONS zebra vtysh_enable watchfrr_enable
; do
198 # First, assign the value set by the user to $value
199 eval value
=\
${${name}:0:3}
201 # Daemon not activated or entry missing?
202 if [ "$value" = "no" -o "$value" = "" ]; then value
=0; fi
204 # These strings parsed for backwards compatibility.
205 if [ "$value" = "yes" -o "$value" = "true" ]; then
209 # Zebra is threatened special. It must be between 0=off and the first
210 # user assigned value "1" so we increase all other enabled daemons' values.
211 if [ "$name" != "zebra" -a "$value" -gt 0 ]; then value
=`expr "$value" + 1`; fi
213 # If e.g. name is zebra then we set "zebra=yes".
218 # Starts watchfrr for all wanted daemons.
226 # Start the monitor daemon only if desired.
227 if [ 0 -eq "$watchfrr_enable" ]; then
231 # Check variable type
232 if declare -p watchfrr_options |
grep -q '^declare \-a'; then
234 watchfrr_options
="${watchfrr_options[@]}"
237 # Which daemons have been started?
239 for daemon_name
in $DAEMONS; do
240 eval daemon_prio
=\$
$daemon_name
241 if [ "$daemon_prio" -gt 0 ]; then
242 eval "daemon_inst=\${${daemon_name}_instances//,/ }"
243 if [ -n "$daemon_inst" ]; then
244 for inst
in ${daemon_inst}; do
245 eval "inst_disable=\${${daemon_name}_${inst}}"
246 if [ -z ${inst_disable} ] ||
[ ${inst_disable} != 0 ]; then
247 if check_daemon
$daemon_name $inst; then
248 watchfrr_options
="$watchfrr_options ${daemon_name}-${inst}"
253 if check_daemon
$daemon_name; then
254 watchfrr_options
="$watchfrr_options $daemon_name"
261 # Start if at least one daemon is activated.
262 if [ $found_one -eq 1 ]; then
263 echo "Starting FRRouting monitor daemon:"
271 echo "Stopping FRRouting monitor daemon:"
275 # Stops all daemons that have a lower level of priority than the given.
276 # (technically if daemon_prio >= wanted_prio)
285 if [ -n "$2" ] && [[ "$2" =~
(.
*)-(.
*) ]]; then
286 daemon
=${BASH_REMATCH[1]}
287 inst
=${BASH_REMATCH[2]}
293 daemon_list
=${daemon:-$DAEMONS}
295 echo "Stopping FRRouting daemons (prio:$wanted_prio):"
297 for prio_i
in `seq 10 -1 $wanted_prio`; do
298 for daemon_name
in $daemon_list; do
299 eval daemon_prio
=\
${${daemon_name}:0:3}
301 if [ $daemon_prio -eq $prio_i ]; then
302 eval "daemon_inst=\${${daemon_name}_instances//,/ }"
303 if [ -n "$daemon_inst" ]; then
304 for i
in ${daemon_inst}; do
305 if [ -n "$inst" ] && [ "$i" == "$inst" ]; then
306 stop
"$daemon_name" "$inst"
307 elif [ x
"$inst" == x
]; then
308 stop
"$daemon_name" "$i"
318 if [ -z "$inst" ]; then
319 # Now stop other daemons that're prowling, coz the daemons file changed
320 echo "Stopping other FRRouting daemons"
321 if [ -n "$daemon" ]; then
322 eval "file_list_suffix="$V_PATH"/"$daemon*""
324 eval "file_list_suffix="$V_PATH/*""
326 for pidfile
in $file_list_suffix.pid
; do
327 if [ -f "$pidfile" ]; then
328 filename
=${pidfile##*/}
329 daemon
=${filename%.*}
331 killproc
-p "$pidfile" "$daemon"
333 [ $RETVAL -eq 0 ] && rm -f $lockfile
338 echo -n "Removing remaining .vty files"
339 for vtyfile
in $file_list_suffix.vty
; do
346 # Starts all daemons that have a higher level of priority than the given.
347 # (technically if daemon_prio <= wanted_prio)
357 if [ -n "$2" ] && [[ "$2" =~
(.
*)-(.
*) ]]; then
358 daemon
=${BASH_REMATCH[1]}
359 inst
=${BASH_REMATCH[2]}
365 daemon_list
=${daemon:-$DAEMONS}
367 echo "Starting FRRouting daemons (prio:$wanted_prio):"
369 for prio_i
in `seq 1 $wanted_prio`; do
370 for daemon_name
in $daemon_list; do
371 eval daemon_prio
=\$
${daemon_name}
373 if [ $daemon_prio -eq $prio_i ]; then
374 eval "daemon_inst=\${${daemon_name}_instances//,/ }"
375 if [ -n "$daemon_inst" ]; then
376 if [ `echo "$daemon_inst" | wc -w` -gt ${MAX_INSTANCES} ]; then
377 echo "Max instances supported is ${MAX_INSTANCES}. Aborting"
380 # Check if we're starting again by switching from single instance
382 if started
"$daemon_name"; then
383 PIDFILE
=`pidfile $daemon_name`
384 killproc
-p "$PIDFILE" "$daemon_name"
389 for i
in ${daemon_inst}; do
390 if [ -n "$inst" ] && [ "$i" == "$inst" ]; then
391 start
"$daemon_name" "$inst"
392 elif [ x
"$inst" == x
]; then
393 start
"$daemon_name" "$i"
397 # Check if we're starting again by switching from
398 # single instance to MI version
399 eval "file_list_suffix="$V_PATH"/"$daemon_name-*""
400 for pidfile
in $file_list_suffix.pid
; do
401 if [ -f "$pidfile" ]; then
402 killproc
-p "$pidfile" "$daemon_name"
406 for vtyfile
in $file_list_suffix.vty
; do
422 local failed_status
=0
424 if [ -n "$1" ] && [[ "$1" =~
(.
*)-(.
*) ]]; then
425 daemon
=${BASH_REMATCH[1]}
426 inst
=${BASH_REMATCH[2]}
431 daemon_list
=${daemon:-$DAEMONS}
433 # Which daemons have been started?
434 for daemon_name
in $daemon_list; do
435 eval daemon_prio
=\$
$daemon_name
436 if [ "$daemon_prio" -gt 0 ]; then
437 eval "daemon_inst=\${${daemon_name}_instances//,/ }"
438 if [ -n "$daemon_inst" ]; then
439 for i
in ${daemon_inst}; do
440 if [ -n "$inst" -a "$inst" = "$i" ]; then
441 started
"$1" "log" || failed_status
=$?
442 elif [ -z "$inst" ]; then
443 started
"$daemon_name-$i" "log" || failed_status
=$?
447 started
"$daemon_name" "log" || failed_status
=$?
452 # All daemons that need to have been started are up and running
453 return $failed_status
456 #########################################################
458 #########################################################
460 # Config broken but script must exit silently.
461 [ ! -r "$C_PATH/daemons" ] && exit 0
466 # Read configuration variable file if it is present
467 [ -r /etc
/sysconfig
/frr
] && .
/etc
/sysconfig
/frr
469 MAX_INSTANCES
=${MAX_INSTANCES:=5}
471 # Set priority of un-startable daemons to 'no' and substitute 'yes' to '0'
474 if [ ! -d $V_PATH ]; then
475 echo "Creating $V_PATH"
477 chown frr
:frr
$V_PATH
481 if [ -n "$3" ] && [ "$3" != "all" ]; then
483 elif [ -n "$2" ] && [ "$2" != "all" ]; then
489 # Try to load this necessary (at least for 2.6) module.
490 if [ -d /lib
/modules
/`uname -r` ] ; then
491 echo "Loading capability module if not yet done."
492 LC_ALL
=C modprobe
-a capability
2>&1 |
egrep -v "(not found|Can't locate)"
497 if [ "$2" != "watchfrr" ]; then
504 1|
2|
3|
4|
5|
6|
7|
8|
9|
10)
505 # Stop/start daemons for the appropriate priority level
512 # Stop all daemons at level '0' or 'stop'
514 if [ "$dmn" != "watchfrr" ]; then
515 [ -n "${dmn}" ] && eval "${dmn/-/_}=0"
519 if [ -z "$dmn" -o "$dmn" = "zebra" ]; then
520 echo "Removing all routes made by zebra."
521 ip route flush proto zebra
522 # At least in CentOS/RHEL 6, iproute2 doesn't know
523 # about the new protocol names, so we have to flush them
524 # by number (it also doesn't support rt_protos.d
525 ip route flush proto
186
526 ip route flush proto
187
527 ip route flush proto
188
528 ip route flush proto
189
529 ip route flush proto
190
530 ip route flush proto
191
531 ip route flush proto
192
532 ip route flush proto
193
533 ip route flush proto
194
535 [ -n "$dmn" ] && eval "${dmn/-/_}=0"
541 # Just apply the commands that have changed, no restart necessary
542 if [ ! -x "$RELOAD_SCRIPT" ]; then
543 echo "frr-reload - reload not supported. Use restart or install frr-pythontools package"
546 NEW_CONFIG_FILE
="${2:-$C_PATH/frr.conf}"
547 if [ ! -r $NEW_CONFIG_FILE ]; then
548 echo "Unable to read configuration file $NEW_CONFIG_FILE. Only supporting integrated config"
551 echo "Applying only incremental changes to running configuration from frr.conf"
552 "$RELOAD_SCRIPT" --reload /etc
/frr
/frr.conf
561 restart|force-reload
)
568 echo "Usage: /etc/init.d/frr {start|stop|status|reload|restart|force-reload|<priority>} [daemon]"
569 echo " E.g. '/etc/init.d/frr 5' would start all daemons with a prio 1-5."
570 echo " reload applies only modifications from the running config to all daemons."
571 echo " reload neither restarts starts any daemon nor starts any new ones."
572 echo " Read /usr/share/doc/frr/README.Debian for details."