diff --git a/Makefile.am b/Makefile.am
index f56e1b8e0b..0ce716e345 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -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@
diff --git a/alpine/APKBUILD.in b/alpine/APKBUILD.in
index 9a29ff3a96..98d3e51452 100644
--- a/alpine/APKBUILD.in
+++ b/alpine/APKBUILD.in
@@ -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 \
diff --git a/babeld/babel_main.c b/babeld/babel_main.c
index 7122d6953b..10ab1b53c3 100644
--- a/babeld/babel_main.c
+++ b/babeld/babel_main.c
@@ -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,18 +125,20 @@ 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.",
+ .vty_port = BABEL_VTY_PORT,
+ .proghelp = "Implementation of the BABEL routing protocol.",
- .signals = babel_signals,
- .n_signals = array_size(babel_signals),
+ .signals = babel_signals,
+ .n_signals = array_size(babel_signals),
- .privs = &babeld_privs,
+ .privs = &babeld_privs,
- .yang_modules = babeld_yang_modules,
- .n_yang_modules = array_size(babeld_yang_modules),
+ .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",
diff --git a/bfdd/bfd.h b/bfdd/bfd.h
index 26bd20b5d7..66bf706808 100644
--- a/bfdd/bfd.h
+++ b/bfdd/bfd.h
@@ -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
diff --git a/bfdd/bfdd.c b/bfdd/bfdd.c
index 71055c32ed..1a89b9b351 100644
--- a/bfdd/bfdd.c
+++ b/bfdd/bfdd.c
@@ -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,
- .proghelp = "Implementation of the BFD protocol.",
- .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 off */
+FRR_DAEMON_INFO(bfdd, BFD,
+ .vty_port = 2617,
+ .proghelp = "Implementation of the BFD protocol.",
+
+ .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();
diff --git a/bfdd/control.c b/bfdd/control.c
index 6ff86f2913..98fd813ef7 100644
--- a/bfdd/control.c
+++ b/bfdd/control.c
@@ -95,11 +95,11 @@ int control_init(const char *path)
mode_t umval;
struct sockaddr_un sun_ = {
.sun_family = AF_UNIX,
- .sun_path = BFDD_CONTROL_SOCKET,
};
- if (path)
- strlcpy(sun_.sun_path, path, sizeof(sun_.sun_path));
+ assert(path);
+
+ strlcpy(sun_.sun_path, path, sizeof(sun_.sun_path));
/* Remove previously created sockets. */
unlink(sun_.sun_path);
diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c
index 1666d654c5..851c4880c3 100644
--- a/bgpd/bgp_main.c
+++ b/bgpd/bgp_main.c
@@ -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.",
- .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,
- .privs = &bgpd_privs, .yang_modules = bgpd_yang_modules,
- .n_yang_modules = array_size(bgpd_yang_modules),
+ .yang_modules = bgpd_yang_modules,
+ .n_yang_modules = array_size(bgpd_yang_modules),
);
+/* clang-format on */
#define DEPRECATED_OPTIONS ""
diff --git a/buildtest.sh b/buildtest.sh
index 4a4a7a0fb5..90ef60ee8b 100755
--- a/buildtest.sh
+++ b/buildtest.sh
@@ -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"
diff --git a/configure.ac b/configure.ac
index 174090d3a9..d902f23d76 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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
diff --git a/debian/frr.postinst b/debian/frr.postinst
index eb9ec67dd9..9c9b4a821c 100644
--- a/debian/frr.postinst
+++ b/debian/frr.postinst
@@ -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.
diff --git a/debian/rules b/debian/rules
index 43e5d7e614..0f84145718 100755
--- a/debian/rules
+++ b/debian/rules
@@ -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 \
diff --git a/doc/developer/building-frr-for-centos6.rst b/doc/developer/building-frr-for-centos6.rst
index fb796e491e..3531162360 100644
--- a/doc/developer/building-frr-for-centos6.rst
+++ b/doc/developer/building-frr-for-centos6.rst
@@ -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 \
diff --git a/doc/developer/building-frr-for-centos7.rst b/doc/developer/building-frr-for-centos7.rst
index e6da830194..eabf515d2e 100644
--- a/doc/developer/building-frr-for-centos7.rst
+++ b/doc/developer/building-frr-for-centos7.rst
@@ -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 \
diff --git a/doc/developer/building-frr-for-centos8.rst b/doc/developer/building-frr-for-centos8.rst
index 6d18e7be93..2d514ead1e 100644
--- a/doc/developer/building-frr-for-centos8.rst
+++ b/doc/developer/building-frr-for-centos8.rst
@@ -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 \
diff --git a/doc/developer/building-frr-for-debian12.rst b/doc/developer/building-frr-for-debian12.rst
index ca882eedbc..06bc18c252 100644
--- a/doc/developer/building-frr-for-debian12.rst
+++ b/doc/developer/building-frr-for-debian12.rst
@@ -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 \
diff --git a/doc/developer/building-frr-for-debian8.rst b/doc/developer/building-frr-for-debian8.rst
index 7071cb660d..fe4eeea601 100644
--- a/doc/developer/building-frr-for-debian8.rst
+++ b/doc/developer/building-frr-for-debian8.rst
@@ -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:
diff --git a/doc/developer/building-frr-for-debian9.rst b/doc/developer/building-frr-for-debian9.rst
index 1b2f1b933a..a590cf7c74 100644
--- a/doc/developer/building-frr-for-debian9.rst
+++ b/doc/developer/building-frr-for-debian9.rst
@@ -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 \
diff --git a/doc/developer/building-frr-for-freebsd10.rst b/doc/developer/building-frr-for-freebsd10.rst
index 707f1e7033..beefb59a27 100644
--- a/doc/developer/building-frr-for-freebsd10.rst
+++ b/doc/developer/building-frr-for-freebsd10.rst
@@ -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 \
diff --git a/doc/developer/building-frr-for-freebsd11.rst b/doc/developer/building-frr-for-freebsd11.rst
index af0b72b16d..7c8fb83cfa 100644
--- a/doc/developer/building-frr-for-freebsd11.rst
+++ b/doc/developer/building-frr-for-freebsd11.rst
@@ -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 \
diff --git a/doc/developer/building-frr-for-freebsd13.rst b/doc/developer/building-frr-for-freebsd13.rst
index 0bc8277930..86506a9dd9 100644
--- a/doc/developer/building-frr-for-freebsd13.rst
+++ b/doc/developer/building-frr-for-freebsd13.rst
@@ -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 \
diff --git a/doc/developer/building-frr-for-freebsd14.rst b/doc/developer/building-frr-for-freebsd14.rst
index 3d1fcacf1b..b3fd37aa10 100644
--- a/doc/developer/building-frr-for-freebsd14.rst
+++ b/doc/developer/building-frr-for-freebsd14.rst
@@ -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 \
diff --git a/doc/developer/building-frr-for-freebsd9.rst b/doc/developer/building-frr-for-freebsd9.rst
index 30332875a0..9f9073d4e2 100644
--- a/doc/developer/building-frr-for-freebsd9.rst
+++ b/doc/developer/building-frr-for-freebsd9.rst
@@ -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 \
diff --git a/doc/developer/building-frr-for-netbsd6.rst b/doc/developer/building-frr-for-netbsd6.rst
index 8958862fea..77c0e008ef 100644
--- a/doc/developer/building-frr-for-netbsd6.rst
+++ b/doc/developer/building-frr-for-netbsd6.rst
@@ -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 \
diff --git a/doc/developer/building-frr-for-netbsd7.rst b/doc/developer/building-frr-for-netbsd7.rst
index e751ba338c..abb04a028b 100644
--- a/doc/developer/building-frr-for-netbsd7.rst
+++ b/doc/developer/building-frr-for-netbsd7.rst
@@ -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 \
diff --git a/doc/developer/building-frr-for-openbsd6.rst b/doc/developer/building-frr-for-openbsd6.rst
index 00bc2e5f09..6d7f346231 100644
--- a/doc/developer/building-frr-for-openbsd6.rst
+++ b/doc/developer/building-frr-for-openbsd6.rst
@@ -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 \
diff --git a/doc/developer/cross-compiling.rst b/doc/developer/cross-compiling.rst
index 3bf78f7633..af99262c4f 100644
--- a/doc/developer/cross-compiling.rst
+++ b/doc/developer/cross-compiling.rst
@@ -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 \
diff --git a/doc/developer/include-compile.rst b/doc/developer/include-compile.rst
index b98d237e68..49fd6c854c 100644
--- a/doc/developer/include-compile.rst
+++ b/doc/developer/include-compile.rst
@@ -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 \
diff --git a/doc/developer/topotests.rst b/doc/developer/topotests.rst
index 2259c7e375..7c65164b0e 100644
--- a/doc/developer/topotests.rst
+++ b/doc/developer/topotests.rst
@@ -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 \
diff --git a/doc/user/bfd.rst b/doc/user/bfd.rst
index 6915885f45..3ca104a3a9 100644
--- a/doc/user/bfd.rst
+++ b/doc/user/bfd.rst
@@ -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
diff --git a/doc/user/installation.rst b/doc/user/installation.rst
index 24c6c223e3..efe4787696 100644
--- a/doc/user/installation.rst
+++ b/doc/user/installation.rst
@@ -394,13 +394,20 @@ options to the configuration script.
.. option:: --sysconfdir
- 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
- 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
+
+ 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
@@ -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 \
...
diff --git a/docker/ubuntu-ci/Dockerfile b/docker/ubuntu-ci/Dockerfile
index 5cdbdb0f3d..9b9b4061ed 100644
--- a/docker/ubuntu-ci/Dockerfile
+++ b/docker/ubuntu-ci/Dockerfile
@@ -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 \
diff --git a/eigrpd/eigrp_main.c b/eigrpd/eigrp_main.c
index 634bf1772e..552ba7cd96 100644
--- a/eigrpd/eigrp_main.c
+++ b/eigrpd/eigrp_main.c
@@ -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.",
- .proghelp = "Implementation of the EIGRP routing protocol.",
+ .signals = eigrp_signals,
+ .n_signals = array_size(eigrp_signals),
- .signals = eigrp_signals,
- .n_signals = array_size(eigrp_signals),
+ .privs = &eigrpd_privs,
- .privs = &eigrpd_privs, .yang_modules = eigrpd_yang_modules,
- .n_yang_modules = array_size(eigrpd_yang_modules),
+ .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)
diff --git a/isisd/isis_main.c b/isisd/isis_main.c
index da4c7bc00a..47e5f6dc93 100644
--- a/isisd/isis_main.c
+++ b/isisd/isis_main.c
@@ -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);
}
+/* 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
-FRR_DAEMON_INFO(fabricd, OPEN_FABRIC, .vty_port = FABRICD_VTY_PORT,
+ fabricd, OPEN_FABRIC,
- .proghelp = "Implementation of the OpenFabric routing protocol.",
+ .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,
- .proghelp = "Implementation of the IS-IS routing protocol.",
+ .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),
+ .signals = isisd_signals,
+ .n_signals = array_size(isisd_signals),
- .privs = &isisd_privs, .yang_modules = isisd_yang_modules,
- .n_yang_modules = array_size(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;
diff --git a/isisd/isisd.c b/isisd/isisd.c
index b1064d8941..772eb9708d 100644
--- a/isisd/isisd.c
+++ b/isisd/isisd.c
@@ -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;
}
diff --git a/ldpd/ldp.h b/ldpd/ldp.h
index 33cf93cb26..1f0fdb560f 100644
--- a/ldpd/ldp.h
+++ b/ldpd/ldp.h
@@ -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
diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c
index a4d45d9c8d..0d66fc70e7 100644
--- a/ldpd/ldpd.c
+++ b/ldpd/ldpd.c
@@ -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));
diff --git a/lib/.gitignore b/lib/.gitignore
index 5d38469ca2..1c9314bf0d 100644
--- a/lib/.gitignore
+++ b/lib/.gitignore
@@ -1,3 +1,4 @@
+/config_paths.h
/version.c
/version.h
/gitversion.h
diff --git a/lib/command.c b/lib/command.c
index becba8452b..fa260721dc 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -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;
diff --git a/lib/config_paths.h.in b/lib/config_paths.h.in
new file mode 100644
index 0000000000..cc40905632
--- /dev/null
+++ b/lib/config_paths.h.in
@@ -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@"
diff --git a/lib/libfrr.c b/lib/libfrr.c
index d38b4ec4c0..d904f6f8bb 100644
--- a/lib/libfrr.c
+++ b/lib/libfrr.c
@@ -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;
diff --git a/lib/libfrr.h b/lib/libfrr.h
index b260a54dfe..27b877da18 100644
--- a/lib/libfrr.h
+++ b/lib/libfrr.h
@@ -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[];
diff --git a/lib/mgmt_be_client.c b/lib/mgmt_be_client.c
index d50dd03fdc..458623844a 100644
--- a/lib/mgmt_be_client.c
+++ b/lib/mgmt_be_client.c
@@ -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,
diff --git a/lib/mgmt_defines.h b/lib/mgmt_defines.h
index 3b7f8f1ef6..b02341ea4e 100644
--- a/lib/mgmt_defines.h
+++ b/lib/mgmt_defines.h
@@ -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
diff --git a/lib/mgmt_fe_client.c b/lib/mgmt_fe_client.c
index 57ac071ecf..92619f4f7f 100644
--- a/lib/mgmt_fe_client.c
+++ b/lib/mgmt_fe_client.c
@@ -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,
diff --git a/lib/vty.c b/lib/vty.c
index a8d90d901b..a6b4de579a 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -46,6 +46,8 @@
#include
#include
+#include "lib/config_paths.h"
+
#include "lib/vty_clippy.c"
DEFINE_MTYPE_STATIC(LIB, VTY, "VTY");
diff --git a/lib/yang.c b/lib/yang.c
index ed855c8498..b6884619d9 100644
--- a/lib/yang.c
+++ b/lib/yang.c
@@ -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");
diff --git a/m4/.gitignore b/m4/.gitignore
index 63f9fa78ed..37888dd46c 100644
--- a/m4/.gitignore
+++ b/m4/.gitignore
@@ -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
diff --git a/m4/ax_recursive_eval.m4 b/m4/ax_recursive_eval.m4
new file mode 100644
index 0000000000..02836025f7
--- /dev/null
+++ b/m4/ax_recursive_eval.m4
@@ -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
+# Copyright (c) 2024 David Lamparter
+
+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")`])
diff --git a/mgmtd/mgmt_be_adapter.c b/mgmtd/mgmt_be_adapter.c
index 2ebbe255d0..6754657500 100644
--- a/mgmtd/mgmt_be_adapter.c
+++ b/mgmtd/mgmt_be_adapter.c
@@ -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);
}
diff --git a/mgmtd/mgmt_ds.h b/mgmtd/mgmt_ds.h
index ca08e37dac..b8e77e330a 100644
--- a/mgmtd/mgmt_ds.h
+++ b/mgmtd/mgmt_ds.h
@@ -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;
diff --git a/mgmtd/mgmt_fe_adapter.c b/mgmtd/mgmt_fe_adapter.c
index ff85f56e3e..a99d92d2b6 100644
--- a/mgmtd/mgmt_fe_adapter.c
+++ b/mgmtd/mgmt_fe_adapter.c
@@ -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);
}
diff --git a/mgmtd/mgmt_history.c b/mgmtd/mgmt_history.c
index ddc5a1844e..c97cb7f0fd 100644
--- a/mgmtd/mgmt_history.c
+++ b/mgmtd/mgmt_history.c
@@ -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))
- return false;
+ snprintf(index_path, sizeof(index_path), MGMTD_COMMIT_INDEX_FILE_PATH);
- fp = fopen(MGMTD_COMMIT_INDEX_FILE_NAME, "rb");
+ fp = fopen(index_path, "rb");
if (!fp) {
- zlog_err("Failed to open commit history %s for reading: %s",
- MGMTD_COMMIT_INDEX_FILE_NAME, safe_strerror(errno));
+ if (errno == ENOENT || errno == ENOTDIR)
+ return false;
+
+ 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;
diff --git a/mgmtd/mgmt_main.c b/mgmtd/mgmt_main.c
index 1bb1299444..100f574b34 100644
--- a/mgmtd/mgmt_main.c
+++ b/mgmtd/mgmt_main.c
@@ -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.",
- .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,
- .privs = &mgmt_privs, .yang_modules = mgmt_yang_modules,
- .n_yang_modules = array_size(mgmt_yang_modules),
+ .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);
+ /* avoid libfrr trying to read our config file for us */
+ .flags = FRR_MANUAL_VTY_START,
+);
+/* clang-format on */
#define DEPRECATED_OPTIONS ""
diff --git a/nhrpd/nhrp_main.c b/nhrpd/nhrp_main.c
index 983a03282b..adb8be36d3 100644
--- a/nhrpd/nhrp_main.c
+++ b/nhrpd/nhrp_main.c
@@ -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.",
- .proghelp = "Implementation of the NHRP routing protocol.",
+ .signals = sighandlers,
+ .n_signals = array_size(sighandlers),
- .signals = sighandlers, .n_signals = array_size(sighandlers),
+ .privs = &nhrpd_privs,
- .privs = &nhrpd_privs, .yang_modules = nhrpd_yang_modules,
- .n_yang_modules = array_size(nhrpd_yang_modules),
+ .yang_modules = nhrpd_yang_modules,
+ .n_yang_modules = array_size(nhrpd_yang_modules),
);
+/* clang-format on */
int main(int argc, char **argv)
{
diff --git a/ospf6d/ospf6_auth_trailer.c b/ospf6d/ospf6_auth_trailer.c
index 54b951654a..8d9eff409e 100644
--- a/ospf6d/ospf6_auth_trailer.c
+++ b/ospf6d/ospf6_auth_trailer.c
@@ -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_free(json);
+ 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);
- ospf6->seqnum_h = json_object_get_int(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);
}
diff --git a/ospf6d/ospf6_auth_trailer.h b/ospf6d/ospf6_auth_trailer.h
index 3f82a7b197..9073ae47dd 100644
--- a/ospf6d/ospf6_auth_trailer.h
+++ b/ospf6d/ospf6_auth_trailer.h
@@ -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__ */
diff --git a/ospf6d/ospf6_gr.c b/ospf6d/ospf6_gr.c
index 69230e572b..34cb9706bd 100644
--- a/ospf6d/ospf6_gr.c
+++ b/ospf6d/ospf6_gr.c
@@ -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)
diff --git a/ospf6d/ospf6_main.c b/ospf6d/ospf6_main.c
index b61c8f9a5f..6449d68453 100644
--- a/ospf6d/ospf6_main.c
+++ b/ospf6d/ospf6_main.c
@@ -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,
+};
- .proghelp = "Implementation of the OSPFv3 routing protocol.",
+/* 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),
+ .signals = ospf6_signals,
+ .n_signals = array_size(ospf6_signals),
- .privs = &ospf6d_privs, .yang_modules = ospf6d_yang_modules,
- .n_yang_modules = array_size(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());
diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c
index 63672a96e7..a3fb205374 100644
--- a/ospf6d/ospf6_top.c
+++ b/ospf6d/ospf6_top.c
@@ -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;
}
diff --git a/ospfd/ospf_gr.c b/ospfd/ospf_gr.c
index c23c42052f..0a4d579fc9 100644
--- a/ospfd/ospf_gr.c
+++ b/ospfd/ospf_gr.c
@@ -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)
diff --git a/ospfd/ospf_main.c b/ospfd/ospf_main.c
index a2a1c4a94f..6a4a9a1481 100644
--- a/ospfd/ospf_main.c
+++ b/ospfd/ospf_main.c
@@ -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,
+};
- .proghelp = "Implementation of the OSPFv2 routing protocol.",
+/* 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,
- .n_yang_modules = array_size(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());
diff --git a/pathd/path_main.c b/pathd/path_main.c
index c333162f2b..c3409522e2 100644
--- a/pathd/path_main.c
+++ b/pathd/path_main.c
@@ -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.",
- .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,
- .privs = &pathd_privs, .yang_modules = pathd_yang_modules,
- .n_yang_modules = array_size(pathd_yang_modules),
+ .yang_modules = pathd_yang_modules,
+ .n_yang_modules = array_size(pathd_yang_modules),
);
+/* clang-format on */
int main(int argc, char **argv, char **envp)
{
diff --git a/pbrd/pbr_main.c b/pbrd/pbr_main.c
index dd4893bb78..8cddf87a27 100644
--- a/pbrd/pbr_main.c
+++ b/pbrd/pbr_main.c
@@ -111,18 +111,20 @@ 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.",
- .proghelp = "Implementation of PBR.",
+ .signals = pbr_signals,
+ .n_signals = array_size(pbr_signals),
- .signals = pbr_signals,
- .n_signals = array_size(pbr_signals),
+ .privs = &pbr_privs,
- .privs = &pbr_privs,
-
- .yang_modules = pbrd_yang_modules,
- .n_yang_modules = array_size(pbrd_yang_modules),
+ .yang_modules = pbrd_yang_modules,
+ .n_yang_modules = array_size(pbrd_yang_modules),
);
+/* clang-format on */
int main(int argc, char **argv, char **envp)
{
diff --git a/pimd/pim_main.c b/pimd/pim_main.c
index 7db0a7676b..400db396c2 100644
--- a/pimd/pim_main.c
+++ b/pimd/pim_main.c
@@ -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.",
- .proghelp = "Implementation of the PIM routing protocol.",
+ .signals = pimd_signals,
+ .n_signals = 4 /* XXX array_size(pimd_signals) XXX*/,
- .signals = pimd_signals,
- .n_signals = 4 /* XXX array_size(pimd_signals) XXX*/,
+ .privs = &pimd_privs,
- .privs = &pimd_privs, .yang_modules = pimd_yang_modules,
- .n_yang_modules = array_size(pimd_yang_modules),
+ .yang_modules = pimd_yang_modules,
+ .n_yang_modules = array_size(pimd_yang_modules),
);
-
+/* clang-format on */
int main(int argc, char **argv, char **envp)
{
diff --git a/pkgsrc/bgpd.sh.in b/pkgsrc/bgpd.sh.in
index d234b5435c..a8ba7c68f0 100644
--- a/pkgsrc/bgpd.sh.in
+++ b/pkgsrc/bgpd.sh.in
@@ -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"
diff --git a/pkgsrc/eigrpd.sh.in b/pkgsrc/eigrpd.sh.in
index b28b81eeda..dd8caf87fa 100644
--- a/pkgsrc/eigrpd.sh.in
+++ b/pkgsrc/eigrpd.sh.in
@@ -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"
diff --git a/pkgsrc/mgmtd.sh.in b/pkgsrc/mgmtd.sh.in
index fb57c0a2fb..313633a782 100644
--- a/pkgsrc/mgmtd.sh.in
+++ b/pkgsrc/mgmtd.sh.in
@@ -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"
diff --git a/pkgsrc/ospf6d.sh.in b/pkgsrc/ospf6d.sh.in
index 3fbdb81b7f..c9854ed793 100644
--- a/pkgsrc/ospf6d.sh.in
+++ b/pkgsrc/ospf6d.sh.in
@@ -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"
diff --git a/pkgsrc/ospfd.sh.in b/pkgsrc/ospfd.sh.in
index daa2252091..07dee55574 100644
--- a/pkgsrc/ospfd.sh.in
+++ b/pkgsrc/ospfd.sh.in
@@ -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"
diff --git a/pkgsrc/ripd.sh.in b/pkgsrc/ripd.sh.in
index 31575419fc..6c9b580a31 100644
--- a/pkgsrc/ripd.sh.in
+++ b/pkgsrc/ripd.sh.in
@@ -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"
diff --git a/pkgsrc/ripngd.sh.in b/pkgsrc/ripngd.sh.in
index d06ac90b02..d316d46014 100644
--- a/pkgsrc/ripngd.sh.in
+++ b/pkgsrc/ripngd.sh.in
@@ -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"
diff --git a/pkgsrc/zebra.sh.in b/pkgsrc/zebra.sh.in
index c2f12a7833..7a24106782 100644
--- a/pkgsrc/zebra.sh.in
+++ b/pkgsrc/zebra.sh.in
@@ -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"
diff --git a/redhat/frr.spec.in b/redhat/frr.spec.in
index c2391206b7..83c881a14b 100644
--- a/redhat/frr.spec.in
+++ b/redhat/frr.spec.in
@@ -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*/*
diff --git a/ripd/rip_main.c b/ripd/rip_main.c
index c86caabaf1..845c5078a5 100644
--- a/ripd/rip_main.c
+++ b/ripd/rip_main.c
@@ -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.",
- .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,
- .privs = &ripd_privs, .yang_modules = ripd_yang_modules,
- .n_yang_modules = array_size(ripd_yang_modules),
+ .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,
+ /* mgmtd will load the per-daemon config file now */
+ .flags = FRR_NO_SPLIT_CONFIG,
);
+/* clang-format on */
#define DEPRECATED_OPTIONS ""
diff --git a/ripngd/ripng_main.c b/ripngd/ripng_main.c
index 80b78a150a..ada9ad4e78 100644
--- a/ripngd/ripng_main.c
+++ b/ripngd/ripng_main.c
@@ -127,21 +127,23 @@ 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.",
- .proghelp = "Implementation of the RIPng routing protocol.",
+ .signals = ripng_signals,
+ .n_signals = array_size(ripng_signals),
- .signals = ripng_signals,
- .n_signals = array_size(ripng_signals),
+ .privs = &ripngd_privs,
- .privs = &ripngd_privs,
+ .yang_modules = ripngd_yang_modules,
+ .n_yang_modules = array_size(ripngd_yang_modules),
- .yang_modules = ripngd_yang_modules,
- .n_yang_modules = array_size(ripngd_yang_modules),
-
- /* mgmtd will load the per-daemon config file now */
- .flags = FRR_NO_SPLIT_CONFIG,
+ /* mgmtd will load the per-daemon config file now */
+ .flags = FRR_NO_SPLIT_CONFIG,
);
+/* clang-format on */
#define DEPRECATED_OPTIONS ""
diff --git a/sharpd/sharp_main.c b/sharpd/sharp_main.c
index 1eba9037ae..57948388b2 100644
--- a/sharpd/sharp_main.c
+++ b/sharpd/sharp_main.c
@@ -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.",
- .proghelp = "Implementation of a Sharp of routes daemon.",
+ .signals = sharp_signals,
+ .n_signals = array_size(sharp_signals),
- .signals = sharp_signals,
- .n_signals = array_size(sharp_signals),
+ .privs = &sharp_privs,
- .privs = &sharp_privs, .yang_modules = sharpd_yang_modules,
- .n_yang_modules = array_size(sharpd_yang_modules),
+ .yang_modules = sharpd_yang_modules,
+ .n_yang_modules = array_size(sharpd_yang_modules),
);
+/* clang-format on */
static void sharp_start_configuration(void)
{
diff --git a/snapcraft/snapcraft.yaml.in b/snapcraft/snapcraft.yaml.in
index 607cbc7fe3..84f3136e06 100644
--- a/snapcraft/snapcraft.yaml.in
+++ b/snapcraft/snapcraft.yaml.in
@@ -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
diff --git a/staticd/static_main.c b/staticd/static_main.c
index b2f5ec4952..1953701fbb 100644
--- a/staticd/static_main.c
+++ b/staticd/static_main.c
@@ -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.",
- .proghelp = "Implementation of STATIC.",
+ .signals = static_signals,
+ .n_signals = array_size(static_signals),
- .signals = static_signals,
- .n_signals = array_size(static_signals),
+ .privs = &static_privs,
- .privs = &static_privs, .yang_modules = staticd_yang_modules,
- .n_yang_modules = array_size(staticd_yang_modules),
+ .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)
{
diff --git a/tests/topotests/docker/inner/compile_frr.sh b/tests/topotests/docker/inner/compile_frr.sh
index 3b296a1497..4a88dc677f 100755
--- a/tests/topotests/docker/inner/compile_frr.sh
+++ b/tests/topotests/docker/inner/compile_frr.sh
@@ -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 \
diff --git a/tests/topotests/kinds.yaml b/tests/topotests/kinds.yaml
index 127790ed07..5f4b61d4b7 100644
--- a/tests/topotests/kinds.yaml
+++ b/tests/topotests/kinds.yaml
@@ -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
diff --git a/tests/topotests/lib/topogen.py b/tests/topotests/lib/topogen.py
index 7b06f3d127..155d2d0986 100644
--- a/tests/topotests/lib/topogen.py
+++ b/tests/topotests/lib/topogen.py
@@ -719,6 +719,7 @@ class TopoRouter(TopoGear):
"/etc/frr",
"/etc/snmp",
"/var/run/frr",
+ "/var/lib/frr",
"/var/log",
]
diff --git a/tools/frr.in b/tools/frr.in
index cd24a96054..94c15d5de3 100755
--- a/tools/frr.in
+++ b/tools/frr.in
@@ -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
diff --git a/tools/frr.service.in b/tools/frr.service.in
index 1e958dd93e..b52ee3f425 100644
--- a/tools/frr.service.in
+++ b/tools/frr.service.in
@@ -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
diff --git a/tools/frr@.service.in b/tools/frr@.service.in
index 85408a0cc7..c8a2d3ba83 100644
--- a/tools/frr@.service.in
+++ b/tools/frr@.service.in
@@ -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
diff --git a/tools/frrcommon.sh.in b/tools/frrcommon.sh.in
index 00b63a78e2..44d41956b3 100755
--- a/tools/frrcommon.sh.in
+++ b/tools/frrcommon.sh.in
@@ -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
diff --git a/tools/frrinit.sh.in b/tools/frrinit.sh.in
index 428d57c55b..178d18d437 100644
--- a/tools/frrinit.sh.in
+++ b/tools/frrinit.sh.in
@@ -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
diff --git a/tools/watchfrr.sh.in b/tools/watchfrr.sh.in
index 712f962a0a..31279f6db1 100644
--- a/tools/watchfrr.sh.in
+++ b/tools/watchfrr.sh.in
@@ -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 "$@"
diff --git a/vrrpd/vrrp_main.c b/vrrpd/vrrp_main.c
index 5245c74689..7f859ca6d2 100644
--- a/vrrpd/vrrp_main.c
+++ b/vrrpd/vrrp_main.c
@@ -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,
- .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 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)
{
diff --git a/vtysh/vtysh_main.c b/vtysh/vtysh_main.c
index 6065776f11..b1299780db 100644
--- a/vtysh/vtysh_main.c
+++ b/vtysh/vtysh_main.c
@@ -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) {
diff --git a/watchfrr/watchfrr.c b/watchfrr/watchfrr.c
index 707e01f4ef..acc612c0a8 100644
--- a/watchfrr/watchfrr.c
+++ b/watchfrr/watchfrr.c
@@ -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,19 +1354,20 @@ 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,
+ .flags = FRR_NO_PRIVSEP | FRR_NO_TCPVTY | FRR_LIMITED_CLI
+ | FRR_NO_CFG_PID_DRY | FRR_NO_ZCLIENT | FRR_DETACH_LATER,
- .printhelp = printhelp,
- .copyright = "Copyright 2004 Andrew J. Schorr",
+ .printhelp = printhelp,
+ .copyright = "Copyright 2004 Andrew J. Schorr",
- .signals = watchfrr_signals,
- .n_signals = array_size(watchfrr_signals),
+ .signals = watchfrr_signals,
+ .n_signals = array_size(watchfrr_signals),
- .privs = &watchfrr_privs,
+ .privs = &watchfrr_privs,
);
+/* clang-format on */
#define DEPRECATED_OPTIONS "aAezR:"
diff --git a/watchfrr/watchfrr_vty.c b/watchfrr/watchfrr_vty.c
index 0547c1e8b3..95a7962ec6 100644
--- a/watchfrr/watchfrr_vty.c
+++ b/watchfrr/watchfrr_vty.c
@@ -18,6 +18,8 @@
#include "watchfrr.h"
+#include "lib/config_paths.h"
+
pid_t integrated_write_pid;
static int integrated_result_fd;
diff --git a/zebra/main.c b/zebra/main.c
index f3e4bf50d5..47aef46cac 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -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)