public inbox for development@lists.ipfire.org
 help / color / mirror / Atom feed
From: Philippe SCARSELLI <p27m@orange.fr>
To: development@lists.ipfire.org
Cc: Philippe SCARSELLI <p27m@orange.fr>
Subject: [PATCH] dhcp: convert dhcpd.conf from CU202 to CU203 format
Date: Sat, 17 Oct 2026 17:11:03 +0200	[thread overview]
Message-ID: <20261017151103.1218-1-p27m@orange.fr> (raw)

Related to bug Bug 14320 - DHCP configuration is not correctly migrated from CU202 to CU203 and more.

here is a proposed fix

This patch enables the automatic migration of the `/var/ipfire/dhcp/dhcpd.conf` file during an upgrade from CU202 to CU203, as well as when restoring a backup from CU202 or earlier onto a CU203 system.
This ensures compliance with the `on commit`, `on release`, and `on expiry` commands required for local DNS management by `knot-resolver`.

This patch was created on the core203 branch to regenerate the core-upgrade-2.29-203.ipfire package and the test CU203 ISO file.
I am not familiar with the integration method for subsequent versions, but it will be useful for backup/restore operations when moving from versions prior to CU203 to CU203 or later.

Tested on x86_64 platform (VMware).
Upgrade from CU202 to CU203 tested.
Restore test of a CU202 backup file onto a fresh CU203 installation on an x86_64 test platform (VMware).
- The /var/ipfire/dhcp/dhcpd.conf file is in the expected format.
- DNS management for DHCP leases is functioning correctly.

Signed-off-by: Philippe SCARSELLI <p27m@orange.fr>
---
 config/backup/backup.pl                   |   4 +
 config/rootfiles/common/aarch64/stage2    |   1 +
 config/rootfiles/common/riscv64/stage2    |   1 +
 config/rootfiles/common/x86_64/stage2     |   1 +
 config/rootfiles/core/203/filelists/files |   1 +
 config/rootfiles/core/203/update.sh       |   4 +-
 src/scripts/convert-dhcp-conf             | 165 ++++++++++++++++++++++
 7 files changed, 174 insertions(+), 3 deletions(-)
 create mode 100644 src/scripts/convert-dhcp-conf

diff --git a/config/backup/backup.pl b/config/backup/backup.pl
index f948c4d21..7ac385ad9 100644
--- a/config/backup/backup.pl
+++ b/config/backup/backup.pl
@@ -213,6 +213,10 @@ restore_backup() {
 	# Convert DNS settings
 	convert-dns-settings
 
+	# Convert DHCP conf
+	convert-dhcp-conf
+	/etc/init.d/dhcp restart
+
 	# move nobeeps if exist
 	[ -e "/var/ipfire/ppp/nobeeps" ] && mv /var/ipfire/ppp/nobeeps /var/ipfire/red/nobeeps
 
diff --git a/config/rootfiles/common/aarch64/stage2 b/config/rootfiles/common/aarch64/stage2
index 4b79d96f6..a02c91c1d 100644
--- a/config/rootfiles/common/aarch64/stage2
+++ b/config/rootfiles/common/aarch64/stage2
@@ -92,6 +92,7 @@ usr/local/bin/backupiso
 usr/local/bin/connscheduler
 usr/local/bin/consort.sh
 usr/local/bin/convert-dns-settings
+usr/local/bin/convert-dhcp-conf
 usr/local/bin/convert-to-location
 usr/local/bin/filesystem-cleanup
 usr/local/bin/hddshutdown
diff --git a/config/rootfiles/common/riscv64/stage2 b/config/rootfiles/common/riscv64/stage2
index 9c3621f62..2d27af818 100644
--- a/config/rootfiles/common/riscv64/stage2
+++ b/config/rootfiles/common/riscv64/stage2
@@ -93,6 +93,7 @@ usr/local/bin/backupiso
 usr/local/bin/connscheduler
 usr/local/bin/consort.sh
 usr/local/bin/convert-dns-settings
+usr/local/bin/convert-dhcp-conf
 usr/local/bin/convert-to-location
 usr/local/bin/filesystem-cleanup
 usr/local/bin/hddshutdown
diff --git a/config/rootfiles/common/x86_64/stage2 b/config/rootfiles/common/x86_64/stage2
index e50df0494..b35aa15d0 100644
--- a/config/rootfiles/common/x86_64/stage2
+++ b/config/rootfiles/common/x86_64/stage2
@@ -92,6 +92,7 @@ usr/local/bin/backupiso
 usr/local/bin/connscheduler
 usr/local/bin/consort.sh
 usr/local/bin/convert-dns-settings
+usr/local/bin/convert-dhcp-conf
 usr/local/bin/convert-to-location
 usr/local/bin/filesystem-cleanup
 usr/local/bin/hddshutdown
diff --git a/config/rootfiles/core/203/filelists/files b/config/rootfiles/core/203/filelists/files
index dd3435411..56dbf818f 100644
--- a/config/rootfiles/core/203/filelists/files
+++ b/config/rootfiles/core/203/filelists/files
@@ -16,6 +16,7 @@ etc/rc.d/rc0.d/K86knot-resolver
 etc/rc.d/rc3.d/S11knot-resolver
 etc/rc.d/rc3.d/S17waitfordns
 etc/rc.d/rc6.d/K86knot-resolver
+usr/local/bin/convert-dhcp-conf
 usr/local/bin/settime
 usr/local/bin/update-rpzs
 usr/local/bin/waitfordns
diff --git a/config/rootfiles/core/203/update.sh b/config/rootfiles/core/203/update.sh
index 5b314664f..7447bef98 100644
--- a/config/rootfiles/core/203/update.sh
+++ b/config/rootfiles/core/203/update.sh
@@ -135,9 +135,7 @@ fi
 
 # Migrate DHCP configuration
 if [ -e "/var/ipfire/dhcp/dhcpd.conf" ]; then
-	sed -e "s/unbound-dhcp-leases-client/dhcp-lease/g" \
-		-i /var/ipfire/dhcp/dhcpd.conf
-
+	/usr/local/bin/convert-dhcp-conf
 	# Restart DHCP
 	/etc/init.d/dhcp restart
 fi
diff --git a/src/scripts/convert-dhcp-conf b/src/scripts/convert-dhcp-conf
new file mode 100644
index 000000000..6215f8315
--- /dev/null
+++ b/src/scripts/convert-dhcp-conf
@@ -0,0 +1,165 @@
+#!/bin/bash
+###############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2007-2026  IPFire Team  <info@ipfire.org>                     #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+#
+# Convert the DHCP configuration from version 202 to version 203.
+#
+# Replace the block from "on commit {" through the closing brace
+# of the "on expiry" block with the version 203 configuration.
+#
+# If DOMAINNAME= is already present, the configuration is
+# considered to be in the new format and no changes are made.
+#
+# All other content in dhcpd.conf must remain unchanged.
+#
+
+set -euo pipefail
+
+DHCP_DIR="/var/ipfire/dhcp"
+TARGET="${DHCP_DIR}/dhcpd.conf"
+
+# Check that the script is running as root.
+if [[ $EUID -ne 0 ]]; then
+    echo "Error: This script must be run as root." >&2
+    exit 1
+fi
+
+# Check that the target configuration file exists.
+if [[ ! -f "$TARGET" ]]; then
+    echo "Error: DHCP configuration file not found: $TARGET" >&2
+    exit 1
+fi
+
+# Skip conversion if the configuration is already in the new format.
+if grep -q 'DOMAINNAME=' "$TARGET"; then
+    echo "DHCP configuration already uses the new format. No changes required."
+    exit 0
+fi
+
+# Define the version 203 hooks.
+read -r -d '' NEW_BLOCK <<'EOF' || true
+on commit {
+	set ClientAddress = concat(
+		"ADDRESS=",
+		binary-to-ascii(10, 8, ".", leased-address)
+	);
+	set ClientHostName = concat(
+		"HOSTNAME=",
+		pick-first-value(option host-name, config-option-host-name, client-name, "")
+	);
+	set ClientDomainName = concat(
+		"DOMAINNAME=",
+		pick-first-value(config-option domain-name, "")
+	);
+
+	if (ClientHostName != "") {
+		execute("/usr/sbin/dhcp-lease", "commit", ClientAddress, ClientHostName, ClientDomainName);
+	}
+}
+
+on release {
+	set ClientAddress = concat(
+		"ADDRESS=",
+		binary-to-ascii(10, 8, ".", leased-address)
+	);
+	set ClientHostName = concat(
+		"HOSTNAME=",
+		pick-first-value(option host-name, config-option-host-name, client-name, "")
+	);
+	set ClientDomainName = concat(
+		"DOMAINNAME=",
+		pick-first-value(config-option domain-name, "")
+	);
+
+	if (ClientHostName != "") {
+		execute("/usr/sbin/dhcp-lease", "release", ClientAddress, ClientHostName, ClientDomainName);
+	}
+}
+
+on expiry {
+	set ClientAddress = concat(
+		"ADDRESS=",
+		binary-to-ascii(10, 8, ".", leased-address)
+	);
+
+	execute("/usr/sbin/dhcp-lease", "expiry", ClientAddress);
+}
+EOF
+
+# Ensure the expected hooks exist in the original configuration.
+if ! grep -q '^on commit[[:space:]]*{' "$TARGET" ||
+   ! grep -q '^on expiry[[:space:]]*{' "$TARGET"; then
+    echo "Error: Expected DHCP hooks were not found in $TARGET." >&2
+    exit 1
+fi
+
+# Create a temporary file in the same directory.
+TMP=$(mktemp "${DHCP_DIR}/dhcpd.conf.XXXXXX")
+trap 'rm -f "$TMP"' EXIT
+
+# Replace only the block from "on commit" to the end of "on expiry".
+awk -v replacement="$NEW_BLOCK" '
+    /^on commit[[:space:]]*\{/ && !done {
+        print replacement
+        done = 1
+        skipping = 1
+        next
+    }
+
+    skipping && /^on expiry[[:space:]]*\{/ {
+        expiry = 1
+        next
+    }
+
+    skipping && expiry && /^}/ {
+        skipping = 0
+        expiry = 0
+        next
+    }
+
+    !skipping {
+        print
+    }
+
+    END {
+        if (!done || skipping) {
+            exit 1
+        }
+    }
+' "$TARGET" > "$TMP" || {
+    echo "Error: Failed to replace the DHCP hooks." >&2
+    exit 1
+}
+
+# Validate the configuration before installing it.
+if ! dhcpd -t -cf "$TMP"; then
+    echo "Error: Invalid DHCP configuration. The original file is unchanged." >&2
+    exit 1
+fi
+
+# Preserve the original permissions and ownership.
+chmod --reference="$TARGET" "$TMP"
+chown --reference="$TARGET" "$TMP"
+
+# Install the updated configuration.
+mv "$TMP" "$TARGET"
+trap - EXIT
+
+echo "DHCP configuration successfully updated to version 203."
-- 
2.47.3



                 reply	other threads:[~2026-10-17 15:11 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261017151103.1218-1-p27m@orange.fr \
    --to=p27m@orange.fr \
    --cc=development@lists.ipfire.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox