This commit is contained in:
Robert Chacon committed 2026-03-30 08:03:13 -06:00
1 parent a18758a7c4
commit 6d9d45d2e3
17 files changed
+558 -335

No files matched your search

+1 -1
View File
@@ -25,7 +25,7 @@ Para la mayoría de operadores:
La mayoría de cambios operativos diarios se realizan en la WebUI (`http://tu_ip_del_shaper:9123/config_general.html`).
Las versiones actuales usan paneles compartidos de configuración en las páginas General, RTT, Queues, TreeGuard, Network Mode, IP Ranges, Flow Tracking y Shaped Devices para que los ajustes del nodo y la afinación operativa sigan la misma presentación visual que el resto de Node Manager. La página de TreeGuard ahora comienza con un resumen del comportamiento actual en lugar de un banner permanente de advertencia.
Las versiones actuales usan paneles compartidos de configuración en las páginas General, RTT, Queues, TreeGuard, Network Mode, valores por defecto de integración, Network Layout, Insight, páginas de integración por proveedor, IP Ranges, Flow Tracking y Shaped Devices para que los ajustes del nodo y la afinación operativa sigan la misma presentación visual que el resto de Node Manager. La página de TreeGuard comienza con un resumen del comportamiento actual en lugar de un banner permanente de advertencia.
### Dónde en la WebUI
+1 -1
View File
@@ -27,7 +27,7 @@ For most operators:
Most day-to-day LibreQoS configuration is handled in WebUI (`http://your_shaper_ip:9123/config_general.html`).
Current builds use shared configuration panels on the General, RTT, Queues, TreeGuard, Network Mode, IP Ranges, Flow Tracking, and Shaped Devices pages so node settings and operational tuning follow the same surface styling as the rest of Node Manager. The TreeGuard page now starts with a live behavior summary rather than a permanent warning banner.
Current builds use shared configuration panels on the General, RTT, Queues, TreeGuard, Network Mode, Integration Defaults, Network Layout, Insight, provider-specific integration pages, IP Ranges, Flow Tracking, and Shaped Devices pages so node settings and operational tuning follow the same surface styling as the rest of Node Manager. The TreeGuard page starts with a live behavior summary rather than a permanent warning banner.
### Where in WebUI
@@ -34,25 +34,25 @@ function applyEditorLockState() {
}
function renderNetworkNode(level, depth) {
let html = `<div class="card mb-3" style="margin-left: ${depth * 30}px;">`;
let html = `<div class="card lqos-network-node-card mb-3" style="margin-left: ${depth * 30}px;">`;
html += `<div class="card-body">`;
for (const [key, value] of Object.entries(level)) {
const isVirtual = value && value.virtual === true;
const actionAttrs = editorButtonAttrs();
// Node header with actions
html += `<div class="d-flex justify-content-between align-items-center mb-2">`;
html += `<h5 class="card-title mb-0">${key}${isVirtual ? ' <span class="badge bg-secondary ms-2"><i class="fa fa-ghost"></i> Virtual</span>' : ''}</h5>`;
html += `<div>`;
html += `<div class="d-flex flex-wrap justify-content-between align-items-center gap-2 mb-2">`;
html += `<h5 class="card-title mb-0">${key}${isVirtual ? ' <span class="badge bg-info-subtle text-info border border-info-subtle ms-2"><i class="fa fa-ghost"></i> Virtual</span>' : ''}</h5>`;
html += `<div class="d-flex flex-wrap gap-2">`;
if (depth > 0) {
html += `<button class="btn btn-sm btn-outline-secondary me-1" onclick="promoteNode('${key}')" title="Promote ${key}" aria-label="Promote ${key}"${actionAttrs}>
html += `<button class="btn btn-sm btn-outline-primary" onclick="promoteNode('${key}')" title="Promote ${key}" aria-label="Promote ${key}"${actionAttrs}>
<i class="fas fa-arrow-up"></i> Promote
</button>`;
}
html += `<button class="btn btn-sm btn-outline-secondary me-1" onclick="toggleVirtualNode('${key}')" title="Toggle virtual mode for ${key}" aria-label="Toggle virtual mode for ${key}"${actionAttrs}>
html += `<button class="btn btn-sm btn-outline-primary" onclick="toggleVirtualNode('${key}')" title="Toggle virtual mode for ${key}" aria-label="Toggle virtual mode for ${key}"${actionAttrs}>
<i class="fas ${isVirtual ? 'fa-toggle-on' : 'fa-toggle-off'}"></i> Virtual
</button>`;
html += `<button class="btn btn-sm btn-outline-secondary me-1" onclick="renameNode('${key}')" title="Rename ${key}" aria-label="Rename ${key}"${actionAttrs}>
html += `<button class="btn btn-sm btn-outline-primary" onclick="renameNode('${key}')" title="Rename ${key}" aria-label="Rename ${key}"${actionAttrs}>
<i class="fas fa-pencil-alt"></i> Rename
</button>`;
html += `<button class="btn btn-sm btn-outline-danger" onclick="deleteNode('${key}')" title="Delete ${key}" aria-label="Delete ${key}"${actionAttrs}>
@@ -61,13 +61,13 @@ function renderNetworkNode(level, depth) {
html += `</div></div>`;
// Node details
html += `<div class="mb-3">`;
html += `<span class="badge bg-primary me-2">Download: ${value.downloadBandwidthMbps} Mbps</span>`;
html += `<button class="btn btn-sm btn-outline-secondary me-2" onclick="nodeSpeedChange('${key}', 'd')" title="Edit download speed for ${key}" aria-label="Edit download speed for ${key}"${actionAttrs}>
html += `<div class="mb-3 d-flex flex-wrap align-items-center gap-2">`;
html += `<span class="badge bg-primary-subtle text-primary border border-primary-subtle">Download: ${value.downloadBandwidthMbps} Mbps</span>`;
html += `<button class="btn btn-sm btn-outline-primary" onclick="nodeSpeedChange('${key}', 'd')" title="Edit download speed for ${key}" aria-label="Edit download speed for ${key}"${actionAttrs}>
<i class="fas fa-pencil-alt" aria-hidden="true"></i>
</button>`;
html += `<span class="badge bg-success me-2">Upload: ${value.uploadBandwidthMbps} Mbps</span>`;
html += `<button class="btn btn-sm btn-outline-secondary" onclick="nodeSpeedChange('${key}', 'u')" title="Edit upload speed for ${key}" aria-label="Edit upload speed for ${key}"${actionAttrs}>
html += `<span class="badge bg-success-subtle text-success border border-success-subtle">Upload: ${value.uploadBandwidthMbps} Mbps</span>`;
html += `<button class="btn btn-sm btn-outline-primary" onclick="nodeSpeedChange('${key}', 'u')" title="Edit upload speed for ${key}" aria-label="Edit upload speed for ${key}"${actionAttrs}>
<i class="fas fa-pencil-alt" aria-hidden="true"></i>
</button>`;
html += `</div>`;
@@ -84,7 +84,7 @@ function renderNetworkNode(level, depth) {
function renderNetwork() {
if (!network_json || Object.keys(network_json).length === 0) {
$("#netjson").html(`<div class="alert alert-info">No network nodes found. Add one to get started!</div>`);
$("#netjson").html(`<div class="lqos-config-note">No network nodes found. Add one to get started.</div>`);
return;
}
$("#netjson").html(renderNetworkNode(network_json, 0));
@@ -84,7 +84,6 @@ const defaultLayout = {
{ tag: "treeguardControlLoop", size: 4 },
{ tag: "treeguardStateMix", size: 4 },
{ tag: "treeguardDecisionImpact", size: 4 },
{ tag: "treeguardControls", size: 12 },
{ tag: "treeguardActivity", size: 12 }
]
},
@@ -1,45 +1,71 @@
<div id="configMenuContainer"></div>
<div class="row">
<div class="col-12">
<form>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="circuitNameAsAddress">
<label class="form-check-label" for="circuitNameAsAddress">Use Circuit Name as Address</label>
<div class="form-text">Replace IP addresses with circuit names in network.json</div>
<div class="lqos-config-page">
<div id="configMenuContainer"></div>
<form class="lqos-config-grid">
<section class="lqos-config-panel">
<div class="lqos-config-panel-header">
<div>
<h5 class="lqos-config-panel-title">Integration Defaults</h5>
<div class="lqos-config-panel-subtitle">Set import behavior shared across integrations, including naming, overwrite policy, queue-refresh timing, and bandwidth adjustments.</div>
</div>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="alwaysOverwriteNetworkJson">
<label class="form-check-label" for="alwaysOverwriteNetworkJson">Always Overwrite network.json</label>
<div class="form-text">Force overwrite of network.json on every update</div>
</div>
<div class="row g-3">
<div class="col-12 col-xl-6">
<div class="lqos-config-section h-100">
<h6 class="lqos-config-section-title">Import Behavior</h6>
<div class="lqos-config-section-subtitle">Control how imported topology and subscriber metadata are written into LibreQoS state files.</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="useMikrotikIpv6">
<label class="form-check-label" for="useMikrotikIpv6">Enrich IPv6 via Mikrotik</label>
<div class="form-text">Use `mikrotikDHCPRouterList.csv` to map IPv4 subscribers to Mikrotik-advertised IPv6 prefixes</div>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="circuitNameAsAddress">
<label class="form-check-label" for="circuitNameAsAddress">Use Circuit Name as Address</label>
<div class="form-text">Replace IP addresses with circuit names in <code>network.json</code>.</div>
</div>
<div class="mb-3">
<label for="queueRefreshInterval" class="form-label">Queue Refresh Interval (minutes)</label>
<input type="number" class="form-control" id="queueRefreshInterval" min="1">
<div class="form-text">How frequently to refresh queue data from the integration</div>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="alwaysOverwriteNetworkJson">
<label class="form-check-label" for="alwaysOverwriteNetworkJson">Always Overwrite network.json</label>
<div class="form-text">Force overwrite of <code>network.json</code> on every update.</div>
</div>
<div class="mb-3">
<label for="promoteToRoot" class="form-label">Promote to Root Nodes</label>
<textarea class="form-control" id="promoteToRoot" rows="3"></textarea>
<div class="form-text">Enter one circuit ID per line to promote to root nodes</div>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="useMikrotikIpv6">
<label class="form-check-label" for="useMikrotikIpv6">Enrich IPv6 via Mikrotik</label>
<div class="form-text">Use <code>mikrotikDHCPRouterList.csv</code> to map IPv4 subscribers to Mikrotik-advertised IPv6 prefixes.</div>
</div>
<div class="mb-3">
<label for="clientBandwidthMultiplier" class="form-label">Client Bandwidth Multiplier</label>
<input type="number" class="form-control" id="clientBandwidthMultiplier" step="0.1" min="0.1" value="1.0">
<div class="form-text">Multiplier applied to client bandwidth values (1.0 = 100%)</div>
</div>
<div class="mb-0">
<label for="queueRefreshInterval" class="form-label">Queue Refresh Interval (minutes)</label>
<input type="number" class="form-control" id="queueRefreshInterval" min="1">
<div class="form-text">How frequently to refresh queue data from the integration.</div>
</div>
</div>
</div>
<div class="col-12 col-xl-6">
<div class="lqos-config-section h-100">
<h6 class="lqos-config-section-title">Promotion and Scaling</h6>
<div class="lqos-config-section-subtitle">Promote selected circuits to the root and adjust imported subscriber bandwidth values before shaping.</div>
<div class="mb-3">
<label for="promoteToRoot" class="form-label">Promote to Root Nodes</label>
<textarea class="form-control" id="promoteToRoot" rows="5"></textarea>
<div class="form-text">Enter one circuit ID per line to promote to root nodes.</div>
</div>
<div class="mb-0">
<label for="clientBandwidthMultiplier" class="form-label">Client Bandwidth Multiplier</label>
<input type="number" class="form-control" id="clientBandwidthMultiplier" step="0.1" min="0.1" value="1.0">
<div class="form-text">Multiplier applied to client bandwidth values. <code>1.0</code> means no adjustment.</div>
</div>
</div>
</div>
</div>
</section>
<div class="lqos-config-actions">
<button type="button" id="saveButton" class="btn btn-outline-primary">Save Changes</button>
</form>
</div>
</div>
</form>
</div>
<script src="config_integration.js%CACHEBUSTERS%"></script>
@@ -1,40 +1,66 @@
<div id="configMenuContainer"></div>
<div class="row">
<div class="col-12">
<form>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="gatherStats">
<label class="form-check-label" for="gatherStats">Gather Insight Statistics</label>
<div class="form-text">Enable collection of Insight performance data</div>
<div class="lqos-config-page">
<div id="configMenuContainer"></div>
<form class="lqos-config-grid">
<section class="lqos-config-panel">
<div class="lqos-config-panel-header">
<div>
<h5 class="lqos-config-panel-title">Insight</h5>
<div class="lqos-config-panel-subtitle">Control Insight statistics collection, licensing, and optional self-hosted endpoint settings.</div>
</div>
</div>
<div class="mb-3">
<label for="collationPeriod" class="form-label">Collation Period (seconds)</label>
<input type="number" class="form-control" id="collationPeriod" min="1">
<div class="form-text">How frequently to aggregate statistics into Insight records</div>
</div>
<div class="row g-3">
<div class="col-12 col-xl-6">
<div class="lqos-config-section h-100">
<h6 class="lqos-config-section-title">Collection and License</h6>
<div class="lqos-config-section-subtitle">Enable Insight data gathering and define the cadence used for aggregation and reporting.</div>
<div class="mb-3">
<label for="licenseKey" class="form-label">License Key</label>
<input type="text" class="form-control" id="licenseKey">
<div class="form-text">License key for LibreQoS Insight (if applicable)</div>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="gatherStats">
<label class="form-check-label" for="gatherStats">Gather Insight Statistics</label>
<div class="form-text">Enable collection of Insight performance data.</div>
</div>
<div class="mb-3">
<label for="uispInterval" class="form-label">UISP Reporting Interval (seconds)</label>
<input type="number" class="form-control" id="uispInterval" min="1">
<div class="form-text">How frequently to query UISP for updates (set 0 to disable)</div>
</div>
<div class="mb-3">
<label for="collationPeriod" class="form-label">Collation Period (seconds)</label>
<input type="number" class="form-control" id="collationPeriod" min="1">
<div class="form-text">How frequently to aggregate statistics into Insight records.</div>
</div>
<div class="mb-3">
<label for="ltsUrl" class="form-label">Custom Insight Server URL</label>
<input type="text" class="form-control" id="ltsUrl">
<div class="form-text">URL for a self-hosted Insight server (leave blank for default)</div>
</div>
<div class="mb-0">
<label for="licenseKey" class="form-label">License Key</label>
<input type="text" class="form-control" id="licenseKey">
<div class="form-text">License key for LibreQoS Insight, when applicable.</div>
</div>
</div>
</div>
<div class="col-12 col-xl-6">
<div class="lqos-config-section h-100">
<h6 class="lqos-config-section-title">Endpoints and Reporting</h6>
<div class="lqos-config-section-subtitle">Set reporting cadence for UISP synchronization and optionally point LibreQoS at a self-hosted Insight service.</div>
<div class="mb-3">
<label for="uispInterval" class="form-label">UISP Reporting Interval (seconds)</label>
<input type="number" class="form-control" id="uispInterval" min="1">
<div class="form-text">How frequently to query UISP for updates. Set <code>0</code> to disable.</div>
</div>
<div class="mb-0">
<label for="ltsUrl" class="form-label">Custom Insight Server URL</label>
<input type="text" class="form-control" id="ltsUrl">
<div class="form-text">URL for a self-hosted Insight server. Leave blank to use the default service.</div>
</div>
</div>
</div>
</div>
</section>
<div class="lqos-config-actions">
<button type="button" id="saveButton" class="btn btn-outline-primary">Save Changes</button>
</form>
</div>
</div>
</form>
</div>
<script src="config_lts.js%CACHEBUSTERS%"></script>
@@ -1,16 +1,28 @@
<div id="configMenuContainer"></div>
<div class="row">
<div class="col-12">
<div id="networkEditorLock" class="alert alert-secondary d-none" role="alert"></div>
</div>
</div>
<div class="row">
<div class="col-12">
<button id="btnSaveNetwork" class="btn btn-outline-primary mb-3">
<i class="fa fa-save"></i> Save Changes
</button>
<div id="netjson"></div>
</div>
<div class="lqos-config-page">
<div id="configMenuContainer"></div>
<section class="lqos-config-panel">
<div class="lqos-config-panel-header">
<div>
<h5 class="lqos-config-panel-title">Network Layout</h5>
<div class="lqos-config-panel-subtitle">Review the shaping hierarchy, rename or promote nodes, and adjust per-node rates before saving <code>network.json</code>.</div>
</div>
</div>
<div id="networkEditorLock" class="lqos-config-note lqos-config-note-warning d-none mb-3" role="alert"></div>
<div class="lqos-config-actions mb-3">
<button id="btnSaveNetwork" class="btn btn-outline-primary">
<i class="fa fa-save"></i> Save Changes
</button>
</div>
<div class="lqos-config-section">
<h6 class="lqos-config-section-title">Topology Editor</h6>
<div class="lqos-config-section-subtitle">Node cards show hierarchy, configured rates, virtualization state, and the actions available for each branch.</div>
<div id="netjson" class="lqos-config-network-editor"></div>
</div>
</section>
</div>
<script src="config_network.js%CACHEBUSTERS%"></script>
@@ -1,7 +1,16 @@
<div id="configMenuContainer"></div>
<div class="row">
<div class="col-12">
<form>
<div class="lqos-config-page">
<div id="configMenuContainer"></div>
<form class="lqos-config-grid">
<section class="lqos-config-panel">
<div class="lqos-config-panel-header">
<div>
<h5 class="lqos-config-panel-title">Netzur Integration</h5>
<div class="lqos-config-panel-subtitle">Configure API access and timeout behavior for automated imports from Netzur CRM.</div>
</div>
</div>
<div class="lqos-config-section">
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="enableNetzur">
<label class="form-check-label" for="enableNetzur">Enable Netzur Integration</label>
@@ -26,8 +35,12 @@
<div class="form-text">Adjust only if the API routinely needs more than 60 seconds</div>
</div>
</div>
</section>
<div class="lqos-config-actions">
<button type="button" id="saveNetzur" class="btn btn-outline-primary">Save Changes</button>
</form>
</div>
</div>
</form>
</div>
<script src="config_netzur.js%CACHEBUSTERS%"></script>
@@ -1,7 +1,16 @@
<div id="configMenuContainer"></div>
<div class="row">
<div class="col-12">
<form>
<div class="lqos-config-page">
<div id="configMenuContainer"></div>
<form class="lqos-config-grid">
<section class="lqos-config-panel">
<div class="lqos-config-panel-header">
<div>
<h5 class="lqos-config-panel-title">Powercode Integration</h5>
<div class="lqos-config-panel-subtitle">Configure authentication and endpoint details for automated imports from Powercode.</div>
</div>
</div>
<div class="lqos-config-section">
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="enablePowercode">
<label class="form-check-label" for="enablePowercode">Enable Powercode Integration</label>
@@ -20,9 +29,13 @@
<div class="form-text">Base URL for Powercode API (e.g. https://your-powercode.com)</div>
</div>
</div>
</section>
<div class="lqos-config-actions">
<button type="button" id="saveButton" class="btn btn-outline-primary">Save Changes</button>
</form>
</div>
</div>
</form>
</div>
<script src="config_powercode.js%CACHEBUSTERS%"></script>
@@ -1,7 +1,16 @@
<div id="configMenuContainer"></div>
<div class="row">
<div class="col-12">
<form>
<div class="lqos-config-page">
<div id="configMenuContainer"></div>
<form class="lqos-config-grid">
<section class="lqos-config-panel">
<div class="lqos-config-panel-header">
<div>
<h5 class="lqos-config-panel-title">Sonar Integration</h5>
<div class="lqos-config-panel-subtitle">Configure Sonar API access plus the SNMP and model metadata LibreQoS uses for wireless device enrichment.</div>
</div>
</div>
<div class="lqos-config-section">
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="enableSonar">
<label class="form-check-label" for="enableSonar">Enable Sonar Integration</label>
@@ -44,9 +53,13 @@
<div class="form-text">Comma-separated list of active status IDs</div>
</div>
</div>
</section>
<div class="lqos-config-actions">
<button type="button" id="saveButton" class="btn btn-outline-primary">Save Changes</button>
</form>
</div>
</div>
</form>
</div>
<script src="config_sonar.js%CACHEBUSTERS%"></script>
@@ -1,7 +1,16 @@
<div id="configMenuContainer"></div>
<div class="row">
<div class="col-12">
<form>
<div class="lqos-config-page">
<div id="configMenuContainer"></div>
<form class="lqos-config-grid">
<section class="lqos-config-panel">
<div class="lqos-config-panel-header">
<div>
<h5 class="lqos-config-panel-title">Splynx Integration</h5>
<div class="lqos-config-panel-subtitle">Connect LibreQoS to Splynx and choose how much hierarchy should be imported into the shaping tree.</div>
</div>
</div>
<div class="lqos-config-section">
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="enableSplynx">
<label class="form-check-label" for="enableSplynx">Enable Splynx Integration</label>
@@ -37,8 +46,12 @@
<div class="form-text">Select the topology strategy for network hierarchy. AP Only provides the best balance of performance and structure.</div>
</div>
</div>
</section>
<div class="lqos-config-actions">
<button type="button" id="saveButton" class="btn btn-outline-primary">Save Changes</button>
</form>
</div>
</div>
</form>
</div>
<script src="config_splynx.js%CACHEBUSTERS%"></script>
@@ -1,59 +1,86 @@
<div id="configMenuContainer"></div>
<div class="row">
<div class="col-12">
<div class="alert alert-warning" role="alert">
<i class="fa fa-exclamation-triangle"></i> Warning: These are advanced settings. Adjust them at your own risk.
</div>
<form>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="stopIrqBalance">
<label class="form-check-label" for="stopIrqBalance">Stop IRQ Balance Service</label>
<div class="form-text">Disables the irq_balance system service</div>
<div class="lqos-config-page">
<div id="configMenuContainer"></div>
<form class="lqos-config-grid">
<section class="lqos-config-panel">
<div class="lqos-config-panel-header">
<div>
<h5 class="lqos-config-panel-title">System Tuning</h5>
<div class="lqos-config-panel-subtitle">Adjust IRQ handling, kernel packet budgets, and NIC offload behavior on systems that need manual tuning.</div>
</div>
</div>
<div class="mb-3">
<label for="netdevBudgetUsecs" class="form-label">Netdev Budget (μs)</label>
<input type="number" class="form-control" id="netdevBudgetUsecs">
<div class="form-text">Time budget for network device processing in microseconds</div>
<div class="lqos-config-note lqos-config-note-warning mb-3" role="alert">
<i class="fa fa-exclamation-triangle me-2"></i>These are advanced settings. Change them only when you have a measured reason to do so.
</div>
<div class="mb-3">
<label for="netdevBudgetPackets" class="form-label">Netdev Budget (Packets)</label>
<input type="number" class="form-control" id="netdevBudgetPackets">
<div class="form-text">Packet budget for network device processing</div>
</div>
<div class="row g-3">
<div class="col-12 col-xl-6">
<div class="lqos-config-section h-100">
<h6 class="lqos-config-section-title">Interrupts and Budgets</h6>
<div class="lqos-config-section-subtitle">Control how aggressively the host services NIC interrupts and packet processing.</div>
<div class="mb-3">
<label for="rxUsecs" class="form-label">RX Polling Frequency (μs)</label>
<input type="number" class="form-control" id="rxUsecs">
<div class="form-text">Receive side polling frequency in microseconds</div>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="stopIrqBalance">
<label class="form-check-label" for="stopIrqBalance">Stop IRQ Balance Service</label>
<div class="form-text">Disables the <code>irq_balance</code> system service.</div>
</div>
<div class="mb-3">
<label for="txUsecs" class="form-label">TX Polling Frequency (μs)</label>
<input type="number" class="form-control" id="txUsecs">
<div class="form-text">Transmit side polling frequency in microseconds</div>
</div>
<div class="mb-3">
<label for="netdevBudgetUsecs" class="form-label">Netdev Budget (μs)</label>
<input type="number" class="form-control" id="netdevBudgetUsecs">
<div class="form-text">Time budget for network device processing in microseconds.</div>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="disableRxVlan">
<label class="form-check-label" for="disableRxVlan">Disable RX VLAN Offloading</label>
</div>
<div class="mb-3">
<label for="netdevBudgetPackets" class="form-label">Netdev Budget (Packets)</label>
<input type="number" class="form-control" id="netdevBudgetPackets">
<div class="form-text">Packet budget for network device processing.</div>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="disableTxVlan">
<label class="form-check-label" for="disableTxVlan">Disable TX VLAN Offloading</label>
</div>
<div class="mb-3">
<label for="rxUsecs" class="form-label">RX Polling Frequency (μs)</label>
<input type="number" class="form-control" id="rxUsecs">
<div class="form-text">Receive-side polling frequency in microseconds.</div>
</div>
<div class="mb-3">
<label for="disableOffload" class="form-label">Disable Offload Features</label>
<input type="text" class="form-control" id="disableOffload" aria-describedby="offloadHelp">
<div id="offloadHelp" class="form-text">Comma-separated list of offload features to disable (e.g. gso,tso,lro)</div>
</div>
<div class="mb-0">
<label for="txUsecs" class="form-label">TX Polling Frequency (μs)</label>
<input type="number" class="form-control" id="txUsecs">
<div class="form-text">Transmit-side polling frequency in microseconds.</div>
</div>
</div>
</div>
<div class="col-12 col-xl-6">
<div class="lqos-config-section h-100">
<h6 class="lqos-config-section-title">Offload Controls</h6>
<div class="lqos-config-section-subtitle">Disable hardware features that interfere with troubleshooting or expected shaping behavior.</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="disableRxVlan">
<label class="form-check-label" for="disableRxVlan">Disable RX VLAN Offloading</label>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="disableTxVlan">
<label class="form-check-label" for="disableTxVlan">Disable TX VLAN Offloading</label>
</div>
<div class="mb-0">
<label for="disableOffload" class="form-label">Disable Offload Features</label>
<input type="text" class="form-control" id="disableOffload" aria-describedby="offloadHelp">
<div id="offloadHelp" class="form-text">Comma-separated list of offload features to disable, for example <code>gso,tso,lro</code>.</div>
</div>
</div>
</div>
</div>
</section>
<div class="lqos-config-actions">
<button type="button" id="saveButton" class="btn btn-outline-primary">Save Changes</button>
</form>
</div>
</div>
</form>
</div>
<script src="config_tuning.js%CACHEBUSTERS%"></script>
@@ -1,133 +1,170 @@
<div id="configMenuContainer"></div>
<div class="row">
<div class="col-12">
<form>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="enableUisp">
<label class="form-check-label" for="enableUisp">Enable UISP Integration</label>
<div class="form-text">Enable integration with UISP billing system</div>
<div class="lqos-config-page">
<div id="configMenuContainer"></div>
<form class="lqos-config-grid">
<section class="lqos-config-panel">
<div class="lqos-config-panel-header">
<div>
<h5 class="lqos-config-panel-title">UISP Integration</h5>
<div class="lqos-config-panel-subtitle">Connect to UISP, choose import strategy, and control how topology, suspended accounts, capacity, and site overrides are handled.</div>
</div>
</div>
<div class="mb-3">
<label for="uispToken" class="form-label">API Token</label>
<input type="text" class="form-control" id="uispToken">
<div class="form-text">UISP API token for authentication</div>
</div>
<div class="row g-3">
<div class="col-12 col-xl-6">
<div class="lqos-config-section h-100">
<h6 class="lqos-config-section-title">Connection</h6>
<div class="lqos-config-section-subtitle">Define API access, default site scope, and transport/security behavior.</div>
<div class="mb-3">
<label for="uispUrl" class="form-label">UISP URL</label>
<input type="text" class="form-control" id="uispUrl">
<div class="form-text">Base URL for UISP API (e.g. https://your-uisp.com)</div>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="enableUisp">
<label class="form-check-label" for="enableUisp">Enable UISP Integration</label>
<div class="form-text">Enable integration with UISP.</div>
</div>
<div class="mb-3">
<label for="uispSite" class="form-label">UISP Site</label>
<input type="text" class="form-control" id="uispSite">
<div class="form-text">Site identifier in UISP</div>
</div>
<div class="mb-3">
<label for="uispToken" class="form-label">API Token</label>
<input type="text" class="form-control" id="uispToken">
<div class="form-text">UISP API token for authentication.</div>
</div>
<div class="mb-3">
<label for="uispStrategy" class="form-label">Strategy</label>
<select class="form-select" id="uispStrategy">
<option value="flat">Flat - Only shapes subscribers by service plan speed</option>
<option value="ap_only">AP Only - Shapes by service plan and Access Point</option>
<option value="ap_site">AP Site - Shapes by service plan, Access Point, and Site</option>
<option value="full">Full - Shapes entire network including backhauls, Sites, APs, and clients</option>
</select>
<div class="form-text">Select the topology strategy for network hierarchy</div>
</div>
<div class="mb-3">
<label for="uispUrl" class="form-label">UISP URL</label>
<input type="text" class="form-control" id="uispUrl">
<div class="form-text">Base URL for the UISP API, for example <code>https://your-uisp.com</code>.</div>
</div>
<div class="mb-3">
<label for="uispSuspendedStrategy" class="form-label">Suspended Strategy</label>
<select class="form-select" id="uispSuspendedStrategy">
<option value="none">None - Do not handle suspensions</option>
<option value="ignore">Ignore - Do not add suspended customers to network map</option>
<option value="slow">Slow - Limit suspended customers to 1mbps</option>
</select>
<div class="form-text">Select how to handle suspended customer accounts</div>
</div>
<div class="mb-3">
<label for="uispSite" class="form-label">UISP Site</label>
<input type="text" class="form-control" id="uispSite">
<div class="form-text">Optional site identifier in UISP.</div>
</div>
<div class="mb-3">
<label for="uispAirmaxCapacity" class="form-label">Airmax Capacity</label>
<input type="number" class="form-control" id="uispAirmaxCapacity" step="0.1">
<div class="form-text">Capacity factor for Airmax devices</div>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="uispIpv6WithMikrotik">
<label class="form-check-label" for="uispIpv6WithMikrotik">IPv6 with Mikrotik</label>
<div class="form-text">Enable IPv6 enrichment with Mikrotik devices.</div>
</div>
<div class="mb-3">
<label for="uispLtuCapacity" class="form-label">LTU Capacity</label>
<input type="number" class="form-control" id="uispLtuCapacity" step="0.1">
<div class="form-text">Capacity factor for LTU devices</div>
</div>
<div class="mb-0 form-check">
<input type="checkbox" class="form-check-input" id="uispInsecureSsl">
<label class="form-check-label" for="uispInsecureSsl">Insecure SSL</label>
<div class="form-text">Disable SSL certificate validation. Use only for testing or known self-signed environments.</div>
</div>
</div>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="uispIpv6WithMikrotik">
<label class="form-check-label" for="uispIpv6WithMikrotik">IPv6 with Mikrotik</label>
<div class="form-text">Enable IPv6 support with Mikrotik devices</div>
</div>
<div class="col-12 col-xl-6">
<div class="lqos-config-section h-100">
<h6 class="lqos-config-section-title">Strategy and Capacity</h6>
<div class="lqos-config-section-subtitle">Choose the imported hierarchy depth and how LibreQoS should interpret suspended accounts and device capacity.</div>
<div class="mb-3">
<label for="uispBandwidthOverhead" class="form-label">Bandwidth Overhead Factor</label>
<input type="number" class="form-control" id="uispBandwidthOverhead" step="0.1" value="1.0">
<div class="form-text">Multiplier for bandwidth overhead calculations</div>
</div>
<div class="mb-3">
<label for="uispStrategy" class="form-label">Strategy</label>
<select class="form-select" id="uispStrategy">
<option value="flat">Flat - Only shapes subscribers by service plan speed</option>
<option value="ap_only">AP Only - Shapes by service plan and Access Point</option>
<option value="ap_site">AP Site - Shapes by service plan, Access Point, and Site</option>
<option value="full">Full - Shapes entire network including backhauls, Sites, APs, and clients</option>
</select>
<div class="form-text">Select the topology strategy for network hierarchy.</div>
</div>
<div class="mb-3">
<label for="uispCommitMultiplier" class="form-label">Commit Bandwidth Multiplier</label>
<input type="number" class="form-control" id="uispCommitMultiplier" step="0.1" value="1.0">
<div class="form-text">Multiplier for commit bandwidth calculations</div>
</div>
<div class="mb-3">
<label for="uispSuspendedStrategy" class="form-label">Suspended Strategy</label>
<select class="form-select" id="uispSuspendedStrategy">
<option value="none">None - Do not handle suspensions</option>
<option value="ignore">Ignore - Do not add suspended customers to network map</option>
<option value="slow">Slow - Limit suspended customers to 1mbps</option>
</select>
<div class="form-text">Select how to handle suspended customer accounts.</div>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="uispUsePtmpAsParent">
<label class="form-check-label" for="uispUsePtmpAsParent">Use PTMP as Parent</label>
<div class="form-text">Treat PTMP devices as parent nodes</div>
</div>
<div class="mb-3">
<label for="uispAirmaxCapacity" class="form-label">Airmax Capacity</label>
<input type="number" class="form-control" id="uispAirmaxCapacity" step="0.1">
<div class="form-text">Capacity factor for Airmax devices.</div>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="uispIgnoreCalculatedCapacity">
<label class="form-check-label" for="uispIgnoreCalculatedCapacity">Ignore Calculated Capacity</label>
<div class="form-text">Ignore capacity calculations from UISP</div>
</div>
<div class="mb-3">
<label for="uispLtuCapacity" class="form-label">LTU Capacity</label>
<input type="number" class="form-control" id="uispLtuCapacity" step="0.1">
<div class="form-text">Capacity factor for LTU devices.</div>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="uispInsecureSsl">
<label class="form-check-label" for="uispInsecureSsl">Insecure SSL</label>
<div class="form-text">Disable SSL certificate validation (not recommended)</div>
</div>
<div class="mb-3">
<label for="uispBandwidthOverhead" class="form-label">Bandwidth Overhead Factor</label>
<input type="number" class="form-control" id="uispBandwidthOverhead" step="0.1" value="1.0">
<div class="form-text">Multiplier for bandwidth overhead calculations.</div>
</div>
<div class="mb-3">
<label for="uispExcludeSites" class="form-label">Exclude Sites</label>
<input type="text" class="form-control" id="uispExcludeSites">
<div class="form-text">Comma-separated list of site IDs to exclude from synchronization</div>
</div>
<div class="mb-3">
<label for="uispCommitMultiplier" class="form-label">Commit Bandwidth Multiplier</label>
<input type="number" class="form-control" id="uispCommitMultiplier" step="0.1" value="1.0">
<div class="form-text">Multiplier for commit bandwidth calculations.</div>
</div>
<div class="mb-3">
<label for="uispSquashSites" class="form-label">Squash Sites</label>
<input type="text" class="form-control" id="uispSquashSites">
<div class="form-text">Comma-separated list of site IDs to consolidate under a single parent</div>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="uispUsePtmpAsParent">
<label class="form-check-label" for="uispUsePtmpAsParent">Use PTMP as Parent</label>
<div class="form-text">Treat PTMP devices as parent nodes.</div>
</div>
<div class="mb-3">
<label for="uispExceptionCpes" class="form-label">Exception CPEs</label>
<input type="text" class="form-control" id="uispExceptionCpes">
<div class="form-text">Comma-separated list of CPE exceptions in "cpe:parent" format</div>
</div>
<div class="mb-0 form-check">
<input type="checkbox" class="form-check-input" id="uispIgnoreCalculatedCapacity">
<label class="form-check-label" for="uispIgnoreCalculatedCapacity">Ignore Calculated Capacity</label>
<div class="form-text">Ignore capacity calculations from UISP.</div>
</div>
</div>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="uispEnableSquashing">
<label class="form-check-label" for="uispEnableSquashing">Enable Squashing</label>
<div class="form-text">Enable site squashing functionality</div>
</div>
<div class="col-12">
<div class="lqos-config-section">
<h6 class="lqos-config-section-title">Site and CPE Overrides</h6>
<div class="lqos-config-section-subtitle">Fine-tune how specific sites and CPEs are excluded, squashed, or reassigned during synchronization.</div>
<div class="mb-3">
<label for="uispDoNotSquashSites" class="form-label">Do Not Squash Sites</label>
<input type="text" class="form-control" id="uispDoNotSquashSites">
<div class="form-text">Comma-separated list of site IDs that should not be squashed</div>
</div>
<div class="row g-3">
<div class="col-12 col-lg-6">
<label for="uispExcludeSites" class="form-label">Exclude Sites</label>
<input type="text" class="form-control" id="uispExcludeSites">
<div class="form-text">Comma-separated list of site IDs to exclude from synchronization.</div>
</div>
<div class="col-12 col-lg-6">
<label for="uispSquashSites" class="form-label">Squash Sites</label>
<input type="text" class="form-control" id="uispSquashSites">
<div class="form-text">Comma-separated list of site IDs to consolidate under a single parent.</div>
</div>
<div class="col-12 col-lg-6">
<label for="uispExceptionCpes" class="form-label">Exception CPEs</label>
<input type="text" class="form-control" id="uispExceptionCpes">
<div class="form-text">Comma-separated list of CPE exceptions in <code>cpe:parent</code> format.</div>
</div>
<div class="col-12 col-lg-6">
<label for="uispDoNotSquashSites" class="form-label">Do Not Squash Sites</label>
<input type="text" class="form-control" id="uispDoNotSquashSites">
<div class="form-text">Comma-separated list of site IDs that should not be squashed.</div>
</div>
<div class="col-12">
<div class="mb-0 form-check">
<input type="checkbox" class="form-check-input" id="uispEnableSquashing">
<label class="form-check-label" for="uispEnableSquashing">Enable Squashing</label>
<div class="form-text">Enable site squashing functionality.</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<div class="lqos-config-actions">
<button type="button" id="saveButton" class="btn btn-outline-primary">Save Changes</button>
</form>
</div>
</div>
</form>
</div>
<script src="config_uisp.js%CACHEBUSTERS%"></script>
@@ -1,7 +1,16 @@
<div id="configMenuContainer"></div>
<div class="row">
<div class="col-12">
<form>
<div class="lqos-config-page">
<div id="configMenuContainer"></div>
<form class="lqos-config-grid">
<section class="lqos-config-panel">
<div class="lqos-config-panel-header">
<div>
<h5 class="lqos-config-panel-title">VISP Integration</h5>
<div class="lqos-config-panel-subtitle">Configure GraphQL UBO API access, tenant selection, and optional online-user enrichment from VISP.</div>
</div>
</div>
<div class="lqos-config-section">
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="enableVisp">
<label class="form-check-label" for="enableVisp">Enable VISP Integration</label>
@@ -46,8 +55,12 @@
<div class="form-text">Used to enrich IPs via online RADIUS sessions if VISP is missing static IPs</div>
</div>
</div>
</section>
<div class="lqos-config-actions">
<button type="button" id="saveVisp" class="btn btn-outline-primary">Save Changes</button>
</form>
</div>
</div>
</form>
</div>
<script src="config_visp.js%CACHEBUSTERS%"></script>
@@ -1,7 +1,16 @@
<div id="configMenuContainer"></div>
<div class="row">
<div class="col-12">
<form>
<div class="lqos-config-page">
<div id="configMenuContainer"></div>
<form class="lqos-config-grid">
<section class="lqos-config-panel">
<div class="lqos-config-panel-header">
<div>
<h5 class="lqos-config-panel-title">WispGate Integration</h5>
<div class="lqos-config-panel-subtitle">Configure API credentials and endpoint details for automated imports from WispGate.</div>
</div>
</div>
<div class="lqos-config-section">
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="enableWispgate">
<label class="form-check-label" for="enableWispgate">Enable WispGate Integration</label>
@@ -20,10 +29,13 @@
<div class="form-text">WispGate API URL</div>
</div>
</div>
</section>
<div class="lqos-config-actions">
<button type="button" id="saveButton" class="btn btn-outline-primary">Save Changes</button>
</form>
</div>
</div>
</form>
</div>
<script src="config_wispgate.js%CACHEBUSTERS%"></script>
@@ -1,58 +1,51 @@
<div class="row g-4">
<div class="col-12">
<div class="card shadow-sm">
<div class="card-body">
<div class="d-flex flex-wrap align-items-center justify-content-between gap-3">
<div>
<h5 class="card-title mb-1"><i class="fa fa-ethernet me-2"></i>Ethernet Caps</h5>
<p class="text-muted mb-0">Circuits automatically down-rated because detected Ethernet speed was below the requested plan.</p>
</div>
<div id="ethernetCapsSummary" class="small text-body-secondary"></div>
<div class="lqos-config-page">
<section class="lqos-config-panel">
<div class="lqos-config-panel-header">
<div>
<h5 class="lqos-config-panel-title"><i class="fa fa-ethernet me-2"></i>Ethernet Caps</h5>
<div class="lqos-config-panel-subtitle">Circuits automatically down-rated because detected Ethernet speed was below the requested plan.</div>
</div>
<div id="ethernetCapsSummary" class="small text-body-secondary"></div>
</div>
<div class="lqos-config-section">
<div class="row g-2 align-items-end mb-3">
<div class="col-12 col-lg-5">
<label class="form-label small text-body-secondary" for="ethernetCapsSearch">Search</label>
<input id="ethernetCapsSearch" class="form-control" type="text" placeholder="Search circuits, parents, device names…">
</div>
<div class="col-6 col-lg-2">
<label class="form-label small text-body-secondary" for="ethernetCapsTier">Ethernet</label>
<select id="ethernetCapsTier" class="form-select">
<option value="">All</option>
<option value="10M">10M</option>
<option value="100M">100M</option>
<option value="1G">1G+</option>
</select>
</div>
<div class="col-6 col-lg-2">
<label class="form-label small text-body-secondary" for="ethernetCapsPageSize">Per page</label>
<select id="ethernetCapsPageSize" class="form-select">
<option value="50">50</option>
<option value="100" selected>100</option>
<option value="250">250</option>
</select>
</div>
<div class="col-12 col-lg-3 d-flex justify-content-lg-end gap-2">
<button id="ethernetCapsPrev" type="button" class="btn btn-outline-primary">
<i class="fa fa-arrow-left"></i>
</button>
<button id="ethernetCapsNext" type="button" class="btn btn-outline-primary">
<i class="fa fa-arrow-right"></i>
</button>
</div>
</div>
</div>
</div>
<div class="col-12">
<div class="card shadow-sm">
<div class="card-body">
<div class="row g-2 align-items-end mb-3">
<div class="col-12 col-lg-5">
<label class="form-label small text-body-secondary" for="ethernetCapsSearch">Search</label>
<input id="ethernetCapsSearch" class="form-control" type="text" placeholder="Search circuits, parents, device names…">
</div>
<div class="col-6 col-lg-2">
<label class="form-label small text-body-secondary" for="ethernetCapsTier">Ethernet</label>
<select id="ethernetCapsTier" class="form-select">
<option value="">All</option>
<option value="10M">10M</option>
<option value="100M">100M</option>
<option value="1G">1G+</option>
</select>
</div>
<div class="col-6 col-lg-2">
<label class="form-label small text-body-secondary" for="ethernetCapsPageSize">Per page</label>
<select id="ethernetCapsPageSize" class="form-select">
<option value="50">50</option>
<option value="100" selected>100</option>
<option value="250">250</option>
</select>
</div>
<div class="col-12 col-lg-3 d-flex justify-content-lg-end gap-2">
<button id="ethernetCapsPrev" type="button" class="btn btn-outline-secondary">
<i class="fa fa-arrow-left"></i>
</button>
<button id="ethernetCapsNext" type="button" class="btn btn-outline-secondary">
<i class="fa fa-arrow-right"></i>
</button>
</div>
</div>
<div id="ethernetCapsTableWrap">
<div class="text-muted small"><i class="fa fa-spinner fa-spin me-1"></i>Loading Ethernet cap data…</div>
</div>
<div id="ethernetCapsPager" class="small text-body-secondary mt-3"></div>
<div id="ethernetCapsTableWrap">
<div class="text-muted small"><i class="fa fa-spinner fa-spin me-1"></i>Loading Ethernet cap data…</div>
</div>
<div id="ethernetCapsPager" class="small text-body-secondary mt-3"></div>
</div>
</div>
</section>
</div>
<script src="ethernet_caps.js%CACHEBUSTERS%"></script>
@@ -1839,6 +1839,32 @@ table tr td a {
color: var(--bs-secondary-color) !important;
}
.lqos-config-network-editor {
display: grid;
gap: 0.9rem;
}
.lqos-config-network-editor .lqos-network-node-card {
background: color-mix(in srgb, var(--lqos-surface-2) 88%, transparent);
}
.lqos-config-network-editor .card-title {
font-size: 1rem;
font-weight: 700;
}
.lqos-config-network-editor .card-body {
padding: 1rem 1rem 0.95rem;
}
.lqos-config-network-editor .btn {
white-space: nowrap;
}
.lqos-config-network-editor .badge {
font-weight: 600;
}
.nav-pills .nav-link {
color: var(--bs-secondary-color);
}