mirror of
https://github.com/Telecominfraproject/wlan-ucentral-schema.git
synced 2026-01-27 10:23:38 +00:00
schema: more fixes for issues that came up while testing on device
Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
10
command/cmd.uc
Normal file → Executable file
10
command/cmd.uc
Normal file → Executable file
@@ -1,5 +1,13 @@
|
||||
#!/usr/bin/ucode
|
||||
{%
|
||||
|
||||
let fs = require("fs");
|
||||
let uci = require("uci");
|
||||
let ubus = require("ubus");
|
||||
let capabfile = fs.open("/etc/ucentral/capabilities.json", "r");
|
||||
let capab = json(capabfile.read("all"));
|
||||
let cmdfile = fs.open(ARGV[2], "r");
|
||||
let cmd = json(cmdfile.read("all"));
|
||||
let id = ARGV[3];
|
||||
let ctx = ubus.connect();
|
||||
|
||||
if (!ctx) {
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
{%
|
||||
let verbose = args.verbose ? true : false;
|
||||
if (args.bands) {
|
||||
for (let band in args.bands)
|
||||
ctx.call("wifi", "scan", { band });
|
||||
} else {
|
||||
ctx.call("wifi", "scan");
|
||||
}
|
||||
ctx.call("wifi", "scan");
|
||||
system("sleep 5");
|
||||
let scan = ctx.call("wifi", "scan_dump", {verbose});
|
||||
let survey = ctx.call("wifi", "survey");
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
let uci = require("uci");
|
||||
let ubus = require("ubus");
|
||||
let math = require("math");
|
||||
|
||||
let cursor = uci ? uci.cursor() : null;
|
||||
let conn = ubus ? ubus.connect() : null;
|
||||
@@ -176,12 +177,22 @@ let ethernet = {
|
||||
return sort(keys(matched));
|
||||
},
|
||||
|
||||
calculate_names: function(interface) {
|
||||
calculate_name: function(interface) {
|
||||
let vid = interface.vlan ? interface.vlan.id : '';
|
||||
let name = interface.role + vid;
|
||||
let ipv4_mode = interface.ipv4 ? interface.ipv4.addressing : 'none';
|
||||
|
||||
return (interface.role == 'upstream' ? 'wan' : 'lan') + vid;
|
||||
},
|
||||
|
||||
calculate_names: function(interface) {
|
||||
let name = this.calculate_name(interface);
|
||||
|
||||
let ipv4_mode = interface.ipv4 ? interface.ipv4.addressing : 'none';
|
||||
let ipv6_mode = interface.ipv6 ? interface.ipv6.addressing : 'none';
|
||||
return name;
|
||||
|
||||
return (
|
||||
(ipv4_mode == 'none') || (ipv6_mode == 'none') ||
|
||||
(ipv4_mode == 'static' && ipv6_mode == 'static')
|
||||
) ? [ name ] : [ name + '_4', name + '_6' ];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
14
renderer/templates/base.uc
Normal file
14
renderer/templates/base.uc
Normal file
@@ -0,0 +1,14 @@
|
||||
# Basic configuration
|
||||
set network.loopback=interface
|
||||
set network.loopback.ifname='lo'
|
||||
set network.loopback.proto='static'
|
||||
set network.loopback.ipaddr='127.0.0.1'
|
||||
set network.loopback.netmask='255.0.0.0'
|
||||
|
||||
add network device
|
||||
set network.@device[-1].name=up
|
||||
set network.@device[-1].type=bridge
|
||||
|
||||
add network device
|
||||
set network.@device[-1].name=down
|
||||
set network.@device[-1].type=bridge
|
||||
@@ -1,4 +1,6 @@
|
||||
{%
|
||||
let math = require("math");
|
||||
|
||||
// Skip interfaces previously marked as conflicting.
|
||||
if (interface.conflicting) {
|
||||
warn("Skipping conflicting interface declaration");
|
||||
@@ -7,14 +9,7 @@
|
||||
}
|
||||
|
||||
// Check this interface for role/vlan uniqueness...
|
||||
let this_vid = interface.vlan ? interface.vlan.id : '';
|
||||
|
||||
if (!this_vid) {
|
||||
if (interface.role == 'upstream')
|
||||
this_vid = 2;
|
||||
else
|
||||
this_vid = 1;
|
||||
}
|
||||
let this_vid = interface.vlan ? interface.vlan.id : 1;
|
||||
|
||||
for (let other_interface in state.interfaces) {
|
||||
if (other_interface == interface)
|
||||
@@ -28,6 +23,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
// check if a downstream interface with a vlan has a matching upstream interface
|
||||
if (interface.vlan && interface.role == "downstream" && index(vlans, this_vid) < 0) {
|
||||
warn("Trying to create a downstream interface with a VLAN ID, without matching upstream interface.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Gather related BSS modes and ethernet ports.
|
||||
let bss_modes = map(interface.ssids, ssid => ssid.bss_mode);
|
||||
let eth_ports = ethernet.lookup_by_interface_spec(interface);
|
||||
@@ -41,27 +42,15 @@
|
||||
return;
|
||||
}
|
||||
|
||||
// Compute unique logical name and netdev name to use
|
||||
let name = ethernet.calculate_names(interface);
|
||||
let bridgedev = 'bridge';
|
||||
let netdev = '';
|
||||
// store the VLAN id assigned to this interface
|
||||
push(vlans, this_vid);
|
||||
|
||||
// If this interface enables host isolation, we need to turn it into a
|
||||
// dedicated isolated netdev...
|
||||
if (interface.isolate_hosts) {
|
||||
// If there are any ethernet ports or multiple SSIDs participating,
|
||||
// we need to spawn a new bridge interface.
|
||||
if (length(eth_ports) > 0 || length(bss_modes) > 1)
|
||||
netdev = 'br-' + name;
|
||||
}
|
||||
// ... upstream interfaces with a vlan require the @upstream syntax
|
||||
else if (interface.role == 'upstream' && interface.vlan) {
|
||||
netdev = "@upstream." + this_vid;
|
||||
}
|
||||
// ... otherwise we program a VLAN on top of the global bridge.
|
||||
else {
|
||||
netdev = bridgedev + '.' + this_vid;
|
||||
}
|
||||
// Compute unique logical name and netdev name to use
|
||||
let name = ethernet.calculate_name(interface);
|
||||
let bridgedev = 'up';
|
||||
if (interface.role == "downstream")
|
||||
bridgedev = 'down';
|
||||
let netdev = bridgedev + '.' + this_vid;
|
||||
|
||||
// Determine the IPv4 and IPv6 configuration modes and figure out if we
|
||||
// can set them both in a single interface (dualstack) or whether we need
|
||||
@@ -72,38 +61,23 @@
|
||||
(ipv4_mode == 'none') || (ipv6_mode == 'none') ||
|
||||
(ipv4_mode == 'static' && ipv6_mode == 'static')
|
||||
);
|
||||
|
||||
// upstream interfaces always have a routing metric of 0
|
||||
if (interface.role == "upstream")
|
||||
interface.metric = 0;
|
||||
%}
|
||||
|
||||
# Network configuration
|
||||
add network interface
|
||||
set networ.@interface[-1].ifname='lo'
|
||||
set networ.@interface[-1].proto='static'
|
||||
set networ.@interface[-1].ipaddr='127.0.0.1'
|
||||
set networ.@interface[-1].netmask='255.0.0.0'
|
||||
|
||||
add network device
|
||||
set network.@device[-1].name=bridge
|
||||
set network.@device[-1].type=bridge
|
||||
|
||||
{% if (interface.isolate_hosts && netdev): %}
|
||||
set network.{{ name }}_dev=device
|
||||
set network.{{ name }}_dev.type=bridge
|
||||
set network.{{ name }}_dev.name={{ netdev }}
|
||||
add network bridge-vlan
|
||||
set network.@bridge-vlan[-1].device={{ bridgedev }}
|
||||
set network.@bridge-vlan[-1].vlan={{ this_vid }}
|
||||
{% for (let i, port in eth_ports): %}
|
||||
{{ i ? 'add_list' : 'set' }} network.{{ name }}_dev.ifname={{ port }}
|
||||
{{ i ? 'add_list' : 'set' }} network.@bridge-vlan[-1].ports={{ port }}{{ ((interface.role == 'upstream') && interface.vlan) ? ':t' : '' }}
|
||||
{% endfor %}
|
||||
{% elif (!interface.isolate_hosts): %}
|
||||
set network.{{ name }}_vlan=bridge-vlan
|
||||
set network.{{ name }}_vlan.device={{ bridgedev }}
|
||||
set network.{{ name }}_vlan.vlan={{ this_vid }}
|
||||
{% for (let i, port in eth_ports): %}
|
||||
{{ i ? 'add_list' : 'set' }} network.{{ name }}_vlan.ports={{ port }}{{ ((interface.role == 'upstream') && interface.vlan) ? ':t' : '' }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if (use_dualstack): %}
|
||||
set network.{{ name }}=interface
|
||||
set network.{{name}}=interface
|
||||
set network.{{ name }}.ucentral_name={{ s(interface.name) }}
|
||||
set network.{{ name }}.ucentral_path={{ s(location) }}
|
||||
set network.{{ name }}.ifname={{ netdev }}
|
||||
set network.{{ name }}.metric={{ interface.metric }}
|
||||
{% if (ipv4_mode == 'static'): %}
|
||||
@@ -121,17 +95,17 @@ set network.{{ name }}.peerdns={{ b(!length(interface.ipv4.use_dns)) }}
|
||||
{% else %}
|
||||
set network.{{ name }}.proto=dhcpv6
|
||||
{% endif %}
|
||||
{% if (interface.role == 'upstream'): %}
|
||||
{% if (interface.role == 'upstream' && interface.vlan): %}
|
||||
set network.{{ name }}.ip4table={{ this_vid }}
|
||||
set network.{{ name }}.ip6table={{ this_vid }}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if (ipv4_mode != 'none'): %}
|
||||
set network.{{ name }}_4=interface
|
||||
set network.{{name}}=interface_4
|
||||
set network.{{ name }}_4.ucentral_name={{ s(interface.name) }}
|
||||
set network.{{ name }}_4.ifname={{ netdev }}
|
||||
set network.{{ name }}_4.metric={{ interface.metric }}
|
||||
{% if (interface.role == 'upstream'): %}
|
||||
{% if (interface.role == 'upstream' && interface.vlan): %}
|
||||
set network.{{ name }}_4.ip4table={{ this_vid }}
|
||||
{% endif %}
|
||||
{% if (ipv4_mode == 'static'): %}
|
||||
@@ -142,11 +116,11 @@ set network.{{ name }}_4.proto=dhcp
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if (ipv6_mode != 'none'): %}
|
||||
set network.{{ name }}_6=interface
|
||||
set network.{{name}}=interface_6
|
||||
set network.{{ name }}_6.ucentral_name={{ s(interface.name) }}
|
||||
set network.{{ name }}_6.ifname={{ netdev }}
|
||||
set network.{{ name }}_6.metric={{ interface.metric }}
|
||||
{% if (interface.role == 'upstream'): %}
|
||||
{% if (interface.role == 'upstream' && interface.vlan): %}
|
||||
set network.{{ name }}_6.ip6table={{ this_vid }}
|
||||
{% endif %}
|
||||
{% if (ipv6_mode == 'static'): %}
|
||||
@@ -161,27 +135,19 @@ set network.{{ name }}_6.proto=dhcp
|
||||
{% if (use_dualstack && interface.role == "downstream" && interface.vlan): %}
|
||||
add network rule
|
||||
set network.@rule[-1].in={{ name }}
|
||||
set network.@rule[-1].lookup={{ this_vid }}
|
||||
set network.@rule[-1].lookup={{ interface.vlan.id }}
|
||||
{% endif %}
|
||||
|
||||
{%
|
||||
include('interface/firewall.uc', {
|
||||
interface,
|
||||
networks: use_dualstack ? [ name ] : [ name + '_4', name + '_6' ]
|
||||
});
|
||||
include('interface/firewall.uc');
|
||||
|
||||
if (interface.ipv4)
|
||||
include('interface/dhcp.uc', {
|
||||
interface,
|
||||
name: use_dualstack ? name : name + '_4'
|
||||
});
|
||||
include('interface/dhcp.uc');
|
||||
|
||||
for (let i, ssid in interface.ssids) {
|
||||
include('ssid.uc', {
|
||||
location: location + '/ssids/' + i,
|
||||
ssid,
|
||||
interface,
|
||||
networks: use_dualstack ? [ name ] : [ name + '_4', name + '_6' ]
|
||||
ssid
|
||||
});
|
||||
}
|
||||
%}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
{% let name = ethernet.calculate_name(interface) %}
|
||||
{% let dhcp = interface.ipv4.dhcp || { ignore: 1 } %}
|
||||
add dhcp dhcp
|
||||
set dhcp.@dhcp[-1].interface={{ s(name) }}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{% for (let n, network in networks): %}
|
||||
{% if (interface.role == upstream): %}
|
||||
{% for (let name in ethernet.calculate_names(interface)): %}
|
||||
{% if (interface.role == "upstream"): %}
|
||||
add firewall zone
|
||||
set firewall.@zone[-1].name={{ s(network) }}
|
||||
set firewall.@zone[-1].network={{ s(network) }}
|
||||
set firewall.@zone[-1].name={{ s(name) }}
|
||||
set firewall.@zone[-1].network={{ s(name) }}
|
||||
set firewall.@zone[-1].input='REJECT'
|
||||
set firewall.@zone[-1].output='ACCEPT'
|
||||
set firewall.@zone[-1].forward='REJECT'
|
||||
@@ -10,14 +10,14 @@ set firewall.@zone[-1].masq=1
|
||||
set firewall.@zone[-1].mtu_fix=1
|
||||
{% else %}
|
||||
add firewall zone
|
||||
set firewall.@zone[-1].name={{ s(network) }}
|
||||
set firewall.@zone[-1].network={{ s(network) }}
|
||||
set firewall.@zone[-1].name={{ s(name) }}
|
||||
set firewall.@zone[-1].network={{ s(name) }}
|
||||
set firewall.@zone[-1].input='ACCEPT'
|
||||
set firewall.@zone[-1].output='ACCEPT'
|
||||
set firewall.@zone[-1].forward='ACCEPT'
|
||||
|
||||
add firewall forwarding
|
||||
set firewall.@forwarding[-1].src={{ network }}
|
||||
set firewall.@forwarding[-1].dest=upstream{{ interface.vlan ? interface.vlan.id : '' }}
|
||||
set firewall.@forwarding[-1].src={{ name }}
|
||||
set firewall.@forwarding[-1].dest='wan{{ interface.vlan ? interface.vlan.id : '' }}'
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
@@ -96,7 +96,7 @@ set wireless.{{ phy.section }}.require_mode={{ s(match_require_mode(radio.requir
|
||||
set wireless.{{ phy.section }}.txpower={{ radio.tx_power }}
|
||||
set wireless.{{ phy.section }}.legacy_rates={{ b(radio.legacy_rates) }}
|
||||
set wireless.{{ phy.section }}.chan_bw={{ radio.bandwidth }}
|
||||
{% if (phy.he_mac_capa && match(htmode, /HE.*/)): %}
|
||||
{% if (radio.he_settings && phy.he_mac_capa && match(htmode, /HE.*/)): %}
|
||||
set wireless.{{ phy.section }}.he_bss_color={{ radio.he_settings.bss_color }}
|
||||
set wireless.{{ phy.section }}.multiple_bssid={{ b(radio.he_settings.multiple_bssid) }}
|
||||
set wireless.{{ phy.section }}.ema={{ b(radio.he_settings.ema) }}
|
||||
|
||||
@@ -44,51 +44,54 @@
|
||||
{% let id = wiphy.allocate_ssid_section_id(phy) %}
|
||||
{% let crypto = validate_encryption(); %}
|
||||
{% if (!crypto) continue; %}
|
||||
set wireless.{{ id }}=wifi-iface
|
||||
set wireless.{{ id }}.device={{ phy.section }}
|
||||
{% for (let i, network in networks): %}
|
||||
{{ i ? 'add_list' : 'set' }} wireless.{{ id }}.network={{ network }}
|
||||
add wireless wifi-iface
|
||||
set wireless.@wifi-iface[-1].ucentral_path={{ s(location) }}
|
||||
set wireless.@wifi-iface[-1].device={{ phy.section }}
|
||||
{% for (let i, name in ethernet.calculate_names(interface)): %}
|
||||
{{ i ? 'add_list' : 'set' }} wireless.@wifi-iface[-1].network={{ name }}
|
||||
{% endfor %}
|
||||
set wireless.{{ id }}.ssid={{ s(ssid.name) }}
|
||||
set wireless.{{ id }}.mode={{ ssid.bss_mode }}
|
||||
set wireless.{{ id }}.bssid={{ ssid.bssid }}
|
||||
set wireless.{{ id }}.hidden={{ b(ssid.hidden_ssid) }}
|
||||
set wireless.{{ id }}.time_advertisement={{ ssid.broadcast_time }}
|
||||
set wireless.{{ id }}.isolate={{ b(ssid.isolate_clients) }}
|
||||
set wireless.{{ id }}.uapsd={{ b(ssid.power_save) }}
|
||||
set wireless.{{ id }}.rts_threshold={{ ssid.rts_threshold }}
|
||||
set wireless.{{ id }}.multicast_to_unicast={{ b(ssid.unicast_conversion) }}
|
||||
set wireless.{{ id }}.beacon_rate={{ ssid.rates.beacon }}
|
||||
set wireless.{{ id }}.mcast_rate={{ ssid.rates.multicast }}
|
||||
set wireless.@wifi-iface[-1].ssid={{ s(ssid.name) }}
|
||||
set wireless.@wifi-iface[-1].mode={{ ssid.bss_mode }}
|
||||
set wireless.@wifi-iface[-1].bssid={{ ssid.bssid }}
|
||||
set wireless.@wifi-iface[-1].hidden={{ b(ssid.hidden_ssid) }}
|
||||
set wireless.@wifi-iface[-1].time_advertisement={{ ssid.broadcast_time }}
|
||||
set wireless.@wifi-iface[-1].isolate={{ b(ssid.isolate_clients) }}
|
||||
set wireless.@wifi-iface[-1].uapsd={{ b(ssid.power_save) }}
|
||||
set wireless.@wifi-iface[-1].rts_threshold={{ ssid.rts_threshold }}
|
||||
set wireless.@wifi-iface[-1].multicast_to_unicast={{ b(ssid.unicast_conversion) }}
|
||||
{% if (ssid.rates): %}
|
||||
set wireless.@wifi-iface[-1].beacon_rate={{ ssid.rates.beacon }}
|
||||
set wireless.@wifi-iface[-1].mcast_rate={{ ssid.rates.multicast }}
|
||||
{% endif %}
|
||||
{% if (ssid.rrm): %}
|
||||
set wireless.{{ id }}.ieee80211k={{ b(ssid.rrm.neighbor_reporting) }}
|
||||
set wireless.{{ id }}.ftm_responder={{ b(ssid.rrm.ftm_responder) }}
|
||||
set wireless.{{ id }}.stationary_ap={{ b(ssid.rrm.stationary_ap) }}
|
||||
set wireless.{{ id }}.lci={{ b(ssid.rrm.lci) }}
|
||||
set wireless.{{ id }}.civic={{ ssid.rrm.civic }}
|
||||
set wireless.@wifi-iface[-1].ieee80211k={{ b(ssid.rrm.neighbor_reporting) }}
|
||||
set wireless.@wifi-iface[-1].ftm_responder={{ b(ssid.rrm.ftm_responder) }}
|
||||
set wireless.@wifi-iface[-1].stationary_ap={{ b(ssid.rrm.stationary_ap) }}
|
||||
set wireless.@wifi-iface[-1].lci={{ b(ssid.rrm.lci) }}
|
||||
set wireless.@wifi-iface[-1].civic={{ ssid.rrm.civic }}
|
||||
{% endif %}
|
||||
{% if (ssid.roaming): %}
|
||||
set wireless.{{ id }}.ieee80211r=1
|
||||
set wireless.{{ id }}.ft_over_ds={{ b(ssid.roaming.message_exchange == "ds") }}
|
||||
set wireless.{{ id }}.ft_psk_generate_local={{ b(ssid.roaming.generate_psk) }}
|
||||
set wireless.{{ id }}.mobility_domain={{ ssid.roaming.domain_identifier }}
|
||||
set wireless.@wifi-iface[-1].ieee80211r=1
|
||||
set wireless.@wifi-iface[-1].ft_over_ds={{ b(ssid.roaming.message_exchange == "ds") }}
|
||||
set wireless.@wifi-iface[-1].ft_psk_generate_local={{ b(ssid.roaming.generate_psk) }}
|
||||
set wireless.@wifi-iface[-1].mobility_domain={{ ssid.roaming.domain_identifier }}
|
||||
{% endif %}
|
||||
set wireless.{{ id }}.ieee80211w={{ match_ieee80211w() }}
|
||||
set wireless.{{ id }}.encryption={{ crypto.proto }}
|
||||
set wireless.{{ id }}.key={{ crypto.key }}
|
||||
set wireless.@wifi-iface[-1].ieee80211w={{ match_ieee80211w() }}
|
||||
set wireless.@wifi-iface[-1].encryption={{ crypto.proto }}
|
||||
set wireless.@wifi-iface[-1].key={{ crypto.key }}
|
||||
{% if (crypto.auth): %}
|
||||
set wireless.{{ id }}.auth_server={{ crypto.auth.host }}
|
||||
set wireless.{{ id }}.auth_port={{ crypto.auth.port }}
|
||||
set wireless.{{ id }}.auth_secret={{ crypto.auth.secret }}
|
||||
set wireless.@wifi-iface[-1].auth_server={{ crypto.auth.host }}
|
||||
set wireless.@wifi-iface[-1].auth_port={{ crypto.auth.port }}
|
||||
set wireless.@wifi-iface[-1].auth_secret={{ crypto.auth.secret }}
|
||||
{% endif %}
|
||||
{% if (crypto.acct): %}
|
||||
set wireless.{{ id }}.acct_server={{ crypto.acct.host }}
|
||||
set wireless.{{ id }}.acct_port={{ crypto.acct.port }}
|
||||
set wireless.{{ id }}.acct_secret={{ crypto.acct.secret }}
|
||||
set wireless.{{ id }}.acct_interval={{ crypto.acct.interval }}
|
||||
set wireless.@wifi-iface[-1].acct_server={{ crypto.acct.host }}
|
||||
set wireless.@wifi-iface[-1].acct_port={{ crypto.acct.port }}
|
||||
set wireless.@wifi-iface[-1].acct_secret={{ crypto.acct.secret }}
|
||||
set wireless.@wifi-iface[-1].acct_interval={{ crypto.acct.interval }}
|
||||
{% endif %}
|
||||
|
||||
{% if (ssid.rate_limit.ingress_rate || ssid.rate_limit.egress_rate): %}
|
||||
{% if (ssid.rate_limit && (ssid.rate_limit.ingress_rate || ssid.rate_limit.egress_rate)): %}
|
||||
add ratelimit rate
|
||||
set ratelimit.@rate[-1].ssid={{ s(ssid.name) }}
|
||||
set ratelimit.@rate[-1].ingress={{ ssid.rate_limit.ingress_rate }}
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
{%
|
||||
include('unit.uc', { location: '/unit', unit: state.unit });
|
||||
// reject the config if there is no valid upstream configuration
|
||||
let upstream;
|
||||
for (let i, interface in state.interfaces) {
|
||||
if (interface.role != 'upstream')
|
||||
continue;
|
||||
upstream = interface;
|
||||
}
|
||||
|
||||
if (!upstream) {
|
||||
location = '/';
|
||||
warn('Configuration must contain at least one valid upstream interface. Rejecting whole file');
|
||||
die('Configuration must contain at least one valid upstream interface. Rejecting whole file');
|
||||
}
|
||||
|
||||
include('base.uc');
|
||||
|
||||
if (state.unit)
|
||||
include('unit.uc', { location: '/unit', unit: state.unit });
|
||||
|
||||
for (let service in state.services)
|
||||
include('services/' + service + '.uc', {
|
||||
@@ -16,8 +33,17 @@
|
||||
for (let i, radio in state.radios)
|
||||
include('radio.uc', { location: '/radios/' + i, radio });
|
||||
|
||||
for (let i, interface in state.interfaces)
|
||||
include('interface.uc', { location: '/interfaces/' + i, interface });
|
||||
let vlans = [];
|
||||
function iterate_interfaces(role) {
|
||||
for (let i, interface in state.interfaces) {
|
||||
if (interface.role != role)
|
||||
continue;
|
||||
include('interface.uc', { location: '/interfaces/' + i, interface, vlans });
|
||||
}
|
||||
}
|
||||
|
||||
iterate_interfaces("upstream");
|
||||
iterate_interfaces("downstream");
|
||||
|
||||
if (state.config_raw)
|
||||
include("config_raw.uc", { location: '/config_raw', config_raw: state.config_raw });
|
||||
|
||||
@@ -8,13 +8,15 @@ let schemareader = require("schemareader");
|
||||
let renderer = require("renderer");
|
||||
let fs = require("fs");
|
||||
|
||||
let inputfile = fs.open("/tmp/test.json", "r");
|
||||
let inputfile = fs.open(ARGV[2], "r");
|
||||
let inputjson = json(inputfile.read("all"));
|
||||
|
||||
let error = 0;
|
||||
|
||||
inputfile.close();
|
||||
let logs = [];
|
||||
|
||||
try {
|
||||
let logs = [];
|
||||
let batch = renderer.render(schemareader.validate(inputjson), logs);
|
||||
|
||||
fs.stdout.write("Log messages:\n" + join("\n", logs) + "\n\n");
|
||||
@@ -35,10 +37,28 @@ try {
|
||||
|
||||
for (let cmd in [ 'uci -c /tmp/config-shadow commit',
|
||||
'cp /tmp/config-shadow/* /etc/config/',
|
||||
'reload_config', 'rm -rf /tmp/config-shadow' ])
|
||||
'rm -rf /tmp/config-shadow',
|
||||
'reload_config'])
|
||||
system(cmd);
|
||||
|
||||
fs.unlink('/etc/ucentral/ucentral.active');
|
||||
fs.symlink(ARGV[2], '/etc/ucentral/ucentral.active');
|
||||
|
||||
}
|
||||
catch (e) {
|
||||
error = 1;
|
||||
warn("Fatal error while generating UCI: ", e, "\n", e.stacktrace[0].context, "\n");
|
||||
}
|
||||
|
||||
let ubus = require("ubus").connect();
|
||||
|
||||
ubus.call("ucentral", "result", {
|
||||
uuid: inputjson.uuid || 0,
|
||||
id: +ARGV[3] || 0,
|
||||
status: {
|
||||
error,
|
||||
text: error ? "Failed" : "Success",
|
||||
rejected: logs || []
|
||||
}
|
||||
});
|
||||
%}
|
||||
|
||||
@@ -29,6 +29,8 @@ properties:
|
||||
- ap
|
||||
- sta
|
||||
- mesh
|
||||
- wds
|
||||
default: ap
|
||||
bssid:
|
||||
description:
|
||||
Override the BSSID of the network, only applicable in adhoc or sta mode.
|
||||
|
||||
@@ -17,3 +17,4 @@ properties:
|
||||
enum:
|
||||
- 802.1ad
|
||||
- 802.1q
|
||||
default: 802.1q
|
||||
|
||||
@@ -12,6 +12,7 @@ properties:
|
||||
description:
|
||||
The reporting interval defined in seconds.
|
||||
type: integer
|
||||
minimum: 60
|
||||
types:
|
||||
description:
|
||||
A list of names of subsystems that shall be reported periodically.
|
||||
@@ -32,6 +33,7 @@ properties:
|
||||
description:
|
||||
The reporting interval defined in seconds.
|
||||
type: integer
|
||||
minimum: 60
|
||||
dhcp-snooping:
|
||||
description:
|
||||
DHCP snooping allows us to intercept DHCP packages on interface that are
|
||||
|
||||
@@ -3,6 +3,10 @@ $schema: http://json-schema.org/draft-07/schema#
|
||||
description: OpenWrt uCentral schema
|
||||
type: object
|
||||
properties:
|
||||
uuid:
|
||||
description:
|
||||
The uniquie ID of the configuration. This is the unix timestamp of when the config was created.
|
||||
type: integer
|
||||
unit:
|
||||
$ref: "https://ucentral.io/schema/v1/unit/"
|
||||
globals:
|
||||
|
||||
@@ -224,6 +224,9 @@ function instantiateInterfaceVlan(value) {
|
||||
assert(value["proto"] in [ "802.1ad", "802.1q" ], "Property interface.vlan.proto must be one of [ \"802.1ad\", \"802.1q\" ]");
|
||||
obj.proto = value["proto"];
|
||||
}
|
||||
else {
|
||||
obj.proto = "802.1q";
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
@@ -954,9 +957,12 @@ function instantiateInterfaceSsid(value) {
|
||||
|
||||
if (exists(value, "bss-mode")) {
|
||||
assert(type(value["bss-mode"]) == "string", "Property interface.ssid.bss-mode must be of type string");
|
||||
assert(value["bss-mode"] in [ "ap", "sta", "mesh" ], "Property interface.ssid.bss-mode must be one of [ \"ap\", \"sta\", \"mesh\" ]");
|
||||
assert(value["bss-mode"] in [ "ap", "sta", "mesh", "wds" ], "Property interface.ssid.bss-mode must be one of [ \"ap\", \"sta\", \"mesh\", \"wds\" ]");
|
||||
obj.bss_mode = value["bss-mode"];
|
||||
}
|
||||
else {
|
||||
obj.bss_mode = "ap";
|
||||
}
|
||||
|
||||
if (exists(value, "bssid")) {
|
||||
assert(type(value["bssid"]) == "string", "Property interface.ssid.bssid must be of type string");
|
||||
@@ -1376,6 +1382,7 @@ function instantiateMetrics(value) {
|
||||
|
||||
if (exists(value, "interval")) {
|
||||
assert(type(value["interval"]) == "int", "Property metrics.statistics.interval must be of type integer");
|
||||
assert(value["interval"] >= 60, "Property metrics.statistics.interval must be >= 60");
|
||||
obj.interval = value["interval"];
|
||||
}
|
||||
|
||||
@@ -1407,6 +1414,7 @@ function instantiateMetrics(value) {
|
||||
|
||||
if (exists(value, "interval")) {
|
||||
assert(type(value["interval"]) == "int", "Property metrics.health.interval must be of type integer");
|
||||
assert(value["interval"] >= 60, "Property metrics.health.interval must be >= 60");
|
||||
obj.interval = value["interval"];
|
||||
}
|
||||
|
||||
@@ -1468,6 +1476,11 @@ function newUCentralState(value) {
|
||||
|
||||
let obj = {};
|
||||
|
||||
if (exists(value, "uuid")) {
|
||||
assert(type(value["uuid"]) == "int", "Property UCentralState.uuid must be of type integer");
|
||||
obj.uuid = value["uuid"];
|
||||
}
|
||||
|
||||
if (exists(value, "unit")) {
|
||||
obj.unit = instantiateUnit(value["unit"]);
|
||||
}
|
||||
|
||||
41
system/capabilities.uc
Normal file → Executable file
41
system/capabilities.uc
Normal file → Executable file
@@ -1,15 +1,30 @@
|
||||
#!/usr/bin/ucode
|
||||
{%
|
||||
capa = {};
|
||||
ctx = ubus.connect();
|
||||
capa.compatible = replace(board.model.id, ',', '_');
|
||||
capa.model = board.model.name;
|
||||
capa.network = board.network;
|
||||
if (board["bridge"])
|
||||
capa["bridge-vlan"] = true;
|
||||
if (board["switch"])
|
||||
capa["switch"] = board["switch"];
|
||||
wifi = ctx.call("wifi", "phy");
|
||||
if (length(wifi))
|
||||
capa.wifi = wifi;
|
||||
print(capa);
|
||||
push(REQUIRE_SEARCH_PATH,
|
||||
"/usr/lib/ucode/*.so",
|
||||
"/usr/share/ucentral/*.uc");
|
||||
|
||||
let ubus = require("ubus");
|
||||
let fs = require("fs");
|
||||
|
||||
let boardfile = fs.open("/etc/board.json", "r");
|
||||
let board = json(boardfile.read("all"));
|
||||
boardfile.close();
|
||||
|
||||
capa = {};
|
||||
ctx = ubus.connect();
|
||||
capa.compatible = replace(board.model.id, ',', '_');
|
||||
capa.model = board.model.name;
|
||||
capa.network = board.network;
|
||||
if (board["bridge"])
|
||||
capa["bridge-vlan"] = true;
|
||||
if (board["switch"])
|
||||
capa["switch"] = board["switch"];
|
||||
wifi = ctx.call("wifi", "phy");
|
||||
if (length(wifi))
|
||||
capa.wifi = wifi;
|
||||
|
||||
capafile = fs.open("/etc/ucentral/capabilities.json", "w");
|
||||
capafile.write(capa);
|
||||
capafile.close();
|
||||
%}
|
||||
|
||||
13
system/crashlog.uc
Executable file
13
system/crashlog.uc
Executable file
@@ -0,0 +1,13 @@
|
||||
{%
|
||||
if (!fs.stat("/sys/fs/pstore/dmesg-ramoops-0"))
|
||||
return 0;
|
||||
let fd = fs.open("/sys/fs/pstore/dmesg-ramoops-0", "r");
|
||||
let line, lines = [];
|
||||
while (line = fd.read("line"))
|
||||
push(lines, trim(line));
|
||||
fd.close();
|
||||
let fd = fs.open("/tmp/crashlog", "w");
|
||||
fd.write({crashlog: lines});
|
||||
fd.close();
|
||||
print(lines);
|
||||
%}
|
||||
7
system/health.uc
Normal file → Executable file
7
system/health.uc
Normal file → Executable file
@@ -1,4 +1,9 @@
|
||||
#!/usr/bin/ucode
|
||||
{%
|
||||
let fs = require("fs");
|
||||
let uci = require("uci");
|
||||
let ubus = require("ubus");
|
||||
|
||||
state = {
|
||||
unit: {},
|
||||
interfaces: {}
|
||||
@@ -103,7 +108,7 @@ catch(e) {
|
||||
|
||||
let errors = length(state.interfaces);
|
||||
if (!errors)
|
||||
delete(state.interfaces);
|
||||
delete(state, "interfaces");
|
||||
|
||||
let sanity = 100 - (errors * 100 / count);
|
||||
|
||||
|
||||
0
system/probe_services.uc
Normal file → Executable file
0
system/probe_services.uc
Normal file → Executable file
7
system/state.uc
Normal file → Executable file
7
system/state.uc
Normal file → Executable file
@@ -1,4 +1,11 @@
|
||||
#!/usr/bin/ucode
|
||||
{%
|
||||
let fs = require("fs");
|
||||
let uci = require("uci");
|
||||
let ubus = require("ubus");
|
||||
let cfgfile = fs.open("/etc/ucentral/ucentral.active", "r");
|
||||
let cfg = json(cfgfile.read("all"));
|
||||
|
||||
/* set up basic functionality */
|
||||
if (!cursor)
|
||||
cursor = uci.cursor();
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"uuid": {
|
||||
"type": "integer"
|
||||
},
|
||||
"unit": {
|
||||
"$ref": "#/$defs/unit"
|
||||
},
|
||||
@@ -231,7 +234,8 @@
|
||||
"enum": [
|
||||
"802.1ad",
|
||||
"802.1q"
|
||||
]
|
||||
],
|
||||
"default": "802.1q"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -858,8 +862,10 @@
|
||||
"enum": [
|
||||
"ap",
|
||||
"sta",
|
||||
"mesh"
|
||||
]
|
||||
"mesh",
|
||||
"wds"
|
||||
],
|
||||
"default": "ap"
|
||||
},
|
||||
"bssid": {
|
||||
"type": "string",
|
||||
@@ -1174,7 +1180,8 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"interval": {
|
||||
"type": "integer"
|
||||
"type": "integer",
|
||||
"minimum": 60
|
||||
},
|
||||
"types": {
|
||||
"type": "array",
|
||||
@@ -1193,7 +1200,8 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"interval": {
|
||||
"type": "integer"
|
||||
"type": "integer",
|
||||
"minimum": 60
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user