luci-mod-status,-network: remove checkUfpInstalled

Right now, the checkUfpInstalled RPC call is performed first, and only after
that can the other Promises be called. Simplify this by adding a single check
for /usr/sbin/ufpd in the rpcd ucode, and replace calls to checkUfpInstalled()
with simple L.hasSystemFeature('ufpd') check (which is only done once, and
cached).

This also allows the 'stat' permission to be removed from a couple of acls.

Signed-off-by: David Härdeman <david@hardeman.nu>
This commit is contained in:
David Härdeman
2025-10-15 15:07:32 +02:00
committed by Paul Donald
parent 3ed815fe4a
commit 50abd15e88
8 changed files with 36 additions and 81 deletions

View File

@@ -237,6 +237,7 @@ const methods = {
relayd: access('/usr/sbin/relayd') == true, relayd: access('/usr/sbin/relayd') == true,
apk: access('/usr/bin/apk') == true, apk: access('/usr/bin/apk') == true,
wifi: access('/sbin/wifi') == true, wifi: access('/sbin/wifi') == true,
ufpd: access('/usr/sbin/ufpd') == true,
vrf: access('/sys/module/vrf/refcnt') == true, // vrf.ko is loaded vrf: access('/sys/module/vrf/refcnt') == true, // vrf.ko is loaded
netifd_vrf: false, netifd_vrf: false,
}; };

View File

@@ -11,7 +11,7 @@
'require tools.dnsrecordhandlers as drh'; 'require tools.dnsrecordhandlers as drh';
var callHostHints, callDUIDHints, callDHCPLeases, CBILeaseStatus, CBILease6Status; var callHostHints, callDUIDHints, callDHCPLeases, CBILeaseStatus, CBILease6Status;
var checkUfpInstalled, callUfpList; var callUfpList;
callHostHints = rpc.declare({ callHostHints = rpc.declare({
object: 'luci-rpc', object: 'luci-rpc',
@@ -31,12 +31,6 @@ callDHCPLeases = rpc.declare({
expect: { '': {} } expect: { '': {} }
}); });
checkUfpInstalled = rpc.declare({
object: 'file',
method: 'stat',
params: [ 'path' ]
});
callUfpList = rpc.declare({ callUfpList = rpc.declare({
object: 'fingerprint', object: 'fingerprint',
method: 'fingerprint', method: 'fingerprint',
@@ -289,19 +283,13 @@ function validateMACAddr(pools, sid, s) {
return view.extend({ return view.extend({
load: function() { load: function() {
return Promise.all([ return Promise.all([
checkUfpInstalled('/usr/sbin/ufpd')
]).then(data => {
var promises = [
callHostHints(), callHostHints(),
callDUIDHints(), callDUIDHints(),
getDHCPPools(), getDHCPPools(),
network.getNetworks(), network.getNetworks(),
data[0].type === 'file' ? callUfpList() : null, L.hasSystemFeature('ufpd') ? callUfpList() : null,
uci.load('firewall') uci.load('firewall')
] ]);
return Promise.all(promises);
});
}, },
render: function([hosts, duids, pools, networks, macdata]) { render: function([hosts, duids, pools, networks, macdata]) {

View File

@@ -39,8 +39,7 @@
"read": { "read": {
"ubus": { "ubus": {
"luci-rpc": [ "getDHCPLeases", "getDUIDHints", "getHostHints" ], "luci-rpc": [ "getDHCPLeases", "getDUIDHints", "getHostHints" ],
"fingerprint": [ "fingerprint" ], "fingerprint": [ "fingerprint" ]
"file": [ "stat" ]
}, },
"uci": [ "dhcp" ] "uci": [ "dhcp" ]
}, },

View File

@@ -16,12 +16,6 @@ var callUfpList = rpc.declare({
method: 'fingerprint', method: 'fingerprint',
}); });
var checkUfpInstalled = rpc.declare({
object: 'file',
method: 'stat',
params: [ 'path' ]
});
return baseclass.extend({ return baseclass.extend({
title: '', title: '',
@@ -30,17 +24,11 @@ return baseclass.extend({
load: function() { load: function() {
return Promise.all([ return Promise.all([
checkUfpInstalled('/usr/sbin/ufpd')
]).then(data => {
var promises = [
callLuciDHCPLeases(), callLuciDHCPLeases(),
network.getHostHints(), network.getHostHints(),
data[0].type === 'file' ? callUfpList() : null, L.hasSystemFeature('ufpd') ? callUfpList() : null,
L.resolveDefault(uci.load('dhcp')) L.resolveDefault(uci.load('dhcp'))
]; ]);
return Promise.all(promises);
});
}, },
handleCreateStaticLease: function(lease, ev) { handleCreateStaticLease: function(lease, ev) {

View File

@@ -11,12 +11,6 @@ const callNetworkInterfaceDump = rpc.declare({
expect: { interface: [] } expect: { interface: [] }
}); });
const checkUfpInstalled = rpc.declare({
object: 'file',
method: 'stat',
params: [ 'path' ]
});
const callUfpList = rpc.declare({ const callUfpList = rpc.declare({
object: 'fingerprint', object: 'fingerprint',
method: 'fingerprint', method: 'fingerprint',
@@ -43,9 +37,6 @@ function applyMask(addr, mask, v6) {
return view.extend({ return view.extend({
load() { load() {
return Promise.all([
checkUfpInstalled('/usr/sbin/ufpd')
]).then(([ufpcheck]) => {
return Promise.all([ return Promise.all([
callNetworkInterfaceDump(), callNetworkInterfaceDump(),
L.resolveDefault(fs.exec('/sbin/ip', [ '-4', 'neigh', 'show' ]), {}), L.resolveDefault(fs.exec('/sbin/ip', [ '-4', 'neigh', 'show' ]), {}),
@@ -54,9 +45,8 @@ return view.extend({
L.resolveDefault(fs.exec('/sbin/ip', [ '-6', 'neigh', 'show' ]), {}), L.resolveDefault(fs.exec('/sbin/ip', [ '-6', 'neigh', 'show' ]), {}),
L.resolveDefault(fs.exec('/sbin/ip', [ '-6', 'route', 'show', 'table', 'all' ]), {}), L.resolveDefault(fs.exec('/sbin/ip', [ '-6', 'route', 'show', 'table', 'all' ]), {}),
L.resolveDefault(fs.exec('/sbin/ip', [ '-6', 'rule', 'show' ]), {}), L.resolveDefault(fs.exec('/sbin/ip', [ '-6', 'rule', 'show' ]), {}),
ufpcheck?.type === 'file' ? callUfpList() : null L.hasSystemFeature('ufpd') ? callUfpList() : null
]); ]);
});
}, },
getNetworkByDevice(networks, dev, addr, mask, v6) { getNetworkByDevice(networks, dev, addr, mask, v6) {

View File

@@ -12,12 +12,6 @@ const callNetworkInterfaceDump = rpc.declare({
expect: { interface: [] } expect: { interface: [] }
}); });
const checkUfpInstalled = rpc.declare({
object: 'file',
method: 'stat',
params: [ 'path' ]
});
const callUfpList = rpc.declare({ const callUfpList = rpc.declare({
object: 'fingerprint', object: 'fingerprint',
method: 'fingerprint', method: 'fingerprint',
@@ -44,9 +38,6 @@ function applyMask(addr, mask, v6) {
return view.extend({ return view.extend({
load() { load() {
return Promise.all([
checkUfpInstalled('/usr/sbin/ufpd')
]).then(([ufpcheck]) => {
return Promise.all([ return Promise.all([
callNetworkInterfaceDump(), callNetworkInterfaceDump(),
L.resolveDefault(fs.exec('/sbin/ip', [ '-4', '-j', 'neigh', 'show' ]), {}), L.resolveDefault(fs.exec('/sbin/ip', [ '-4', '-j', 'neigh', 'show' ]), {}),
@@ -55,9 +46,8 @@ return view.extend({
L.resolveDefault(fs.exec('/sbin/ip', [ '-6', '-j', 'neigh', 'show' ]), {}), L.resolveDefault(fs.exec('/sbin/ip', [ '-6', '-j', 'neigh', 'show' ]), {}),
L.resolveDefault(fs.exec('/sbin/ip', [ '-6', '-j', 'route', 'show', 'table', 'all' ]), {}), L.resolveDefault(fs.exec('/sbin/ip', [ '-6', '-j', 'route', 'show', 'table', 'all' ]), {}),
L.resolveDefault(fs.exec('/sbin/ip', [ '-6', '-j', 'rule', 'show' ]), {}), L.resolveDefault(fs.exec('/sbin/ip', [ '-6', '-j', 'rule', 'show' ]), {}),
ufpcheck?.type === 'file' ? callUfpList() : null, L.hasSystemFeature('ufpd') ? callUfpList() : null,
]); ]);
});
}, },
getNetworkByDevice(networks, dev, addr, mask, v6) { getNetworkByDevice(networks, dev, addr, mask, v6) {

View File

@@ -34,8 +34,7 @@
"read": { "read": {
"ubus": { "ubus": {
"luci-rpc": [ "getDHCPLeases" ], "luci-rpc": [ "getDHCPLeases" ],
"fingerprint": [ "fingerprint" ], "fingerprint": [ "fingerprint" ]
"file": [ "stat" ]
} }
} }
}, },

View File

@@ -49,7 +49,7 @@
"/sbin/ip -[46] rule show": [ "exec" ] "/sbin/ip -[46] rule show": [ "exec" ]
}, },
"ubus": { "ubus": {
"file": [ "exec", "stat" ], "file": [ "exec" ],
"fingerprint": [ "fingerprint" ] "fingerprint": [ "fingerprint" ]
} }
} }
@@ -64,7 +64,7 @@
"/sbin/ip -[46] -j rule show": [ "exec" ] "/sbin/ip -[46] -j rule show": [ "exec" ]
}, },
"ubus": { "ubus": {
"file": [ "exec", "stat" ], "file": [ "exec" ],
"fingerprint": [ "fingerprint" ] "fingerprint": [ "fingerprint" ]
} }
} }