diff --git a/configure.ac b/configure.ac index 09d57ab0f2..f7328988b2 100755 --- a/configure.ac +++ b/configure.ac @@ -2180,6 +2180,9 @@ AC_CONFIG_FILES([ AC_CONFIG_FILES([vtysh/extract.pl], [chmod +x vtysh/extract.pl]) AC_CONFIG_FILES([tools/frr], [chmod +x tools/frr]) +AC_CONFIG_FILES([tools/watchfrr.sh], [chmod +x tools/watchfrr.sh]) +AC_CONFIG_FILES([tools/frrinit.sh], [chmod +x tools/frrinit.sh]) +AC_CONFIG_FILES([tools/frrcommon.sh]) AC_CONFIG_COMMANDS([lib/route_types.h], [ dst="${ac_abs_top_builddir}/lib/route_types.h" diff --git a/debianpkg/backports/ubuntu12.04/debian/control b/debianpkg/backports/ubuntu12.04/debian/control deleted file mode 100644 index 9bae348840..0000000000 --- a/debianpkg/backports/ubuntu12.04/debian/control +++ /dev/null @@ -1,56 +0,0 @@ -Source: frr -Section: net -Priority: optional -Maintainer: Nobody -Uploaders: Nobody -XSBC-Original-Maintainer: -Build-Depends: debhelper (>= 7.0.50~), libncurses5-dev, libreadline-dev, texlive-latex-base, texlive-generic-recommended, libpam0g-dev | libpam-dev, libcap-dev, texinfo (>= 4.7), imagemagick, ghostscript, groff, autotools-dev, libpcre3-dev, gawk, chrpath, libsnmp-dev, git, dh-autoreconf, libjson0, libjson0-dev, pkg-config, python (>= 2.7), python-ipaddr -Standards-Version: 3.9.6 -Homepage: http://www.frrouting.org/ -XS-Testsuite: autopkgtest - -Package: frr -Architecture: any -Depends: ${shlibs:Depends}, logrotate (>= 3.2-11), ${misc:Depends} -Pre-Depends: adduser -Conflicts: zebra, zebra-pj, quagga -Replaces: zebra, zebra-pj -Suggests: snmpd -Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon forked from Quagga - FRR is free software which manages TCP/IP based routing protocols. - It supports BGP4, BGP4+, OSPFv2, OSPFv3, IS-IS, RIPv1, RIPv2, RIPng, - PIM and LDP as well as the IPv6 versions of these. - . - FRR is a fork of Quagga with an open community model. The main git - lives on https://github.com/frrouting/frr.git - -Package: frr-dbg -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, frr (= ${binary:Version}) -Priority: extra -Section: debug -Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon (debug symbols) - This package provides debugging symbols for all binary packages built - from frr source package. It's highly recommended to have this package - installed before reporting any FRR crashes to either FRR developers or - Debian package maintainers. - -Package: frr-doc -Section: net -Architecture: all -Depends: ${misc:Depends} -Suggests: frr -Description: documentation files for FRR - This package includes info files for frr, a free software which manages - TCP/IP based routing protocols. It supports BGP4, BGP4+, OSPFv2, OSPFv3, - IS-IS, RIPv1, RIPv2, RIPng, PIM and LDP as well as the IPv6 versions of these. - -Package: frr-pythontools -Section: net -Architecture: all -Depends: ${misc:Depends}, frr (= ${binary:Version}), python (>= 2.7), python-ipaddr -Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon (Python Tools) - This package includes info files for frr, a free software which manages - TCP/IP based routing protocols. It supports BGP4, BGP4+, OSPFv2, OSPFv3, - IS-IS, RIPv1, RIPv2, RIPng, PIM and LDP as well as the IPv6 versions of these. - diff --git a/debianpkg/backports/ubuntu12.04/debian/frr.install b/debianpkg/backports/ubuntu12.04/debian/frr.install deleted file mode 120000 index 83ecca5958..0000000000 --- a/debianpkg/backports/ubuntu12.04/debian/frr.install +++ /dev/null @@ -1 +0,0 @@ -../../ubuntu14.04/debian/frr.install \ No newline at end of file diff --git a/debianpkg/backports/ubuntu12.04/debian/frr.postinst b/debianpkg/backports/ubuntu12.04/debian/frr.postinst deleted file mode 120000 index eb98053c7b..0000000000 --- a/debianpkg/backports/ubuntu12.04/debian/frr.postinst +++ /dev/null @@ -1 +0,0 @@ -../../ubuntu14.04/debian/frr.postinst \ No newline at end of file diff --git a/debianpkg/backports/ubuntu12.04/debian/frr.postrm b/debianpkg/backports/ubuntu12.04/debian/frr.postrm deleted file mode 120000 index 4f4380872f..0000000000 --- a/debianpkg/backports/ubuntu12.04/debian/frr.postrm +++ /dev/null @@ -1 +0,0 @@ -../../ubuntu14.04/debian/frr.postrm \ No newline at end of file diff --git a/debianpkg/backports/ubuntu12.04/debian/rules b/debianpkg/backports/ubuntu12.04/debian/rules deleted file mode 100755 index 7495db89cb..0000000000 --- a/debianpkg/backports/ubuntu12.04/debian/rules +++ /dev/null @@ -1,162 +0,0 @@ -#!/usr/bin/make -f - -# FRRouting Configuration options -###################################### -# -# WANT_xxxx --> Set to 1 for enable, 0 for disable -# The following are the defaults. They can be overridden by setting a -# env variable to a different value - -WANT_LDP ?= 1 -WANT_PIM ?= 1 -WANT_OSPFAPI ?= 1 -WANT_BGP_VNC ?= 1 -WANT_CUMULUS_MODE ?= 0 -WANT_MULTIPATH ?= 1 -WANT_SNMP ?= 0 - -# NOTES: -# -# If multipath is enabled (WANT_MULTIPATH=1), then set number of multipaths here -# Please be aware that 0 is NOT disabled, but treated as unlimited - -MULTIPATH ?= 256 - -# Set the following to the value required (or leave alone for the default below) -# WANT_FRR_USER is used for the username and groupname of the FRR user account - -WANT_FRR_USER ?= frr -WANT_FRR_VTY_GROUP ?= frrvty - -# Don't build PDF docs by default -GENERATE_PDF ?= 0 - -# -#################################### - -export DH_VERBOSE=1 -export DEB_BUILD_MAINT_OPTIONS = hardening=+all -export DH_OPTIONS=-v - -ifeq ($(WANT_SNMP), 1) - USE_SNMP=--enable-snmp - $(warning "DEBIAN: SNMP enabled, sorry for your inconvenience") -else - USE_SNMP=--disable-snmp - $(warning "DEBIAN: SNMP disabled, see README.Debian") -endif - -ifeq ($(WANT_LDP), 1) - USE_LDP=--enable-ldpd -else - USE_LDP=--disable-ldpd -endif - -ifeq ($(WANT_PIM), 1) - USE_PIM=--enable-pimd -else - USE_PIM=--disable-pimd -endif - -ifeq ($(WANT_OSPFAPI), 1) - USE_OSPFAPI=--enable-ospfapi=yes -else - USE_OSPFAPI=--enable-ospfapi=no -endif - -ifeq ($(WANT_BGP_VNC), 1) - USE_BGP_VNC=--enable-bgp-vnc=yes -else - USE_BGP_VNC=--enable-bgp-vnc=no -endif - -USE_FRR_USER=--enable-user=$(WANT_FRR_USER) -USE_FRR_GROUP=--enable-group=$(WANT_FRR_USER) -USE_FRR_VTY_GROUP=--enable-vty-group=$(WANT_FRR_VTY_GROUP) - -ifeq ($(WANT_MULTIPATH), 1) - USE_MULTIPATH=--enable-multipath=$(MULTIPATH) -else - USE_MULTIPATH=--disable-multipath -endif - -ifeq ($(WANT_CUMULUS_MODE), 1) - USE_CUMULUS=--enable-cumulus=yes -else - USE_CUMULUS=--enable-cumulus=no -endif - -ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) - DEBIAN_JOBS := $(subst parallel=,,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) -endif - -ifdef DEBIAN_JOBS -MAKEFLAGS += -j$(DEBIAN_JOBS) -endif - -%: - dh $@ --with=autoreconf --parallel --dbg-package=frr-dbg --list-missing - -override_dh_auto_configure: - # Frr needs /proc to check some BSD vs Linux specific stuff. - # Else it fails with an obscure error message pointing out that - # IPCTL_FORWARDING is an undefined symbol which is not very helpful. - @if ! [ -d /proc/1 ]; then \ - echo "./configure needs a mounted /proc"; \ - exit 1; \ - fi - - if ! [ -e config.status ]; then \ - dh_auto_configure -- \ - --enable-exampledir=/usr/share/doc/frr/examples/ \ - --localstatedir=/var/run/frr \ - --sbindir=/usr/lib/frr \ - --sysconfdir=/etc/frr \ - $(USE_SNMP) \ - $(USE_OSPFAPI) \ - $(USE_MULTIPATH) \ - $(USE_LDP) \ - --enable-fpm \ - $(USE_FRR_USER) $(USE_FRR_GROUP) \ - $(USE_FRR_VTY_GROUP) \ - --enable-configfile-mask=0640 \ - --enable-logfile-mask=0640 \ - --with-libpam \ - --enable-systemd=no \ - --enable-poll=yes \ - $(USE_CUMULUS) \ - $(USE_PIM) \ - --disable-bfdd \ - --enable-dependency-tracking \ - $(USE_BGP_VNC) \ - $(shell dpkg-buildflags --export=configure); \ - fi - -override_dh_auto_build: -ifeq ($(GENERATE_PDF), 1) - dh_auto_build -- -C doc pdf -endif - rm -vf doc/user/_build/texinfo/frr.info - dh_auto_build -- -C doc info - -override_dh_auto_test: - -override_dh_auto_install: - dh_auto_install - - # installed in frr-pythontools - rm debian/tmp/usr/lib/frr/frr-reload.py - - # cleaning up the info dir - rm -f debian/tmp/usr/share/info/dir* - - # install config files - mkdir -p debian/tmp/etc/frr/ - perl -pi -e 's#^!log file #!log file /var/log/frr/#' debian/tmp/usr/share/doc/frr/examples/*sample* - - # leftover from previously shipping SMUX client OID MIB - mkdir -p debian/tmp/usr/share/snmp/mibs - - # cleaning .la files - sed -i "/dependency_libs/ s/'.*'/''/" debian/tmp/usr/lib/*.la - sed -i "/dependency_libs/ s/'.*'/''/" debian/tmp/usr/lib/frr/modules/*.la diff --git a/debianpkg/backports/ubuntu12.04/debian/source/format b/debianpkg/backports/ubuntu12.04/debian/source/format deleted file mode 100644 index 163aaf8d82..0000000000 --- a/debianpkg/backports/ubuntu12.04/debian/source/format +++ /dev/null @@ -1 +0,0 @@ -3.0 (quilt) diff --git a/debianpkg/backports/ubuntu12.04/exclude b/debianpkg/backports/ubuntu12.04/exclude deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/debianpkg/backports/ubuntu12.04/versionext b/debianpkg/backports/ubuntu12.04/versionext deleted file mode 100644 index 159e2e4160..0000000000 --- a/debianpkg/backports/ubuntu12.04/versionext +++ /dev/null @@ -1 +0,0 @@ --1~ubuntu12.04+1 diff --git a/debianpkg/backports/ubuntu14.04/debian/frr.install b/debianpkg/backports/ubuntu14.04/debian/frr.install index 199d264f1a..7fb81c44a0 100644 --- a/debianpkg/backports/ubuntu14.04/debian/frr.install +++ b/debianpkg/backports/ubuntu14.04/debian/frr.install @@ -3,7 +3,6 @@ usr/bin/vtysh usr/bin/mtracebis usr/include/frr/ usr/lib/ -tools/frr etc/init.d/ usr/share/doc/frr/ usr/share/snmp/mibs/ usr/share/yang/ diff --git a/debianpkg/backports/ubuntu14.04/debian/frr.postinst b/debianpkg/backports/ubuntu14.04/debian/frr.postinst deleted file mode 100644 index 5a14e510cd..0000000000 --- a/debianpkg/backports/ubuntu14.04/debian/frr.postinst +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash -e - -###################### -PASSWDFILE=/etc/passwd -GROUPFILE=/etc/group - -frruid=`egrep "^frr:" $PASSWDFILE | awk -F ":" '{ print $3 }'` -frrgid=`egrep "^frr:" $GROUPFILE | awk -F ":" '{ print $3 }'` -frrvtygid=`egrep "^frrvty:" $GROUPFILE | awk -F ":" '{ print $3 }'` - -[ -n ${frruid} ] || (echo "No uid for frr in ${PASSWDFILE}" && /bin/false) -[ -n ${frrgid} ] || (echo "No gid for frr in ${GROUPFILE}" && /bin/false) -[ -n ${frrVTYgid} ] || (echo "No gid for frrvty in ${GROUPFILE}" && /bin/false) - -chown -R ${frruid}:${frrgid} /etc/frr -touch /etc/frr/vtysh.conf -chgrp ${frrvtygid} /etc/frr/vtysh* -chmod 644 /etc/frr/* - -ENVIRONMENTFILE=/etc/environment -if ! egrep --quiet '^VTYSH_PAGER=' ${ENVIRONMENTFILE}; then - echo "VTYSH_PAGER=/bin/cat" >> ${ENVIRONMENTFILE} -fi -################################################## - -if [ -n "$DEBIAN_SCRIPT_DEBUG" ]; then set -v -x; DEBIAN_SCRIPT_TRACE=1; fi -${DEBIAN_SCRIPT_TRACE:+ echo "#42#DEBUG# RUNNING $0 $*"} - -# This is most likely due to the answer "no" to the "really stop the server" -# question in the prerm script. -if [ "$1" = "abort-upgrade" ]; then - exit 0 -fi - -update-rc.d frr defaults > /dev/null - -#DEBHELPER# - diff --git a/debianpkg/backports/ubuntu14.04/debian/frr.postrm b/debianpkg/backports/ubuntu14.04/debian/frr.postrm deleted file mode 100644 index 48c23321f7..0000000000 --- a/debianpkg/backports/ubuntu14.04/debian/frr.postrm +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash -e - -if [ -n "$DEBIAN_SCRIPT_DEBUG" ]; then set -v -x; DEBIAN_SCRIPT_TRACE=1; fi -${DEBIAN_SCRIPT_TRACE:+ echo "#42#DEBUG# RUNNING $0 $*"} -# set -u not because of debhelper - -update-rc.d -f frr remove >> /dev/null - -if [ "$1" = "purge" ]; then - rm -rf /etc/frr /var/run/frr /var/log/frr - userdel frr >/dev/null 2>&1 || true -fi - -#DEBHELPER# diff --git a/debianpkg/backports/ubuntu14.04/debian/rules b/debianpkg/backports/ubuntu14.04/debian/rules index 291233c147..21b442d85a 100755 --- a/debianpkg/backports/ubuntu14.04/debian/rules +++ b/debianpkg/backports/ubuntu14.04/debian/rules @@ -178,6 +178,8 @@ override_dh_auto_test: override_dh_auto_install: dh_auto_install + cp tools/frrinit.sh debian/frr.init + # installed in frr-pythontools rm debian/tmp/usr/lib/frr/frr-reload.py diff --git a/debianpkg/rules b/debianpkg/rules index 7cdb8fbaf7..12d6c3545c 100755 --- a/debianpkg/rules +++ b/debianpkg/rules @@ -171,7 +171,7 @@ override_dh_systemd_enable: # backports SRCPKG = frr -KNOWN_BACKPORTS = debian8 debian9 ubuntu12.04 ubuntu14.04 ubuntu16.04 ubuntu17.10 ubuntu18.04 +KNOWN_BACKPORTS = debian8 debian9 ubuntu14.04 ubuntu16.04 ubuntu17.10 ubuntu18.04 DEBIAN_VERSION := $(shell dh_testdir && \ dpkg-parsechangelog -c1 < debian/changelog | \ sed -rn 's/^Version: ?//p') diff --git a/debianpkg/subdir.am b/debianpkg/subdir.am index b6251962b7..af17e4642a 100644 --- a/debianpkg/subdir.am +++ b/debianpkg/subdir.am @@ -23,18 +23,8 @@ EXTRA_DIST += \ debianpkg/backports/debian9/debian/source/format \ debianpkg/backports/debian9/exclude \ debianpkg/backports/debian9/versionext \ - debianpkg/backports/ubuntu12.04/debian/control \ - debianpkg/backports/ubuntu12.04/debian/frr.install \ - debianpkg/backports/ubuntu12.04/debian/frr.postinst \ - debianpkg/backports/ubuntu12.04/debian/frr.postrm \ - debianpkg/backports/ubuntu12.04/debian/rules \ - debianpkg/backports/ubuntu12.04/debian/source/format \ - debianpkg/backports/ubuntu12.04/exclude \ - debianpkg/backports/ubuntu12.04/versionext \ debianpkg/backports/ubuntu14.04/debian/control \ debianpkg/backports/ubuntu14.04/debian/frr.install \ - debianpkg/backports/ubuntu14.04/debian/frr.postinst \ - debianpkg/backports/ubuntu14.04/debian/frr.postrm \ debianpkg/backports/ubuntu14.04/debian/rules \ debianpkg/backports/ubuntu14.04/debian/source/format \ debianpkg/backports/ubuntu14.04/exclude \ diff --git a/redhat/frr.spec.in b/redhat/frr.spec.in index d2da06faa6..7a6344aa4c 100644 --- a/redhat/frr.spec.in +++ b/redhat/frr.spec.in @@ -637,6 +637,9 @@ fi %config(noreplace) %{_sysconfdir}/pam.d/frr %config(noreplace) %{_sysconfdir}/logrotate.d/frr %{_sbindir}/frr-reload +%{_sbindir}/frrcommon.sh +%{_sbindir}/frrinit.sh +%{_sbindir}/watchfrr.sh %files contrib diff --git a/tools/.gitignore b/tools/.gitignore index c23322c4c6..85dae7fd36 100644 --- a/tools/.gitignore +++ b/tools/.gitignore @@ -3,3 +3,6 @@ /gen_yang_deviations /permutations /ssd +/watchfrr.sh +/frrinit.sh +/frrcommon.sh diff --git a/tools/etc/frr/daemons b/tools/etc/frr/daemons index 1514082e90..3f513bf618 100644 --- a/tools/etc/frr/daemons +++ b/tools/etc/frr/daemons @@ -1,11 +1,5 @@ # This file tells the frr package which daemons to start. # -# Entries are in the format: =(yes|no|priority) -# 0, "no" = disabled -# 1, "yes" = highest priority -# 2 .. 10 = lower priorities -# Read /usr/share/doc/frr/README.Debian for details. -# # Sample configurations for these daemons can be found in # /usr/share/doc/frr/examples/. # @@ -18,10 +12,8 @@ # When using "vtysh" such a config file is also needed. It should be owned by # group "frrvty" and set to ug=rw,o= though. Check /etc/pam.d/frr, too. # -# The watchfrr daemon is always started. Per default in monitoring-only but -# that can be changed via /etc/frr/daemons.conf. +# The watchfrr and zebra daemons are always started. # -zebra=no bgpd=no ospfd=no ospf6d=no diff --git a/tools/etc/frr/daemons.conf b/tools/etc/frr/daemons.conf index 1f608cfe08..02a785c87a 100644 --- a/tools/etc/frr/daemons.conf +++ b/tools/etc/frr/daemons.conf @@ -4,29 +4,30 @@ # Check /etc/pam.d/frr if you intend to use "vtysh"! # vtysh_enable=yes -zebra_options=" -s 90000000 --daemon -A 127.0.0.1" -bgpd_options=" --daemon -A 127.0.0.1" -ospfd_options=" --daemon -A 127.0.0.1" -ospf6d_options=" --daemon -A ::1" -ripd_options=" --daemon -A 127.0.0.1" -ripngd_options=" --daemon -A ::1" -isisd_options=" --daemon -A 127.0.0.1" -pimd_options=" --daemon -A 127.0.0.1" -ldpd_options=" --daemon -A 127.0.0.1" -nhrpd_options=" --daemon -A 127.0.0.1" -eigrpd_options=" --daemon -A 127.0.0.1" -babeld_options=" --daemon -A 127.0.0.1" -sharpd_options=" --daemon -A 127.0.0.1" -pbrd_options=" --daemon -A 127.0.0.1" -staticd_options=" --daemon -A 127.0.0.1" -bfdd_options=" --daemon -A 127.0.0.1" -fabricd_options=" --daemon -A 127.0.0.1" +zebra_options=" -A 127.0.0.1 -s 90000000" +bgpd_options=" -A 127.0.0.1" +ospfd_options=" -A 127.0.0.1" +ospf6d_options=" -A ::1" +ripd_options=" -A 127.0.0.1" +ripngd_options=" -A ::1" +isisd_options=" -A 127.0.0.1" +pimd_options=" -A 127.0.0.1" +ldpd_options=" -A 127.0.0.1" +nhrpd_options=" -A 127.0.0.1" +eigrpd_options=" -A 127.0.0.1" +babeld_options=" -A 127.0.0.1" +sharpd_options=" -A 127.0.0.1" +pbrd_options=" -A 127.0.0.1" +staticd_options="-A 127.0.0.1" +bfdd_options=" -A 127.0.0.1" +fabricd_options="-A 127.0.0.1" # The list of daemons to watch is automatically generated by the init script. -watchfrr_enable=yes -watchfrr_options="-d -r '/usr/lib/frr/frr restart %s' -s '/usr/lib/frr/frr start %s' -k '/usr/lib/frr/frr stop %s'" +watchfrr_options="-r '/usr/lib/frr/watchfrr.sh restart %s' -s '/usr/lib/frr/watchfrr.sh start %s' -k '/usr/lib/frr/watchfrr.sh stop %s'" -# If valgrind_enable is 'yes' the frr daemons will be started via valgrind. -# The use case for doing so is tracking down memory leaks, etc in frr. -valgrind_enable=no -valgrind=/usr/bin/valgrind +# for debugging purposes, you can specify a "wrap" command to start instead +# of starting the daemon directly, e.g. to use valgrind on ospfd: +# ospfd_wrap="/usr/bin/valgrind" +# or you can use "all_wrap" for all daemons, e.g. to use perf record: +# all_wrap="/usr/bin/perf record --call-graph -" +# the normal daemon command is added to this at the end. diff --git a/tools/frr.service b/tools/frr.service index 5f44274ec3..03112bd7cd 100644 --- a/tools/frr.service +++ b/tools/frr.service @@ -5,7 +5,6 @@ OnFailure=heartbeat-failed@%n.service [Service] Nice=-5 -EnvironmentFile=/etc/default/frr Type=forking NotifyAccess=all StartLimitInterval=3m @@ -15,8 +14,8 @@ WatchdogSec=60s RestartSec=5 Restart=on-abnormal LimitNOFILE=1024 -ExecStart=/usr/lib/frr/frr start -ExecStop=/usr/lib/frr/frr stop -ExecReload=/usr/lib/frr/frr-reload +ExecStart=/usr/lib/frr/frrinit.sh start +ExecStop=/usr/lib/frr/frrinit.sh stop +ExecReload=/usr/lib/frr/frrinit.sh reload [Install] WantedBy=network-online.target diff --git a/tools/frrcommon.sh.in b/tools/frrcommon.sh.in new file mode 100644 index 0000000000..7278e3f9df --- /dev/null +++ b/tools/frrcommon.sh.in @@ -0,0 +1,317 @@ +#!/bin/sh +# +# This is a "library" of sorts for use by the other FRR shell scripts. It +# has most of the daemon start/stop logic, but expects the following shell +# functions/commands to be provided by the "calling" script: +# +# log_success_msg +# log_warning_msg +# log_failure_msg +# +# (coincidentally, these are LSB standard functions.) +# +# Sourcing this file in a shell script will load FRR config variables but +# not perform any action. Note there is an "exit 1" if the main config +# file does not exist. +# +# This script should be installed in @CFG_SBIN@/frrcommon.sh + +PATH=/bin:/usr/bin:/sbin:/usr/sbin +D_PATH="@CFG_SBIN@" # /usr/lib/frr +C_PATH="@CFG_SYSCONF@" # /etc/frr +V_PATH="@CFG_STATE@" # /var/run/frr +VTYSH="@vtysh_bin@" # /usr/bin/vtysh +FRR_USER="@enable_user@" # frr +FRR_GROUP="@enable_group@" # frr +FRR_VTY_GROUP="@enable_vty_group@" # frrvty + +# ORDER MATTERS FOR $DAEMONS! +# - keep zebra first +# - watchfrr does NOT belong in this list + +DAEMONS="zebra bgpd ripd ripngd ospfd ospf6d isisd babeld pimd ldpd nhrpd eigrpd sharpd pbrd staticd bfdd fabricd" +RELOAD_SCRIPT="$D_PATH/frr-reload.py" + +# +# general helpers +# + +debug() { + [ -n "$watchfrr_debug" ] || return 0 + + printf '%s %s(%s):' "`date +%Y-%m-%dT%H:%M:%S.%N`" "$0" $$ >&2 + # this is to show how arguments are split regarding whitespace & co. + # (e.g. for use with `debug "message" "$@"`) + while [ $# -gt 0 ]; do + printf ' "%s"' "$1" >&2 + shift + done + printf '\n' >&2 +} + +chownfrr() { + [ -n "$FRR_USER" ] && chown "$FRR_USER" "$1" + [ -n "$FRR_GROUP" ] && chgrp "$FRR_GROUP" "$1" +} + +vtysh_b () { + [ "$1" = "watchfrr" ] && return 0 + [ -r "$C_PATH/frr.conf" ] || return 0 + if [ -n "$1" ]; then + "$VTYSH" -b -n -d "$1" + else + "$VTYSH" -b -n + fi +} + +daemon_inst() { + # note this sets global variables ($dmninst, $daemon, $inst) + dmninst="$1" + daemon="${dmninst%:*}" + inst="" + [ "$daemon" != "$dmninst" ] && inst="${dmninst#*:}" +} + +daemon_list() { + # note $1 and $2 specify names for global variables to be set + local enabled disabled evar dvar + enabled="" + disabled="" + evar="$1" + dvar="$2" + + for daemon in $DAEMONS; do + eval cfg=\$$daemon + eval inst=\$${daemon}_instances + [ "$daemon" = zebra ] && cfg=yes + if [ -n "$cfg" -a "$cfg" != "no" -a "$cfg" != "0" ]; then + debug "$daemon enabled" + enabled="$enabled $daemon" + if [ -n "$inst" ]; then + debug "$daemon multi-instance $inst" + for i in $inst; do + enabled="$enabled $daemon:$inst" + done + fi + else + debug "$daemon disabled" + disabled="$disabled $daemon" + fi + done + + enabled="${enabled# }" + disabled="${disabled# }" + [ -z "$evar" ] && echo "$enabled" + [ -n "$evar" ] && eval $evar="\"$enabled\"" + [ -n "$dvar" ] && eval $dvar="\"$disabled\"" +} + +# +# individual daemon management +# + +daemon_prep() { + local daemon inst cfg + daemon="$1" + inst="$2" + [ "$daemon" = "watchfrr" ] && return 0 + [ -x "$D_PATH/$daemon" ] || { + log_failure_msg "cannot start $daemon${inst:+ (instance $inst)}: daemon binary not installed\n" + return 1 + } + [ -r "$C_PATH/frr.conf" ] && return 0 + + cfg="$C_PATH/$daemon${inst:+-$inst}.conf" + if [ ! -r "$cfg" ]; then + touch "$cfg" + chownfrr "$cfg" + fi + return 0 +} + +daemon_start() { + local dmninst daemon inst args instopt wrap bin + daemon_inst "$1" + + ulimit -n $MAX_FDS > /dev/null 2> /dev/null + daemon_prep "$daemon" "$inst" || return 1 + + eval wrap="\$${daemon}_wrap" + bin="$D_PATH/$daemon" + instopt="${inst:+-n $inst}" + eval args="\$${daemon}_options" + + if eval "$all_wrap $wrap $bin -d $instopt $args"; then + log_success_msg "Started $dmninst" + vtysh_b "$daemon" + else + log_failure_msg "Failed to start $dmninst!" + fi +} + +daemon_stop() { + local dmninst daemon inst pidfile vtyfile pid cnt fail + daemon_inst "$1" + + pidfile="$V_PATH/$daemon${inst:+-$inst}.pid" + vtyfile="$V_PATH/$daemon${inst:+-$inst}.vty" + + [ -r "$pidfile" ] || fail="pid file not found" + [ -z "$fail" ] && pid="`cat \"$pidfile\"`" + [ -z "$fail" -a -z "$pid" ] && fail="pid file is empty" + [ -n "$fail" ] || kill -0 "$pid" 2>/dev/null || fail="pid $pid not running" + + if [ -n "$fail" ]; then + log_failure_msg "Cannot stop $dmninst: $fail" + return 1 + fi + + debug "kill -2 $pid" + kill -2 "$pid" + cnt=1200 + while kill -0 "$pid" 2>/dev/null; do + sleep .1 + [ $(( cnt -= 1 )) -gt 0 ] || break + done + if kill -0 "$pid" 2>/dev/null; then + log_failure_msg "Failed to stop $dmninst, pid $pid still running" + still_running=1 + return 1 + else + log_success_msg "Stopped $dmninst" + rm -f "$pidfile" + return 0 + fi +} + +daemon_status() { + local dmninst daemon inst pidfile pid fail + daemon_inst "$1" + + pidfile="$V_PATH/$daemon${inst:+-$inst}.pid" + + [ -r "$pidfile" ] || return 3 + pid="`cat \"$pidfile\"`" + [ -z "$pid" ] && return 1 + kill -0 "$pid" 2>/dev/null || return 1 + return 0 +} + +print_status() { + daemon_status "$1" + rv=$? + if [ "$rv" -eq 0 ]; then + log_success_msg "Status of $1: running" + else + log_failure_msg "Status of $1: FAILED" + fi + return $rv +} + +# +# all-daemon commands +# + +all_start() { + daemon_list daemons + for dmninst in $daemons; do + daemon_start "$dmninst" + done +} + +all_stop() { + local pids reversed + + daemon_list daemons disabled + [ "$1" = "--reallyall" ] && daemons="$daemons $disabled" + + reversed="" + for dmninst in $daemons; do + reversed="$dmninst $reversed" + done + + for dmninst in $reversed; do + daemon_stop "$dmninst" & + pids="$pids $!" + done + for pid in $pids; do + wait $pid + done +} + +all_status() { + local fail + + daemon_list daemons + fail=0 + for dmninst in $daemons; do + print_status "$dmninst" || fail=1 + done + return $fail +} + +# +# config sourcing +# + +load_old_config() { + oldcfg="$1" + [ -r "$oldcfg" ] || return 0 + [ -s "$oldcfg" ] || return 0 + grep -v '^[[:blank:]]*\(#\|$\)' "$oldcfg" > /dev/null || return 0 + + log_warning_msg "Reading deprecated $oldcfg. Please move its settings to $C_PATH/daemons and remove it." + + # save off settings from daemons for the OR below + for dmn in $DAEMONS; do eval "_new_$dmn=\${$dmn:-no}"; done + + . "$oldcfg" + + # OR together the daemon enabling options between config files + for dmn in $DAEMONS; do eval "test \$_new_$dmn != no && $dmn=\$_new_$dmn; unset _new_$dmn"; done +} + +[ -r "$C_PATH/daemons" ] || { + log_failure_msg "cannot run $@: $C_PATH/daemons does not exist\n" + exit 1 +} +. "$C_PATH/daemons" + +load_old_config "$C_PATH/daemons.conf" +load_old_config "/etc/default/frr" +load_old_config "/etc/sysconfig/frr" + +# +# other defaults and dispatch +# + +frrcommon_main() { + local cmd + + debug "frrcommon_main" "$@" + + cmd="$1" + shift + + if [ "$1" = "all" -o -z "$1" ]; then + case "$cmd" in + start) all_start;; + stop) all_stop;; + restart) + all_stop + all_start + ;; + *) $cmd "$@";; + esac + else + case "$cmd" in + start) daemon_start "$@";; + stop) daemon_stop "$@";; + restart) + daemon_stop "$@" + daemon_start "$@" + ;; + *) $cmd "$@";; + esac + fi +} diff --git a/tools/frrinit.sh.in b/tools/frrinit.sh.in new file mode 100644 index 0000000000..3dddf5bd44 --- /dev/null +++ b/tools/frrinit.sh.in @@ -0,0 +1,90 @@ +#!/bin/sh +# +### BEGIN INIT INFO +# Provides: frr +# Required-Start: $local_fs $network $remote_fs $syslog +# Required-Stop: $local_fs $network $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: start and stop the FRR routing suite +# Description: FRR is a routing suite for IP routing protocols like +# BGP, OSPF, RIP and others. This script contols the main +# "watchfrr" daemon. +### END INIT INFO +# +# This is the main init script for FRR. It mostly wraps frrcommon.sh which +# provides the actual functions to start/stop/restart things. +# + +if [ -r "/lib/lsb/init-functions" ]; then + . /lib/lsb/init-functions +else + log_success_msg() { + echo "$@" + } + log_warning_msg() { + echo "$@" >&2 + } + log_failure_msg() { + echo "$@" >&2 + } +fi + +self="`dirname $0`" +if [ -r "$self/frrcommon.sh" ]; then + . "$self/frrcommon.sh" +else + . "@CFG_SBIN@/frrcommon.sh" +fi + +case "$1" in +start) + daemon_list daemons + watchfrr_options="$watchfrr_options $daemons" + daemon_start watchfrr + ;; +stop) + daemon_stop watchfrr + all_stop --reallyall + exit ${still_running:-0} + ;; + +restart|force-reload) + daemon_stop watchfrr + all_stop --reallyall + + daemon_list daemons + watchfrr_options="$watchfrr_options $daemons" + daemon_start watchfrr + ;; + +status) + fail=0 + print_status watchfrr || fail=1 + all_status || fail=1 + exit $fail + ;; + +reload) + if [ ! -x "$RELOAD_SCRIPT" ]; then + log_failure_msg "The frr-pythontools package is required for reload functionality." + exit 1 + fi + + # restart watchfrr to pick up added daemons. + # NB: This will NOT cause the other daemons to be restarted. + daemon_list daemons + watchfrr_options="$watchfrr_options $daemons" + daemon_stop watchfrr && \ + daemon_start watchfrr + + NEW_CONFIG_FILE="${2:-$C_PATH/frr.conf}" + [ ! -r $NEW_CONFIG_FILE ] && log_failure_msg "Unable to read new configuration file $NEW_CONFIG_FILE" && exit 1 + "$RELOAD_SCRIPT" --reload "$NEW_CONFIG_FILE" + exit $? + ;; + +*) + log_failure_msg "Unknown command: $1" >&2 + exit 1 +esac diff --git a/tools/subdir.am b/tools/subdir.am index 2e68dfee09..ff41fe2c63 100644 --- a/tools/subdir.am +++ b/tools/subdir.am @@ -13,6 +13,10 @@ sbin_SCRIPTS += \ tools/frr-reload \ tools/frr-reload.py \ tools/frr \ + \ + tools/frrcommon.sh \ + tools/frrinit.sh \ + tools/watchfrr.sh \ # end tools_permutations_SOURCES = tools/permutations.c diff --git a/tools/watchfrr.sh.in b/tools/watchfrr.sh.in new file mode 100644 index 0000000000..3051d91044 --- /dev/null +++ b/tools/watchfrr.sh.in @@ -0,0 +1,33 @@ +#!/bin/sh +# +# This is NOT the init script! This is the watchfrr start/stop/restart +# command handler, passed to watchfrr with the -s/-r/-k commands. It is used +# internally by watchfrr to start the protocol daemons with the appropriate +# options. +# +# This script should be installed in @CFG_SBIN@/watchfrr.sh + +log_success_msg() { + : +} + +log_warning_msg() { + echo "$@" >&2 + [ -x /usr/bin/logger ] && echo "$@" \ + | /usr/bin/logger -t watchfrr.sh -p daemon.warn +} + +log_failure_msg() { + echo "$@" >&2 + [ -x /usr/bin/logger ] && echo "$@" \ + | /usr/bin/logger -t watchfrr.sh -p daemon.err +} + +self="`dirname $0`" +if [ -r "$self/frrcommon.sh" ]; then + . "$self/frrcommon.sh" +else + . "@CFG_SBIN@/frrcommon.sh" +fi + +frrcommon_main "$@"