Merge pull request #359 from bile0026/start_readthedocs

Rebuild and aggregate documentation for Read the Docs
This commit is contained in:
Robert Chacón 2023-05-19 13:33:05 -06:00 committed by GitHub
commit 5e76084cd0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
208 changed files with 19558 additions and 76 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

4
.gitignore vendored
View File

@ -101,3 +101,7 @@ Sessionx.vim
tramp
.\#*
\#*
# virtual environments
.venv
venv

20
Makefile Normal file
View File

@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

View File

@ -2,11 +2,12 @@
LibreQoS is a Quality of Experience (QoE) Smart Queue Management (SQM) system designed for Internet Service Providers to optimize the flow of their network traffic and thus reduce bufferbloat, keep the network responsive, and improve the end-user experience.
Servers running LibreQoS can shape traffic for many thousands of customers.
Servers running LibreQoS can shape traffic for many thousands of customers.
Learn more at [LibreQoS.io](https://libreqos.io/)!
## Sponsors
Special thanks to Equinix for providing server resources to support the development of LibreQoS.
Learn more about [Equinix Metal here](https://deploy.equinix.com/metal/).
@ -14,98 +15,37 @@ Learn more about [Equinix Metal here](https://deploy.equinix.com/metal/).
Please support the continued development of LibreQoS by sponsoring us via [GitHub Sponsors](https://github.com/sponsors/LibreQoE) or [Patreon](https://patreon.com/libreqos).
## Documentation
[Docs](https://libreqos.readthedocs.io)
## Matrix Chat
Our Matrix chat channel is available at [https://matrix.to/#/#libreqos:matrix.org](https://matrix.to/#/#libreqos:matrix.org).
<img alt="LibreQoS" src="https://user-images.githubusercontent.com/22501920/223866474-603e1112-e2e6-4c67-93e4-44c17b1b7c43.png"></a>
## Features
### Flexible Hierarchical Shaping / Back-Haul Congestion Mitigation
<img src="https://raw.githubusercontent.com/LibreQoE/LibreQoS/main/docs/nestedHTB2.png" width="350"></img>
Starting in version v1.1+, operators can map their network hierarchy in LibreQoS. This enables both simple network hierarchies (Site>AP>Client) as well as much more complex ones (Site>Site>Micro-PoP>AP>Site>AP>Client). This can be used to ensure that a given sites peak bandwidth will not exceed the capacity of its back-haul links (back-haul congestion control). Operators can support more users on the same network equipment with LibreQoS than with competing QoE solutions which only shape by AP and Client.
### CAKE
CAKE is the product of nearly a decade of development efforts to improve on fq\_codel. With the diffserv\_4 parameter enabled CAKE groups traffic in to Bulk, Best Effort, Video, and Voice. This means that without having to fine-tune traffic priorities as you would with DPI products CAKE automatically ensures your clients OS update downloads will not disrupt their zoom calls. It allows for multiple video conferences to operate on the same connection which might otherwise “fight” for upload bandwidth causing call disruptions. With work-from-home, remote learning, and tele-medicine becoming increasingly common minimizing video call disruptions can save jobs, keep students engaged, and help ensure equitable access to medical care.
### XDP
Fast, multi-CPU queueing leveraging xdp-cpumap-tc and cpumap-pping. Currently tested in the real world past 11 Gbps (so far) with just 30% CPU use on a 16 core Intel Xeon Gold 6254. It's likely capable of 30Gbps or more.
### Graphing
You can graph bandwidth and TCP RTT by client and node (Site, AP, etc), using InfluxDB.
### CRM Integrations
* UISP
* Splynx
## Server Recommendations
It is most cost-effective to buy a used server with specifications matching your unique requirements, as laid out in the System Requirements section below.
For those who do not have the time to do that, here are some off-the-shelf options to consider:
* 1 Gbps | [Supermicro SuperServer E100-9W-L](https://www.thinkmate.com/system/superserver-e100-9w-l)
* 10 Gbps | [Supermicro SuperServer 510T-ML (Choose E-2388G)](https://www.thinkmate.com/system/superserver-510t-ml)
* 20 Gbps | [Dell R450 Config](https://www.dell.com/en-us/shop/servers-storage-and-networking/poweredge-r450-rack-server/spd/poweredge-r450/pe_r450_15127_vi_vp?configurationid=a7663c54-6e4a-4c96-9a21-bc5a69d637ba)
The [AsRock 1U4LW-B6502L2T](https://www.thinkmate.com/system/asrock-1u4lw-b6502l2t/635744) can be a great lower-cost option as well.
## System Requirements
### VM or physical server
* For VMs, NIC passthrough is required for optimal throughput and latency (XDP vs generic XDP). Using Virtio / bridging is much slower than NIC passthrough. Virtio / bridging should not be used for large amounts of traffic.
### CPU
* 2 or more CPU cores
* A CPU with solid [single-thread performance](https://www.cpubenchmark.net/singleThread.html#server-thread) within your budget. Queuing is very CPU-intensive, and requires high single-thread performance.
Single-thread CPU performance will determine the max throughput of a single HTB (cpu core), and in turn, what max speed plan you can offer customers.
| Customer Max Plan | Passmark Single-Thread |
| --------------------| ------------------------ |
| 100 Mbps | 1000 |
| 250 Mbps | 1500 |
| 500 Mbps | 2000 |
| 1 Gbps | 2500 |
| 2 Gbps | 3000 |
Below is a table of approximate aggregate throughput capacity, assuming a a CPU with a [single thread](https://www.cpubenchmark.net/singleThread.html#server-thread) performance of 2700 or greater:
| Aggregate Throughput | CPU Cores |
| ------------------------| ------------- |
| 500 Mbps | 2 |
| 1 Gbps | 4 |
| 5 Gbps | 6 |
| 10 Gbps | 8 |
| 20 Gbps | 16 |
| 50 Gbps* | 32 |
(* Estimated)
So for example, an ISP delivering 1Gbps service plans with 10Gbps aggregate throughput would choose a CPU with a 2500+ single-thread score and 8 cores, such as the Intel Xeon E-2388G @ 3.20GHz.
### Memory
* Minimum RAM = 2 + (0.002 x Subscriber Count) GB
* Recommended RAM:
| Subscribers | RAM |
| ------------- | ------------- |
| 100 | 4 GB |
| 1,000 | 8 GB |
| 5,000 | 16 GB |
| 10,000* | 18 GB |
| 50,000* | 24 GB |
(* Estimated)
### Network Interface Requirements
* One management network interface completely separate from the traffic shaping interfaces. Usually this would be the Ethernet interface built in to the motherboard.
* Dedicated Network Interface Card for Shaping Interfaces
* NIC must have 2 or more interfaces for traffic shaping.
* NIC must have multiple TX/RX transmit queues. [Here's how to check from the command line](https://serverfault.com/questions/772380/how-to-tell-if-nic-has-multiqueue-enabled).
* Known supported cards:
* [NVIDIA Mellanox MCX512A-ACAT](https://www.fs.com/products/119649.html)
* NVIDIA Mellanox MCX416A-CCAT
* [Intel X710](https://www.fs.com/products/75600.html)
* Intel X520
## Get Started
- [v1.4](https://github.com/LibreQoE/LibreQoS/wiki/v1.4)
- UISP
- Splynx

BIN
_build/.DS_Store vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

4
_build/html/.buildinfo Normal file
View File

@ -0,0 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: 8d3e45e0860d7625d69fe0179331271f
tags: 645f666f9bcd5a90fca523b33c5a78b7

254
_build/html/.github/CODE_OF_CONDUCT.html vendored Normal file
View File

@ -0,0 +1,254 @@
<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Contributor Covenant Code of Conduct &mdash; LibreQoE documentation</title>
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
<!--[if lt IE 9]>
<script src="../_static/js/html5shiv.min.js"></script>
<![endif]-->
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/sphinx_highlight.js"></script>
<script src="../_static/js/theme.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="../index.html" class="icon icon-home">
LibreQoE
</a>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<p class="caption" role="heading"><span class="caption-text">Readme:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../README.html">Sponsors</a></li>
<li class="toctree-l1"><a class="reference internal" href="../README.html#support-libreqos">Support LibreQoS</a></li>
<li class="toctree-l1"><a class="reference internal" href="../README.html#documentation">Documentation</a></li>
<li class="toctree-l1"><a class="reference internal" href="../README.html#matrix-chat">Matrix Chat</a></li>
<li class="toctree-l1"><a class="reference internal" href="../README.html#features">Features</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Read me first!</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../docs/Quickstart/networkdesignassumptions.html">Network Design Assumptions</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Change Notes:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../docs/ChangeNotes/v1.4.html">LibreQoS v1.3.1 to v1.4 Change Summary</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Quickstart:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../docs/SystemRequirements/Compute.html">System Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="../docs/SystemRequirements/Networking.html">Network Interface Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="../docs/Quickstart/quickstart-prereq.html">Server Setup - Pre-requisites</a></li>
<li class="toctree-l1"><a class="reference internal" href="../docs/Quickstart/quickstart-libreqos-1.4.html">Install LibreQoS 1.4</a></li>
<li class="toctree-l1"><a class="reference internal" href="../docs/Quickstart/share.html">Share your before and after</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Updates:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../docs/Updates/update.html">Updating 1.4 To Latest Version</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Technical Documentation:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../docs/TechnicalDocs/troubleshooting.html">Troubleshooting</a></li>
<li class="toctree-l1"><a class="reference internal" href="../docs/TechnicalDocs/integrations.html">Integrations</a></li>
<li class="toctree-l1"><a class="reference internal" href="../docs/TechnicalDocs/extras.html">Extras</a></li>
<li class="toctree-l1"><a class="reference internal" href="../docs/TechnicalDocs/performance-tuning.html">Performance Tuning</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Legacy:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../docs/Legacy/v1.3.1.html">LibreQoS v1.3.1</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../index.html">LibreQoE</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="../index.html" class="icon icon-home" aria-label="Home"></a></li>
<li class="breadcrumb-item active">Contributor Covenant Code of Conduct</li>
<li class="wy-breadcrumbs-aside">
<a href="../_sources/.github/CODE_OF_CONDUCT.md.txt" rel="nofollow"> View page source</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<section id="contributor-covenant-code-of-conduct">
<h1>Contributor Covenant Code of Conduct<a class="headerlink" href="#contributor-covenant-code-of-conduct" title="Permalink to this heading"></a></h1>
<section id="our-pledge">
<h2>Our Pledge<a class="headerlink" href="#our-pledge" title="Permalink to this heading"></a></h2>
<p>We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.</p>
<p>We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.</p>
</section>
<section id="our-standards">
<h2>Our Standards<a class="headerlink" href="#our-standards" title="Permalink to this heading"></a></h2>
<p>Examples of behavior that contributes to a positive environment for our
community include:</p>
<ul class="simple">
<li><p>Demonstrating empathy and kindness toward other people</p></li>
<li><p>Being respectful of differing opinions, viewpoints, and experiences</p></li>
<li><p>Giving and gracefully accepting constructive feedback</p></li>
<li><p>Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience</p></li>
<li><p>Focusing on what is best not just for us as individuals, but for the
overall community</p></li>
</ul>
<p>Examples of unacceptable behavior include:</p>
<ul class="simple">
<li><p>The use of sexualized language or imagery, and sexual attention or
advances of any kind</p></li>
<li><p>Trolling, insulting or derogatory comments, and personal or political attacks</p></li>
<li><p>Public or private harassment</p></li>
<li><p>Publishing others private information, such as a physical or email
address, without their explicit permission</p></li>
<li><p>Other conduct which could reasonably be considered inappropriate in a
professional setting</p></li>
</ul>
</section>
<section id="enforcement-responsibilities">
<h2>Enforcement Responsibilities<a class="headerlink" href="#enforcement-responsibilities" title="Permalink to this heading"></a></h2>
<p>Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.</p>
<p>Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.</p>
</section>
<section id="scope">
<h2>Scope<a class="headerlink" href="#scope" title="Permalink to this heading"></a></h2>
<p>This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.</p>
</section>
<section id="enforcement">
<h2>Enforcement<a class="headerlink" href="#enforcement" title="Permalink to this heading"></a></h2>
<p>Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
robert&#64;libreqos.io.
All complaints will be reviewed and investigated promptly and fairly.</p>
<p>All community leaders are obligated to respect the privacy and security of the
reporter of any incident.</p>
</section>
<section id="enforcement-guidelines">
<h2>Enforcement Guidelines<a class="headerlink" href="#enforcement-guidelines" title="Permalink to this heading"></a></h2>
<p>Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:</p>
<section id="correction">
<h3>1. Correction<a class="headerlink" href="#correction" title="Permalink to this heading"></a></h3>
<p><strong>Community Impact</strong>: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.</p>
<p><strong>Consequence</strong>: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.</p>
</section>
<section id="warning">
<h3>2. Warning<a class="headerlink" href="#warning" title="Permalink to this heading"></a></h3>
<p><strong>Community Impact</strong>: A violation through a single incident or series
of actions.</p>
<p><strong>Consequence</strong>: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.</p>
</section>
<section id="temporary-ban">
<h3>3. Temporary Ban<a class="headerlink" href="#temporary-ban" title="Permalink to this heading"></a></h3>
<p><strong>Community Impact</strong>: A serious violation of community standards, including
sustained inappropriate behavior.</p>
<p><strong>Consequence</strong>: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.</p>
</section>
<section id="permanent-ban">
<h3>4. Permanent Ban<a class="headerlink" href="#permanent-ban" title="Permalink to this heading"></a></h3>
<p><strong>Community Impact</strong>: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.</p>
<p><strong>Consequence</strong>: A permanent ban from any sort of public interaction within
the community.</p>
</section>
</section>
<section id="attribution">
<h2>Attribution<a class="headerlink" href="#attribution" title="Permalink to this heading"></a></h2>
<p>This Code of Conduct is adapted from the <a class="reference external" href="https://www.contributor-covenant.org">Contributor Covenant</a>,
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.</p>
<p>Community Impact Guidelines were inspired by <a class="reference external" href="https://github.com/mozilla/diversity">Mozillas code of conduct
enforcement ladder</a>.</p>
<p>For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.</p>
</section>
</section>
</div>
</div>
<footer>
<hr/>
<div role="contentinfo">
<p>&#169; Copyright 2023, LibreQoE.</p>
</div>
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>

View File

@ -0,0 +1,337 @@
<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Contributing to LibreQoS &mdash; LibreQoE documentation</title>
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<!--[if lt IE 9]>
<script src="_static/js/html5shiv.min.js"></script>
<![endif]-->
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
<script src="_static/doctools.js"></script>
<script src="_static/sphinx_highlight.js"></script>
<script src="_static/js/theme.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="index.html" class="icon icon-home">
LibreQoE
</a>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="search.html" method="get">
<input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<p class="caption" role="heading"><span class="caption-text">Readme:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="README.html">Sponsors</a></li>
<li class="toctree-l1"><a class="reference internal" href="README.html#support-libreqos">Support LibreQoS</a></li>
<li class="toctree-l1"><a class="reference internal" href="README.html#documentation">Documentation</a></li>
<li class="toctree-l1"><a class="reference internal" href="README.html#matrix-chat">Matrix Chat</a></li>
<li class="toctree-l1"><a class="reference internal" href="README.html#features">Features</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Read me first!</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="docs/Quickstart/networkdesignassumptions.html">Network Design Assumptions</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Change Notes:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="docs/ChangeNotes/v1.4.html">LibreQoS v1.3.1 to v1.4 Change Summary</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Quickstart:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="docs/SystemRequirements/Compute.html">System Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="docs/SystemRequirements/Networking.html">Network Interface Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="docs/Quickstart/quickstart-prereq.html">Server Setup - Pre-requisites</a></li>
<li class="toctree-l1"><a class="reference internal" href="docs/Quickstart/quickstart-libreqos-1.4.html">Install LibreQoS 1.4</a></li>
<li class="toctree-l1"><a class="reference internal" href="docs/Quickstart/share.html">Share your before and after</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Updates:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="docs/Updates/update.html">Updating 1.4 To Latest Version</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Technical Documentation:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="docs/TechnicalDocs/troubleshooting.html">Troubleshooting</a></li>
<li class="toctree-l1"><a class="reference internal" href="docs/TechnicalDocs/integrations.html">Integrations</a></li>
<li class="toctree-l1"><a class="reference internal" href="docs/TechnicalDocs/extras.html">Extras</a></li>
<li class="toctree-l1"><a class="reference internal" href="docs/TechnicalDocs/performance-tuning.html">Performance Tuning</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Legacy:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="docs/Legacy/v1.3.1.html">LibreQoS v1.3.1</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="index.html">LibreQoE</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="index.html" class="icon icon-home" aria-label="Home"></a></li>
<li class="breadcrumb-item active">Contributing to LibreQoS</li>
<li class="wy-breadcrumbs-aside">
<a href="_sources/CONTRIBUTING.md.txt" rel="nofollow"> View page source</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<blockquote>
<div><p>This is <strong>draft 1</strong> of the contributing guide. Comments/edits appreciated.</p>
</div></blockquote>
<section id="contributing-to-libreqos">
<h1>Contributing to LibreQoS<a class="headerlink" href="#contributing-to-libreqos" title="Permalink to this heading"></a></h1>
<p>So your interested in contributing to LibreQoS! Awesome! Feel free to pitch in with whatever interests you, and well be happy to help.</p>
<p>Check out our <a class="reference external" href="https://github.com/LibreQoE/LibreQoS/blob/main/.github/CODE_OF_CONDUCT.md">Code of Conduct</a>, wed like to keep this a happy, constructive place. Also, please join the chat on <a class="reference external" href="https://app.element.io/#/room/#libreqos:matrix.org">Matrix</a>—the core developers hang out there, and will be happy to help you.</p>
<p>In particular:</p>
<ul class="simple">
<li><p>We can check that an issue isnt already being worked on. Theres nothing more frustrating than working hard on an issue only to discover that someone else already fixed it!</p></li>
<li><p>We can help point you at issues that might interest you.</p></li>
<li><p>We can offer help and/or mentoring with Rust and C.</p></li>
</ul>
</section>
<section id="how-you-can-help">
<h1>How You Can Help<a class="headerlink" href="#how-you-can-help" title="Permalink to this heading"></a></h1>
<p>Theres lots of ways you can help:</p>
<ul class="simple">
<li><p><strong>Battle-Testing LibreQos</strong>: use the software, let us know what does/doesnt work!</p></li>
<li><p><strong>Donate</strong>: its free software, but we appreciate your support.</p></li>
<li><p><strong>Let us Know Your Thoughts</strong>: Hop on the chat or our discussions page and let us know what youre thinking about.</p></li>
<li><p><strong>Finding Bugs</strong> - something doesnt work for you? We cant fix it if you dont tell us about it.</p></li>
<li><p><strong>Fixing Bugs</strong> and <strong>Adding Features</strong>: See the “Development Guide”, below.</p></li>
<li><p><strong>Teaching Others</strong>: if LibreQoS is working well for you, you can help others benefit by sharing your experience. See someone struggling? Feel free to pitch in and help them.</p></li>
</ul>
<p>LibreQos strive to create an open, friendly environment. If you have an idea for how to help, let us know.</p>
</section>
<section id="development-guidelines">
<h1>Development Guidelines<a class="headerlink" href="#development-guidelines" title="Permalink to this heading"></a></h1>
<p>This section contains some advice to help get you started writing code for LibreQoS.</p>
<section id="getting-oriented-with-libreqos">
<h2>Getting Oriented with LibreQoS<a class="headerlink" href="#getting-oriented-with-libreqos" title="Permalink to this heading"></a></h2>
<p>LibreQos is divided into several sections:</p>
<ul class="simple">
<li><p><strong>Rust: system management/control plane</strong></p>
<ul>
<li><p><strong>System Daemons</strong></p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">lqosd</span></code> is probably the most important part of the Rust system. It loads the eBPF system that provides bridging and traffic shaping control, runs the “bus” for other systems to communicate, and gathers information directly from the eBPF and kernel systems. It has several sub-crates:</p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">lqos_heimdall</span></code> handles all of the packet sniffing, flow tracking and <code class="docutils literal notranslate"><span class="pre">libcap</span></code> compatible packet data.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">lqos_queue_tracker</span></code> maintains statistics for Linux <code class="docutils literal notranslate"><span class="pre">tc</span></code> shaping queues, particularly Cake.</p></li>
</ul>
</li>
<li><p><code class="docutils literal notranslate"><span class="pre">lqos_node_manager</span></code> provides a per-node management web interface. It gathers most of its data from <code class="docutils literal notranslate"><span class="pre">lqosd</span></code> via the bus.</p></li>
</ul>
</li>
<li><p><strong>CLI Utilities</strong></p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">lqusers</span></code> provides a CLI interface for managing authentication to the node manager.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">lqtop</span></code> provides a quick and easy way to see what the shaper is doing from the local management console.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">xdp_iphash_to_cpu_cmdline</span></code> (the name is inherited from previous projects) provides a command-line interface to map IP subnets to TC and CPU handles.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">xdp_pping</span></code> provides a CLI tool to give a quick summary of TCP RTT times, grouped by TC handle.</p></li>
</ul>
</li>
<li><p><strong>Libraries</strong></p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">lqos_bus</span></code> provides a local-only (never leaving the shaper node) inter-process communication system. Its used by programs that need to ask <code class="docutils literal notranslate"><span class="pre">lqosd</span></code> to do something, or retrieve information from it.</p>
<ul>
<li><p>The <code class="docutils literal notranslate"><span class="pre">lqos_bus</span></code> crate also acts as a repository for shared data structures when data is passed between portions of the program.</p></li>
</ul>
</li>
<li><p><code class="docutils literal notranslate"><span class="pre">lqos_config</span></code> manages Rust integration with the <code class="docutils literal notranslate"><span class="pre">ispConfig.py</span></code> configuration file, and the <code class="docutils literal notranslate"><span class="pre">/etc/lqos.conf</span></code> file. It is designed as a helper for other systems to quickly access configuration parameters.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">lqos_python</span></code> compiles into a Python loadable library, providing a convenient interface to Rust code from the Python portions of the program.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">lqos_setup</span></code> provides a text-based initial setup system for users who install LibreQoS via <code class="docutils literal notranslate"><span class="pre">apt-get</span></code>.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">lqos_utils</span></code> provides a grab-bag of handy functions weve found useful elsewhere in the system.</p></li>
</ul>
</li>
</ul>
</li>
<li><p><strong>Python: system operation and integration</strong></p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">LibreQoS.py</span></code> maps all circuits to TC handles and gets the shaper system running.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">ispConfig.py</span></code> provides a system-wide configuration.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">integrationX.py</span></code> provide integrations with UISP, Spylnx and other CRM tools.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">lqTools.py</span></code> provides an interface for gathering statistics.</p></li>
</ul>
</li>
</ul>
</section>
<section id="what-we-re-building">
<h2>What Were Building<a class="headerlink" href="#what-we-re-building" title="Permalink to this heading"></a></h2>
<p>LibreQoS is a free/open source fair queueing system. Its designed for ISPs, but can be useful elsewhere. Primary goals:</p>
<ul class="simple">
<li><p>Provide fair-queueing to help maximize the use of the Internet resources you have.</p></li>
<li><p>Keep end-user latency low.</p></li>
<li><p>Dont alter user traffic (for example by lowering the quality of their streaming video).</p></li>
<li><p>Dont invade users privacy.</p></li>
<li><p>Provide excellent support tools to help keep your ISP running smoothly.</p></li>
</ul>
<p>Some secondary goals include:</p>
<ul class="simple">
<li><p>Visualize data to facilitate moving the state-of-the-art in fair queueing forwards.</p></li>
<li><p>Provide amazing throughput on inexpensive hardware.</p></li>
</ul>
</section>
<section id="making-changes-to-libreqos">
<h2>Making Changes to LibreQoS<a class="headerlink" href="#making-changes-to-libreqos" title="Permalink to this heading"></a></h2>
<p>We try to remain fast-moving and “process light”.</p>
<blockquote>
<div><p>When we use the word “agile”, we dont mean the heavily formalized process with scrums, kanban boards and similar. We mean lightweight, fast moving, and adhering to useful guides like “Code Complete” and “The Pragmatic Programmer”. Not getting bogged down in heavy process.</p>
</div></blockquote>
<section id="simple-changes">
<h3>Simple Changes<a class="headerlink" href="#simple-changes" title="Permalink to this heading"></a></h3>
<p>For a straightforward change, do the following:</p>
<ol class="arabic simple">
<li><p>Do one (or more!) of the following:</p>
<ul class="simple">
<li><p>Let us know on the chat that youre working on it.</p></li>
<li><p>Create an Issue in our GitHub repo.</p></li>
<li><p>Submit a PR, following the Branch Guidelines below.</p></li>
</ul>
</li>
<li><p>Other community members review and comment on your change in an informal manner.</p></li>
<li><p>Once consensus is reached, well merge to the <code class="docutils literal notranslate"><span class="pre">develop</span></code> branch (or a branch parented from <code class="docutils literal notranslate"><span class="pre">develop</span></code> if its a big change) and test it on our server resources at Equinix.</p></li>
<li><p>When ready, well merge it into the next release.</p></li>
</ol>
</section>
<section id="complex-changes">
<h3>Complex Changes<a class="headerlink" href="#complex-changes" title="Permalink to this heading"></a></h3>
<p>If you need/want a complicated change, please get in touch with us on the Matrix chat first. Wed like to avoid duplicating effort and wasting anyones time. Well be happy to offer advice and guidance. Then the process is similar:</p>
<ol class="arabic simple">
<li><p>Work on your local branch, parented off of <code class="docutils literal notranslate"><span class="pre">develop</span></code>.</p></li>
<li><p>Create a PR (targeting <code class="docutils literal notranslate"><span class="pre">develop</span></code>). If youd like interim feedback, create a “draft PR” and we can help test your branch before the PR finalizes.</p></li>
<li><p>Once your PR is ready, submit it.</p></li>
<li><p>The community will review/comment on your PR.</p></li>
<li><p>Once consensus is reached, well merge it into <code class="docutils literal notranslate"><span class="pre">develop</span></code>.</p></li>
<li><p>Once ready, <code class="docutils literal notranslate"><span class="pre">develop</span></code> will merge into <code class="docutils literal notranslate"><span class="pre">main</span></code>.</p></li>
</ol>
</section>
</section>
<section id="branch-guidelines">
<h2>Branch Guidelines<a class="headerlink" href="#branch-guidelines" title="Permalink to this heading"></a></h2>
<p>LibreQoS has adopted the following scheme for branches:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">main</span></code> - released code (tagged at releases), safe to pull.</p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">develop</span></code> - Parented from <code class="docutils literal notranslate"><span class="pre">main</span></code> and rebased on release. Nothing gets directly comitted into <code class="docutils literal notranslate"><span class="pre">develop</span></code>, its the parent tree for ongoing development work.</p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">my_feature</span></code> - if youre working on a feature, your feature branch goes here - with <code class="docutils literal notranslate"><span class="pre">develop</span></code> as the parent. PRs—once the feature is ready for inclusion—should be targeted at <code class="docutils literal notranslate"><span class="pre">develop</span></code>.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">issue_xxx_name</span></code> - if youre working on a bugfix, work on it in a branch here. When the issue resolution is complete, PRs should be targeted at <code class="docutils literal notranslate"><span class="pre">develop</span></code>.</p></li>
</ul>
</li>
<li><p><code class="docutils literal notranslate"><span class="pre">hotfix_xxx</span></code> - If an emergency occurs and you have to push a fix to <code class="docutils literal notranslate"><span class="pre">main</span></code> in a hurry, hotfix branches can be parented from <code class="docutils literal notranslate"><span class="pre">main</span></code>. The resulting PR should target <code class="docutils literal notranslate"><span class="pre">main</span></code>. Let the developers know that they need to rebase <code class="docutils literal notranslate"><span class="pre">develop</span></code>.</p></li>
</ul>
</li>
</ul>
<p>The goal is for <code class="docutils literal notranslate"><span class="pre">main</span></code> to <em>always</em> be safe to clone and run, without surprises.</p>
</section>
<section id="code-guidelines">
<h2>Code Guidelines<a class="headerlink" href="#code-guidelines" title="Permalink to this heading"></a></h2>
<p>This is very much a work in progress.</p>
<section id="rust">
<h3>Rust<a class="headerlink" href="#rust" title="Permalink to this heading"></a></h3>
<section id="code-formatting">
<h4>Code Formatting<a class="headerlink" href="#code-formatting" title="Permalink to this heading"></a></h4>
<ul class="simple">
<li><p>Use <code class="docutils literal notranslate"><span class="pre">cargo</span> <span class="pre">fmt</span></code> to format your code. Weve got a customized format setup in place.</p></li>
<li><p>Adhere to standard Rust case and naming guidelines.</p></li>
</ul>
</section>
<section id="dependencies">
<h4>Dependencies<a class="headerlink" href="#dependencies" title="Permalink to this heading"></a></h4>
<ul class="simple">
<li><p>Check that you arent including any dependencies that incompatible with our license—GPL v2.</p></li>
<li><p>Look through the <code class="docutils literal notranslate"><span class="pre">Cargo.toml</span></code> files (or run <code class="docutils literal notranslate"><span class="pre">cargo</span> <span class="pre">tree</span></code>) and try to prefer using a dependency we use elsewhere.</p></li>
<li><p>Try to avoid using unmaintained crates.</p></li>
</ul>
</section>
<section id="naming">
<h4>Naming<a class="headerlink" href="#naming" title="Permalink to this heading"></a></h4>
<ul class="simple">
<li><p>Dont use short, incomprehensible names in any API or function accessible from outside. You dont save any RAM by naming your variable <code class="docutils literal notranslate"><span class="pre">sz</span></code> instead of <code class="docutils literal notranslate"><span class="pre">size</span></code>—you just make it harder for anyone reading the code.</p></li>
<li><p>Its fine to use <code class="docutils literal notranslate"><span class="pre">i</span></code> and similar for internal counting iterators. Try to use meaningful names for everything else.</p></li>
</ul>
</section>
<section id="code-style">
<h4>Code Style<a class="headerlink" href="#code-style" title="Permalink to this heading"></a></h4>
<ul class="simple">
<li><p>Prefer functional/iterative code to imperative. Sometimes you need a <code class="docutils literal notranslate"><span class="pre">for</span></code> loop, but if it can be replaced with an <code class="docutils literal notranslate"><span class="pre">iter</span></code>, <code class="docutils literal notranslate"><span class="pre">map</span></code> and <code class="docutils literal notranslate"><span class="pre">fold</span></code> it will both compile into faster code and be less error prone.</p></li>
<li><p>Its better to have lots of small functions than one big one. Rust is really good at inlining, and its much easier to understand short functions. Its also easier to test small functions.</p></li>
<li><p>If you have to override a Clippy warning, add a comment explaining why you did so.</p></li>
<li><p>Functions accessible from other crates should use the RustDoc standard for documentation.</p></li>
</ul>
</section>
<section id="unit-tests">
<h4>Unit Tests<a class="headerlink" href="#unit-tests" title="Permalink to this heading"></a></h4>
<ul class="simple">
<li><p>If you fix an issue, and its testable: add a unit test to check that we dont regress and suffer from that bug again.</p></li>
<li><p>If you create a type, write unit tests to test its constraints.</p></li>
</ul>
</section>
<section id="error-handling">
<h4>Error Handling<a class="headerlink" href="#error-handling" title="Permalink to this heading"></a></h4>
<ul class="simple">
<li><p>Use <code class="docutils literal notranslate"><span class="pre">thiserror</span></code> to emit readable error messages from your functions.</p></li>
<li><p>Its fine to use <code class="docutils literal notranslate"><span class="pre">?</span></code> and <code class="docutils literal notranslate"><span class="pre">anyhow</span></code> inside function chains; prefer <code class="docutils literal notranslate"><span class="pre">result.map_err</span></code> to transform your errors into your own errors whenever its possible that an error can be returned from a function accessible beyond the immediate crate.</p></li>
<li><p>Issue a <code class="docutils literal notranslate"><span class="pre">log::error!</span></code> or <code class="docutils literal notranslate"><span class="pre">log::warn!</span></code> messaage when an error occurs. Dont trust the callee to do it for you. Its better to have duplicate error messages than none at all.</p></li>
</ul>
</section>
</section>
</section>
</section>
</div>
</div>
<footer>
<hr/>
<div role="contentinfo">
<p>&#169; Copyright 2023, LibreQoE.</p>
</div>
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>

195
_build/html/README.html Normal file
View File

@ -0,0 +1,195 @@
<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Sponsors &mdash; LibreQoE documentation</title>
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<!--[if lt IE 9]>
<script src="_static/js/html5shiv.min.js"></script>
<![endif]-->
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
<script src="_static/doctools.js"></script>
<script src="_static/sphinx_highlight.js"></script>
<script src="_static/js/theme.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Network Design Assumptions" href="docs/Quickstart/networkdesignassumptions.html" />
<link rel="prev" title="Welcome to the LibreQoS documentation!" href="index.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="index.html" class="icon icon-home">
LibreQoE
</a>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="search.html" method="get">
<input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<p class="caption" role="heading"><span class="caption-text">Readme:</span></p>
<ul class="current">
<li class="toctree-l1 current"><a class="current reference internal" href="#">Sponsors</a></li>
<li class="toctree-l1"><a class="reference internal" href="#support-libreqos">Support LibreQoS</a></li>
<li class="toctree-l1"><a class="reference internal" href="#documentation">Documentation</a></li>
<li class="toctree-l1"><a class="reference internal" href="#matrix-chat">Matrix Chat</a></li>
<li class="toctree-l1"><a class="reference internal" href="#features">Features</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#flexible-hierarchical-shaping-back-haul-congestion-mitigation">Flexible Hierarchical Shaping / Back-Haul Congestion Mitigation</a></li>
<li class="toctree-l2"><a class="reference internal" href="#cake">CAKE</a></li>
<li class="toctree-l2"><a class="reference internal" href="#xdp">XDP</a></li>
<li class="toctree-l2"><a class="reference internal" href="#graphing">Graphing</a></li>
<li class="toctree-l2"><a class="reference internal" href="#crm-integrations">CRM Integrations</a></li>
</ul>
</li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Read me first!</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="docs/Quickstart/networkdesignassumptions.html">Network Design Assumptions</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Change Notes:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="docs/ChangeNotes/v1.4.html">LibreQoS v1.3.1 to v1.4 Change Summary</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Quickstart:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="docs/SystemRequirements/Compute.html">System Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="docs/SystemRequirements/Networking.html">Network Interface Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="docs/Quickstart/quickstart-prereq.html">Server Setup - Pre-requisites</a></li>
<li class="toctree-l1"><a class="reference internal" href="docs/Quickstart/quickstart-libreqos-1.4.html">Install LibreQoS 1.4</a></li>
<li class="toctree-l1"><a class="reference internal" href="docs/Quickstart/share.html">Share your before and after</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Updates:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="docs/Updates/update.html">Updating 1.4 To Latest Version</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Technical Documentation:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="docs/TechnicalDocs/troubleshooting.html">Troubleshooting</a></li>
<li class="toctree-l1"><a class="reference internal" href="docs/TechnicalDocs/integrations.html">Integrations</a></li>
<li class="toctree-l1"><a class="reference internal" href="docs/TechnicalDocs/extras.html">Extras</a></li>
<li class="toctree-l1"><a class="reference internal" href="docs/TechnicalDocs/performance-tuning.html">Performance Tuning</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Legacy:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="docs/Legacy/v1.3.1.html">LibreQoS v1.3.1</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="index.html">LibreQoE</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="index.html" class="icon icon-home" aria-label="Home"></a></li>
<li class="breadcrumb-item active">Sponsors</li>
<li class="wy-breadcrumbs-aside">
<a href="_sources/README.md.txt" rel="nofollow"> View page source</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<p><a href="https://libreqos.io/"><img alt="LibreQoS" src="https://user-images.githubusercontent.com/22501920/202913614-4ff2e506-e645-4a94-9918-d512905ab290.png"></a></p>
<p>LibreQoS is a Quality of Experience (QoE) Smart Queue Management (SQM) system designed for Internet Service Providers to optimize the flow of their network traffic and thus reduce bufferbloat, keep the network responsive, and improve the end-user experience.</p>
<p>Servers running LibreQoS can shape traffic for many thousands of customers.</p>
<p>Learn more at <a class="reference external" href="https://libreqos.io/">LibreQoS.io</a>!</p>
<section id="sponsors">
<h1>Sponsors<a class="headerlink" href="#sponsors" title="Permalink to this heading"></a></h1>
<p>Special thanks to Equinix for providing server resources to support the development of LibreQoS.
Learn more about <a class="reference external" href="https://deploy.equinix.com/metal/">Equinix Metal here</a>.</p>
</section>
<section id="support-libreqos">
<h1>Support LibreQoS<a class="headerlink" href="#support-libreqos" title="Permalink to this heading"></a></h1>
<p>Please support the continued development of LibreQoS by sponsoring us via <a class="reference external" href="https://github.com/sponsors/LibreQoE">GitHub Sponsors</a> or <a class="reference external" href="https://patreon.com/libreqos">Patreon</a>.</p>
</section>
<section id="documentation">
<h1>Documentation<a class="headerlink" href="#documentation" title="Permalink to this heading"></a></h1>
<p><a class="reference external" href="https://libreqos.readthedocs.io">Docs</a></p>
</section>
<section id="matrix-chat">
<h1>Matrix Chat<a class="headerlink" href="#matrix-chat" title="Permalink to this heading"></a></h1>
<p>Our Matrix chat channel is available at <a class="reference external" href="https://matrix.to/#/#libreqos:matrix.org">https://matrix.to/#/#libreqos:matrix.org</a>.</p>
<p><img alt="LibreQoS" src="https://user-images.githubusercontent.com/22501920/223866474-603e1112-e2e6-4c67-93e4-44c17b1b7c43.png"></a></p>
</section>
<section id="features">
<h1>Features<a class="headerlink" href="#features" title="Permalink to this heading"></a></h1>
<section id="flexible-hierarchical-shaping-back-haul-congestion-mitigation">
<h2>Flexible Hierarchical Shaping / Back-Haul Congestion Mitigation<a class="headerlink" href="#flexible-hierarchical-shaping-back-haul-congestion-mitigation" title="Permalink to this heading"></a></h2>
<p><img src="https://raw.githubusercontent.com/LibreQoE/LibreQoS/main/docs/nestedHTB2.png" width="350"></img></p>
<p>Starting in version v1.1+, operators can map their network hierarchy in LibreQoS. This enables both simple network hierarchies (Site&gt;AP&gt;Client) as well as much more complex ones (Site&gt;Site&gt;Micro-PoP&gt;AP&gt;Site&gt;AP&gt;Client). This can be used to ensure that a given sites peak bandwidth will not exceed the capacity of its back-haul links (back-haul congestion control). Operators can support more users on the same network equipment with LibreQoS than with competing QoE solutions which only shape by AP and Client.</p>
</section>
<section id="cake">
<h2>CAKE<a class="headerlink" href="#cake" title="Permalink to this heading"></a></h2>
<p>CAKE is the product of nearly a decade of development efforts to improve on fq_codel. With the diffserv_4 parameter enabled CAKE groups traffic in to Bulk, Best Effort, Video, and Voice. This means that without having to fine-tune traffic priorities as you would with DPI products CAKE automatically ensures your clients OS update downloads will not disrupt their zoom calls. It allows for multiple video conferences to operate on the same connection which might otherwise “fight” for upload bandwidth causing call disruptions. With work-from-home, remote learning, and tele-medicine becoming increasingly common minimizing video call disruptions can save jobs, keep students engaged, and help ensure equitable access to medical care.</p>
</section>
<section id="xdp">
<h2>XDP<a class="headerlink" href="#xdp" title="Permalink to this heading"></a></h2>
<p>Fast, multi-CPU queueing leveraging xdp-cpumap-tc and cpumap-pping. Currently tested in the real world past 11 Gbps (so far) with just 30% CPU use on a 16 core Intel Xeon Gold 6254. Its likely capable of 30Gbps or more.</p>
</section>
<section id="graphing">
<h2>Graphing<a class="headerlink" href="#graphing" title="Permalink to this heading"></a></h2>
<p>You can graph bandwidth and TCP RTT by client and node (Site, AP, etc), using InfluxDB.</p>
</section>
<section id="crm-integrations">
<h2>CRM Integrations<a class="headerlink" href="#crm-integrations" title="Permalink to this heading"></a></h2>
<ul class="simple">
<li><p>UISP</p></li>
<li><p>Splynx</p></li>
</ul>
</section>
</section>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="index.html" class="btn btn-neutral float-left" title="Welcome to the LibreQoS documentation!" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="docs/Quickstart/networkdesignassumptions.html" class="btn btn-neutral float-right" title="Network Design Assumptions" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>
<div role="contentinfo">
<p>&#169; Copyright 2023, LibreQoE.</p>
</div>
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

View File

@ -0,0 +1,128 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
robert@libreqos.io.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.

View File

@ -0,0 +1,155 @@
> This is **draft 1** of the contributing guide. Comments/edits appreciated.
# Contributing to LibreQoS
So your interested in contributing to LibreQoS! Awesome! Feel free to pitch in with whatever interests you, and we'll be happy to help.
Check out our [Code of Conduct](https://github.com/LibreQoE/LibreQoS/blob/main/.github/CODE_OF_CONDUCT.md), we'd like to keep this a happy, constructive place. Also, please join the chat on [Matrix](https://app.element.io/#/room/#libreqos:matrix.org)---the core developers hang out there, and will be happy to help you.
In particular:
* We can check that an issue isn't already being worked on. There's nothing more frustrating than working hard on an issue only to discover that someone else already fixed it!
* We can help point you at issues that might interest you.
* We can offer help and/or mentoring with Rust and C.
# How You Can Help
There's lots of ways you can help:
* **Battle-Testing LibreQos**: use the software, let us know what does/doesn't work!
* **Donate**: it's free software, but we appreciate your support.
* **Let us Know Your Thoughts**: Hop on the chat or our discussions page and let us know what you're thinking about.
* **Finding Bugs** - something doesn't work for you? We can't fix it if you don't tell us about it.
* **Fixing Bugs** and **Adding Features**: See the "Development Guide", below.
* **Teaching Others**: if LibreQoS is working well for you, you can help others benefit by sharing your experience. See someone struggling? Feel free to pitch in and help them.
LibreQos strive to create an open, friendly environment. If you have an idea for how to help, let us know.
# Development Guidelines
This section contains some advice to help get you started writing code for LibreQoS.
## Getting Oriented with LibreQoS
LibreQos is divided into several sections:
* **Rust: system management/control plane**
* **System Daemons**
* `lqosd` is probably the most important part of the Rust system. It loads the eBPF system that provides bridging and traffic shaping control, runs the "bus" for other systems to communicate, and gathers information directly from the eBPF and kernel systems. It has several sub-crates:
* `lqos_heimdall` handles all of the packet sniffing, flow tracking and `libcap` compatible packet data.
* `lqos_queue_tracker` maintains statistics for Linux `tc` shaping queues, particularly Cake.
* `lqos_node_manager` provides a per-node management web interface. It gathers most of its data from `lqosd` via the bus.
* **CLI Utilities**
* `lqusers` provides a CLI interface for managing authentication to the node manager.
* `lqtop` provides a quick and easy way to see what the shaper is doing from the local management console.
* `xdp_iphash_to_cpu_cmdline` (the name is inherited from previous projects) provides a command-line interface to map IP subnets to TC and CPU handles.
* `xdp_pping` provides a CLI tool to give a quick summary of TCP RTT times, grouped by TC handle.
* **Libraries**
* `lqos_bus` provides a local-only (never leaving the shaper node) inter-process communication system. It's used by programs that need to ask `lqosd` to do something, or retrieve information from it.
* The `lqos_bus` crate also acts as a repository for shared data structures when data is passed between portions of the program.
* `lqos_config` manages Rust integration with the `ispConfig.py` configuration file, and the `/etc/lqos.conf` file. It is designed as a helper for other systems to quickly access configuration parameters.
* `lqos_python` compiles into a Python loadable library, providing a convenient interface to Rust code from the Python portions of the program.
* `lqos_setup` provides a text-based initial setup system for users who install LibreQoS via `apt-get`.
* `lqos_utils` provides a grab-bag of handy functions we've found useful elsewhere in the system.
* **Python: system operation and integration**
* `LibreQoS.py` maps all circuits to TC handles and gets the shaper system running.
* `ispConfig.py` provides a system-wide configuration.
* `integrationX.py` provide integrations with UISP, Spylnx and other CRM tools.
* `lqTools.py` provides an interface for gathering statistics.
## What We're Building
LibreQoS is a free/open source fair queueing system. It's designed for ISPs, but can be useful elsewhere. Primary goals:
* Provide fair-queueing to help maximize the use of the Internet resources you have.
* Keep end-user latency low.
* Don't alter user traffic (for example by lowering the quality of their streaming video).
* Don't invade user's privacy.
* Provide excellent support tools to help keep your ISP running smoothly.
Some secondary goals include:
* Visualize data to facilitate moving the state-of-the-art in fair queueing forwards.
* Provide amazing throughput on inexpensive hardware.
## Making Changes to LibreQoS
We try to remain fast-moving and "process light".
> When we use the word "agile", we don't mean the heavily formalized process with scrums, kanban boards and similar. We mean lightweight, fast moving, and adhering to useful guides like "Code Complete" and "The Pragmatic Programmer". Not getting bogged down in heavy process.
### Simple Changes
For a straightforward change, do the following:
1. Do one (or more!) of the following:
* Let us know on the chat that you're working on it.
* Create an Issue in our GitHub repo.
* Submit a PR, following the Branch Guidelines below.
2. Other community members review and comment on your change in an informal manner.
3. Once consensus is reached, we'll merge to the `develop` branch (or a branch parented from `develop` if it's a big change) and test it on our server resources at Equinix.
4. When ready, we'll merge it into the next release.
### Complex Changes
If you need/want a complicated change, please get in touch with us on the Matrix chat first. We'd like to avoid duplicating effort and wasting anyone's time. We'll be happy to offer advice and guidance. Then the process is similar:
1. Work on your local branch, parented off of `develop`.
2. Create a PR (targeting `develop`). If you'd like interim feedback, create a "draft PR" and we can help test your branch before the PR finalizes.
3. Once your PR is ready, submit it.
4. The community will review/comment on your PR.
5. Once consensus is reached, we'll merge it into `develop`.
6. Once ready, `develop` will merge into `main`.
## Branch Guidelines
LibreQoS has adopted the following scheme for branches:
* `main` - released code (tagged at releases), safe to pull.
* `develop` - Parented from `main` and rebased on release. Nothing gets directly comitted into `develop`, it's the parent tree for ongoing development work.
* `my_feature` - if you're working on a feature, your feature branch goes here - with `develop` as the parent. PRs---once the feature is ready for inclusion---should be targeted at `develop`.
* `issue_xxx_name` - if you're working on a bugfix, work on it in a branch here. When the issue resolution is complete, PRs should be targeted at `develop`.
* `hotfix_xxx` - If an emergency occurs and you have to push a fix to `main` in a hurry, hotfix branches can be parented from `main`. The resulting PR should target `main`. Let the developers know that they need to rebase `develop`.
The goal is for `main` to *always* be safe to clone and run, without surprises.
## Code Guidelines
This is very much a work in progress.
### Rust
#### Code Formatting
* Use `cargo fmt` to format your code. We've got a customized format setup in place.
* Adhere to standard Rust case and naming guidelines.
#### Dependencies
* Check that you aren't including any dependencies that incompatible with our license---GPL v2.
* Look through the `Cargo.toml` files (or run `cargo tree`) and try to prefer using a dependency we use elsewhere.
* Try to avoid using unmaintained crates.
#### Naming
* Don't use short, incomprehensible names in any API or function accessible from outside. You don't save any RAM by naming your variable `sz` instead of `size`---you just make it harder for anyone reading the code.
* It's fine to use `i` and similar for internal counting iterators. Try to use meaningful names for everything else.
#### Code Style
* Prefer functional/iterative code to imperative. Sometimes you need a `for` loop, but if it can be replaced with an `iter`, `map` and `fold` it will both compile into faster code and be less error prone.
* It's better to have lots of small functions than one big one. Rust is really good at inlining, and it's much easier to understand short functions. It's also easier to test small functions.
* If you have to override a Clippy warning, add a comment explaining why you did so.
* Functions accessible from other crates should use the RustDoc standard for documentation.
#### Unit Tests
* If you fix an issue, and it's testable: add a unit test to check that we don't regress and suffer from that bug again.
* If you create a type, write unit tests to test its constraints.
#### Error Handling
* Use `thiserror` to emit readable error messages from your functions.
* It's fine to use `?` and `anyhow` inside function chains; prefer `result.map_err` to transform your errors into your own errors whenever it's possible that an error can be returned from a function accessible beyond the immediate crate.
* Issue a `log::error!` or `log::warn!` messaage when an error occurs. Don't trust the callee to do it for you. It's better to have duplicate error messages than none at all.

View File

@ -0,0 +1,51 @@
<a href="https://libreqos.io/"><img alt="LibreQoS" src="https://user-images.githubusercontent.com/22501920/202913614-4ff2e506-e645-4a94-9918-d512905ab290.png"></a>
LibreQoS is a Quality of Experience (QoE) Smart Queue Management (SQM) system designed for Internet Service Providers to optimize the flow of their network traffic and thus reduce bufferbloat, keep the network responsive, and improve the end-user experience.
Servers running LibreQoS can shape traffic for many thousands of customers.
Learn more at [LibreQoS.io](https://libreqos.io/)!
## Sponsors
Special thanks to Equinix for providing server resources to support the development of LibreQoS.
Learn more about [Equinix Metal here](https://deploy.equinix.com/metal/).
## Support LibreQoS
Please support the continued development of LibreQoS by sponsoring us via [GitHub Sponsors](https://github.com/sponsors/LibreQoE) or [Patreon](https://patreon.com/libreqos).
## Documentation
[Docs](https://libreqos.readthedocs.io)
## Matrix Chat
Our Matrix chat channel is available at [https://matrix.to/#/#libreqos:matrix.org](https://matrix.to/#/#libreqos:matrix.org).
<img alt="LibreQoS" src="https://user-images.githubusercontent.com/22501920/223866474-603e1112-e2e6-4c67-93e4-44c17b1b7c43.png"></a>
## Features
### Flexible Hierarchical Shaping / Back-Haul Congestion Mitigation
<img src="https://raw.githubusercontent.com/LibreQoE/LibreQoS/main/docs/nestedHTB2.png" width="350"></img>
Starting in version v1.1+, operators can map their network hierarchy in LibreQoS. This enables both simple network hierarchies (Site>AP>Client) as well as much more complex ones (Site>Site>Micro-PoP>AP>Site>AP>Client). This can be used to ensure that a given sites peak bandwidth will not exceed the capacity of its back-haul links (back-haul congestion control). Operators can support more users on the same network equipment with LibreQoS than with competing QoE solutions which only shape by AP and Client.
### CAKE
CAKE is the product of nearly a decade of development efforts to improve on fq\_codel. With the diffserv\_4 parameter enabled CAKE groups traffic in to Bulk, Best Effort, Video, and Voice. This means that without having to fine-tune traffic priorities as you would with DPI products CAKE automatically ensures your clients OS update downloads will not disrupt their zoom calls. It allows for multiple video conferences to operate on the same connection which might otherwise “fight” for upload bandwidth causing call disruptions. With work-from-home, remote learning, and tele-medicine becoming increasingly common minimizing video call disruptions can save jobs, keep students engaged, and help ensure equitable access to medical care.
### XDP
Fast, multi-CPU queueing leveraging xdp-cpumap-tc and cpumap-pping. Currently tested in the real world past 11 Gbps (so far) with just 30% CPU use on a 16 core Intel Xeon Gold 6254. It's likely capable of 30Gbps or more.
### Graphing
You can graph bandwidth and TCP RTT by client and node (Site, AP, etc), using InfluxDB.
### CRM Integrations
- UISP
- Splynx

View File

@ -0,0 +1,120 @@
# LibreQoS v1.3.1 to v1.4 Change Summary
Version 1.4 is a huge milestone. A whole new back-end, new GUI, 30%+ performance improvements, support for single-interface mode.
## Some Statistics
- **564** Commits since 1.3.1
- **28,399** Lines of Code
- **10,142** lines of Rust
- **5,448** lines of HTML & JavaScript
- **3,126** lines of Python
- **2,023** lines of C
## Peak Performance (So Far)
- Tested single-stream performance of just under 10 gbit/s on a 16-core Xeon Gold (single interface architecture, using 8 cores for each direction). The flow was shaped with Cake, and retained good (<10 ms RTT latency) performance.
- Tested 25 gbit/s total throughput on the same system. CPU was not saturated---we didn't have a bigger network to test!
- Running live at ISPs with 11 gbit/s of real customer performance and plenty of room to grow.
## New Architecture
- Rust-based back-end provides:
- `lqosd` - a daemon that manages:
- Loading/setup/unloading eBPF programs.
- Gathers statistics directly from eBPF.
- Provides a local "bus" for transporting data between components.
- Sets "tunables", replacing the need for a separate offloading service.
- `lqtop` - a console-based utility for viewing current activity.
- `lqos_node_manager` - a web-based GUI that:
- Monitors current activity.
- Monitors system status.
- Provides "best/worst" summaries of RTT.
- Provides visibility into the working of queues.
- Categorizes traffic to match your network hierarchy, letting you quickly find the bottlenecks.
- Let's you browse and search your shaped devices.
- Lists "unknown IP addresses" that are passing through the shaper but do not have a rule associated.
- Allows you to view and edit the LibreQoS configuration.
- `lqos_python` - provides Python access to the bus system.
- `lqos_setup` - builds enough configuration files to get you started.
- `lqos_users` - authentication for the GUIs.
- High-performance Python script:
- Batches TC commands for fast execution.
- Batches bus-transactions to associate IP subnets with users for fast execution.
- Improved scheduler for InfluxDB graphing.
## High Performance Bridge (Bifrost)
- Optionally replace the Linux bridge system with an XDP-based bridge accelerator.
- Throughput is 30% higher in this mode.
## Packet and Flow Analysis (Heimdall)
- Viewing a circuit in the web UI displays a summary of IP traffic flows for that circuit.
- A "capture" button will capture packet headers, and allow nanosecond-level analysis of traffic data.
- You can download the packet captures in `libpcap` format, for analysis in Wireshark and similar tools.
- Configure the capture delay in `/etc/lqos.conf`
## Single-interface Mode
- Operate with a single network interface and VLANs for "in" and "out".
## Graphs
- Graph current throughput, shaped and unshaped.
- Graph CPU and RAM performance.
- Graph individual Cake shaper tins, backlog, delays.
- TCP "round trip time" histogram showing overall network latency performance.
- Per-network node traffic graph.
- Per-network node RTT latency histogram, to let you zero-in on troublespots.
## Miscellaneous
- `build_rust.sh` builds the entire package from a Git update, with minimal (<1 second) downtime.
- `build_dpkg.sh` assembles the entire system into an Ubuntu/Debian `.deb` installer.
- Sample `.service` files for `systemd` integration.
- Real-time adjustment to tunables.
- Redact text into Klingon to allow screenshots without sharing customer data.
- Preliminary support for reading IP data inside MPLS packets, as long as they are ordered "VLAN->MPLS->VPLS" and not the other way around.
- Automatically trim network trees that exceed 9 levels deep.
- Very accurate timing functions for better statistics.
- Greatly improved documentation.
- Improved rejection of TCP round-trip-time outliers (from long-polled connections).
- Improved Spylnx and UISP integrations.
## Better Distribution
> This is in alpha testing. It has worked on some test setups, but needs production testing.
Installation via `apt-get` and LibreQoS's own repo. Add the `libreqos` repo, and you can use `apt-get` to install/update the traffic shaper. This doesn't get you the development toolchain.
```sh
sudo echo "deb http://stats.libreqos.io/ubuntu jammy main" > /etc/apt/sources.list.d/libreqos.list
wget -O - -q http://stats.libreqos.io/repo.asc | apt-key add -
apt-get update
apt-get install libreqos
```
You will be asked some questions about your configuration, and the management daemon and webserver will automatically start. Go to `http://<your_ip>:9123/` to finish installation.
## Gallery
### Node Manager - Dashboard
![image](https://user-images.githubusercontent.com/14896751/227727398-ff9e0321-cae3-4daf-a9f7-59fafaf30061.png)
*The node manager displays current activity on your network*
### Node Manager - Circuit View
![image](https://user-images.githubusercontent.com/14896751/227727646-c6eaaece-f2f0-4667-9b66-5cb08a7f4eb8.png)
*Find out exactly what's going on inside each circuit, monitoring all of the queue stats - you can even view the details of each category tin*
### Node Manager - Flow Analysis
![image](https://user-images.githubusercontent.com/14896751/227727691-e82bc021-4da4-436a-93af-0f7cd13824be.png)
*Analyze what's going on for a specific client, viewing real-time traffic flow data. No need to run `torch` or equivalent on their router. Ideal for finding connectivity problems.*
### Node Manager - Packet Capture
![image](https://user-images.githubusercontent.com/14896751/227727755-e8c9bce6-58b2-4c50-a466-2e68b29a4b18.png)
*Capture traffic and analyze per-packet in an intuitive, zoomable traffic analysis system. You can view down to nanosecond granularity to find performance problems, and see what's really going on with your traffic. Click "Download PCAP Dump" to analyze the same data in Wireshark.*

View File

@ -0,0 +1,28 @@
## Integrations
### UISP Integration
First, set the relevant parameters for UISP (uispAuthToken, UISPbaseURL, etc.) in ispConfig.py.
To test the UISP Integration, use
```
python3 integrationUISP.py
```
On the first successful run, it will create a network.json and ShapedDevices.csv file.
If a network.json file exists, it will not be overwritten.
You can modify the network.json file to more accurately reflect bandwidth limits.
ShapedDevices.csv will be overwritten every time the UISP integration is run.
You have the option to run integrationUISP.py automatically on boot and every 30 minutes, which is recommended. This can be enabled by setting ```automaticImportUISP = True``` in ispConfig.py
### Splynx Integration
First, set the relevant parameters for Splynx (splynx_api_key, splynx_api_secret, etc.) in ispConfig.py.
To test the Splynx Integration, use
```
python3 integrationSplynx.py
```
On the first successful run, it will create a ShapedDevices.csv file.
You can manually create your network.json file to more accurately reflect bandwidth limits.
ShapedDevices.csv will be overwritten every time the Splynx integration is run.
You have the option to run integrationSplynx.py automatically on boot and every 30 minutes, which is recommended. This can be enabled by setting ```automaticImportSplynx = True``` in ispConfig.py

View File

@ -0,0 +1,14 @@
## Integrations
### Splynx Integration
First, set the relevant parameters for Splynx (splynx_api_key, splynx_api_secret, etc.) in ispConfig.py.
To test the Splynx Integration, use
```
python3 integrationSplynx.py
```
On the first successful run, it will create a ShapedDevices.csv file.
You can manually create your network.json file to more accurately reflect bandwidth limits.
ShapedDevices.csv will be overwritten every time the Splynx integration is run.
You have the option to run integrationSplynx.py automatically on boot and every 30 minutes, which is recommended. This can be enabled by setting ```automaticImportSplynx = True``` in ispConfig.py

View File

@ -0,0 +1,15 @@
## Integrations
### UISP Integration
First, set the relevant parameters for UISP (uispAuthToken, UISPbaseURL, etc.) in ispConfig.py.
To test the UISP Integration, use
```
python3 integrationUISP.py
```
On the first successful run, it will create a network.json and ShapedDevices.csv file.
If a network.json file exists, it will not be overwritten.
You can modify the network.json file to more accurately reflect bandwidth limits.
ShapedDevices.csv will be overwritten every time the UISP integration is run.
You have the option to run integrationUISP.py automatically on boot and every 30 minutes, which is recommended. This can be enabled by setting ```automaticImportUISP = True``` in ispConfig.py

View File

@ -0,0 +1,434 @@
# LibreQoS v1.3.1
## LibreQoS v1.3.1 Installation & Usage Guide - Physical Server and Ubuntu 22.04
## Notes for upgrading from v1.2 or prior
### Custom CRM Integrations
If you use a custom CRM integration, please ensure your integration uses a unique circuit identifier for the 'Circuit ID' field in ShapedDevices.csv. This is now required in v1.3 in order to make partial reloading possible. A good choice for this ID would be internet service plan unique ID, or the subscriber site ID your CRM provides for customer service locations. Multiple devices within the same circuit would use the same 'Circuit ID', but aside from that, all Circuit IDs should be distinct. The built-in Splynx and UISP integrations for v1.3 handle this automatically.
## Network Design Assumptions
Officially supported configuration:
- Edge and Core routers with MTU 1500 on links between them
- If you use MPLS, you would terminate MPLS traffic at the core router.
LibreQoS cannot decapsulate MPLS on its own.
- OSPF primary link (low cost) through the server running LibreQoS
- OSPF backup link
![](https://raw.githubusercontent.com/rchac/LibreQoS/main/docs/design.png)
Is it possible to use LibreQoS in-line without a core router, but that setup requires depending on STP instead of OSPF, which can cause issues. Such configurations are not officially supported.
## Network Interface Card
LibreQoS requires a NIC with 2 or more RX/TX queues and XDP support. While many cards theoretically meet these requirements, less commonly used cards tend to have unreported driver bugs which impede XDP functionality and make them unusable for our purposes. At this time we can only recommend Intel x520, Intel x710, and Nvidia (ConnectX-5 or newer) NICs.
## Server Setup
Disable hyperthreading on the BIOS/UEFI of your host system. Hyperthreaading is also known as Simultaneous Multi Threading (SMT) on AMD systems. Disabling this is very important for optimal performance of the XDP cpumap filtering and, in turn, throughput and latency.
- Boot, pressing the appropriate key to enter the BIOS settings
- For AMD systems, you will have to navigate the settings to find the "SMT Control" setting. Usually it is under something like ```Advanced -> AMD CBS -> CPU Common Options -> Thread Enablement -> SMT Control``` Once you find it, switch to "Disabled" or "Off"
- For Intel systems, you will also have to navigate the settings to find the "hyperthrading" toggle option. On HP servers it's under ```System Configuration > BIOS/Platform Configuration (RBSU) > Processor Options > Intel (R) Hyperthreading Options.```
- Save changes and reboot
## Install Ubuntu
Download Ubuntu Server 22.04 from <a href="https://ubuntu.com/download/server">https://ubuntu.com/download/server</a>.
1. Boot Ubuntu Server from USB.
2. Follow the steps to install Ubuntu Server.
3. If you use a Mellanox network card, the Ubuntu Server installer will ask you whether to install the mellanox/intel NIC drivers. Check the box to confirm. This extra driver is important.
4. On the Networking settings step, it is recommended to assign a static IP address to the management NIC.
5. Ensure SSH server is enabled so you can more easily log into the server later.
6. You can use scp or sftp to access files from your LibreQoS server for easier file editing. Here's how to access via scp or sftp using an [Ubuntu](https://www.addictivetips.com/ubuntu-linux-tips/sftp-server-ubuntu/) or [Windows](https://winscp.net/eng/index.php) machine.
## Use Installer Script (For Sponsors - Skip If Not Applicable)
Sponsors can use the LibreQoS-Installer script. This script does the following:
- Disables IRQbalance
- Disables required offloading types using service
- Creates a bridge between two interfaces - applied by the above service at each boot
- Installs LibreQoS and cpumap-pping
Once complete - skip to [this section](https://github.com/LibreQoE/LibreQoS/wiki/LibreQoS-v1.3-Installation-&-Usage-Guide-Physical-Server-and-Ubuntu-22.04#install-influxdb-for-graphing) of the guide.
## Setup
### Disable IRQbalance
```shell
sudo systemctl stop irqbalance
sudo systemctl disable irqbalance
```
### Disable Offloading
We need to disable certain hardware offloading features, as they break XDP, used by XDP-CPUMAP-TC to send traffic to appropriate CPUs.
You can create a bash script to disabled these offload features upon boot.
```shell
sudo nano /usr/local/sbin/offloadOff.sh
```
Enter the following
```shell
#!/bin/sh
ethtool --offload eth1 gso off tso off lro off sg off gro off
ethtool --offload eth2 gso off tso off lro off sg off gro off
```
Replace eth1 and eth2 with your two shaper interfaces (order doesn't matter).
Then create
```shell
sudo nano /etc/systemd/system/offloadOff.service
```
With the following
```text
[Unit]
After=network.service
[Service]
ExecStart=/usr/local/sbin/offloadOff.sh
[Install]
WantedBy=default.target
```
Then change permissions and enable the service with
```shell
sudo chmod 664 /etc/systemd/system/offloadOff.service
sudo chmod 744 /usr/local/sbin/offloadOff.sh
sudo systemctl daemon-reload
sudo systemctl enable offloadOff.service
sudo reboot
```
### Add a bridge between edge/core interfaces
From the Ubuntu VM, create a linux interface bridge - br0 - with the two shaping interfaces.
Find your existing .yaml file in /etc/netplan/ with
```shell
cd /etc/netplan/
ls
```
Then edit the .yaml file there with
```shell
sudo nano XX-cloud-init.yaml
```
with XX corresponding to the name of the existing file.
Editing the .yaml file, we need to define the shaping interfaces (here, ens19 and ens20) and add the bridge with those two interfaces. Assuming your interfaces are ens18, ens19, and ens20, here is what your file might look like:
```yaml
# This is the network config written by 'subiquity'
network:
ethernets:
ens18:
addresses:
- 10.0.0.12/24
routes:
- to: default
via: 10.0.0.1
nameservers:
addresses:
- 1.1.1.1
- 8.8.8.8
search: []
ens19:
dhcp4: no
ens20:
dhcp4: no
version: 2
bridges:
br0:
interfaces:
- ens19
- ens20
```
Make sure to replace 10.0.0.12/24 with your LibreQoS VM's address and subnet, and to replace the default gateway 10.0.0.1 with whatever your default gateway is.
Then run
```shell
sudo netplan apply
```
### Install LibreQoS and dependencies
Cd to your preferred directory and download the latest release
```shell
cd home/$USER/
sudo apt update
sudo apt install python3-pip clang gcc gcc-multilib llvm libelf-dev git nano graphviz
python3 -m pip install -r requirements.txt
sudo python3 -m pip install -r requirements.txt
git clone https://github.com/rchac/LibreQoS.git
git checkout v1.3.1
```
### Install and compile cpumap-pping
```shell
cd home/$USER/LibreQoS/src
git submodule update --init
cd cpumap-pping/
git submodule update --init
cd src/
make
```
### Install InfluxDB for Graphing
To install InfluxDB 2.x., follow the steps at [https://portal.influxdata.com/downloads/](https://portal.influxdata.com/downloads/).
For high throughput networks (5+ Gbps) you will likely want to install InfluxDB to a separate machine or VM from that of the LibreQoS server to avoid CPU load.
Restart your system that is running InfluxDB
```shell
sudo reboot
```
Check to ensure InfluxDB is running properly. This command should show "Active: active" with green dot.
```shell
sudo service influxdb status
```
Check that Web UI is running:<br>
```shell
http://SERVER_IP_ADDRESS:8086
```
Create Bucket
- Data > Buckets > Create Bucket
Call the bucket "libreqos" (all lowercase, without quotes).<br>
Have it store as many days of data as you prefer. 7 days is standard.<>
Import Dashboard
- Boards > Create Dashboard > Import Dashboard
Then upload the file [influxDBdashboardTemplate.json](https://github.com/rchac/LibreQoS/blob/main/src/influxDBdashboardTemplate.json) to InfluxDB.
[Generate an InfluxDB Token](https://docs.influxdata.com/influxdb/cloud/security/tokens/create-token/). It will be added to ispConfig.py in the following steps.
### Modify ispConfig.py
Copy ispConfig.example.py to ispConfig.py and edit as needed
```shell
cd /home/$USER/LibreQoS/src/
cp ispConfig.example.py ispConfig.py
nano ispConfig.py
```
- Set upstreamBandwidthCapacityDownloadMbps and upstreamBandwidthCapacityUploadMbps to match the bandwidth in Mbps of your network's upstream / WAN internet connection. The same can be done for generatedPNDownloadMbps and generatedPNUploadMbps.
- Set interfaceA to the interface facing your core router (or bridged internal network if your network is bridged)
- Set interfaceB to the interface facing your edge router
- Set ```enableActualShellCommands = True``` to allow the program to actually run the commands.
### Integrations
Integrations now share a common framework thanks to [this pull](https://github.com/rchac/LibreQoS/pull/145). This also allows for graphing the network topology with graphviz.
#### UISP Integration
To run the UISP Integration, use
```shell
python3 integrationUISP.py
```
On the first successful run, it will create a network.json and ShapedDevices.csv file.
If a network.json file exists, it will not be overwritten.
You can modify the network.json file to more accurately reflect bandwidth limits.
ShapedDevices.csv will be overwritten every time the UISP integration is run.
You have the option to run integrationUISP.py automatically on boot and every 30 minutes, which is recommended. This can be enabled by setting ```automaticImportUISP = True``` in ispConfig.py
### Network.json
Network.json allows ISP operators to define a Hierarchical Network Topology, or Flat Network Topology.
For networks with no Parent Nodes (no strictly defined Access Points or Sites) edit the network.json to use a Flat Network Topology with
```nano network.json```
setting the following file content:
```json
{}
```
If you plan to use the built-in UISP or Splynx integrations, you do not need to create a network.json file quite yet.
If you plan to use the built-in UISP integration, it will create this automatically on its first run (assuming network.json is not already present). You can then modify the network.json to more accurately reflect your topology.
If you will not be using an integration, you can manually define the network.json following the template file - network.example.json
```text
+-----------------------------------------------------------------------+
| Entire Network |
+-----------------------+-----------------------+-----------------------+
| Parent Node A | Parent Node B | Parent Node C |
+-----------------------+-------+-------+-------+-----------------------+
| Parent Node D | Sub 3 | Sub 4 | Sub 5 | Sub 6 | Sub 7 | Parent Node F |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| Sub 1 | Sub 2 | | | | Sub 8 | Sub 9 |
+-------+-------+-------+-----------------------+-------+-------+-------+
```
#### Manual Editing
- Modify the network.json file using your preferred JSON editor (Geany for example)
- Parent node name must match that used for clients in ShapedDevices.csv
### ShapedDevices.csv
If you are using an integration, this file will be automatically generated. If you are not using an integration, you can manually edit the file.
- Modify the ShapedDevices.csv file using your preferred spreadsheet editor (LibreOffice Calc, Excel, etc), following the template file - ShapedDevices.example.csv
- An IPv4 address or IPv6 address is required for each entry.
- The Access Point or Site name should be set in the Parent Node field. Parent Node can be left blank for flat networks.
- The ShapedDevices.csv file allows you to set minimum guaranteed, and maximum allowed bandwidth per subscriber.
- The minimum allowed plan rates for Circuits are 2Mbit. Bandwidth min and max should both be above that threshold.
- Recommendation: set the min bandwidth to something like 25/10 and max to 1.15X advertised plan rate by using bandwidthOverheadFactor = 1.15
- This way, when an AP hits its ceiling, users have any remaining AP capacity fairly distributed between them.
- Ensure a reasonable minimum bandwidth minimum for every subscriber, allowing them to utilize up to the maximum provided when AP utilization is below 100%.
Note regarding SLAs: For customers with SLA contracts that guarantee them a minimum bandwidth, set their plan rate as the minimum bandwidth. That way when an AP approaches its ceiling, SLA customers will always get that amount.
![image](https://user-images.githubusercontent.com/22501920/200134960-28709d0f-48fe-4129-b4fd-70b204cade2c.png)
## How to run LibreQoS
### One-Time / Debug Runs
One-time runs show the response from the terminal for each filter rule applied, and can be very helpful for debugging and to make sure it is correctly configured.
- Modify setting parameters in ispConfig.py to suit your environment
- For one-time runs, use
```shell
sudo ./LibreQoS.py
```
- To use the debug mode with more verbose output, use:
```shell
sudo ./LibreQoS.py --debug
```
### Running as a service
To run as a service, we create a systemd service to run scheduler.py.
scheduler.py does the following:
- On start: Run a full setup of queues
- Every 30 minutes: Update queues, pulling new configuration from CRM integration if enabled
On Linux distributions that use systemd, such as Ubuntu, we create
```shell
sudo nano /etc/systemd/system/LibreQoS.service
```
Then paste the text below, replacing "/home/YOUR_USERNAME/LibreQoS" with wherever you downloaded LibreQoS to. Be sure to replace YOUR_USERNAME with your actual username, because otherwise when the root user executes it, it will look in the wrong directory.
```text
[Unit]
After=network.service
[Service]
WorkingDirectory=/home/YOUR_USERNAME/LibreQoS/src
ExecStart=/usr/bin/python3 /home/YOUR_USERNAME/LibreQoS/src/scheduler.py
ExecStopPost=/bin/bash -c '/usr/bin/python3 /home/YOUR_USERNAME/LibreQoS/src/LibreQoS.py --clearrules'
ExecStop=/bin/bash -c '/usr/bin/python3 /home/YOUR_USERNAME/LibreQoS/src/LibreQoS.py --clearrules'
Restart=always
[Install]
WantedBy=default.target
```
Then run
```shell
sudo chmod 664 /etc/systemd/system/LibreQoS.service
sudo systemctl daemon-reload
sudo systemctl enable LibreQoS.service
```
You can start the service using
```shell
sudo systemctl start LibreQoS.service
```
You can check the status of the service using
```shell
sudo systemctl status LibreQoS.service
```
You can restart the service to refresh any changes you've made to the ShapedDevices.csv file by doing
```shell
sudo systemctl restart LibreQoS.service
```
You can also stop the service to remove all queues and IP rules by doing
```shell
sudo systemctl stop LibreQoS.service
```
### Crontab
- At 4AM: Runs a full reload of all queues to make sure they perfectly match queueStructure.py and that any changes to network.json can be applied.
First, check to make sure the cron job does not already exist.
```shell
sudo crontab -l | grep -q 'LibreQoS' && echo 'entry exists' || echo 'entry does not exist'
```
The above should output "entry does not exist". If so, proceed to add it with:
```shell
(sudo crontab -l 2>/dev/null; echo "0 4 * * * /bin/systemctl try-restart LibreQoS") | sudo crontab -
sudo /etc/init.d/cron start
```
## Common Issues
### Program Running, But Traffic Not Shaping
In ispConfig.py, make sure the edge and core interfaces correspond to correctly to the edge and core. Try swapping the interfaces to see if shaping starts to work.
### RTNETLINK answers: Invalid argument
This tends to show up when the MQ qdisc cannot be added correctly to the NIC interface. This would suggest the NIC has insufficient RX/TX queues. Please make sure you are using the [recommended NICs](#network-interface-card).
## Performance Tuning
### OSPF
It is recommended to set the OSPF timers of both OSPF neighbors (core and edge router) to minimize downtime upon a reboot of the LibreQoS server.
- hello interval
- dead

View File

@ -0,0 +1,103 @@
# Configure LibreQoS
## Configure lqos.conf
Copy the lqosd daemon configuration file to `/etc`:
```shell
cd /opt/libreqos/src
sudo cp lqos.example /etc/lqos.conf
```
Now edit the file to match your setup with
```shell
sudo nano /etc/lqos.conf
```
Change `enp1s0f1` and `enp1s0f2` to match your network interfaces. It doesn't matter which one is which. Notice, it's paring the interfaces, so when you first enter enps0f<ins>**1**</ins> in the first line, the `redirect_to` parameter is enp1s0f<ins>**2**</ins> (replacing with your actual interface names).
- First Line: `name = "enp1s0f1", redirect_to = "enp1s0f2"`
- Second Line: `name = "enp1s0f2", redirect_to = "enp1s0f1"`
Then, if using Bifrost/XDP set `use_xdp_bridge = true` under that same `[bridge]` section.
## Configure ispConfig.py
Copy ispConfig.example.py to ispConfig.py and edit as needed
```shell
cd /opt/libreqos/src/
cp ispConfig.example.py ispConfig.py
nano ispConfig.py
```
- Set upstreamBandwidthCapacityDownloadMbps and upstreamBandwidthCapacityUploadMbps to match the bandwidth in Mbps of your network's upstream / WAN internet connection. The same can be done for generatedPNDownloadMbps and generatedPNUploadMbps.
- Set interfaceA to the interface facing your core router (or bridged internal network if your network is bridged)
- Set interfaceB to the interface facing your edge router
- Set ```enableActualShellCommands = True``` to allow the program to actually run the commands.
## Network.json
Network.json allows ISP operators to define a Hierarchical Network Topology, or Flat Network Topology.
For networks with no Parent Nodes (no strictly defined Access Points or Sites) edit the network.json to use a Flat Network Topology with
```nano network.json```
setting the following file content:
```json
{}
```
If you plan to use the built-in UISP or Splynx integrations, you do not need to create a network.json file quite yet.
If you plan to use the built-in UISP integration, it will create this automatically on its first run (assuming network.json is not already present). You can then modify the network.json to more accurately reflect your topology.
If you will not be using an integration, you can manually define the network.json following the template file - network.example.json
```text
+-----------------------------------------------------------------------+
| Entire Network |
+-----------------------+-----------------------+-----------------------+
| Parent Node A | Parent Node B | Parent Node C |
+-----------------------+-------+-------+-------+-----------------------+
| Parent Node D | Sub 3 | Sub 4 | Sub 5 | Sub 6 | Sub 7 | Parent Node F |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| Sub 1 | Sub 2 | | | | Sub 8 | Sub 9 |
+-------+-------+-------+-----------------------+-------+-------+-------+
```
## Manual Setup
You can use
```shell
python3 csvToNetworkJSON.py
```
to convert manualNetwork.csv to a network.json file.
manualNetwork.csv can be copied from the template file, manualNetwork.template.csv
Note: The parent node name must match that used for clients in ShapedDevices.csv
## ShapedDevices.csv
If you are using an integration, this file will be automatically generated. If you are not using an integration, you can manually edit the file.
### Manual Editing
- Modify the ShapedDevices.csv file using your preferred spreadsheet editor (LibreOffice Calc, Excel, etc), following the template file - ShapedDevices.example.csv
- Circuit ID is required. Must be a string of some sort (int is fine, gets parsed as string). Must NOT include any number symbols (#).
- An IPv4 address or IPv6 address is required for each entry.
- The Access Point or Site name should be set in the Parent Node field. Parent Node can be left blank for flat networks.
- The ShapedDevices.csv file allows you to set minimum guaranteed, and maximum allowed bandwidth per subscriber.
- The minimum allowed plan rates for Circuits are 2Mbit. Bandwidth min and max should both be above that threshold.
- Recommendation: set the min bandwidth to something like 25/10 and max to 1.15X advertised plan rate by using bandwidthOverheadFactor = 1.15
- This way, when an AP hits its ceiling, users have any remaining AP capacity fairly distributed between them.
- Ensure a reasonable minimum bandwidth minimum for every subscriber, allowing them to utilize up to the maximum provided when AP utilization is below 100%.
Note regarding SLAs: For customers with SLA contracts that guarantee them a minimum bandwidth, set their plan rate as the minimum bandwidth. That way when an AP approaches its ceiling, SLA customers will always get that amount.
![image](https://user-images.githubusercontent.com/22501920/200134960-28709d0f-48fe-4129-b4fd-70b204cade2c.png)
Once your configuration is complete. You're ready to run the application and start the [Deamons](./services-and-run.md)

View File

@ -0,0 +1,42 @@
# Network Design Assumptions
## Officially supported configuration
- LibreQoS placed inline in network, usually between an edge router (NAT, firewall) and core router (distribution to sites across network).
- If you use NAT/CG-NAT, place LibreQoS inline south of where NAT is applied, as LibreQoS needs to shape internal addresses (100.64.0.0/12) not public post-NAT IPs.
- Edge and Core routers should have 1500 MTU on links between them
- If you use MPLS, you would terminate MPLS traffic at the core router. LibreQoS cannot decapsulate MPLS on its own.
- OSPF primary link (low cost) through the server running LibreQoS
- OSPF backup link (high cost, maybe 200 for example)
![Offical Configuration](https://raw.githubusercontent.com/rchac/LibreQoS/main/docs/design.png)
### Network Interface Card
```{note}
You must have one of these:
- single NIC with two interfaces,
- two NICs with single interface,
- 2x VLANs interface (using one or two NICs).
```
LibreQoS requires NICs to have 2 or more RX/TX queues and XDP support. While many cards theoretically meet these requirements, less commonly used cards tend to have unreported driver bugs which impede XDP functionality and make them unusable for our purposes. At this time we recommend the Intel x520, Intel x710, and Nvidia (ConnectX-5 or newer) NICs. We cannot guarantee compatibility with other cards.
## Alternate configuration (Not officially supported)
This alternate configuration uses Spanning Tree Protocol (STP) to modify the data path in the event the LibreQoS device is offline for maintenance or another problem.
```{note}
Most of the same considerations apply to the alternate configuration as they do to the officially supported configuation
```
- LibreQoS placed inline in network, usually between an edge router (NAT, firewall) and core router (distribution to sites across network).
- If you use NAT/CG-NAT, place LibreQoS inline south of where NAT is applied, as LibreQoS needs to shape internal addresses (100.64.0.0/12) not public post-NAT IPs.
- Edge router and Core switch should have 1500 MTU on links between them
- If you use MPLS, you would terminate MPLS traffic somewhere south of the core/distribution switch. LibreQoS cannot decapsulate MPLS on its own.
- Spanning Tree primary link (low cost) through the server running LibreQoS
- Spanning Tree backup link (high cost, maybe 80 for example)
Keep in mind that if you use different bandwidth links, for example, 10 Gbps through LibreQoS, and 1 Gbps between core switch and edge router, you may need to be more intentional with your STP costs.
![Alternate Configuration](../stp-diagram.png)

View File

@ -0,0 +1,37 @@
# Install LibreQoS 1.4
## Updating from v1.3
### Remove offloadOff.service
```shell
sudo systemctl disable offloadOff.service
sudo rm /usr/local/sbin/offloadOff.sh /etc/systemd/system/offloadOff.service
```
### Remove cron tasks from v1.3
Run ```sudo crontab -e``` and remove any entries pertaining to LibreQoS from v1.3.
## Simple install via .Deb package (Recommended)
Use the deb package from the [latest v1.4 release](https://github.com/LibreQoE/LibreQoS/releases/).
```shell
sudo echo "deb http://stats.libreqos.io/ubuntu jammy main" > /etc/apt/sources.list.d/libreqos.list
wget -O - -q http://stats.libreqos.io/repo.asc | apt-key add -
apt-get update
apt-get install libreqos
```
You will be asked some questions about your configuration, and the management daemon and webserver will automatically start. Go to http://<your_ip>:9123/ to finish installation.
## Complex Install (Not Reccomended)
```{note}
Use this install if you'd like to constantly deploy from the main branch on Github. For experienced users only!
```
[Complex Installation](../TechnicalDocs/complex-install.md)
You are now ready to [Configure](./configuration.md) LibreQoS!

View File

@ -0,0 +1,240 @@
## Install LibreQoS
## Updating from v1.3
### Remove offloadOff.service
```
sudo systemctl disable offloadOff.service
sudo rm /usr/local/sbin/offloadOff.sh /etc/systemd/system/offloadOff.service
```
### Remove cron tasks from v1.3
Run ```sudo crontab -e``` and remove any entries pertaining to LibreQoS from v1.3.
### Simple install via .Deb package (Recommended)
Use the deb package from the [latest v1.4 release](https://github.com/LibreQoE/LibreQoS/releases/).
### Complex install (Not Recommended)
#### Clone the repo
The recommended install location is `/opt/libreqos`
Go to the install location, and clone the repo:
```
cd /opt/
git clone https://github.com/LibreQoE/LibreQoS.git libreqos
sudo chown -R YOUR_USER /opt/libreqos
```
By specifying `libreqos` at the end, git will ensure the folder name is lowercase.
#### Install Dependencies from apt and pip
You need to have a few packages from `apt` installed:
```
sudo apt-get install -y python3-pip clang gcc gcc-multilib llvm libelf-dev git nano graphviz curl screen llvm pkg-config linux-tools-common linux-tools-`uname -r` libbpf-dev
```
Then you need to install some Python dependencies:
```
cd /opt/libreqos
python3 -m pip install -r requirements.txt
sudo python3 -m pip install -r requirements.txt
```
#### Install the Rust development system
Go to [RustUp](https://rustup.rs) and follow the instructions. Basically, run the following:
```
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```
When Rust finishes installing, it will tell you to execute a command to place the Rust build tools into your path. You need to either execute this command or logout and back in again.
Once that's done, please run:
```
cd /opt/libreqos/src/
./build_rust.sh
```
This will take a while the first time, but it puts everything in the right place.
Now, to build rust crates, run:
```
cd rust
cargo build --all
```
## Configure LibreQoS
### Configure lqos.conf
Copy the lqosd daemon configuration file to `/etc`:
```
cd /opt/libreqos/src
sudo cp lqos.example /etc/lqos.conf
```
Now edit the file to match your setup with
```
sudo nano /etc/lqos.conf
```
Change `enp1s0f1` and `enp1s0f2` to match your network interfaces. It doesn't matter which one is which. Notice, it's paring the interfaces, so when you first enter enps0f<ins>**1**</ins> in the first line, the `redirect_to` parameter is enp1s0f<ins>**2**</ins> (replacing with your actual interface names).
- First Line: `name = "enp1s0f1", redirect_to = "enp1s0f2"`
- Second Line: `name = "enp1s0f2", redirect_to = "enp1s0f1"`
Then, if using Bifrost/XDP set `use_xdp_bridge = true` under that same `[bridge]` section.
### Configure ispConfig.py
Copy ispConfig.example.py to ispConfig.py and edit as needed
```
cd /opt/libreqos/src/
cp ispConfig.example.py ispConfig.py
nano ispConfig.py
```
* Set upstreamBandwidthCapacityDownloadMbps and upstreamBandwidthCapacityUploadMbps to match the bandwidth in Mbps of your network's upstream / WAN internet connection. The same can be done for generatedPNDownloadMbps and generatedPNUploadMbps.
* Set interfaceA to the interface facing your core router (or bridged internal network if your network is bridged)
* Set interfaceB to the interface facing your edge router
* Set ```enableActualShellCommands = True``` to allow the program to actually run the commands.
### Integrations
#### UISP Integration
First, set the relevant parameters for UISP (uispAuthToken, UISPbaseURL, etc.) in ispConfig.py.
To test the UISP Integration, use
```
python3 integrationUISP.py
```
On the first successful run, it will create a network.json and ShapedDevices.csv file.
If a network.json file exists, it will not be overwritten.
You can modify the network.json file to more accurately reflect bandwidth limits.
ShapedDevices.csv will be overwritten every time the UISP integration is run.
You have the option to run integrationUISP.py automatically on boot and every 30 minutes, which is recommended. This can be enabled by setting ```automaticImportUISP = True``` in ispConfig.py
#### Splynx Integration
First, set the relevant parameters for Splynx (splynx_api_key, splynx_api_secret, etc.) in ispConfig.py.
To test the Splynx Integration, use
```
python3 integrationSplynx.py
```
On the first successful run, it will create a ShapedDevices.csv file.
You can manually create your network.json file to more accurately reflect bandwidth limits.
ShapedDevices.csv will be overwritten every time the Splynx integration is run.
You have the option to run integrationSplynx.py automatically on boot and every 30 minutes, which is recommended. This can be enabled by setting ```automaticImportSplynx = True``` in ispConfig.py
### Network.json
Network.json allows ISP operators to define a Hierarchical Network Topology, or Flat Network Topology.
For networks with no Parent Nodes (no strictly defined Access Points or Sites) edit the network.json to use a Flat Network Topology with
```nano network.json```
setting the following file content:
```
{}
```
If you plan to use the built-in UISP or Splynx integrations, you do not need to create a network.json file quite yet.
If you plan to use the built-in UISP integration, it will create this automatically on its first run (assuming network.json is not already present). You can then modify the network.json to more accurately reflect your topology.
If you will not be using an integration, you can manually define the network.json following the template file - network.example.json
```
+-----------------------------------------------------------------------+
| Entire Network |
+-----------------------+-----------------------+-----------------------+
| Parent Node A | Parent Node B | Parent Node C |
+-----------------------+-------+-------+-------+-----------------------+
| Parent Node D | Sub 3 | Sub 4 | Sub 5 | Sub 6 | Sub 7 | Parent Node F |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| Sub 1 | Sub 2 | | | | Sub 8 | Sub 9 |
+-------+-------+-------+-----------------------+-------+-------+-------+
```
#### Manual Setup
You can use
```
python3 csvToNetworkJSON.py
```
to convert manualNetwork.csv to a network.json file.
manualNetwork.csv can be copied from the template file, manualNetwork.template.csv
Note: The parent node name must match that used for clients in ShapedDevices.csv
### ShapedDevices.csv
If you are using an integration, this file will be automatically generated. If you are not using an integration, you can manually edit the file.
#### Manual Editing
* Modify the ShapedDevices.csv file using your preferred spreadsheet editor (LibreOffice Calc, Excel, etc), following the template file - ShapedDevices.example.csv
* Circuit ID is required. Must be a string of some sort (int is fine, gets parsed as string). Must NOT include any number symbols (#).
* An IPv4 address or IPv6 address is required for each entry.
* The Access Point or Site name should be set in the Parent Node field. Parent Node can be left blank for flat networks.
* The ShapedDevices.csv file allows you to set minimum guaranteed, and maximum allowed bandwidth per subscriber.
* The minimum allowed plan rates for Circuits are 2Mbit. Bandwidth min and max should both be above that threshold.
* Recommendation: set the min bandwidth to something like 25/10 and max to 1.15X advertised plan rate by using bandwidthOverheadFactor = 1.15
* This way, when an AP hits its ceiling, users have any remaining AP capacity fairly distributed between them.
* Ensure a reasonable minimum bandwidth minimum for every subscriber, allowing them to utilize up to the maximum provided when AP utilization is below 100%.
Note regarding SLAs: For customers with SLA contracts that guarantee them a minimum bandwidth, set their plan rate as the minimum bandwidth. That way when an AP approaches its ceiling, SLA customers will always get that amount.
![image](https://user-images.githubusercontent.com/22501920/200134960-28709d0f-48fe-4129-b4fd-70b204cade2c.png)
## LibreQoS daemons
lqosd
* Manages actual XDP code. Build with Rust.
lqos_node_manager
* Runs the GUI available at http://a.b.c.d:9123
lqos_scheduler
* lqos_scheduler handles statistics and performs continuous refreshes of LibreQoS' shapers, including pulling from any enabled CRM Integrations (UISP, Splynx).
* On start: Run a full setup of queues
* Every 10 seconds: Graph bandwidth and latency stats
* Every 30 minutes: Update queues, pulling new configuration from CRM integration if enabled
### Run daemons with systemd
You can setup `lqosd`, `lqos_node_manager`, and `lqos_scheduler` as systemd services.
```
sudo cp /opt/libreqos/src/bin/lqos_node_manager.service.example /etc/systemd/system/lqos_node_manager.service
sudo cp /opt/libreqos/src/bin/lqosd.service.example /etc/systemd/system/lqosd.service
sudo cp /opt/libreqos/src/bin/lqos_scheduler.service.example /etc/systemd/system/lqos_scheduler.service
```
Finally, run
```
sudo systemctl daemon-reload
sudo systemctl enable lqosd lqos_node_manager lqos_scheduler
```
You can now point a web browser at `http://a.b.c.d:9123` (replace `a.b.c.d` with the management IP address of your shaping server) and enjoy a real-time view of your network.
### Debugging lqos_scheduler
In the background, lqos_scheduler runs scheduler.py, which in turn runs LibreQoS.py
One-time runs of these individual components can be very helpful for debugging and to make sure everything is correctly configured.
First, stop lqos_scheduler
```
sudo systemctl stop lqos_scheduler
```
For one-time runs of LibreQoS.py, use
```
sudo ./LibreQoS.py
```
* To use the debug mode with more verbose output, use:
```
sudo ./LibreQoS.py --debug
```
To confirm that lqos_scheduler (scheduler.py) is able to work correctly, run:
```
sudo python3 scheduler.py
```
Once you have any errors eliminated, restart lqos_scheduler with
```
sudo systemctl start lqos_scheduler
```

View File

@ -0,0 +1,127 @@
# Server Setup - Pre-requisites
Disable hyperthreading on the BIOS/UEFI of your host system. Hyperthreaading is also known as Simultaneous Multi Threading (SMT) on AMD systems. Disabling this is very important for optimal performance of the XDP cpumap filtering and, in turn, throughput and latency.
- Boot, pressing the appropriate key to enter the BIOS settings
- For AMD systems, you will have to navigate the settings to find the "SMT Control" setting. Usually it is under something like ```Advanced -> AMD CBS -> CPU Common Options -> Thread Enablement -> SMT Control``` Once you find it, switch to "Disabled" or "Off"
- For Intel systems, you will also have to navigate the settings to find the "hyperthrading" toggle option. On HP servers it's under ```System Configuration > BIOS/Platform Configuration (RBSU) > Processor Options > Intel (R) Hyperthreading Options.```
- Save changes and reboot
## Install Ubuntu Server
We recommend Ubuntu Server because its kernel version tends to track closely with the mainline Linux releases. Our current documentation assumes Ubuntu Server. To run LibreQoS v1.4, Linux kernel 5.11 or greater is required, as 5.11 includes some important XDP patches. Ubuntu Server 22.04 uses kernel 5.13, which meets that requirement.
You can download Ubuntu Server 22.04 from <a href="https://ubuntu.com/download/server">https://ubuntu.com/download/server</a>.
1. Boot Ubuntu Server from USB.
2. Follow the steps to install Ubuntu Server.
3. If you use a Mellanox network card, the Ubuntu Server installer will ask you whether to install the mellanox/intel NIC drivers. Check the box to confirm. This extra driver is important.
4. On the Networking settings step, it is recommended to assign a static IP address to the management NIC.
5. Ensure SSH server is enabled so you can more easily log into the server later.
6. You can use scp or sftp to access files from your LibreQoS server for easier file editing. Here's how to access via scp or sftp using an [Ubuntu](https://www.addictivetips.com/ubuntu-linux-tips/sftp-server-ubuntu/) or [Windows](https://winscp.net/eng/index.php) machine.
### Choose Bridge Type
There are two options for the bridge to pass data through your two interfaces:
- Bifrost XDP-Accelerated Bridge
- Regular Linux Bridge
The Bifrost Bridge is faster and generally recommended, but may not work perfectly in a VM setup using virtualized NICs.
To use the Bifrost bridge, skip the regular Linux bridge section below, and be sure to enable Bifrost/XDP in lqos.conf a few sections below.
### Adding a regular Linux bridge (if not using Bifrost XDP bridge)
From the Ubuntu VM, create a linux interface bridge - br0 - with the two shaping interfaces.
Find your existing .yaml file in /etc/netplan/ with
```shell
cd /etc/netplan/
ls
```
Then edit the .yaml file there with
```shell
sudo nano XX-cloud-init.yaml
```
With XX corresponding to the name of the existing file.
Editing the .yaml file, we need to define the shaping interfaces (here, ens19 and ens20) and add the bridge with those two interfaces. Assuming your interfaces are ens18, ens19, and ens20, here is what your file might look like:
```yaml
# This is the network config written by 'subiquity'
network:
ethernets:
ens18:
addresses:
- 10.0.0.12/24
routes:
- to: default
via: 10.0.0.1
nameservers:
addresses:
- 1.1.1.1
- 8.8.8.8
search: []
ens19:
dhcp4: no
ens20:
dhcp4: no
version: 2
bridges:
br0:
interfaces:
- ens19
- ens20
```
Make sure to replace 10.0.0.12/24 with your LibreQoS VM's address and subnet, and to replace the default gateway 10.0.0.1 with whatever your default gateway is.
Then run
```shell
sudo netplan apply
```
### Install InfluxDB (Optional but Recommended)
InfluxDB allows you to track long-term stats beyond what lqos_node_manager can so far.
To install InfluxDB 2.x., follow the steps at [https://portal.influxdata.com/downloads/](https://portal.influxdata.com/downloads/).
For high throughput networks (5+ Gbps) you will likely want to install InfluxDB to a separate machine or VM from that of the LibreQoS server to avoid CPU load.
Restart your system that is running InfluxDB
```shell
sudo reboot
```
Check to ensure InfluxDB is running properly. This command should show "Active: active" with green dot.
```shell
sudo service influxdb status
```
Check that Web UI is running:<br>
```shell
http://SERVER_IP_ADDRESS:8086
```
Create Bucket
- Data > Buckets > Create Bucket
Call the bucket `libreqos` (all lowercase).<br>
Have it store as many days of data as you prefer. 7 days is standard.<>
Import Dashboard `Boards > Create Dashboard > Import Dashboard`
Then upload the file [influxDBdashboardTemplate.json](https://github.com/rchac/LibreQoS/blob/main/src/influxDBdashboardTemplate.json) to InfluxDB.
[Generate an InfluxDB Token](https://docs.influxdata.com/influxdb/cloud/security/tokens/create-token/). It will be added to ispConfig.py in the following steps.
```{note}
You may want to install a reverse proxy in front of the web interfaces for influx and lqos. Setting these up is outside the scope of this document, but some examples are [Caddy](https://caddyserver.com/), and Nginx [Proxy Manager](https://nginxproxymanager.com/)
```

View File

@ -0,0 +1,110 @@
## Server Setup - Pre-requisites
Disable hyperthreading on the BIOS/UEFI of your host system. Hyperthreaading is also known as Simultaneous Multi Threading (SMT) on AMD systems. Disabling this is very important for optimal performance of the XDP cpumap filtering and, in turn, throughput and latency.
* Boot, pressing the appropriate key to enter the BIOS settings
* For AMD systems, you will have to navigate the settings to find the "SMT Control" setting. Usually it is under something like ```Advanced -> AMD CBS -> CPU Common Options -> Thread Enablement -> SMT Control``` Once you find it, switch to "Disabled" or "Off"
* For Intel systems, you will also have to navigate the settings to find the "hyperthrading" toggle option. On HP servers it's under ```System Configuration > BIOS/Platform Configuration (RBSU) > Processor Options > Intel (R) Hyperthreading Options.```
* Save changes and reboot
### Install Ubuntu Server
We recommend Ubuntu Server because its kernel version tends to track closely with the mainline Linux releases. Our current documentation assumes Ubuntu Server. To run LibreQoS v1.4, Linux kernel 5.11 or greater is required, as 5.11 includes some important XDP patches. Ubuntu Server 22.04 uses kernel 5.13, which meets that requirement.
You can download Ubuntu Server 22.04 from <a href="https://ubuntu.com/download/server">https://ubuntu.com/download/server</a>.
1. Boot Ubuntu Server from USB.
2. Follow the steps to install Ubuntu Server.
3. If you use a Mellanox network card, the Ubuntu Server installer will ask you whether to install the mellanox/intel NIC drivers. Check the box to confirm. This extra driver is important.
4. On the Networking settings step, it is recommended to assign a static IP address to the management NIC.
5. Ensure SSH server is enabled so you can more easily log into the server later.
6. You can use scp or sftp to access files from your LibreQoS server for easier file editing. Here's how to access via scp or sftp using an [Ubuntu](https://www.addictivetips.com/ubuntu-linux-tips/sftp-server-ubuntu/) or [Windows](https://winscp.net/eng/index.php) machine.
### Choose Bridge Type
There are two options for the bridge to pass data through your two interfaces:
* Bifrost XDP-Accelerated Bridge
* Regular Linux Bridge
The Bifrost Bridge is faster and generally recommended, but may not work perfectly in a VM setup using virtualized NICs.
To use the Bifrost bridge, skip the regular Linux bridge section below, and be sure to enable Bifrost/XDP in lqos.conf a few sections below.
### Adding a regular Linux bridge (if not using Bifrost XDP bridge)
From the Ubuntu VM, create a linux interface bridge - br0 - with the two shaping interfaces.
Find your existing .yaml file in /etc/netplan/ with
```
cd /etc/netplan/
ls
```
Then edit the .yaml file there with
```
sudo nano XX-cloud-init.yaml
```
with XX corresponding to the name of the existing file.
Editing the .yaml file, we need to define the shaping interfaces (here, ens19 and ens20) and add the bridge with those two interfaces. Assuming your interfaces are ens18, ens19, and ens20, here is what your file might look like:
```
# This is the network config written by 'subiquity'
network:
ethernets:
ens18:
addresses:
- 10.0.0.12/24
routes:
- to: default
via: 10.0.0.1
nameservers:
addresses:
- 1.1.1.1
- 8.8.8.8
search: []
ens19:
dhcp4: no
ens20:
dhcp4: no
version: 2
bridges:
br0:
interfaces:
- ens19
- ens20
```
Make sure to replace 10.0.0.12/24 with your LibreQoS VM's address and subnet, and to replace the default gateway 10.0.0.1 with whatever your default gateway is.
Then run
```
sudo netplan apply
```
### Install InfluxDB (Optional but Recommended)
InfluxDB allows you to track long-term stats beyond what lqos_node_manager can so far.
To install InfluxDB 2.x., follow the steps at [https://portal.influxdata.com/downloads/](https://portal.influxdata.com/downloads/).
For high throughput networks (5+ Gbps) you will likely want to install InfluxDB to a separate machine or VM from that of the LibreQoS server to avoid CPU load.
Restart your system that is running InfluxDB
```
sudo reboot
```
Check to ensure InfluxDB is running properly. This command should show "Active: active" with green dot.
```
sudo service influxdb status
```
Check that Web UI is running:<br>
```
http://SERVER_IP_ADDRESS:8086
```
Create Bucket
* Data > Buckets > Create Bucket
Call the bucket `libreqos` (all lowercase).<br>
Have it store as many days of data as you prefer. 7 days is standard.<>
Import Dashboard
* Boards > Create Dashboard > Import Dashboard
Then upload the file [influxDBdashboardTemplate.json](https://github.com/rchac/LibreQoS/blob/main/src/influxDBdashboardTemplate.json) to InfluxDB.
[Generate an InfluxDB Token](https://docs.influxdata.com/influxdb/cloud/security/tokens/create-token/). It will be added to ispConfig.py in the following steps.
## Install LibreQoS

View File

@ -0,0 +1,20 @@
## Network Design Assumptions - Read this First!
Officially supported configuration:
- LibreQoS placed inline in network, usually between an edge router (NAT, firewall) and core router (distribution to sites across network).
* If you use NAT/CG-NAT, place LibreQoS inline south of where NAT is applied, as LibreQoS needs to shape internal addresses (100.64.0.0/12) not public post-NAT IPs.
- Edge and Core routers should have 1500 MTU on links between them
- If you use MPLS, you would terminate MPLS traffic at the core router. LibreQoS cannot decapsulate MPLS on its own.
- OSPF primary link (low cost) through the server running LibreQoS
- OSPF backup link (high cost, maybe 200 for example)
![](https://raw.githubusercontent.com/rchac/LibreQoS/main/docs/design.png)
Is it possible to use LibreQoS in-line without a core router, but that setup requires depending on STP instead of OSPF, which can cause issues. Such configurations are not officially supported.
### Network Interface Card
You must have one of these:
*single NIC with two interfaces,
*two NICs with single interface,
*2x VLANs interface (using one or two NICs).
LibreQoS requires NICs to have 2 or more RX/TX queues and XDP support. While many cards theoretically meet these requirements, less commonly used cards tend to have unreported driver bugs which impede XDP functionality and make them unusable for our purposes. At this time we recommend the Intel x520, Intel x710, and Nvidia (ConnectX-5 or newer) NICs. We cannot guarantee compatibility with other cards.

View File

@ -0,0 +1,71 @@
# LibreQoS daemons
lqosd
- Manages actual XDP code. Build with Rust.
lqos_node_manager
- Runs the GUI available at http://a.b.c.d:9123
lqos_scheduler
- lqos_scheduler handles statistics and performs continuous refreshes of LibreQoS' shapers, including pulling from any enabled CRM Integrations (UISP, Splynx).
- On start: Run a full setup of queues
- Every 10 seconds: Graph bandwidth and latency stats
- Every 30 minutes: Update queues, pulling new configuration from CRM integration if enabled
## Run daemons with systemd
You can setup `lqosd`, `lqos_node_manager`, and `lqos_scheduler` as systemd services.
```shell
sudo cp /opt/libreqos/src/bin/lqos_node_manager.service.example /etc/systemd/system/lqos_node_manager.service
sudo cp /opt/libreqos/src/bin/lqosd.service.example /etc/systemd/system/lqosd.service
sudo cp /opt/libreqos/src/bin/lqos_scheduler.service.example /etc/systemd/system/lqos_scheduler.service
```
Finally, run
```shell
sudo systemctl daemon-reload
sudo systemctl enable lqosd lqos_node_manager lqos_scheduler
```
You can now point a web browser at `http://a.b.c.d:9123` (replace `a.b.c.d` with the management IP address of your shaping server) and enjoy a real-time view of your network.
## Debugging lqos_scheduler
In the background, lqos_scheduler runs scheduler.py, which in turn runs LibreQoS.py
One-time runs of these individual components can be very helpful for debugging and to make sure everything is correctly configured.
First, stop lqos_scheduler
```shell
sudo systemctl stop lqos_scheduler
```
For one-time runs of LibreQoS.py, use
```shell
sudo ./LibreQoS.py
```
- To use the debug mode with more verbose output, use:
```shell
sudo ./LibreQoS.py --debug
```
To confirm that lqos_scheduler (scheduler.py) is able to work correctly, run:
```shell
sudo python3 scheduler.py
```
Once you have any errors eliminated, restart lqos_scheduler with
```shell
sudo systemctl start lqos_scheduler
```

View File

@ -0,0 +1,31 @@
# Share your before and after
We ask that you please share an anonymized screenshot of your LibreQoS deployment before (monitor only mode) and after (queuing enabled) to our [Matrix Channel](https://matrix.to/#/#libreqos:matrix.org). This helps us gauge the impact of our software. It also makes us smile.
1. Enable monitor only mode
2. Klingon mode (Redact customer info)
3. Screenshot
4. Resume regular queuing
5. Screenshot
## Enable monitor only mode
```shell
sudo systemctl stop lqos_scheduler
sudo systemctl restart lqosd
sudo systemctl restart lqos_node_manager
```
## Klingon mode
Please go to the Web UI and click Configuration. Toggle Redact Customer Information (screenshot mode) and then Apply Changes.
## Resume regular queuing
```shell
sudo systemctl start lqos_scheduler
```
## Screenshot
To generate a screenshot - please go to the Web UI and click Configuration. Toggle Redact Customer Information (screenshot mode), Apply Changes, and then return to the dashboard to take a screenshot.

View File

@ -0,0 +1,55 @@
## System Requirements
### VM or physical server
* For VMs, NIC passthrough is required for optimal throughput and latency (XDP vs generic XDP). Using Virtio / bridging is much slower than NIC passthrough. Virtio / bridging should not be used for large amounts of traffic.
### CPU
* 2 or more CPU cores
* A CPU with solid [single-thread performance](https://www.cpubenchmark.net/singleThread.html#server-thread) within your budget. Queuing is very CPU-intensive, and requires high single-thread performance.
Single-thread CPU performance will determine the max throughput of a single HTB (cpu core), and in turn, what max speed plan you can offer customers.
| Customer Max Plan | Passmark Single-Thread |
| --------------------| ------------------------ |
| 100 Mbps | 1000 |
| 250 Mbps | 1500 |
| 500 Mbps | 2000 |
| 1 Gbps | 2500 |
| 2 Gbps | 3000 |
Below is a table of approximate aggregate throughput capacity, assuming a a CPU with a [single thread](https://www.cpubenchmark.net/singleThread.html#server-thread) performance of 2700 or greater:
| Aggregate Throughput | CPU Cores |
| ------------------------| ------------- |
| 500 Mbps | 2 |
| 1 Gbps | 4 |
| 5 Gbps | 6 |
| 10 Gbps | 8 |
| 20 Gbps | 16 |
| 50 Gbps* | 32 |
(* Estimated)
So for example, an ISP delivering 1Gbps service plans with 10Gbps aggregate throughput would choose a CPU with a 2500+ single-thread score and 8 cores, such as the Intel Xeon E-2388G @ 3.20GHz.
### Memory
* Minimum RAM = 2 + (0.002 x Subscriber Count) GB
* Recommended RAM:
| Subscribers | RAM |
| ------------- | ------------- |
| 100 | 4 GB |
| 1,000 | 8 GB |
| 5,000 | 16 GB |
| 10,000* | 18 GB |
| 50,000* | 24 GB |
(* Estimated)
### Server Recommendations
It is most cost-effective to buy a used server with specifications matching your unique requirements, as laid out in the System Requirements section below.
For those who do not have the time to do that, here are some off-the-shelf options to consider:
* 1 Gbps | [Supermicro SuperServer E100-9W-L](https://www.thinkmate.com/system/superserver-e100-9w-l)
* 10 Gbps | [Supermicro SuperServer 510T-ML (Choose E-2388G)](https://www.thinkmate.com/system/superserver-510t-ml)
* 20 Gbps | [Dell R450 Config](https://www.dell.com/en-us/shop/servers-storage-and-networking/poweredge-r450-rack-server/spd/poweredge-r450/pe_r450_15127_vi_vp?configurationid=a7663c54-6e4a-4c96-9a21-bc5a69d637ba)
The [AsRock 1U4LW-B6502L2T](https://www.thinkmate.com/system/asrock-1u4lw-b6502l2t/635744) can be a great lower-cost option as well.

View File

@ -0,0 +1,10 @@
## Network Interface Requirements
* One management network interface completely separate from the traffic shaping interfaces. Usually this would be the Ethernet interface built in to the motherboard.
* Dedicated Network Interface Card for Shaping Interfaces
* NIC must have 2 or more interfaces for traffic shaping.
* NIC must have multiple TX/RX transmit queues. [Here's how to check from the command line](https://serverfault.com/questions/772380/how-to-tell-if-nic-has-multiqueue-enabled).
* Known supported cards:
* [NVIDIA Mellanox MCX512A-ACAT](https://www.fs.com/products/119649.html)
* NVIDIA Mellanox MCX416A-CCAT
* [Intel X710](https://www.fs.com/products/75600.html)
* Intel X520

View File

@ -0,0 +1,55 @@
## System Requirements
### VM or physical server
* For VMs, NIC passthrough is required for optimal throughput and latency (XDP vs generic XDP). Using Virtio / bridging is much slower than NIC passthrough. Virtio / bridging should not be used for large amounts of traffic.
### CPU
* 2 or more CPU cores
* A CPU with solid [single-thread performance](https://www.cpubenchmark.net/singleThread.html#server-thread) within your budget. Queuing is very CPU-intensive, and requires high single-thread performance.
Single-thread CPU performance will determine the max throughput of a single HTB (cpu core), and in turn, what max speed plan you can offer customers.
| Customer Max Plan | Passmark Single-Thread |
| --------------------| ------------------------ |
| 100 Mbps | 1000 |
| 250 Mbps | 1500 |
| 500 Mbps | 2000 |
| 1 Gbps | 2500 |
| 2 Gbps | 3000 |
Below is a table of approximate aggregate throughput capacity, assuming a a CPU with a [single thread](https://www.cpubenchmark.net/singleThread.html#server-thread) performance of 2700 or greater:
| Aggregate Throughput | CPU Cores |
| ------------------------| ------------- |
| 500 Mbps | 2 |
| 1 Gbps | 4 |
| 5 Gbps | 6 |
| 10 Gbps | 8 |
| 20 Gbps | 16 |
| 50 Gbps* | 32 |
(* Estimated)
So for example, an ISP delivering 1Gbps service plans with 10Gbps aggregate throughput would choose a CPU with a 2500+ single-thread score and 8 cores, such as the Intel Xeon E-2388G @ 3.20GHz.
### Memory
* Minimum RAM = 2 + (0.002 x Subscriber Count) GB
* Recommended RAM:
| Subscribers | RAM |
| ------------- | ------------- |
| 100 | 4 GB |
| 1,000 | 8 GB |
| 5,000 | 16 GB |
| 10,000* | 18 GB |
| 50,000* | 24 GB |
(* Estimated)
### Server Recommendations
It is most cost-effective to buy a used server with specifications matching your unique requirements, as laid out in the System Requirements section below.
For those who do not have the time to do that, here are some off-the-shelf options to consider:
* 1 Gbps | [Supermicro SuperServer E100-9W-L](https://www.thinkmate.com/system/superserver-e100-9w-l)
* 10 Gbps | [Supermicro SuperServer 510T-ML (Choose E-2388G)](https://www.thinkmate.com/system/superserver-510t-ml)
* 20 Gbps | [Dell R450 Config](https://www.dell.com/en-us/shop/servers-storage-and-networking/poweredge-r450-rack-server/spd/poweredge-r450/pe_r450_15127_vi_vp?configurationid=a7663c54-6e4a-4c96-9a21-bc5a69d637ba)
The [AsRock 1U4LW-B6502L2T](https://www.thinkmate.com/system/asrock-1u4lw-b6502l2t/635744) can be a great lower-cost option as well.

View File

@ -0,0 +1,10 @@
## Network Interface Requirements
* One management network interface completely separate from the traffic shaping interfaces. Usually this would be the Ethernet interface built in to the motherboard.
* Dedicated Network Interface Card for Shaping Interfaces
* NIC must have 2 or more interfaces for traffic shaping.
* NIC must have multiple TX/RX transmit queues. [Here's how to check from the command line](https://serverfault.com/questions/772380/how-to-tell-if-nic-has-multiqueue-enabled).
* Known supported cards:
* [NVIDIA Mellanox MCX512A-ACAT](https://www.fs.com/products/119649.html)
* NVIDIA Mellanox MCX416A-CCAT
* [Intel X710](https://www.fs.com/products/75600.html)
* Intel X520

View File

@ -0,0 +1,12 @@
# Extras
## Flamegraph
```shell
git clone https://github.com/brendangregg/FlameGraph.git
cd FlameGraph
sudo perf record -F 99 -a -g -- sleep 60
perf script > out.perf
./stackcollapse-perf.pl out.perf > out.folded
./flamegraph.pl --title LibreQoS --width 7200 out.folded > libreqos.svg
```

View File

@ -0,0 +1,28 @@
## Integrations
### UISP Integration
First, set the relevant parameters for UISP (uispAuthToken, UISPbaseURL, etc.) in ispConfig.py.
To test the UISP Integration, use
```
python3 integrationUISP.py
```
On the first successful run, it will create a network.json and ShapedDevices.csv file.
If a network.json file exists, it will not be overwritten.
You can modify the network.json file to more accurately reflect bandwidth limits.
ShapedDevices.csv will be overwritten every time the UISP integration is run.
You have the option to run integrationUISP.py automatically on boot and every 30 minutes, which is recommended. This can be enabled by setting ```automaticImportUISP = True``` in ispConfig.py
### Splynx Integration
First, set the relevant parameters for Splynx (splynx_api_key, splynx_api_secret, etc.) in ispConfig.py.
To test the Splynx Integration, use
```
python3 integrationSplynx.py
```
On the first successful run, it will create a ShapedDevices.csv file.
You can manually create your network.json file to more accurately reflect bandwidth limits.
ShapedDevices.csv will be overwritten every time the Splynx integration is run.
You have the option to run integrationSplynx.py automatically on boot and every 30 minutes, which is recommended. This can be enabled by setting ```automaticImportSplynx = True``` in ispConfig.py

View File

@ -0,0 +1,28 @@
# Performance Tuning
## Ubuntu Starts Slowly (~2 minutes)
### List all services which requires network
```shell
systemctl show -p WantedBy network-online.target
```
### For Ubuntu 22.04 this command can help
```shell
systemctl disable cloud-config iscsid cloud-final
```
### Set proper governor for CPU (baremetal/hypervisior host)
```shell
cpupower frequency-set --governor performance
```
### OSPF
It is recommended to set the OSPF timers of both OSPF neighbors (core and edge router) to minimize downtime upon a reboot of the LibreQoS server.
* hello interval
* dead

View File

@ -0,0 +1,28 @@
# Performance Tuning
## Ubuntu Starts Slowly (~2 minutes)
### List all services which requires network
```shell
systemctl show -p WantedBy network-online.target
```
### For Ubuntu 22.04 this command can help
```shell
systemctl disable cloud-config iscsid cloud-final
```
### Set proper governor for CPU (baremetal/hypervisior host)
```shell
cpupower frequency-set --governor performance
```
### OSPF
It is recommended to set the OSPF timers of both OSPF neighbors (core and edge router) to minimize downtime upon a reboot of the LibreQoS server.
* hello interval
* dead

View File

@ -0,0 +1,12 @@
# Troubleshooting
## Common Issues
### LibreQoS Is Running, But Traffic Not Shaping
- In ispConfig.py, make sure the edge and core interfaces correspond to correctly to the edge and core. Try swapping the interfaces to see if shaping starts to work.
- Make sure your services are running properly `lqos.service`, `lqos_node_manager`, `lqos_scheduler`. Node manager and scheduler are dependent on the `lqos.service` being in a healthy, running state.
### RTNETLINK answers: Invalid argument
This tends to show up when the MQ qdisc cannot be added correctly to the NIC interface. This would suggest the NIC has insufficient RX/TX queues. Please make sure you are using the [recommended NICs](#network-interface-card).

View File

@ -0,0 +1,56 @@
# Complex install (Not Recommended)
## Clone the repo
The recommended install location is `/opt/libreqos`
Go to the install location, and clone the repo:
```shell
cd /opt/
git clone https://github.com/LibreQoE/LibreQoS.git libreqos
sudo chown -R YOUR_USER /opt/libreqos
```
By specifying `libreqos` at the end, git will ensure the folder name is lowercase.
## Install Dependencies from apt and pip
You need to have a few packages from `apt` installed:
```shell
sudo apt-get install -y python3-pip clang gcc gcc-multilib llvm libelf-dev git nano graphviz curl screen llvm pkg-config linux-tools-common linux-tools-`uname -r` libbpf-dev
```
Then you need to install some Python dependencies:
```shell
cd /opt/libreqos
python3 -m pip install -r requirements.txt
sudo python3 -m pip install -r requirements.txt
```
## Install the Rust development system
Go to [RustUp](https://rustup.rs) and follow the instructions. Basically, run the following:
```shell
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```
When Rust finishes installing, it will tell you to execute a command to place the Rust build tools into your path. You need to either execute this command or logout and back in again.
Once that's done, please run:
```shell
cd /opt/libreqos/src/
./build_rust.sh
```
This will take a while the first time, but it puts everything in the right place.
Now, to build rust crates, run:
```shell
cd rust
cargo build --all
```

View File

@ -0,0 +1,12 @@
# Extras
## Flamegraph
```shell
git clone https://github.com/brendangregg/FlameGraph.git
cd FlameGraph
sudo perf record -F 99 -a -g -- sleep 60
perf script > out.perf
./stackcollapse-perf.pl out.perf > out.folded
./flamegraph.pl --title LibreQoS --width 7200 out.folded > libreqos.svg
```

View File

@ -0,0 +1,32 @@
# Integrations
## UISP Integration
First, set the relevant parameters for UISP (uispAuthToken, UISPbaseURL, etc.) in ispConfig.py.
To test the UISP Integration, use
```shell
python3 integrationUISP.py
```
On the first successful run, it will create a network.json and ShapedDevices.csv file.
If a network.json file exists, it will not be overwritten.
You can modify the network.json file to more accurately reflect bandwidth limits.
ShapedDevices.csv will be overwritten every time the UISP integration is run.
You have the option to run integrationUISP.py automatically on boot and every 30 minutes, which is recommended. This can be enabled by setting ```automaticImportUISP = True``` in ispConfig.py
## Splynx Integration
First, set the relevant parameters for Splynx (splynx_api_key, splynx_api_secret, etc.) in ispConfig.py.
To test the Splynx Integration, use
```shell
python3 integrationSplynx.py
```
On the first successful run, it will create a ShapedDevices.csv file.
You can manually create your network.json file to more accurately reflect bandwidth limits.
ShapedDevices.csv will be overwritten every time the Splynx integration is run.
You have the option to run integrationSplynx.py automatically on boot and every 30 minutes, which is recommended. This can be enabled by setting ```automaticImportSplynx = True``` in ispConfig.py

View File

@ -0,0 +1,28 @@
# Performance Tuning
## Ubuntu Starts Slowly (~2 minutes)
### List all services which requires network
```shell
systemctl show -p WantedBy network-online.target
```
### For Ubuntu 22.04 this command can help
```shell
systemctl disable cloud-config iscsid cloud-final
```
### Set proper governor for CPU (baremetal/hypervisior host)
```shell
cpupower frequency-set --governor performance
```
### OSPF
It is recommended to set the OSPF timers of both OSPF neighbors (core and edge router) to minimize downtime upon a reboot of the LibreQoS server.
* hello interval
* dead

View File

@ -0,0 +1,19 @@
# Troubleshooting
## Common Issues
### LibreQoS Is Running, But Traffic Not Shaping
In ispConfig.py, make sure the edge and core interfaces correspond to correctly to the edge and core. Try swapping the interfaces to see if shaping starts to work.
Make sure your services are running properly
- `lqos.service`
- `lqos_node_manager`
- `lqos_scheduler`
Node manager and scheduler are dependent on the `lqos.service` being in a healthy, running state.
### RTNETLINK answers: Invalid argument
This tends to show up when the MQ qdisc cannot be added correctly to the NIC interface. This would suggest the NIC has insufficient RX/TX queues. Please make sure you are using the [recommended NICs](../SystemRequirements/Networking.md).

View File

@ -0,0 +1,24 @@
# Updating 1.4 To Latest Version
```{warning}
If you use the XDP bridge, traffic will stop passing through the bridge during the update (XDP bridge is only operating while lqosd runs).
```
## If you installed with Git
1. Change to your `LibreQoS` directory (e.g. `cd /opt/LibreQoS`)
2. Update from Git: `git pull`
3. Recompile: `./build-rust.sh`
4. `sudo rust/remove_pinned_maps.sh`
Run the following commands to reload the LibreQoS services.
```shell
sudo systemctl restart lqosd
sudo systemctl restart lqos_node_manager
sudo systemctl restart lqos_scheduler
```
## If you installed through the APT repository
All you should have to do in this case is run `sudo apt update && sudo apt upgrade` and LibreQoS should install the new package.

View File

@ -0,0 +1,60 @@
.. LibreQoE documentation master file, created by
sphinx-quickstart on Fri May 19 10:37:27 2023.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to the LibreQoS documentation!
====================================
.. toctree::
:maxdepth: 1
:caption: Readme:
README
.. toctree::
:maxdepth: 1
:caption: Read me first!
docs/Quickstart/networkdesignassumptions
.. toctree::
:maxdepth: 1
:caption: Change Notes:
docs/ChangeNotes/v1.4
.. toctree::
:maxdepth: 1
:caption: Quickstart:
docs/SystemRequirements/Compute
docs/SystemRequirements/Networking
docs/Quickstart/quickstart-prereq
docs/Quickstart/quickstart-libreqos-1.4
docs/Quickstart/configuration
docs/Quickstart/services-and-run
docs/Quickstart/share
.. toctree::
::maxdepth: 1
:caption: Updates:
docs/Updates/update
.. toctree::
:maxdepth: 1
:caption: Technical Documentation:
docs/TechnicalDocs/complex-install
docs/TechnicalDocs/troubleshooting
docs/TechnicalDocs/integrations
docs/TechnicalDocs/extras
docs/TechnicalDocs/performance-tuning
.. toctree::
:maxdepth: 1
:caption: Legacy:
docs/Legacy/v1.3.1

View File

@ -0,0 +1,149 @@
# LibreQoS Integrations
If you need to create an integration for your network, we've tried to give you the tools you need. We currently ship integrations for UISP and Spylnx. We'd love to include more.
### Overall Concept
LibreQoS enforces customer bandwidth limits, and applies CAKE-based optimizations at several levels:
* Per-user Cake flows are created. These require the maximum bandwidth permitted per customer.
* Customers can have more than one device that share a pool of bandwidth. Customers are grouped into "circuits"
* *Optional* Access points can have a speed limit/queue, applied to all customers associated with the access point.
* *Optional* Sites can contain access points, and apply a speed limit/queue to all access points (and associated circuits).
* *Optional* Sites can be nested beneath other sites and access point, providing for a queue hierarchy that represents physical limitations of backhaul connections.
Additionally, you might grow to have more than one shaper - and need to express your network topology from the perspective of different parts of your network. (For example, if *Site A* and *Site B* both have Internet connections - you want to generate an efficient topology for both sites. It's helpful if you can derive this from the same overall topology)
LibreQoS's network modeling accomplishes this by modeling your network as a *graph*: a series of interconnected nodes, each featuring a "parent". Any "node" (entry) in the graph can be turned into a "root" node, allowing you to generate the `network.json` and `ShapedDevices.csv` files required to manage your customers from the perspective of that root node.
### Flat Shaping
The simplest form of integration produces a "flat" network. This is the highest performance model in terms of raw throughput, but lacks the ability to provide shaping at the access point or site level: every customer site is parented directly off the root.
> For an integration, it's recommended that you fetch the customer/device data from your management system rather than type them all in Python.
A flat integration is relatively simple. Start by importing the common API:
```python
from integrationCommon import isIpv4Permitted, fixSubnet, NetworkGraph, NetworkNode, NodeType
```
Then create an empty network graph (it will grow to represent your network):
```python
net = NetworkGraph()
```
Once you have your `NetworkGraph` object, you start adding customers and devices. Customers may have any number of devices. You can add a single customer with one device as follows:
```python
# Add the customer
customer = NetworkNode(
id="Unique Customer ID",
displayName="The Doe Family",
type=NodeType.client,
download=100, # Download is in Mbit/second
upload=20, # Upload is in Mbit/second
address="1 My Road, My City, My State")
net.addRawNode(customer) # Insert the customer ID
# Give them a device
device = NetworkNode(
id="Unique Device ID",
displayName="Doe Family CPE",
parentId="Unique Customer ID", # must match the customer's ID
type=NodeType.device,
ipv4=["100.64.1.5/32"], # As many as you need, express networks as the network ID - e.g. 192.168.100.0/24
ipv6=["feed:beef::12/64"], # Same again. May be [] for none.
mac="00:00:5e:00:53:af"
)
net.addRawNode(device)
```
If the customer has multiple devices, you can add as many as you want - with `ParentId` continuing to match the parent customer's `id`.
Once you have entered all of your customers, you can finish the integration:
```python
net.prepareTree() # This is required, and builds parent-child relationships.
net.createNetworkJson() # Create `network.json`
net.createShapedDevices() # Create the `ShapedDevices.csv` file.
```
### Detailed Hierarchies
Creating a full hierarchy (with as many levels as you want) uses a similar strategy to flat networks---we recommend that you start by reading the "flat shaping" section above.
Start by importing the common API:
```python
from integrationCommon import isIpv4Permitted, fixSubnet, NetworkGraph, NetworkNode, NodeType
```
Then create an empty network graph (it will grow to represent your network):
```python
net = NetworkGraph()
```
Now you can start to insert sites and access points. Sites and access points are inserted like customer or device nodes: they have a unique ID, and a `ParentId`. Customers can then use a `ParentId` of the site or access point beneath which they should be located.
For example, let's create `Site_1` and `Site_2` - at the top of the tree:
```python
net.addRawNode(NetworkNode(id="Site_1", displayName="Site_1", parentId="", type=NodeType.site, download=1000, upload=1000))
net.addRawNode(NetworkNode(id="Site_2", displayName="Site_2", parentId="", type=NodeType.site, download=500, upload=500))
```
Let's attach some access points and point-of-presence sites:
```python
net.addRawNode(NetworkNode(id="AP_A", displayName="AP_A", parentId="Site_1", type=NodeType.ap, download=500, upload=500))
net.addRawNode(NetworkNode(id="Site_3", displayName="Site_3", parentId="Site_1", type=NodeType.site, download=500, upload=500))
net.addRawNode(NetworkNode(id="PoP_5", displayName="PoP_5", parentId="Site_3", type=NodeType.site, download=200, upload=200))
net.addRawNode(NetworkNode(id="AP_9", displayName="AP_9", parentId="PoP_5", type=NodeType.ap, download=120, upload=120))
net.addRawNode(NetworkNode(id="PoP_6", displayName="PoP_6", parentId="PoP_5", type=NodeType.site, download=60, upload=60))
net.addRawNode(NetworkNode(id="AP_11", displayName="AP_11", parentId="PoP_6", type=NodeType.ap, download=30, upload=30))
net.addRawNode(NetworkNode(id="PoP_1", displayName="PoP_1", parentId="Site_2", type=NodeType.site, download=200, upload=200))
net.addRawNode(NetworkNode(id="AP_7", displayName="AP_7", parentId="PoP_1", type=NodeType.ap, download=100, upload=100))
net.addRawNode(NetworkNode(id="AP_1", displayName="AP_1", parentId="Site_2", type=NodeType.ap, download=150, upload=150))
```
When you attach a customer, you can specify a tree entry (e.g. `PoP_5`) as a parent:
```python
# Add the customer
customer = NetworkNode(
id="Unique Customer ID",
displayName="The Doe Family",
parentId="PoP_5",
type=NodeType.client,
download=100, # Download is in Mbit/second
upload=20, # Upload is in Mbit/second
address="1 My Road, My City, My State")
net.addRawNode(customer) # Insert the customer ID
# Give them a device
device = NetworkNode(
id="Unique Device ID",
displayName="Doe Family CPE",
parentId="Unique Customer ID", # must match the customer's ID
type=NodeType.device,
ipv4=["100.64.1.5/32"], # As many as you need, express networks as the network ID - e.g. 192.168.100.0/24
ipv6=["feed:beef::12/64"], # Same again. May be [] for none.
mac="00:00:5e:00:53:af"
)
net.addRawNode(device)
```
Once you have entered all of your network topology and customers, you can finish the integration:
```python
net.prepareTree() # This is required, and builds parent-child relationships.
net.createNetworkJson() # Create `network.json`
net.createShapedDevices() # Create the `ShapedDevices.csv` file.
```
You can also add a call to `net.plotNetworkGraph(False)` (use `True` to also include every customer; this can make for a HUGE file) to create a PDF file (currently named `network.pdf.pdf`) displaying your topology. The example shown here looks like this:
![](testdata/sample_layout.png)

View File

@ -0,0 +1,46 @@
# v1.3 (IPv4 + IPv6)
![image](https://user-images.githubusercontent.com/22501920/202913336-256b591b-f372-44fe-995c-5e08ec08a925.png)
## Features
### Fast TCP Latency Tracking
[@thebracket](https://github.com/thebracket/) has created [cpumap-pping](https://github.com/thebracket/cpumap-pping) which merges the functionality of the [xdp-cpumap-tc](https://github.com/xdp-project/xdp-cpumap-tc) and [ePPing](https://github.com/xdp-project/bpf-examples/tree/master/pping) projects, while keeping CPU use within ~1% of xdp-cpumap-tc.
### Integrations
- Added Splynx integration
- UISP integration overhaul by [@thebracket](https://github.com/thebracket/)
- [LMS integation](https://github.com/interduo/LMSLibreQoS) for Polish ISPs by [@interduo](https://github.com/interduo)
### Partial Queue Reload
In v1.2 and prior, the the entire queue structure had to be reloaded to make any changes. This led to a few milliseconds of packet loss for some clients each time that reload happened. The scheduled.py was set to reload all queues each morning at 4AM to avoid any potential disruptions that could theoretically cause.
Starting with v1.3 - LibreQoS tracks the state of the queues, and can do incremental changes without a full reload of all queues. Every 30 minutes - scheduler.py runs the CRM import, and runs a partial reload affecting just the queues that have changed. It still runs a full reload at 4AM.
### v1.3 Improvements to help scale
#### HTB major:minor handle
HTB uses a hex handle for classes. It is two 16-bit hex values joined by a colon - major:minor (<u16>:<u16>). In LibreQoS, each CPU core uses a different major handle.
In v1.2 and prior, the minor handle was unique across all CPUs, meaning only 30k subscribers could be added total.
Starting with LibreQoS v1.3 - minor handles are counted independently by CPU core. With this change, the maximum possible subscriber qdiscs/classes goes from a hard limit of 30k to instead be 30k x CPU core count. So for a higher end system with a 64 core processor such as the AMD EPYC™ 7713P, that would mean ~1.9 million possible subscriber classes. Of course CPU use will be the bottleneck well before class handles are in that scenario. But at least we have that arbitrary 30k limit out of the way.
#### "Circuit ID" Unique Identifier
In order to improve queue reload time in v1.3, it was necessary to use a unique identifier for each circuit. We went with Circuit ID. It can be a number or string, it just needs to be unique between circuits, and the same for multiple devices in the same circuit. This allows us to avoid costly lookups when sorting through the queue structure.
If you have your own script creating ShapedDevices.csv - you could use your CRM's unique identifier for customer services / circuits to serve as this Circuit ID. The UISP and Splynx integrations already do this automatically.
## Compatability Notes
The most major changes are the renaming of the fqorCake variable to "sqm",
and the addition of the Circuit identifier field.
Also after upgrading to LibreQos v1.3, a reboot is required to clear out the
old ebpf code.

View File

@ -0,0 +1,152 @@
# LibreQoS Integrations
If you need to create an integration for your network, we've tried to give you the tools you need. We currently ship integrations for UISP and Spylnx. We'd love to include more.
### Overall Concept
LibreQoS enforces customer bandwidth limits, and applies CAKE-based optimizations at several levels:
* Per-user Cake flows are created. These require the maximum bandwidth permitted per customer.
* Customers can have more than one device that share a pool of bandwidth. Customers are grouped into "circuits"
* *Optional* Access points can have a speed limit/queue, applied to all customers associated with the access point.
* *Optional* Sites can contain access points, and apply a speed limit/queue to all access points (and associated circuits).
* *Optional* Sites can be nested beneath other sites and access point, providing for a queue hierarchy that represents physical limitations of backhaul connections.
Additionally, you might grow to have more than one shaper - and need to express your network topology from the perspective of different parts of your network. (For example, if *Site A* and *Site B* both have Internet connections - you want to generate an efficient topology for both sites. It's helpful if you can derive this from the same overall topology)
LibreQoS's network modeling accomplishes this by modeling your network as a *graph*: a series of interconnected nodes, each featuring a "parent". Any "node" (entry) in the graph can be turned into a "root" node, allowing you to generate the `network.json` and `ShapedDevices.csv` files required to manage your customers from the perspective of that root node.
### Flat Shaping
The simplest form of integration produces a "flat" network. This is the highest performance model in terms of raw throughput, but lacks the ability to provide shaping at the access point or site level: every customer site is parented directly off the root.
> For an integration, it's recommended that you fetch the customer/device data from your management system rather than type them all in Python.
A flat integration is relatively simple. Start by importing the common API:
```python
from integrationCommon import isIpv4Permitted, fixSubnet, NetworkGraph, NetworkNode, NodeType
```
Then create an empty network graph (it will grow to represent your network):
```python
net = NetworkGraph()
```
Once you have your `NetworkGraph` object, you start adding customers and devices. Customers may have any number of devices. You can add a single customer with one device as follows:
```python
# Add the customer
customer = NetworkNode(
id="Unique Customer ID",
displayName="The Doe Family",
type=NodeType.client,
download=100, # Download is in Mbit/second
upload=20, # Upload is in Mbit/second
address="1 My Road, My City, My State")
net.addRawNode(customer) # Insert the customer ID
# Give them a device
device = NetworkNode(
id="Unique Device ID",
displayName="Doe Family CPE",
parentId="Unique Customer ID", # must match the customer's ID
type=NodeType.device,
ipv4=["100.64.1.5/32"], # As many as you need, express networks as the network ID - e.g. 192.168.100.0/24
ipv6=["feed:beef::12/64"], # Same again. May be [] for none.
mac="00:00:5e:00:53:af"
)
net.addRawNode(device)
```
If the customer has multiple devices, you can add as many as you want - with `ParentId` continuing to match the parent customer's `id`.
Once you have entered all of your customers, you can finish the integration:
```python
net.prepareTree() # This is required, and builds parent-child relationships.
net.createNetworkJson() # Create `network.json`
net.createShapedDevices() # Create the `ShapedDevices.csv` file.
```
### Detailed Hierarchies
Creating a full hierarchy (with as many levels as you want) uses a similar strategy to flat networks---we recommend that you start by reading the "flat shaping" section above.
Start by importing the common API:
```python
from integrationCommon import isIpv4Permitted, fixSubnet, NetworkGraph, NetworkNode, NodeType
```
Then create an empty network graph (it will grow to represent your network):
```python
net = NetworkGraph()
```
Now you can start to insert sites and access points. Sites and access points are inserted like customer or device nodes: they have a unique ID, and a `ParentId`. Customers can then use a `ParentId` of the site or access point beneath which they should be located.
For example, let's create `Site_1` and `Site_2` - at the top of the tree:
```python
net.addRawNode(NetworkNode(id="Site_1", displayName="Site_1", parentId="", type=NodeType.site, download=1000, upload=1000))
net.addRawNode(NetworkNode(id="Site_2", displayName="Site_2", parentId="", type=NodeType.site, download=500, upload=500))
```
Let's attach some access points and point-of-presence sites:
```python
net.addRawNode(NetworkNode(id="AP_A", displayName="AP_A", parentId="Site_1", type=NodeType.ap, download=500, upload=500))
net.addRawNode(NetworkNode(id="Site_3", displayName="Site_3", parentId="Site_1", type=NodeType.site, download=500, upload=500))
net.addRawNode(NetworkNode(id="PoP_5", displayName="PoP_5", parentId="Site_3", type=NodeType.site, download=200, upload=200))
net.addRawNode(NetworkNode(id="AP_9", displayName="AP_9", parentId="PoP_5", type=NodeType.ap, download=120, upload=120))
net.addRawNode(NetworkNode(id="PoP_6", displayName="PoP_6", parentId="PoP_5", type=NodeType.site, download=60, upload=60))
net.addRawNode(NetworkNode(id="AP_11", displayName="AP_11", parentId="PoP_6", type=NodeType.ap, download=30, upload=30))
net.addRawNode(NetworkNode(id="PoP_1", displayName="PoP_1", parentId="Site_2", type=NodeType.site, download=200, upload=200))
net.addRawNode(NetworkNode(id="AP_7", displayName="AP_7", parentId="PoP_1", type=NodeType.ap, download=100, upload=100))
net.addRawNode(NetworkNode(id="AP_1", displayName="AP_1", parentId="Site_2", type=NodeType.ap, download=150, upload=150))
```
When you attach a customer, you can specify a tree entry (e.g. `PoP_5`) as a parent:
```python
# Add the customer
customer = NetworkNode(
id="Unique Customer ID",
displayName="The Doe Family",
parentId="PoP_5",
type=NodeType.client,
download=100, # Download is in Mbit/second
upload=20, # Upload is in Mbit/second
address="1 My Road, My City, My State")
net.addRawNode(customer) # Insert the customer ID
# Give them a device
device = NetworkNode(
id="Unique Device ID",
displayName="Doe Family CPE",
parentId="Unique Customer ID", # must match the customer's ID
type=NodeType.device,
ipv4=["100.64.1.5/32"], # As many as you need, express networks as the network ID - e.g. 192.168.100.0/24
ipv6=["feed:beef::12/64"], # Same again. May be [] for none.
mac="00:00:5e:00:53:af"
)
net.addRawNode(device)
```
Once you have entered all of your network topology and customers, you can finish the integration:
```python
net.prepareTree() # This is required, and builds parent-child relationships.
net.createNetworkJson() # Create `network.json`
net.createShapedDevices() # Create the `ShapedDevices.csv` file.
```
You can also add a call to `net.plotNetworkGraph(False)` (use `True` to also include every customer; this can make for a HUGE file) to create a PDF file (currently named `network.pdf.pdf`) displaying your topology. The example shown here looks like this:
![](testdata/sample_layout.png)
## Longest Prefix Match Tip
You could theoretically throttle all unknown IPs until they are associated with a client. For example, you could limit every unknown to 1.5x0.5 with single entry in ShapedDevices.csv, until you associate them with an account. IPs need to be non-exact matches. So you can't have two 192.168.1.1 entries, but you can have a 192.168.1.0/24 subnet and a 192.168.1.2/32 - they aren't duplicates, and the LPM search is smart enough to pick the most exact match.

View File

@ -0,0 +1,5 @@
# v1.4 (Alpha)
![image](https://i0.wp.com/libreqos.io/wp-content/uploads/2023/01/v1.4-alpha-2.png?w=3664&ssl=1)
See [wiki here](https://github.com/LibreQoE/LibreQoS/wiki/v1.4)

View File

@ -0,0 +1,188 @@
# How to Test V1.4
Version 1.4 is still undergoing active development, but if you'd like to benefit from it right now (or help us test/develop it!), here's a guide.
<strong> Please see the [v1.4 Wiki](https://github.com/LibreQoE/LibreQoS/wiki/v1.4) which replaces this document. </strong>
## Updating from v1.3
### Remove cron tasks from v1.3
Run ```sudo crontab -e``` and remove any entries pertaining to LibreQoS from v1.3.
## Clone the repo
The recommended install location is `/opt/libreqos`.
Go to the install location, and clone the repo:
```
cd /opt/
git clone https://github.com/LibreQoE/LibreQoS.git libreqos
sudo chown YOUR_USER /opt/libreqos -R
```
By specifying `libreqos` at the end, git will ensure the folder name is lowercase.
> Now that this is in `main`, you no longer need to switch git branch. If you were previously on the `v1.4-pre-alpha-rust-integration` branch, please switch to main with `git checkout main; git pull`.
## Install Dependencies from apt and pip
You need to have a few packages from `apt` installed:
```
apt-get install -y python3-pip clang gcc gcc-multilib llvm libelf-dev git nano graphviz curl screen llvm pkg-config linux-tools-common linux-tools-`uname -r` libbpf-dev
```
Then you need to install some Python dependencies:
```
python3 -m pip install ipaddress schedule influxdb-client requests flask flask_restful flask_httpauth waitress psutil binpacking graphviz
```
## Install the Rust development system
Go to [RustUp](https://rustup.rs) and follow the instructions. Basically, run the following:
```
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```
When Rust finishes installing, it will tell you to execute a command to place the Rust build tools into your path. You need to either execute this command or logout and back in again.
Once that's done, change directory to `/wherever_you_put_libreqos/src/`, and run:
```
./build_rust.sh
```
This will take a while the first time, but it puts everything in the right place.
Remember to run this command everytime after `git pull`.
Now, run:
```
cd /src/rust
cargo build --all
```
Again, please run this command everytime after `git pull`.
## Setup the LibreQoS Daemon
Copy the daemon configuration file to `/etc`:
```
sudo cp lqos.example /etc/lqos.conf
```
Now edit the file to match your setup:
```toml
lqos_directory = '/opt/libreqos/src'
queue_check_period_ms = 1000
[tuning]
stop_irq_balance = true
netdev_budget_usecs = 8000
netdev_budget_packets = 300
rx_usecs = 8
tx_usecs = 8
disable_rxvlan = true
disable_txvlan = true
disable_offload = [ "gso", "tso", "lro", "sg", "gro" ]
interface_mapping = [
{ name = "enp1s0f1", redirect_to = "enp1s0f2", scan_vlans = false },
{ name = "enp1s0f2", redirect_to = "enp1s0f1", scan_vlans = false }
]
vlan_mapping = []
```
Change `enp1s0f1` and `enp1s0f2` to match your network interfaces. It doesn't matter which one is which.
## Configure LibreQoS
Follow the regular instructions to set your interfaces in `ispConfig.py` and your `network.json` and `ShapedDevices.csv` files.
## Option A: Run as systemd services
```
sudo cp /opt/libreqos/src/bin/lqos_node_manager.service.example /etc/systemd/system/lqos_node_manager.service
sudo cp /opt/libreqos/src/bin/lqosd.service.example /etc/systemd/system/lqosd.service
sudo cp /opt/libreqos/src/bin/lqos_scheduler.service.example /etc/systemd/system/lqos_scheduler.service
sudo systemctl daemon-reload
sudo systemctl enable lqosd lqos_node_manager lqos_scheduler
```
lqos_scheduler handles statistics and performs continuous refreshes of LibreQoS' shapers, including pulling from any enabled CRM Integrations (UISP, Splynx).
* On start: Run a full setup of queues
* Every 10 seconds: Graph bandwidth and latency stats
* Every 30 minutes: Update queues, pulling new configuration from CRM integration if enabled
## Option B: Run in debug mode
You can setup `lqosd` and `lqos_node_manager` as daemons to keep running (there are example `systemd` files in the `src/bin` folder). Since v1.4 is under such heavy development, I recommend using `screen` to run detached instances - and make finding issues easier.
1. Stop services: systemctl stop lqosd lqos_node_manager
2. `screen`
3. `cd /wherever_you_put_libreqos/src/bin`
4. `sudo ./lqosd`
5. Create a new `screen` window with `Ctrl-A, C`.
6. Run the webserver with `./lqos_node_manager`
7. If you didn't see errors, detach with `Ctrl-A, D`
You can now point a web browser at `http://a.b.c.d:9123` (replace `a.b.c.d` with the management IP address of your shaping server) and enjoy a real-time view of your network.
In the web browser, click `Reload LibreQoS` to setup your shaping rules.
## Updating 1.4 Once You Have It
* Note: On January 22nd 2023 /etc/lqos was changed to /etc/lqos.conf to remedy Issue #205. If upgrading, be sure to move /etc/lqos to /etc/lqos.conf
* Note: If you use the XDP bridge, traffic will stop passing through the bridge during the update (XDP bridge is only operating while lqosd runs).
### If using systemd services
1.
```
sudo systemctl stop lqos_scheduler lqos_node_manager lqosd
```
2. Change to your `LibreQoS` directory (e.g. `cd /opt/LibreQoS`)
3. Update from Git: `git pull`
4. Recompile: `./build_rust.sh`
5.
```
cd /src/rust
cargo build --all
```
6.
```
sudo systemctl start lqosd lqos_node_manager lqos_scheduler
```
### If running debug mode
1. Resume screen with `screen -r`
2. Go to console 0 (`Ctrl-A, 0`) and stop `lqosd` with `ctrl+c`.
3. Go to console 1 (`Ctl-A, 1`) and stop `lqos_node_manager` with `ctrl+c`.
4. Detach from `screen` with `Ctrl-A, D`.
5. Change to your `LibreQoS` directory (e.g. `cd /opt/libreqos`)
6. Update from Git: `git pull`
7. Recompile: `./build_rust.sh`
8. Run: `rust/remove_pinned_maps.sh`
9. Resume screen with `screen -r`.
10. Go to console 0 (`Ctrl-A, 0`) and run `sudo ./lqosd` to restart the bridge/manager.
11. Go to console 1 (`Ctrl-A, 1`) and run `./lqos_node_manager` to restart the web server.
12. If you didn't see errors, detach with `Ctrl-A, D`
## Bugfix for slowly Ubuntu starting (~2 minutes penalty) in situation when one of the networking interface is down during startup
#List all services which requires network
```
systemctl show -p WantedBy network-online.target
```
#For my Ubuntu 22.04 instance this command helped
```
systemctl disable cloud-config iscsid cloud-final
```
## Performance tips
#Set proper governor for CPU (baremetal/hypervisior host)
```
cpupower frequency-set --governor performance
```

View File

@ -0,0 +1,19 @@
# Comprehensively handling errors from the OS is a difficult job
# In test, they rarely happen. In production, doing sane things
# IN ALL CASES, is sane.
# Deciding what the sane things are, for each error return, is hard.
# The example pinned.c file is a good example - What goes wrong if
# ANY of these operations fail? What are the symptoms? Merely
# removing the file does not mean that the daemon holding it open
# notices
See:
https://github.com/LibreQoE/LibreQoS/issues/209
https://github.com/LibreQoE/LibreQoS/issues/208
https://github.com/LibreQoE/LibreQoS/issues/118
And several closed bugs, where EEXIST was not an error. Etc.

View File

@ -0,0 +1,32 @@
# Rust Management System for LibreQoS
> Very much a work in progress. Details will be filled out as it stabilizes.
## Sub Projects
This project contains a number of projects arranged in a workspace. The projects are:
* `lqos_sys` - a library that builds, installs, removes and manages the LibreQoS XDP and TC programs.
* `lqos_bus` - definitions and helper functions for passing data across the local management bus.
* `lqos_config` - a crate that handles pulling configuration from the Python manager.
* `lqosd` - the management daemon that should eventually be run as a `systemd` service.
* When started, the daemon sets up XDP/TC eBPF programs for the interfaces specified in the LibreQoS configuration.
* When exiting, all eBPF programs are unloaded.
* Listens for bus commands and applies them.
* `lqtop` - A CLI tool that outputs the top X downloaders and mostly verifies that the bus and daemons work.
* `xdp_iphash_to_cpu_cmdline` - An almost-compatible command that acts like the tool of the same name from the previous verion.
* `xdp_pping` - Port of the previous release's `xdp_pping` tool, for compatibility. Will eventually not be needed.
## Required Ubuntu packages
* `clang`
* `linux-tools-common` (for `bpftool`)
* `libbpf-dev`
* `gcc-multilib`
* `llvm`
* `pkg-config`
* `linux-tools-5.15.0-56-generic` (the common version doesn't work?)
## Helper Scripts
* `remove_pinned_maps.sh` deletes all of the BPF shared maps. Useful during development.

View File

@ -0,0 +1,15 @@
# LQosConfig
`lqos_config` is designed to manage configuration of LibreQoS.
Since all of the parts of the system need to know where to find LibreQoS, it first looks for a file named `/etc/lqos.conf` and uses that to locate the LibreQoS installation.
`/etc/lqos.conf` looks like this:
```toml
lqos_directory = '/opt/libreqos'
```
The entries are:
* `lqos_directory`: where LibreQoS is installed (e.g. `/opt/libreqos`)

View File

@ -0,0 +1,28 @@
ways_collisions, if you are seeing a lot of these, it's indicative of a ping flood of some kind.
thresh 6Mbit
target 5.0ms
interval 100.0ms
these are the bandwidth and codel settiings. On a vpn interface, or in a place where the typical rtt is to sydney and back, you can set rtt lower in cake, otherwise, don't touch.
pk_delay 440us
av_delay 13us
sp_delay 2us
All these are ewmas (I forget the interval). pk_delay would be a good statistic to graph, tho I suspect that the highest peak delays would be on the lowest end plans, so peak delay by plan would pull out folk that were above average here.
av_delay is pretty useless, like all averages, IMHO. Still I could be wrong.
sp_delay = sparse delay and is an indicator of overload. Customers with the largest sparse delay would be interesting. Ideally this number never cracks 2ms.
backlog - a persistent backlog is OK, but a sign that someone is using a torrent-like app, doing a big backup, or underprovisioned in some way. Seeing a persistent backlog in an AP on the other hand says the AP is overloaded.
pkts
bytes
do what they say and are a summary statistic since invokation of cake.
way_inds
way_mis
way_cols are indicators of how well the FQ is working, but not ver good ones.
drops
marks
ack_drop
in general I care about pkts, ack_drops, drops and marks, most, these are best plotted together on an invlog scale. When last I looked robert was combining drops and marks to treat as drops (which they are), but I am caring about the rise of ECN in general. As for the top 10 approach, the largest number of drops or marks relative to packets, would be useful.
sp_flows 1
bk_flows 1
un_flows 0
bulk_flows indicate large transfers. They have nothing to do with diffserv marks, they are just bulk.
max_len - if this is greater than your MTU, GRO and GSO are loose on your network.
Quantum varies as a function of bandwidth, it may be 300 is more optimal than an MTU even at higher bandwidths than we first tested cake at.

Some files were not shown because too many files have changed in this diff Show More