Minimal read-only view of most of the configuration - a good start.

This commit is contained in:
Herbert Wolverson 2024-04-24 15:43:43 -05:00
parent 4c0af0bdea
commit 062e1e7eb8

View File

@ -63,15 +63,26 @@
<div class="d-flex align-items-start">
<div class="nav flex-column nav-pills me-3" id="v-pills-tab" role="tablist" aria-orientation="vertical">
<button class="nav-link active" id="v-pills-display-tab" data-bs-toggle="pill" data-bs-target="#v-pills-display" type="button" role="tab" aria-controls="v-pills-home" aria-selected="true"><i class="fa fa-tv"></i> Display</button>
<button class="nav-link" id="v-pills-home-tab" data-bs-toggle="pill" data-bs-target="#v-pills-home" type="button" role="tab" aria-controls="v-pills-home" aria-selected="true"><i class="fa fa-wifi"></i> Network</button>
<button class="nav-link" id="v-pills-shaper-tab" data-bs-toggle="pill" data-bs-target="#v-pills-shaper" type="button" role="tab" aria-controls="v-pills-profile" aria-selected="false"><i class="fa fa-balance-scale"></i> Shaper</button>
<button class="nav-link" id="v-pills-server-tab" data-bs-toggle="pill" data-bs-target="#v-pills-server" type="button" role="tab" aria-controls="v-pills-server" aria-selected="false"><i class="fa fa-server"></i> Server</button>
<button class="nav-link" id="v-pills-tuning-tab" data-bs-toggle="pill" data-bs-target="#v-pills-tuning" type="button" role="tab" aria-controls="v-pills-settings" aria-selected="false"><i class="fa fa-warning"></i> Tuning</button>
<button class="nav-link" id="v-pills-spylnx-tab" data-bs-toggle="pill" data-bs-target="#v-pills-spylnx" type="button" role="tab" aria-controls="v-pills-settings" aria-selected="false"><i class="fa fa-eye"></i> Spylnx</button>
<button class="nav-link" id="v-pills-uisp-tab" data-bs-toggle="pill" data-bs-target="#v-pills-uisp" type="button" role="tab" aria-controls="v-pills-settings" aria-selected="false"><i class="fa fa-eye"></i> UISP</button>
<button class="nav-link" id="v-pills-home-tab" data-bs-toggle="pill" data-bs-target="#v-pills-home" type="button" role="tab" aria-controls="v-pills-home" aria-selected="true"><i class="fa fa-server"></i> General</button>
<button class="nav-link" id="v-pills-anon-tab" data-bs-toggle="pill" data-bs-target="#v-pills-anon" type="button" role="tab" aria-controls="v-pills-profile" aria-selected="false"><i class="fa fa-user-secret"></i> Anonymous Usage Stats</button>
<button class="nav-link" id="v-pills-tuning-tab" data-bs-toggle="pill" data-bs-target="#v-pills-tuning" type="button" role="tab" aria-controls="v-pills-server" aria-selected="false"><i class="fa fa-warning"></i> Tuning</button>
<button class="nav-link" id="v-pills-bridge-tab" data-bs-toggle="pill" data-bs-target="#v-pills-bridge" type="button" role="tab" aria-controls="v-pills-settings" aria-selected="false"><i class="fa fa-chain"></i> Bridge/On-a-Stick</button>
<button class="nav-link" id="v-pills-queues-tab" data-bs-toggle="pill" data-bs-target="#v-pills-queues" type="button" role="tab" aria-controls="v-pills-settings" aria-selected="false"><i class="fa fa-car"></i> Queues</button>
<button class="nav-link" id="v-pills-lts-tab" data-bs-toggle="pill" data-bs-target="#v-pills-lts" type="button" role="tab" aria-controls="v-pills-settings" aria-selected="false"><i class="fa fa-line-chart"></i> Long-Term Stats</button>
<button class="nav-link" id="v-pills-iprange-tab" data-bs-toggle="pill" data-bs-target="#v-pills-iprange" type="button" role="tab" aria-controls="v-pills-settings" aria-selected="false"><i class="fa fa-address-card"></i> IP Ranges</button>
<button class="nav-link" id="v-pills-flows-tab" data-bs-toggle="pill" data-bs-target="#v-pills-flows" type="button" role="tab" aria-controls="v-pills-settings" aria-selected="false"><i class="fa fa-arrow-circle-down"></i> Flow Tracking</button>
<button class="nav-link" id="v-pills-icommon-tab" data-bs-toggle="pill" data-bs-target="#v-pills-icommon" type="button" role="tab" aria-controls="v-pills-settings" aria-selected="false"><i class="fa fa-link"></i> Integration - Common</button>
<button class="nav-link" id="v-pills-spylnx-tab" data-bs-toggle="pill" data-bs-target="#v-pills-spylnx" type="button" role="tab" aria-controls="v-pills-settings" aria-selected="false"><i class="fa fa-link"></i> Spylnx</button>
<button class="nav-link" id="v-pills-uisp-tab" data-bs-toggle="pill" data-bs-target="#v-pills-uisp" type="button" role="tab" aria-controls="v-pills-settings" aria-selected="false"><i class="fa fa-link"></i> UISP</button>
<button class="nav-link" id="v-pills-powercode-tab" data-bs-toggle="pill" data-bs-target="#v-pills-powercode" type="button" role="tab" aria-controls="v-pills-settings" aria-selected="false"><i class="fa fa-link"></i> Powercode</button>
<button class="nav-link" id="v-pills-sonar-tab" data-bs-toggle="pill" data-bs-target="#v-pills-sonar" type="button" role="tab" aria-controls="v-pills-settings" aria-selected="false"><i class="fa fa-link"></i> Sonar</button>
<button class="nav-link" id="v-pills-influxdb-tab" data-bs-toggle="pill" data-bs-target="#v-pills-influxdb" type="button" role="tab" aria-controls="v-pills-settings" aria-selected="false"><i class="fa fa-link"></i> InfluxDB</button>
<button class="nav-link" id="v-pills-netjson-tab" data-bs-toggle="pill" data-bs-target="#v-pills-netjson" type="button" role="tab" aria-controls="v-pills-settings" aria-selected="false"><i class="fa fa-map"></i> Network Layout</button>
<button class="nav-link" id="v-pills-shapeddevs-tab" data-bs-toggle="pill" data-bs-target="#v-pills-shapeddevs" type="button" role="tab" aria-controls="v-pills-settings" aria-selected="false"><i class="fa fa-table"></i> Shaped Devices</button>
<button class="nav-link" id="v-pills-users-tab" data-bs-toggle="pill" data-bs-target="#v-pills-users" type="button" role="tab" aria-controls="v-pills-settings" aria-selected="false"><i class="fa fa-users"></i> LibreQoS Users</button>
</div>
<div class="tab-content" id="v-pills-tabContent">
<!-- Tabbed config elements -->
<div class="tab-pane fade show active" id="v-pills-display" role="tabpanel" aria-labelledby="v-pills-display-tab">
<h2><i class="fa fa-wifi"></i> Display Settings</h2>
<table class="table">
@ -106,299 +117,401 @@
</tr>
</table>
</div>
<div class="tab-pane fade" id="v-pills-home" role="tabpanel" aria-labelledby="v-pills-home-tab">
<h2><i class="fa fa-wifi"></i> Network Settings</h2>
<!-- General tab -->
<div class="tab-pane fade" id="v-pills-home" role="tabpanel" aria-labelledby="v-pills-home-tab">
<h2><i class="fa fa-server"></i> General Settings</h2>
<table class="table">
<tr>
<td colspan="2">Setup the basic network interface configuration.</td>
<td><label for="bindVersion">Version: </label></td>
<td><input type="text" id="bindVersion" style="background: #ddd" /></td>
</tr>
<tr>
<td colspan="2" class="alert alert-info" role="alert">
<i class="fa fa-info"></i> For normal operation, you need one NIC port facing the Internet, and a second facing your core router.
If you are operating in "on a stick" mode (with a single NIC, and VLANs for inbound and outbound),
select the same NIC for both directions.
</td>
<td><label for="bindPath">Path to LibreQoS: </label></td>
<td><input type="text" id="bindPath" style="width: 500px" /></td>
</tr>
<tr>
<td>Interface facing your core router</td>
<td><select id="nicCore"></option></td>
<td><label for="bindNodeId">Node ID: </label></td>
<td><input type="text" id="bindNodeId" style="width: 500px" /></td>
</tr>
<tr>
<td>Interface facing the Internet</td>
<td><select id="nicInternet"></option></td>
<td><label for="bindNodeName">Node Name: </label></td>
<td><input type="text" id="bindNodeName" style="width: 500px" /></td>
</tr>
<tr>
<td colspan="2"><h3>Single-Interface ("On A Stick") Configuration</td>
<td><label for="bindPacketCaptureTime">Packet Capture Time: </label></td>
<td><input type="text" id="bindPacketCaptureTime" style="width: 500px" /></td>
</tr>
<tr>
<td colspan="2" class="alert alert-info" role="alert">
<i class="fa fa-info"></i> "On a stick" mode allows you to operate with a single NIC, with one VLAN
containing inbound traffic and the other outbound. Please refer to the
documentation.
</td>
</tr>
<tr colspan="2">
<td>
<input class="form-check-input" type="checkbox" value="" id="onAStick">
<label class="form-check-label" for="onAStick">
Enable Single-Interface ("on a stick") mode?
</label>
</td>
</tr>
<tr>
<td>VLAN facing your core router</td>
<td>
<input class="form-input" type="number" min="0" max="4094" id="StickVLANCore" />
</td>
</tr>
<tr>
<td>VLAN facing the Internet</td>
<td>
<input class="form-input" type="number" min="0" max="4094" id="StickVLANInternet" />
</td>
</tr>
<tr>
<td colspan="2">
<h3>Bifrost XDP-Accelerated Bridge</h3>
<p class="alert alert-danger" role="alert">
You must configure XDP bridging by editing the `/etc/lqos.conf` file on the server.
</p>
</td>
</tr>
<tr>
<td colspan="2" class="alert alert-warning" role="alert">
<i class="fa fa-warning"></i> Bifrost is an experimental feature at this time. Bifrost XDP allows you to bypass the entire
Linux bridge system, and use XDP to bridge directly between interfaces or VLANs. This can result
in significant performance improvements on NICs that support XDP in "driver" mode.
</td>
</tr>
<tr>
<td colspan="2">
<input class="form-check-input" type="checkbox" value="" id="useKernelBridge" disabled="true">
<label class="form-check-label" for="useKernelBridge">
Enable Bifrost Acceleration
</label>
</td>
</tr>
<tr>
<td id="bifrostInterfaces" colspan="2">Interface Mapping</td>
</tr>
<tr>
<td id="bifrostVlans" colspan="2">VLAN Mapping</td>
<td><label for="bindQueueCheckPeriodMs">Queue Check Period (ms): </label></td>
<td><input type="text" id="bindQueueCheckPeriodMs" style="width: 500px" /></td>
</tr>
</table>
</div>
<div class="tab-pane fade" id="v-pills-shaper" role="tabpanel" aria-labelledby="v-pills-shaper-tab">
<h2><i class="fa fa-balance-scale"></i>Shaper Settings</h2>
<p>Tune the LibreQoS traffic shaper to your needs.</p>
<!-- Anonymous Usage tab -->
<div class="tab-pane fade" id="v-pills-anon" role="tabpanel" aria-labelledby="v-pills-anon-tab">
<h2><i class="fa fa-user-secret"></i>Anonymous Usage Statistics Settings</h2>
<table class="table">
<tr>
<td colspan="2">
<h3>Traffic Shaping Control</h3>
</td>
</tr>
<tr class="alert-info alert" role="alert">
<td colspan="2"><i class="fa fa-info"></i> FQ_CODEL offers good latency management and low CPU overhead. CAKE requires more CPU, but offers excellent latency management.</td>
<td><label for="bindSendAnonymous">Send Anonymous Stats: </label></td>
<td><input type="checkbox" id="bindSendAnonymous" /></td>
</tr>
<tr>
<td>SQM Mode</td>
<td><label for="bindAnonymousServer">Anonymous Stats Server: </label></td>
<td><input type="text" id="bindAnonymousServer" style="width: 500px" /></td>
</tr>
</table>
</div>
<!-- Tuning tab -->
<div class="tab-pane fade" id="v-pills-tuning" role="tabpanel" aria-labelledby="v-pills-tuning-tab">
<h2><i class="fa fa-warning"></i> Tuning Settings</h2>
<table class="table">
<tr>
<td><label for="bindStopIrqBalance">Stop IRQ Balancer: </label></td>
<td><input type="checkbox" id="bindStopIrqBalance" /></td>
</tr>
<tr>
<td><label for="bindNetdevBudgetUs">Netdev Budget (usecs): </label></td>
<td><input type="text" id="bindNetdevBudgetUs" style="width: 500px" /></td>
</tr>
<tr>
<td><label for="bindNetdevBudgetPackets">Netdev Budget (packets): </label></td>
<td><input type="text" id="bindNetdevBudgetPackets" style="width: 500px" /></td>
</tr>
<tr>
<td><label for="bindRxUs">Rx Period (usecs): </label></td>
<td><input type="text" id="bindRxUs" style="width: 500px" /></td>
</tr>
<tr>
<td><label for="bindTxUs">Tx Period (usecs): </label></td>
<td><input type="text" id="bindTxUs" style="width: 500px" /></td>
</tr>
<tr>
<td><label for="bindDisableRxVlan">Disable RxVlan Offload: </label></td>
<td><input type="checkbox" id="bindDisableRxVlan" /></td>
</tr>
<tr>
<td><label for="bindDisableTxVlan">Disable TxVlan Offload: </label></td>
<td><input type="checkbox" id="bindDisableTxVlan" /></td>
</tr>
<tr>
<td><label for="bindDisableOffload">Offloads to Disable: </label></td>
<td><input type="text" id="bindDisableOffload" /></td>
</tr>
</table>
</div>
<!-- Bridge/On-a-Stick tab -->
<div class="tab-pane fade" id="v-pills-bridge" role="tabpanel" aria-labelledby="v-pills-bridge-tab">
<h2><i class="fa fa-chain"></i> Bridge Settings</h2>
</div>
<!-- Queues Tab -->
<div class="tab-pane fade" id="v-pills-queues" role="tabpanel" aria-labelledby="v-pills-queues-tab">
<h2><i class="fa car"></i> Queue Settings</h2>
<table class="table">
<tr>
<td><label for="bindSqm">SQM Mode: </label></td>
<td>
<select id="sqmMode">
<option value="fq_codel">FQ_Codel</option>
<option value="cake diffserv4">Cake + Diffserv4</option>
<option value="cake diffserv4 ack-filter">Cake + Diffserv4 + ACK Filter</option>
<select id="bindSqm">
<option value="cake diffserv4">Cake with Diffserv4</option>
<option value="cake diffserv4 ack-filter">Cake with Diffserv4 + Duplicate ACK Filtering</option>
</select>
</td>
</tr>
<tr class="alert-info">
<td colspan="2">Monitor mode disables all traffic shaping, allowing you to watch your network undisturbed.</td>
<tr>
<td><label for="bindMonitorMode">Monitor Only Mode (No Shaping): </label></td>
<td><input type="checkbox" id="bindMonitorMode" /></td>
</tr>
<tr>
<td colspan="2">
<input class="form-check-input" type="checkbox" value="" id="monitorMode">
<label class="form-check-label" for="monitorMode">
Enable Monitor Mode
</label>
</td>
<td><label for="bindUplinkMbps">Uplink Bandwidth (Mbps): </label></td>
<td><input type="text" id="bindUplinkMbps" /></td>
</tr>
<tr>
<td colspan="2">
<h3>Bandwidth</h3>
</td>
<td><label for="bindDownlinkMbps">Downlink Bandwidth (Mbps): </label></td>
<td><input type="text" id="bindDownlinkMbps" /></td>
</tr>
<tr>
<td>Total Download Bandwidth (Mbps)</td>
<td><input type="number" min="1" max="1000000000" step="100" id="maxDownload"></td>
<td><label for="bindGeneratedDownlinkMbps">Generated PN Download Bandwidth (Mbps): </label></td>
<td><input type="text" id="bindGeneratedDownlinkMbps" /></td>
</tr>
<tr>
<td>Total Upload Bandwidth (Mbps)</td>
<td><input type="number" min="1" max="1000000000" step="100" id="maxUpload"></td>
</tr>
<tr class="alert-info">
<td colspan="2">
<i class="fa fa-info"></i> Devices without a parent will be placed underneath evenly-balanced generated nodes. This defines the
available bandwidth for those nodes. If in doubt, set to equal your total bandwidth.
</td>
<td><label for="bindGeneratedUplinkMbps">Generated PN Upload Bandwidth (Mbps): </label></td>
<td><input type="text" id="bindGeneratedUplinkMbps" /></td>
</tr>
<tr>
<td>Generated Node Download Bandwidth (Mbps)</td>
<td><input type="number" min="1" max="1000000000" step="100" id="generatedDownload"></td>
<td><label for="bindDryRun">Dry Run (Don't Make Queues): </label></td>
<td><input type="checkbox" id="bindDryRun" /></td>
</tr>
<tr>
<td>Generated Node Upload Bandwidth (Mbps)</td>
<td><input type="number" min="1" max="1000000000" step="100" id="generatedUpload"></td>
</tr>
<tr class="alert-info">
<td colspan="2">
Bin packing is only useful for devices without parent nodes in the shaper tree. Enable this option
to automatically assign devices to nodes based on the device's plans, evenly balancing load across
CPUs.
</td>
</tr>
<td colspan="2">
<input class="form-check-input" type="checkbox" value="" id="binpacking">
<label class="form-check-label" for="binpacking">
Use Binpacking
</label>
</td>
</table>
</div>
<div class="tab-pane fade" id="v-pills-server" role="tabpanel" aria-labelledby="v-pills-server-tab">
<h2><i class="fa fa-server"></i> Server Settings</h2>
<table class="table">
<tr>
<td colspan="2" class="alert-danger">
<i class="fa fa-warning"></i> Disabling actual shell commands stops LibreQoS from actually doing anything. Simulated
output is logged to the console and text files, allowing for debugging.
</td>
<td><label for="bindSudo">Use Sudo: </label></td>
<td><input type="checkbox" id="bindSudo" /></td>
</tr>
<tr>
<td colspan="2">
<input class="form-check-input" type="checkbox" value="" id="actualShellCommands">
<label class="form-check-label" for="actualShellCommands">
Enable Actual Shell Commands
</label>
</td>
<td><label for="bindBinpack">Use Binpacking to equalize CPU usage: </label></td>
<td><input type="checkbox" id="bindBinpack" /></td>
</tr>
<tr>
<td colspan="2" class="alert-info">
<i class="fa fa-info"></i> Running shell commands with "sudo" isn't necessary on a default configuration.
</td>
</tr>
<tr>
<td colspan="2">
<input class="form-check-input" type="checkbox" value="" id="useSudo">
<label class="form-check-label" for="useSudo">
Run Shell Commands as Sudo
</label>
</td>
</tr>
<tr>
<td colspan="2" class="alert-danger">
<i class="fa fa-warning"></i> Overriding the number of queues is only necessary if your NIC is giving
very strange results. Use with extreme caution. Leave this at 0 unless you really know what you are doing.
</td>
</tr>
<tr>
<td>Override count of available queues?</td>
<td><input type="number" min="2" max="256" step="2" id="overrideQueues" /></td>
<td><label for="bindQueuesAvailableOverride">Queues Available Override: </label></td>
<td><input type="text" id="bindQueuesAvailableOverride" /></td>
</tr>
</table>
</div>
<div class="tab-pane fade" id="v-pills-tuning" role="tabpanel" aria-labelledby="v-pills-tuning-tab">
<h2><i class="fa fa-warning"></i> Tuning Settings</h2>
<table class="table">
<tr>
<td colspan="2" class="alert alert-danger" role="alert">
<i class="fa fa-warning"></i> <strong>DANGER</strong>
<p>These settings can drastically affect performance of your server, including rendering it non-functional.</p>
</td>
</tr>
<tr>
<td colspan="2" class="alert-info" role="alert">
How frequently should the TC queues be polled? 30-50 is good for detailed analysis,
1000 is good for normal running. If you select a value slower than the time currently taken
to access queue information, queue analysis will no longer display data on a consistent
time-step. Values less than 20ms are not recommended.
</td>
</tr>
<tr>
<td>
Queue Check Frequency (ms)
</td>
<td>
<input type="number" min="10" max="1000" id="queuecheckms" />
</td>
</tr>
<tr><td colspan="2">IRQ Balancing should generally be disabled.</td></tr>
<tr>
<td colspan="2">
<input class="form-check-input" type="checkbox" value="" id="stopIrqBalance">
<label class="form-check-label" for="stopIrqBalance">
Stop IRQ Balancing
</label>
</td>
</tr>
<tr><td colspan="2">Network device budget (usec) controls how frequently the kernel passes batches of packets to the processing system. Low numbers tend to reduce latency, higher numbers can improve throughput.</td></tr>
<tr>
<td>Netdev Budget (usecs)</td>
<td><input type="number" min="0" max="1000000" id="netDevUsec" /></td>
</tr>
<tr><td colspan="2">Network device budget (packets) controls how frequently the kernel passes batches of packets to the processing system. Low numbers tend to reduce latency, higher numbers can improve throughput.</td></tr>
<tr>
<td>Netdev Budget (packets)</td>
<td><input type="number" min="0" max="1000000" id="netDevPackets" /></td>
</tr>
<tr><td colspan="2">How frequently should the kernel poll for receive packets?</td></tr>
<tr>
<td>RX Usecs</td>
<td><input type="number" min="0" max="1000000" id="rxUsecs" /></td>
</tr>
<tr><td colspan="2">How frequently should the kernel poll for transmit packets?</td></tr>
<tr>
<td>TX Usecs</td>
<td><input type="number" min="0" max="1000000" id="txUsecs" /></td>
</tr>
<tr><td colspan="2">If you are using VLANs, you generally need to enable this feature</td></tr>
<tr>
<td colspan="2">
<input class="form-check-input" type="checkbox" value="" id="disableRxVlan">
<label class="form-check-label" for="disableRxVlan">
Disable RX VLAN Offloading
</label>
</td>
</tr>
<tr><td colspan="2">If you are using VLANs, you generally need to enable this feature</td></tr>
<tr>
<td colspan="2">
<input class="form-check-input" type="checkbox" value="" id="disableTxVlan">
<label class="form-check-label" for="disableTxVlan">
Disable TX VLAN Offloading
</label>
</td>
</tr>
<tr><td colspan="2">Offloads to disable. We've tried to include the important ones.</td></tr>
<tr>
<td>Disable Offloads (space separated)</td>
<td><input type="text" id="disableOffloadList" /></td>
</tr>
</table>
<p class="alert alert-info" role="alert">
At this time, you can only apply these settings to the current running instance. Edit <em>/etc/lqos.conf</em> to
apply changes permanently. Applying tuning settings will not restart your XDP bridge.
</p>
<a class="btn btn-secondary" id="btnApplyTuning">Apply Tuning Settings</a>
<!-- Long-Term Stats Tab -->
<div class="tab-pane fade" id="v-pills-lts" role="tabpanel" aria-labelledby="v-pills-lts-tab">
<h2><i class="fa fa-line-chart"></i> Long-Term Stats Settings</h2>
<table class="table">
<tr>
<td><label for="bindEnableLTS">Send Statistics to Long-Term Stats: </label></td>
<td><input type="checkbox" id="bindEnableLTS" /></td>
</tr>
<tr>
<td><label for="bindLtsCollation">Collation Period (seconds): </label></td>
<td><input type="text" id="bindLtsCollation" /></td>
</tr>
<tr>
<td><label for="bindLtsLicense">License Key: </label></td>
<td><input type="text" id="bindLtsLicense" /></td>
</tr>
<tr>
<td><label for="bindLtsUispInterval">UISP Reporting Interval (Seconds): </label></td>
<td><input type="text" id="bindLtsUispInterval" /></td>
</tr>
</table>
</div>
<!-- IP Ranges Stats Tab -->
<div class="tab-pane fade" id="v-pills-iprange" role="tabpanel" aria-labelledby="v-pills-iprange-tab">
<h2><i class="fa fa-address-card"></i> IP Ranges Settings</h2>
...
</div>
<!-- Flows Tab -->
<div class="tab-pane fade" id="v-pills-flows" role="tabpanel" aria-labelledby="v-pills-flow-tab">
<h2><i class="fa fa-arrow-circle-down"></i> Flows Settings</h2>
<table class="table">
<tr>
<td><label for="bindFlowsTimeout">Flow Timeout (Seconds): </label></td>
<td><input type="text" id="bindFlowsTimeout" /></td>
</tr>
<tr>
<td><label for="bindEnableNetflow">Enable Netflow Collection: </label></td>
<td><input type="checkbox" id="bindEnableNetflow" /></td>
</tr>
<tr>
<td><label for="bindFlowsPort">Netflow Port Number: </label></td>
<td><input type="text" id="bindFlowsPort" /></td>
</tr>
<tr>
<td><label for="bindFlowsTarget">Send Netflow to IP: </label></td>
<td><input type="text" id="bindFlowsTarget" /></td>
</tr>
<tr>
<td><label for="bindFlowsVersion">Netflow Version: </label></td>
<td>
<select id="bindFlowsVersion">
<option value="5">Netflow v5 - fast, but IPv4 only</option>
<option value="9">Netflow v6/IPFIX</option>
</select>
</td>
</tr>
</table>
</div>
<!-- Integration Common Tab -->
<div class="tab-pane fade" id="v-pills-icommon" role="tabpanel" aria-labelledby="v-pills-icommon-tab">
<h2><i class="fa fa-link"></i> Common Integration Settings</h2>
<table class="table">
<tr>
<td><label for="bindCircuitNameAsAddress">Use Circuit Name as Address: </label></td>
<td><input type="checkbox" id="bindCircuitNameAsAddress" /></td>
</tr>
<tr>
<td><label for="bindOverwriteNetJson">Always Overwrite Network.json: </label></td>
<td><input type="checkbox" id="bindOverwriteNetJson" /></td>
</tr>
<tr>
<td><label for="bindQueueRefreshInterval">Queue Refresh Interval (Minutes): </label></td>
<td><input type="text" id="bindQueueRefreshInterval" /></td>
</tr>
</table>
</div>
<!-- Spylnx Tab -->
<div class="tab-pane fade" id="v-pills-spylnx" role="tabpanel" aria-labelledby="v-pills-spylnx-tab">
Spylnx Settings
...
<h2><i class="fa fa-link"></i> Spylnx Integration Settings</h2>
<table class="table">
<tr>
<td><label for="bindSplynxEnable">Enable Spylnx Integration: </label></td>
<td><input type="checkbox" id="bindSplynxEnable" /></td>
</tr>
<tr>
<td><label for="bindSplynxApiKey">API Key: </label></td>
<td><input type="text" id="bindSplynxApiKey" /></td>
</tr>
<tr>
<td><label for="bindSplynxApiSecret">API Secret: </label></td>
<td><input type="text" id="bindSplynxApiSecret" /></td>
</tr>
<tr>
<td><label for="bindSplynxApiUrl">API URL: </label></td>
<td><input type="text" id="bindSplynxApiUrl" /></td>
</tr>
</table>
</div>
<!-- UISP Tab -->
<div class="tab-pane fade" id="v-pills-uisp" role="tabpanel" aria-labelledby="v-pills-uisp-tab">
UISP Settings
<h2><i class="fa fa-link"></i> UISP Integration Settings</h2>
<table class="table">
<tr>
<td><label for="bindUispEnable">Enable UISP Integration: </label></td>
<td><input type="checkbox" id="bindUispEnable" /></td>
</tr>
<tr>
<td><label for="bindUispToken">UISP Token: </label></td>
<td><input type="text" id="bindUispToken" /></td>
</tr>
<tr>
<td><label for="bindUispUrl">UISP URL: </label></td>
<td><input type="text" id="bindUispUrl" /></td>
</tr>
<tr>
<td><label for="bindUispSite">Root Site Name (for 'full' integrations): </label></td>
<td><input type="text" id="bindUispSite" /></td>
</tr>
<tr>
<td><label for="bindUispStrategy">Generation Strategy: </label></td>
<td>
<select id="bindUispStrategy">
<option value="flat">Flat: no topology</option>
<option value="full">Full: construct a full hierarchy</option>
</select>
</td>
</tr>
<tr>
<td><label for="bindUispSuspended">Suspended Customer Strategy: </label></td>
<td>
<select id="bindUispSuspended">
<option value="none">Do Nothing</option>
<option value="slow">Apply a Slow Speed</option>
</select>
</td>
</tr>
<tr>
<td><label for="bindUispAirmaxCapacity">Airmax Capacity Multiplier: </label></td>
<td><input type="text" id="bindUispAirmaxCapacity" /></td>
</tr>
<tr>
<td><label for="bindUispLtuCapacity">LTU Capacity Multiplier: </label></td>
<td><input type="text" id="bindUispLtuCapacity" /></td>
</tr>
<tr>
<td><label for="bindUispIpv6Mikrotik">Query Mikrotiks for IPv6 Information: </label></td>
<td><input type="checkbox" id="bindUispIpv6Mikrotik" /></td>
</tr>
<tr>
<td><label for="bindUispOverheadFactor">Bandwidth Overhead Factor: </label></td>
<td><input type="text" id="bindUispOverheadFactor" /></td>
</tr>
<tr>
<td><label for="bindUispCommitMultiplier">Commit Bandwidth Multiplier: </label></td>
<td><input type="text" id="bindUispCommitMultiplier" /></td>
</tr>
<tr>
<td><label for="bindUispUsePtmpAsParent">Use PTMP As Parent: </label></td>
<td><input type="checkbox" id="bindUispUsePtmpAsParent" /></td>
</tr>
</table>
</div>
<!-- Powercode Tab -->
<div class="tab-pane fade" id="v-pills-powercode" role="tabpanel" aria-labelledby="v-pills-powercode-tab">
<h2><i class="fa fa-link"></i> Powercode Integration Settings</h2>
<table class="table">
<tr>
<td><label for="bindPowercodeEnable">Enable Powercode Integration: </label></td>
<td><input type="checkbox" id="bindPowercodeEnable" /></td>
</tr>
<tr>
<td><label for="bindPowercodeKey">Powercode API Key: </label></td>
<td><input type="text" id="bindPowercodeKey" /></td>
</tr>
<tr>
<td><label for="bindPowercodeUrl">Powercode API URL: </label></td>
<td><input type="text" id="bindPowercodeUrl" /></td>
</tr>
</table>
</div>
<!-- Sonar Tab -->
<div class="tab-pane fade" id="v-pills-sonar" role="tabpanel" aria-labelledby="v-pills-sonar-tab">
<h2><i class="fa fa-link"></i> Sonar Integration Settings</h2>
<table class="table">
<tr>
<td><label for="bindSonarEnable">Enable Sonar Integration: </label></td>
<td><input type="checkbox" id="bindSonarEnable" /></td>
</tr>
<tr>
<td><label for="bindSonarApiKey">Sonar API Key: </label></td>
<td><input type="text" id="bindSonarApiKey" /></td>
</tr>
<tr>
<td><label for="bindSonarApiUrl">Sonar API URL: </label></td>
<td><input type="text" id="bindSonarApiUrl" /></td>
</tr>
<tr>
<td><label for="bindSonarSnmp">Sonar SNMP Community: </label></td>
<td><input type="text" id="bindSonarSnmp" /></td>
</tr>
</table>
</div>
<!-- InfluxDB Tab -->
<div class="tab-pane fade" id="v-pills-influxdb" role="tabpanel" aria-labelledby="v-pills-influxdb-tab">
<h2><i class="fa fa-link"></i> InfluxDB Integration Settings</h2>
<table class="table">
<tr>
<td><label for="bindInfluxEnable">Enable InfluxDB Integration: </label></td>
<td><input type="checkbox" id="bindInfluxEnable" /></td>
</tr>
<tr>
<td><label for="bindInfluxUrl">InfluxDB URL: </label></td>
<td><input type="text" id="bindInfluxUrl" /></td>
</tr>
<tr>
<td><label for="bindInfluxOrg">InfluxDB Organization: </label></td>
<td><input type="text" id="bindInfluxOrg" /></td>
</tr>
<tr>
<td><label for="bindInfluxBucket">InfluxDB Bucket: </label></td>
<td><input type="text" id="bindInfluxBucket" /></td>
</tr>
<tr>
<td><label for="bindInfluxToken">InfluxDB Token: </label></td>
<td><input type="text" id="bindInfluxToken" /></td>
</tr>
</table>
</div>
<!-- Network Layout/JSON Tab -->
<div class="tab-pane fade" id="v-pills-netjson" role="tabpanel" aria-labelledby="v-pills-netjson-tab">
<h2><i class="fa fa-map"></i> Network.Json - Network Layout</h2>
...
</div>
<!-- ShapedDevices.csv Tab -->
<div class="tab-pane fade" id="v-pills-shapeddevs" role="tabpanel" aria-labelledby="v-pills-shapeddevs-tab">
<h2><i class="fa table"></i> Shaped Devices</h2>
...
</div>
<div class="tab-pane fade" id="v-pills-users" role="tabpanel" aria-labelledby="v-pills-users-tab">
<h2><i class="fa fa-users"></i> LibreQos Web Interface Users</h2>
<div id="userManager"></div>
@ -417,10 +530,103 @@
<footer>&copy; 2022-2023, LibreQoE LLC</footer>
<script>
let python_config = null;
let nics = null;
let lqosd_config = null;
const bindings = [
{ field: "bindVersion", path: ".version", data: "string", editable: false },
{ field: "bindPath", path: ".lqos_directory", data: "string", editable: true },
{ field: "bindNodeId", path: ".node_id", data: "string", editable: true },
{ field: "bindNodeName", path: ".node_name", data: "string", editable: true },
{ field: "bindPacketCaptureTime", path: ".packet_capture_time", data: "integer", editable: true },
{ field: "bindQueueCheckPeriodMs", path: ".queue_check_period_ms", data: "integer", editable: true },
{ field: "bindSendAnonymous", path: ".usage_stats.send_anonymous", data: "bool", editable: true },
{ field: "bindAnonymousServer", path: ".usage_stats.anonymous_server", data: "string", editable: true },
{ field: "bindStopIrqBalance", path: ".tuning.stop_irq_balance", data: "bool", editable: true },
{ field: "bindNetdevBudgetUs", path: ".tuning.netdev_budget_usecs", data: "integer", editable: true },
{ field: "bindNetdevBudgetPackets", path: ".tuning.netdev_budget_packets", data: "integer", editable: true },
{ field: "bindRxUs", path: ".tuning.rx_usecs", data: "integer", editable: true },
{ field: "bindTxUs", path: ".tuning.tx_usecs", data: "integer", editable: true },
{ field: "bindDisableRxVlan", path: ".tuning.disable_rxvlan", data: "bool", editable: true },
{ field: "bindDisableTxVlan", path: ".tuning.disable_txvlan", data: "bool", editable: true },
// bindDisableOffload is special - do it later
// bridge/stick is special - do it later
{ field: "bindSqm", path: ".queues.default_sqm", data: "select-premade", editable: true },
{ field: "bindMonitorMode", path: ".queues.monitor_only", data: "bool", editable: true },
{ field: "bindUplinkMbps", path: ".queues.uplink_bandwidth_mbps", data: "integer", editable: true },
{ field: "bindDownlinkMbps", path: ".queues.downlink_bandwidth_mbps", data: "integer", editable: true },
{ field: "bindGeneratedDownlinkMbps", path: ".queues.generated_pn_download_mbps", data: "integer", editable: true },
{ field: "bindGeneratedUplinkMbps", path: ".queues.generated_pn_upload_mbps", data: "integer", editable: true },
{ field: "bindDryRun", path: ".queues.dry_run", data: "bool", editable: true },
{ field: "bindSudo", path: ".queues.sudo", data: "bool", editable: true },
{ field: "bindBinpack", path: ".queues.use_binpacking", data: "bool", editable: true },
{ field: "bindQueuesAvailableOverride", path: ".queues.queues_available_override", data: "integer", editable: true },
{ field: "bindEnableLTS", path: ".long_term_stats.gather_stats", data: "bool", editable: true },
{ field: "bindLtsCollation", path: ".long_term_stats.collation_period_seconds", data: "integer", editable: true },
{ field: "bindLtsLicense", path: ".long_term_stats.license_key", data: "string", editable: true },
{ field: "bindLtsUispInterval", path: ".long_term_stats.uisp_reporting_interval_seconds", data: "integer", editable: true },
// IP Ranges will require help
// Flow tracking settings are optional
{ field: "bindFlowsTimeout", path: ".flows.flow_timeout_seconds", data: "integer", editable: true },
{ field: "bindEnableNetflow", path: ".flows.netflow_enabled", data: "bool", editable: true },
{ field: "bindFlowsPort", path: ".flows.netflow_port", data: "integer", editable: true },
{ field: "bindFlowsTarget", path: ".flows.netflow_ip", data: "string", editable: true },
{ field: "bindFlowsVersion", path: ".flows.netflow_ip", data: "select-premade", editable: true },
{ field: "bindCircuitNameAsAddress", path: ".integration_common.circuit_name_as_address", data: "bool", editable: true },
{ field: "bindOverwriteNetJson", path: ".integration_common.always_overwrite_network_json", data: "bool", editable: true },
{ field: "bindQueueRefreshInterval", path: ".integration_common.queue_refresh_interval_mins", data: "integer", editable: true },
{ field: "bindSplynxEnable", path: ".spylnx_integration.enable_spylnx", data: "bool", editable: true },
{ field: "bindSplynxApiKey", path: ".spylnx_integration.api_key", data: "string", editable: true },
{ field: "bindSplynxApiSecret", path: ".spylnx_integration.api_secret", data: "string", editable: true },
{ field: "bindSplynxApiUrl", path: ".spylnx_integration.url", data: "string", editable: true },
{ field: "bindUispEnable", path: ".uisp_integration.enable_uisp", data: "bool", editable: true },
{ field: "bindUispToken", path: ".uisp_integration.token", data: "string", editable: true },
{ field: "bindUispUrl", path: ".uisp_integration.url", data: "string", editable: true },
{ field: "bindUispSite", path: ".uisp_integration.site", data: "string", editable: true },
{ field: "bindUispStrategy", path: ".uisp_integration.strategy", data: "select-premade", editable: true },
{ field: "bindUispSuspended", path: ".uisp_integration.suspended_strategy", data: "select-premade", editable: true },
{ field: "bindUispAirmaxCapacity", path: ".uisp_integration.airmax_capacity", data: "float", editable: true },
{ field: "bindUispLtuCapacity", path: ".uisp_integration.ltu_capacity", data: "float", editable: true },
{ field: "bindUispIpv6Mikrotik", path: ".uisp_integration.ipv6_with_mikrotik", data: "bool", editable: true },
{ field: "bindUispOverheadFactor", path: ".uisp_integration.bandwidth_overhead_factor", data: "float", editable: true },
{ field: "bindUispCommitMultiplier", path: ".uisp_integration.commit_bandwidth_multiplier", data: "float", editable: true },
// Exclude Sites is handled specially
// Exception CPEs is handled specially
{ field: "bindUispUsePtmpAsParent", path: ".uisp_integration.use_ptmp_as_parent", data: "bool", editable: true },
{ field: "bindPowercodeEnable", path: ".powercode_integration.enable_powercode", data: "bool", editable: true },
{ field: "bindPowercodeKey", path: ".powercode_integration.powercode_api_key", data: "string", editable: true },
{ field: "bindPowercodeUrl", path: ".powercode_integration.powercode_api_url", data: "string", editable: true },
{ field: "bindSonarEnable", path: ".sonar_integration.enable_sonar", data: "bool", editable: true },
{ field: "bindSonarApiKey", path: ".sonar_integration.sonar_api_key", data: "string", editable: true },
{ field: "bindSonarApiUrl", path: ".sonar_integration.sonar_api_url", data: "string", editable: true },
{ field: "bindSonarSnmp", path: ".sonar_integration.snmp_community", data: "string", editable: true },
// Model IDs have to be handled specially
{ field: "bindInfluxEnable", path: ".influxdb.enable_influxdb", data: "bool", editable: true },
{ field: "bindInfluxUrl", path: ".influxdb.url", data: "string", editable: true },
{ field: "bindInfluxOrg", path: ".influxdb.org", data: "string", editable: true },
{ field: "bindInfluxBucket", path: ".influxdb.bucket", data: "string", editable: true },
{ field: "bindInfluxToken", path: ".influxdb.token", data: "string", editable: true },
];
function doBindings() {
for (var i=0; i<bindings.length; ++i) {
let entry = bindings[i];
let value_location = "lqosd_config" + entry.path;
let value = eval(value_location);
let controlId = "#" + entry.field;
if (entry.data === "bool") {
$(controlId).prop('checked', value);
} else if (entry.data === "selector-premade") {
$(controlId + " select").val(value);
} else {
$(controlId).val(value);
}
$(controlId).prop('readonly', !entry.editable);
}
}
function start() {
display();
colorReloadButton();
@ -432,117 +638,22 @@
} else {
// Handle Saving ispConfig.py
$("#btnSaveIspConfig").on('click', (data) => {
let new_config = python_config;
new_config.isp_interface = $("#nicCore").val();
new_config.internet_interface = $("#nicInternet").val();
new_config.on_a_stick_mode = $("#onAStick").prop('checked');
new_config.stick_vlans[0] = Number($("#StickVLANCore").val());
new_config.stick_vlans[1] = Number($("#StickVLANInternet").val());
new_config.sqm = $("#sqmMode").val();
new_config.total_download_mbps = Number($("#maxDownload").val());
new_config.total_upload_mbps = Number($("#maxUpload").val());
new_config.monitor_mode = $("#monitorMode").prop('checked');
new_config.generated_download_mbps = Number($("#generatedDownload").val());
new_config.generated_upload_mbps = Number($("#generatedUpload").val());
new_config.use_binpacking = $("#binpacking").prop('checked');
new_config.enable_shell_commands = $("#actualShellCommands").prop('checked');
new_config.run_as_sudo = $("#useSudo").prop('checked');
new_config.override_queue_count = Number($("#overrideQueues").val());
$.ajax({
type: "POST",
url: "/api/python_config",
data: JSON.stringify(new_config),
success: (data) => {
if (data == "ERROR") {
alert("Unable to create a first user.")
} else {
alert("Save Successful. Original backed up in ispConfig.py.backup. The window will now reload with the new configuration.");
window.location.reload()
}
}
})
// TODO
});
}
$.get("/api/python_config", (data) => {
python_config = data;
$.get("/api/lqosd_config", (data) => {
lqosd_config = data;
$.get("/api/list_nics", (data) => {
nics = data;
fillNicList("nicCore", python_config.isp_interface);
fillNicList("nicInternet", python_config.internet_interface);
$.get("/api/config", (data) => {
lqosd_config = data;
console.log(lqosd_config);
doBindings();
console.log("Bindings Done");
$.get("/api/list_nics", (data) => {
nics = data;
$("#onAStick").prop('checked', python_config.on_a_stick_mode);
$("#StickVLANCore").val(python_config.stick_vlans[0]);
$("#StickVLANInternet").val(python_config.stick_vlans[1]);
if (lqosd_config.bridge != null) {
$("#useKernelBridge").prop('checked', lqosd_config.bridge.use_xdp_bridge);
// Map Bifrost Interfaces
let html = "<h4>Interface Mapping</h4>";
html += "<table class='table'>";
html += "<thead><th>Input Interface</th><th>Output Interface</th><th>Scan VLANs?</th></thead>";
html += "<tbody>";
for (let i=0; i<lqosd_config.bridge.interface_mapping.length; i++) {
html += "<tr>";
html += "<td>" + buildNICList('bfIn_' + i, lqosd_config.bridge.interface_mapping[i].name, true) + "</td>";
html += "<td>" + buildNICList('bfOut_' + i, lqosd_config.bridge.interface_mapping[i].redirect_to, true) + "</td>";
html += "<td><input type='checkbox' class='form-check-input' id='bfScanVLAN_" + i + "'";
if (lqosd_config.bridge.interface_mapping[i].scan_vlans) {
html += ' checked';
}
html += " disabled='true' /></td>";
html += "</tr>";
}
html += "</tbody></table>";
$("#bifrostInterfaces").html(html);
// Map Bifrost VLAN mappings
html = "<h4>VLAN Mapping</h4>";
html += "<table class='table'>";
html += "<thead><th>Parent Interface</th><th>Input Tag</th><th>Remapped Tag</th></thead>";
html += "<tbody>";
for (let i=0; i<lqosd_config.bridge.vlan_mapping.length; i++) {
html += "<tr>";
html += "<td>" + buildNICList('bfvlanif_' + i, lqosd_config.bridge.vlan_mapping[i].parent, true) + "</td>";
html += "<td><input id='bfvlantag_" + i + "' type='number' min='0' max='4094' value='" + lqosd_config.bridge.vlan_mapping[i].tag + "' disabled='true' /></td>";
html += "<td><input id='bfvlanout_" + i + "' type='number' min='0' max='4094' value='" + lqosd_config.bridge.vlan_mapping[i].redirect_to + "' disabled='true' /></td>";
html += "</tr>";
}
html += "</tbody></table>";
$("#bifrostVlans").html(html);
}
$("#sqmMode option[value='" + python_config.sqm + "']").prop("selected", true);
$("#maxDownload").val(python_config.total_download_mbps);
$("#maxUpload").val(python_config.total_upload_mbps);
$("#monitorMode").prop('checked', python_config.monitor_mode);
$("#generatedDownload").val(python_config.generated_download_mbps);
$("#generatedUpload").val(python_config.generated_upload_mbps);
$("#binpacking").prop('checked', python_config.use_binpacking);
$("#queuecheckms").val(lqosd_config.queue_check_period_ms);
$("#actualShellCommands").prop('checked', python_config.enable_shell_commands);
$("#useSudo").prop('checked', python_config.run_as_sudo);
$("#overrideQueues").val(python_config.override_queue_count);
$("#stopIrqBalance").prop('checked', lqosd_config.tuning.stop_irq_balance);
$("#netDevUsec").val(lqosd_config.tuning.netdev_budget_usecs);
$("#netDevPackets").val(lqosd_config.tuning.netdev_budget_packets);
$("#rxUsecs").val(lqosd_config.tuning.rx_usecs);
$("#txUsecs").val(lqosd_config.tuning.tx_usecs);
$("#disableRxVlan").prop('checked', lqosd_config.tuning.disable_rxvlan);
$("#disableTxVlan").prop('checked', lqosd_config.tuning.disable_txvlan);
let offloads = "";
for (let i=0; i<lqosd_config.tuning.disable_offload.length; i++) {
offloads += lqosd_config.tuning.disable_offload[i] + " ";
}
$("#disableOffloadList").val(offloads);
// User management
if (is_admin) {
userManager();
tuning();
}
});
});
// User management
if (is_admin) {
userManager();
}
});
});
});
}
@ -552,34 +663,6 @@
$("#userManager").html(html);
}
function tuning() {
$("#btnApplyTuning").on('click', () => {
let period = Number($("#queuecheckms").val());
let new_config = {
stop_irq_balance: $("#stopIrqBalance").prop('checked'),
netdev_budget_usecs: Number($("#netDevUsec").val()),
netdev_budget_packets: Number($("#netDevPackets").val()),
rx_usecs: Number($("#rxUsecs").val()),
tx_usecs: Number($("#txUsecs").val()),
disable_rxvlan: $("#disableRxVlan").prop('checked'),
disable_txvlan: $("#disableTxVlan").prop('checked'),
disable_offload: $("#disableOffloadList").val().split(' ')
};
$.ajax({
type: "POST",
url: "/api/lqos_tuning/" + period,
data: JSON.stringify(new_config),
success: (data) => {
if (data == "ERROR") {
alert("Unable to apply settings.")
} else {
alert("Settings Applied");
}
}
})
});
}
function fillNicList(id, selected) {
let select = $("#" + id);
let html = "";