Skip to content

Commit b72fb8f

Browse files
authored
Merge pull request #1211 from kernelkit/misc-fixes
2 parents 3384507 + 7e37fc4 commit b72fb8f

File tree

10 files changed

+91
-9
lines changed

10 files changed

+91
-9
lines changed

.github/workflows/generic-x86-build.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,17 @@ jobs:
1010
runs-on: ubuntu-latest
1111

1212
steps:
13+
- name: Free Disk Space
14+
uses: jlumbroso/free-disk-space@main
15+
with:
16+
tool-cache: true
17+
android: true
18+
dotnet: true
19+
haskell: true
20+
large-packages: true
21+
docker-images: true
22+
swap-storage: false
23+
1324
- name: Install build dependencies
1425
run: |
1526
sudo apt-get update

doc/ChangeLog.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Change Log
33

44
All notable changes to the project are documented in this file.
55

6-
[v25.10.0][UNRELEASED] -
6+
[v25.10.0][] - 2025-10-31
77
-------------------------
88

99
### Changes
@@ -31,6 +31,13 @@ All notable changes to the project are documented in this file.
3131

3232
- Fix #981: copying any file, including `running-config`, to the persistent
3333
back-end store for `startup-config`, does not take
34+
- Fix #1121: Ensure DHCP server does not crash if no address pool is set. This
35+
change infers a pool range (only) for /24 networks, and only when a pool is
36+
enabled. YANG validation for this and other use-cases is also included. As
37+
an unforeseen bonus, Infix now also support non-pool (static lease) setups
38+
- Fix #1122: Add YANG validation for consistency, IP addresses are not allowed
39+
on bridge port (interfaces). Even though Infix previously allowed this, but
40+
disregarded it operationally, it is no longer supported in the configuration
3441
- Fix #1146: Possible to set longer containers names than the system supports.
3542
Root cause, a limit of 15 characters implicitly imposed by the service mgmt
3643
daemon, Finit. The length has not been increased to 64 characters (min: 2)

patches/libyang/3.13.5/0001-lyd_validate_obsolete-change-log-level-warning-debug.patch

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
From 4603d09f5d1bd9ca0a1d4467d30a71528c8e2df4 Mon Sep 17 00:00:00 2001
1+
From 50a8a5c0d07de5f72323be6d9ba1d1b78fdc6b9b Mon Sep 17 00:00:00 2001
22
From: Joachim Wiberg <[email protected]>
33
Date: Mon, 1 Sep 2025 14:24:03 +0200
44
Subject: [PATCH] lyd_validate_obsolete: change log level warning -> debug
@@ -46,15 +46,15 @@ index 85f2ac6d4..2bbb0b19b 100644
4646
/**
4747
* @}
4848
diff --git a/src/validation.c b/src/validation.c
49-
index 25be0feeb..8e308c61f 100644
49+
index 25be0feeb..86b82dbff 100644
5050
--- a/src/validation.c
5151
+++ b/src/validation.c
5252
@@ -1624,7 +1624,7 @@ lyd_validate_obsolete(const struct lyd_node *node)
5353
if (snode->flags & LYS_STATUS_OBSLT &&
5454
(!(snode->nodetype & LYD_NODE_INNER) || lyd_child(node))) {
5555
LOG_LOCSET(NULL, node);
5656
- LOGWRN(snode->module->ctx, "Obsolete schema node \"%s\" instantiated in data.", snode->name);
57-
+ LOGDBG(LY_LDGSCHEMA, snode->module->ctx, "Obsolete schema node \"%s\" instantiated in data.", snode->name);
57+
+ LOGDBG(LY_LDGSCHEMA, "%s: obsolete schema node \"%s\" instantiated in data.", snode->module->name, snode->name);
5858
LOG_LOCBACK(0, 1);
5959
break;
6060
}

src/confd/src/infix-dhcp-server.c

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,10 +223,12 @@ static void add(const char *subnet, struct lyd_node *cfg)
223223
start = lydx_get_cattr(node, "start-address");
224224
end = lydx_get_cattr(node, "end-address");
225225

226-
fprintf(fp, "\n# Subnet pool %s - %s\n", start, end);
227-
fprintf(fp, "dhcp-range=%s%sset:%s,%s,%s,%s\n",
228-
ifname ?: "", ifname ? "," : "", tag,
229-
start, end, lydx_get_cattr(node, "lease-time"));
226+
if (start && end) {
227+
fprintf(fp, "\n# Subnet pool %s - %s\n", start, end);
228+
fprintf(fp, "dhcp-range=%s%sset:%s,%s,%s,%s\n",
229+
ifname ?: "", ifname ? "," : "", tag,
230+
start, end, lydx_get_cattr(node, "lease-time"));
231+
}
230232
}
231233

232234
err:
@@ -400,6 +402,7 @@ static int cand(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
400402
"router",
401403
"dns-server",
402404
};
405+
sr_val_t *subnets = NULL;
403406
size_t i, cnt = 0;
404407

405408
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,
413416
srx_set_item(session, &inferred, 0, fmt, opt[i]);
414417
}
415418

419+
/* Infer pool: .100 to .250 for /24 networks */
420+
if (sr_get_items(session, CFG_XPATH "/subnet/subnet", 0, 0, &subnets, &cnt) == 0) {
421+
for (i = 0; i < cnt; i++) {
422+
const char *pool_xpathfmt = CFG_XPATH "/subnet[subnet='%s']/pool";
423+
const char *host_xpathfmt = CFG_XPATH "/subnet[subnet='%s']/host";
424+
const char *subnet = subnets[i].data.string_val;
425+
sr_val_t pool_val = { .type = SR_STRING_T };
426+
char start_addr[16], end_addr[16];
427+
unsigned int a, b, c, d, len;
428+
size_t pool_cnt = 0, host_cnt = 0;
429+
430+
if (sscanf(subnet, "%u.%u.%u.%u/%u", &a, &b, &c, &d, &len) != 5 || len != 24)
431+
continue;
432+
433+
/* Don't auto-infer if pool or static hosts already exist */
434+
if (!srx_nitems(session, &pool_cnt, pool_xpathfmt, subnet) && pool_cnt)
435+
continue;
436+
if (!srx_nitems(session, &host_cnt, host_xpathfmt, subnet) && host_cnt)
437+
continue;
438+
439+
snprintf(start_addr, sizeof(start_addr), "%u.%u.%u.100", a, b, c);
440+
snprintf(end_addr, sizeof(end_addr), "%u.%u.%u.250", a, b, c);
441+
442+
pool_val.data.string_val = start_addr;
443+
srx_set_item(session, &pool_val, 0, CFG_XPATH "/subnet[subnet='%s']/pool/start-address", subnet);
444+
pool_val.data.string_val = end_addr;
445+
srx_set_item(session, &pool_val, 0, CFG_XPATH "/subnet[subnet='%s']/pool/end-address", subnet);
446+
}
447+
sr_free_values(subnets, cnt);
448+
}
449+
416450
return 0;
417451
}
418452

src/confd/yang/confd.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ MODULES=(
2727
2828
2929
30-
"infix-dhcp-server@2025-01-29.yang"
30+
"infix-dhcp-server@2025-10-28.yang"
3131
3232
3333

src/confd/yang/confd/infix-dhcp-server.yang

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ module infix-dhcp-server {
2020
contact "[email protected]";
2121
description "This module implements a DHCPv4 server";
2222

23+
revision 2025-10-28 {
24+
description "Make pool a presence container and add pool validation.
25+
Also, require each subnet to have either a pool or
26+
at least one static host entry.";
27+
reference "internal";
28+
}
29+
2330
revision 2025-01-29 {
2431
description "Initial revision adapted for Infix from DHCPv6 model.";
2532
reference "internal";
@@ -132,6 +139,10 @@ module infix-dhcp-server {
132139
description "Subnet specific settings, including static host entries.";
133140
key "subnet";
134141

142+
must "pool or host" {
143+
error-message "Subnet must have either a pool or at least one static host entry.";
144+
}
145+
135146
leaf subnet {
136147
description "Subnet to serve DHCP leases from.";
137148
type inet:ipv4-prefix;
@@ -160,8 +171,13 @@ module infix-dhcp-server {
160171
}
161172

162173
container pool {
174+
presence "Enable dynamic DHCP address pool for this subnet.";
163175
description "IP address pool for this subnet.";
164176

177+
must "start-address and end-address" {
178+
error-message "Both start-address and end-address must be set if pool is configured.";
179+
}
180+
165181
leaf start-address {
166182
description "The start address of the DHCP address pool.";
167183
type inet:ipv4-address;

src/confd/yang/confd/infix-if-bridge.yang

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ submodule infix-if-bridge {
1515
import ietf-interfaces {
1616
prefix if;
1717
}
18+
import ietf-ip {
19+
prefix ip;
20+
}
1821
import ieee802-dot1q-types {
1922
prefix dot1q-types;
2023
}
@@ -26,6 +29,10 @@ submodule infix-if-bridge {
2629
contact "[email protected]";
2730
description "Linux bridge extension for ietf-interfaces.";
2831

32+
revision 2025-10-28 {
33+
description "Prevent IP addresses on bridge ports.";
34+
reference "internal";
35+
}
2936

3037
revision 2025-10-23 {
3138
description "Add WiFi interfaces to be able to be added to a bridge.";
@@ -918,6 +925,9 @@ submodule infix-if-bridge {
918925
description "Extension of the IETF Interfaces model (RFC7223).";
919926

920927
container bridge-port {
928+
must "not(../ip:ipv4/ip:address or ../ip:ipv6/ip:address)" {
929+
error-message "Bridge ports cannot have IP addresses configured.";
930+
}
921931
description "Bridge association and port specific settings.";
922932
uses bridge-port-common;
923933
uses bridge-port-lower {

test/docker/pip-requirements.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,8 @@ pydot==1.4.2
66
pyyaml==6.0.1
77
passlib==1.7.4
88
requests~=2.32.4
9+
# GHSA-cq46-m9x9-j8w2: scapy <=2.6.1 has pickle deserialization vuln in session
10+
# loading (-s flag). Low risk: test framework only uses packet crafting (Ether,
11+
# sendp, LLDP), not session loading. Update to 2.7.0+ when available on PyPI.
12+
# https://github.com/advisories/GHSA-cq46-m9x9-j8w2
913
scapy==2.6.1

0 commit comments

Comments
 (0)