Files
infix/src/netd/configure.ac
T
Joachim Wiberg 221fea13a2 netd: watch conf.d with inotify, retry on backend failure
Two races could prevent DHCP-learned default routes from being installed
at boot:

1. The signal from the DHCP client script could be lost leaving conf.d
   updated but frr.conf stale.

2. Even when the signal was received, 'vtysh -b' could fail because the
   FRR daemon chain (mgmtd→zebra→staticd) writes PID files before being
   fully operational, causing netd to give up with no retry.

Fix both by refactoring netd to use libev:

- Use an inotify watch of CONF_DIR, so netd reacts directly to file
  changes without depending on signal delivery.

- On backend_apply() failure, schedule a retry in 5s and call pidfile()
  unconditionally so dependent services are not blocked waiting for the
  Finit condition 'pid/netd' to be satisfied.

We also take this opportunity to rename /etc/netd/conf.d/ to /etc/net.d/
The extra /etc/netd/ directory level served no purpose — nothing else
lives there.  Flatten to /etc/net.d/ which reads more naturally as the
drop-in directory for network configuration snippets.

Also, reduce logging a bit since each netd backend already logs success
or fail which is sufficient to know that a configuration change has been
applied or not.

Finally, with the new inotify processing in netd it's redundant to call
'initctl reload netd' from the udhcpc script, in fact it will only cause
unnecessary overhead, so we drop it.

Fixes #1438

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-03-12 12:07:49 +01:00

129 lines
3.9 KiB
Plaintext

AC_PREREQ(2.61)
AC_INIT([netd], [1.1.0], [https://github.com/kernelkit/infix/issues])
AM_INIT_AUTOMAKE(1.11 foreign subdir-objects)
AM_SILENT_RULES(yes)
AC_CONFIG_FILES([
Makefile
])
AC_PROG_CC
AC_PROG_CXX
AC_PROG_INSTALL
#
# FRR backend selection
#
AC_ARG_WITH(frr,
AS_HELP_STRING([--with-frr], [Build with FRR gRPC backend]),
[with_frr=$withval],
[with_frr=no])
AC_ARG_WITH(frr-conf,
AS_HELP_STRING([--with-frr-conf], [Build with FRR frr.conf file backend (default when FRR available)]),
[with_frr_conf=$withval],
[with_frr_conf=no])
AC_ARG_WITH(frr-vtysh,
AS_HELP_STRING([--with-frr-vtysh], [Build with FRR vtysh -b backend (incremental config)]),
[with_frr_vtysh=$withval],
[with_frr_vtysh=no])
# Mutual exclusion check
AS_IF([test "x$with_frr" = "xyes" -a "x$with_frr_conf" = "xyes"], [
AC_MSG_ERROR([--with-frr and --with-frr-conf are mutually exclusive])
])
AS_IF([test "x$with_frr" = "xyes" -a "x$with_frr_vtysh" = "xyes"], [
AC_MSG_ERROR([--with-frr and --with-frr-vtysh are mutually exclusive])
])
AS_IF([test "x$with_frr_conf" = "xyes" -a "x$with_frr_vtysh" = "xyes"], [
AC_MSG_ERROR([--with-frr-conf and --with-frr-vtysh are mutually exclusive])
])
AS_IF([test "x$with_frr" = "xyes"], [
# Check for protoc and grpc_cpp_plugin
AC_PATH_PROG([PROTOC], [protoc], [no])
AS_IF([test "x$PROTOC" = "xno"], [
AC_MSG_ERROR([protoc not found, required for FRR gRPC support])
])
AC_PATH_PROG([GRPC_CPP_PLUGIN], [grpc_cpp_plugin], [no])
AS_IF([test "x$GRPC_CPP_PLUGIN" = "xno"], [
AC_MSG_ERROR([grpc_cpp_plugin not found, required for FRR gRPC support])
])
# Check for grpc++ and protobuf libraries
PKG_CHECK_MODULES([grpc], [grpc++ >= 1.16.0])
PKG_CHECK_MODULES([protobuf], [protobuf >= 3.0.0])
AC_DEFINE(HAVE_FRR_GRPC, 1, [Built with FRR gRPC northbound API support])
AC_SUBST(PROTOC)
AC_SUBST(GRPC_CPP_PLUGIN)
])
AS_IF([test "x$with_frr_conf" = "xyes"], [
AC_DEFINE(HAVE_FRR_CONF, 1, [Built with FRR frr.conf file backend])
])
AS_IF([test "x$with_frr_vtysh" = "xyes"], [
AC_DEFINE(HAVE_FRR_VTYSH, 1, [Built with FRR vtysh -b backend])
])
AM_CONDITIONAL(HAVE_FRR_GRPC, [test "x$with_frr" = "xyes"])
AM_CONDITIONAL(HAVE_FRR_CONF, [test "x$with_frr_conf" = "xyes"])
AM_CONDITIONAL(HAVE_FRR_VTYSH, [test "x$with_frr_vtysh" = "xyes"])
# Check for pkg-config first
PKG_PROG_PKG_CONFIG
PKG_CHECK_MODULES([libite], [libite >= 2.6.1])
PKG_CHECK_MODULES([libconfuse], [libconfuse >= 3.0])
PKG_CHECK_MODULES([jansson], [jansson >= 2.0])
AC_CHECK_HEADER([ev.h],
[saved_LIBS="$LIBS"
AC_CHECK_LIB([ev], [ev_loop_new],
[EV_LIBS="-lev"],
[AC_MSG_ERROR("libev not found")])
LIBS="$saved_LIBS"],
[AC_MSG_ERROR("ev.h not found")]
)
AC_SUBST([EV_LIBS])
test "x$prefix" = xNONE && prefix=$ac_default_prefix
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
DATAROOTDIR=`eval echo $datarootdir`
DATAROOTDIR=`eval echo $DATAROOTDIR`
AC_SUBST(DATAROOTDIR)
SYSCONFDIR=`eval echo $sysconfdir`
SYSCONFDIR=`eval echo $SYSCONFDIR`
AC_SUBST(SYSCONFDIR)
RUNSTATEDIR=`eval echo $runstatedir`
RUNSTATEDIR=`eval echo $RUNSTATEDIR`
AC_SUBST(RUNSTATEDIR)
AC_OUTPUT
cat <<EOF
------------------ Summary ------------------
$PACKAGE_NAME version $PACKAGE_VERSION
Prefix................: $prefix
Exec prefix...........: $eprefix
Sysconfdir............: `eval echo $sysconfdir`
Backend...............: $(test "x$with_frr" = "xyes" && echo "FRR gRPC" || (test "x$with_frr_conf" = "xyes" && echo "FRR frr.conf" || (test "x$with_frr_vtysh" = "xyes" && echo "FRR vtysh" || echo "Linux kernel")))
C Compiler............: $CC $CFLAGS $CPPFLAGS $LDFLAGS $LIBS
------------- Compiler version --------------
$($CC --version || true)
---------------------------------------------
Check the above options and compile with:
${MAKE-make}
EOF