uspot/spotfilter: implement captive generate

For basic uspot setups, this commit implements a 'generate' verb to
uspot /usr/bin/captive that takes a config uspot section name, and
parses the following extra options to generate the relevant spotfilter
config:

  option generate_spotfilter (bool) # if unset/false, generate is a NOP
  option interface 'name' # config/network interface name to redirect to
  option client_autoremove (bool) # if set/true, sets client_autoremove
  list wl_hosts '*.example.com' # optional list of whitelist hostnames
  list wl_addrs '1.2.3.4' # optional list of whitelist IPs

"captive generate" is called in spotfilter.init to optionally (depending
on 'generate_spotfilter') create the required spotfilter-XXX.json before
starting spotfilter.

Signed-off-by: Thibaut VARÈNE <hacks@slashdirt.org>
This commit is contained in:
Thibaut VARÈNE
2023-05-11 16:23:40 +02:00
committed by John Crispin
parent 74651831ef
commit 243f42454f
2 changed files with 71 additions and 1 deletions

View File

@@ -7,7 +7,12 @@ USE_PROCD=1
PROG=/usr/sbin/spotfilter
add_interface() {
ubus call spotfilter interface_add "$(cat /tmp/spotfilter-$1.json)"
local cfg="$1"
local enabled
config_get_bool enabled "$cfg" "configure_spotfilter" 0
[ $enabled -eq 0 ] || /usr/bin/captive generate "$cfg" > /tmp/spotfilter-$cfg.json
ubus call spotfilter interface_add "$(cat /tmp/spotfilter-$cfg.json)"
}
reload_service() {

View File

@@ -17,6 +17,68 @@ function interfaces() {
return uniq(interfaces);
}
function generate_spotfilter(name) {
function parse_bool(val) {
if (val == "1" || val == "on" || val == "true" || val == "yes")
return true;
else if (val == "0" || val == "off" || val == "false" || val == "no")
return false;
else
return null;
}
function fail(msg) {
warn(msg + '\n');
exit(1);
}
if (!parse_bool(uci.get('uspot', name, 'configure_spotfilter')))
exit(0);
let uspot = uci.get_all('uspot', name);
if (!uspot)
fail('Cannot load uspot config for "' + name);
let device_macaddr = uci.get('network', uspot.interface, 'device');
if (!device_macaddr)
fail('Cannot find target network interface');
if (uspot.wl_hosts && type(uspot.wl_hosts) != "array")
fail('Expecting list for wl_hosts');
if (uspot.wl_addrs && type(uspot.wl_addrs) != "array")
fail('Expecting list for wl_addrs');
let class = [
{
index: 0,
device_macaddr,
fwmark: 1,
fwmark_mask: 127
}, {
index: 1,
fwmark: 2,
fwmark_mask: 127
}
];
let whitelist = [{
class: 1,
hosts: uspot.wl_hosts || [],
address: uspot.wl_addrs || [],
}];
let conf = {
name,
devices: type(uspot.ifname) == "array" ? uspot.ifname : [ uspot.ifname ],
config: {
default_class: 0,
default_dns_class: 1,
client_autoremove: !!parse_bool(uspot.client_autoremove),
class,
whitelist
}
};
printf('%.J\n', conf);
}
switch(ARGV[0]) {
case 'dump':
for (let interface in interfaces()) {
@@ -58,6 +120,9 @@ case 'debugoff':
uci.commit();
restart();
break;
case 'generate':
generate_spotfilter(ARGV[1]);
break;
default:
break;
}