diff options
| author | Donald Sharp <donaldsharp72@gmail.com> | 2024-01-28 14:30:28 -0500 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-01-28 14:30:28 -0500 | 
| commit | 259e3d4dac2da37b9abad9f84e41f90c81325a60 (patch) | |
| tree | 33292e442296b1b4a04b7753e3055706bfd6c7e5 | |
| parent | 4d92badcde7573b97d2acc2228d0ca5fe7168e1e (diff) | |
| parent | bbd858935fad9a469b5b339948e1215b347b05c0 (diff) | |
Merge pull request #15243 from opensourcerouting/autoconf-dir-mess
*: fix a pile of directory and/or state retention related issues
92 files changed, 933 insertions, 540 deletions
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]) - -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]) +AC_DEFUN([AX_SUBST_EXPANDED], [ +  AX_RECURSIVE_EVAL([[$]$1], [e_$1]) +  AC_SUBST([e_$1]) +]) + +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 <dir> -   Look for configuration files in `dir` [`prefix`/etc]. Note that sample -   configuration files will be installed here. +   Look for configuration files in `dir`/frr [`prefix`/etc]. Note that sample +   configuration files will be installed here.  Should be ``/etc`` unless +   your platform splits package configuration locations.  .. option:: --localstatedir <dir> -   Configure zebra to use `dir` for local state files, such as pid files and -   unix sockets. +   Configure base directory for local state.  Indirectly controls +   ``--runstatedir``.  Should be ``/var`` in most cases. + +.. option:: --runstatedir <dir> + +   Configure FRR to use `dir`/frr for local state files, such as pid files and +   unix sockets.  Should be ``/var/run`` (default through ``--localstatedir``) +   or ``/run`` in most cases.  .. option:: --with-scriptdir <dir> @@ -579,9 +586,9 @@ the options you chose:     ./configure \         --prefix=/usr \ -       --localstatedir=/var/run/frr \ +       --sysconfdir=/etc \ +       --localstatedir=/var \         --sbindir=/usr/lib/frr \ -       --sysconfdir=/etc/frr \         --enable-pimd \         --enable-watchfrr \         ... 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 @@ -3346,35 +3346,19 @@ 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, @@ -46,6 +46,8 @@  #include <arpa/telnet.h>  #include <termios.h> +#include "lib/config_paths.h" +  #include "lib/vty_clippy.c"  DEFINE_MTYPE_STATIC(LIB, VTY, "VTY"); 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 <adl@gnu.org> +#   Copyright (c) 2024 David Lamparter <equinox@opensourcerouting.org> + +AC_DEFUN([AX_RECURSIVE_EVAL], +[_lcl_receval="$1" +$2=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" +     test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" +     _lcl_receval_old='' +     for _rec_limit in 1 2 3 4 5 6 7 8 9 10; do +       test "[$]_lcl_receval_old" = "[$]_lcl_receval" && break +       _lcl_receval_old="[$]_lcl_receval" +       eval _lcl_receval="\"[$]_lcl_receval\"" +     done +     echo "[$]_lcl_receval")`]) 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_get_ex(json_instances, inst_name, &json_instance); +	if (json_instance) { +		json_object_put(json); +		return;  	} -	json_object_object_del(json_instances, inst_name); +	json_object_object_del(json_instance, "sequence_number"); -	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);  } +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, +}; + +/* 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), -		.proghelp = "Implementation of the OSPFv3 routing protocol.", +	.privs = &ospf6d_privs, -		.signals = ospf6_signals, -		.n_signals = array_size(ospf6_signals), +	.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, +}; + +/* 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), -		.proghelp = "Implementation of the OSPFv2 routing protocol.", +	.privs = &ospfd_privs, -		.signals = ospf_signals, .n_signals = array_size(ospf_signals), +	.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)  | 
