From a5fc2f797b124b3f7ccc3c03d83962d288aad404 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Tue, 28 Oct 2025 13:24:01 +0100 Subject: [PATCH 1/5] .github: add free-disk-space action to generic x86_64 workflow Addresses disk space issues in GitHub Actions for generic x86_64 builds by removing unused tools (Android SDK, .NET, Docker images, etc.) before the build starts. This frees up ~30GB of space. Fixes #1210 Signed-off-by: Joachim Wiberg --- .github/workflows/generic-x86-build.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/generic-x86-build.yml b/.github/workflows/generic-x86-build.yml index 3a624f46..8dc06705 100644 --- a/.github/workflows/generic-x86-build.yml +++ b/.github/workflows/generic-x86-build.yml @@ -10,6 +10,17 @@ jobs: runs-on: ubuntu-latest steps: + - name: Free Disk Space + uses: jlumbroso/free-disk-space@main + with: + tool-cache: true + android: true + dotnet: true + haskell: true + large-packages: true + docker-images: true + swap-storage: false + - name: Install build dependencies run: | sudo apt-get update From f8e62fb8dfae9157bfa16443af03e0a76c6f3d28 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Tue, 28 Oct 2025 13:21:21 +0100 Subject: [PATCH 2/5] patch/libyang: follow-up to 77963d5, fix wrong arguments to LOGDBG() Signed-off-by: Joachim Wiberg --- ...d_validate_obsolete-change-log-level-warning-debug.patch | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/patches/libyang/3.13.5/0001-lyd_validate_obsolete-change-log-level-warning-debug.patch b/patches/libyang/3.13.5/0001-lyd_validate_obsolete-change-log-level-warning-debug.patch index 33db1b88..3fcf71db 100644 --- a/patches/libyang/3.13.5/0001-lyd_validate_obsolete-change-log-level-warning-debug.patch +++ b/patches/libyang/3.13.5/0001-lyd_validate_obsolete-change-log-level-warning-debug.patch @@ -1,4 +1,4 @@ -From 4603d09f5d1bd9ca0a1d4467d30a71528c8e2df4 Mon Sep 17 00:00:00 2001 +From 50a8a5c0d07de5f72323be6d9ba1d1b78fdc6b9b Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Mon, 1 Sep 2025 14:24:03 +0200 Subject: [PATCH] lyd_validate_obsolete: change log level warning -> debug @@ -46,7 +46,7 @@ index 85f2ac6d4..2bbb0b19b 100644 /** * @} diff --git a/src/validation.c b/src/validation.c -index 25be0feeb..8e308c61f 100644 +index 25be0feeb..86b82dbff 100644 --- a/src/validation.c +++ b/src/validation.c @@ -1624,7 +1624,7 @@ lyd_validate_obsolete(const struct lyd_node *node) @@ -54,7 +54,7 @@ index 25be0feeb..8e308c61f 100644 (!(snode->nodetype & LYD_NODE_INNER) || lyd_child(node))) { LOG_LOCSET(NULL, node); - LOGWRN(snode->module->ctx, "Obsolete schema node \"%s\" instantiated in data.", snode->name); -+ LOGDBG(LY_LDGSCHEMA, snode->module->ctx, "Obsolete schema node \"%s\" instantiated in data.", snode->name); ++ LOGDBG(LY_LDGSCHEMA, "%s: obsolete schema node \"%s\" instantiated in data.", snode->module->name, snode->name); LOG_LOCBACK(0, 1); break; } From d80186a55646f53bd71af830081feb906ba6bc17 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Tue, 28 Oct 2025 17:12:36 +0100 Subject: [PATCH 3/5] test/docker: security analysis of GHSA-cq46-m9x9-j8w2 for scapy Signed-off-by: Joachim Wiberg --- test/docker/pip-requirements.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/docker/pip-requirements.txt b/test/docker/pip-requirements.txt index f0935781..1a8df2d4 100644 --- a/test/docker/pip-requirements.txt +++ b/test/docker/pip-requirements.txt @@ -6,4 +6,8 @@ pydot==1.4.2 pyyaml==6.0.1 passlib==1.7.4 requests~=2.32.4 +# GHSA-cq46-m9x9-j8w2: scapy <=2.6.1 has pickle deserialization vuln in session +# loading (-s flag). Low risk: test framework only uses packet crafting (Ether, +# sendp, LLDP), not session loading. Update to 2.7.0+ when available on PyPI. +# https://github.com/advisories/GHSA-cq46-m9x9-j8w2 scapy==2.6.1 From cb5d804a88e596ad9dfeab87137c647b4b57dfc8 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Tue, 28 Oct 2025 13:34:28 +0100 Subject: [PATCH 4/5] confd: add dhcp-server validation of address pool and/or static host A valid DHCP server setup for a subnet is one of pool and/or at least one static host entry/lease. If pool is enabled the pool must have a start and an end address. To allow setting up a DHCP server with no pool and at least one static host entry/lease, we make the pool a presence container, otherwise the pool will always be set and trigger the below inference. When an interactive CLI/Web user enables the address pool we infer a default range .100-.250, but only for /24, C-class networks. This is what most users know and expect. The YANG model now validates that: - If an address pool is created, both start-address and end-address must be set - Each subnet must have either a pool or at least one static host entry - The pool container is now a presence container, so "no pool" fully deletes it Fixes #1121 Signed-off-by: Joachim Wiberg --- doc/ChangeLog.md | 6 ++- src/confd/src/infix-dhcp-server.c | 42 +++++++++++++++++-- src/confd/yang/confd.inc | 2 +- src/confd/yang/confd/infix-dhcp-server.yang | 16 +++++++ ...yang => infix-dhcp-server@2025-10-28.yang} | 0 5 files changed, 60 insertions(+), 6 deletions(-) rename src/confd/yang/confd/{infix-dhcp-server@2025-01-29.yang => infix-dhcp-server@2025-10-28.yang} (100%) diff --git a/doc/ChangeLog.md b/doc/ChangeLog.md index 743d909c..484a2b39 100644 --- a/doc/ChangeLog.md +++ b/doc/ChangeLog.md @@ -3,7 +3,7 @@ Change Log All notable changes to the project are documented in this file. -[v25.10.0][UNRELEASED] - +[v25.10.0][] - 2025-10-31 ------------------------- ### Changes @@ -31,6 +31,10 @@ All notable changes to the project are documented in this file. - Fix #981: copying any file, including `running-config`, to the persistent back-end store for `startup-config`, does not take +- Fix #1121: Ensure DHCP server does not crash if no address pool is set. This + change infers a pool range (only) for /24 networks, and only when a pool is + enabled. YANG validation for this and other use-cases is also included. As + an unforeseen bonus, Infix now also support non-pool (static lease) setups - Fix #1146: Possible to set longer containers names than the system supports. Root cause, a limit of 15 characters implicitly imposed by the service mgmt daemon, Finit. The length has not been increased to 64 characters (min: 2) diff --git a/src/confd/src/infix-dhcp-server.c b/src/confd/src/infix-dhcp-server.c index 91302b10..2e921b92 100644 --- a/src/confd/src/infix-dhcp-server.c +++ b/src/confd/src/infix-dhcp-server.c @@ -223,10 +223,12 @@ static void add(const char *subnet, struct lyd_node *cfg) start = lydx_get_cattr(node, "start-address"); end = lydx_get_cattr(node, "end-address"); - fprintf(fp, "\n# Subnet pool %s - %s\n", start, end); - fprintf(fp, "dhcp-range=%s%sset:%s,%s,%s,%s\n", - ifname ?: "", ifname ? "," : "", tag, - start, end, lydx_get_cattr(node, "lease-time")); + if (start && end) { + fprintf(fp, "\n# Subnet pool %s - %s\n", start, end); + fprintf(fp, "dhcp-range=%s%sset:%s,%s,%s,%s\n", + ifname ?: "", ifname ? "," : "", tag, + start, end, lydx_get_cattr(node, "lease-time")); + } } err: @@ -400,6 +402,7 @@ static int cand(sr_session_ctx_t *session, uint32_t sub_id, const char *module, "router", "dns-server", }; + sr_val_t *subnets = NULL; size_t i, cnt = 0; if (event != SR_EV_UPDATE && event != SR_EV_CHANGE) @@ -413,6 +416,37 @@ static int cand(sr_session_ctx_t *session, uint32_t sub_id, const char *module, srx_set_item(session, &inferred, 0, fmt, opt[i]); } + /* Infer pool: .100 to .250 for /24 networks */ + if (sr_get_items(session, CFG_XPATH "/subnet/subnet", 0, 0, &subnets, &cnt) == 0) { + for (i = 0; i < cnt; i++) { + const char *pool_xpathfmt = CFG_XPATH "/subnet[subnet='%s']/pool"; + const char *host_xpathfmt = CFG_XPATH "/subnet[subnet='%s']/host"; + const char *subnet = subnets[i].data.string_val; + sr_val_t pool_val = { .type = SR_STRING_T }; + char start_addr[16], end_addr[16]; + unsigned int a, b, c, d, len; + size_t pool_cnt = 0, host_cnt = 0; + + if (sscanf(subnet, "%u.%u.%u.%u/%u", &a, &b, &c, &d, &len) != 5 || len != 24) + continue; + + /* Don't auto-infer if pool or static hosts already exist */ + if (!srx_nitems(session, &pool_cnt, pool_xpathfmt, subnet) && pool_cnt) + continue; + if (!srx_nitems(session, &host_cnt, host_xpathfmt, subnet) && host_cnt) + continue; + + snprintf(start_addr, sizeof(start_addr), "%u.%u.%u.100", a, b, c); + snprintf(end_addr, sizeof(end_addr), "%u.%u.%u.250", a, b, c); + + pool_val.data.string_val = start_addr; + srx_set_item(session, &pool_val, 0, CFG_XPATH "/subnet[subnet='%s']/pool/start-address", subnet); + pool_val.data.string_val = end_addr; + srx_set_item(session, &pool_val, 0, CFG_XPATH "/subnet[subnet='%s']/pool/end-address", subnet); + } + sr_free_values(subnets, cnt); + } + return 0; } diff --git a/src/confd/yang/confd.inc b/src/confd/yang/confd.inc index 298145df..c868a70c 100644 --- a/src/confd/yang/confd.inc +++ b/src/confd/yang/confd.inc @@ -27,7 +27,7 @@ MODULES=( "infix-lldp@2025-05-05.yang" "infix-dhcp-common@2025-01-29.yang" "infix-dhcp-client@2025-01-29.yang" - "infix-dhcp-server@2025-01-29.yang" + "infix-dhcp-server@2025-10-28.yang" "infix-firewall@2025-04-26.yang" "infix-firewall-services@2025-04-26.yang" "infix-firewall-icmp-types@2025-04-26.yang" diff --git a/src/confd/yang/confd/infix-dhcp-server.yang b/src/confd/yang/confd/infix-dhcp-server.yang index 8bf0e78f..84d6242d 100644 --- a/src/confd/yang/confd/infix-dhcp-server.yang +++ b/src/confd/yang/confd/infix-dhcp-server.yang @@ -20,6 +20,13 @@ module infix-dhcp-server { contact "kernelkit@googlegroups.com"; description "This module implements a DHCPv4 server"; + revision 2025-10-28 { + description "Make pool a presence container and add pool validation. + Also, require each subnet to have either a pool or + at least one static host entry."; + reference "internal"; + } + revision 2025-01-29 { description "Initial revision adapted for Infix from DHCPv6 model."; reference "internal"; @@ -132,6 +139,10 @@ module infix-dhcp-server { description "Subnet specific settings, including static host entries."; key "subnet"; + must "pool or host" { + error-message "Subnet must have either a pool or at least one static host entry."; + } + leaf subnet { description "Subnet to serve DHCP leases from."; type inet:ipv4-prefix; @@ -160,8 +171,13 @@ module infix-dhcp-server { } container pool { + presence "Enable dynamic DHCP address pool for this subnet."; description "IP address pool for this subnet."; + must "start-address and end-address" { + error-message "Both start-address and end-address must be set if pool is configured."; + } + leaf start-address { description "The start address of the DHCP address pool."; type inet:ipv4-address; diff --git a/src/confd/yang/confd/infix-dhcp-server@2025-01-29.yang b/src/confd/yang/confd/infix-dhcp-server@2025-10-28.yang similarity index 100% rename from src/confd/yang/confd/infix-dhcp-server@2025-01-29.yang rename to src/confd/yang/confd/infix-dhcp-server@2025-10-28.yang From 7e37fc49a3004982d16baa5cd414eded06515077 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Tue, 28 Oct 2025 17:38:49 +0100 Subject: [PATCH 5/5] confd: prevent IP addresses on bridge ports Bridge ports should not have IP addresses configured. The IP address should be configured on the bridge interface itself, not its member ports. Add YANG must expression to enforce this rule at configuration time. Fixes #1122 Signed-off-by: Joachim Wiberg --- doc/ChangeLog.md | 3 +++ src/confd/yang/confd/infix-if-bridge.yang | 10 ++++++++++ ...2025-10-23.yang => infix-if-bridge@2025-10-28.yang} | 0 3 files changed, 13 insertions(+) rename src/confd/yang/confd/{infix-if-bridge@2025-10-23.yang => infix-if-bridge@2025-10-28.yang} (100%) diff --git a/doc/ChangeLog.md b/doc/ChangeLog.md index 484a2b39..edad7424 100644 --- a/doc/ChangeLog.md +++ b/doc/ChangeLog.md @@ -35,6 +35,9 @@ All notable changes to the project are documented in this file. change infers a pool range (only) for /24 networks, and only when a pool is enabled. YANG validation for this and other use-cases is also included. As an unforeseen bonus, Infix now also support non-pool (static lease) setups +- Fix #1122: Add YANG validation for consistency, IP addresses are not allowed + on bridge port (interfaces). Even though Infix previously allowed this, but + disregarded it operationally, it is no longer supported in the configuration - Fix #1146: Possible to set longer containers names than the system supports. Root cause, a limit of 15 characters implicitly imposed by the service mgmt daemon, Finit. The length has not been increased to 64 characters (min: 2) diff --git a/src/confd/yang/confd/infix-if-bridge.yang b/src/confd/yang/confd/infix-if-bridge.yang index 59b4db78..72247ba6 100644 --- a/src/confd/yang/confd/infix-if-bridge.yang +++ b/src/confd/yang/confd/infix-if-bridge.yang @@ -15,6 +15,9 @@ submodule infix-if-bridge { import ietf-interfaces { prefix if; } + import ietf-ip { + prefix ip; + } import ieee802-dot1q-types { prefix dot1q-types; } @@ -26,6 +29,10 @@ submodule infix-if-bridge { contact "kernelkit@googlegroups.com"; description "Linux bridge extension for ietf-interfaces."; + revision 2025-10-28 { + description "Prevent IP addresses on bridge ports."; + reference "internal"; + } revision 2025-10-23 { description "Add WiFi interfaces to be able to be added to a bridge."; @@ -918,6 +925,9 @@ submodule infix-if-bridge { description "Extension of the IETF Interfaces model (RFC7223)."; container bridge-port { + must "not(../ip:ipv4/ip:address or ../ip:ipv6/ip:address)" { + error-message "Bridge ports cannot have IP addresses configured."; + } description "Bridge association and port specific settings."; uses bridge-port-common; uses bridge-port-lower { diff --git a/src/confd/yang/confd/infix-if-bridge@2025-10-23.yang b/src/confd/yang/confd/infix-if-bridge@2025-10-28.yang similarity index 100% rename from src/confd/yang/confd/infix-if-bridge@2025-10-23.yang rename to src/confd/yang/confd/infix-if-bridge@2025-10-28.yang