luci-mod-network,-status: expose the lease interface

This adds support to LuCI for showing the interface which a given lease
corresponds to (assuming that odhcpd is providing the DHCPv4/6 services,
which the code also checks for).

Signed-off-by: David Härdeman <david@hardeman.nu>
This commit is contained in:
David Härdeman
2025-11-30 20:03:03 +01:00
committed by Paul Donald
parent 570b4bfe6f
commit 70d89764e3
2 changed files with 22 additions and 2 deletions

View File

@@ -39,6 +39,7 @@ const CBILeaseStatus = form.DummyValue.extend({
E('h4', _('Active DHCPv4 Leases')), E('h4', _('Active DHCPv4 Leases')),
E('table', { 'id': 'lease_status_table', 'class': 'table' }, [ E('table', { 'id': 'lease_status_table', 'class': 'table' }, [
E('tr', { 'class': 'tr table-titles' }, [ E('tr', { 'class': 'tr table-titles' }, [
L.hasSystemFeature('odhcpd', 'dhcpv4') ? E('th', { 'class': 'th' }, _('Interface')) : E([]),
E('th', { 'class': 'th' }, _('Hostname')), E('th', { 'class': 'th' }, _('Hostname')),
E('th', { 'class': 'th' }, _('IPv4 address')), E('th', { 'class': 'th' }, _('IPv4 address')),
E('th', { 'class': 'th' }, _('MAC address')), E('th', { 'class': 'th' }, _('MAC address')),
@@ -58,6 +59,7 @@ const CBILease6Status = form.DummyValue.extend({
E('h4', _('Active DHCPv6 Leases')), E('h4', _('Active DHCPv6 Leases')),
E('table', { 'id': 'lease6_status_table', 'class': 'table' }, [ E('table', { 'id': 'lease6_status_table', 'class': 'table' }, [
E('tr', { 'class': 'tr table-titles' }, [ E('tr', { 'class': 'tr table-titles' }, [
L.hasSystemFeature('odhcpd', 'dhcpv6') ? E('th', { 'class': 'th' }, _('Interface')) : E([]),
E('th', { 'class': 'th' }, _('Hostname')), E('th', { 'class': 'th' }, _('Hostname')),
E('th', { 'class': 'th' }, _('IPv6 addresses')), E('th', { 'class': 'th' }, _('IPv6 addresses')),
E('th', { 'class': 'th' }, _('DUID')), E('th', { 'class': 'th' }, _('DUID')),
@@ -249,12 +251,17 @@ return view.extend({
else if (lease.hostname) else if (lease.hostname)
host = lease.hostname; host = lease.hostname;
return [ const columns = [
host || '-', host || '-',
lease.ipaddr, lease.ipaddr,
vendor ? lease.macaddr + vendor : lease.macaddr, vendor ? lease.macaddr + vendor : lease.macaddr,
exp exp
]; ];
if (L.hasSystemFeature('odhcpd', 'dhcpv4'))
columns.unshift(lease.interface || '-');
return columns;
}), }),
E('em', _('There are no active leases')) E('em', _('There are no active leases'))
); );
@@ -281,13 +288,18 @@ return view.extend({
else if (name) else if (name)
host = name; host = name;
return [ const columns = [
host || '-', host || '-',
lease.ip6addrs ? lease.ip6addrs.join('<br />') : lease.ip6addr, lease.ip6addrs ? lease.ip6addrs.join('<br />') : lease.ip6addr,
lease.duid, lease.duid,
lease.iaid, lease.iaid,
exp exp
]; ];
if (L.hasSystemFeature('odhcpd', 'dhcpv6'))
columns.unshift(lease.interface || '-');
return columns;
}), }),
E('em', _('There are no active leases')) E('em', _('There are no active leases'))
); );

View File

@@ -106,6 +106,7 @@ return baseclass.extend({
const table = E('table', { 'id': 'status_leases', 'class': 'table lases' }, [ const table = E('table', { 'id': 'status_leases', 'class': 'table lases' }, [
E('tr', { 'class': 'tr table-titles' }, [ E('tr', { 'class': 'tr table-titles' }, [
L.hasSystemFeature('odhcpd', 'dhcpv4') ? E('th', { 'class': 'th' }, _('Interface')) : E([]),
E('th', { 'class': 'th' }, _('Hostname')), E('th', { 'class': 'th' }, _('Hostname')),
E('th', { 'class': 'th' }, _('IPv4 address')), E('th', { 'class': 'th' }, _('IPv4 address')),
E('th', { 'class': 'th' }, _('MAC address')), E('th', { 'class': 'th' }, _('MAC address')),
@@ -145,6 +146,9 @@ return baseclass.extend({
exp, exp,
]; ];
if (L.hasSystemFeature('odhcpd', 'dhcpv4'))
columns.unshift(lease.interface || '-');
if (!isReadonlyView && lease.macaddr != null) { if (!isReadonlyView && lease.macaddr != null) {
columns.push(E('button', { columns.push(E('button', {
'class': 'cbi-button cbi-button-apply', 'class': 'cbi-button cbi-button-apply',
@@ -159,6 +163,7 @@ return baseclass.extend({
const table6 = E('table', { 'id': 'status_leases6', 'class': 'table leases6' }, [ const table6 = E('table', { 'id': 'status_leases6', 'class': 'table leases6' }, [
E('tr', { 'class': 'tr table-titles' }, [ E('tr', { 'class': 'tr table-titles' }, [
L.hasSystemFeature('odhcpd', 'dhcpv6') ? E('th', { 'class': 'th' }, _('Interface')) : E([]),
E('th', { 'class': 'th' }, _('Host')), E('th', { 'class': 'th' }, _('Host')),
E('th', { 'class': 'th' }, _('IPv6 addresses')), E('th', { 'class': 'th' }, _('IPv6 addresses')),
E('th', { 'class': 'th' }, _('DUID')), E('th', { 'class': 'th' }, _('DUID')),
@@ -208,6 +213,9 @@ return baseclass.extend({
exp exp
]; ];
if (L.hasSystemFeature('odhcpd', 'dhcpv6'))
columns.unshift(lease.interface || '-');
if (!isReadonlyView && lease.duid) { if (!isReadonlyView && lease.duid) {
columns.push(E('button', { columns.push(E('button', {
'class': 'cbi-button cbi-button-apply', 'class': 'cbi-button cbi-button-apply',