Merge pull request #15243 from opensourcerouting/autoconf-dir-mess

*: fix a pile of directory and/or state retention related issues
This commit is contained in:
Donald Sharp 2024-01-28 14:30:28 -05:00 committed by GitHub
commit 259e3d4dac
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
92 changed files with 932 additions and 539 deletions

View file

@ -56,7 +56,7 @@ MODULE_LDFLAGS = \
$(SAN_FLAGS) \
# end
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" -DCONFDATE=$(CONFDATE)
DEFS = @DEFS@ -DCONFDATE=$(CONFDATE)
AR_FLAGS = @AR_FLAGS@
ARFLAGS = @ARFLAGS@

View file

@ -28,9 +28,7 @@ source="$pkgname-$pkgver.tar.gz"
builddir="$srcdir"/$pkgname-$pkgver
_sbindir=/usr/lib/frr
_sysconfdir=/etc/frr
_libdir=/usr/lib
_localstatedir=/var/run/frr
_user=frr
build() {
@ -38,10 +36,10 @@ build() {
./configure \
--prefix=/usr \
--sysconfdir=/etc \
--localstatedir=/var \
--sbindir=$_sbindir \
--sysconfdir=$_sysconfdir \
--libdir=$_libdir \
--localstatedir=$_localstatedir \
--enable-rpki \
--enable-vtysh \
--enable-multipath=64 \

View file

@ -58,7 +58,6 @@ unsigned char protocol_group[16]; /* babel's link-local multicast address */
int protocol_port; /* babel's port */
int protocol_socket = -1; /* socket: communicate with others babeld */
static const char babel_config_default[] = SYSCONFDIR BABEL_DEFAULT_CONFIG;
static char *babel_vty_addr = NULL;
static int babel_vty_port = BABEL_VTY_PORT;
@ -126,6 +125,7 @@ static const struct frr_yang_module_info *const babeld_yang_modules[] = {
&frr_vrf_info,
};
/* clang-format off */
FRR_DAEMON_INFO(babeld, BABELD,
.vty_port = BABEL_VTY_PORT,
.proghelp = "Implementation of the BABEL routing protocol.",
@ -138,6 +138,7 @@ FRR_DAEMON_INFO(babeld, BABELD,
.yang_modules = babeld_yang_modules,
.n_yang_modules = array_size(babeld_yang_modules),
);
/* clang-format on */
int
main(int argc, char **argv)
@ -171,8 +172,8 @@ main(int argc, char **argv)
}
}
snprintf(state_file, sizeof(state_file), "%s/%s",
frr_vtydir, "babel-state");
snprintf(state_file, sizeof(state_file), "%s/%s", frr_runstatedir,
"babel-state");
/* create the threads handler */
master = frr_init ();
@ -366,7 +367,7 @@ show_babel_main_configuration (struct vty *vty)
"id = %s\n"
"kernel_metric = %d\n",
state_file,
babeld_di.config_file ? babeld_di.config_file : babel_config_default,
babeld_di.config_file,
format_address(protocol_group),
protocol_port,
babel_vty_addr ? babel_vty_addr : "None",

View file

@ -32,6 +32,8 @@ DECLARE_MGROUP(BFDD);
DECLARE_MTYPE(BFDD_CONTROL);
DECLARE_MTYPE(BFDD_NOTIFICATION);
#define BFDD_SOCK_NAME "%s/bfdd.sock", frr_runstatedir
/* bfd Authentication Type. */
#define BFD_AUTH_NULL 0
#define BFD_AUTH_SIMPLE 1

View file

@ -117,13 +117,20 @@ static const struct frr_yang_module_info *const bfdd_yang_modules[] = {
&frr_vrf_info,
};
FRR_DAEMON_INFO(bfdd, BFD, .vty_port = 2617,
/* clang-format off */
FRR_DAEMON_INFO(bfdd, BFD,
.vty_port = 2617,
.proghelp = "Implementation of the BFD protocol.",
.signals = bfd_signals, .n_signals = array_size(bfd_signals),
.signals = bfd_signals,
.n_signals = array_size(bfd_signals),
.privs = &bglobal.bfdd_privs,
.yang_modules = bfdd_yang_modules,
.n_yang_modules = array_size(bfdd_yang_modules),
);
/* clang-format on */
#define OPTION_CTLSOCK 1001
#define OPTION_DPLANEADDR 2000
@ -335,8 +342,6 @@ int main(int argc, char *argv[])
" --bfdctl Specify bfdd control socket\n"
" --dplaneaddr Specify BFD data plane address\n");
snprintf(ctl_path, sizeof(ctl_path), BFDD_CONTROL_SOCKET,
"", "");
while (true) {
opt = frr_getopt(argc, argv, NULL);
if (opt == EOF)
@ -357,9 +362,8 @@ int main(int argc, char *argv[])
}
}
if (bfdd_di.pathspace && !ctlsockused)
snprintf(ctl_path, sizeof(ctl_path), BFDD_CONTROL_SOCKET,
"/", bfdd_di.pathspace);
if (!ctlsockused)
snprintf(ctl_path, sizeof(ctl_path), BFDD_SOCK_NAME);
/* Initialize FRR infrastructure. */
master = frr_init();

View file

@ -95,10 +95,10 @@ int control_init(const char *path)
mode_t umval;
struct sockaddr_un sun_ = {
.sun_family = AF_UNIX,
.sun_path = BFDD_CONTROL_SOCKET,
};
if (path)
assert(path);
strlcpy(sun_.sun_path, path, sizeof(sun_.sun_path));
/* Remove previously created sockets. */

View file

@ -385,15 +385,20 @@ static const struct frr_yang_module_info *const bgpd_yang_modules[] = {
&frr_bgp_route_map_info,
};
FRR_DAEMON_INFO(bgpd, BGP, .vty_port = BGP_VTY_PORT,
/* clang-format off */
FRR_DAEMON_INFO(bgpd, BGP,
.vty_port = BGP_VTY_PORT,
.proghelp = "Implementation of the BGP routing protocol.",
.signals = bgp_signals, .n_signals = array_size(bgp_signals),
.signals = bgp_signals,
.n_signals = array_size(bgp_signals),
.privs = &bgpd_privs, .yang_modules = bgpd_yang_modules,
.privs = &bgpd_privs,
.yang_modules = bgpd_yang_modules,
.n_yang_modules = array_size(bgpd_yang_modules),
);
/* clang-format on */
#define DEPRECATED_OPTIONS ""

View file

@ -5,7 +5,7 @@
# builds some git commit of FRR in some different configurations
# usage: buildtest.sh [commit [configurations...]]
basecfg="--prefix=/usr --enable-user=frr --enable-group=frr --enable-vty-group=frr --enable-configfile-mask=0660 --enable-logfile-mask=0640 --enable-vtysh --sysconfdir=/etc/frr --localstatedir=/var/run/frr --libdir=/usr/lib64/frr --enable-rtadv --disable-static --enable-isisd --enable-multipath=0 --enable-pimd --enable-werror"
basecfg="--prefix=/usr --enable-user=frr --enable-group=frr --enable-vty-group=frr --enable-configfile-mask=0660 --enable-logfile-mask=0640 --enable-vtysh --sysconfdir=/etc --localstatedir=/var --libdir=/usr/lib64/frr --enable-rtadv --disable-static --enable-isisd --enable-multipath=0 --enable-pimd --enable-werror"
configs_base="gcc|$basecfg"

View file

@ -20,6 +20,79 @@ AC_CONFIG_SRCDIR([lib/zebra.h])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_AUX_DIR([m4/ac])
dnl ------------------------------
dnl system paths
dnl ------------------------------
dnl Versions of FRR (or Quagga, or Zebra) before ca. 9.2 used sysconfdir and
dnl localstatedir as-is, without appending /frr. The /frr was expected to be
dnl given on ./configure invocations.
dnl
dnl This does not match standard behavior by other packages and makes FRR
dnl specific packaging changes necessary to add these options. localstatedir
dnl was also misused to include the /run part (it normally is only /var),
dnl leaving no path configuration option that references /var itself. This
dnl is because runstatedir did not exist in ancient autoconf.
dnl
dnl The path options have been changed to expect plain / system prefix
dnl directories. As a temporary workaround to not break packaging, eventual
dnl /frr suffixes are stripped and a warning is printed.
path_warn_banner=false
AC_MSG_CHECKING([whether --sysconfdir option is FRR-specific])
case "$sysconfdir" in
*/frr)
AC_MSG_RESULT([yes, ends in /frr - removing suffix])
AC_MSG_WARN([Please remove /frr suffix from --sysconfdir="${sysconfdir}" (it should be /etc in 99% of cases)])
sysconfdir="${sysconfdir%/frr}"
path_warn_banner=true
;;
*)
AC_MSG_RESULT([no, as expected])
;;
esac
frr_sysconfdir="\${sysconfdir}/frr"
AC_MSG_CHECKING([whether --localstatedir option is FRR-specific])
case "$localstatedir" in
*/run/frr)
AC_MSG_RESULT([yes, ends in /run/frr - removing suffix])
AC_MSG_WARN([Please remove /run/frr suffix from --localstatedir=${localstatedir} (it should be /var in 99% of cases)])
localstatedir="${localstatedir%/run/frr}"
path_warn_banner=true
;;
*/frr)
AC_MSG_RESULT([yes, ends in /frr - removing suffix])
AC_MSG_WARN([The --localstatedir=${localstatedir} option seems to include /frr but not /run, this is unexpected. Please check for consistency.)])
localstatedir="${localstatedir%/frr}"
path_warn_banner=true
;;
*)
AC_MSG_RESULT([no, as expected])
;;
esac
dnl runstatedir is either ${localstatedir}/run or plain /run
dnl the change of localstatedir above may impact this
dnl
dnl note runstatedir was never used with /frr as the other two above, so does
dnl not need the same cleanup hack
: "${runstatedir:=\${localstatedir\}/run}"
frr_runstatedir="\${runstatedir}/frr"
if $path_warn_banner; then
AC_MSG_WARN([^])
AC_MSG_WARN([^])
AC_MSG_WARN([^ warnings regarding system path configuration were printed above])
AC_MSG_WARN([^ paths have been adjusted by temporary workarounds])
AC_MSG_WARN([^ please fix your ./configure invocation (remove /frr) so it will work without the workarounds])
AC_MSG_WARN([^])
AC_MSG_WARN([^])
fi
frr_libstatedir="\${localstatedir}/lib/frr"
dnl -----------------------------------
dnl Get hostname and other information.
dnl -----------------------------------
@ -130,10 +203,10 @@ AC_ARG_WITH([moduledir], [AS_HELP_STRING([--with-moduledir=DIR], [module directo
])
AC_SUBST([moduledir], [$moduledir])
AC_ARG_WITH([scriptdir], [AS_HELP_STRING([--with-scriptdir=DIR], [script directory (${sysconfdir}/scripts)])], [
AC_ARG_WITH([scriptdir], [AS_HELP_STRING([--with-scriptdir=DIR], [script directory (${sysconfdir}/frr/scripts)])], [
scriptdir="$withval"
], [
scriptdir="\${sysconfdir}/scripts"
scriptdir="\${frr_sysconfdir}/scripts"
])
AC_SUBST([scriptdir], [$scriptdir])
@ -2641,87 +2714,27 @@ else
fi
AC_SUBST([CONFDATE])
dnl ------------------------------
dnl set paths for state directory
dnl ------------------------------
AC_MSG_CHECKING([directory to use for state file])
if test "$prefix" = "NONE"; then
frr_statedir_prefix="";
else
frr_statedir_prefix=${prefix}
fi
if test "$localstatedir" = '${prefix}/var'; then
for FRR_STATE_DIR in ${frr_statedir_prefix}/var/run dnl
${frr_statedir_prefix}/var/adm dnl
${frr_statedir_prefix}/etc dnl
/var/run dnl
/var/adm dnl
/etc dnl
/dev/null;
do
test -d $FRR_STATE_DIR && break
done
frr_statedir=$FRR_STATE_DIR
else
frr_statedir=${localstatedir}
fi
if test "$frr_statedir" = "/dev/null"; then
AC_MSG_ERROR([STATE DIRECTORY NOT FOUND! FIX OR SPECIFY --localstatedir!])
fi
AC_MSG_RESULT([${frr_statedir}])
AC_SUBST([frr_statedir])
AC_DEFINE_UNQUOTED([LDPD_SOCKET], ["$frr_statedir%s%s/ldpd.sock"], [ldpd control socket])
AC_DEFINE_UNQUOTED([ZEBRA_SERV_PATH], ["$frr_statedir%s%s/zserv.api"], [zebra api socket])
AC_DEFINE_UNQUOTED([BFDD_CONTROL_SOCKET], ["$frr_statedir%s%s/bfdd.sock"], [bfdd control socket])
AC_DEFINE_UNQUOTED([OSPFD_GR_STATE], ["$frr_statedir%s/ospfd-gr.json"], [ospfd GR state information])
AC_DEFINE_UNQUOTED([MGMTD_FE_SERVER_PATH], ["$frr_statedir/mgmtd_fe.sock"], [mgmtd frontend server socket])
AC_DEFINE_UNQUOTED([MGMTD_BE_SERVER_PATH], ["$frr_statedir/mgmtd_be.sock"], [mgmtd backend server socket])
AC_DEFINE_UNQUOTED([OSPF6D_GR_STATE], ["$frr_statedir/ospf6d-gr.json"], [ospf6d GR state information])
AC_DEFINE_UNQUOTED([ISISD_RESTART], ["$frr_statedir%s/isid-restart.json"], [isisd restart information])
AC_DEFINE_UNQUOTED([OSPF6_AUTH_SEQ_NUM_FILE], ["$frr_statedir/ospf6d-at-seq-no.dat"], [ospf6d AT Sequence number information])
AC_DEFINE_UNQUOTED([DAEMON_VTY_DIR], ["$frr_statedir%s%s"], [daemon vty directory])
AC_DEFINE_UNQUOTED([DAEMON_DB_DIR], ["$frr_statedir"], [daemon database directory])
dnl autoconf does this, but it does it too late...
test "$prefix" = "NONE" && prefix=$ac_default_prefix
test "$exec_prefix" = "NONE" && exec_prefix='${prefix}'
dnl get the full path, recursing through variables...
vtysh_bin="$bindir/vtysh"
for I in 1 2 3 4 5 6 7 8 9 10; do
eval vtysh_bin="\"$vtysh_bin\""
done
AC_DEFINE_UNQUOTED([VTYSH_BIN_PATH], ["$vtysh_bin"], [path to vtysh binary])
AC_SUBST([vtysh_bin])
AC_DEFUN([AX_SUBST_EXPANDED], [
AX_RECURSIVE_EVAL([[$]$1], [e_$1])
AC_SUBST([e_$1])
])
CFG_SYSCONF="$sysconfdir"
CFG_SBIN="$sbindir"
CFG_BIN="$bindir"
CFG_STATE="$frr_statedir"
CFG_MODULE="$moduledir"
CFG_YANGMODELS="$yangmodelsdir"
CFG_SCRIPT="$scriptdir"
for I in 1 2 3 4 5 6 7 8 9 10; do
eval CFG_SYSCONF="\"$CFG_SYSCONF\""
eval CFG_SBIN="\"$CFG_SBIN\""
eval CFG_BIN="\"$CFG_BIN\""
eval CFG_STATE="\"$CFG_STATE\""
eval CFG_MODULE="\"$CFG_MODULE\""
eval CFG_YANGMODELS="\"$CFG_YANGMODELS\""
eval CFG_SCRIPT="\"$CFG_SCRIPT\""
done
AC_SUBST([CFG_SYSCONF])
AC_SUBST([CFG_SBIN])
AC_SUBST([CFG_BIN])
AC_SUBST([CFG_STATE])
AC_SUBST([CFG_MODULE])
AC_SUBST([CFG_SCRIPT])
AC_SUBST([CFG_YANGMODELS])
AC_DEFINE_UNQUOTED([MODULE_PATH], ["$CFG_MODULE"], [path to modules])
AC_DEFINE_UNQUOTED([SCRIPT_PATH], ["$CFG_SCRIPT"], [path to scripts])
AC_DEFINE_UNQUOTED([YANG_MODELS_PATH], ["$CFG_YANGMODELS"], [path to YANG data models])
AC_DEFINE_UNQUOTED([WATCHFRR_SH_PATH], ["${CFG_SBIN%/}/watchfrr.sh"], [path to watchfrr.sh])
AX_SUBST_EXPANDED([bindir])
AX_SUBST_EXPANDED([sbindir])
AX_SUBST_EXPANDED([frr_sysconfdir])
AX_SUBST_EXPANDED([frr_runstatedir])
AX_SUBST_EXPANDED([frr_libstatedir])
AX_SUBST_EXPANDED([moduledir])
AX_SUBST_EXPANDED([yangmodelsdir])
AX_SUBST_EXPANDED([scriptdir])
dnl strip duplicate trailing slashes if necessary
dnl note this uses e_bindir / e_sbindir created above
watchfrr_sh="\${e_sbindir%/}/watchfrr.sh"
AX_SUBST_EXPANDED([watchfrr_sh])
vtysh_bin="\${e_bindir%/}/vtysh"
AX_SUBST_EXPANDED([vtysh_bin])
dnl various features
AM_CONDITIONAL([SUPPORT_REALMS], [test "$enable_realms" = "yes"])
@ -2793,6 +2806,7 @@ AC_CONFIG_FILES([
alpine/APKBUILD
snapcraft/snapcraft.yaml
lib/version.h
lib/config_paths.h
tests/lib/cli/test_cli.refout pkgsrc/mgmtd.sh
pkgsrc/bgpd.sh pkgsrc/ospf6d.sh pkgsrc/ospfd.sh
pkgsrc/ripd.sh pkgsrc/ripngd.sh pkgsrc/zebra.sh
@ -2837,7 +2851,7 @@ fi
FRR_ALL_CCLS_FLAGS="$(echo ${LIBYANG_CFLAGS} ${LUA_INCLUDE} ${SQLITE3_CFLAGS} | sed -e 's/ */ /g')"
FRR_ALL_CCLS_CFLAGS="$(echo ${CFLAGS} ${WERROR} ${AC_CFLAGS} ${SAN_FLAGS} | sed -e 's/ */ /g')"
ac_frr_confdate="${CONFDATE}"
ac_frr_sysconfdir="${sysconfdir}/"
ac_frr_sysconfdir="${frr_sysconfdir}/"
])
])
@ -2880,10 +2894,10 @@ compiler : ${CC}
compiler flags : ${CFLAGS} ${WERROR} ${AC_CFLAGS} ${SAN_FLAGS}
make : ${MAKE-make}
linker flags : ${LDFLAGS} ${SAN_FLAGS} ${LIBS} ${LIBCAP} ${LIBREADLINE} ${LIBM}
state file directory : ${frr_statedir}
config file directory : `eval echo \`echo ${sysconfdir}\``
module directory : ${CFG_MODULE}
script directory : ${CFG_SCRIPT}
state file directory : ${e_frr_runstatedir}
config file directory : ${e_sysconfdir}
module directory : ${e_moduledir}
script directory : ${e_scriptdir}
user to run as : ${enable_user}
group to run as : ${enable_group}
group for vty sockets : ${enable_vty_group}
@ -2905,3 +2919,11 @@ fi
if test "$frr_py_mod_pytest" = "false"; then
AC_MSG_WARN([pytest is missing, unit tests cannot be performed])
fi
if $path_warn_banner; then
AC_MSG_WARN([^])
AC_MSG_WARN([^])
AC_MSG_WARN([^ warnings regarding system path configuration were printed at the very top of output])
AC_MSG_WARN([^ paths have been adjusted by temporary workarounds])
AC_MSG_WARN([^ please fix your ./configure invocation (remove /frr) so it will work without the workarounds])
fi

2
debian/frr.postinst vendored
View file

@ -17,8 +17,10 @@ adduser \
usermod -a -G frrvty frr
mkdir -m 0755 -p /var/log/frr
mkdir -m 0700 -p /var/lib/frr
mkdir -p /etc/frr
chown frr: /var/lib/frr
# only change ownership of files when they were previously owned by root or
# quagga; this is to ensure we don't trample over some custom user setup.

2
debian/rules vendored
View file

@ -41,9 +41,7 @@ export PYTHON=python3
override_dh_auto_configure:
$(shell dpkg-buildflags --export=sh); \
dh_auto_configure -- \
--localstatedir=/var/run/frr \
--sbindir=/usr/lib/frr \
--sysconfdir=/etc/frr \
--with-vtysh-pager=/usr/bin/pager \
--libdir=/usr/lib/$(DEB_HOST_MULTIARCH)/frr \
--with-moduledir=/usr/lib/$(DEB_HOST_MULTIARCH)/frr/modules \

View file

@ -161,10 +161,8 @@ an example.)
./configure \
--bindir=/usr/bin \
--sbindir=/usr/lib/frr \
--sysconfdir=/etc/frr \
--libdir=/usr/lib/frr \
--libexecdir=/usr/lib/frr \
--localstatedir=/var/run/frr \
--with-moduledir=/usr/lib/frr/modules \
--disable-pimd \
--enable-snmp=agentx \

View file

@ -58,10 +58,8 @@ an example.)
./configure \
--bindir=/usr/bin \
--sbindir=/usr/lib/frr \
--sysconfdir=/etc/frr \
--libdir=/usr/lib/frr \
--libexecdir=/usr/lib/frr \
--localstatedir=/var/run/frr \
--with-moduledir=/usr/lib/frr/modules \
--enable-snmp=agentx \
--enable-multipath=64 \

View file

@ -52,10 +52,8 @@ an example.)
./configure \
--bindir=/usr/bin \
--sbindir=/usr/lib/frr \
--sysconfdir=/etc/frr \
--libdir=/usr/lib/frr \
--libexecdir=/usr/lib/frr \
--localstatedir=/var/run/frr \
--with-moduledir=/usr/lib/frr/modules \
--enable-snmp=agentx \
--enable-multipath=64 \

View file

@ -47,9 +47,9 @@ an example.)
cd frr
./bootstrap.sh
./configure \
--localstatedir=/var/opt/frr \
--sysconfdir=/etc \
--localstatedir=/var \
--sbindir=/usr/lib/frr \
--sysconfdir=/etc/frr \
--enable-multipath=64 \
--enable-user=frr \
--enable-group=frr \

View file

@ -57,9 +57,9 @@ an example.)
cd frr
./bootstrap.sh
./configure \
--localstatedir=/var/run/frr \
--sysconfdir=/etc \
--localstatedir=/var \
--sbindir=/usr/lib/frr \
--sysconfdir=/etc/frr \
--enable-multipath=64 \
--enable-user=frr \
--enable-group=frr \
@ -118,9 +118,9 @@ Troubleshooting
The local state directory must exist and have the correct permissions
applied for the frrouting daemons to start. In the above ./configure
example the local state directory is set to /var/run/frr
(--localstatedir=/var/run/frr) Debian considers /var/run/frr to be
temporary and this is removed after a reboot.
example the local state directory is set to ``/var`` such that ``/var/run/frr``
is used. Debian considers ``/var/run/frr`` to be temporary and this is removed
after a reboot.
When using a different local state directory you need to create the new
directory and change the ownership to the frr user, for example:

View file

@ -47,9 +47,9 @@ an example.)
cd frr
./bootstrap.sh
./configure \
--localstatedir=/var/opt/frr \
--sysconfdir=/etc \
--localstatedir=/var \
--sbindir=/usr/lib/frr \
--sysconfdir=/etc/frr \
--enable-multipath=64 \
--enable-user=frr \
--enable-group=frr \

View file

@ -60,9 +60,9 @@ an example)
export LDFLAGS="-L/usr/local/lib"
export CPPFLAGS="-I/usr/local/include"
./configure \
--sysconfdir=/usr/local/etc/frr \
--sysconfdir=/usr/local/etc \
--localstatedir=/var \
--enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \
--localstatedir=/var/run/frr \
--prefix=/usr/local \
--enable-multipath=64 \
--enable-user=frr \

View file

@ -65,9 +65,9 @@ an example)
setenv CPPFLAGS -I/usr/local/include
ln -s /usr/local/bin/sphinx-build-3.6 /usr/local/bin/sphinx-build
./configure \
--sysconfdir=/usr/local/etc/frr \
--sysconfdir=/usr/local/etc \
--localstatedir=/var \
--enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \
--localstatedir=/var/run/frr \
--prefix=/usr/local \
--enable-multipath=64 \
--enable-user=frr \

View file

@ -52,9 +52,9 @@ an example)
./bootstrap.sh
export MAKE=gmake LDFLAGS=-L/usr/local/lib CPPFLAGS=-I/usr/local/include
./configure \
--sysconfdir=/usr/local/etc/frr \
--sysconfdir=/usr/local/etc \
--localstatedir=/var \
--enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \
--localstatedir=/var/run/frr \
--prefix=/usr/local \
--enable-multipath=64 \
--enable-user=frr \

View file

@ -52,9 +52,9 @@ an example)
./bootstrap.sh
export MAKE=gmake LDFLAGS=-L/usr/local/lib CPPFLAGS=-I/usr/local/include
./configure \
--sysconfdir=/usr/local/etc/frr \
--sysconfdir=/usr/local/etc \
--localstatedir=/var \
--enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \
--localstatedir=/var/run/frr \
--prefix=/usr/local \
--enable-multipath=64 \
--enable-user=frr \

View file

@ -70,9 +70,9 @@ an example)
export LDFLAGS="-L/usr/local/lib"
export CPPFLAGS="-I/usr/local/include"
./configure \
--sysconfdir=/usr/local/etc/frr \
--sysconfdir=/usr/local/etc \
--localstatedir=/var \
--enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \
--localstatedir=/var/run/frr \
--prefix=/usr/local \
--enable-multipath=64 \
--enable-user=frr \

View file

@ -64,9 +64,9 @@ an example)
export LDFLAGS="-L/usr/pkg/lib -R/usr/pkg/lib"
export CPPFLAGS="-I/usr/pkg/include"
./configure \
--sysconfdir=/usr/pkg/etc/frr \
--sysconfdir=/usr/pkg/etc \
--localstatedir=/var \
--enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \
--localstatedir=/var/run/frr \
--enable-multipath=64 \
--enable-user=frr \
--enable-group=frr \

View file

@ -55,9 +55,9 @@ an example)
export LDFLAGS="-L/usr/pkg/lib -R/usr/pkg/lib"
export CPPFLAGS="-I/usr/pkg/include"
./configure \
--sysconfdir=/usr/pkg/etc/frr \
--sysconfdir=/usr/pkg/etc \
--localstatedir=/var \
--enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \
--localstatedir=/var/run/frr \
--enable-multipath=64 \
--enable-user=frr \
--enable-group=frr \

View file

@ -71,8 +71,8 @@ an example)
export LDFLAGS="-L/usr/local/lib"
export CPPFLAGS="-I/usr/local/include"
./configure \
--sysconfdir=/etc/frr \
--localstatedir=/var/frr \
--sysconfdir=/etc \
--localstatedir=/var \
--enable-multipath=64 \
--enable-user=_frr \
--enable-group=_frr \

View file

@ -239,9 +239,9 @@ the last thing to actually build is FRR itself:
--host=${HOST_ARCH} \
--with-sysroot=/usr/${HOST_ARCH} \
--with-clippy=./build-clippy/lib/clippy \
--sysconfdir=/etc/frr \
--sysconfdir=/etc \
--localstatedir=/var \
--sbindir="\${prefix}/lib/frr" \
--localstatedir=/var/run/frr \
--prefix=/usr \
--enable-user=frr \
--enable-group=frr \

View file

@ -14,8 +14,8 @@ obtained by running ``./configure -h``. The options shown below are examples.
--sbindir=\${prefix}/lib/frr \
--libdir=\${prefix}/lib/frr \
--libexecdir=\${prefix}/lib/frr \
--localstatedir=/var/run/frr \
--sysconfdir=/etc/frr \
--sysconfdir=/etc \
--localstatedir=/var \
--with-moduledir=\${prefix}/lib/frr/modules \
--enable-configfile-mask=0640 \
--enable-logfile-mask=0640 \

View file

@ -113,9 +113,9 @@ If you prefer to manually build FRR, then use the following suggested config:
./configure \
--prefix=/usr \
--localstatedir=/var/run/frr \
--sysconfdir=/etc \
--localstatedir=/var \
--sbindir=/usr/lib/frr \
--sysconfdir=/etc/frr \
--enable-vtysh \
--enable-pimd \
--enable-pim6d \
@ -383,8 +383,9 @@ for ``master`` branch:
./bootstrap.sh
./configure \
--enable-address-sanitizer \
--prefix=/usr/lib/frr --sysconfdir=/etc/frr \
--localstatedir=/var/run/frr \
--prefix=/usr/lib/frr \
--sysconfdir=/etc \
--localstatedir=/var \
--sbindir=/usr/lib/frr --bindir=/usr/lib/frr \
--with-moduledir=/usr/lib/frr/modules \
--enable-multipath=0 --enable-rtadv \

View file

@ -46,9 +46,7 @@ may also be specified (:ref:`common-invocation-options`).
/usr/lib/frr/bfdd --bfdctl /tmp/bfdd.sock
The default UNIX socket location is:
#define BFDD_CONTROL_SOCKET "|INSTALL_PREFIX_STATE|/bfdd.sock"
The default UNIX socket location is |INSTALL_PREFIX_STATE|/bfdd.sock
This option overrides the location addition that the -N option provides
to the bfdd.sock

View file

@ -394,13 +394,20 @@ options to the configuration script.
.. option:: --sysconfdir <dir>
Look for configuration files in `dir` [`prefix`/etc]. Note that sample
configuration files will be installed here.
Look for configuration files in `dir`/frr [`prefix`/etc]. Note that sample
configuration files will be installed here. Should be ``/etc`` unless
your platform splits package configuration locations.
.. option:: --localstatedir <dir>
Configure zebra to use `dir` for local state files, such as pid files and
unix sockets.
Configure base directory for local state. Indirectly controls
``--runstatedir``. Should be ``/var`` in most cases.
.. option:: --runstatedir <dir>
Configure FRR to use `dir`/frr for local state files, such as pid files and
unix sockets. Should be ``/var/run`` (default through ``--localstatedir``)
or ``/run`` in most cases.
.. option:: --with-scriptdir <dir>
@ -579,9 +586,9 @@ the options you chose:
./configure \
--prefix=/usr \
--localstatedir=/var/run/frr \
--sysconfdir=/etc \
--localstatedir=/var \
--sbindir=/usr/lib/frr \
--sysconfdir=/etc/frr \
--enable-pimd \
--enable-watchfrr \
...

View file

@ -110,9 +110,9 @@ RUN cd ~/frr && \
./bootstrap.sh && \
./configure \
--prefix=/usr \
--localstatedir=/var/run/frr \
--sysconfdir=/etc \
--localstatedir=/var \
--sbindir=/usr/lib/frr \
--sysconfdir=/etc/frr \
--enable-sharpd \
--enable-multipath=64 \
--enable-user=frr \

View file

@ -134,16 +134,20 @@ static const struct frr_yang_module_info *const eigrpd_yang_modules[] = {
&frr_vrf_info,
};
FRR_DAEMON_INFO(eigrpd, EIGRP, .vty_port = EIGRP_VTY_PORT,
/* clang-format off */
FRR_DAEMON_INFO(eigrpd, EIGRP,
.vty_port = EIGRP_VTY_PORT,
.proghelp = "Implementation of the EIGRP routing protocol.",
.signals = eigrp_signals,
.n_signals = array_size(eigrp_signals),
.privs = &eigrpd_privs, .yang_modules = eigrpd_yang_modules,
.privs = &eigrpd_privs,
.yang_modules = eigrpd_yang_modules,
.n_yang_modules = array_size(eigrpd_yang_modules),
);
/* clang-format on */
/* EIGRPd main routine. */
int main(int argc, char **argv, char **envp)

View file

@ -55,6 +55,16 @@
#define ISISD_VTY_PORT 2608
#define FABRICD_VTY_PORT 2618
#define FABRICD_STATE_NAME "%s/fabricd.json", frr_libstatedir
#define ISISD_STATE_NAME "%s/isisd.json", frr_libstatedir
/* The typo was there before. Do not fix it! The point is to load mis-saved
* state files from older versions.
*
* Also fabricd was using the same file. Sigh.
*/
#define ISISD_COMPAT_STATE_NAME "%s/isid-restart.json", frr_runstatedir
/* isisd privileges */
zebra_capabilities_t _caps_p[] = {ZCAP_NET_RAW, ZCAP_BIND, ZCAP_SYS_ADMIN};
@ -212,24 +222,41 @@ static void isis_config_end(void)
isis_config_finish(t_isis_cfg);
}
#ifdef FABRICD
FRR_DAEMON_INFO(fabricd, OPEN_FABRIC, .vty_port = FABRICD_VTY_PORT,
/* actual paths filled in main() */
static char state_path[512];
static char state_compat_path[512];
static char *state_paths[] = {
state_path,
state_compat_path,
NULL,
};
/* clang-format off */
FRR_DAEMON_INFO(
#ifdef FABRICD
fabricd, OPEN_FABRIC,
.vty_port = FABRICD_VTY_PORT,
.proghelp = "Implementation of the OpenFabric routing protocol.",
#else
FRR_DAEMON_INFO(isisd, ISIS, .vty_port = ISISD_VTY_PORT,
isisd, ISIS,
.vty_port = ISISD_VTY_PORT,
.proghelp = "Implementation of the IS-IS routing protocol.",
#endif
.copyright =
"Copyright (c) 2001-2002 Sampo Saaristo, Ofer Wald and Hannes Gredler",
.copyright = "Copyright (c) 2001-2002 Sampo Saaristo, Ofer Wald and Hannes Gredler",
.signals = isisd_signals,
.n_signals = array_size(isisd_signals),
.privs = &isisd_privs, .yang_modules = isisd_yang_modules,
.privs = &isisd_privs,
.yang_modules = isisd_yang_modules,
.n_yang_modules = array_size(isisd_yang_modules),
.state_paths = state_paths,
);
/* clang-format on */
/*
* Main routine of isisd. Parse arguments and handle IS-IS state machine.
@ -269,6 +296,14 @@ int main(int argc, char **argv, char **envp)
}
}
#ifdef FABRICD
snprintf(state_path, sizeof(state_path), FABRICD_STATE_NAME);
#else
snprintf(state_path, sizeof(state_path), ISISD_STATE_NAME);
#endif
snprintf(state_compat_path, sizeof(state_compat_path),
ISISD_COMPAT_STATE_NAME);
/* thread master */
isis_master_init(frr_init());
master = im->master;

View file

@ -3345,36 +3345,20 @@ void isis_area_advertise_high_metrics_set(struct isis_area *area,
}
}
/*
* Returns the path of the file (non-volatile memory) that contains restart
* information.
*/
char *isis_restart_filepath(void)
{
static char filepath[MAXPATHLEN];
snprintf(filepath, sizeof(filepath), ISISD_RESTART, "");
return filepath;
}
/*
* Record in non-volatile memory the overload on startup time.
*/
void isis_restart_write_overload_time(struct isis_area *isis_area,
uint32_t overload_time)
{
char *filepath;
const char *area_name;
json_object *json;
json_object *json_areas;
json_object *json_area;
filepath = isis_restart_filepath();
json = frr_daemon_state_load();
area_name = isis_area->area_tag;
json = json_object_from_file(filepath);
if (json == NULL)
json = json_object_new_object();
json_object_object_get_ex(json, "areas", &json_areas);
if (!json_areas) {
json_areas = json_object_new_object();
@ -3389,8 +3373,8 @@ void isis_restart_write_overload_time(struct isis_area *isis_area,
json_object_int_add(json_area, "overload_time",
isis_area->overload_on_startup_time);
json_object_to_file_ext(filepath, json, JSON_C_TO_STRING_PRETTY);
json_object_free(json);
frr_daemon_state_save(&json);
}
/*
@ -3398,7 +3382,6 @@ void isis_restart_write_overload_time(struct isis_area *isis_area,
*/
uint32_t isis_restart_read_overload_time(struct isis_area *isis_area)
{
char *filepath;
const char *area_name;
json_object *json;
json_object *json_areas;
@ -3406,12 +3389,9 @@ uint32_t isis_restart_read_overload_time(struct isis_area *isis_area)
json_object *json_overload_time;
uint32_t overload_time = 0;
filepath = isis_restart_filepath();
area_name = isis_area->area_tag;
json = json_object_from_file(filepath);
if (json == NULL)
json = json_object_new_object();
json = frr_daemon_state_load();
json_object_object_get_ex(json, "areas", &json_areas);
if (!json_areas) {
@ -3433,8 +3413,7 @@ uint32_t isis_restart_read_overload_time(struct isis_area *isis_area)
json_object_object_del(json_areas, area_name);
json_object_to_file_ext(filepath, json, JSON_C_TO_STRING_PRETTY);
json_object_free(json);
frr_daemon_state_save(&json);
return overload_time;
}

View file

@ -12,6 +12,12 @@
#ifndef _LDP_H_
#define _LDP_H_
/* this does not include "%s/", frr_runstatedir because the command-line
* override option specifies a *directory* rather than a full file name.
* Therefore the final part is needed on its own.
*/
#define LDPD_SOCK_NAME "ldpd.sock"
/* misc */
#define LDP_VERSION 1
#define LDP_PORT 646

View file

@ -197,6 +197,7 @@ static const struct frr_yang_module_info *const ldpd_yang_modules[] = {
&frr_vrf_info,
};
/* clang-format off */
FRR_DAEMON_INFO(ldpd, LDP,
.vty_port = LDP_VTY_PORT,
@ -210,6 +211,7 @@ FRR_DAEMON_INFO(ldpd, LDP,
.yang_modules = ldpd_yang_modules,
.n_yang_modules = array_size(ldpd_yang_modules),
);
/* clang-format on */
static void ldp_config_fork_apply(struct event *t)
{
@ -232,12 +234,8 @@ main(int argc, char *argv[])
int lflag = 0, eflag = 0;
int pipe_parent2ldpe[2], pipe_parent2ldpe_sync[2];
int pipe_parent2lde[2], pipe_parent2lde_sync[2];
char *ctl_sock_name;
bool ctl_sock_used = false;
snprintf(ctl_sock_path, sizeof(ctl_sock_path), LDPD_SOCKET,
"", "");
ldpd_process = PROC_MAIN;
log_procname = log_procnames[ldpd_process];
@ -263,21 +261,8 @@ main(int argc, char *argv[])
break;
case OPTION_CTLSOCK:
ctl_sock_used = true;
ctl_sock_name = strrchr(LDPD_SOCKET, '/');
if (ctl_sock_name)
/* skip '/' */
ctl_sock_name++;
else
/*
* LDPD_SOCKET configured as relative path
* during config? Should really never happen for
* sensible config
*/
ctl_sock_name = (char *)LDPD_SOCKET;
strlcpy(ctl_sock_path, optarg, sizeof(ctl_sock_path));
strlcat(ctl_sock_path, "/", sizeof(ctl_sock_path));
strlcat(ctl_sock_path, ctl_sock_name,
sizeof(ctl_sock_path));
snprintf(ctl_sock_path, sizeof(ctl_sock_path),
"%s/" LDPD_SOCK_NAME, optarg);
break;
case 'n':
init.instance = atoi(optarg);
@ -295,9 +280,9 @@ main(int argc, char *argv[])
}
}
if (ldpd_di.pathspace && !ctl_sock_used)
snprintf(ctl_sock_path, sizeof(ctl_sock_path), LDPD_SOCKET,
"/", ldpd_di.pathspace);
if (!ctl_sock_used)
snprintf(ctl_sock_path, sizeof(ctl_sock_path),
"%s/" LDPD_SOCK_NAME, frr_runstatedir);
strlcpy(init.user, ldpd_privs.user, sizeof(init.user));
strlcpy(init.group, ldpd_privs.group, sizeof(init.group));

1
lib/.gitignore vendored
View file

@ -1,3 +1,4 @@
/config_paths.h
/version.c
/version.h
/gitversion.h

View file

@ -43,6 +43,8 @@
#include "frrscript.h"
#include "lib/config_paths.h"
DEFINE_MTYPE_STATIC(LIB, HOST, "Host config");
DEFINE_MTYPE(LIB, COMPLETION, "Completion item");
@ -1633,6 +1635,10 @@ static int vty_write_config(struct vty *vty)
return CMD_SUCCESS;
}
/* cross-reference frr_daemon_state_save in libfrr.c
* the code there is similar but not identical (state files always use the same
* name for the new write, and don't keep a backup of previous state.)
*/
static int file_write_config(struct vty *vty)
{
int fd, dirfd;

24
lib/config_paths.h.in Normal file
View file

@ -0,0 +1,24 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/* autogenerated by configure / config.status */
/* IF YOU ARE INCLUDING THIS FILE FROM A DAEMON OR ZEBRA, YOU ARE PROBABLY
* DOING SOMETHING WRONG. Check for / add a library function that retrieves
* the path you need.
*
* Only libfrr and watchfrr should be including this file.
*/
/* the replacements for these are emitted by AX_SUBST_EXPANDED, which also
* adds the e_ prefix
*/
#define FRR_RUNSTATE_PATH "@e_frr_runstatedir@"
#define FRR_LIBSTATE_PATH "@e_frr_libstatedir@"
#define YANG_MODELS_PATH "@e_yangmodelsdir@"
#define MODULE_PATH "@e_moduledir@"
#define SCRIPT_PATH "@e_scriptdir@"
/* for extra footgunning, this one has a trailing slash */
#define SYSCONFDIR "@e_frr_sysconfdir@/"
#define VTYSH_BIN_PATH "@e_vtysh_bin@"
#define WATCHFRR_SH_PATH "@e_watchfrr_sh@"

View file

@ -37,6 +37,8 @@
#include "frrscript.h"
#include "systemd.h"
#include "lib/config_paths.h"
DEFINE_HOOK(frr_early_init, (struct event_loop * tm), (tm));
DEFINE_HOOK(frr_late_init, (struct event_loop * tm), (tm));
DEFINE_HOOK(frr_config_pre, (struct event_loop * tm), (tm));
@ -45,10 +47,8 @@ DEFINE_KOOH(frr_early_fini, (), ());
DEFINE_KOOH(frr_fini, (), ());
const char frr_sysconfdir[] = SYSCONFDIR;
char frr_vtydir[256];
#ifdef HAVE_SQLITE3
const char frr_dbdir[] = DAEMON_DB_DIR;
#endif
char frr_runstatedir[256] = FRR_RUNSTATE_PATH;
char frr_libstatedir[256] = FRR_LIBSTATE_PATH;
const char frr_moduledir[] = MODULE_PATH;
const char frr_scriptdir[] = SCRIPT_PATH;
@ -56,7 +56,7 @@ char frr_protoname[256] = "NONE";
char frr_protonameinst[256] = "NONE";
char config_default[512];
char frr_zclientpath[256];
char frr_zclientpath[512];
static char pidfile_default[1024];
#ifdef HAVE_SQLITE3
static char dbfile_default[512];
@ -310,11 +310,6 @@ bool frr_zclient_addr(struct sockaddr_storage *sa, socklen_t *sa_len,
static struct frr_daemon_info *di = NULL;
void frr_init_vtydir(void)
{
snprintf(frr_vtydir, sizeof(frr_vtydir), DAEMON_VTY_DIR, "", "");
}
void frr_preinit(struct frr_daemon_info *daemon, int argc, char **argv)
{
di = daemon;
@ -344,16 +339,14 @@ void frr_preinit(struct frr_daemon_info *daemon, int argc, char **argv)
if (di->flags & FRR_DETACH_LATER)
nodetach_daemon = true;
frr_init_vtydir();
snprintf(config_default, sizeof(config_default), "%s/%s.conf",
frr_sysconfdir, di->name);
snprintf(pidfile_default, sizeof(pidfile_default), "%s/%s.pid",
frr_vtydir, di->name);
snprintf(frr_zclientpath, sizeof(frr_zclientpath),
ZEBRA_SERV_PATH, "", "");
frr_runstatedir, di->name);
snprintf(frr_zclientpath, sizeof(frr_zclientpath), ZAPI_SOCK_NAME);
#ifdef HAVE_SQLITE3
snprintf(dbfile_default, sizeof(dbfile_default), "%s/%s.db",
frr_dbdir, di->name);
frr_libstatedir, di->name);
#endif
strlcpy(frr_protoname, di->logname, sizeof(frr_protoname));
@ -502,13 +495,15 @@ static int frr_opt(int opt)
}
di->pathspace = optarg;
snprintf(frr_runstatedir, sizeof(frr_runstatedir),
FRR_RUNSTATE_PATH "/%s", di->pathspace);
snprintf(frr_libstatedir, sizeof(frr_libstatedir),
FRR_LIBSTATE_PATH "/%s", di->pathspace);
snprintf(pidfile_default, sizeof(pidfile_default), "%s/%s.pid",
frr_runstatedir, di->name);
if (!di->zpathspace)
snprintf(frr_zclientpath, sizeof(frr_zclientpath),
ZEBRA_SERV_PATH, "/", di->pathspace);
snprintf(frr_vtydir, sizeof(frr_vtydir), DAEMON_VTY_DIR, "/",
di->pathspace);
snprintf(pidfile_default, sizeof(pidfile_default), "%s/%s.pid",
frr_vtydir, di->name);
ZAPI_SOCK_NAME);
break;
case 'o':
vrf_set_default_name(optarg);
@ -729,10 +724,10 @@ struct event_loop *frr_init(void)
snprintf(config_default, sizeof(config_default), "%s%s%s%s.conf",
frr_sysconfdir, p_pathspace, di->name, p_instance);
snprintf(pidfile_default, sizeof(pidfile_default), "%s/%s%s.pid",
frr_vtydir, di->name, p_instance);
frr_runstatedir, di->name, p_instance);
#ifdef HAVE_SQLITE3
snprintf(dbfile_default, sizeof(dbfile_default), "%s/%s%s%s.db",
frr_dbdir, p_pathspace, di->name, p_instance);
frr_libstatedir, p_pathspace, di->name, p_instance);
#endif
zprivs_preinit(di->privs);
@ -761,8 +756,9 @@ struct event_loop *frr_init(void)
/* don't mkdir these as root... */
if (!(di->flags & FRR_NO_PRIVSEP)) {
frr_mkdir(frr_libstatedir, false);
if (!di->pid_file || !di->vty_path)
frr_mkdir(frr_vtydir, false);
frr_mkdir(frr_runstatedir, false);
if (di->pid_file)
frr_mkdir(di->pid_file, true);
if (di->vty_path)
@ -1049,7 +1045,7 @@ void frr_vty_serv_start(void)
const char *dir;
char defvtydir[256];
snprintf(defvtydir, sizeof(defvtydir), "%s", frr_vtydir);
snprintf(defvtydir, sizeof(defvtydir), "%s", frr_runstatedir);
dir = di->vty_sock_path ? di->vty_sock_path : defvtydir;
@ -1275,6 +1271,161 @@ void frr_fini(void)
}
}
struct json_object *frr_daemon_state_load(void)
{
struct json_object *state;
char **state_path;
assertf(di->state_paths,
"CODE BUG: daemon trying to load state, but no state path in frr_daemon_info");
for (state_path = di->state_paths; *state_path; state_path++) {
state = json_object_from_file(*state_path);
if (state)
return state;
}
return json_object_new_object();
}
/* cross-reference file_write_config() in command.c
* the code there is similar but not identical (configs use a unique temporary
* name for writing and keep a backup of the previous config.)
*/
void frr_daemon_state_save(struct json_object **statep)
{
struct json_object *state = *statep;
char *state_path, *slash, *temp_name, **other;
size_t name_len, json_len;
const char *json_str;
int dirfd, fd;
assertf(di->state_paths,
"CODE BUG: daemon trying to save state, but no state path in frr_daemon_info");
state_path = di->state_paths[0];
json_str = json_object_to_json_string_ext(state,
JSON_C_TO_STRING_PRETTY);
json_len = strlen(json_str);
/* To correctly fsync() and ensure we have either consistent old state
* or consistent new state but no fs-damage garbage inbetween, we need
* to work with a directory fd. If we need that anyway we might as
* well use the dirfd with openat() & co in fd-relative operations.
*/
slash = strrchr(state_path, '/');
if (slash) {
char *state_dir;
state_dir = XSTRDUP(MTYPE_TMP, state_path);
state_dir[slash - state_path] = '\0';
dirfd = open(state_dir, O_DIRECTORY | O_RDONLY);
XFREE(MTYPE_TMP, state_dir);
if (dirfd < 0) {
zlog_err("failed to open directory %pSQq for saving daemon state: %m",
state_dir);
return;
}
/* skip to file name */
slash++;
} else {
dirfd = open(".", O_DIRECTORY | O_RDONLY);
if (dirfd < 0) {
zlog_err(
"failed to open current directory for saving daemon state: %m");
return;
}
/* file name = path */
slash = state_path;
}
/* unlike saving configs, a temporary unique filename is unhelpful
* here as it might litter files on limited write-heavy storage
* (think switch with small NOR flash for frequently written data.)
*
* => always use filename with .sav suffix, worst case it litters one
* file.
*/
name_len = strlen(slash);
temp_name = XMALLOC(MTYPE_TMP, name_len + 5);
memcpy(temp_name, slash, name_len);
memcpy(temp_name + name_len, ".sav", 5);
/* state file is always 0600, it's by and for FRR itself only */
fd = openat(dirfd, temp_name, O_WRONLY | O_CREAT | O_TRUNC, 0600);
if (fd < 0) {
zlog_err("failed to open temporary daemon state save file for %pSQq: %m",
state_path);
goto out_closedir_free;
}
while (json_len) {
ssize_t nwr = write(fd, json_str, json_len);
if (nwr <= 0) {
zlog_err("failed to write temporary daemon state to %pSQq: %m",
state_path);
close(fd);
unlinkat(dirfd, temp_name, 0);
goto out_closedir_free;
}
json_str += nwr;
json_len -= nwr;
}
/* fsync is theoretically implicit in close(), but... */
if (fsync(fd) < 0)
zlog_warn("fsync for daemon state %pSQq failed: %m", state_path);
close(fd);
/* this is the *actual* fsync that ensures we're consistent. The
* file fsync only syncs the inode, but not the directory entry
* referring to it.
*/
if (fsync(dirfd) < 0)
zlog_warn("directory fsync for daemon state %pSQq failed: %m",
state_path);
/* atomic, hopefully. */
if (renameat(dirfd, temp_name, dirfd, slash) < 0) {
zlog_err("renaming daemon state %pSQq to %pSQq failed: %m",
temp_name, state_path);
/* no unlink here, give the user a chance to investigate */
goto out_closedir_free;
}
/* and the rename needs to be synced too */
if (fsync(dirfd) < 0)
zlog_warn("directory fsync for daemon state %pSQq failed after rename: %m",
state_path);
/* daemon may specify other deprecated paths to load from; since we
* just saved successfully we should delete those.
*/
for (other = di->state_paths + 1; *other; other++) {
if (unlink(*other) == 0)
continue;
if (errno == ENOENT || errno == ENOTDIR)
continue;
zlog_warn("failed to remove deprecated daemon state file %pSQq: %m",
*other);
}
out_closedir_free:
XFREE(MTYPE_TMP, temp_name);
close(dirfd);
json_object_free(state);
*statep = NULL;
}
#ifdef INTERP
static const char interp[]
__attribute__((section(".interp"), used)) = INTERP;

View file

@ -22,6 +22,8 @@
extern "C" {
#endif
#define ZAPI_SOCK_NAME "%s/zserv.api", frr_runstatedir
/* The following options disable specific command line options that
* are not applicable for a particular daemon.
*/
@ -85,6 +87,7 @@ struct frr_daemon_info {
const char *vty_path;
const char *module_path;
const char *script_path;
char **state_paths;
const char *pathspace;
bool zpathspace;
@ -130,7 +133,6 @@ struct frr_daemon_info {
.version = FRR_VERSION, ); \
MACRO_REQUIRE_SEMICOLON() /* end */
extern void frr_init_vtydir(void);
extern void frr_preinit(struct frr_daemon_info *daemon, int argc, char **argv);
extern void frr_opt_add(const char *optstr, const struct option *longopts,
const char *helpstr);
@ -161,6 +163,10 @@ extern void frr_vty_serv_stop(void);
extern bool frr_zclient_addr(struct sockaddr_storage *sa, socklen_t *sa_len,
const char *path);
struct json_object;
extern struct json_object *frr_daemon_state_load(void);
extern void frr_daemon_state_save(struct json_object **statep);
/* these two are before the protocol daemon does its own shutdown
* it's named this way being the counterpart to frr_late_init */
DECLARE_KOOH(frr_early_fini, (), ());
@ -170,9 +176,10 @@ DECLARE_KOOH(frr_fini, (), ());
extern void frr_fini(void);
extern char config_default[512];
extern char frr_zclientpath[256];
extern char frr_zclientpath[512];
extern const char frr_sysconfdir[];
extern char frr_vtydir[256];
extern char frr_runstatedir[256];
extern char frr_libstatedir[256];
extern const char frr_moduledir[];
extern const char frr_scriptdir[];

View file

@ -1055,6 +1055,7 @@ struct mgmt_be_client *mgmt_be_client_create(const char *client_name,
struct event_loop *event_loop)
{
struct mgmt_be_client *client;
char server_path[MAXPATHLEN];
if (__be_client)
return NULL;
@ -1071,7 +1072,10 @@ struct mgmt_be_client *mgmt_be_client_create(const char *client_name,
if (cbs)
client->cbs = *cbs;
mgmt_be_txns_init(&client->txn_head);
msg_client_init(&client->client, event_loop, MGMTD_BE_SERVER_PATH,
snprintf(server_path, sizeof(server_path), MGMTD_BE_SOCK_NAME);
msg_client_init(&client->client, event_loop, server_path,
mgmt_be_client_notify_conenct,
mgmt_be_client_notify_disconenct,
mgmt_be_client_process_msg, MGMTD_BE_MAX_NUM_MSG_PROC,

View file

@ -11,6 +11,9 @@
#include "yang.h"
#define MGMTD_FE_SOCK_NAME "%s/mgmtd_fe.sock", frr_runstatedir
#define MGMTD_BE_SOCK_NAME "%s/mgmtd_be.sock", frr_runstatedir
#define MGMTD_CLIENT_NAME_MAX_LEN 32
#define MGMTD_MAX_XPATH_LEN XPATH_MAXLEN

View file

@ -712,6 +712,7 @@ struct mgmt_fe_client *mgmt_fe_client_create(const char *client_name,
struct event_loop *event_loop)
{
struct mgmt_fe_client *client;
char server_path[MAXPATHLEN];
if (__fe_client)
return NULL;
@ -726,7 +727,9 @@ struct mgmt_fe_client *mgmt_fe_client_create(const char *client_name,
mgmt_sessions_init(&client->sessions);
msg_client_init(&client->client, event_loop, MGMTD_FE_SERVER_PATH,
snprintf(server_path, sizeof(server_path), MGMTD_FE_SOCK_NAME);
msg_client_init(&client->client, event_loop, server_path,
mgmt_fe_client_notify_connect,
mgmt_fe_client_notify_disconnect,
mgmt_fe_client_process_msg, MGMTD_FE_MAX_NUM_MSG_PROC,

View file

@ -46,6 +46,8 @@
#include <arpa/telnet.h>
#include <termios.h>
#include "lib/config_paths.h"
#include "lib/vty_clippy.c"
DEFINE_MTYPE_STATIC(LIB, VTY, "VTY");

View file

@ -13,6 +13,8 @@
#include "yang_translator.h"
#include "northbound.h"
#include "lib/config_paths.h"
DEFINE_MTYPE_STATIC(LIB, YANG_MODULE, "YANG module");
DEFINE_MTYPE_STATIC(LIB, YANG_DATA, "YANG data structure");

1
m4/.gitignore vendored
View file

@ -7,6 +7,7 @@
!ax_prog_perl_modules.m4
!ax_pthread.m4
!ax_python.m4
!ax_recursive_eval.m4
!ax_sys_weak_alias.m4
!ax_sys_weak_alias.m4
!pkg.m4

31
m4/ax_recursive_eval.m4 Normal file
View file

@ -0,0 +1,31 @@
# SPDX-License-Identifier: GPL-2.0-or-later WITH Autoconf-exception-2.0
#
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_recursive_eval.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_RECURSIVE_EVAL(VALUE, RESULT)
#
# DESCRIPTION
#
# Interpolate the VALUE in loop until it doesn't change, and set the
# result to $RESULT. This version has a recursion limit (10).
#
# LICENSE
#
# Copyright (c) 2008 Alexandre Duret-Lutz <adl@gnu.org>
# Copyright (c) 2024 David Lamparter <equinox@opensourcerouting.org>
AC_DEFUN([AX_RECURSIVE_EVAL],
[_lcl_receval="$1"
$2=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix"
test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
_lcl_receval_old=''
for _rec_limit in 1 2 3 4 5 6 7 8 9 10; do
test "[$]_lcl_receval_old" = "[$]_lcl_receval" && break
_lcl_receval_old="[$]_lcl_receval"
eval _lcl_receval="\"[$]_lcl_receval\""
done
echo "[$]_lcl_receval")`])

View file

@ -706,15 +706,18 @@ extern void mgmt_be_adapter_unlock(struct mgmt_be_client_adapter **adapter)
*/
void mgmt_be_adapter_init(struct event_loop *tm)
{
char server_path[MAXPATHLEN];
assert(!mgmt_loop);
mgmt_loop = tm;
mgmt_be_adapters_init(&mgmt_be_adapters);
mgmt_be_xpath_map_init();
if (msg_server_init(&mgmt_be_server, MGMTD_BE_SERVER_PATH, tm,
mgmt_be_create_adapter, "backend",
&mgmt_debug_be)) {
snprintf(server_path, sizeof(server_path), MGMTD_BE_SOCK_NAME);
if (msg_server_init(&mgmt_be_server, server_path, tm,
mgmt_be_create_adapter, "backend", &mgmt_debug_be)) {
zlog_err("cannot initialize backend server");
exit(1);
}

View file

@ -29,8 +29,8 @@
#define MGMTD_MAX_COMMIT_LIST 10
#define MGMTD_COMMIT_FILE_PATH DAEMON_DB_DIR "/commit-%s.json"
#define MGMTD_COMMIT_INDEX_FILE_NAME DAEMON_DB_DIR "/commit-index.dat"
#define MGMTD_COMMIT_FILE_PATH(id) "%s/commit-%s.json", frr_libstatedir, id
#define MGMTD_COMMIT_INDEX_FILE_PATH "%s/commit-index.dat", frr_libstatedir
extern struct nb_config *running_config;

View file

@ -1309,6 +1309,8 @@ extern void mgmt_fe_adapter_unlock(struct mgmt_fe_client_adapter **adapter)
*/
void mgmt_fe_adapter_init(struct event_loop *tm)
{
char server_path[MAXPATHLEN];
assert(!mgmt_loop);
mgmt_loop = tm;
@ -1319,9 +1321,10 @@ void mgmt_fe_adapter_init(struct event_loop *tm)
hash_create(mgmt_fe_session_hash_key, mgmt_fe_session_hash_cmp,
"MGMT Frontend Sessions");
if (msg_server_init(&mgmt_fe_server, MGMTD_FE_SERVER_PATH, tm,
mgmt_fe_create_adapter, "frontend",
&mgmt_debug_fe)) {
snprintf(server_path, sizeof(server_path), MGMTD_FE_SOCK_NAME);
if (msg_server_init(&mgmt_fe_server, server_path, tm,
mgmt_fe_create_adapter, "frontend", &mgmt_debug_fe)) {
zlog_err("cannot initialize frontend server");
exit(1);
}

View file

@ -63,7 +63,7 @@ static struct mgmt_cmt_info_t *mgmt_history_new_cmt_info(void)
mgmt_time_to_string(&tv, true, new->time_str, sizeof(new->time_str));
mgmt_time_to_string(&tv, false, new->cmtid_str, sizeof(new->cmtid_str));
snprintf(new->cmt_json_file, sizeof(new->cmt_json_file),
MGMTD_COMMIT_FILE_PATH, new->cmtid_str);
MGMTD_COMMIT_FILE_PATH(new->cmtid_str));
return new;
}
@ -104,18 +104,21 @@ mgmt_history_find_cmt_record(const char *cmtid_str)
static bool mgmt_history_read_cmt_record_index(void)
{
char index_path[MAXPATHLEN];
FILE *fp;
struct mgmt_cmt_info_t cmt_info;
struct mgmt_cmt_info_t *new;
int cnt = 0;
if (!file_exists(MGMTD_COMMIT_FILE_PATH))
snprintf(index_path, sizeof(index_path), MGMTD_COMMIT_INDEX_FILE_PATH);
fp = fopen(index_path, "rb");
if (!fp) {
if (errno == ENOENT || errno == ENOTDIR)
return false;
fp = fopen(MGMTD_COMMIT_INDEX_FILE_NAME, "rb");
if (!fp) {
zlog_err("Failed to open commit history %s for reading: %s",
MGMTD_COMMIT_INDEX_FILE_NAME, safe_strerror(errno));
zlog_err("Failed to open commit history %pSQq for reading: %m",
index_path);
return false;
}
@ -132,9 +135,8 @@ static bool mgmt_history_read_cmt_record_index(void)
memcpy(new, &cmt_info, sizeof(struct mgmt_cmt_info_t));
mgmt_cmt_infos_add_tail(&mm->cmts, new);
} else {
zlog_warn(
"More records found in commit history file %s than expected",
MGMTD_COMMIT_INDEX_FILE_NAME);
zlog_warn("More records found in commit history file %pSQq than expected",
index_path);
fclose(fp);
return false;
}
@ -148,16 +150,19 @@ static bool mgmt_history_read_cmt_record_index(void)
static bool mgmt_history_dump_cmt_record_index(void)
{
char index_path[MAXPATHLEN];
FILE *fp;
int ret = 0;
struct mgmt_cmt_info_t *cmt_info;
struct mgmt_cmt_info_t cmt_info_set[10];
int cnt = 0;
fp = fopen(MGMTD_COMMIT_INDEX_FILE_NAME, "wb");
snprintf(index_path, sizeof(index_path), MGMTD_COMMIT_INDEX_FILE_PATH);
fp = fopen(index_path, "wb");
if (!fp) {
zlog_err("Failed to open commit history %s for writing: %s",
MGMTD_COMMIT_INDEX_FILE_NAME, safe_strerror(errno));
zlog_err("Failed to open commit history %pSQq for writing: %m",
index_path);
return false;
}
@ -176,7 +181,7 @@ static bool mgmt_history_dump_cmt_record_index(void)
fclose(fp);
if (ret != cnt) {
zlog_err("Failed to write full commit history, removing file");
remove_file(MGMTD_COMMIT_INDEX_FILE_NAME);
remove_file(index_path);
return false;
}
return true;

View file

@ -197,17 +197,23 @@ static const struct frr_yang_module_info *const mgmt_yang_modules[] = {
#endif
};
FRR_DAEMON_INFO(mgmtd, MGMTD, .vty_port = MGMTD_VTY_PORT,
/* clang-format off */
FRR_DAEMON_INFO(mgmtd, MGMTD,
.vty_port = MGMTD_VTY_PORT,
.proghelp = "FRR Management Daemon.",
.signals = mgmt_signals, .n_signals = array_size(mgmt_signals),
.signals = mgmt_signals,
.n_signals = array_size(mgmt_signals),
.privs = &mgmt_privs, .yang_modules = mgmt_yang_modules,
.privs = &mgmt_privs,
.yang_modules = mgmt_yang_modules,
.n_yang_modules = array_size(mgmt_yang_modules),
/* avoid libfrr trying to read our config file for us */
.flags = FRR_MANUAL_VTY_START);
.flags = FRR_MANUAL_VTY_START,
);
/* clang-format on */
#define DEPRECATED_OPTIONS ""

View file

@ -120,15 +120,20 @@ static const struct frr_yang_module_info *const nhrpd_yang_modules[] = {
&frr_vrf_info,
};
FRR_DAEMON_INFO(nhrpd, NHRP, .vty_port = NHRP_VTY_PORT,
/* clang-format off */
FRR_DAEMON_INFO(nhrpd, NHRP,
.vty_port = NHRP_VTY_PORT,
.proghelp = "Implementation of the NHRP routing protocol.",
.signals = sighandlers, .n_signals = array_size(sighandlers),
.signals = sighandlers,
.n_signals = array_size(sighandlers),
.privs = &nhrpd_privs, .yang_modules = nhrpd_yang_modules,
.privs = &nhrpd_privs,
.yang_modules = nhrpd_yang_modules,
.n_yang_modules = array_size(nhrpd_yang_modules),
);
/* clang-format on */
int main(int argc, char **argv)
{

View file

@ -30,9 +30,13 @@
#include "ospf6_zebra.h"
#include "lib/keychain.h"
#define OSPF6D_COMPAT_AUTHSEQ_NAME "%s/ospf6d-at-seq-no.dat", frr_runstatedir
unsigned char conf_debug_ospf6_auth[2];
DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_AUTH_HASH_XOR, "OSPF6 auth hash xor");
static void ospf6_auth_seqno_nvm_update(struct ospf6 *ospf6);
/*Apad is the hexadecimal value 0x878FE1F3. */
const uint8_t ospf6_hash_apad_max[KEYCHAIN_MAX_HASH_SIZE] = {
0x87, 0x8f, 0xe1, 0xf3, 0x87, 0x8f, 0xe1, 0xf3, 0x87, 0x8f, 0xe1,
@ -862,23 +866,11 @@ void install_element_ospf6_clear_intf_auth(void)
install_element(ENABLE_NODE, &clear_ipv6_ospf6_intf_auth_cmd);
}
enum ospf6_auth_err ospf6_auth_nvm_file_exist(void)
{
struct stat buffer;
int exist;
exist = stat(OSPF6_AUTH_SEQ_NUM_FILE, &buffer);
if (exist == 0)
return OSPF6_AUTH_FILE_EXIST;
else
return OSPF6_AUTH_FILE_DO_NOT_EXIST;
}
/*
* Record in non-volatile memory the given ospf6 process,
* authentication trailer higher order sequence number.
*/
void ospf6_auth_seqno_nvm_update(struct ospf6 *ospf6)
static void ospf6_auth_seqno_nvm_update(struct ospf6 *ospf6)
{
const char *inst_name;
json_object *json;
@ -890,9 +882,7 @@ void ospf6_auth_seqno_nvm_update(struct ospf6 *ospf6)
inst_name = ospf6->name ? ospf6->name : VRF_DEFAULT_NAME;
json = json_object_from_file((char *)OSPF6_AUTH_SEQ_NUM_FILE);
if (json == NULL)
json = json_object_new_object();
json = frr_daemon_state_load();
json_object_object_get_ex(json, "instances", &json_instances);
if (!json_instances) {
@ -912,49 +902,82 @@ void ospf6_auth_seqno_nvm_update(struct ospf6 *ospf6)
*/
json_object_int_add(json_instance, "sequence_number", ospf6->seqnum_h);
json_object_to_file_ext((char *)OSPF6_AUTH_SEQ_NUM_FILE, json,
JSON_C_TO_STRING_PRETTY);
json_object_free(json);
frr_daemon_state_save(&json);
}
/*
* Delete authentication sequence number for a given OSPF6 process
* from non-volatile memory.
*/
void ospf6_auth_seqno_nvm_delete(struct ospf6 *ospf6)
__attribute__((unused)) static void
ospf6_auth_seqno_nvm_delete(struct ospf6 *ospf6)
{
const char *inst_name;
json_object *json;
json_object *json_instances;
json_object *json_instance;
zlog_err("Higher order sequence number delete for %s process",
ospf6->name);
inst_name = ospf6->name ? ospf6->name : VRF_DEFAULT_NAME;
json = json_object_from_file((char *)OSPF6_AUTH_SEQ_NUM_FILE);
if (json == NULL)
json = json_object_new_object();
json = frr_daemon_state_load();
json_object_object_get_ex(json, "instances", &json_instances);
if (!json_instances) {
json_instances = json_object_new_object();
json_object_object_add(json, "instances", json_instances);
json_object_put(json);
return;
}
json_object_object_del(json_instances, inst_name);
json_object_object_get_ex(json_instances, inst_name, &json_instance);
if (json_instance) {
json_object_put(json);
return;
}
json_object_to_file_ext((char *)OSPF6_AUTH_SEQ_NUM_FILE, json,
JSON_C_TO_STRING_PRETTY);
json_object_object_del(json_instance, "sequence_number");
frr_daemon_state_save(&json);
}
static struct json_object *ospf6_auth_seqno_compat_read(const char *inst_name)
{
/* try legacy location */
char compat_path[512];
json_object *json;
json_object *json_instances = NULL;
json_object *json_instance = NULL;
json_object *json_seqnum = NULL;
snprintf(compat_path, sizeof(compat_path), OSPF6D_COMPAT_AUTHSEQ_NAME);
json = json_object_from_file(compat_path);
if (json)
json_object_object_get_ex(json, "instances", &json_instances);
if (json_instances)
json_object_object_get_ex(json_instances, inst_name,
&json_instance);
if (json_instance)
json_object_object_get_ex(json_instance, "sequence_number",
&json_seqnum);
if (json_seqnum)
/* => free the file-level object and still return this */
json_seqnum = json_object_get(json_seqnum);
if (json) {
json_object_free(json);
unlink(compat_path);
}
return json_seqnum;
}
/*
* Fetch from non-volatile memory the stored ospf6 process
* authentication sequence number.
*/
void ospf6_auth_seqno_nvm_read(struct ospf6 *ospf6)
static void ospf6_auth_seqno_nvm_read(struct ospf6 *ospf6)
{
const char *inst_name;
json_object *json;
@ -964,9 +987,7 @@ void ospf6_auth_seqno_nvm_read(struct ospf6 *ospf6)
inst_name = ospf6->name ? ospf6->name : VRF_DEFAULT_NAME;
json = json_object_from_file((char *)OSPF6_AUTH_SEQ_NUM_FILE);
if (json == NULL)
json = json_object_new_object();
json = frr_daemon_state_load();
json_object_object_get_ex(json, "instances", &json_instances);
if (!json_instances) {
@ -983,13 +1004,34 @@ void ospf6_auth_seqno_nvm_read(struct ospf6 *ospf6)
json_object_object_get_ex(json_instance, "sequence_number",
&json_seqnum);
if (json_seqnum)
/* cf. reference taken in compat_read above */
json_seqnum = json_object_get(json_seqnum);
else
json_seqnum = ospf6_auth_seqno_compat_read(inst_name);
ospf6->seqnum_l = 0;
if (json_seqnum) {
ospf6->seqnum_h = json_object_get_int(json_seqnum);
ospf6->seqnum_h += 1;
} else {
ospf6->seqnum_h = 0;
}
if (json_seqnum)
json_object_put(json_seqnum);
zlog_err("Higher order sequence number %d read for %s process %s",
ospf6->seqnum_h, ospf6->name, strerror(errno));
json_object_object_del(json_instances, inst_name);
json_object_to_file_ext((char *)OSPF6_AUTH_SEQ_NUM_FILE, json,
JSON_C_TO_STRING_PRETTY);
json_object_free(json);
json_object_object_del(json_instance, "sequence_number");
frr_daemon_state_save(&json);
}
void ospf6_auth_init(struct ospf6 *o)
{
ospf6_auth_seqno_nvm_read(o);
ospf6_auth_seqno_nvm_update(o);
}

View file

@ -48,10 +48,10 @@ enum ospf6_auth_err {
OSPF6_AUTH_VALIDATE_SUCCESS = 0,
OSPF6_AUTH_VALIDATE_FAILURE,
OSPF6_AUTH_PROCESS_NORMAL,
OSPF6_AUTH_FILE_EXIST,
OSPF6_AUTH_FILE_DO_NOT_EXIST
};
void ospf6_auth_init(struct ospf6 *o);
void ospf6_auth_hdr_dump_send(struct ospf6_header *ospfh, uint16_t length);
void ospf6_auth_hdr_dump_recv(struct ospf6_header *ospfh, uint16_t length,
unsigned int lls_len);
@ -73,8 +73,5 @@ void ospf6_auth_digest_send(struct in6_addr *src, struct ospf6_interface *oi,
void install_element_ospf6_debug_auth(void);
int config_write_ospf6_debug_auth(struct vty *vty);
void install_element_ospf6_clear_intf_auth(void);
enum ospf6_auth_err ospf6_auth_nvm_file_exist(void);
void ospf6_auth_seqno_nvm_update(struct ospf6 *ospf6);
void ospf6_auth_seqno_nvm_delete(struct ospf6 *ospf6);
void ospf6_auth_seqno_nvm_read(struct ospf6 *ospf6);
#endif /* __OSPF6_AUTH_TRAILER_H__ */

View file

@ -561,9 +561,7 @@ static void ospf6_gr_nvm_update(struct ospf6 *ospf6, bool prepare)
inst_name = ospf6->name ? ospf6->name : VRF_DEFAULT_NAME;
json = json_object_from_file((char *)OSPF6D_GR_STATE);
if (json == NULL)
json = json_object_new_object();
json = frr_daemon_state_load();
json_object_object_get_ex(json, "instances", &json_instances);
if (!json_instances) {
@ -591,9 +589,7 @@ static void ospf6_gr_nvm_update(struct ospf6 *ospf6, bool prepare)
json_object_int_add(json_instance, "timestamp",
time(NULL) + ospf6->gr_info.grace_period);
json_object_to_file_ext((char *)OSPF6D_GR_STATE, json,
JSON_C_TO_STRING_PRETTY);
json_object_free(json);
frr_daemon_state_save(&json);
}
/*
@ -608,9 +604,7 @@ void ospf6_gr_nvm_delete(struct ospf6 *ospf6)
inst_name = ospf6->name ? ospf6->name : VRF_DEFAULT_NAME;
json = json_object_from_file((char *)OSPF6D_GR_STATE);
if (json == NULL)
json = json_object_new_object();
json = frr_daemon_state_load();
json_object_object_get_ex(json, "instances", &json_instances);
if (!json_instances) {
@ -620,9 +614,7 @@ void ospf6_gr_nvm_delete(struct ospf6 *ospf6)
json_object_object_del(json_instances, inst_name);
json_object_to_file_ext((char *)OSPF6D_GR_STATE, json,
JSON_C_TO_STRING_PRETTY);
json_object_free(json);
frr_daemon_state_save(&json);
}
/*
@ -641,9 +633,7 @@ void ospf6_gr_nvm_read(struct ospf6 *ospf6)
inst_name = ospf6->name ? ospf6->name : VRF_DEFAULT_NAME;
json = json_object_from_file((char *)OSPF6D_GR_STATE);
if (json == NULL)
json = json_object_new_object();
json = frr_daemon_state_load();
json_object_object_get_ex(json, "instances", &json_instances);
if (!json_instances) {
@ -687,11 +677,10 @@ void ospf6_gr_nvm_read(struct ospf6 *ospf6)
ospf6->gr_info.grace_period);
}
json_object_object_del(json_instances, inst_name);
json_object_object_del(json_instance, "gracePeriod");
json_object_object_del(json_instance, "timestamp");
json_object_to_file_ext((char *)OSPF6D_GR_STATE, json,
JSON_C_TO_STRING_PRETTY);
json_object_free(json);
frr_daemon_state_save(&json);
}
void ospf6_gr_unplanned_start_interface(struct ospf6_interface *oi)

View file

@ -38,6 +38,14 @@
/* Default configuration file name for ospf6d. */
#define OSPF6_DEFAULT_CONFIG "ospf6d.conf"
/* GR and auth trailer persistent state */
#define OSPF6D_STATE_NAME "%s/ospf6d.json", frr_libstatedir
#define OSPF6D_COMPAT_STATE_NAME "%s/ospf6d-gr.json", frr_runstatedir
/* for extra confusion, "ospf6d-at-seq-no.dat" is handled directly in
* ospf6_auth_trailer.c; the alternative would be somehow merging JSON which
* is excessive for just supporting a legacy compatibility file location
*/
/* Default port values. */
#define OSPF6_VTY_PORT 2606
@ -166,16 +174,31 @@ static const struct frr_yang_module_info *const ospf6d_yang_modules[] = {
&frr_ospf6_route_map_info,
};
FRR_DAEMON_INFO(ospf6d, OSPF6, .vty_port = OSPF6_VTY_PORT,
/* actual paths filled in main() */
static char state_path[512];
static char state_compat_path[512];
static char *state_paths[] = {
state_path,
state_compat_path,
NULL,
};
/* clang-format off */
FRR_DAEMON_INFO(ospf6d, OSPF6,
.vty_port = OSPF6_VTY_PORT,
.proghelp = "Implementation of the OSPFv3 routing protocol.",
.signals = ospf6_signals,
.n_signals = array_size(ospf6_signals),
.privs = &ospf6d_privs, .yang_modules = ospf6d_yang_modules,
.privs = &ospf6d_privs,
.yang_modules = ospf6d_yang_modules,
.n_yang_modules = array_size(ospf6d_yang_modules),
.state_paths = state_paths,
);
/* clang-format on */
/* Max wait time for config to load before accepting hellos */
#define OSPF6_PRE_CONFIG_MAX_WAIT_SECONDS 600
@ -233,6 +256,10 @@ int main(int argc, char *argv[], char *envp[])
exit(1);
}
snprintf(state_path, sizeof(state_path), OSPF6D_STATE_NAME);
snprintf(state_compat_path, sizeof(state_compat_path),
OSPF6D_COMPAT_STATE_NAME);
/* OSPF6 master init. */
ospf6_master_init(frr_init());

View file

@ -430,17 +430,7 @@ static struct ospf6 *ospf6_create(const char *name)
/* Make ospf protocol socket. */
ospf6_serv_sock(o);
/* If sequence number is stored in persistent storage, read it.
*/
if (ospf6_auth_nvm_file_exist() == OSPF6_AUTH_FILE_EXIST) {
ospf6_auth_seqno_nvm_read(o);
o->seqnum_h = o->seqnum_h + 1;
ospf6_auth_seqno_nvm_update(o);
} else {
o->seqnum_l = o->seqnum_h = 0;
ospf6_auth_seqno_nvm_update(o);
}
ospf6_auth_init(o);
return o;
}

View file

@ -555,21 +555,6 @@ static void ospf_gr_grace_period_expired(struct event *thread)
ospf_gr_restart_exit(ospf, "grace period has expired");
}
/*
* Returns the path of the file (non-volatile memory) that contains GR status
* information.
*/
static char *ospf_gr_nvm_filepath(struct ospf *ospf)
{
static char filepath[MAXPATHLEN];
char instance[16] = "";
if (ospf->instance)
snprintf(instance, sizeof(instance), "-%d", ospf->instance);
snprintf(filepath, sizeof(filepath), OSPFD_GR_STATE, instance);
return filepath;
}
/* Send extra Grace-LSA out the interface (unplanned outages only). */
void ospf_gr_iface_send_grace_lsa(struct event *thread)
{
@ -591,18 +576,14 @@ void ospf_gr_iface_send_grace_lsa(struct event *thread)
*/
static void ospf_gr_nvm_update(struct ospf *ospf, bool prepare)
{
char *filepath;
const char *inst_name;
json_object *json;
json_object *json_instances;
json_object *json_instance;
filepath = ospf_gr_nvm_filepath(ospf);
inst_name = ospf_get_name(ospf);
json = json_object_from_file(filepath);
if (json == NULL)
json = json_object_new_object();
json = frr_daemon_state_load();
json_object_object_get_ex(json, "instances", &json_instances);
if (!json_instances) {
@ -630,8 +611,7 @@ static void ospf_gr_nvm_update(struct ospf *ospf, bool prepare)
json_object_int_add(json_instance, "timestamp",
time(NULL) + ospf->gr_info.grace_period);
json_object_to_file_ext(filepath, json, JSON_C_TO_STRING_PRETTY);
json_object_free(json);
frr_daemon_state_save(&json);
}
/*
@ -640,17 +620,13 @@ static void ospf_gr_nvm_update(struct ospf *ospf, bool prepare)
*/
void ospf_gr_nvm_delete(struct ospf *ospf)
{
char *filepath;
const char *inst_name;
json_object *json;
json_object *json_instances;
filepath = ospf_gr_nvm_filepath(ospf);
inst_name = ospf_get_name(ospf);
json = json_object_from_file(filepath);
if (json == NULL)
json = json_object_new_object();
json = frr_daemon_state_load();
json_object_object_get_ex(json, "instances", &json_instances);
if (!json_instances) {
@ -660,8 +636,7 @@ void ospf_gr_nvm_delete(struct ospf *ospf)
json_object_object_del(json_instances, inst_name);
json_object_to_file_ext(filepath, json, JSON_C_TO_STRING_PRETTY);
json_object_free(json);
frr_daemon_state_save(&json);
}
/*
@ -670,7 +645,6 @@ void ospf_gr_nvm_delete(struct ospf *ospf)
*/
void ospf_gr_nvm_read(struct ospf *ospf)
{
char *filepath;
const char *inst_name;
json_object *json;
json_object *json_instances;
@ -679,12 +653,9 @@ void ospf_gr_nvm_read(struct ospf *ospf)
json_object *json_grace_period;
time_t timestamp = 0;
filepath = ospf_gr_nvm_filepath(ospf);
inst_name = ospf_get_name(ospf);
json = json_object_from_file(filepath);
if (json == NULL)
json = json_object_new_object();
json = frr_daemon_state_load();
json_object_object_get_ex(json, "instances", &json_instances);
if (!json_instances) {
@ -730,8 +701,7 @@ void ospf_gr_nvm_read(struct ospf *ospf)
json_object_object_del(json_instances, inst_name);
json_object_to_file_ext(filepath, json, JSON_C_TO_STRING_PRETTY);
json_object_free(json);
frr_daemon_state_save(&json);
}
void ospf_gr_unplanned_start_interface(struct ospf_interface *oi)

View file

@ -45,6 +45,16 @@
#include "ospfd/ospf_ldp_sync.h"
#include "ospfd/ospf_routemap_nb.h"
#define OSPFD_STATE_NAME "%s/ospfd.json", frr_libstatedir
#define OSPFD_INST_STATE_NAME(i) "%s/ospfd-%d.json", frr_runstatedir, i
/* this one includes the path... because the instance number was in the path
* before :( ... which totally didn't have a mkdir anywhere.
*/
#define OSPFD_COMPAT_STATE_NAME "%s/ospfd-gr.json", frr_libstatedir
#define OSPFD_COMPAT_INST_STATE_NAME(i) \
"%s-%d/ospfd-gr.json", frr_runstatedir, i
/* ospfd privileges */
zebra_capabilities_t _caps_p[] = {ZCAP_NET_RAW, ZCAP_BIND, ZCAP_NET_ADMIN,
ZCAP_SYS_ADMIN};
@ -126,15 +136,31 @@ static const struct frr_yang_module_info *const ospfd_yang_modules[] = {
&frr_ospf_route_map_info,
};
FRR_DAEMON_INFO(ospfd, OSPF, .vty_port = OSPF_VTY_PORT,
/* actual paths filled in main() */
static char state_path[512];
static char state_compat_path[512];
static char *state_paths[] = {
state_path,
state_compat_path,
NULL,
};
/* clang-format off */
FRR_DAEMON_INFO(ospfd, OSPF,
.vty_port = OSPF_VTY_PORT,
.proghelp = "Implementation of the OSPFv2 routing protocol.",
.signals = ospf_signals, .n_signals = array_size(ospf_signals),
.signals = ospf_signals,
.n_signals = array_size(ospf_signals),
.privs = &ospfd_privs, .yang_modules = ospfd_yang_modules,
.privs = &ospfd_privs,
.yang_modules = ospfd_yang_modules,
.n_yang_modules = array_size(ospfd_yang_modules),
.state_paths = state_paths,
);
/* clang-format on */
/** Max wait time for config to load before accepting hellos */
#define OSPF_PRE_CONFIG_MAX_WAIT_SECONDS 600
@ -208,6 +234,17 @@ int main(int argc, char **argv)
exit(1);
}
if (ospf_instance) {
snprintf(state_path, sizeof(state_path),
OSPFD_INST_STATE_NAME(ospf_instance));
snprintf(state_compat_path, sizeof(state_compat_path),
OSPFD_COMPAT_INST_STATE_NAME(ospf_instance));
} else {
snprintf(state_path, sizeof(state_path), OSPFD_STATE_NAME);
snprintf(state_compat_path, sizeof(state_compat_path),
OSPFD_COMPAT_STATE_NAME);
}
/* OSPF master init. */
ospf_master_init(frr_init());

View file

@ -97,15 +97,20 @@ static const struct frr_yang_module_info *pathd_yang_modules[] = {
#define PATH_VTY_PORT 2621
FRR_DAEMON_INFO(pathd, PATH, .vty_port = PATH_VTY_PORT,
/* clang-format off */
FRR_DAEMON_INFO(pathd, PATH,
.vty_port = PATH_VTY_PORT,
.proghelp = "Implementation of PATH.",
.signals = path_signals, .n_signals = array_size(path_signals),
.signals = path_signals,
.n_signals = array_size(path_signals),
.privs = &pathd_privs, .yang_modules = pathd_yang_modules,
.privs = &pathd_privs,
.yang_modules = pathd_yang_modules,
.n_yang_modules = array_size(pathd_yang_modules),
);
/* clang-format on */
int main(int argc, char **argv, char **envp)
{

View file

@ -111,8 +111,9 @@ static const struct frr_yang_module_info *const pbrd_yang_modules[] = {
&frr_vrf_info,
};
FRR_DAEMON_INFO(pbrd, PBR, .vty_port = PBR_VTY_PORT,
/* clang-format off */
FRR_DAEMON_INFO(pbrd, PBR,
.vty_port = PBR_VTY_PORT,
.proghelp = "Implementation of PBR.",
.signals = pbr_signals,
@ -123,6 +124,7 @@ FRR_DAEMON_INFO(pbrd, PBR, .vty_port = PBR_VTY_PORT,
.yang_modules = pbrd_yang_modules,
.n_yang_modules = array_size(pbrd_yang_modules),
);
/* clang-format on */
int main(int argc, char **argv, char **envp)
{

View file

@ -70,17 +70,20 @@ static const struct frr_yang_module_info *const pimd_yang_modules[] = {
&frr_gmp_info,
};
FRR_DAEMON_INFO(pimd, PIM, .vty_port = PIMD_VTY_PORT,
/* clang-format off */
FRR_DAEMON_INFO(pimd, PIM,
.vty_port = PIMD_VTY_PORT,
.proghelp = "Implementation of the PIM routing protocol.",
.signals = pimd_signals,
.n_signals = 4 /* XXX array_size(pimd_signals) XXX*/,
.privs = &pimd_privs, .yang_modules = pimd_yang_modules,
.privs = &pimd_privs,
.yang_modules = pimd_yang_modules,
.n_yang_modules = array_size(pimd_yang_modules),
);
/* clang-format on */
int main(int argc, char **argv, char **envp)
{

View file

@ -16,7 +16,7 @@ fi
name="bgpd"
rcvar=$name
required_files="@sysconfdir@/${name}.conf"
required_files="@e_sysconfdir@/${name}.conf"
command="@prefix@/sbin/${name}"
command_args="-d"

View file

@ -16,7 +16,7 @@ fi
name="eigrpd"
rcvar=$name
required_files="@sysconfdir@/${name}.conf"
required_files="@e_sysconfdir@/${name}.conf"
command="@prefix@/sbin/${name}"
command_args="-d"

View file

@ -16,7 +16,7 @@ fi
name="mgmtd"
rcvar=$name
required_files="@sysconfdir@/${name}.conf"
required_files="@e_sysconfdir@/${name}.conf"
command="@prefix@/sbin/${name}"
command_args="-d"

View file

@ -16,7 +16,7 @@ fi
name="ospf6d"
rcvar=$name
required_files="@sysconfdir@/${name}.conf"
required_files="@e_sysconfdir@/${name}.conf"
command="@prefix@/sbin/${name}"
command_args="-d"

View file

@ -16,7 +16,7 @@ fi
name="ospfd"
rcvar=$name
required_files="@sysconfdir@/${name}.conf"
required_files="@e_sysconfdir@/${name}.conf"
command="@prefix@/sbin/${name}"
command_args="-d"

View file

@ -16,7 +16,7 @@ fi
name="ripd"
rcvar=$name
required_files="@sysconfdir@/${name}.conf"
required_files="@e_sysconfdir@/${name}.conf"
command="@prefix@/sbin/${name}"
command_args="-d"

View file

@ -16,7 +16,7 @@ fi
name="ripngd"
rcvar=$name
required_files="@sysconfdir@/${name}.conf"
required_files="@e_sysconfdir@/${name}.conf"
command="@prefix@/sbin/${name}"
command_args="-d"

View file

@ -16,7 +16,7 @@ fi
name="zebra"
rcvar=$name
required_files="@sysconfdir@/${name}.conf"
required_files="@e_sysconfdir@/${name}.conf"
command="@prefix@/sbin/${name}"
command_args="-d"

View file

@ -42,8 +42,9 @@
%define zeb_docs %{zeb_src}/doc
%define frr_tools %{zeb_src}/tools
# defines for configure
%define rundir %{_localstatedir}/run/%{name}
%if 0%{!?_runstatedir:1}
%define _runstatedir %{_localstatedir}/run
%endif
############################################################################
@ -317,8 +318,8 @@ routing state through standard SNMP MIBs.
%configure \
--sbindir=%{_sbindir} \
--sysconfdir=%{configdir} \
--localstatedir=%{rundir} \
--sysconfdir=%{_sysconfdir} \
--localstatedir=%{_localstatedir} \
--disable-static \
--disable-werror \
--enable-irdp \
@ -471,7 +472,7 @@ install %{zeb_src}/tools/etc/frr/daemons %{buildroot}%{_sysconfdir}/frr
install %{zeb_src}/tools/etc/frr/frr.conf %{buildroot}%{_sysconfdir}/frr/frr.conf.template
install -m644 %{zeb_rh_src}/frr.pam %{buildroot}%{_sysconfdir}/pam.d/frr
install -m644 %{zeb_src}/tools/etc/logrotate.d/frr %{buildroot}%{_sysconfdir}/logrotate.d/frr
install -d -m750 %{buildroot}%{rundir}
install -d -m750 %{buildroot}%{_runstatedir}/frr
%if 0%{?rhel} > 7 || 0%{?fedora} > 29
# avoid `ERROR: ambiguous python shebang in` errors
@ -495,7 +496,7 @@ rm -f %{buildroot}%{_sbindir}/ospfclient.py
getent passwd %{frr_user} >/dev/null || \
useradd -r -u %{frr_uid} -g %{frr_user} \
-s /sbin/nologin -c "FRRouting suite" \
-d %{rundir} %{frr_user}
-d %{_runstatedir}/frr %{frr_user}
%if 0%{?vty_group:1}
usermod -a -G %{vty_group} %{frr_user}
@ -655,11 +656,11 @@ fi
%if 0%{?frr_user:1}
%dir %attr(751,%{frr_user},%{frr_user}) %{configdir}
%dir %attr(755,%{frr_user},%{frr_user}) %{_localstatedir}/log/frr
%dir %attr(751,%{frr_user},%{frr_user}) %{rundir}
%dir %attr(751,%{frr_user},%{frr_user}) %{_runstatedir}/frr
%else
%dir %attr(750,root,root) %{configdir}
%dir %attr(755,root,root) %{_localstatedir}/log/frr
%dir %attr(750,root,root) %{rundir}
%dir %attr(750,root,root) %{_runstatedir}/frr
%endif
%{_infodir}/frr.info.gz
%{_mandir}/man*/*

View file

@ -133,18 +133,23 @@ static const struct frr_yang_module_info *const ripd_yang_modules[] = {
&frr_vrf_info,
};
FRR_DAEMON_INFO(ripd, RIP, .vty_port = RIP_VTY_PORT,
/* clang-format off */
FRR_DAEMON_INFO(ripd, RIP,
.vty_port = RIP_VTY_PORT,
.proghelp = "Implementation of the RIP routing protocol.",
.signals = ripd_signals, .n_signals = array_size(ripd_signals),
.signals = ripd_signals,
.n_signals = array_size(ripd_signals),
.privs = &ripd_privs, .yang_modules = ripd_yang_modules,
.privs = &ripd_privs,
.yang_modules = ripd_yang_modules,
.n_yang_modules = array_size(ripd_yang_modules),
/* mgmtd will load the per-daemon config file now */
.flags = FRR_NO_SPLIT_CONFIG,
);
/* clang-format on */
#define DEPRECATED_OPTIONS ""

View file

@ -127,8 +127,9 @@ static const struct frr_yang_module_info *const ripngd_yang_modules[] = {
&frr_vrf_info,
};
FRR_DAEMON_INFO(ripngd, RIPNG, .vty_port = RIPNG_VTY_PORT,
/* clang-format off */
FRR_DAEMON_INFO(ripngd, RIPNG,
.vty_port = RIPNG_VTY_PORT,
.proghelp = "Implementation of the RIPng routing protocol.",
.signals = ripng_signals,
@ -142,6 +143,7 @@ FRR_DAEMON_INFO(ripngd, RIPNG, .vty_port = RIPNG_VTY_PORT,
/* mgmtd will load the per-daemon config file now */
.flags = FRR_NO_SPLIT_CONFIG,
);
/* clang-format on */
#define DEPRECATED_OPTIONS ""

View file

@ -129,16 +129,20 @@ static const struct frr_yang_module_info *const sharpd_yang_modules[] = {
&frr_vrf_info,
};
FRR_DAEMON_INFO(sharpd, SHARP, .vty_port = SHARP_VTY_PORT,
/* clang-format off */
FRR_DAEMON_INFO(sharpd, SHARP,
.vty_port = SHARP_VTY_PORT,
.proghelp = "Implementation of a Sharp of routes daemon.",
.signals = sharp_signals,
.n_signals = array_size(sharp_signals),
.privs = &sharp_privs, .yang_modules = sharpd_yang_modules,
.privs = &sharp_privs,
.yang_modules = sharpd_yang_modules,
.n_yang_modules = array_size(sharpd_yang_modules),
);
/* clang-format on */
static void sharp_start_configuration(void)
{

View file

@ -381,10 +381,10 @@ parts:
- --enable-vrrpd
- --enable-configfile-mask=0640
- --enable-logfile-mask=0640
- --localstatedir=/var/run
- --sysconfdir=/etc
- --localstatedir=/var
- --sbindir=/sbin
- --bindir=/bin
- --sysconfdir=/etc/frr
- --with-pkg-extra-version=@PACKAGE_EXTRAVERSION@
frr-defaults:
plugin: dump

View file

@ -119,17 +119,22 @@ static const struct frr_yang_module_info *const staticd_yang_modules[] = {
* NOTE: .flags == FRR_NO_SPLIT_CONFIG to avoid reading split config, mgmtd will
* do this for us now
*/
FRR_DAEMON_INFO(staticd, STATIC, .vty_port = STATIC_VTY_PORT,
/* clang-format off */
FRR_DAEMON_INFO(staticd, STATIC,
.vty_port = STATIC_VTY_PORT,
.proghelp = "Implementation of STATIC.",
.signals = static_signals,
.n_signals = array_size(static_signals),
.privs = &static_privs, .yang_modules = staticd_yang_modules,
.privs = &static_privs,
.yang_modules = staticd_yang_modules,
.n_yang_modules = array_size(staticd_yang_modules),
.flags = FRR_NO_SPLIT_CONFIG);
.flags = FRR_NO_SPLIT_CONFIG,
);
/* clang-format on */
int main(int argc, char **argv, char **envp)
{

View file

@ -64,9 +64,9 @@ if [ ! -e Makefile ]; then
--enable-dev-build \
--with-moduledir=/usr/lib/frr/modules \
--prefix=/usr \
--localstatedir=/var/run/frr \
--sysconfdir=/etc \
--localstatedir=/var \
--sbindir=/usr/lib/frr \
--sysconfdir=/etc/frr \
--enable-multipath=0 \
--enable-fpm \
--enable-sharpd \

View file

@ -12,6 +12,7 @@ kinds:
- "./%NAME%:/etc/frr"
- "%RUNDIR%/var.log.frr:/var/log/frr"
- "%RUNDIR%/var.run.frr:/var/run/frr"
- "%RUNDIR%/var.lib.frr:/var/lib/frr"
cap-add:
- SYS_ADMIN
- AUDIT_WRITE

View file

@ -719,6 +719,7 @@ class TopoRouter(TopoGear):
"/etc/frr",
"/etc/snmp",
"/var/run/frr",
"/var/lib/frr",
"/var/log",
]

View file

@ -14,11 +14,11 @@
#
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
B_PATH="@CFG_BIN@"
VTYSH="@vtysh_bin@" # /usr/bin/vtysh
D_PATH="@e_sbindir@" # /usr/lib/frr
C_PATH="@e_frr_sysconfdir@" # /etc/frr
V_PATH="@e_frr_runstatedir@" # /var/run/frr
B_PATH="@e_bindir@"
VTYSH="@e_vtysh_bin@" # /usr/bin/vtysh
FRR_USER="@enable_user@" # frr
FRR_GROUP="@enable_group@" # frr
FRR_VTY_GROUP="@enable_vty_group@" # frrvty

View file

@ -17,10 +17,10 @@ WatchdogSec=60s
RestartSec=5
Restart=always
LimitNOFILE=1024
PIDFile=@CFG_STATE@/watchfrr.pid
ExecStart=@CFG_SBIN@/frrinit.sh start
ExecStop=@CFG_SBIN@/frrinit.sh stop
ExecReload=@CFG_SBIN@/frrinit.sh reload
PIDFile=@e_frr_runstatedir@/watchfrr.pid
ExecStart=@e_sbindir@/frrinit.sh start
ExecStop=@e_sbindir@/frrinit.sh stop
ExecReload=@e_sbindir@/frrinit.sh reload
[Install]
WantedBy=multi-user.target

View file

@ -17,10 +17,10 @@ WatchdogSec=60s
RestartSec=5
Restart=always
LimitNOFILE=1024
PIDFile=@CFG_STATE@/%I/watchfrr.pid
ExecStart=@CFG_SBIN@/frrinit.sh start %I
ExecStop=@CFG_SBIN@/frrinit.sh stop %I
ExecReload=@CFG_SBIN@/frrinit.sh reload %I
PIDFile=@e_frr_runstatedir@/%I/watchfrr.pid
ExecStart=@e_sbindir@/frrinit.sh start %I
ExecStop=@e_sbindir@/frrinit.sh stop %I
ExecReload=@e_sbindir@/frrinit.sh reload %I
[Install]
WantedBy=multi-user.target

View file

@ -14,18 +14,18 @@
# 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
# This script should be installed in @e_sbindir@/frrcommon.sh
# FRR_PATHSPACE is passed in from watchfrr
suffix="${FRR_PATHSPACE:+/${FRR_PATHSPACE}}"
nsopt="${FRR_PATHSPACE:+-N ${FRR_PATHSPACE}}"
PATH=/bin:/usr/bin:/sbin:/usr/sbin
D_PATH="@CFG_SBIN@" # /usr/lib/frr
C_PATH="@CFG_SYSCONF@${suffix}" # /etc/frr
V_PATH="@CFG_STATE@${suffix}" # /var/run/frr
B_PATH="@CFG_BIN@"
VTYSH="@vtysh_bin@" # /usr/bin/vtysh
D_PATH="@e_sbindir@" # /usr/lib/frr
C_PATH="@e_frr_sysconfdir@${suffix}" # /etc/frr
V_PATH="@e_frr_runstatedir@${suffix}" # /var/run/frr
B_PATH="@e_bindir@"
VTYSH="@e_vtysh_bin@" # /usr/bin/vtysh
FRR_USER="@enable_user@" # frr
FRR_GROUP="@enable_group@" # frr
FRR_VTY_GROUP="@enable_vty_group@" # frrvty

View file

@ -37,7 +37,7 @@ self="`dirname $0`"
if [ -r "$self/frrcommon.sh" ]; then
. "$self/frrcommon.sh"
else
. "@CFG_SBIN@/frrcommon.sh"
. "@e_sbindir@/frrcommon.sh"
fi
case "$1" in

View file

@ -5,7 +5,7 @@
# internally by watchfrr to start the protocol daemons with the appropriate
# options.
#
# This script should be installed in @CFG_SBIN@/watchfrr.sh
# This script should be installed in @e_sbindir@/watchfrr.sh
log_success_msg() {
:
@ -27,7 +27,7 @@ self="`dirname $0`"
if [ -r "$self/frrcommon.sh" ]; then
. "$self/frrcommon.sh"
else
. "@CFG_SBIN@/frrcommon.sh"
. "@e_sbindir@/frrcommon.sh"
fi
frrcommon_main "$@"

View file

@ -109,14 +109,20 @@ static const struct frr_yang_module_info *const vrrp_yang_modules[] = {
#define VRRP_VTY_PORT 2619
FRR_DAEMON_INFO(vrrpd, VRRP, .vty_port = VRRP_VTY_PORT,
/* clang-format off */
FRR_DAEMON_INFO(vrrpd, VRRP,
.vty_port = VRRP_VTY_PORT,
.proghelp = "Virtual Router Redundancy Protocol",
.signals = vrrp_signals,
.n_signals = array_size(vrrp_signals),
.privs = &vrrp_privs,
.yang_modules = vrrp_yang_modules,
.n_yang_modules = array_size(vrrp_yang_modules),
);
/* clang-format on */
int main(int argc, char **argv, char **envp)
{

View file

@ -364,8 +364,7 @@ int main(int argc, char **argv, char **env)
strlcpy(sysconfdir, frr_sysconfdir, sizeof(sysconfdir));
frr_init_vtydir();
strlcpy(vtydir, frr_vtydir, sizeof(vtydir));
strlcpy(vtydir, frr_runstatedir, sizeof(vtydir));
/* Option handling. */
while (1) {

View file

@ -32,6 +32,8 @@
#include "watchfrr.h"
#include "watchfrr_errors.h"
#include "lib/config_paths.h"
#ifndef MIN
#define MIN(X,Y) (((X) <= (Y)) ? (X) : (Y))
#endif
@ -120,7 +122,7 @@ static struct global_state {
int numdown; /* # of daemons that are not UP or UNRESPONSIVE */
} gs = {
.phase = PHASE_INIT,
.vtydir = frr_vtydir,
.vtydir = frr_runstatedir,
.period = 1000 * DEFAULT_PERIOD,
.timeout = DEFAULT_TIMEOUT,
.restart_timeout = DEFAULT_RESTART_TIMEOUT,
@ -297,11 +299,11 @@ Otherwise, the interval is doubled (but capped at the -M value).\n\n",
passing command-line arguments with embedded spaces.\n\
-v, --version Print program version\n\
-h, --help Display this help and exit\n",
frr_vtydir, DEFAULT_LOGLEVEL, LOG_EMERG, LOG_DEBUG, LOG_DEBUG,
DEFAULT_MIN_RESTART, DEFAULT_MAX_RESTART,
frr_runstatedir, DEFAULT_LOGLEVEL, LOG_EMERG, LOG_DEBUG,
LOG_DEBUG, DEFAULT_MIN_RESTART, DEFAULT_MAX_RESTART,
DEFAULT_OPERATIONAL_TIMEOUT, DEFAULT_PERIOD, DEFAULT_TIMEOUT,
DEFAULT_RESTART_TIMEOUT, DEFAULT_RESTART_CMD, DEFAULT_START_CMD,
DEFAULT_STOP_CMD, frr_vtydir);
DEFAULT_STOP_CMD, frr_runstatedir);
}
static pid_t run_background(char *shell_cmd)
@ -728,7 +730,7 @@ static void daemon_send_ready(int exitcode)
frr_detach();
snprintf(started, sizeof(started), "%s/%s", frr_vtydir,
snprintf(started, sizeof(started), "%s/%s", frr_runstatedir,
"watchfrr.started");
fp = fopen(started, "w");
if (fp)
@ -1352,10 +1354,10 @@ static struct frr_signal_t watchfrr_signals[] = {
},
};
/* clang-format off */
FRR_DAEMON_INFO(watchfrr, WATCHFRR,
.flags = FRR_NO_PRIVSEP | FRR_NO_TCPVTY | FRR_LIMITED_CLI
| FRR_NO_CFG_PID_DRY | FRR_NO_ZCLIENT
| FRR_DETACH_LATER,
| FRR_NO_CFG_PID_DRY | FRR_NO_ZCLIENT | FRR_DETACH_LATER,
.printhelp = printhelp,
.copyright = "Copyright 2004 Andrew J. Schorr",
@ -1365,6 +1367,7 @@ FRR_DAEMON_INFO(watchfrr, WATCHFRR,
.privs = &watchfrr_privs,
);
/* clang-format on */
#define DEPRECATED_OPTIONS "aAezR:"

View file

@ -18,6 +18,8 @@
#include "watchfrr.h"
#include "lib/config_paths.h"
pid_t integrated_write_pid;
static int integrated_result_fd;

View file

@ -289,19 +289,23 @@ static const struct frr_yang_module_info *const zebra_yang_modules[] = {
};
/* clang-format on */
FRR_DAEMON_INFO(
zebra, ZEBRA, .vty_port = ZEBRA_VTY_PORT, .flags = FRR_NO_ZCLIENT,
/* clang-format off */
FRR_DAEMON_INFO(zebra, ZEBRA,
.vty_port = ZEBRA_VTY_PORT,
.proghelp =
"Daemon which manages kernel routing table management and\nredistribution between different routing protocols.",
.signals = zebra_signals, .n_signals = array_size(zebra_signals),
.flags = FRR_NO_ZCLIENT,
.signals = zebra_signals,
.n_signals = array_size(zebra_signals),
.privs = &zserv_privs,
.yang_modules = zebra_yang_modules,
.n_yang_modules = array_size(zebra_yang_modules),
);
/* clang-format on */
/* Main startup routine. */
int main(int argc, char **argv)