luci-mod-status: improve detection of static cfg

Note that "duid" from UCI can be *either* "<DUID>" or "<DUID>%<IAID>",
so update the code to handle both cases.

Also, make sure the "Reserve IP" button is disabled if the "duid" is
unknown (can only happen if dnsmasq is responsible for DHCPv6) and that
DUIDs/IAIDs are always rendered in lowercase in the UI.

Signed-off-by: David Härdeman <david@hardeman.nu>
This commit is contained in:
David Härdeman
2025-11-09 11:36:03 +01:00
committed by Paul Donald
parent 4a651d591b
commit 6cb0bebf5f

View File

@@ -21,6 +21,7 @@ return baseclass.extend({
isMACStatic: {}, isMACStatic: {},
isDUIDStatic: {}, isDUIDStatic: {},
isDUIDIAIDStatic: {},
load() { load() {
return Promise.all([ return Promise.all([
@@ -63,9 +64,10 @@ return baseclass.extend({
const ip6arr = ip6addr ? validation.parseIPv6(ip6addr) : null; const ip6arr = ip6addr ? validation.parseIPv6(ip6addr) : null;
// Combine DUID and IAID if both available // Combine DUID and IAID if both available
let duid_iaid = lease.duid ? lease.duid.toUpperCase() : null; // (note that we know that lease.duid is set here)
if (duid_iaid && lease.iaid) let duid_iaid = lease.duid.toLowerCase();
duid_iaid += `%${lease.iaid}`; if (lease.iaid)
duid_iaid += `%${lease.iaid}`.toLowerCase();
uci.set('dhcp', cfg, 'name', lease.hostname); uci.set('dhcp', cfg, 'name', lease.hostname);
uci.set('dhcp', cfg, 'duid', [duid_iaid]); uci.set('dhcp', cfg, 'duid', [duid_iaid]);
@@ -85,24 +87,20 @@ return baseclass.extend({
if (leases.length == 0 && leases6.length == 0) if (leases.length == 0 && leases6.length == 0)
return E([]); return E([]);
const machints = host_hints.getMACHints(false); const machints = host_hints.getMACHints(false);
const hosts = uci.sections('dhcp', 'host');
const isReadonlyView = !L.hasViewPermission(); const isReadonlyView = !L.hasViewPermission();
for (const host of uci.sections('dhcp', 'host')) { for (const host of uci.sections('dhcp', 'host')) {
if (host.mac) { for (const mac of L.toArray(host.mac).map(m => m.toLowerCase()))
for (const mac of L.toArray(host.mac).map(m => m.toUpperCase())) { this.isMACStatic[mac] = true;
this.isMACStatic[mac] = true;
} for (const duid_iaid of L.toArray(host.duid).map(m => m.toLowerCase())) {
} const parts = duid_iaid.split('%').length;
if (host.duid) {
if (Array.isArray(host.duid)){ if (parts == 1)
host.duid.map(m => { this.isDUIDStatic[duid_iaid] = true;
this.isDUIDStatic[m.toUpperCase()] = true; else if (parts == 2)
}) this.isDUIDIAIDStatic[duid_iaid] = true;
} else {
this.isDUIDStatic[host.duid.toUpperCase()] = true;
}
} }
}; };
@@ -190,11 +188,23 @@ return baseclass.extend({
else if (hint) else if (hint)
host = hint[1]; host = hint[1];
const duid = lease.duid?.toLowerCase();
const iaid = lease.iaid?.toLowerCase();
// Note: "disabled: false" doesn't work
let disabled = null;
if (!duid)
disabled = true;
else if (duid && this.isDUIDStatic[duid])
disabled = true;
else if (duid && iaid && this.isDUIDIAIDStatic[`${duid}%${iaid}`])
disabled = true;
const columns = [ const columns = [
host || '-', host || '-',
lease.ip6addrs ? lease.ip6addrs.join('<br />') : lease.ip6addr, lease.ip6addrs ? lease.ip6addrs.join('<br />') : lease.ip6addr,
lease?.duid, duid || '-',
lease?.iaid, iaid || '-',
exp exp
]; ];
@@ -203,7 +213,7 @@ return baseclass.extend({
'class': 'cbi-button cbi-button-apply', 'class': 'cbi-button cbi-button-apply',
'click': L.bind(this.handleCreateStaticLease6, this, lease), 'click': L.bind(this.handleCreateStaticLease6, this, lease),
'data-tooltip': _('Reserve a specific IP address for this device'), 'data-tooltip': _('Reserve a specific IP address for this device'),
'disabled': this.isDUIDStatic[lease?.duid?.toUpperCase()] 'disabled': disabled
}, [ _('Reserve IP') ])); }, [ _('Reserve IP') ]));
} }