Merge pull request #1415 from kernelkit/add-yang-check

Add yang check
This commit is contained in:
Mattias Walström
2026-02-27 13:58:27 +01:00
committed by GitHub
29 changed files with 442 additions and 119 deletions
+1 -1
View File
@@ -2,6 +2,7 @@
.claude
.gdb_history
.claude
AGENTS.md
/.backup
/.ccache
/dl
@@ -11,4 +12,3 @@
/test/.log
/local.mk
/test/spec/Readme.adoc
+1 -1
View File
@@ -1,5 +1,5 @@
# From https://github.com/troglobit/finit/releases/
sha256 7f8b5a49149b17670d93e41a9b146c5633e035aa00087b8c945def8387cdecbd finit-4.16-rc1.tar.gz
sha256 f0894cd8b79ce030fdc656600208ddb0b994364f86ebad066de2e005e5e18a35 finit-4.16.tar.gz
# Locally calculated
sha256 868cb6c5414933a48db11186042cfe65c87480d326734bc6cf0e4b19b4a2e52a LICENSE
+1 -1
View File
@@ -4,7 +4,7 @@
#
################################################################################
FINIT_VERSION = 4.16-rc1
FINIT_VERSION = 4.16
FINIT_SITE = https://github.com/troglobit/finit/releases/download/$(FINIT_VERSION)
FINIT_LICENSE = MIT
FINIT_LICENSE_FILES = LICENSE
@@ -1,11 +1,15 @@
From efe7706fd7397c2feb384afea00ee97e74287df0 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Tue, 28 Mar 2023 10:37:53 +0200
Subject: [PATCH 1/9] sysrepo-plugind: add support for running in foreground
Subject: [PATCH 01/10] sysrepo-plugind: add support for running in foreground
with syslog
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Wires
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Signed-off-by: Mattias Walström <lazzer@gmail.com>
---
src/executables/sysrepo-plugind.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
@@ -1,7 +1,10 @@
From 11b9938206cf2bafc456bb22e14c7f85a604760c Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Tue, 7 May 2024 15:41:53 +0200
Subject: [PATCH 2/9] Allow SR_EV_DONE to return any error to sysrepocfg
Subject: [PATCH 02/10] Allow SR_EV_DONE to return any error to sysrepocfg
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Wires
Importing a system configuration with sysrepocfg the model callbacks do
@@ -17,6 +20,7 @@ This patch is a clumsy way of forcing the (first) error to bubble up to
the surface and cause a non-zero exit code from sysrepocfg.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Signed-off-by: Mattias Walström <lazzer@gmail.com>
---
src/shm_sub.c | 40 +++++++++++++++++++++++++++++++---------
src/shm_sub.h | 2 +-
@@ -1,10 +1,13 @@
From 9e0267d4f20733b2a26df6d0ee0bc4019db8b13f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mattias=20Walstr=C3=B6m?= <lazzer@gmail.com>
Date: Wed, 8 May 2024 17:00:50 +0200
Subject: [PATCH 3/9] Allow to copy from factory default
Subject: [PATCH 03/10] Allow to copy from factory default
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Wires
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Signed-off-by: Mattias Walström <lazzer@gmail.com>
---
src/sysrepo.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
@@ -1,13 +1,16 @@
From e0c899ba266b959544d7cc08c917cebba7ac91c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mattias=20Walstr=C3=B6m?= <lazzer@gmail.com>
Date: Mon, 6 May 2024 14:49:32 +0200
Subject: [PATCH 4/9] Add -z switch to sysrepoctl to install factory config
Subject: [PATCH 04/10] Add -z switch to sysrepoctl to install factory config
from a json file
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Wires
This to be able to load the yang modules during build time instead on boot.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Signed-off-by: Mattias Walström <lazzer@gmail.com>
---
src/executables/sysrepoctl.c | 20 +++++++++++++--
src/lyd_mods.h | 7 ++++++
@@ -1,7 +1,10 @@
From c7602dc8eabb941e0a163208aaf4de92dd5ef526 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Wed, 21 Aug 2024 16:00:35 +0200
Subject: [PATCH 5/9] Introduce new log level [SEC] for audit trails
Subject: [PATCH 05/10] Introduce new log level [SEC] for audit trails
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Wires
This adds a new log level for security and audit trail related log
@@ -19,6 +22,7 @@ system log daemon, dropping any [SEVERITY] prefix. Also, \n is most
often dropped by log daemons.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Signed-off-by: Mattias Walström <lazzer@gmail.com>
---
src/log.c | 18 +++++++++++++++++-
src/log.h | 1 +
@@ -1,7 +1,10 @@
From a86dfdd4a5cb74c1f8c90c8d5aea6f5505c1b88c Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Wed, 21 Aug 2024 16:04:43 +0200
Subject: [PATCH 6/9] Add audit trail for high priority system changes
Subject: [PATCH 06/10] Add audit trail for high priority system changes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Wires
Committing a change to running, copying to a datastore, or calling an
@@ -13,6 +16,7 @@ is when the system actually activates the changes. Copying to startup
or other datastores is handled separately.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Signed-off-by: Mattias Walström <lazzer@gmail.com>
---
src/sysrepo.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
@@ -1,7 +1,10 @@
From dbf08c67d8f17bdf98466b18fd72a230269e5d46 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Fri, 23 Aug 2024 12:22:06 +0200
Subject: [PATCH 7/9] On error in sr_shmsub_listen_thread(), exit process
Subject: [PATCH 07/10] On error in sr_shmsub_listen_thread(), exit process
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Wires
If processing callback events in, e.g., sysrepo-plugind, make sure to
@@ -9,6 +12,7 @@ log the error and exit(1) the entire process so the system can decide
to handle the problem. For example, restart all dependent services.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Signed-off-by: Mattias Walström <lazzer@gmail.com>
---
src/shm_sub.c | 2 ++
1 file changed, 2 insertions(+)
@@ -1,10 +1,13 @@
From 2549c966c090dd38a7a09907d27d13107d15aedd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mattias=20Walstr=C3=B6m?= <lazzer@gmail.com>
Date: Tue, 16 Dec 2025 08:18:32 +0100
Subject: [PATCH 8/9] Cross compile fixes
Subject: [PATCH 08/10] Cross compile fixes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Wires
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Signed-off-by: Mattias Walström <lazzer@gmail.com>
---
CMakeModules/SetupPrintedContext.cmake | 9 +++++++++
1 file changed, 9 insertions(+)
@@ -1,13 +1,17 @@
From 78d62382bf9d665764844a0f686b27e42d73bea9 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Wed, 7 Jan 2026 18:09:32 +0100
Subject: [PATCH 9/9] sr_mkfifo(): set sysrepo group if available
Subject: [PATCH 09/10] sr_mkfifo(): set sysrepo group if available
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Wires
We already set the umask, set the group to allow users of the sysrepo
group to initiate events.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Signed-off-by: Mattias Walström <lazzer@gmail.com>
---
src/common.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
@@ -0,0 +1,32 @@
From ab76b2dd926cd181838b555ef4e25712539aeabc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mattias=20Walstr=C3=B6m?= <lazzer@gmail.com>
Date: Tue, 24 Feb 2026 16:45:35 +0100
Subject: [PATCH 10/10] Fix sr_lyd_new_path() reporting stale libyang errors
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Wires
Signed-off-by: Mattias Walström <lazzer@gmail.com>
---
src/ly_wrap.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/ly_wrap.c b/src/ly_wrap.c
index 340b8b2a..465580e0 100644
--- a/src/ly_wrap.c
+++ b/src/ly_wrap.c
@@ -610,6 +610,10 @@ sr_lyd_new_path(struct lyd_node *parent, const struct ly_ctx *ctx, const char *p
{
sr_error_info_t *err_info = NULL;
uint32_t temp_lo = LY_LOSTORE;
+ const struct ly_ctx *err_ctx = ctx ? ctx : LYD_CTX(parent);
+
+ /* clear any stale errors so sr_errinfo_new_ly() only finds fresh ones */
+ ly_err_clean((struct ly_ctx *)err_ctx, NULL);
ly_temp_log_options(&temp_lo);
--
2.43.0
+190 -14
View File
@@ -163,6 +163,76 @@ static bool is_uri(const char *str)
return strstr(str, "://") != NULL;
}
static bool is_ssh_uri(const char *uri)
{
return !strncmp(uri, "scp://", 6) || !strncmp(uri, "sftp://", 7);
}
/*
* Parse scp:// or sftp:// URI into an scp(1)-compatible remote string
* of the form [user@]host:path, and optionally extract the port.
*
* URI format: scheme://[user@]host[:port]/path
*
* Returns a heap-allocated string the caller must free, and sets *portp
* to a heap-allocated port string (or NULL) the caller must also free.
* Returns NULL on parse failure.
*/
static char *ssh_uri_to_remote(const char *uri, char **portp)
{
const char *p, *slash, *path;
char auth[256], *auth_at, *auth_colon, *host_start;
char *user, *remote = NULL, *port = NULL;
size_t auth_len;
*portp = NULL;
if (!strncmp(uri, "scp://", 6))
p = uri + 6;
else if (!strncmp(uri, "sftp://", 7))
p = uri + 7;
else
return NULL;
slash = strchr(p, '/');
if (!slash)
slash = p + strlen(p);
auth_len = (size_t)(slash - p);
if (auth_len >= sizeof(auth))
return NULL;
memcpy(auth, p, auth_len);
auth[auth_len] = '\0';
auth_at = strchr(auth, '@');
if (auth_at) {
*auth_at = '\0';
user = auth;
host_start = auth_at + 1;
} else {
user = (char *)remote_user; /* may be NULL */
host_start = auth;
}
auth_colon = strchr(host_start, ':');
if (auth_colon) {
*auth_colon = '\0';
port = strdup(auth_colon + 1);
if (!port)
return NULL;
}
path = *slash ? slash : "/";
if (user)
(void)asprintf(&remote, "%s@%s:%s", user, host_start, path);
else
(void)asprintf(&remote, "%s:%s", host_start, path);
*portp = port;
return remote;
}
static bool is_stdout(const char *path)
{
if (!path)
@@ -394,29 +464,37 @@ static int subprocess(char * const *argv)
static int curl(char *op, const char *path, const char *uri)
{
char *argv[] = {
"curl", "-L", op, NULL, NULL, NULL, NULL, NULL,
};
int err = 1;
char *argv[10] = { "curl", "-L", NULL };
int err = 1, i = 2;
int path_i, uri_i, user_i = 0;
argv[3] = strdup(path);
argv[4] = strdup(uri);
if (!(argv[3] && argv[4]))
argv[i++] = op;
path_i = i;
argv[i] = strdup(path);
if (!argv[i++])
goto out;
uri_i = i;
argv[i] = strdup(uri);
if (!argv[i++])
goto out;
if (remote_user) {
argv[5] = strdup("-u");
argv[6] = strdup(remote_user);
if (!(argv[5] && argv[6]))
argv[i++] = "-u";
user_i = i;
argv[i] = strdup(remote_user);
if (!argv[i++])
goto out;
}
err = subprocess(argv);
out:
free(argv[6]);
free(argv[5]);
free(argv[4]);
free(argv[3]);
free(argv[path_i]);
free(argv[uri_i]);
if (user_i)
free(argv[user_i]);
return err;
}
@@ -445,6 +523,72 @@ static int curl_download(const char *uri, const char *dstpath)
return 0;
}
static int scp_upload(const char *srcpath, const char *uri)
{
char *argv[12] = { "scp", "-o", "StrictHostKeyChecking=no", NULL };
int i = 3, err = 1;
char *remote = NULL, *port = NULL, *src_dup = NULL;
remote = ssh_uri_to_remote(uri, &port);
if (!remote) {
warnx("failed to parse URI: %s", uri);
goto out;
}
if (port) {
argv[i++] = "-P";
argv[i++] = port;
}
src_dup = strdup(srcpath);
if (!src_dup)
goto out;
argv[i++] = src_dup;
argv[i++] = remote;
err = subprocess(argv);
if (err)
warnx("upload to %s failed", uri);
out:
free(src_dup);
free(port);
free(remote);
return err;
}
static int scp_download(const char *uri, const char *dstpath)
{
char *argv[12] = { "scp", "-o", "StrictHostKeyChecking=no", NULL };
int i = 3, err = 1;
char *remote = NULL, *port = NULL, *dst_dup = NULL;
remote = ssh_uri_to_remote(uri, &port);
if (!remote) {
warnx("failed to parse URI: %s", uri);
goto out;
}
if (port) {
argv[i++] = "-P";
argv[i++] = port;
}
argv[i++] = remote;
dst_dup = strdup(dstpath);
if (!dst_dup)
goto out;
argv[i++] = dst_dup;
err = subprocess(argv);
if (err)
warnx("download of %s failed", uri);
out:
free(dst_dup);
free(port);
free(remote);
return err;
}
static int cat(const char *srcpath)
{
char *argv[] = { "cat", NULL, NULL };
@@ -492,6 +636,8 @@ static int put(const char *srcpath, const char *dst,
err = sysrepo_import(ds, srcpath);
else if (is_stdout(dst))
err = cat(srcpath);
else if (is_ssh_uri(dst))
err = scp_upload(srcpath, dst);
else if (is_uri(dst))
err = curl_upload(srcpath, dst);
@@ -513,6 +659,8 @@ static int get(const char *src, const struct infix_ds *ds, const char *path)
if (ds)
err = sysrepo_export(ds, path);
else if (is_ssh_uri(src))
err = scp_download(src, path);
else if (is_uri(src))
err = curl_download(src, path);
@@ -581,6 +729,7 @@ static int copy(const char *src, const char *dst)
{
const struct infix_ds *srcds = NULL, *dstds = NULL;
char *srcpath = NULL, *dstpath = NULL;
char *dst_uri = NULL;
bool rmsrc = false;
mode_t oldmask;
int err = 1;
@@ -597,6 +746,32 @@ static int copy(const char *src, const char *dst)
if (err)
goto err;
/*
* When uploading to an SSH URI ending in '/', scp(1) would use the
* basename of the local (temp) file as the remote name. Append a
* meaningful name instead: the datastore's on-disk filename, or the
* source file's own basename.
*/
if (is_ssh_uri(dst) && dst[strlen(dst) - 1] == '/') {
const char *bn, *slash;
if (srcds && srcds->path) {
slash = strrchr(srcds->path, '/');
bn = slash ? slash + 1 : srcds->path;
} else if (srcds) {
bn = srcds->name;
} else {
slash = strrchr(srcpath, '/');
bn = slash ? slash + 1 : srcpath;
}
if (asprintf(&dst_uri, "%s%s", dst, bn) < 0) {
err = 1;
goto err;
}
dst = dst_uri;
}
err = resolve_dst(&dst, &dstds, &dstpath);
if (err)
goto err;
@@ -614,6 +789,7 @@ err:
if (rmsrc)
rmtmp(srcpath);
free(dst_uri);
if (dstpath)
free(dstpath);
free(srcpath);
+16 -9
View File
@@ -12,8 +12,6 @@
#define XPATH_KEYSTORE_ASYM "/ietf-keystore:keystore/asymmetric-keys"
#define XPATH_KEYSTORE_SYM "/ietf-keystore:keystore/symmetric-keys"
#define SSH_PRIVATE_KEY "/tmp/ssh.key"
#define SSH_PUBLIC_KEY "/tmp/ssh.pub"
/* return file size */
static size_t filesz(const char *fn)
@@ -91,6 +89,9 @@ static int keystore_update(sr_session_ctx_t *session, struct lyd_node *config, s
}
for (size_t i = 0; i < count; i++) {
char tmpdir[] = "/tmp/keystore.XXXXXX";
char priv_path[sizeof(tmpdir) + 16];
char pub_path[sizeof(tmpdir) + 16];
char *name = srx_get_str(session, "%s/name", list[i].xpath);
char *public_key_format, *private_key_format;
char *pub_key = NULL, *priv_key = NULL;
@@ -115,16 +116,24 @@ static int keystore_update(sr_session_ctx_t *session, struct lyd_node *config, s
continue;
NOTE("SSH key (%s) does not exist, generating...", name);
if (systemf("/usr/libexec/infix/mkkeys %s %s", SSH_PRIVATE_KEY, SSH_PUBLIC_KEY)) {
if (!mkdtemp(tmpdir)) {
ERRNO("Failed creating temp dir for SSH key generation");
goto next;
}
snprintf(priv_path, sizeof(priv_path), "%s/ssh.key", tmpdir);
snprintf(pub_path, sizeof(pub_path), "%s/ssh.pub", tmpdir);
if (systemf("/usr/libexec/infix/mkkeys %s %s", priv_path, pub_path)) {
ERROR("Failed generating SSH keys for %s", name);
goto next;
}
priv_key = filerd(SSH_PRIVATE_KEY, filesz(SSH_PRIVATE_KEY));
priv_key = filerd(priv_path, filesz(priv_path));
if (!priv_key)
goto next;
pub_key = filerd(SSH_PUBLIC_KEY, filesz(SSH_PUBLIC_KEY));
pub_key = filerd(pub_path, filesz(pub_path));
if (!pub_key)
goto next;
@@ -140,10 +149,8 @@ static int keystore_update(sr_session_ctx_t *session, struct lyd_node *config, s
goto next;
}
next:
if (erase(SSH_PRIVATE_KEY))
ERRNO("Failed removing SSH server private key");
if (erase(SSH_PUBLIC_KEY))
ERRNO("Failed removing SSH server public key");
if (rmrf(tmpdir))
ERRNO("Failed removing temp dir %s", tmpdir);
if (priv_key)
free(priv_key);
+3 -10
View File
@@ -35,18 +35,11 @@ static int change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd
return SR_ERR_OK;
case SR_EV_DONE:
/* Check if NTP container exists (presence container) */
if (!lydx_get_xpathf(config, XPATH_NTP_)) {
DEBUG("NTP server disabled, removing config");
systemf("rm -f %s", NTP_CONF);
/* Check if passed validation in previous event */
if (!fexist(NTP_NEXT)) {
(void)remove(NTP_CONF);
return SR_ERR_OK;
}
/* Check if passed validation in previous event */
if (!fexist(NTP_NEXT))
return SR_ERR_OK;
(void)remove(NTP_PREV);
(void)rename(NTP_CONF, NTP_PREV);
(void)rename(NTP_NEXT, NTP_CONF);
+31 -9
View File
@@ -22,6 +22,11 @@ module infix-containers {
prefix infix-sys;
}
revision 2026-02-23 {
description "Input validation improvements";
reference "internal";
}
revision 2025-12-09 {
description "Add resource management:
- Add resource-limit container with memory and cpu configuration.
@@ -84,6 +89,17 @@ module infix-containers {
}
}
typedef image-reference {
description "OCI image reference or transport URI.
Allows registry references (e.g., quay.io/user/image:tag),
transport prefixes (docker://, oci-archive:, dir:), and
download URLs (ftp://, http://, https://).";
type string {
pattern '[a-zA-Z0-9][a-zA-Z0-9_./:@=+%~-]*';
}
}
typedef mount-type {
type enumeration {
enum bind {
@@ -181,7 +197,7 @@ module infix-containers {
container will be put on a queue that retries pull every time
there is a route change in the host's system.";
mandatory true;
type string;
type image-reference;
}
container checksum {
@@ -240,7 +256,9 @@ module infix-containers {
leaf command {
description "Override ENTRYPOINT from image and run command + args.";
type string;
type string {
pattern '[a-zA-Z0-9_./ :=@%^,+-]+';
}
}
leaf hostname {
@@ -298,7 +316,9 @@ module infix-containers {
NOTE: Some (*) options only work with masquerading container bridges,
which automatically create VETH pairs with one end in the host
bridge and the other in the container.";
type string;
type string {
pattern '[a-zA-Z_][a-zA-Z0-9_]*=[a-zA-Z0-9.:_/-]+';
}
}
}
@@ -310,7 +330,9 @@ module infix-containers {
Sample: 8080:80 -- forward tcp port 8080 to container port 80
69:69/udp -- forward udp port 69 to container port 69
127.0.0.1:8080:80 -- forward only from loopback interface";
type string;
type string {
pattern '[0-9.:\[\]]+(/[a-zA-Z]+)?';
}
}
leaf-list dns {
@@ -464,7 +486,7 @@ module infix-containers {
When mounting files, directories (and globs) from the host,
the source must be an absolute path.";
type string {
pattern '/.*';
pattern '/[a-zA-Z0-9_./*?-]+([ ]?[a-zA-Z0-9_./*?-]+)*';
}
}
}
@@ -493,7 +515,7 @@ module infix-containers {
or import the text file using the 'content' node.";
mandatory true;
type string {
pattern '/.*';
pattern '/[a-zA-Z0-9_./-]+(/[a-zA-Z0-9_./-]+)*';
}
}
@@ -545,7 +567,7 @@ module infix-containers {
description "Absolute path to target destination directory inside the container.";
mandatory true;
type string {
pattern '/.*';
pattern '/[a-zA-Z0-9_./-]+(/[a-zA-Z0-9_./-]+)*';
}
}
}
@@ -593,12 +615,12 @@ module infix-containers {
input {
leaf uri {
description "The URL or local file path, e.g., /lib/oci/archive.tar.gz";
type string;
type image-reference;
mandatory true;
}
leaf name {
description "Image name[:tag], default: basename of archive dir + :latest";
type string;
type image-reference;
}
}
}
+9 -3
View File
@@ -113,7 +113,9 @@ module infix-dhcp-server {
case default-opt {
leaf string {
description "Generic string value.";
type string;
type string {
pattern '[^\p{Cc}]*';
}
}
}
}
@@ -150,7 +152,9 @@ module infix-dhcp-server {
leaf description {
description "Additional information about this subnet (e.g., purpose, location, or notes).";
type string;
type string {
pattern '[^\p{Cc}]*';
}
}
leaf enabled {
@@ -206,7 +210,9 @@ module infix-dhcp-server {
leaf description {
description "Additional information about this entry, e.g., owner's name, equipment details, or location.";
type string;
type string {
pattern '[^\p{Cc}]*';
}
}
container match {
+9 -3
View File
@@ -201,7 +201,9 @@ module infix-firewall {
leaf description {
description "Free-form description of the zone.";
type string;
type string {
pattern '[^\p{Cc}<>&]*';
}
}
leaf-list interface {
@@ -304,7 +306,9 @@ module infix-firewall {
leaf description {
description "Free-form description of this policy's purpose and scope.";
type string;
type string {
pattern '[^\p{Cc}<>&]*';
}
}
leaf-list ingress {
@@ -421,7 +425,9 @@ module infix-firewall {
leaf description {
description "Free-form description of the service.";
type string;
type string {
pattern '[^\p{Cc}<>&]*';
}
}
list port {
@@ -204,6 +204,7 @@ module infix-interfaces {
deviate replace {
type string {
length "0..64";
pattern '[^\p{Cc}]*';
}
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
# -*- sh -*-
MODULES=(
"infix-interfaces -e containers"
"infix-containers@2025-12-09.yang"
"infix-containers@2026-02-23.yang"
)
+1 -1
View File
@@ -48,7 +48,7 @@ def network(ps, inspect):
if port["host_ip"]:
addr = f"{port['host_ip']}:"
pub = f"{addr}{port['host_port']}->{port['container_port']}/{port['protocol']}"
pub = f"{addr}{port['host_port']}:{port['container_port']}/{port['protocol']}"
net["publish"].append(pub)
return net
@@ -1,12 +1,12 @@
 DESTINATION PREF NEXT-HOP PROTO UPTIME
>* 0.0.0.0/0 110/2 10.1.1.100 ospfv2 16:03:51
0.0.0.0/0 254/0 br0 static 16:04:31
10.1.1.0/24 110/1 e6 ospfv2 16:04:45
>* 10.1.1.0/24 0/0 e6 direct 16:04:45
* 10.1.1.1/32 0/0 e4.8 direct 16:04:46
>* 10.1.1.1/32 0/0 e3.8 direct 16:04:46
>* 10.1.2.0/24 110/2 10.1.1.100 ospfv2 16:03:51
>* 0.0.0.0/0 110/2 10.1.1.100 ospfv2 06:43:38
0.0.0.0/0 254/0 br0 static 06:44:18
10.1.1.0/24 110/1 e6 ospfv2 06:44:32
>* 10.1.1.0/24 0/0 e6 direct 06:44:32
* 10.1.1.1/32 0/0 e4.8 direct 06:44:33
>* 10.1.1.1/32 0/0 e3.8 direct 06:44:33
>* 10.1.2.0/24 110/2 10.1.1.100 ospfv2 06:43:38
* 10.1.2.1
>* 10.1.3.0/24 110/2 10.1.1.100 ospfv2 16:03:51
>* 10.1.3.0/24 110/2 10.1.1.100 ospfv2 06:43:38
* 10.1.3.1
>* 169.254.0.0/16 0/0 br0 direct 16:04:40
>* 169.254.0.0/16 0/0 br0 direct 06:44:27
@@ -1,7 +1,7 @@
 DESTINATION PREF NEXT-HOP PROTO UPTIME
* fe80::/64 0/0 e6 direct 16:04:44
* fe80::/64 0/0 br0 direct 16:04:45
* fe80::/64 0/0 e2 direct 16:04:47
* fe80::/64 0/0 e7 direct 16:05:37
* fe80::/64 0/0 e5 direct 16:05:37
>* fe80::/64 0/0 e1 direct 16:05:37
* fe80::/64 0/0 e6 direct 06:44:31
* fe80::/64 0/0 br0 direct 06:44:32
* fe80::/64 0/0 e2 direct 06:44:34
* fe80::/64 0/0 e7 direct 06:45:24
* fe80::/64 0/0 e5 direct 06:45:24
>* fe80::/64 0/0 e1 direct 06:45:24
+15 -15
View File
@@ -18,7 +18,7 @@
"active": [
null
],
"last-updated": "2025-02-11T19:56:09+00:00",
"last-updated": "2026-02-25T05:16:22+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -36,7 +36,7 @@
"ietf-ipv4-unicast-routing:destination-prefix": "0.0.0.0/0",
"source-protocol": "static",
"route-preference": 254,
"last-updated": "2025-02-11T19:55:29+00:00",
"last-updated": "2026-02-25T05:15:42+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -52,7 +52,7 @@
"source-protocol": "ietf-ospf:ospfv2",
"route-preference": 110,
"ietf-ospf:metric": 1,
"last-updated": "2025-02-11T19:55:15+00:00",
"last-updated": "2026-02-25T05:15:28+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -70,7 +70,7 @@
"active": [
null
],
"last-updated": "2025-02-11T19:55:15+00:00",
"last-updated": "2026-02-25T05:15:28+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -88,7 +88,7 @@
"ietf-ipv4-unicast-routing:destination-prefix": "10.1.1.1/32",
"source-protocol": "direct",
"route-preference": 0,
"last-updated": "2025-02-11T19:55:14+00:00",
"last-updated": "2026-02-25T05:15:27+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -109,7 +109,7 @@
"active": [
null
],
"last-updated": "2025-02-11T19:55:14+00:00",
"last-updated": "2026-02-25T05:15:27+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -131,7 +131,7 @@
"active": [
null
],
"last-updated": "2025-02-11T19:56:09+00:00",
"last-updated": "2026-02-25T05:16:22+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -159,7 +159,7 @@
"active": [
null
],
"last-updated": "2025-02-11T19:56:09+00:00",
"last-updated": "2026-02-25T05:16:22+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -186,7 +186,7 @@
"active": [
null
],
"last-updated": "2025-02-11T19:55:20+00:00",
"last-updated": "2026-02-25T05:15:33+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -212,7 +212,7 @@
"ietf-ipv6-unicast-routing:destination-prefix": "fe80::/64",
"source-protocol": "direct",
"route-preference": 0,
"last-updated": "2025-02-11T19:55:16+00:00",
"last-updated": "2026-02-25T05:15:29+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -230,7 +230,7 @@
"ietf-ipv6-unicast-routing:destination-prefix": "fe80::/64",
"source-protocol": "direct",
"route-preference": 0,
"last-updated": "2025-02-11T19:55:15+00:00",
"last-updated": "2026-02-25T05:15:28+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -248,7 +248,7 @@
"ietf-ipv6-unicast-routing:destination-prefix": "fe80::/64",
"source-protocol": "direct",
"route-preference": 0,
"last-updated": "2025-02-11T19:55:13+00:00",
"last-updated": "2026-02-25T05:15:26+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -266,7 +266,7 @@
"ietf-ipv6-unicast-routing:destination-prefix": "fe80::/64",
"source-protocol": "direct",
"route-preference": 0,
"last-updated": "2025-02-11T19:54:23+00:00",
"last-updated": "2026-02-25T05:14:36+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -284,7 +284,7 @@
"ietf-ipv6-unicast-routing:destination-prefix": "fe80::/64",
"source-protocol": "direct",
"route-preference": 0,
"last-updated": "2025-02-11T19:54:23+00:00",
"last-updated": "2026-02-25T05:14:36+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -305,7 +305,7 @@
"active": [
null
],
"last-updated": "2025-02-11T19:54:23+00:00",
"last-updated": "2026-02-25T05:14:36+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -39,7 +39,7 @@
}
],
"publish": [
"34515->91/tcp"
"34515:91/tcp"
]
}
},
+69 -22
View File
@@ -693,13 +693,21 @@
"ietf-ospf:interfaces": {
"ietf-ospf:interface": [
{
"cost": 1,
"dead-interval": 40,
"enabled": true,
"hello-interval": 10,
"hello-timer": 2,
"ietf-ospf:neighbors": {
"ietf-ospf:neighbor": [
{
"address": "10.1.2.1",
"dead-timer": 22506,
"dead-timer": 22,
"infix-routing:interface-name": "e3.8:10.1.1.1",
"infix-routing:role": "DROther",
"infix-routing:uptime": 57,
"neighbor-router-id": "10.1.2.1",
"priority": 1,
"state": "full"
}
]
@@ -707,16 +715,28 @@
"interface-type": "point-to-point",
"name": "e3.8",
"passive": false,
"state": "point-to-point"
"priority": 1,
"retransmit-interval": 5,
"state": "point-to-point",
"transmit-delay": 1,
"wait-timer": 40
},
{
"cost": 1,
"dead-interval": 40,
"enabled": true,
"hello-interval": 10,
"hello-timer": 2,
"ietf-ospf:neighbors": {
"ietf-ospf:neighbor": [
{
"address": "10.1.3.1",
"dead-timer": 22334,
"dead-timer": 22,
"infix-routing:interface-name": "e4.8:10.1.1.1",
"infix-routing:role": "DROther",
"infix-routing:uptime": 57,
"neighbor-router-id": "10.1.3.1",
"priority": 1,
"state": "full"
}
]
@@ -724,22 +744,34 @@
"interface-type": "point-to-point",
"name": "e4.8",
"passive": false,
"state": "point-to-point"
"priority": 1,
"retransmit-interval": 5,
"state": "point-to-point",
"transmit-delay": 1,
"wait-timer": 40
},
{
"bdr-ip-addr": "10.1.1.101",
"bdr-router-id": "10.1.1.1",
"cost": 1,
"dead-interval": 40,
"dr-ip-addr": "10.1.1.100",
"dr-router-id": "192.168.100.1",
"enabled": true,
"hello-interval": 10,
"hello-timer": 2,
"ietf-ospf:neighbors": {
"ietf-ospf:neighbor": [
{
"address": "10.1.1.100",
"bdr-router-id": "10.1.1.1",
"dead-timer": 31385,
"dead-timer": 31,
"dr-router-id": "192.168.100.1",
"infix-routing:interface-name": "e6:10.1.1.101",
"infix-routing:role": "DR",
"infix-routing:uptime": 23,
"neighbor-router-id": "192.168.100.1",
"priority": 1,
"state": "full"
}
]
@@ -747,7 +779,11 @@
"interface-type": "broadcast",
"name": "e6",
"passive": false,
"state": "bdr"
"priority": 1,
"retransmit-interval": 5,
"state": "bdr",
"transmit-delay": 1,
"wait-timer": 40
}
]
}
@@ -757,6 +793,8 @@
"ietf-ospf:local-rib": {
"ietf-ospf:route": [
{
"infix-routing:area-id": "0.0.0.1",
"metric": 2,
"next-hops": {
"next-hop": [
{
@@ -768,6 +806,8 @@
"route-type": "inter-area"
},
{
"infix-routing:area-id": "0.0.0.1",
"metric": 1,
"next-hops": {
"next-hop": [
{
@@ -779,6 +819,8 @@
"route-type": "intra-area"
},
{
"infix-routing:area-id": "0.0.0.1",
"metric": 2,
"next-hops": {
"next-hop": [
{
@@ -793,6 +835,8 @@
"route-type": "intra-area"
},
{
"infix-routing:area-id": "0.0.0.1",
"metric": 2,
"next-hops": {
"next-hop": [
{
@@ -815,6 +859,9 @@
}
]
},
"interfaces": {
"interface": []
},
"ribs": {
"rib": [
{
@@ -828,7 +875,7 @@
],
"ietf-ipv4-unicast-routing:destination-prefix": "0.0.0.0/0",
"ietf-ospf:metric": 2,
"last-updated": "2025-02-11T19:56:09+00:00",
"last-updated": "2026-02-25T05:16:22+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -846,7 +893,7 @@
},
{
"ietf-ipv4-unicast-routing:destination-prefix": "0.0.0.0/0",
"last-updated": "2025-02-11T19:55:29+00:00",
"last-updated": "2026-02-25T05:15:42+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -862,7 +909,7 @@
{
"ietf-ipv4-unicast-routing:destination-prefix": "10.1.1.0/24",
"ietf-ospf:metric": 1,
"last-updated": "2025-02-11T19:55:15+00:00",
"last-updated": "2026-02-25T05:15:28+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -880,7 +927,7 @@
null
],
"ietf-ipv4-unicast-routing:destination-prefix": "10.1.1.0/24",
"last-updated": "2025-02-11T19:55:15+00:00",
"last-updated": "2026-02-25T05:15:28+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -898,7 +945,7 @@
},
{
"ietf-ipv4-unicast-routing:destination-prefix": "10.1.1.1/32",
"last-updated": "2025-02-11T19:55:14+00:00",
"last-updated": "2026-02-25T05:15:27+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -919,7 +966,7 @@
null
],
"ietf-ipv4-unicast-routing:destination-prefix": "10.1.1.1/32",
"last-updated": "2025-02-11T19:55:14+00:00",
"last-updated": "2026-02-25T05:15:27+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -941,7 +988,7 @@
],
"ietf-ipv4-unicast-routing:destination-prefix": "10.1.2.0/24",
"ietf-ospf:metric": 2,
"last-updated": "2025-02-11T19:56:09+00:00",
"last-updated": "2026-02-25T05:16:22+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -969,7 +1016,7 @@
],
"ietf-ipv4-unicast-routing:destination-prefix": "10.1.3.0/24",
"ietf-ospf:metric": 2,
"last-updated": "2025-02-11T19:56:09+00:00",
"last-updated": "2026-02-25T05:16:22+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -996,7 +1043,7 @@
null
],
"ietf-ipv4-unicast-routing:destination-prefix": "169.254.0.0/16",
"last-updated": "2025-02-11T19:55:20+00:00",
"last-updated": "2026-02-25T05:15:33+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -1022,7 +1069,7 @@
"route": [
{
"ietf-ipv6-unicast-routing:destination-prefix": "fe80::/64",
"last-updated": "2025-02-11T19:55:16+00:00",
"last-updated": "2026-02-25T05:15:29+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -1040,7 +1087,7 @@
},
{
"ietf-ipv6-unicast-routing:destination-prefix": "fe80::/64",
"last-updated": "2025-02-11T19:55:15+00:00",
"last-updated": "2026-02-25T05:15:28+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -1058,7 +1105,7 @@
},
{
"ietf-ipv6-unicast-routing:destination-prefix": "fe80::/64",
"last-updated": "2025-02-11T19:55:13+00:00",
"last-updated": "2026-02-25T05:15:26+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -1076,7 +1123,7 @@
},
{
"ietf-ipv6-unicast-routing:destination-prefix": "fe80::/64",
"last-updated": "2025-02-11T19:54:23+00:00",
"last-updated": "2026-02-25T05:14:36+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -1094,7 +1141,7 @@
},
{
"ietf-ipv6-unicast-routing:destination-prefix": "fe80::/64",
"last-updated": "2025-02-11T19:54:23+00:00",
"last-updated": "2026-02-25T05:14:36+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -1115,7 +1162,7 @@
null
],
"ietf-ipv6-unicast-routing:destination-prefix": "fe80::/64",
"last-updated": "2025-02-11T19:54:23+00:00",
"last-updated": "2026-02-25T05:14:36+00:00",
"next-hop": {
"next-hop-list": {
"next-hop": [
@@ -1175,7 +1222,7 @@
}
],
"publish": [
"34515->91/tcp"
"34515:91/tcp"
]
},
"running": true,
+1 -1
View File
@@ -1,2 +1,2 @@
1739303782
1771996595