From fd4f183d166dd87f1b4b45577944c6e52f16110f Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Thu, 13 Apr 2023 21:59:39 +0200 Subject: [PATCH 01/36] confd: Allow usage of asprintf --- src/confd/configure.ac | 4 ++++ src/confd/lib/asprintf.c | 18 ++++++++++++++++++ src/confd/lib/vasprintf.c | 25 +++++++++++++++++++++++++ src/confd/src/Makefile.am | 2 +- src/confd/src/core.h | 6 ++++++ 5 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 src/confd/lib/asprintf.c create mode 100644 src/confd/lib/vasprintf.c diff --git a/src/confd/configure.ac b/src/confd/configure.ac index fe2923ee6..110e15a05 100644 --- a/src/confd/configure.ac +++ b/src/confd/configure.ac @@ -15,6 +15,10 @@ AC_CONFIG_FILES([ AC_PROG_CC AC_PROG_INSTALL +AC_CONFIG_LIBOBJ_DIR(lib) +AC_REPLACE_FUNCS(vasprintf) +AC_REPLACE_FUNCS(asprintf) + # Check for pkg-config first, warn if it's not installed PKG_PROG_PKG_CONFIG diff --git a/src/confd/lib/asprintf.c b/src/confd/lib/asprintf.c new file mode 100644 index 000000000..18b4fe34f --- /dev/null +++ b/src/confd/lib/asprintf.c @@ -0,0 +1,18 @@ +#include +#include +#include + +#ifndef HAVE_VASPRINTF +int vasprintf(char **strp, const char *fmt, va_list ap); +#endif + +int asprintf(char **strp, const char *fmt, ...) +{ + va_list ap; + int len; + + va_start(ap, fmt); + len = vasprintf(strp, fmt, ap); + va_end(ap); + return len; +} diff --git a/src/confd/lib/vasprintf.c b/src/confd/lib/vasprintf.c new file mode 100644 index 000000000..b79bdfc11 --- /dev/null +++ b/src/confd/lib/vasprintf.c @@ -0,0 +1,25 @@ +#include +#include +#include + +int vasprintf(char **strp, const char *fmt, va_list ap) +{ + va_list apdup; + char *str; + int len; + + va_copy(apdup, ap); + len = vsnprintf(0, 0, fmt, apdup); + va_end(apdup); + + if (len < 0) + return -1; + + len++; + str = malloc(len); + if (!str) + return -1; + + *strp = str; + return vsnprintf(str, len, fmt, ap); +} diff --git a/src/confd/src/Makefile.am b/src/confd/src/Makefile.am index 49083c9a0..6813923fa 100644 --- a/src/confd/src/Makefile.am +++ b/src/confd/src/Makefile.am @@ -1,5 +1,5 @@ CFLAGS = -Wall -Wextra -Werror -Wno-unused-parameter -AM_CPPFLAGS = -D_DEFAULT_SOURCE -D_XOPEN_SOURCE -DYANG_PATH_=\"$(YANGDIR)/\" +AM_CPPFLAGS = -D_DEFAULT_SOURCE -D_XOPEN_SOURCE -D_GNU_SOURCE -DYANG_PATH_=\"$(YANGDIR)/\" plugindir = $(srpdplugindir) plugin_LTLIBRARIES = confd-plugin.la diff --git a/src/confd/src/core.h b/src/confd/src/core.h index 4dd130fcf..cbe9d517d 100644 --- a/src/confd/src/core.h +++ b/src/confd/src/core.h @@ -17,6 +17,12 @@ #include #include +#ifndef HAVE_VASPRINTF +int vasprintf(char **strp, const char *fmt, va_list ap); +#endif +#ifndef HAVE_ASPRINTF +int asprintf(char **strp, const char *fmt, ...); +#endif #define NELEMS(arr) (sizeof(arr) / sizeof(arr[0])) From 6a168b9589a7b194d0bd9653affb762f6a498d08 Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Thu, 13 Apr 2023 22:01:24 +0200 Subject: [PATCH 02/36] confd: Add helper to ensure that required modules are loaded Unfortunately, sysrepo considers it an error to load a module that is already loaded, ruling out using `sr_install_modules`. Therefore, provide `require_modules` instead, which ensures that a given set of modules are loaded, or loads them otherwise. --- src/confd/src/Makefile.am | 2 +- src/confd/src/sr_ext.c | 60 +++++++++++++++++++++++++++++++++++++++ src/confd/src/sr_ext.h | 18 ++++++++++++ 3 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 src/confd/src/sr_ext.c create mode 100644 src/confd/src/sr_ext.h diff --git a/src/confd/src/Makefile.am b/src/confd/src/Makefile.am index 6813923fa..393e56934 100644 --- a/src/confd/src/Makefile.am +++ b/src/confd/src/Makefile.am @@ -7,4 +7,4 @@ plugin_LTLIBRARIES = confd-plugin.la confd_plugin_la_CFLAGS = $(augeas_CFLAGS) $(sysrepo_CFLAGS) $(CFLAGS) confd_plugin_la_LIBADD = $(augeas_LIBS) $(sysrepo_LIBS) confd_plugin_la_LDFLAGS = -module -avoid-version -shared -confd_plugin_la_SOURCES = core.c core.h run.c ietf-system.c ietf-interfaces.c +confd_plugin_la_SOURCES = core.c core.h run.c sr_ext.c sr_ext.h ietf-system.c ietf-interfaces.c diff --git a/src/confd/src/sr_ext.c b/src/confd/src/sr_ext.c new file mode 100644 index 000000000..4def500f1 --- /dev/null +++ b/src/confd/src/sr_ext.c @@ -0,0 +1,60 @@ +#include + +#include "sr_ext.h" + +sr_error_t srx_require_module(sr_conn_ctx_t *conn, + const struct srx_module_requirement *mr) +{ + sr_error_t err = SR_ERR_OK; + const struct ly_ctx *ly; + struct lys_module *mod; + const char **f; + char *path; + + ly = sr_acquire_context(conn); + if (!ly) + return SR_ERR_INVAL_ARG; + + mod = ly_ctx_get_module(ly, mr->name, mr->rev); + sr_release_context(conn); + + if (mod && mod->implemented) { + if (!mr->features) + return SR_ERR_OK; + + for (f = mr->features; *f; f++) { + switch (lys_feature_value(mod, *f)) { + case LY_SUCCESS: + continue; + case LY_ENOT: + err = sr_enable_module_feature(conn, mr->name, *f); + if (err) + return err; + break; + default: + return SR_ERR_UNSUPPORTED; + } + } + } else { + /* `search_dirs` argument is ignored by sysrepo 2.2.60, + * so we supply the full path instead. + */ + asprintf(&path, "%s/%s%s%s.yang", mr->dir ? : "", mr->name, + mr->rev ? "@" : "", mr->rev ? : ""); + err = sr_install_module(conn, path, NULL, mr->features); + free(path); + } + + return err; +} + +sr_error_t srx_require_modules(sr_conn_ctx_t *conn, + const struct srx_module_requirement *mrs) +{ + sr_error_t err = SR_ERR_OK; + + for (; mrs->name && !err; mrs++) + err = srx_require_module(conn, mrs); + + return err; +} diff --git a/src/confd/src/sr_ext.h b/src/confd/src/sr_ext.h new file mode 100644 index 000000000..71731f29d --- /dev/null +++ b/src/confd/src/sr_ext.h @@ -0,0 +1,18 @@ +#ifndef CONFD_SR_EXT_H_ +#define CONFD_SR_EXT_H_ + +#include + +struct srx_module_requirement { + const char *dir; + const char *name; + const char *rev; + const char **features; +}; + +sr_error_t srx_require_module(sr_conn_ctx_t *conn, + const struct srx_module_requirement *mr); +sr_error_t srx_require_modules(sr_conn_ctx_t *conn, + const struct srx_module_requirement *mrs); + +#endif /* CONFD_SR_EXT_H_ */ From f6454e2c9eea29db6436c97d7c3da5cee258d77a Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Thu, 13 Apr 2023 22:04:23 +0200 Subject: [PATCH 03/36] confd: if: Ensure that the required modules are loaded --- src/confd/src/ietf-interfaces.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/confd/src/ietf-interfaces.c b/src/confd/src/ietf-interfaces.c index d2052a4b8..5c3d2a528 100644 --- a/src/confd/src/ietf-interfaces.c +++ b/src/confd/src/ietf-interfaces.c @@ -1,8 +1,28 @@ /* SPDX-License-Identifier: BSD-3-Clause */ #include "core.h" +#include "sr_ext.h" + +const struct srx_module_requirement ietf_if_reqs[] = { + { .dir = YANG_PATH_, .name = "ietf-interfaces", .rev = "2018-02-20" }, + { .dir = YANG_PATH_, .name = "iana-if-type", .rev = "2023-01-26" }, + { .dir = YANG_PATH_, .name = "ietf-ip", .rev = "2018-02-22" }, + + { NULL } +}; int ietf_interfaces_init(struct confd *confd) { + int err; + + err = srx_require_modules(confd->conn, ietf_if_reqs); + if (err) + goto err; + return SR_ERR_OK; +err: + ERROR("init failed: %s", sr_strerror(err)); + sr_unsubscribe(confd->sub); + + return err; } From 025a877e51ab9c345ee75913afbc5c4b66e4706d Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Fri, 14 Apr 2023 14:43:22 +0200 Subject: [PATCH 04/36] src/confd: minor, fix iana-if-type revision Signed-off-by: Joachim Wiberg --- src/confd/src/ietf-interfaces.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/confd/src/ietf-interfaces.c b/src/confd/src/ietf-interfaces.c index 5c3d2a528..f6ce9cbb9 100644 --- a/src/confd/src/ietf-interfaces.c +++ b/src/confd/src/ietf-interfaces.c @@ -5,7 +5,7 @@ const struct srx_module_requirement ietf_if_reqs[] = { { .dir = YANG_PATH_, .name = "ietf-interfaces", .rev = "2018-02-20" }, - { .dir = YANG_PATH_, .name = "iana-if-type", .rev = "2023-01-26" }, + { .dir = YANG_PATH_, .name = "iana-if-type", .rev = "2017-01-19" }, { .dir = YANG_PATH_, .name = "ietf-ip", .rev = "2018-02-22" }, { NULL } From 81faceccd14684a4fa03b12928e3ee854fcda3d9 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Fri, 14 Apr 2023 14:44:18 +0200 Subject: [PATCH 05/36] src/confd: minor, use more common fmt rather than frmt Signed-off-by: Joachim Wiberg --- src/confd/src/core.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/confd/src/core.h b/src/confd/src/core.h index cbe9d517d..49c5fbbbf 100644 --- a/src/confd/src/core.h +++ b/src/confd/src/core.h @@ -26,10 +26,10 @@ int asprintf(char **strp, const char *fmt, ...); #define NELEMS(arr) (sizeof(arr) / sizeof(arr[0])) -#define DEBUG(frmt, ...) -//#define DEBUG(frmt, ...) syslog(LOG_DEBUG, "%s: "frmt, __func__, ##__VA_ARGS__) -#define ERROR(frmt, ...) syslog(LOG_ERR, "%s: " frmt, __func__, ##__VA_ARGS__) -#define ERRNO(frmt, ...) syslog(LOG_ERR, "%s: " frmt ": %s", __func__, ##__VA_ARGS__, strerror(errno)) +#define DEBUG(fmt, ...) +//#define DEBUG(fmt, ...) syslog(LOG_DEBUG, "%s: "fmt, __func__, ##__VA_ARGS__) +#define ERROR(fmt, ...) syslog(LOG_ERR, "%s: " fmt, __func__, ##__VA_ARGS__) +#define ERRNO(fmt, ...) syslog(LOG_ERR, "%s: " fmt ": %s", __func__, ##__VA_ARGS__, strerror(errno)) static inline void print_val(sr_val_t *val) { From 5aa07b104e8378f5d072596715cd0d7b87545650 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Fri, 14 Apr 2023 14:45:46 +0200 Subject: [PATCH 06/36] src/confd: add SPDX license identifier to new files Signed-off-by: Joachim Wiberg --- src/confd/src/core.h | 1 + src/confd/src/sr_ext.c | 2 ++ src/confd/src/sr_ext.h | 2 ++ 3 files changed, 5 insertions(+) diff --git a/src/confd/src/core.h b/src/confd/src/core.h index 49c5fbbbf..3f78c72f1 100644 --- a/src/confd/src/core.h +++ b/src/confd/src/core.h @@ -1,4 +1,5 @@ /* SPDX-License-Identifier: BSD-3-Clause */ + #ifndef CONFD_CORE_H_ #define CONFD_CORE_H_ diff --git a/src/confd/src/sr_ext.c b/src/confd/src/sr_ext.c index 4def500f1..597b73076 100644 --- a/src/confd/src/sr_ext.c +++ b/src/confd/src/sr_ext.c @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + #include #include "sr_ext.h" diff --git a/src/confd/src/sr_ext.h b/src/confd/src/sr_ext.h index 71731f29d..a544e209d 100644 --- a/src/confd/src/sr_ext.h +++ b/src/confd/src/sr_ext.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + #ifndef CONFD_SR_EXT_H_ #define CONFD_SR_EXT_H_ From 4386a50e3a2a2c741c053ccd5b35a5c785554731 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Fri, 14 Apr 2023 14:47:15 +0200 Subject: [PATCH 07/36] src/confd: minor, drop trailing / from YANG_PATH_ Prevent // in new srx_require_module() when composing module PATH. Signed-off-by: Joachim Wiberg --- src/confd/src/Makefile.am | 2 +- src/confd/src/core.c | 2 +- src/confd/src/ietf-system.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/confd/src/Makefile.am b/src/confd/src/Makefile.am index 393e56934..685e6e437 100644 --- a/src/confd/src/Makefile.am +++ b/src/confd/src/Makefile.am @@ -1,5 +1,5 @@ CFLAGS = -Wall -Wextra -Werror -Wno-unused-parameter -AM_CPPFLAGS = -D_DEFAULT_SOURCE -D_XOPEN_SOURCE -D_GNU_SOURCE -DYANG_PATH_=\"$(YANGDIR)/\" +AM_CPPFLAGS = -D_DEFAULT_SOURCE -D_XOPEN_SOURCE -D_GNU_SOURCE -DYANG_PATH_=\"$(YANGDIR)\" plugindir = $(srpdplugindir) plugin_LTLIBRARIES = confd-plugin.la diff --git a/src/confd/src/core.c b/src/confd/src/core.c index 8c2708aa7..b3a0a952e 100644 --- a/src/confd/src/core.c +++ b/src/confd/src/core.c @@ -70,7 +70,7 @@ int sr_plugin_init_cb(sr_session_ctx_t *session, void **priv) goto err; } - rc = sr_install_module(confd.conn, YANG_PATH_"kernelkit-infix-deviations.yang", NULL, NULL); + rc = sr_install_module(confd.conn, YANG_PATH_"/kernelkit-infix-deviations.yang", NULL, NULL); if (rc) goto err; diff --git a/src/confd/src/ietf-system.c b/src/confd/src/ietf-system.c index 7c7841c42..7ba1003e3 100644 --- a/src/confd/src/ietf-system.c +++ b/src/confd/src/ietf-system.c @@ -758,11 +758,11 @@ int ietf_system_init(struct confd *confd) goto err; } - rc = sr_install_module(confd->conn, YANG_PATH_"ietf-system@2014-08-06.yang", NULL, features); + rc = sr_install_module(confd->conn, YANG_PATH_"/ietf-system@2014-08-06.yang", NULL, features); if (rc) goto err; /* Augment to ietf-systems */ - rc = sr_install_module(confd->conn, YANG_PATH_"infix-system@2014-08-06.yang", NULL, NULL); + rc = sr_install_module(confd->conn, YANG_PATH_"/infix-system@2014-08-06.yang", NULL, NULL); if (rc) goto err; From 2b2c440a97e714b9d574e8bd3e05049d71688e15 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Fri, 14 Apr 2023 14:48:28 +0200 Subject: [PATCH 08/36] src/confd: add missing header Signed-off-by: Joachim Wiberg --- src/confd/src/sr_ext.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/confd/src/sr_ext.c b/src/confd/src/sr_ext.c index 597b73076..25dfc196e 100644 --- a/src/confd/src/sr_ext.c +++ b/src/confd/src/sr_ext.c @@ -2,6 +2,7 @@ #include +#include "core.h" #include "sr_ext.h" sr_error_t srx_require_module(sr_conn_ctx_t *conn, From 58d3c448ac5c15decb5c394af33c9e464723db13 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Fri, 14 Apr 2023 14:49:05 +0200 Subject: [PATCH 09/36] src/confd: refactor helper fns to new namespace Signed-off-by: Joachim Wiberg --- src/confd/src/Makefile.am | 3 ++- src/confd/src/ietf-system.c | 50 +++++++------------------------------ src/confd/src/srx_val.c | 37 +++++++++++++++++++++++++++ src/confd/src/srx_val.h | 11 ++++++++ 4 files changed, 59 insertions(+), 42 deletions(-) create mode 100644 src/confd/src/srx_val.c create mode 100644 src/confd/src/srx_val.h diff --git a/src/confd/src/Makefile.am b/src/confd/src/Makefile.am index 685e6e437..489e49828 100644 --- a/src/confd/src/Makefile.am +++ b/src/confd/src/Makefile.am @@ -7,4 +7,5 @@ plugin_LTLIBRARIES = confd-plugin.la confd_plugin_la_CFLAGS = $(augeas_CFLAGS) $(sysrepo_CFLAGS) $(CFLAGS) confd_plugin_la_LIBADD = $(augeas_LIBS) $(sysrepo_LIBS) confd_plugin_la_LDFLAGS = -module -avoid-version -shared -confd_plugin_la_SOURCES = core.c core.h run.c sr_ext.c sr_ext.h ietf-system.c ietf-interfaces.c +confd_plugin_la_SOURCES = core.c core.h run.c sr_ext.c sr_ext.h srx_val.c srx_val.h \ + ietf-system.c ietf-interfaces.c diff --git a/src/confd/src/ietf-system.c b/src/confd/src/ietf-system.c index 7ba1003e3..45733b86e 100644 --- a/src/confd/src/ietf-system.c +++ b/src/confd/src/ietf-system.c @@ -1,6 +1,8 @@ /* SPDX-License-Identifier: BSD-3-Clause */ #include "core.h" +#include "srx_val.h" + #include #include #include @@ -339,40 +341,6 @@ int sr_get_bool(sr_session_ctx_t *session, const char *fmt, ...) return rc; } -char *sr_get_str(sr_session_ctx_t *session, const char *fmt, ...) -{ - char *str = NULL; - sr_val_t *val; - char *xpath; - va_list ap; - int len; - - va_start(ap, fmt); - len = vsnprintf(NULL, 0, fmt, ap) + 1; - va_end(ap); - - xpath = alloca(len); - if (!xpath) - return NULL; - - va_start(ap, fmt); - vsnprintf(xpath, len, fmt, ap); - va_end(ap); - - if (sr_get_item(session, xpath, 0, &val)) { - ERROR("Failed reading string value from xpath %s", xpath); - goto fail; - } - if (!val || val->type != SR_STRING_T) - goto fail; - - str = strdup(val->data.string_val); -fail: - if (val) - sr_free_val(val); - return str; -} - #define TIMEZONE_CONF "/etc/timezone" #define TIMEZONE_PREV TIMEZONE_CONF "-" #define TIMEZONE_NEXT TIMEZONE_CONF "+" @@ -413,7 +381,7 @@ static int change_clock(sr_session_ctx_t *session, uint32_t sub_id, const char * } /* XXX: add support also for /ietf-system:system/clock/timezone-utc-offset (deviation) */ - timezone = sr_get_str(session, "/ietf-system:system/clock/timezone-name"); + timezone = srx_get_str(session, "/ietf-system:system/clock/timezone-name"); if (!timezone) { ERROR("Failed reading timezone-name"); return SR_ERR_VALIDATION_FAILED; @@ -510,16 +478,16 @@ static int change_ntp(sr_session_ctx_t *session, uint32_t sub_id, const char *mo valid = 0; /* Get /ietf-system:system/ntp/server[name='foo'] */ - ptr = sr_get_str(session, "%s/udp/address", xpath); + ptr = srx_get_str(session, "%s/udp/address", xpath); if (ptr) { - type = sr_get_str(session, "%s/association-type", xpath); + type = srx_get_str(session, "%s/association-type", xpath); fprintf(fp, "%s %s", type ?: "server", ptr); server++; if (type) free(type); free(ptr); - ptr = sr_get_str(session, "%s/udp/port", xpath); + ptr = srx_get_str(session, "%s/udp/port", xpath); if (ptr) { fprintf(fp, " port %s", ptr); free(ptr); @@ -636,7 +604,7 @@ static int change_dns(sr_session_ctx_t *session, uint32_t sub_id, const char *mo char *ptr; /* Get /ietf-system:system/dns-resolver/server[name='foo'] */ - ptr = sr_get_str(session, "%s/udp-and-tcp/address", xpath); + ptr = srx_get_str(session, "%s/udp-and-tcp/address", xpath); if (ptr) /* XXX: add support also for udp-and-tcp/port */ fprintf(fp, "nameserver %s\n", ptr); @@ -666,7 +634,7 @@ static int change_motd(sr_session_ctx_t *session, uint32_t sub_id, const char *m if (!fp) return SR_ERR_SYS; - nm = sr_get_str(session, xpath); + nm = srx_get_str(session, xpath); if (nm) { fprintf(fp, "%s\n", nm); } else { @@ -691,7 +659,7 @@ static int change_hostname(sr_session_ctx_t *session, uint32_t sub_id, const cha if (event != SR_EV_DONE) return SR_ERR_OK; - nm = sr_get_str(session, xpath); + nm = srx_get_str(session, xpath); if (!nm) { /* XXX: derive from global "options.h" or /usr/share/factory/ */ nm = strdup("infix"); diff --git a/src/confd/src/srx_val.c b/src/confd/src/srx_val.c new file mode 100644 index 000000000..00091d9f3 --- /dev/null +++ b/src/confd/src/srx_val.c @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#include "core.h" + +char *srx_get_str(sr_session_ctx_t *session, const char *fmt, ...) +{ + char *str = NULL; + sr_val_t *val; + char *xpath; + va_list ap; + int len; + + va_start(ap, fmt); + len = vsnprintf(NULL, 0, fmt, ap) + 1; + va_end(ap); + + xpath = alloca(len); + if (!xpath) + return NULL; + + va_start(ap, fmt); + vsnprintf(xpath, len, fmt, ap); + va_end(ap); + + if (sr_get_item(session, xpath, 0, &val)) { + ERROR("Failed reading string value from xpath %s", xpath); + goto fail; + } + if (!val || val->type != SR_STRING_T) + goto fail; + + str = strdup(val->data.string_val); +fail: + if (val) + sr_free_val(val); + return str; +} diff --git a/src/confd/src/srx_val.h b/src/confd/src/srx_val.h new file mode 100644 index 000000000..ae57aea10 --- /dev/null +++ b/src/confd/src/srx_val.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#ifndef CONFD_SRX_VAL_H_ +#define CONFD_SRX_VAL_H_ + + +#include "core.h" + +char *srx_get_str(sr_session_ctx_t *session, const char *fmt, ...); + +#endif /* CONFD_SRX_VAL_H_ */ From 030b0b1b617548644eee3fd96af1be44bb78d1b2 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Fri, 14 Apr 2023 14:50:29 +0200 Subject: [PATCH 10/36] src/confd: minor, rename local var for consistency Signed-off-by: Joachim Wiberg --- src/confd/src/ietf-interfaces.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/confd/src/ietf-interfaces.c b/src/confd/src/ietf-interfaces.c index f6ce9cbb9..f189c1dc1 100644 --- a/src/confd/src/ietf-interfaces.c +++ b/src/confd/src/ietf-interfaces.c @@ -13,16 +13,16 @@ const struct srx_module_requirement ietf_if_reqs[] = { int ietf_interfaces_init(struct confd *confd) { - int err; + int rc; - err = srx_require_modules(confd->conn, ietf_if_reqs); - if (err) + rc = srx_require_modules(confd->conn, ietf_if_reqs); + if (rc) goto err; return SR_ERR_OK; err: - ERROR("init failed: %s", sr_strerror(err)); + ERROR("init failed: %s", sr_strerror(rc)); sr_unsubscribe(confd->sub); - return err; + return rc; } From da29f0b2a1132b037dfee5f71adfd5b2f639ad26 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Fri, 14 Apr 2023 16:15:11 +0200 Subject: [PATCH 11/36] src/confd: unlock -lite API, e.g. fopenf(), systemf(), etc. Signed-off-by: Joachim Wiberg --- src/confd/configure.ac | 3 ++- src/confd/src/Makefile.am | 4 ++-- src/confd/src/core.h | 3 +-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/confd/configure.ac b/src/confd/configure.ac index 110e15a05..e3d46a948 100644 --- a/src/confd/configure.ac +++ b/src/confd/configure.ac @@ -22,9 +22,10 @@ AC_REPLACE_FUNCS(asprintf) # Check for pkg-config first, warn if it's not installed PKG_PROG_PKG_CONFIG -PKG_CHECK_MODULES([sysrepo], [sysrepo >= 2.2.36]) PKG_CHECK_MODULES([augeas], [augeas >= 1.12.0]) PKG_CHECK_MODULES([jansson], [jansson >= 2.0.0]) +PKG_CHECK_MODULES([libite], [libite >= 2.5.0]) +PKG_CHECK_MODULES([sysrepo], [sysrepo >= 2.2.36]) # Plugin installation path for sysrepo-plugind PKG_CHECK_VAR([srpdplugindir], [sysrepo], [SRPD_PLUGINS_PATH]) diff --git a/src/confd/src/Makefile.am b/src/confd/src/Makefile.am index 489e49828..9a2178df0 100644 --- a/src/confd/src/Makefile.am +++ b/src/confd/src/Makefile.am @@ -4,8 +4,8 @@ AM_CPPFLAGS = -D_DEFAULT_SOURCE -D_XOPEN_SOURCE -D_GNU_SOURCE -DYANG plugindir = $(srpdplugindir) plugin_LTLIBRARIES = confd-plugin.la -confd_plugin_la_CFLAGS = $(augeas_CFLAGS) $(sysrepo_CFLAGS) $(CFLAGS) -confd_plugin_la_LIBADD = $(augeas_LIBS) $(sysrepo_LIBS) +confd_plugin_la_CFLAGS = $(augeas_CFLAGS) $(libite_CFLAGS) $(sysrepo_CFLAGS) $(CFLAGS) +confd_plugin_la_LIBADD = $(augeas_LIBS) $(libite_LIBS) $(sysrepo_LIBS) confd_plugin_la_LDFLAGS = -module -avoid-version -shared confd_plugin_la_SOURCES = core.c core.h run.c sr_ext.c sr_ext.h srx_val.c srx_val.h \ ietf-system.c ietf-interfaces.c diff --git a/src/confd/src/core.h b/src/confd/src/core.h index 3f78c72f1..3872a99fc 100644 --- a/src/confd/src/core.h +++ b/src/confd/src/core.h @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -25,8 +26,6 @@ int vasprintf(char **strp, const char *fmt, va_list ap); int asprintf(char **strp, const char *fmt, ...); #endif -#define NELEMS(arr) (sizeof(arr) / sizeof(arr[0])) - #define DEBUG(fmt, ...) //#define DEBUG(fmt, ...) syslog(LOG_DEBUG, "%s: "fmt, __func__, ##__VA_ARGS__) #define ERROR(fmt, ...) syslog(LOG_ERR, "%s: " fmt, __func__, ##__VA_ARGS__) From e6a014d64ad560938c1ee48056b83fb2a8a4a7a7 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Fri, 14 Apr 2023 16:24:35 +0200 Subject: [PATCH 12/36] src/confd: replace local run() function with systemf() from libite It started its life as a copy of systemf() anyway, time to clean up. Signed-off-by: Joachim Wiberg --- src/confd/src/Makefile.am | 2 +- src/confd/src/core.c | 2 +- src/confd/src/core.h | 4 --- src/confd/src/ietf-system.c | 16 ++++++------ src/confd/src/run.c | 52 ------------------------------------- 5 files changed, 10 insertions(+), 66 deletions(-) delete mode 100644 src/confd/src/run.c diff --git a/src/confd/src/Makefile.am b/src/confd/src/Makefile.am index 9a2178df0..fca460b99 100644 --- a/src/confd/src/Makefile.am +++ b/src/confd/src/Makefile.am @@ -7,5 +7,5 @@ plugin_LTLIBRARIES = confd-plugin.la confd_plugin_la_CFLAGS = $(augeas_CFLAGS) $(libite_CFLAGS) $(sysrepo_CFLAGS) $(CFLAGS) confd_plugin_la_LIBADD = $(augeas_LIBS) $(libite_LIBS) $(sysrepo_LIBS) confd_plugin_la_LDFLAGS = -module -avoid-version -shared -confd_plugin_la_SOURCES = core.c core.h run.c sr_ext.c sr_ext.h srx_val.c srx_val.h \ +confd_plugin_la_SOURCES = core.c core.h sr_ext.c sr_ext.h srx_val.c srx_val.h \ ietf-system.c ietf-interfaces.c diff --git a/src/confd/src/core.c b/src/confd/src/core.c index b3a0a952e..042bd943e 100644 --- a/src/confd/src/core.c +++ b/src/confd/src/core.c @@ -7,7 +7,7 @@ static struct confd confd; static int startup_save_hook(sr_session_ctx_t *session, uint32_t sub_id, const char *module, const char *xpath, sr_event_t event, unsigned request_id, void *priv) { - if (run("sysrepocfg -X/cfg/startup-config.cfg -d startup -f json")) + if (systemf("sysrepocfg -X/cfg/startup-config.cfg -d startup -f json")) return SR_ERR_SYS; return SR_ERR_OK; diff --git a/src/confd/src/core.h b/src/confd/src/core.h index 3872a99fc..457261508 100644 --- a/src/confd/src/core.h +++ b/src/confd/src/core.h @@ -75,10 +75,6 @@ static inline int register_rpc(sr_session_ctx_t *session, const char *xpath, return rc; } - -/* core.c */ -int run(const char *fmt, ...); - /* ietf-interfaces.c */ int ietf_interfaces_init(struct confd *confd); diff --git a/src/confd/src/ietf-system.c b/src/confd/src/ietf-system.c index 45733b86e..2630f5f2b 100644 --- a/src/confd/src/ietf-system.c +++ b/src/confd/src/ietf-system.c @@ -189,7 +189,7 @@ static int rpc_exec(sr_session_ctx_t *session, uint32_t sub_id, const char *path { DEBUG("path: %s", path); - if (run(priv)) + if (systemf(priv)) return SR_ERR_INTERNAL; return SR_ERR_OK; @@ -248,7 +248,7 @@ static int rpc_set_datetime(sr_session_ctx_t *session, uint32_t sub_id, static int sys_reload_services(void) { - return run("initctl -nbq touch sysklogd lldpd"); + return systemf("initctl -nbq touch sysklogd lldpd"); } int sr_get_int(sr_session_ctx_t *session, const char *fmt, ...) @@ -388,7 +388,7 @@ static int change_clock(sr_session_ctx_t *session, uint32_t sub_id, const char * } remove("/etc/localtime+"); - if (run("ln -s /usr/share/zoneinfo/%s /etc/localtime+", timezone)) { + if (systemf("ln -s /usr/share/zoneinfo/%s /etc/localtime+", timezone)) { ERROR("No such timezone %s", timezone); return SR_ERR_VALIDATION_FAILED; } @@ -437,15 +437,15 @@ static int change_ntp(sr_session_ctx_t *session, uint32_t sub_id, const char *mo rename(CHRONY_CONF, CHRONY_PREV); rename(CHRONY_NEXT, CHRONY_CONF); if (!sr_get_bool(session, "/ietf-system:system/ntp/enabled")) { - run("initctl -nbq disable chronyd"); + systemf("initctl -nbq disable chronyd"); return SR_ERR_OK; } /* * If chrony is alrady enabled we tell Finit it's been * modified , so Finit restarts it, otherwise enable it. */ - run("initctl -nbq touch chronyd"); - run("initctl -nbq enable chronyd"); + systemf("initctl -nbq touch chronyd"); + systemf("initctl -nbq enable chronyd"); return SR_ERR_OK; default: @@ -555,10 +555,10 @@ static int change_dns(sr_session_ctx_t *session, uint32_t sub_id, const char *mo rename(RESOLV_NEXT, RESOLV_CONF); /* in bootstrap, another resolvconf will soon take your call */ - if (run("initctl cond get hook/sys/up")) + if (systemf("initctl cond get hook/sys/up")) return 0; - run("resolvconf -u"); + systemf("resolvconf -u"); return SR_ERR_OK; default: diff --git a/src/confd/src/run.c b/src/confd/src/run.c deleted file mode 100644 index 1a809c681..000000000 --- a/src/confd/src/run.c +++ /dev/null @@ -1,52 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ - -#include "core.h" - -/** - * Like system(), but takes a formatted string as argument. - * @param fmt printf style format list to command to run - * - * This system() wrapper greatly simplifies operations that usually - * consist of composing a command from parts into a dynamic buffer - * before calling it. The return value from system() is also parsed, - * checking for proper exit and signals. - * - * @returns If the command exits normally, the return code of the command - * is returned. Otherwise, if the command is signalled, the return code - * is -1 and @a errno is set to @c EINTR. - */ -int run(const char *fmt, ...) -{ - va_list ap; - char *cmd; - int len; - int rc; - - va_start(ap, fmt); - len = vsnprintf(NULL, 0, fmt, ap); - va_end(ap); - - cmd = alloca(++len); - if (!cmd) { - errno = ENOMEM; - return -1; - } - - va_start(ap, fmt); - vsnprintf(cmd, len, fmt, ap); - va_end(ap); - - rc = system(cmd); - if (rc == -1) - return -1; - - if (WIFEXITED(rc)) { - errno = 0; - rc = WEXITSTATUS(rc); - } else if (WIFSIGNALED(rc)) { - errno = EINTR; - rc = -1; - } - - return rc; -} From 9af0bf398a62f4d81ad99705b464649004ec1a0f Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Fri, 14 Apr 2023 16:25:46 +0200 Subject: [PATCH 13/36] src/confd: refactor sr_get_bool() into srx_get_bool() Note: new API, srx_get_bool() returns -1 on error, leaving 0 and 1 as false and true, respectively. Signed-off-by: Joachim Wiberg --- src/confd/src/ietf-system.c | 38 ++-------------------- src/confd/src/srx_val.c | 65 +++++++++++++++++++++++++++---------- src/confd/src/srx_val.h | 3 +- 3 files changed, 53 insertions(+), 53 deletions(-) diff --git a/src/confd/src/ietf-system.c b/src/confd/src/ietf-system.c index 2630f5f2b..364e0390b 100644 --- a/src/confd/src/ietf-system.c +++ b/src/confd/src/ietf-system.c @@ -309,38 +309,6 @@ int sr_get_int(sr_session_ctx_t *session, const char *fmt, ...) return rc; } -int sr_get_bool(sr_session_ctx_t *session, const char *fmt, ...) -{ - sr_val_t *val = NULL; - char *xpath; - va_list ap; - int rc = 0; - int len; - - va_start(ap, fmt); - len = vsnprintf(NULL, 0, fmt, ap) + 1; - va_end(ap); - - xpath = alloca(len); - if (!xpath) - goto fail; - - va_start(ap, fmt); - vsnprintf(xpath, len, fmt, ap); - va_end(ap); - - if (sr_get_item(session, xpath, 0, &val)) - goto fail; - if (!val || val->type != SR_BOOL_T) - goto fail; - - rc = val->data.bool_val; -fail: - if (val) - sr_free_val(val); - return rc; -} - #define TIMEZONE_CONF "/etc/timezone" #define TIMEZONE_PREV TIMEZONE_CONF "-" #define TIMEZONE_NEXT TIMEZONE_CONF "+" @@ -436,7 +404,7 @@ static int change_ntp(sr_session_ctx_t *session, uint32_t sub_id, const char *mo remove(CHRONY_PREV); rename(CHRONY_CONF, CHRONY_PREV); rename(CHRONY_NEXT, CHRONY_CONF); - if (!sr_get_bool(session, "/ietf-system:system/ntp/enabled")) { + if (srx_get_bool(session, "/ietf-system:system/ntp/enabled") == 0) { systemf("initctl -nbq disable chronyd"); return SR_ERR_OK; } @@ -495,9 +463,9 @@ static int change_ntp(sr_session_ctx_t *session, uint32_t sub_id, const char *mo } if (server) { - if (sr_get_bool(session, "%s/iburst", xpath)) + if (srx_get_bool(session, "%s/iburst", xpath) > 0) fprintf(fp, " iburst"); - if (sr_get_bool(session, "%s/prefer", xpath)) + if (srx_get_bool(session, "%s/prefer", xpath) > 0) fprintf(fp, " prefer"); fprintf(fp, "\n"); diff --git a/src/confd/src/srx_val.c b/src/confd/src/srx_val.c index 00091d9f3..48515949d 100644 --- a/src/confd/src/srx_val.c +++ b/src/confd/src/srx_val.c @@ -1,37 +1,68 @@ /* SPDX-License-Identifier: BSD-3-Clause */ +#include #include "core.h" -char *srx_get_str(sr_session_ctx_t *session, const char *fmt, ...) +static int srx_vaget(sr_session_ctx_t *session, const char *fmt, va_list ap, sr_val_t **val, sr_val_type_t type) { - char *str = NULL; - sr_val_t *val; + va_list apdup; char *xpath; - va_list ap; int len; - va_start(ap, fmt); - len = vsnprintf(NULL, 0, fmt, ap) + 1; - va_end(ap); + va_copy(apdup, ap); + len = vsnprintf(NULL, 0, fmt, apdup) + 1; + va_end(apdup); xpath = alloca(len); if (!xpath) - return NULL; + return -1; + + va_copy(apdup, ap); + vsnprintf(xpath, len, fmt, apdup); + va_end(apdup); + + if (sr_get_item(session, xpath, 0, val)) { + ERROR("Failed reading xpath %s", xpath); + return -1; + } + + if (type != SR_UNKNOWN_T && (*val)->type != type) + return -1; + + return 0; +} + +int srx_get_bool(sr_session_ctx_t *session, const char *fmt, ...) +{ + sr_val_t *val = NULL; + int result = -1; + va_list ap; va_start(ap, fmt); - vsnprintf(xpath, len, fmt, ap); + if (srx_vaget(session, fmt, ap, &val, SR_BOOL_T)) + goto fail; + + result = val->data.bool_val; + sr_free_val(val); +fail: va_end(ap); + return result; +} - if (sr_get_item(session, xpath, 0, &val)) { - ERROR("Failed reading string value from xpath %s", xpath); - goto fail; - } - if (!val || val->type != SR_STRING_T) + +char *srx_get_str(sr_session_ctx_t *session, const char *fmt, ...) +{ + sr_val_t *val = NULL; + char *str = NULL; + va_list ap; + + va_start(ap, fmt); + if (srx_vaget(session, fmt, ap, &val, SR_STRING_T)) goto fail; - str = strdup(val->data.string_val); + str = sr_val_to_str(val); + sr_free_val(val); fail: - if (val) - sr_free_val(val); + va_end(ap); return str; } diff --git a/src/confd/src/srx_val.h b/src/confd/src/srx_val.h index ae57aea10..da72b4f2d 100644 --- a/src/confd/src/srx_val.h +++ b/src/confd/src/srx_val.h @@ -6,6 +6,7 @@ #include "core.h" -char *srx_get_str(sr_session_ctx_t *session, const char *fmt, ...); +char *srx_get_str (sr_session_ctx_t *session, const char *fmt, ...); +int srx_get_bool (sr_session_ctx_t *session, const char *fmt, ...); #endif /* CONFD_SRX_VAL_H_ */ From a1c4c415c46ed05709dc1bf14f4397ac9a49f1b1 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Fri, 14 Apr 2023 16:26:50 +0200 Subject: [PATCH 14/36] src/confd: draft ietf-interfaces prototype to set static IP address Signed-off-by: Joachim Wiberg --- src/confd/src/ietf-interfaces.c | 64 +++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/src/confd/src/ietf-interfaces.c b/src/confd/src/ietf-interfaces.c index f189c1dc1..3bb9577c2 100644 --- a/src/confd/src/ietf-interfaces.c +++ b/src/confd/src/ietf-interfaces.c @@ -2,6 +2,7 @@ #include "core.h" #include "sr_ext.h" +#include "srx_val.h" const struct srx_module_requirement ietf_if_reqs[] = { { .dir = YANG_PATH_, .name = "ietf-interfaces", .rev = "2018-02-20" }, @@ -11,6 +12,67 @@ const struct srx_module_requirement ietf_if_reqs[] = { { NULL } }; +static int ifchange(sr_session_ctx_t *session, uint32_t sub_id, const char *module, + const char *xpath, sr_event_t event, unsigned request_id, void *priv) +{ + sr_val_t *val; + size_t cnt; + int rc; + + if (event != SR_EV_DONE) + return SR_ERR_OK; + + rc = sr_get_items(session, "/ietf-interfaces:interfaces/interface", 0, 0, &val, &cnt); + if (rc) + goto fail; + + for (size_t i = 0; i < cnt; i++) { + const char *xpath = val[i].xpath; + char path[strlen(xpath) + 64]; + sr_val_t *addr; + size_t addrcnt; + char *ifname; + char *ptr; + int ena; + + ifname = srx_get_str(session, "%s/name", xpath); + ptr = srx_get_str(session, "%s/description", xpath); + if (ptr) { + FILE *fp; + + fp = fopenf("w", "/sys/class/net/%s/ifalias", ifname); + if (fp) { + fprintf(fp, "%s\n", ptr); + fclose(fp); + } + free(ptr); + } + + systemf("ip addr flush dev %s", ifname); + + snprintf(path, sizeof(path), "%s/ietf-ip:ipv4/address", xpath); + rc = sr_get_items(session, path, 0, 0, &addr, &addrcnt); + for (size_t j = 0; j < addrcnt; j++) { + char *address; + char *plen; + + address = srx_get_str(session, "%s/ip", addr[j].xpath); + plen = srx_get_str(session, "%s/prefix-length", addr[j].xpath); + systemf("ip addr add %s/%s dev %s", address, plen, ifname); + free(address); + free(plen); + } + + ena = srx_get_bool(session, "%s/enabled", xpath); + systemf("ip link set %s %s", ifname, ena <= 0 ? "down" : "up"); + } + sr_free_values(val, cnt); + + rc = SR_ERR_OK; +fail: + return rc; +} + int ietf_interfaces_init(struct confd *confd) { int rc; @@ -19,6 +81,8 @@ int ietf_interfaces_init(struct confd *confd) if (rc) goto err; + REGISTER_CHANGE(confd->session, "ietf-interfaces", "/ietf-interfaces:interfaces", 0, ifchange, confd, &confd->sub); + return SR_ERR_OK; err: ERROR("init failed: %s", sr_strerror(rc)); From 11067dcb2613e0999463ec5c934fe92edd1f506a Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Fri, 14 Apr 2023 16:30:47 +0200 Subject: [PATCH 15/36] src/confd: rename sr_ext.[ch] -> srx_module.[ch] Signed-off-by: Joachim Wiberg --- src/confd/src/Makefile.am | 2 +- src/confd/src/ietf-interfaces.c | 2 +- src/confd/src/{sr_ext.c => srx_module.c} | 2 +- src/confd/src/{sr_ext.h => srx_module.h} | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename src/confd/src/{sr_ext.c => srx_module.c} (98%) rename src/confd/src/{sr_ext.h => srx_module.h} (100%) diff --git a/src/confd/src/Makefile.am b/src/confd/src/Makefile.am index fca460b99..649a72c1a 100644 --- a/src/confd/src/Makefile.am +++ b/src/confd/src/Makefile.am @@ -7,5 +7,5 @@ plugin_LTLIBRARIES = confd-plugin.la confd_plugin_la_CFLAGS = $(augeas_CFLAGS) $(libite_CFLAGS) $(sysrepo_CFLAGS) $(CFLAGS) confd_plugin_la_LIBADD = $(augeas_LIBS) $(libite_LIBS) $(sysrepo_LIBS) confd_plugin_la_LDFLAGS = -module -avoid-version -shared -confd_plugin_la_SOURCES = core.c core.h sr_ext.c sr_ext.h srx_val.c srx_val.h \ +confd_plugin_la_SOURCES = core.c core.h srx_module.c srx_module.h srx_val.c srx_val.h \ ietf-system.c ietf-interfaces.c diff --git a/src/confd/src/ietf-interfaces.c b/src/confd/src/ietf-interfaces.c index 3bb9577c2..4c9646688 100644 --- a/src/confd/src/ietf-interfaces.c +++ b/src/confd/src/ietf-interfaces.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause */ #include "core.h" -#include "sr_ext.h" +#include "srx_module.h" #include "srx_val.h" const struct srx_module_requirement ietf_if_reqs[] = { diff --git a/src/confd/src/sr_ext.c b/src/confd/src/srx_module.c similarity index 98% rename from src/confd/src/sr_ext.c rename to src/confd/src/srx_module.c index 25dfc196e..63de9cdd2 100644 --- a/src/confd/src/sr_ext.c +++ b/src/confd/src/srx_module.c @@ -3,7 +3,7 @@ #include #include "core.h" -#include "sr_ext.h" +#include "srx_module.h" sr_error_t srx_require_module(sr_conn_ctx_t *conn, const struct srx_module_requirement *mr) diff --git a/src/confd/src/sr_ext.h b/src/confd/src/srx_module.h similarity index 100% rename from src/confd/src/sr_ext.h rename to src/confd/src/srx_module.h From 4b0b544b13ba82a90b94abc765a8c11dfdb7309c Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Fri, 14 Apr 2023 18:29:04 +0200 Subject: [PATCH 16/36] src/confd: refactor sr_get_int() into a generic srx_get_int() Signed-off-by: Joachim Wiberg --- src/confd/src/ietf-system.c | 64 ++----------------------------------- src/confd/src/srx_val.c | 48 ++++++++++++++++++++++++++++ src/confd/src/srx_val.h | 4 ++- 3 files changed, 54 insertions(+), 62 deletions(-) diff --git a/src/confd/src/ietf-system.c b/src/confd/src/ietf-system.c index 364e0390b..040a547d8 100644 --- a/src/confd/src/ietf-system.c +++ b/src/confd/src/ietf-system.c @@ -251,64 +251,6 @@ static int sys_reload_services(void) return systemf("initctl -nbq touch sysklogd lldpd"); } -int sr_get_int(sr_session_ctx_t *session, const char *fmt, ...) -{ - sr_val_t *val = NULL; - char *xpath; - va_list ap; - int rc = 0; - int len; - - va_start(ap, fmt); - len = vsnprintf(NULL, 0, fmt, ap) + 1; - va_end(ap); - - xpath = alloca(len); - if (!xpath) - goto fail; - - va_start(ap, fmt); - vsnprintf(xpath, len, fmt, ap); - va_end(ap); - - if (sr_get_item(session, xpath, 0, &val) || !val) - goto fail; - - switch (val->type) { - case SR_INT8_T: - rc = val->data.int8_val; - break; - case SR_UINT8_T: - rc = val->data.uint8_val; - break; - case SR_INT16_T: - rc = val->data.int16_val; - break; - case SR_UINT16_T: - rc = val->data.uint16_val; - break; - case SR_INT32_T: - rc = val->data.int32_val; - break; - case SR_UINT32_T: - rc = val->data.uint32_val; - break; - case SR_INT64_T: - rc = val->data.int64_val; - break; - case SR_UINT64_T: - rc = val->data.uint64_val; - break; - default: - goto fail; - } - -fail: - if (val) - sr_free_val(val); - return rc; -} - #define TIMEZONE_CONF "/etc/timezone" #define TIMEZONE_PREV TIMEZONE_CONF "-" #define TIMEZONE_NEXT TIMEZONE_CONF "+" @@ -497,7 +439,7 @@ static int change_dns(sr_session_ctx_t *session, uint32_t sub_id, const char *mo const char *xpath, sr_event_t event, unsigned request_id, void *priv) { const char *fn = RESOLV_NEXT; - int timeout, attempts; + int timeout = 0, attempts = 0; int rc = SR_ERR_SYS; sr_val_t *val; size_t cnt; @@ -540,8 +482,8 @@ static int change_dns(sr_session_ctx_t *session, uint32_t sub_id, const char *mo return SR_ERR_SYS; } - timeout = sr_get_int(session, "/ietf-system:system/dns-resolver/options/timeout"); - attempts = sr_get_int(session, "/ietf-system:system/dns-resolver/options/attempts"); + SRX_GET_UINT8(session, timeout, "/ietf-system:system/dns-resolver/options/timeout"); + SRX_GET_UINT8(session, timeout, "/ietf-system:system/dns-resolver/options/attempts"); if (timeout || attempts) { fprintf(fp, "options"); if (timeout) diff --git a/src/confd/src/srx_val.c b/src/confd/src/srx_val.c index 48515949d..5dd21b304 100644 --- a/src/confd/src/srx_val.c +++ b/src/confd/src/srx_val.c @@ -49,6 +49,54 @@ int srx_get_bool(sr_session_ctx_t *session, const char *fmt, ...) return result; } +int srx_get_int(sr_session_ctx_t *session, int *result, sr_val_type_t type, const char *fmt, ...) +{ + sr_val_t *val = NULL; + va_list ap; + int rc; + + va_start(ap, fmt); + rc = srx_vaget(session, fmt, ap, &val, type); + va_end(ap); + + if (rc) + return rc; + rc = -1; + + switch (val->type) { + case SR_INT8_T: + *result = val->data.int8_val; + break; + case SR_UINT8_T: + *result = val->data.uint8_val; + break; + case SR_INT16_T: + *result = val->data.int16_val; + break; + case SR_UINT16_T: + *result = val->data.uint16_val; + break; + case SR_INT32_T: + *result = val->data.int32_val; + break; + case SR_UINT32_T: + *result = val->data.uint32_val; + break; + case SR_INT64_T: + *result = val->data.int64_val; + break; + case SR_UINT64_T: + *result = val->data.uint64_val; + break; + default: + goto fail; + } + + rc = 0; +fail: + sr_free_val(val); + return rc; +} char *srx_get_str(sr_session_ctx_t *session, const char *fmt, ...) { diff --git a/src/confd/src/srx_val.h b/src/confd/src/srx_val.h index da72b4f2d..80d996fdd 100644 --- a/src/confd/src/srx_val.h +++ b/src/confd/src/srx_val.h @@ -3,10 +3,12 @@ #ifndef CONFD_SRX_VAL_H_ #define CONFD_SRX_VAL_H_ - #include "core.h" +#define SRX_GET_UINT8(s,v,fmt,...) srx_get_int(s, &v, SR_UINT8_T, fmt, ##__VA_ARGS__) + char *srx_get_str (sr_session_ctx_t *session, const char *fmt, ...); +int srx_get_int (sr_session_ctx_t *session, int *result, sr_val_type_t type, const char *fmt, ...); int srx_get_bool (sr_session_ctx_t *session, const char *fmt, ...); #endif /* CONFD_SRX_VAL_H_ */ From 847c564771ceba4d771e543f3359bebaea5c4534 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Fri, 14 Apr 2023 18:32:21 +0200 Subject: [PATCH 17/36] src/confd: refactor srx_get_bool() to create srx_enabled() All value functions, except the new srx_enabled(), now return clear error indication, with the value as a separate argument. The srx_enabled() predicate function is for cases where the default value is disabled and code checks enable a subsystem or flag. I.e., when an error can safely be returned as 'false'. Signed-off-by: Joachim Wiberg --- src/confd/src/ietf-interfaces.c | 4 +-- src/confd/src/ietf-system.c | 6 ++--- src/confd/src/srx_val.c | 43 +++++++++++++++++++++++++++------ src/confd/src/srx_val.h | 1 + 4 files changed, 40 insertions(+), 14 deletions(-) diff --git a/src/confd/src/ietf-interfaces.c b/src/confd/src/ietf-interfaces.c index 4c9646688..fb26b1252 100644 --- a/src/confd/src/ietf-interfaces.c +++ b/src/confd/src/ietf-interfaces.c @@ -33,7 +33,6 @@ static int ifchange(sr_session_ctx_t *session, uint32_t sub_id, const char *modu size_t addrcnt; char *ifname; char *ptr; - int ena; ifname = srx_get_str(session, "%s/name", xpath); ptr = srx_get_str(session, "%s/description", xpath); @@ -63,8 +62,7 @@ static int ifchange(sr_session_ctx_t *session, uint32_t sub_id, const char *modu free(plen); } - ena = srx_get_bool(session, "%s/enabled", xpath); - systemf("ip link set %s %s", ifname, ena <= 0 ? "down" : "up"); + systemf("ip link set %s %s", ifname, srx_enabled(session, "%s/enabled", xpath) ? "up" : "down"); } sr_free_values(val, cnt); diff --git a/src/confd/src/ietf-system.c b/src/confd/src/ietf-system.c index 040a547d8..78f565ea1 100644 --- a/src/confd/src/ietf-system.c +++ b/src/confd/src/ietf-system.c @@ -346,7 +346,7 @@ static int change_ntp(sr_session_ctx_t *session, uint32_t sub_id, const char *mo remove(CHRONY_PREV); rename(CHRONY_CONF, CHRONY_PREV); rename(CHRONY_NEXT, CHRONY_CONF); - if (srx_get_bool(session, "/ietf-system:system/ntp/enabled") == 0) { + if (srx_enabled(session, "/ietf-system:system/ntp/enabled")) { systemf("initctl -nbq disable chronyd"); return SR_ERR_OK; } @@ -405,9 +405,9 @@ static int change_ntp(sr_session_ctx_t *session, uint32_t sub_id, const char *mo } if (server) { - if (srx_get_bool(session, "%s/iburst", xpath) > 0) + if (srx_enabled(session, "%s/iburst", xpath) > 0) fprintf(fp, " iburst"); - if (srx_get_bool(session, "%s/prefer", xpath) > 0) + if (srx_enabled(session, "%s/prefer", xpath) > 0) fprintf(fp, " prefer"); fprintf(fp, "\n"); diff --git a/src/confd/src/srx_val.c b/src/confd/src/srx_val.c index 5dd21b304..4c4369838 100644 --- a/src/confd/src/srx_val.c +++ b/src/confd/src/srx_val.c @@ -32,21 +32,48 @@ static int srx_vaget(sr_session_ctx_t *session, const char *fmt, va_list ap, sr_ return 0; } -int srx_get_bool(sr_session_ctx_t *session, const char *fmt, ...) +static int get_vabool(sr_session_ctx_t *session, int *result, const char *fmt, va_list ap) { sr_val_t *val = NULL; - int result = -1; + va_list apdup; + int rc; + + va_copy(apdup, ap); + rc = srx_vaget(session, fmt, apdup, &val, SR_BOOL_T); + va_end(apdup); + + if (rc) + return rc; + + *result = val->data.bool_val; + sr_free_val(val); + + return 0; +} + +int srx_get_bool(sr_session_ctx_t *session, int *result, const char *fmt, ...) +{ va_list ap; + int rc; va_start(ap, fmt); - if (srx_vaget(session, fmt, ap, &val, SR_BOOL_T)) - goto fail; + rc = get_vabool(session, result, fmt, ap); + va_end(ap); - result = val->data.bool_val; - sr_free_val(val); -fail: + return rc; +} + +int srx_enabled(sr_session_ctx_t *session, const char *fmt, ...) +{ + va_list ap; + int v = 0; + int rc; + + va_start(ap, fmt); + rc = get_vabool(session, &v, fmt, ap); va_end(ap); - return result; + + return rc ? 0 : v; } int srx_get_int(sr_session_ctx_t *session, int *result, sr_val_type_t type, const char *fmt, ...) diff --git a/src/confd/src/srx_val.h b/src/confd/src/srx_val.h index 80d996fdd..3da0b2032 100644 --- a/src/confd/src/srx_val.h +++ b/src/confd/src/srx_val.h @@ -10,5 +10,6 @@ char *srx_get_str (sr_session_ctx_t *session, const char *fmt, ...); int srx_get_int (sr_session_ctx_t *session, int *result, sr_val_type_t type, const char *fmt, ...); int srx_get_bool (sr_session_ctx_t *session, const char *fmt, ...); +int srx_enabled (sr_session_ctx_t *session, const char *fmt, ...); #endif /* CONFD_SRX_VAL_H_ */ From 31f4f09bfa47b3cadab1edd32eb7931f6c12cb4a Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Fri, 14 Apr 2023 18:35:50 +0200 Subject: [PATCH 18/36] src/confd: optionally use netmask instead of prefix-length Some users still prefer the old netmask style to set up an interface. This patch enables the corresponding model feature and checks for a netmask only if prefix-length is unset. Signed-off-by: Joachim Wiberg --- src/confd/src/ietf-interfaces.c | 51 ++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/src/confd/src/ietf-interfaces.c b/src/confd/src/ietf-interfaces.c index fb26b1252..aa1a3f961 100644 --- a/src/confd/src/ietf-interfaces.c +++ b/src/confd/src/ietf-interfaces.c @@ -4,14 +4,35 @@ #include "srx_module.h" #include "srx_val.h" -const struct srx_module_requirement ietf_if_reqs[] = { +static const char *ipfeat[] = { + "ipv4-non-contiguous-netmasks", + NULL +}; + +static const struct srx_module_requirement ietf_if_reqs[] = { { .dir = YANG_PATH_, .name = "ietf-interfaces", .rev = "2018-02-20" }, { .dir = YANG_PATH_, .name = "iana-if-type", .rev = "2017-01-19" }, - { .dir = YANG_PATH_, .name = "ietf-ip", .rev = "2018-02-22" }, + { .dir = YANG_PATH_, .name = "ietf-ip", .rev = "2018-02-22", .features = ipfeat }, { NULL } }; +static int inet_mask2len(char *netmask) +{ + struct in_addr ina; + int len = 0; + + if (inet_pton(AF_INET, netmask, &ina) != 1) + return 0; + + while (ina.s_addr) { + ina.s_addr >>= 1; + len++; + } + + return len; +} + static int ifchange(sr_session_ctx_t *session, uint32_t sub_id, const char *module, const char *xpath, sr_event_t event, unsigned request_id, void *priv) { @@ -52,17 +73,33 @@ static int ifchange(sr_session_ctx_t *session, uint32_t sub_id, const char *modu snprintf(path, sizeof(path), "%s/ietf-ip:ipv4/address", xpath); rc = sr_get_items(session, path, 0, 0, &addr, &addrcnt); for (size_t j = 0; j < addrcnt; j++) { - char *address; - char *plen; + char *address, *netmask; + int plen = 0; address = srx_get_str(session, "%s/ip", addr[j].xpath); - plen = srx_get_str(session, "%s/prefix-length", addr[j].xpath); - systemf("ip addr add %s/%s dev %s", address, plen, ifname); + SRX_GET_UINT8(session, plen, "%s/prefix-length", addr[j].xpath); + if (!plen) { + netmask = srx_get_str(session, "%s/netmask", addr[j].xpath); + ERROR("read netmask instead: %s", netmask ?: ""); + if (netmask) { + plen = inet_mask2len(netmask); + free(netmask); + } + } + if (plen > 0) { + char *add = "add"; + + if (!srx_enabled(session, "%s/enabled", addr[j].xpath)) + add = "del"; + + ERROR("Preparing to %s addess %s", add, address); + systemf("ip addr add %s/%d dev %s", address, plen, ifname); + } free(address); - free(plen); } systemf("ip link set %s %s", ifname, srx_enabled(session, "%s/enabled", xpath) ? "up" : "down"); + free(ifname); } sr_free_values(val, cnt); From ba7ee1e3583956b785cfc0373e63c3c139271ea6 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sat, 15 Apr 2023 10:12:19 +0200 Subject: [PATCH 19/36] src/confd: refactor, add first file function helper: writesf() Signed-off-by: Joachim Wiberg --- src/confd/src/Makefile.am | 2 +- src/confd/src/core.h | 2 ++ src/confd/src/helpers.c | 25 +++++++++++++++++++++++++ src/confd/src/helpers.h | 8 ++++++++ src/confd/src/ietf-interfaces.c | 13 +++---------- src/confd/src/ietf-system.c | 32 ++++++++++++++------------------ 6 files changed, 53 insertions(+), 29 deletions(-) create mode 100644 src/confd/src/helpers.c create mode 100644 src/confd/src/helpers.h diff --git a/src/confd/src/Makefile.am b/src/confd/src/Makefile.am index 649a72c1a..1c4609f7f 100644 --- a/src/confd/src/Makefile.am +++ b/src/confd/src/Makefile.am @@ -7,5 +7,5 @@ plugin_LTLIBRARIES = confd-plugin.la confd_plugin_la_CFLAGS = $(augeas_CFLAGS) $(libite_CFLAGS) $(sysrepo_CFLAGS) $(CFLAGS) confd_plugin_la_LIBADD = $(augeas_LIBS) $(libite_LIBS) $(sysrepo_LIBS) confd_plugin_la_LDFLAGS = -module -avoid-version -shared -confd_plugin_la_SOURCES = core.c core.h srx_module.c srx_module.h srx_val.c srx_val.h \ +confd_plugin_la_SOURCES = core.c core.h helpers.c helpers.h srx_module.c srx_module.h srx_val.c srx_val.h \ ietf-system.c ietf-interfaces.c diff --git a/src/confd/src/core.h b/src/confd/src/core.h index 457261508..02b96d4ae 100644 --- a/src/confd/src/core.h +++ b/src/confd/src/core.h @@ -19,6 +19,8 @@ #include #include +#include "helpers.h" + #ifndef HAVE_VASPRINTF int vasprintf(char **strp, const char *fmt, va_list ap); #endif diff --git a/src/confd/src/helpers.c b/src/confd/src/helpers.c new file mode 100644 index 000000000..f08fd0bf3 --- /dev/null +++ b/src/confd/src/helpers.c @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#include +#include "core.h" + +/* + * Write str to a file composed from fmt and optional args. + */ +int writesf(const char *str, const char *fmt, ...) +{ + va_list ap; + int rc = -1; + FILE *fp; + + va_start(ap, fmt); + fp = fopenf("w", fmt, ap); + if (fp) { + fprintf(fp, "%s\n", str); + rc = fclose(fp); + } + va_end(ap); + + return rc; +} + diff --git a/src/confd/src/helpers.h b/src/confd/src/helpers.h new file mode 100644 index 000000000..05a2fa229 --- /dev/null +++ b/src/confd/src/helpers.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#ifndef CONFD_HELPERS_H_ +#define CONFD_HELPERS_H_ + +int writesf(const char *str, const char *fmt, ...); + +#endif /* CONFD_HELPERS_H_ */ diff --git a/src/confd/src/ietf-interfaces.c b/src/confd/src/ietf-interfaces.c index aa1a3f961..a9802fff1 100644 --- a/src/confd/src/ietf-interfaces.c +++ b/src/confd/src/ietf-interfaces.c @@ -57,16 +57,9 @@ static int ifchange(sr_session_ctx_t *session, uint32_t sub_id, const char *modu ifname = srx_get_str(session, "%s/name", xpath); ptr = srx_get_str(session, "%s/description", xpath); - if (ptr) { - FILE *fp; - - fp = fopenf("w", "/sys/class/net/%s/ifalias", ifname); - if (fp) { - fprintf(fp, "%s\n", ptr); - fclose(fp); - } - free(ptr); - } + if (ptr) + writesf(ptr, "/sys/class/net/%s/ifalias", ifname); + free(ptr); systemf("ip addr flush dev %s", ifname); diff --git a/src/confd/src/ietf-system.c b/src/confd/src/ietf-system.c index 78f565ea1..4d01de73a 100644 --- a/src/confd/src/ietf-system.c +++ b/src/confd/src/ietf-system.c @@ -259,7 +259,6 @@ static int change_clock(sr_session_ctx_t *session, uint32_t sub_id, const char * const char *xpath, sr_event_t event, unsigned request_id, void *priv) { char *timezone; - FILE *fp; switch (event) { case SR_EV_ENABLED: /* first time, on register. */ @@ -303,13 +302,10 @@ static int change_clock(sr_session_ctx_t *session, uint32_t sub_id, const char * return SR_ERR_VALIDATION_FAILED; } - fp = fopen(TIMEZONE_NEXT, "w"); - if (!fp) { + if (writesf(timezone, TIMEZONE_NEXT)) { ERRNO("Failed preparing %s", TIMEZONE_NEXT); return SR_ERR_SYS; } - fprintf(fp, "%s\n", timezone); - fclose(fp); return SR_ERR_OK; } @@ -533,26 +529,26 @@ static int change_dns(sr_session_ctx_t *session, uint32_t sub_id, const char *mo static int change_motd(sr_session_ctx_t *session, uint32_t sub_id, const char *module, const char *xpath, sr_event_t event, unsigned request_id, void *priv) { - char *nm; - FILE *fp; + /* XXX: derive from global "options.h" or /usr/share/factory/ */ + const char *msg = "\033[1;90mNote:\033[0m" + "\033[0;90m use help, show, and setup commands to set up and diagnose the system\033[0m"; + char *str; + int rc; /* Ignore all events except SR_EV_DONE */ if (event != SR_EV_DONE) return SR_ERR_OK; - fp = fopen("/etc/motd", "w"); - if (!fp) - return SR_ERR_SYS; - - nm = srx_get_str(session, xpath); - if (nm) { - fprintf(fp, "%s\n", nm); + str = srx_get_str(session, xpath); + if (str) { + rc = writesf(str, "/etc/motd"); + free(str); } else { - /* XXX: derive from global "options.h" or /usr/share/factory/ */ - fprintf(fp, "\033[1;90mNote:\033[0m "); - fprintf(fp, "\033[0;90m use help, show, and setup commands to set up and diagnose the system\033[0m\n"); + rc = writesf(msg, "/etc/motd"); } - fclose(fp); + + if (rc) + return SR_ERR_SYS; return SR_ERR_OK; } From 130991aaf1b1641524ca7edf78b6c2e0ad7b8af8 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sun, 16 Apr 2023 12:22:37 +0200 Subject: [PATCH 20/36] src/confd: add support for ietf-ip:ipv4/forwarding Signed-off-by: Joachim Wiberg --- src/confd/src/helpers.c | 20 ++++++++++++++++++++ src/confd/src/helpers.h | 1 + src/confd/src/ietf-interfaces.c | 3 +++ 3 files changed, 24 insertions(+) diff --git a/src/confd/src/helpers.c b/src/confd/src/helpers.c index f08fd0bf3..1338c7316 100644 --- a/src/confd/src/helpers.c +++ b/src/confd/src/helpers.c @@ -3,6 +3,26 @@ #include #include "core.h" +/* + * Write interger value to a file composed from fmt and optional args. + */ +int writedf(int value, const char *fmt, ...) +{ + va_list ap; + int rc = -1; + FILE *fp; + + va_start(ap, fmt); + fp = fopenf("w", fmt, ap); + if (fp) { + fprintf(fp, "%d\n", value); + rc = fclose(fp); + } + va_end(ap); + + return rc; +} + /* * Write str to a file composed from fmt and optional args. */ diff --git a/src/confd/src/helpers.h b/src/confd/src/helpers.h index 05a2fa229..87ea93c6c 100644 --- a/src/confd/src/helpers.h +++ b/src/confd/src/helpers.h @@ -3,6 +3,7 @@ #ifndef CONFD_HELPERS_H_ #define CONFD_HELPERS_H_ +int writedf(int value, const char *fmt, ...); int writesf(const char *str, const char *fmt, ...); #endif /* CONFD_HELPERS_H_ */ diff --git a/src/confd/src/ietf-interfaces.c b/src/confd/src/ietf-interfaces.c index a9802fff1..5e8aab355 100644 --- a/src/confd/src/ietf-interfaces.c +++ b/src/confd/src/ietf-interfaces.c @@ -61,6 +61,9 @@ static int ifchange(sr_session_ctx_t *session, uint32_t sub_id, const char *modu writesf(ptr, "/sys/class/net/%s/ifalias", ifname); free(ptr); + writedf(srx_enabled(session, "%s/ietf-ip:ipv4/forwarding", xpath), + "/proc/sys/net/ipv4/conf/%s/forwarding", ifname); + systemf("ip addr flush dev %s", ifname); snprintf(path, sizeof(path), "%s/ietf-ip:ipv4/address", xpath); From 046fa91b9fe452a6dee752fec4796d01a2fd521c Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sun, 16 Apr 2023 14:36:31 +0200 Subject: [PATCH 21/36] src/confd: drop developer debug messages Signed-off-by: Joachim Wiberg --- src/confd/src/ietf-interfaces.c | 1 - src/confd/src/ietf-system.c | 1 - 2 files changed, 2 deletions(-) diff --git a/src/confd/src/ietf-interfaces.c b/src/confd/src/ietf-interfaces.c index 5e8aab355..d8a5b78e2 100644 --- a/src/confd/src/ietf-interfaces.c +++ b/src/confd/src/ietf-interfaces.c @@ -76,7 +76,6 @@ static int ifchange(sr_session_ctx_t *session, uint32_t sub_id, const char *modu SRX_GET_UINT8(session, plen, "%s/prefix-length", addr[j].xpath); if (!plen) { netmask = srx_get_str(session, "%s/netmask", addr[j].xpath); - ERROR("read netmask instead: %s", netmask ?: ""); if (netmask) { plen = inet_mask2len(netmask); free(netmask); diff --git a/src/confd/src/ietf-system.c b/src/confd/src/ietf-system.c index 4d01de73a..6b9d8d94b 100644 --- a/src/confd/src/ietf-system.c +++ b/src/confd/src/ietf-system.c @@ -606,7 +606,6 @@ static int change_hostname(sr_session_ctx_t *session, uint32_t sub_id, const cha return err; } - ERROR("Reload hostname-dependent services ..."); err = err ? : aug_save(confd->aug); if (sys_reload_services()) return SR_ERR_SYS; From 494da26c6eda6e1e0c235d4bbcfbb9571494584b Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sun, 16 Apr 2023 14:37:41 +0200 Subject: [PATCH 22/36] src/confd: fix invalid use of fopenf() in write*f() wrappers Signed-off-by: Joachim Wiberg --- src/confd/src/helpers.c | 47 +++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/src/confd/src/helpers.c b/src/confd/src/helpers.c index 1338c7316..d61488b13 100644 --- a/src/confd/src/helpers.c +++ b/src/confd/src/helpers.c @@ -3,24 +3,45 @@ #include #include "core.h" +static FILE *open_file(const char *mode, const char *fmt, va_list ap) +{ + va_list apc; + char *file; + int len; + + va_copy(apc, ap); + len = vsnprintf(NULL, 0, fmt, apc); + va_end(apc); + + file = alloca(len + 1); + if (!file) { + errno = ENOMEM; + return NULL; + } + + va_copy(apc, ap); + vsnprintf(file, len + 1, fmt, apc); + va_end(apc); + + return fopen(file, mode); +} + /* * Write interger value to a file composed from fmt and optional args. */ int writedf(int value, const char *fmt, ...) { va_list ap; - int rc = -1; FILE *fp; va_start(ap, fmt); - fp = fopenf("w", fmt, ap); - if (fp) { - fprintf(fp, "%d\n", value); - rc = fclose(fp); - } + fp = open_file("r+", fmt, ap); va_end(ap); + if (!fp) + return -1; - return rc; + fprintf(fp, "%d\n", value); + return fclose(fp); } /* @@ -29,17 +50,15 @@ int writedf(int value, const char *fmt, ...) int writesf(const char *str, const char *fmt, ...) { va_list ap; - int rc = -1; FILE *fp; va_start(ap, fmt); - fp = fopenf("w", fmt, ap); - if (fp) { - fprintf(fp, "%s\n", str); - rc = fclose(fp); - } + fp = open_file("r+", fmt, ap); va_end(ap); + if (!fp) + return -1; - return rc; + fprintf(fp, "%s\n", str); + return fclose(fp); } From 5d7588ced196287a4326d5cf565c909017d30447 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sun, 16 Apr 2023 14:39:00 +0200 Subject: [PATCH 23/36] src/confd: fix invalid xpath, 'enabled' not available per address Signed-off-by: Joachim Wiberg --- src/confd/src/ietf-interfaces.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/confd/src/ietf-interfaces.c b/src/confd/src/ietf-interfaces.c index d8a5b78e2..b638442c1 100644 --- a/src/confd/src/ietf-interfaces.c +++ b/src/confd/src/ietf-interfaces.c @@ -65,6 +65,8 @@ static int ifchange(sr_session_ctx_t *session, uint32_t sub_id, const char *modu "/proc/sys/net/ipv4/conf/%s/forwarding", ifname); systemf("ip addr flush dev %s", ifname); + if (!srx_enabled(session, "%s//ietf-ip:ipv4/enabled", xpath)) + goto ipv6; snprintf(path, sizeof(path), "%s/ietf-ip:ipv4/address", xpath); rc = sr_get_items(session, path, 0, 0, &addr, &addrcnt); @@ -81,18 +83,17 @@ static int ifchange(sr_session_ctx_t *session, uint32_t sub_id, const char *modu free(netmask); } } - if (plen > 0) { - char *add = "add"; - if (!srx_enabled(session, "%s/enabled", addr[j].xpath)) - add = "del"; - - ERROR("Preparing to %s addess %s", add, address); + if (plen == 0) + ERROR("%s: missing netmask or invalid prefix-length", address); + else systemf("ip addr add %s/%d dev %s", address, plen, ifname); - } free(address); } + ipv6: + /* XXX todo */ + systemf("ip link set %s %s", ifname, srx_enabled(session, "%s/enabled", xpath) ? "up" : "down"); free(ifname); } From 2d8e216dd226fb0bf9f0a268700b2df4f68c1b2b Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sun, 16 Apr 2023 14:39:58 +0200 Subject: [PATCH 24/36] src/confd: refactor srx_val.c to use sr_get_items() to silence log Calling sr_get_time() for an xpath that has no data causes sysrepo to always log the access as an error. With sr_get_items() it is left to the callee to determine if the missing data should cause an error. This patch is a refactor that silences the syslog message and also fixes one or tow memory leaks. Signed-off-by: Joachim Wiberg --- src/confd/src/srx_val.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/src/confd/src/srx_val.c b/src/confd/src/srx_val.c index 4c4369838..705bfd17a 100644 --- a/src/confd/src/srx_val.c +++ b/src/confd/src/srx_val.c @@ -3,11 +3,12 @@ #include #include "core.h" -static int srx_vaget(sr_session_ctx_t *session, const char *fmt, va_list ap, sr_val_t **val, sr_val_type_t type) +static int srx_vaget(sr_session_ctx_t *session, const char *fmt, va_list ap, sr_val_type_t type, sr_val_t **val, size_t *cnt) { va_list apdup; char *xpath; int len; + int rc; va_copy(apdup, ap); len = vsnprintf(NULL, 0, fmt, apdup) + 1; @@ -21,13 +22,26 @@ static int srx_vaget(sr_session_ctx_t *session, const char *fmt, va_list ap, sr_ vsnprintf(xpath, len, fmt, apdup); va_end(apdup); - if (sr_get_item(session, xpath, 0, val)) { - ERROR("Failed reading xpath %s", xpath); + rc = sr_get_items(session, xpath, 0, 0, val, cnt); + if (rc) { + ERROR("Failed reading xpath %s: %s", xpath, sr_strerror(rc)); + return -1; + } + + if (*cnt == 0) { + errno = ENODATA; + return -1; + } else if (*cnt > 1) { + sr_free_values(*val, *cnt); + errno = EOVERFLOW; return -1; } - if (type != SR_UNKNOWN_T && (*val)->type != type) + if (type != SR_UNKNOWN_T && val[0]->type != type) { + sr_free_values(*val, *cnt); + errno = EINVAL; return -1; + } return 0; } @@ -35,18 +49,19 @@ static int srx_vaget(sr_session_ctx_t *session, const char *fmt, va_list ap, sr_ static int get_vabool(sr_session_ctx_t *session, int *result, const char *fmt, va_list ap) { sr_val_t *val = NULL; + size_t cnt = 0; va_list apdup; int rc; va_copy(apdup, ap); - rc = srx_vaget(session, fmt, apdup, &val, SR_BOOL_T); + rc = srx_vaget(session, fmt, apdup, SR_BOOL_T, &val, &cnt); va_end(apdup); if (rc) return rc; *result = val->data.bool_val; - sr_free_val(val); + sr_free_values(val, cnt); return 0; } @@ -79,11 +94,12 @@ int srx_enabled(sr_session_ctx_t *session, const char *fmt, ...) int srx_get_int(sr_session_ctx_t *session, int *result, sr_val_type_t type, const char *fmt, ...) { sr_val_t *val = NULL; + size_t cnt = 0; va_list ap; int rc; va_start(ap, fmt); - rc = srx_vaget(session, fmt, ap, &val, type); + rc = srx_vaget(session, fmt, ap, type, &val, &cnt); va_end(ap); if (rc) @@ -121,7 +137,7 @@ int srx_get_int(sr_session_ctx_t *session, int *result, sr_val_type_t type, cons rc = 0; fail: - sr_free_val(val); + sr_free_values(val, cnt); return rc; } @@ -129,14 +145,15 @@ char *srx_get_str(sr_session_ctx_t *session, const char *fmt, ...) { sr_val_t *val = NULL; char *str = NULL; + size_t cnt = 0; va_list ap; va_start(ap, fmt); - if (srx_vaget(session, fmt, ap, &val, SR_STRING_T)) + if (srx_vaget(session, fmt, ap, SR_UNKNOWN_T, &val, &cnt)) goto fail; str = sr_val_to_str(val); - sr_free_val(val); + sr_free_values(val, cnt); fail: va_end(ap); return str; From 9d6d657a8998ca2d1641e732cf075943fda89634 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sun, 16 Apr 2023 16:01:15 +0200 Subject: [PATCH 25/36] src/confd: add support for ipv6 in ietf-interfaces Signed-off-by: Joachim Wiberg --- src/confd/src/ietf-interfaces.c | 35 ++++++++++++++++++++++++++++++--- src/confd/src/srx_val.h | 3 ++- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/confd/src/ietf-interfaces.c b/src/confd/src/ietf-interfaces.c index b638442c1..f3420b0c1 100644 --- a/src/confd/src/ietf-interfaces.c +++ b/src/confd/src/ietf-interfaces.c @@ -50,6 +50,7 @@ static int ifchange(sr_session_ctx_t *session, uint32_t sub_id, const char *modu for (size_t i = 0; i < cnt; i++) { const char *xpath = val[i].xpath; char path[strlen(xpath) + 64]; + int dad_xmit = 1; sr_val_t *addr; size_t addrcnt; char *ifname; @@ -65,7 +66,7 @@ static int ifchange(sr_session_ctx_t *session, uint32_t sub_id, const char *modu "/proc/sys/net/ipv4/conf/%s/forwarding", ifname); systemf("ip addr flush dev %s", ifname); - if (!srx_enabled(session, "%s//ietf-ip:ipv4/enabled", xpath)) + if (!srx_enabled(session, "%s/ietf-ip:ipv4/enabled", xpath)) goto ipv6; snprintf(path, sizeof(path), "%s/ietf-ip:ipv4/address", xpath); @@ -90,10 +91,38 @@ static int ifchange(sr_session_ctx_t *session, uint32_t sub_id, const char *modu systemf("ip addr add %s/%d dev %s", address, plen, ifname); free(address); } - ipv6: - /* XXX todo */ + writedf(srx_enabled(session, "%s/ietf-ip:ipv6/forwarding", xpath), + "/proc/sys/net/ipv6/conf/%s/forwarding", ifname); + + SRX_GET_UINT32(session, dad_xmit, "%s/ietf-ip:ipv6/dup-addr-detect-transmits", xpath); + writedf(dad_xmit, "/proc/sys/net/ipv6/conf/%s/dad_transmits", ifname); + + if (!srx_enabled(session, "%s/ietf-ip:ipv6/enabled", xpath)) { + writedf(1, "/proc/sys/net/ipv6/conf/%s/disable_ipv6", ifname); + goto done; + + } + writedf(0, "/proc/sys/net/ipv6/conf/%s/disable_ipv6", ifname); + + writedf(srx_enabled(session, "%s/ietf-ip:ipv6/autoconf/create-global-addresses", xpath), + "/proc/sys/net/ipv6/conf/%s/autoconf", ifname); + + snprintf(path, sizeof(path), "%s/ietf-ip:ipv6/address", xpath); + rc = sr_get_items(session, path, 0, 0, &addr, &addrcnt); + for (size_t j = 0; j < addrcnt; j++) { + char *address; + int plen = 0; + address = srx_get_str(session, "%s/ip", addr[j].xpath); + SRX_GET_UINT8(session, plen, "%s/prefix-length", addr[j].xpath); + if (plen == 0) + ERROR("%s: missing netmask or invalid prefix-length", address); + else + systemf("ip addr add %s/%d dev %s", address, plen, ifname); + free(address); + } + done: systemf("ip link set %s %s", ifname, srx_enabled(session, "%s/enabled", xpath) ? "up" : "down"); free(ifname); } diff --git a/src/confd/src/srx_val.h b/src/confd/src/srx_val.h index 3da0b2032..abefe54dc 100644 --- a/src/confd/src/srx_val.h +++ b/src/confd/src/srx_val.h @@ -5,7 +5,8 @@ #include "core.h" -#define SRX_GET_UINT8(s,v,fmt,...) srx_get_int(s, &v, SR_UINT8_T, fmt, ##__VA_ARGS__) +#define SRX_GET_UINT8(s,v,fmt,...) srx_get_int(s, &v, SR_UINT8_T, fmt, ##__VA_ARGS__) +#define SRX_GET_UINT32(s,v,fmt,...) srx_get_int(s, &v, SR_UINT32_T, fmt, ##__VA_ARGS__) char *srx_get_str (sr_session_ctx_t *session, const char *fmt, ...); int srx_get_int (sr_session_ctx_t *session, int *result, sr_val_type_t type, const char *fmt, ...); From 955d14f6a3d009d751923e04b968db437aae7a10 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sun, 16 Apr 2023 16:16:57 +0200 Subject: [PATCH 26/36] src/confd: minor refactor, add convenience macro REGISTER_OPER() Signed-off-by: Joachim Wiberg --- src/confd/src/core.h | 13 +++++++++++++ src/confd/src/ietf-system.c | 13 +++---------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/confd/src/core.h b/src/confd/src/core.h index 02b96d4ae..6f28ac979 100644 --- a/src/confd/src/core.h +++ b/src/confd/src/core.h @@ -47,6 +47,10 @@ static inline void print_val(sr_val_t *val) if ((rc = register_change(s, m, x, f, c, a, u))) \ goto err +#define REGISTER_OPER(s,m,x,c,a,f,u) \ + if ((rc = register_oper(s, m, x, c, a, f, u))) \ + goto err + #define REGISTER_RPC(s,x,c,a,u) \ if ((rc = register_rpc(s, x, c, a, u))) \ goto err @@ -68,6 +72,15 @@ static inline int register_change(sr_session_ctx_t *session, const char *module, return rc; } +static inline int register_oper(sr_session_ctx_t *session, const char *module, const char *xpath, + sr_oper_get_items_cb cb, void *arg, int flags, sr_subscription_ctx_t **sub) +{ + int rc = sr_oper_get_subscribe(session, module, xpath, cb, arg, flags | SR_SUBSCR_DEFAULT, sub); + if (rc) + ERROR("failed subscribing to %s oper: %s", xpath, sr_strerror(rc)); + return rc; +} + static inline int register_rpc(sr_session_ctx_t *session, const char *xpath, sr_rpc_cb cb, void *arg, sr_subscription_ctx_t **sub) { diff --git a/src/confd/src/ietf-system.c b/src/confd/src/ietf-system.c index 6b9d8d94b..decd0ed73 100644 --- a/src/confd/src/ietf-system.c +++ b/src/confd/src/ietf-system.c @@ -639,22 +639,15 @@ int ietf_system_init(struct confd *confd) if (rc) goto err; - rc = sr_oper_get_subscribe(confd->session, "ietf-system", CLOCK_PATH_, - clock_cb, NULL, SR_SUBSCR_DEFAULT, &confd->sub); - if (rc != SR_ERR_OK) - goto err; - - rc = sr_oper_get_subscribe(confd->session, "ietf-system", PLATFORM_PATH_, - platform_cb, NULL, SR_SUBSCR_DEFAULT, &confd->sub); - if (rc != SR_ERR_OK) - goto err; - REGISTER_CHANGE(confd->session, "ietf-system", "/ietf-system:system/hostname", 0, change_hostname, confd, &confd->sub); REGISTER_CHANGE(confd->session, "ietf-system", "/ietf-system:system/infix-system:motd", 0, change_motd, confd, &confd->sub); REGISTER_CHANGE(confd->session, "ietf-system", "/ietf-system:system/clock", 0, change_clock, confd, &confd->sub); REGISTER_CHANGE(confd->session, "ietf-system", "/ietf-system:system/ntp", 0, change_ntp, confd, &confd->sub); REGISTER_CHANGE(confd->session, "ietf-system", "/ietf-system:system/dns-resolver", 0, change_dns, confd, &confd->sub); + REGISTER_OPER(confd->session, "ietf-system", CLOCK_PATH_, clock_cb, NULL, 0, &confd->sub); + REGISTER_OPER(confd->session, "ietf-system", PLATFORM_PATH_, platform_cb, NULL, 0, &confd->sub); + REGISTER_RPC(confd->session, "/ietf-system:system-restart", rpc_exec, "reboot", &confd->sub); REGISTER_RPC(confd->session, "/ietf-system:system-shutdown", rpc_exec, "poweroff", &confd->sub); REGISTER_RPC(confd->session, "/ietf-system:set-current-datetime", rpc_set_datetime, NULL, &confd->sub); From a33963584301c71eacca2208c3202226758ef0ac Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sun, 16 Apr 2023 20:41:45 +0200 Subject: [PATCH 27/36] src/confd: add missing calls to release context in ieft-system Signed-off-by: Joachim Wiberg --- src/confd/src/ietf-system.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/confd/src/ietf-system.c b/src/confd/src/ietf-system.c index decd0ed73..646b5d1ad 100644 --- a/src/confd/src/ietf-system.c +++ b/src/confd/src/ietf-system.c @@ -111,6 +111,7 @@ static int clock_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *modu if (rc) { fail: ERROR("Failed building data tree, libyang error %d", rc); + sr_release_context(sr_session_get_connection(session)); return SR_ERR_INTERNAL; } @@ -138,6 +139,7 @@ static int clock_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *modu lyd_print_mem(&buf, *parent, LYD_XML, 0); DEBUG("%s", buf); + sr_release_context(sr_session_get_connection(session)); return SR_ERR_OK; } @@ -156,6 +158,7 @@ static int platform_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *m if (rc) { fail: ERROR("Failed building data tree, libyang error %d", rc); + sr_release_context(sr_session_get_connection(session)); return SR_ERR_INTERNAL; } @@ -178,6 +181,7 @@ static int platform_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *m lyd_print_mem(&buf, *parent, LYD_XML, 0); DEBUG("%s", buf); + sr_release_context(sr_session_get_connection(session)); return SR_ERR_OK; } From 1279fbdfda69b5e5138d2228109baf72265ad5aa Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sun, 16 Apr 2023 20:42:17 +0200 Subject: [PATCH 28/36] src/confd: add missing free() of data from lyd_print_mem() Signed-off-by: Joachim Wiberg --- src/confd/src/ietf-system.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/confd/src/ietf-system.c b/src/confd/src/ietf-system.c index 646b5d1ad..36eebe912 100644 --- a/src/confd/src/ietf-system.c +++ b/src/confd/src/ietf-system.c @@ -117,6 +117,7 @@ static int clock_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *modu lyd_print_mem(&buf, *parent, LYD_XML, 0); DEBUG("%s", buf); + free(buf); now = time(NULL); if (!boottime[0]) { @@ -138,6 +139,7 @@ static int clock_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *modu lyd_print_mem(&buf, *parent, LYD_XML, 0); DEBUG("%s", buf); + free(buf); sr_release_context(sr_session_get_connection(session)); return SR_ERR_OK; @@ -164,6 +166,7 @@ static int platform_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *m lyd_print_mem(&buf, *parent, LYD_XML, 0); DEBUG("%s", buf); + free(buf); rc = lyd_new_path(*parent, NULL, PLATFORM_PATH_"/os-name", os, 0, NULL); if (rc) @@ -180,6 +183,7 @@ static int platform_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *m lyd_print_mem(&buf, *parent, LYD_XML, 0); DEBUG("%s", buf); + free(buf); sr_release_context(sr_session_get_connection(session)); return SR_ERR_OK; From 9567284c9e4fe5c1d0b1ea48cd3e1336372bd61a Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sun, 16 Apr 2023 20:43:41 +0200 Subject: [PATCH 29/36] src/confd: initial operational data support for ietf-interfaces Signed-off-by: Joachim Wiberg --- src/confd/src/core.h | 1 + src/confd/src/ietf-interfaces.c | 166 +++++++++++++++++++++++++++++++- src/confd/src/srx_val.c | 37 +++++++ src/confd/src/srx_val.h | 3 + 4 files changed, 206 insertions(+), 1 deletion(-) diff --git a/src/confd/src/core.h b/src/confd/src/core.h index 6f28ac979..7e32fe782 100644 --- a/src/confd/src/core.h +++ b/src/confd/src/core.h @@ -14,6 +14,7 @@ #include #include +#include #include #include #include diff --git a/src/confd/src/ietf-interfaces.c b/src/confd/src/ietf-interfaces.c index f3420b0c1..8bbdd13be 100644 --- a/src/confd/src/ietf-interfaces.c +++ b/src/confd/src/ietf-interfaces.c @@ -1,22 +1,44 @@ /* SPDX-License-Identifier: BSD-3-Clause */ +#include + #include "core.h" #include "srx_module.h" #include "srx_val.h" +struct iface { + TAILQ_ENTRY(iface) link; + + int ifindex; + char ifname[IFNAMSIZ]; + char hwaddr[18]; + short flags; + uint64_t speed; + short vid; + short pvid; + char upper[IFNAMSIZ]; +}; + +static const char *iffeat[] = { + "if-mib", + NULL +}; + static const char *ipfeat[] = { "ipv4-non-contiguous-netmasks", NULL }; static const struct srx_module_requirement ietf_if_reqs[] = { - { .dir = YANG_PATH_, .name = "ietf-interfaces", .rev = "2018-02-20" }, + { .dir = YANG_PATH_, .name = "ietf-interfaces", .rev = "2018-02-20", .features = iffeat }, { .dir = YANG_PATH_, .name = "iana-if-type", .rev = "2017-01-19" }, { .dir = YANG_PATH_, .name = "ietf-ip", .rev = "2018-02-22", .features = ipfeat }, { NULL } }; +static TAILQ_HEAD(iflist, iface) iface_list = TAILQ_HEAD_INITIALIZER(iface_list); + static int inet_mask2len(char *netmask) { struct in_addr ina; @@ -33,6 +55,104 @@ static int inet_mask2len(char *netmask) return len; } +static void ifprobe(void) +{ + struct if_nameindex *if_list, *i; + + if_list = if_nameindex(); + if (!if_list) { + ERROR("failed if_nameindex(): %s", strerror(errno)); + return; + } + + for (i = if_list; !(i->if_index == 0 && i->if_name == NULL); i++) { + struct iface *iface; + + if (!i->if_name || i->if_index == 0) + continue; + + iface = calloc(1, sizeof(struct iface)); + if (!iface) { + ERROR("out of memory"); + return; + } + + iface->ifindex = i->if_index; + strlcpy(iface->ifname, i->if_name, sizeof(iface->ifname)); + + /* XXX: add other data */ + TAILQ_INSERT_TAIL(&iface_list, iface, link); + } + + if_freenameindex(if_list); +} + +#define INTERFACE_XPATH "/ietf-interfaces:interfaces/interface[name='%s']" + +static void ifpopul(sr_session_ctx_t *session) +{ + struct iface *iface; + int rc = 0; + + TAILQ_FOREACH(iface, &iface_list, link) { + char xpath[sizeof(INTERFACE_XPATH) + IFNAMSIZ + 42]; + sr_val_t val = { 0 }; + + snprintf(xpath, sizeof(xpath), INTERFACE_XPATH "/if-index", iface->ifname); + val.data.int32_val = iface->ifindex; + val.type = SR_INT32_T; + rc = sr_set_item(session, xpath, &val, 0); + if (rc) + ERROR("failed setting item %s", xpath); + snprintf(xpath, sizeof(xpath), INTERFACE_XPATH "/admin-status", iface->ifname); + val.data.enum_val = "up"; + val.type = SR_ENUM_T; + rc = sr_set_item(session, xpath, &val, 0); + if (rc) + ERROR("failed setting item %s", xpath); + + if (!iface->hwaddr[0]) /* e.g., loopback */ + continue; + + snprintf(xpath, sizeof(xpath), INTERFACE_XPATH "/phys-address", iface->ifname); + rc = sr_set_item_str(session, xpath, iface->hwaddr, 0, 0); + if (rc) + ERROR("failed setting item %s", xpath); + } + + rc = sr_apply_changes(session, 0); + if (rc) + ERROR("faled: %s", sr_strerror(rc)); +} + +static void ifinit(sr_session_ctx_t *session) +{ + struct iface *iface; + int rc = 0; + + TAILQ_FOREACH(iface, &iface_list, link) { + char xpath[sizeof(INTERFACE_XPATH) + IFNAMSIZ + 42]; + sr_val_t val; + + snprintf(xpath, sizeof(xpath), INTERFACE_XPATH "/type", iface->ifname); + if (!strcmp("lo", iface->ifname)) + val.data.string_val = "iana-if-type:softwareLoopback"; + else if (!strncmp("eth", iface->ifname, 3)) + val.data.string_val = "iana-if-type:ethernetCsmacd"; + else + continue; + + val.type = SR_IDENTITYREF_T; + rc = sr_set_item(session, xpath, &val, 0); + if (rc) + ERROR("failed setting item %s", xpath); + } + + rc = sr_apply_changes(session, 0); + if (rc) + ERROR("faled: %s", sr_strerror(rc)); +} + static int ifchange(sr_session_ctx_t *session, uint32_t sub_id, const char *module, const char *xpath, sr_event_t event, unsigned request_id, void *priv) { @@ -133,6 +253,42 @@ static int ifchange(sr_session_ctx_t *session, uint32_t sub_id, const char *modu return rc; } +static int ifoper(sr_session_ctx_t *session, uint32_t sub_id, const char *module, + const char *path, const char *request_path, uint32_t request_id, + struct lyd_node **parent, void *priv) +{ + char xpath[sizeof(INTERFACE_XPATH) + IFNAMSIZ + 42]; + const struct ly_ctx *ctx; + struct iface *iface; + int first = 1; + int rc = 0; + + ctx = sr_acquire_context(sr_session_get_connection(session)); + + TAILQ_FOREACH(iface, &iface_list, link) { + snprintf(xpath, sizeof(xpath), INTERFACE_XPATH, iface->ifname); + + if ((rc = srx_set_item(ctx, parent, &first, xpath, "if-index", "%d", iface->ifindex))) + goto fail; + + if ((rc = srx_set_item(ctx, parent, &first, xpath, "admin-status", "up"))) + goto fail; + + if ((rc = srx_set_item(ctx, parent, &first, xpath, "oper-status", "up"))) + goto fail; + + if (rc) { + fail: + ERROR("Failed building data tree, libyang error %d", rc); + sr_release_context(sr_session_get_connection(session)); + return SR_ERR_INTERNAL; + } + } + + sr_release_context(sr_session_get_connection(session)); + return SR_ERR_OK; +} + int ietf_interfaces_init(struct confd *confd) { int rc; @@ -141,7 +297,15 @@ int ietf_interfaces_init(struct confd *confd) if (rc) goto err; + ifprobe(); + REGISTER_CHANGE(confd->session, "ietf-interfaces", "/ietf-interfaces:interfaces", 0, ifchange, confd, &confd->sub); + REGISTER_OPER(confd->session, "ietf-interfaces", "/ietf-interfaces:interfaces", ifoper, NULL, 0, &confd->sub); + + sr_session_switch_ds(confd->session, SR_DS_OPERATIONAL); + ifpopul(confd->session); + sr_session_switch_ds(confd->session, SR_DS_RUNNING); + ifinit(confd->session); return SR_ERR_OK; err: diff --git a/src/confd/src/srx_val.c b/src/confd/src/srx_val.c index 705bfd17a..a74d494ec 100644 --- a/src/confd/src/srx_val.c +++ b/src/confd/src/srx_val.c @@ -3,6 +3,43 @@ #include #include "core.h" +int srx_set_item(const struct ly_ctx *ctx, struct lyd_node **parent, int *first, + char *xpath_base, char *node, const char *fmt, ...) +{ + char xpath[strlen(xpath_base) + strlen(node) + 2]; + va_list ap; + size_t len; + char *val; + int rc; + + va_start(ap, fmt); + len = vsnprintf(NULL, 0, fmt, ap) + 1; + va_end(ap); + + val = alloca(len); + if (!val) + return -1; + + snprintf(xpath, sizeof(xpath), "%s/%s", xpath_base, node); + va_start(ap, fmt); + vsnprintf(val, len, fmt, ap); + va_end(ap); + + DEBUG("Setting first:%d xpath %s to %s", *first, xpath, val); + + if (*first) + rc = lyd_new_path(NULL, ctx, xpath, val, 0, parent); + else + rc = lyd_new_path(*parent, NULL, xpath, val, 0, NULL); + + *first = 0; + if (rc) + ERROR("Failed building data tree, xpath %s, libyang error %d: %s", + xpath, rc, ly_errmsg(ctx)); + + return rc; +} + static int srx_vaget(sr_session_ctx_t *session, const char *fmt, va_list ap, sr_val_type_t type, sr_val_t **val, size_t *cnt) { va_list apdup; diff --git a/src/confd/src/srx_val.h b/src/confd/src/srx_val.h index abefe54dc..669644e2b 100644 --- a/src/confd/src/srx_val.h +++ b/src/confd/src/srx_val.h @@ -8,6 +8,9 @@ #define SRX_GET_UINT8(s,v,fmt,...) srx_get_int(s, &v, SR_UINT8_T, fmt, ##__VA_ARGS__) #define SRX_GET_UINT32(s,v,fmt,...) srx_get_int(s, &v, SR_UINT32_T, fmt, ##__VA_ARGS__) +int srx_set_item(const struct ly_ctx *ctx, struct lyd_node **parent, int *first, char *xpath_base, + char *node, const char *fmt, ...); + char *srx_get_str (sr_session_ctx_t *session, const char *fmt, ...); int srx_get_int (sr_session_ctx_t *session, int *result, sr_val_type_t type, const char *fmt, ...); int srx_get_bool (sr_session_ctx_t *session, const char *fmt, ...); From 70bac457a028aad0aa5627c679574162ad6b66e1 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sun, 16 Apr 2023 20:45:45 +0200 Subject: [PATCH 30/36] src/confd: standardize on 'fail:' as cleanup label on failure Signed-off-by: Joachim Wiberg --- src/confd/src/core.h | 6 +++--- src/confd/src/ietf-interfaces.c | 4 ++-- src/confd/src/ietf-system.c | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/confd/src/core.h b/src/confd/src/core.h index 7e32fe782..fcc277cf1 100644 --- a/src/confd/src/core.h +++ b/src/confd/src/core.h @@ -46,15 +46,15 @@ static inline void print_val(sr_val_t *val) #define REGISTER_CHANGE(s,m,x,f,c,a,u) \ if ((rc = register_change(s, m, x, f, c, a, u))) \ - goto err + goto fail #define REGISTER_OPER(s,m,x,c,a,f,u) \ if ((rc = register_oper(s, m, x, c, a, f, u))) \ - goto err + goto fail #define REGISTER_RPC(s,x,c,a,u) \ if ((rc = register_rpc(s, x, c, a, u))) \ - goto err + goto fail struct confd { sr_session_ctx_t *session; diff --git a/src/confd/src/ietf-interfaces.c b/src/confd/src/ietf-interfaces.c index 8bbdd13be..565336bc9 100644 --- a/src/confd/src/ietf-interfaces.c +++ b/src/confd/src/ietf-interfaces.c @@ -295,7 +295,7 @@ int ietf_interfaces_init(struct confd *confd) rc = srx_require_modules(confd->conn, ietf_if_reqs); if (rc) - goto err; + goto fail; ifprobe(); @@ -308,7 +308,7 @@ int ietf_interfaces_init(struct confd *confd) ifinit(confd->session); return SR_ERR_OK; -err: +fail: ERROR("init failed: %s", sr_strerror(rc)); sr_unsubscribe(confd->sub); diff --git a/src/confd/src/ietf-system.c b/src/confd/src/ietf-system.c index 36eebe912..e2c12465b 100644 --- a/src/confd/src/ietf-system.c +++ b/src/confd/src/ietf-system.c @@ -636,16 +636,16 @@ int ietf_system_init(struct confd *confd) if (aug_load_file(confd->aug, "/etc/hostname") || aug_load_file(confd->aug, "/etc/hosts")) { ERROR("ietf-system: Augeas initialization failed"); - goto err; + goto fail; } rc = sr_install_module(confd->conn, YANG_PATH_"/ietf-system@2014-08-06.yang", NULL, features); if (rc) - goto err; + goto fail; /* Augment to ietf-systems */ rc = sr_install_module(confd->conn, YANG_PATH_"/infix-system@2014-08-06.yang", NULL, NULL); if (rc) - goto err; + goto fail; REGISTER_CHANGE(confd->session, "ietf-system", "/ietf-system:system/hostname", 0, change_hostname, confd, &confd->sub); REGISTER_CHANGE(confd->session, "ietf-system", "/ietf-system:system/infix-system:motd", 0, change_motd, confd, &confd->sub); @@ -661,7 +661,7 @@ int ietf_system_init(struct confd *confd) REGISTER_RPC(confd->session, "/ietf-system:set-current-datetime", rpc_set_datetime, NULL, &confd->sub); return SR_ERR_OK; -err: +fail: ERROR("init failed: %s", sr_strerror(rc)); sr_unsubscribe(confd->sub); From 7e089ee259bf5213578b49f18ced68ef2ee27654 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sun, 16 Apr 2023 20:47:07 +0200 Subject: [PATCH 31/36] qemu: disable bond0, dummy0, sit0, erspan0, etc. fallback interfaces Signed-off-by: Joachim Wiberg --- qemu/qemu.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qemu/qemu.sh b/qemu/qemu.sh index 3e02839fa..845b2d151 100755 --- a/qemu/qemu.sh +++ b/qemu/qemu.sh @@ -51,7 +51,7 @@ append_args() echo -n "debug " fi - echo -n "${QEMU_APPEND} ${QEMU_EXTRA_APPEND} " + echo -n "${QEMU_APPEND} bonding.max_bonds=0 dummy.numdummies=0 fb_tunnels=none ${QEMU_EXTRA_APPEND} " } rootfs_args() From 31f71b1539500a6c78fe794c834997bd9ec734fb Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sun, 16 Apr 2023 23:43:44 +0200 Subject: [PATCH 32/36] src/confd: refactor, simplify ietf-system:system-state We now have our own srx_set_item() that hides a lot of the complexity. Signed-off-by: Joachim Wiberg --- src/confd/src/ietf-system.c | 71 +++++++++++-------------------------- 1 file changed, 21 insertions(+), 50 deletions(-) diff --git a/src/confd/src/ietf-system.c b/src/confd/src/ietf-system.c index e2c12465b..aa259d2eb 100644 --- a/src/confd/src/ietf-system.c +++ b/src/confd/src/ietf-system.c @@ -101,24 +101,11 @@ static int clock_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *modu const struct ly_ctx *ctx; char curtime[64]; time_t now, boot; - char *buf; + int first = 1; int rc; - DEBUG("path=%s, request_path=%s", path, request_path); ctx = sr_acquire_context(sr_session_get_connection(session)); - rc = lyd_new_path(NULL, ctx, CLOCK_PATH_, NULL, 0, parent); - if (rc) { - fail: - ERROR("Failed building data tree, libyang error %d", rc); - sr_release_context(sr_session_get_connection(session)); - return SR_ERR_INTERNAL; - } - - lyd_print_mem(&buf, *parent, LYD_XML, 0); - DEBUG("%s", buf); - free(buf); - now = time(NULL); if (!boottime[0]) { struct sysinfo si; @@ -127,22 +114,21 @@ static int clock_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *modu boot = now - si.uptime; fmtime(boot, boottime, sizeof(boottime)); } + fmtime(now, curtime, sizeof(curtime)); - rc = lyd_new_path(*parent, NULL, CLOCK_PATH_ "/boot-datetime", boottime, 0, NULL); - if (rc) + if ((rc = srx_set_item(ctx, parent, &first, CLOCK_PATH_, "boot-datetime", boottime))) goto fail; - - fmtime(now, curtime, sizeof(curtime)); - rc = lyd_new_path(*parent, NULL, CLOCK_PATH_ "/current-datetime", curtime, 0, NULL); - if (rc) + if ((rc = srx_set_item(ctx, parent, &first, CLOCK_PATH_, "current-datetime", curtime))) goto fail; - lyd_print_mem(&buf, *parent, LYD_XML, 0); - DEBUG("%s", buf); - free(buf); + if (rc) { + fail: + ERROR("Failed building data tree, libyang error %d", rc); + rc = SR_ERR_INTERNAL; + } sr_release_context(sr_session_get_connection(session)); - return SR_ERR_OK; + return rc; } static int platform_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *module, @@ -150,43 +136,28 @@ static int platform_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *m struct lyd_node **parent, void *priv) { const struct ly_ctx *ctx; - char *buf; + int first = 1; int rc; - DEBUG("path=%s request_path=%s", path, request_path); ctx = sr_acquire_context(sr_session_get_connection(session)); - rc = lyd_new_path(NULL, ctx, PLATFORM_PATH_, NULL, 0, parent); - if (rc) { - fail: - ERROR("Failed building data tree, libyang error %d", rc); - sr_release_context(sr_session_get_connection(session)); - return SR_ERR_INTERNAL; - } - - lyd_print_mem(&buf, *parent, LYD_XML, 0); - DEBUG("%s", buf); - free(buf); - - rc = lyd_new_path(*parent, NULL, PLATFORM_PATH_"/os-name", os, 0, NULL); - if (rc) + if ((rc = srx_set_item(ctx, parent, &first, PLATFORM_PATH_, "os-name", os))) goto fail; - rc = lyd_new_path(*parent, NULL, PLATFORM_PATH_"/os-release", rel, 0, NULL); - if (rc) + if ((rc = srx_set_item(ctx, parent, &first, PLATFORM_PATH_, "os-release", rel))) goto fail; - rc = lyd_new_path(*parent, NULL, PLATFORM_PATH_"/os-version", ver, 0, NULL); - if (rc) + if ((rc = srx_set_item(ctx, parent, &first, PLATFORM_PATH_, "os-version", ver))) goto fail; - rc = lyd_new_path(*parent, NULL, PLATFORM_PATH_"/machine", sys, 0, NULL); - if (rc) + if ((rc = srx_set_item(ctx, parent, &first, PLATFORM_PATH_, "machine", sys))) goto fail; - lyd_print_mem(&buf, *parent, LYD_XML, 0); - DEBUG("%s", buf); - free(buf); + if (rc) { + fail: + ERROR("Failed building data tree, libyang error %d", rc); + rc = SR_ERR_INTERNAL; + } sr_release_context(sr_session_get_connection(session)); - return SR_ERR_OK; + return rc; } static int rpc_exec(sr_session_ctx_t *session, uint32_t sub_id, const char *path, From 2d29e63d3e4307dae73cfca45965487d7e9b8f92 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Mon, 17 Apr 2023 00:19:39 +0200 Subject: [PATCH 33/36] src/confd: set default loopback addresses Signed-off-by: Joachim Wiberg --- src/confd/src/ietf-interfaces.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/confd/src/ietf-interfaces.c b/src/confd/src/ietf-interfaces.c index 565336bc9..0e0fb7a30 100644 --- a/src/confd/src/ietf-interfaces.c +++ b/src/confd/src/ietf-interfaces.c @@ -115,7 +115,7 @@ static void ifpopul(sr_session_ctx_t *session) continue; snprintf(xpath, sizeof(xpath), INTERFACE_XPATH "/phys-address", iface->ifname); - rc = sr_set_item_str(session, xpath, iface->hwaddr, 0, 0); + rc = sr_set_item_str(session, xpath, iface->hwaddr, NULL, 0); if (rc) ERROR("failed setting item %s", xpath); } @@ -131,7 +131,7 @@ static void ifinit(sr_session_ctx_t *session) int rc = 0; TAILQ_FOREACH(iface, &iface_list, link) { - char xpath[sizeof(INTERFACE_XPATH) + IFNAMSIZ + 42]; + char xpath[sizeof(INTERFACE_XPATH) + IFNAMSIZ + 128]; sr_val_t val; snprintf(xpath, sizeof(xpath), INTERFACE_XPATH "/type", iface->ifname); @@ -143,9 +143,25 @@ static void ifinit(sr_session_ctx_t *session) continue; val.type = SR_IDENTITYREF_T; - rc = sr_set_item(session, xpath, &val, 0); - if (rc) + if ((rc = sr_set_item(session, xpath, &val, 0))) + goto fail; + + if (strcmp(iface->ifname, "lo")) + continue; + + snprintf(xpath, sizeof(xpath), INTERFACE_XPATH + "/ietf-ip:ipv4/address[ip='%s']/prefix-length", iface->ifname, "127.0.0.1"); + if ((rc = sr_set_item_str(session, xpath, "8", NULL, 0))) + goto fail; + + snprintf(xpath, sizeof(xpath), INTERFACE_XPATH + "/ietf-ip:ipv6/address[ip='%s']/prefix-length", iface->ifname, "::1"); + rc = sr_set_item_str(session, xpath, "128", NULL, 0); + if (rc) { + fail: ERROR("failed setting item %s", xpath); + continue; + } } rc = sr_apply_changes(session, 0); From a41343b3fae325ac1435d588f57a2ec4e0b6521e Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Mon, 17 Apr 2023 12:50:25 +0200 Subject: [PATCH 34/36] Follow-up to 025a877, import new iana-if-type version Signed-off-by: Joachim Wiberg --- src/confd/src/ietf-interfaces.c | 2 +- ...1-19.yang => iana-if-type@2023-01-26.yang} | 238 +++++++++++++++++- 2 files changed, 236 insertions(+), 4 deletions(-) rename src/confd/yang/{iana-if-type@2017-01-19.yang => iana-if-type@2023-01-26.yang} (88%) diff --git a/src/confd/src/ietf-interfaces.c b/src/confd/src/ietf-interfaces.c index 0e0fb7a30..3d56e1d3c 100644 --- a/src/confd/src/ietf-interfaces.c +++ b/src/confd/src/ietf-interfaces.c @@ -31,7 +31,7 @@ static const char *ipfeat[] = { static const struct srx_module_requirement ietf_if_reqs[] = { { .dir = YANG_PATH_, .name = "ietf-interfaces", .rev = "2018-02-20", .features = iffeat }, - { .dir = YANG_PATH_, .name = "iana-if-type", .rev = "2017-01-19" }, + { .dir = YANG_PATH_, .name = "iana-if-type", .rev = "2023-01-26" }, { .dir = YANG_PATH_, .name = "ietf-ip", .rev = "2018-02-22", .features = ipfeat }, { NULL } diff --git a/src/confd/yang/iana-if-type@2017-01-19.yang b/src/confd/yang/iana-if-type@2023-01-26.yang similarity index 88% rename from src/confd/yang/iana-if-type@2017-01-19.yang rename to src/confd/yang/iana-if-type@2023-01-26.yang index 7bfee3647..fea9330bf 100644 --- a/src/confd/yang/iana-if-type@2017-01-19.yang +++ b/src/confd/yang/iana-if-type@2023-01-26.yang @@ -16,7 +16,7 @@ module iana-if-type { United States Tel: +1 310 301 5800 - "; + "; description "This YANG module defines YANG identities for IANA-registered interface types. @@ -28,7 +28,7 @@ module iana-if-type { the IANA web site. Requests for new values should be made to IANA via - email (iana&iana.org). + email (iana@iana.org). Copyright (c) 2014 IETF Trust and the persons identified as authors of the code. All rights reserved. @@ -46,6 +46,124 @@ module iana-if-type { "IANA 'ifType definitions' registry. "; + revision 2023-01-26 { + description + "Fix incorrect quotation for previous 3 revision statements."; + } + + revision 2022-08-24 { + description + "Updated reference for ifType 303."; + } + + revision 2022-08-17 { + description + "Changed gpon description to refer to G.984."; + } + + revision 2022-03-07 { + description + "Coalesced revision history entries for 2018-06-28."; + } + + revision 2021-06-21 { + description + "Corrected reference for ifType 303."; + } + + revision 2021-05-17 { + description + "Registered ifType 303."; + } + + revision 2021-04-22 { + description + "Registered ifType 302."; + } + + revision 2021-04-01 { + description + "Updated reference for 301."; + } + + revision 2021-02-18 { + description + "Registered ifType 301."; + } + + revision 2020-08-27 { + description + "Added missing references."; + } + + revision 2020-07-13 { + description + "Added identity cpri."; + } + + revision 2020-07-10 { + description + "Registered ifType 300."; + } + + revision 2020-01-10 { + description + "Registered ifType 299."; + } + + revision 2019-10-16 { + description + "Registered ifType 298."; + } + revision 2019-07-16 { + description + "Registered ifType 297."; + } + revision 2019-06-21 { + description + "Updated reference associated with ifTypes 295-296."; + } + + revision 2019-02-08 { + description + "Corrected formatting issue."; + } + + revision 2019-01-31 { + description + "Registered ifTypes 295-296."; + } + + revision 2018-07-03 { + description + "Corrected revision date."; + } + + revision 2018-06-29 { + description + "Corrected formatting issue."; + } + + revision 2018-06-28 { + description + "Registered ifTypes 293 and 294."; + } + + revision 2018-06-22 { + description + "Registered ifType 292."; + } + + revision 2018-06-21 { + description + "Registered ifType 291."; + } + + revision 2017-03-30 { + description + "Registered ifType 290."; + } + revision 2017-01-19 { description "Registered ifType 289."; @@ -1410,7 +1528,7 @@ module iana-if-type { base iana-interface-type; description "Gigabit-capable passive optical networks (G-PON) as per - ITU-T G.948."; + ITU-T G.984."; } identity vdsl2 { base iana-interface-type; @@ -1549,11 +1667,17 @@ module iana-if-type { base iana-interface-type; description "CATV Downstream OFDM interface."; + reference + "Cable Modem Operations Support System Interface + Specification"; } identity docsOfdmaUpstream { base iana-interface-type; description "CATV Upstream OFDMA interface."; + reference + "Cable Modem Operations Support System Interface + Specification"; } identity gfast { base iana-interface-type; @@ -1585,21 +1709,29 @@ module iana-if-type { base iana-interface-type; description "Cable SCTE 55-1 OOB Forward Channel."; + reference + "ANSI/SCTE 55-1 2009"; } identity docsCableScte55d1RetOob { base iana-interface-type; description "Cable SCTE 55-1 OOB Return Channel."; + reference + "ANSI/SCTE 55-1 2009"; } identity docsCableScte55d2DsOob { base iana-interface-type; description "Cable SCTE 55-2 OOB Downstream Channel."; + reference + "ANSI/SCTE 55-2 2008"; } identity docsCableScte55d2UsOob { base iana-interface-type; description "Cable SCTE 55-2 OOB Upstream Channel."; + reference + "ANSI/SCTE 55-2 2008"; } identity docsCableNdf { base iana-interface-type; @@ -1615,5 +1747,105 @@ module iana-if-type { base iana-interface-type; description "Packet Transfer Mode."; + reference + "IEEE G.993.1, Annex H; IEEE G.993.2; IEEE G.9701"; + } + identity ghn { + base iana-interface-type; + description + "G.hn port."; + reference + "IEEE G.9961"; + } + identity otnOtsi { + base iana-interface-type; + description + "Optical Tributary Signal."; + reference + "ITU-T G.959.1"; + } + identity otnOtuc { + base iana-interface-type; + description + "OTN OTUCn."; + reference + "ITU-T G.709/Y.1331"; + } + identity otnOduc { + base iana-interface-type; + description + "OTN ODUC."; + reference + "ITU-T G.709"; + } + identity otnOtsig { + base iana-interface-type; + description + "OTN OTUC Signal."; + reference + "ITU-T G.709"; + } + identity microwaveCarrierTermination { + base iana-interface-type; + description + "air interface of a single microwave carrier."; + reference + "RFC 8561 - A YANG Data Model for Microwave Radio Link"; + } + identity microwaveRadioLinkTerminal { + base iana-interface-type; + description + "radio link interface for one or several aggregated microwave carriers."; + reference + "RFC 8561 - A YANG Data Model for Microwave Radio Link"; + } + identity ieee8021axDrni { + base iana-interface-type; + description + "IEEE 802.1AX Distributed Resilient Network Interface."; + reference + "IEEE 802.1AX-Rev-d2-0"; + } + identity ax25 { + base iana-interface-type; + description + "AX.25 network interfaces."; + reference + "AX.25 Link Access Protocol for Amateur Packet Radio version 2.2"; + } + identity ieee19061nanocom { + base iana-interface-type; + description + "Nanoscale and Molecular Communication."; + reference + "IEEE 1906.1-2015"; + } + identity cpri { + base iana-interface-type; + description + "Common Public Radio Interface."; + reference + "CPRI v7.0"; + } + identity omni { + base iana-interface-type; + description + "Overlay Multilink Network Interface (OMNI)."; + reference + "draft-templin-6man-omni-00"; + } + identity roe { + base iana-interface-type; + description + "Radio over Ethernet Interface."; + reference + "1914.3-2018 - IEEE Standard for Radio over Ethernet Encapsulations and Mappings"; + } + identity p2pOverLan { + base iana-interface-type; + description + "Point to Point over LAN interface."; + reference + "RFC 9296 - ifStackTable for the Point-to-Point (P2P) Interface over a LAN Type: Definition and Examples"; } } From a3195ef6f3396db536ec172214e57f0268a13638 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Mon, 17 Apr 2023 13:57:16 +0200 Subject: [PATCH 35/36] Follow-up to 7e089ee: convert to kernel modules, use /etc/modprobe.d Instead of having to rely on the kernel command line, we convert all the kernel functionality in question into modules and rely on the auto-load feature in the kernel and modprobe to add options at load time. The fb_tunnels setting is a net core setting, for that we use sysctl. This commit also syncs the kernel config between our two main archs, disabling DRM and SOUND for the Amd64 build as a spin-off. Signed-off-by: Joachim Wiberg --- board/aarch64/linux_defconfig | 109 ++++++++++++---- board/amd64/linux_defconfig | 117 +++++++++++++----- .../common/rootfs/etc/modprobe.d/bonding.conf | 2 + board/common/rootfs/etc/modprobe.d/dummy.conf | 2 + board/common/rootfs/etc/sysctl.d/system.conf | 1 + qemu/qemu.sh | 2 +- 6 files changed, 180 insertions(+), 53 deletions(-) create mode 100644 board/common/rootfs/etc/modprobe.d/bonding.conf create mode 100644 board/common/rootfs/etc/modprobe.d/dummy.conf create mode 100644 board/common/rootfs/etc/sysctl.d/system.conf diff --git a/board/aarch64/linux_defconfig b/board/aarch64/linux_defconfig index ca1ab4c2b..3ad3f1315 100644 --- a/board/aarch64/linux_defconfig +++ b/board/aarch64/linux_defconfig @@ -67,28 +67,32 @@ CONFIG_CMA=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y +CONFIG_XDP_SOCKETS=y +CONFIG_XDP_SOCKETS_DIAG=y CONFIG_INET=y CONFIG_IP_MULTICAST=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_NET_IPIP=y -CONFIG_NET_IPGRE_DEMUX=y -CONFIG_NET_IPGRE=y +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m +CONFIG_NET_IPGRE=m CONFIG_NET_IPGRE_BROADCAST=y CONFIG_IP_MROUTE=y CONFIG_IP_MROUTE_MULTIPLE_TABLES=y CONFIG_IP_PIMSM_V1=y CONFIG_IP_PIMSM_V2=y -CONFIG_NET_IPVTI=y +CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=m +CONFIG_NET_FOU_IP_TUNNELS=y +CONFIG_IPV6_SIT=m +CONFIG_IPV6_GRE=m CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_IPV6_SUBTREES=y CONFIG_IPV6_MROUTE=y CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y CONFIG_IPV6_PIMSM_V2=y +CONFIG_NETWORK_PHY_TIMESTAMPING=y CONFIG_NETFILTER=y CONFIG_BRIDGE_NETFILTER=y CONFIG_NETFILTER_NETLINK_QUEUE=y @@ -98,6 +102,26 @@ CONFIG_NF_CONNTRACK_EVENTS=y CONFIG_NF_CONNTRACK_FTP=y CONFIG_NF_TABLES=y CONFIG_NF_TABLES_INET=y +CONFIG_NF_TABLES_NETDEV=y +CONFIG_NFT_CT=m +CONFIG_NFT_CONNLIMIT=m +CONFIG_NFT_LOG=m +CONFIG_NFT_LIMIT=m +CONFIG_NFT_MASQ=m +CONFIG_NFT_REDIR=m +CONFIG_NFT_NAT=m +CONFIG_NFT_TUNNEL=m +CONFIG_NFT_OBJREF=m +CONFIG_NFT_QUEUE=m +CONFIG_NFT_REJECT=m +CONFIG_NFT_COMPAT=m +CONFIG_NFT_HASH=m +CONFIG_NFT_XFRM=m +CONFIG_NFT_SOCKET=m +CONFIG_NFT_OSF=m +CONFIG_NFT_DUP_NETDEV=m +CONFIG_NFT_FWD_NETDEV=m +CONFIG_NFT_REJECT_NETDEV=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_LOG=m CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m @@ -108,7 +132,37 @@ CONFIG_IP_NF_TARGET_REJECT=m CONFIG_IP_NF_NAT=m CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_MANGLE=m -CONFIG_NF_LOG_IPV6=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_NAT=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m +CONFIG_NF_TABLES_BRIDGE=m +CONFIG_NFT_BRIDGE_META=m +CONFIG_NF_CONNTRACK_BRIDGE=m +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_NFLOG=m CONFIG_BRIDGE=y CONFIG_BRIDGE_VLAN_FILTERING=y CONFIG_BRIDGE_MRP=y @@ -117,9 +171,16 @@ CONFIG_NET_DSA=y CONFIG_VLAN_8021Q=y CONFIG_VLAN_8021Q_GVRP=y CONFIG_VLAN_8021Q_MVRP=y -CONFIG_NET_L3_MASTER_DEV=y +CONFIG_NETLINK_DIAG=y +CONFIG_MPLS=y +CONFIG_NET_MPLS_GSO=y +CONFIG_MPLS_ROUTING=m +CONFIG_MPLS_IPTUNNEL=m +CONFIG_NET_PKTGEN=y +# CONFIG_WIRELESS is not set CONFIG_NET_9P=y CONFIG_NET_9P_VIRTIO=y +CONFIG_LWTUNNEL=y CONFIG_PCI=y CONFIG_PCIEPORTBUS=y CONFIG_PCI_IOV=y @@ -163,21 +224,21 @@ CONFIG_DM_INIT=y CONFIG_DM_VERITY=y CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y CONFIG_NETDEVICES=y -CONFIG_BONDING=y -CONFIG_DUMMY=y -CONFIG_NET_TEAM=y -CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=y -CONFIG_NET_TEAM_MODE_LOADBALANCE=y -CONFIG_MACVLAN=y -CONFIG_MACVTAP=y -CONFIG_IPVLAN=y -CONFIG_IPVTAP=y -CONFIG_VXLAN=y -CONFIG_GENEVE=y -CONFIG_BAREUDP=y -CONFIG_MACSEC=y -CONFIG_TUN=y -CONFIG_VETH=y +CONFIG_BONDING=m +CONFIG_DUMMY=m +CONFIG_NET_TEAM=m +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m +CONFIG_NET_TEAM_MODE_LOADBALANCE=m +CONFIG_MACVLAN=m +CONFIG_MACVTAP=m +CONFIG_IPVLAN=m +CONFIG_IPVTAP=m +CONFIG_VXLAN=m +CONFIG_GENEVE=m +CONFIG_BAREUDP=m +CONFIG_MACSEC=m +CONFIG_TUN=m +CONFIG_VETH=m CONFIG_VIRTIO_NET=y CONFIG_NLMON=y CONFIG_NET_VRF=y diff --git a/board/amd64/linux_defconfig b/board/amd64/linux_defconfig index 423675b5c..bc141589a 100644 --- a/board/amd64/linux_defconfig +++ b/board/amd64/linux_defconfig @@ -38,25 +38,32 @@ CONFIG_MODULE_UNLOAD=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y +CONFIG_XDP_SOCKETS=y +CONFIG_XDP_SOCKETS_DIAG=y CONFIG_INET=y CONFIG_IP_MULTICAST=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_NET_IPIP=y -CONFIG_NET_IPGRE_DEMUX=y -CONFIG_NET_IPGRE=y +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m +CONFIG_NET_IPGRE=m CONFIG_NET_IPGRE_BROADCAST=y CONFIG_IP_MROUTE=y CONFIG_IP_MROUTE_MULTIPLE_TABLES=y CONFIG_IP_PIMSM_V1=y CONFIG_IP_PIMSM_V2=y -CONFIG_NET_IPVTI=y +CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=m +CONFIG_NET_FOU_IP_TUNNELS=y +CONFIG_IPV6_SIT=m +CONFIG_IPV6_GRE=m CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_IPV6_SUBTREES=y CONFIG_IPV6_MROUTE=y CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y CONFIG_IPV6_PIMSM_V2=y +CONFIG_NETWORK_PHY_TIMESTAMPING=y CONFIG_NETFILTER=y CONFIG_BRIDGE_NETFILTER=y CONFIG_NETFILTER_NETLINK_QUEUE=y @@ -66,6 +73,26 @@ CONFIG_NF_CONNTRACK_EVENTS=y CONFIG_NF_CONNTRACK_FTP=y CONFIG_NF_TABLES=y CONFIG_NF_TABLES_INET=y +CONFIG_NF_TABLES_NETDEV=y +CONFIG_NFT_CT=m +CONFIG_NFT_CONNLIMIT=m +CONFIG_NFT_LOG=m +CONFIG_NFT_LIMIT=m +CONFIG_NFT_MASQ=m +CONFIG_NFT_REDIR=m +CONFIG_NFT_NAT=m +CONFIG_NFT_TUNNEL=m +CONFIG_NFT_OBJREF=m +CONFIG_NFT_QUEUE=m +CONFIG_NFT_REJECT=m +CONFIG_NFT_COMPAT=m +CONFIG_NFT_HASH=m +CONFIG_NFT_XFRM=m +CONFIG_NFT_SOCKET=m +CONFIG_NFT_OSF=m +CONFIG_NFT_DUP_NETDEV=m +CONFIG_NFT_FWD_NETDEV=m +CONFIG_NFT_REJECT_NETDEV=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_LOG=m CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m @@ -76,7 +103,37 @@ CONFIG_IP_NF_TARGET_REJECT=m CONFIG_IP_NF_NAT=m CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_MANGLE=m -CONFIG_NF_LOG_IPV6=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_NAT=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m +CONFIG_NF_TABLES_BRIDGE=m +CONFIG_NFT_BRIDGE_META=m +CONFIG_NF_CONNTRACK_BRIDGE=m +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_NFLOG=m CONFIG_BRIDGE=y CONFIG_BRIDGE_VLAN_FILTERING=y CONFIG_BRIDGE_MRP=y @@ -84,8 +141,16 @@ CONFIG_BRIDGE_CFM=y CONFIG_VLAN_8021Q=y CONFIG_VLAN_8021Q_GVRP=y CONFIG_VLAN_8021Q_MVRP=y +CONFIG_NETLINK_DIAG=y +CONFIG_MPLS=y +CONFIG_NET_MPLS_GSO=y +CONFIG_MPLS_ROUTING=m +CONFIG_MPLS_IPTUNNEL=m +CONFIG_NET_PKTGEN=y +# CONFIG_WIRELESS is not set CONFIG_NET_9P=y CONFIG_NET_9P_VIRTIO=y +CONFIG_LWTUNNEL=y CONFIG_PCI=y CONFIG_UEVENT_HELPER=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" @@ -107,21 +172,21 @@ CONFIG_BLK_DEV_DM=y CONFIG_DM_VERITY=y CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y CONFIG_NETDEVICES=y -CONFIG_BONDING=y -CONFIG_DUMMY=y -CONFIG_NET_TEAM=y -CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=y -CONFIG_NET_TEAM_MODE_LOADBALANCE=y -CONFIG_MACVLAN=y -CONFIG_MACVTAP=y -CONFIG_IPVLAN=y -CONFIG_IPVTAP=y -CONFIG_VXLAN=y -CONFIG_GENEVE=y -CONFIG_BAREUDP=y -CONFIG_MACSEC=y -CONFIG_TUN=y -CONFIG_VETH=y +CONFIG_BONDING=m +CONFIG_DUMMY=m +CONFIG_NET_TEAM=m +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m +CONFIG_NET_TEAM_MODE_LOADBALANCE=m +CONFIG_MACVLAN=m +CONFIG_MACVTAP=m +CONFIG_IPVLAN=m +CONFIG_IPVTAP=m +CONFIG_VXLAN=m +CONFIG_GENEVE=m +CONFIG_BAREUDP=m +CONFIG_MACSEC=m +CONFIG_TUN=m +CONFIG_VETH=m CONFIG_VIRTIO_NET=y CONFIG_NLMON=y CONFIG_NET_VRF=y @@ -134,24 +199,18 @@ CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_VIRTIO_CONSOLE=y CONFIG_HW_RANDOM_VIRTIO=m +CONFIG_I2C=y CONFIG_WATCHDOG=y CONFIG_WATCHDOG_SYSFS=y CONFIG_SOFT_WATCHDOG=y CONFIG_I6300ESB_WDT=y -CONFIG_DRM=y -CONFIG_DRM_QXL=y -CONFIG_DRM_VIRTIO_GPU=y -CONFIG_DRM_BOCHS=y -CONFIG_SOUND=y -CONFIG_SND=y -CONFIG_SND_HDA_INTEL=y -CONFIG_SND_HDA_GENERIC=y CONFIG_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_UHCI_HCD=y CONFIG_USB_STORAGE=y CONFIG_RTC_CLASS=y +CONFIG_SYNC_FILE=y CONFIG_VIRTIO_PCI=y CONFIG_VIRTIO_BALLOON=y CONFIG_VIRTIO_INPUT=y @@ -172,7 +231,9 @@ CONFIG_SQUASHFS_ZSTD=y CONFIG_9P_FS=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y +CONFIG_CRYPTO_GCM=y CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_AES=y CONFIG_DEBUG_KERNEL=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_FS=y diff --git a/board/common/rootfs/etc/modprobe.d/bonding.conf b/board/common/rootfs/etc/modprobe.d/bonding.conf new file mode 100644 index 000000000..88f138543 --- /dev/null +++ b/board/common/rootfs/etc/modprobe.d/bonding.conf @@ -0,0 +1,2 @@ +options bonding max_bonds=0 + diff --git a/board/common/rootfs/etc/modprobe.d/dummy.conf b/board/common/rootfs/etc/modprobe.d/dummy.conf new file mode 100644 index 000000000..022ea0773 --- /dev/null +++ b/board/common/rootfs/etc/modprobe.d/dummy.conf @@ -0,0 +1,2 @@ +options dummy numdummies=0 + diff --git a/board/common/rootfs/etc/sysctl.d/system.conf b/board/common/rootfs/etc/sysctl.d/system.conf new file mode 100644 index 000000000..cca845303 --- /dev/null +++ b/board/common/rootfs/etc/sysctl.d/system.conf @@ -0,0 +1 @@ +net.core.fb_tunnels_only_for_init_net=2 diff --git a/qemu/qemu.sh b/qemu/qemu.sh index 845b2d151..3e02839fa 100755 --- a/qemu/qemu.sh +++ b/qemu/qemu.sh @@ -51,7 +51,7 @@ append_args() echo -n "debug " fi - echo -n "${QEMU_APPEND} bonding.max_bonds=0 dummy.numdummies=0 fb_tunnels=none ${QEMU_EXTRA_APPEND} " + echo -n "${QEMU_APPEND} ${QEMU_EXTRA_APPEND} " } rootfs_args() From 0eda972889d9d478d28bc7d5a84d6286c9e72731 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Mon, 17 Apr 2023 14:01:27 +0200 Subject: [PATCH 36/36] board/common: enable ipv4 and ipv6 global forwarding flag by default The per-interface and per-af setting in the ietf-ip yang module allow the user to enable a more granular forwarding between interfaces, which is disabled by default. Signed-off-by: Joachim Wiberg --- board/common/rootfs/etc/sysctl.d/forwarding.conf | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 board/common/rootfs/etc/sysctl.d/forwarding.conf diff --git a/board/common/rootfs/etc/sysctl.d/forwarding.conf b/board/common/rootfs/etc/sysctl.d/forwarding.conf new file mode 100644 index 000000000..c24ade969 --- /dev/null +++ b/board/common/rootfs/etc/sysctl.d/forwarding.conf @@ -0,0 +1,2 @@ +net.ipv4.ip_forward=1 +net.ipv6.conf.all.forwarding=1