Skip to content

Releases: Bluedot-Insight/quantumipoebng

QuantumTouch BNG 1.3.0

Choose a tag to compare

@Bobafettywut Bobafettywut released this 16 Sep 20:23

QuantumTouch BNG 1.3.0

Release notes for the QuantumTouch BNG appliance and console, combined with the
Quantum BNG controller's own v1.3.0 notes. Controller-layer items are marked
[controller]; everything else is the QuantumTouch console, installer and
evaluation appliance.

Overview

Onboarding that scales, and the console surfaces to drive it.

The controller's serial punt→DHCP bottleneck is gone and the run-over-run
throughput decay that used to require a systemctl restart is fixed, so
back-to-back high-count runs hold their rate. Churn no longer over-drains live
sessions.

On top of that, bulk subscriber provisioning and out-of-contract DSCP
marking
gained console pages, RADIUS exchanges became a source on the audit
timeline, and the appliance gained a Grafana dashboard pack installable in
one click.

Two further capabilities are staged rather than delivered in this release.
Capacity licensing and local CDR / usage records both have their console
surfaces in place and their controller-side plumbing landing, but neither is
ready to operate in 1.3.0 — they complete in 1.4.0. They are described under
Staged for 1.4.0 below rather than among the new features, so nobody plans
around them this cycle.

Component versions

Component 1.2.0 shipped 1.3.0 ships
Quantum BNG controller v1.2.0 v1.3.0
quantum_core v1.4.0 v1.5.0
quantumtouch-bng (console plugin) 0.9.x 0.10.31
quantumtouch-core 0.10.x 0.10.16
CPESIM plugin v0.3.7 v0.4.16
VPP 25.10 25.10.0-23
Installer bundle 1.2.0-63 1.3.0-13

Ubuntu 24.04 (Noble), x86_64. The evaluation appliance ships GA kernel 6.8
deliberately — see Known issues.


New features

Onboarding scale and throughput [controller] (#11, #27)

  • Punt→DHCP processing is no longer strictly serial. Punts are fast-consumed,
    deduplicated by subscriber identity and applied in batched session adds, so
    completion no longer collapses as the concurrent-request rate rises.
  • Onboarding throughput no longer degrades cumulatively under heavy load, and
    no longer needs a restart to recover.

Measured. Against a 900/s requested in-rush, the box completes the cold
phase at ~600 subscribers/s (run 670: 605.65/s cold, 491.8/s warm; runs
663/665/669/670 average ~610/s cold), with limited_by: none — neither the
BNG nor the load generator saturated at that rate. Earlier in the cycle the
same suite could only request 220/s; the generator-side work in CPESIM 0.4.16
is what made a rate this high askable, and the box answered it.

Bulk local-AAA provisioning [controller + console] (#26)

Gated-mode admission previously required one PUT per subscriber line, which
serialised through the controller and collapsed provisioning throughput at
scale. A bulk endpoint loads many lines in one atomic call.

The console's bulk subscriber import was rewritten onto that atomic endpoint,
with batched subscriber and session reads and an all-or-nothing result
state
— a partial import no longer leaves the operator guessing which rows
landed. The per-row console path cost three controller round-trips per
subscriber (a record GET, a full session-list GET, and the record PUT), which
is what held CSV import to ~2/s before this change.

Captive-portal URL via DHCP Option 114 [controller] (#25)

The DHCP OFFER/ACK path emits Option 114 (RFC 7710 / 8910) carrying the
captive-portal metadata URL, so iOS 12+, Android 10+, macOS 10.13+ and
Windows 10 2004+ natively detect the captive network and open the sign-in flow.
No DNS-interception fallback required.

Out-of-contract DSCP marking [controller + console] (#19)

The per-subscriber trTCM policer DSCP-marks yellow (out-of-contract) traffic as
AF11 on both upstream and downstream paths, so downstream devices can
differentiate in- from out-of-contract packets. Previously yellow was counted
but forwarded byte-identical to green; green/red behaviour is unchanged (red
still dropped). The console gained a DSCP marking policy section on the
Dataplane page
to set it, and the dashboard's QoS panel captions the
active marking state.

RADIUS diagnostics on the audit timeline

radius-exchanges joins qt-events as a source on the audit timeline:
decoded, linted RADIUS exchanges shown beside everything else that happened on
the box, so a failing subscriber authentication can be read without leaving the
console or running tcpdump by hand.

Off by default, and opt-in. When enabled, the box elects a single capture
owner so four gunicorn workers cannot start four dumpcap children over one
ring buffer, and every path where a capture was requested but could not be
started publishes that fact rather than showing an empty feed. With capture
off, the timeline's "no tap" clause is a true statement rather than an absence
of evidence.

RADIUS shared secrets are read for verification and never emitted — the
timeline distinguishes thirteen secret states without printing one.

Prometheus read proxy

A same-origin read proxy for Prometheus with a default-deny allowlist,
registered on /api/bng and forwarding allowlisted reads unwrapped. This is
what lets a Grafana instance query the box without handing it broad access, and
it pairs with the scoped metrics-only API key preset below.

Grafana dashboard pack

A curated BNG dashboard pack, installable in one click from About → Toybox,
with a multi-select download. Platform Health reads the host rather than a
metric that never populated, and host sections sort above the fold.

Supporting work: a Prometheus read proxy with a default-deny allowlist, and
a Grafana/metrics-only API key preset with a 365-day default expiry and a
visible path_scope, so a dashboard key is visibly scoped to what it can read.

Observability

IPMI chassis sensors are exported to Prometheus, and Prometheus alerting rules
ship wired into rule_files.


Staged for 1.4.0

Both of these have shipped code in 1.3.0 and neither is ready to use. They are
here because the controller-side work landed this cycle and we would rather stage
the console against it now than build it all in one jump later — but treat them
as groundwork, not capability.

Capacity-tier session licensing

[controller] The controller gained capacity licensing in v1.3.0. The free
tier is capped at 1,000 concurrent sessions; a signed capacity licence raises the
cap to a per-customer limit and applies immediately on activation. Licensing
gates capacity only, never function — a missing, expired or tampered licence
reverts to the free-tier cap rather than blocking operation. GET /bng/health
sessions.max reflects the active cap. Activation requires a TPM 2.0 device;
the free tier requires neither a licence nor a TPM.

Activation is done on the box with quantum-license-fingerprint,
quantum-license-install and quantum-license-status.

[console] A Licensing page exists and shows the capacity in force. It cannot
yet operate activation — see Known issues. The evaluation appliance ships a
vTPM (state stripped at export, so each import seeds its own identity) so the
flow can be exercised there once the console side completes.

Nothing here changes what a 1.3.0 box does. Without a licence — which is
every box today — the free tier applies exactly as before.

Local CDR / usage records

[controller] Durable per-subscriber usage records, the local-AAA analogue of
RADIUS accounting, persisted on the box for operators who bill by usage.

[console] A Usage Records page lists them with CSV download and an
Acknowledge & prune action that permanently removes what it consumes —
download before acknowledging.

Marked a preview: records are held, downloadable and prunable, but RADIUS
accounting is not enabled in this release, so they are not produced from live
subscriber traffic. Full accounting arrives in 1.4.0.

Evaluation appliance

The build account is gone. Previous appliances — including the published
v1.2.0-63 — shipped the Vagrant build account: user vagrant with the
well-known default password, passwordless sudo, and sshd accepting password
authentication on a forwarded port. That is remote root on any reachable
appliance, guessable without ever downloading the image. The account, its
sudoers grants and the build host keys are now removed before export, SSH
password authentication is off, and each appliance regenerates its own host
keys on first boot.

Console access is preserved: a random root password is generated per build
and recorded in /root/QUICKSTART.md beside the web credentials. It is a
console credential — it will not work over SSH.

Other appliance changes:

  • The Vagrant shared folder is no longer exported. It pointed at the build
    machine's directory, so VirtualBox reported invalid storage on import and the
    OVA leaked the builder's filesystem layout.
  • The documented 8 GiB minimum is now actually reachable. Preflight
    floor-divided MemTotal, which excludes firmware reservation, so a genuine
    8 GiB box read as 7 GiB and was refused — on real hardware, not just in a VM.
    It rounds to the nearest GiB now.
  • Hugepages are sized to the box. The installer reserved a flat 8 GiB
    regardless of RAM, which on an 8 GiB box is the entire machine. The budget is
    tiered (8192 MiB at ≥12 GiB, 2048 MiB at ≥6 GiB, 1024 MiB below), so boxes at
    or above 12 GiB — the perf rig and every production target — are unchanged.
  • The intermittent first-boot hang is fixed. Roughly 1 first boot in 6-10
    after import never reached the web console, stalling in
    systemd-tmpfiles-setup-dev-early with a (no limit) job timer. It was
    present in v1.2.0-63 at the same rate, so it is not new in this release, and
    a power cycle always recovered it — but a first impression should not need
    one. The cause is a stalled *e...
Read more

QuantumTouch BNG 1.3.0

Choose a tag to compare

@Bobafettywut Bobafettywut released this 14 Sep 19:10

QuantumTouch BNG 1.3.0

Release notes for the QuantumTouch BNG appliance and console, combined with the
Quantum BNG controller's own v1.3.0 notes. Controller-layer items are marked
[controller]; everything else is the QuantumTouch console, installer and
evaluation appliance.

Overview

Onboarding that scales, and the console surfaces to drive it.

The controller's serial punt→DHCP bottleneck is gone and the run-over-run
throughput decay that used to require a systemctl restart is fixed, so
back-to-back high-count runs hold their rate. Churn no longer over-drains live
sessions.

On top of that, 1.3.0 is the release where the standalone story becomes usable
from the UI rather than the API: capacity licensing, bulk subscriber
provisioning
, local CDR / usage records, and out-of-contract DSCP
marking
all gained console pages, and the appliance gained a Grafana
dashboard pack
installable in one click.

Component versions

Component 1.2.0 shipped 1.3.0 ships
Quantum BNG controller v1.2.0 v1.3.0
quantum_core v1.4.0 v1.5.0
quantumtouch-bng (console plugin) 0.9.x 0.10.31
quantumtouch-core 0.10.x 0.10.16
CPESIM plugin v0.3.7 v0.4.16
VPP 25.10 25.10.0-23
Installer bundle 1.2.0-63 1.3.0-09

Ubuntu 24.04 (Noble), x86_64. The evaluation appliance ships GA kernel 6.8
deliberately — see Known issues.


New features

Onboarding scale and throughput [controller] (#11, #27)

  • Punt→DHCP processing is no longer strictly serial. Punts are fast-consumed,
    deduplicated by subscriber identity and applied in batched session adds, so
    completion no longer collapses as the concurrent-request rate rises.
  • Onboarding throughput no longer degrades cumulatively under heavy load, and
    no longer needs a restart to recover.

Capacity-tier session licensing [controller + console]

The free tier is capped at 1,000 concurrent sessions. A signed capacity
licence raises the cap to a per-customer limit, validated end-to-end to 100,000.

Licensing gates capacity only, never function: a missing, expired or
tampered licence reverts to the free-tier cap and never blocks operation.
GET /bng/health sessions.max reflects the active cap, and a licensed limit
applies immediately on activation with no restart.

New Licensing page in the console covers the whole flow — read the box
fingerprint, send it to Bluedot, activate the returned file, and see the
resulting capacity — so activation no longer requires the CLI. Capacity
activation requires a TPM 2.0 device on the target; the free tier requires
neither a licence nor a TPM. The evaluation appliance now ships with a vTPM,
and its state is stripped at export so each import seeds its own identity.

The dashboard also gained a session-capacity indicator showing live count
against the active cap.

Bulk local-AAA provisioning [controller + console] (#26)

Gated-mode admission previously required one PUT per subscriber line, which
serialised through the controller and collapsed provisioning throughput
(~2/s against ~25/s) at scale. A bulk endpoint loads many lines in one call,
restoring realistic 500–650-CPE provisioning rates.

The console's bulk subscriber import was rewritten onto that atomic endpoint,
with batched subscriber and session reads and an all-or-nothing result
state
— a partial import no longer leaves the operator guessing which rows
landed.

Local CDR / usage export [controller + console] (#23)

Standalone and local-AAA deployments that bill by usage now get durable
per-subscriber usage records — the local-AAA analogue of RADIUS accounting —
persisted on the box, beyond the live GET /bng/counters gauges.

A Usage Records page exposes them in the console, with a confirmed prune.
The page is marked a 1.3.0 preview.

Captive-portal URL via DHCP Option 114 [controller] (#25)

The DHCP OFFER/ACK path emits Option 114 (RFC 7710 / 8910) carrying the
captive-portal metadata URL, so iOS 12+, Android 10+, macOS 10.13+ and
Windows 10 2004+ natively detect the captive network and open the sign-in flow.
No DNS-interception fallback required.

Out-of-contract DSCP marking [controller + console] (#19)

The per-subscriber trTCM policer DSCP-marks yellow (out-of-contract) traffic as
AF11 on both upstream and downstream paths, so downstream devices can
differentiate in- from out-of-contract packets. Previously yellow was counted
but forwarded byte-identical to green; green/red behaviour is unchanged (red
still dropped). The console gained a DSCP marking policy section on the
Dataplane page
to set it, and the dashboard's QoS panel captions the
active marking state.

RADIUS diagnostics on the audit timeline

radius-exchanges joins qt-events as a source on the audit timeline:
decoded, linted RADIUS exchanges shown beside everything else that happened on
the box, so a failing subscriber authentication can be read without leaving the
console or running tcpdump by hand.

Off by default, and opt-in. When enabled, the box elects a single capture
owner so four gunicorn workers cannot start four dumpcap children over one
ring buffer, and every path where a capture was requested but could not be
started publishes that fact rather than showing an empty feed. With capture
off, the timeline's "no tap" clause is a true statement rather than an absence
of evidence.

RADIUS shared secrets are read for verification and never emitted — the
timeline distinguishes thirteen secret states without printing one.

Prometheus read proxy

A same-origin read proxy for Prometheus with a default-deny allowlist,
registered on /api/bng and forwarding allowlisted reads unwrapped. This is
what lets a Grafana instance query the box without handing it broad access, and
it pairs with the scoped metrics-only API key preset below.

Grafana dashboard pack

A curated BNG dashboard pack, installable in one click from About → Toybox,
with a multi-select download. Platform Health reads the host rather than a
metric that never populated, and host sections sort above the fold.

Supporting work: a Prometheus read proxy with a default-deny allowlist, and
a Grafana/metrics-only API key preset with a 365-day default expiry and a
visible path_scope, so a dashboard key is visibly scoped to what it can read.

Observability

IPMI chassis sensors are exported to Prometheus, and Prometheus alerting rules
ship wired into rule_files.


Evaluation appliance

The build account is gone. Previous appliances — including the published
v1.2.0-63 — shipped the Vagrant build account: user vagrant with the
well-known default password, passwordless sudo, and sshd accepting password
authentication on a forwarded port. That is remote root on any reachable
appliance, guessable without ever downloading the image. The account, its
sudoers grants and the build host keys are now removed before export, SSH
password authentication is off, and each appliance regenerates its own host
keys on first boot.

Console access is preserved: a random root password is generated per build
and recorded in /root/QUICKSTART.md beside the web credentials. It is a
console credential — it will not work over SSH.

Other appliance changes:

  • The Vagrant shared folder is no longer exported. It pointed at the build
    machine's directory, so VirtualBox reported invalid storage on import and the
    OVA leaked the builder's filesystem layout.
  • The documented 8 GiB minimum is now actually reachable. Preflight
    floor-divided MemTotal, which excludes firmware reservation, so a genuine
    8 GiB box read as 7 GiB and was refused — on real hardware, not just in a VM.
    It rounds to the nearest GiB now.
  • Hugepages are sized to the box. The installer reserved a flat 8 GiB
    regardless of RAM, which on an 8 GiB box is the entire machine. The budget is
    tiered (8192 MiB at ≥12 GiB, 2048 MiB at ≥6 GiB, 1024 MiB below), so boxes at
    or above 12 GiB — the perf rig and every production target — are unchanged.
  • The appliance ships 4 vCPU / 8 GiB, matching what its README advertises
    for the first time.
  • The appliance's virtual disk advertises 64 GiB but occupies ~4.3 GiB.
    It is dynamically allocated: VirtualBox writes blocks on demand and does not
    pre-check the host against the advertised size, so you do not need 64 GiB
    free to import or run it
    . Verified by importing and booting this appliance
    on a 9.8 GiB volume — it used 4.3 GiB and left 5.5 GiB free. Budget roughly
    7 GiB in total: 2.1 GiB for the download plus ~4.3 GiB for the imported VM.
    The guest's root filesystem is 31 GiB, so the file can grow toward that under
    heavy use; on a tight volume leave headroom, since a full host pauses the VM
    with a disk-full error. (Earlier notes said 20 GiB, which was never what
    shipped.)
  • CPESIM v0.4.16: struct-packed DHCP relay frames (36× on the rig, 17.2×
    measured on the appliance, byte-identical to the previous output), each frame
    parsed once instead of twice, a tick_hz throttle that had been declared and
    never referenced while costing 76% of the onboard loop, and QoS scoring that
    no longer counts subscribers which produced no measurement.

Bug fixes

Controller

  • Churn no longer over-drains live sessions (#24). Session reconciliation
    matches on subscriber identity rather than MAC only, so a subscriber that
    reconnects during churn keeps its live session. (A v1.2.0 known issue, now
    resolved.)
  • Idle sessions are no longer reaped prematurely. Idle detection
    establishes a counter baseline on a session's first interim before accruing
    idle time, so a session survives its full configured idle_timeout.
  • Reset fully clears the dataplane session table, so no stale entry
    survives to collide with a re-added framed IP (previously
    ...
Read more

QuantumTouch BNG v1.2.0-63 — OVA build actually persists wizard state (the -58..-62 shipping bug)

Choose a tag to compare

@Bobafettywut Bobafettywut released this 14 Aug 18:03

QuantumTouch BNG 1.2.0 — installer wrapper v1.2.0-63

The shipped-OVA CPESIM-doesn't-onboard bug is fixed. Every OVA from v1.2.0-58 through v1.2.0-62 shipped with an unusable BNG state — evaluators following the guide's Step 7 (install CPESIM, click Start) would see the fleet "start" but no subscribers ever onboard. v1.2.0-63 fixes it end-to-end and adds a build-time assertion so this class of failure can't recur silently.

What's fixed since v1.2.0-62

  • OVA build-time wizard bootstrap now actually persists all sections. The v1.2.0-58..-62 build ran 50-bootstrap-wizard.sh cleanly, the wizard's apply endpoint returned 200 with "Plans OK, Pools OK, Data Plane OK, ...", and the build log printed every section OK — but the resulting OVA shipped with the controller's pool/plan/dataplane state empty, because vagrant halt at end of the build escalated to force-shutdown before pending SQLite WAL frames + settings.json writes made it durable. Root cause + full investigation: docs/reports/2026-08-14-ova-wizard-bootstrap-only-cpu-and-auth-persist.md.
  • Three-layer fix:
    1. 50-bootstrap-wizard.sh now waits for the controller to be responsive before POSTing, forces sqlite3 PRAGMA wal_checkpoint(TRUNCATE) on controller.db after apply (via built-in Python — no new deps), double-syncs, then does a readback assertion that GETs /v1/bng/pools + /v1/bng/plans and confirms the data is actually there. If readback fails, the script exits 2 and fails the whole build — no more silent-fail OVAs.
    2. build-ova.sh replaces vagrant halt (which escalates to force-shutdown when services take >30s) with an in-guest sudo systemctl poweroff that respects service ordering + syncs the filesystem. Poll VBoxManage until the VM shows powered-off; only fall back to force-halt after 120s.
    3. 50-bootstrap-wizard.sh also adds a controller-readiness wait so PUTs don't spuriously fail with 503 while quantum-controller is still starting up.

Three evaluation paths

Fastest — pre-built VirtualBox appliance (OVA)

Download:  quantumtouch-bng-eval-v1.2.0-63.ova    (~2 GiB)
Sizing:    4 vCPU, 12 GiB RAM
Login:     admin / BluedotEval2026   ← rotate on first login
Console:   USB-tablet mouse (no capture), clipboard bidirectional

Import into VirtualBox (File → Import Appliance), boot, open https://localhost:8443/ (NAT port-forward pre-baked). SSH ssh -p 2222 vagrant@localhost (password vagrant) if you want a shell.

All 8 wizard sections applied end-to-end. Install the CPESIM plugin (About → Toybox → CPESIM → Install), click Start with 10 subscribers, and the fleet actually onboards. Aggregate throughput hovers around 200 Mbps.

Scripted — Vagrantfile

VERSION=1.2.0-63
curl -LO https://github.com/Bluedot-Insight/quantumipoebng/releases/download/v${VERSION}/Vagrantfile
export QBNG_GH_TAG=v${VERSION}
vagrant up
vagrant provision --provision-with install
vagrant reload

From-scratch — installer tarball

curl -LO https://github.com/Bluedot-Insight/quantumipoebng/releases/download/v${VERSION}/quantumipoebng_v${VERSION}.tar.gz
tar xzf quantumipoebng_v${VERSION}.tar.gz
cd quantumtouch-installer-${VERSION}
sudo ./install.sh

What's in the box

Component Version
Upstream controller (VPP + Quantum Controller + vpp-bridge) Bluedot-Insight/bng@v1.2.0
bng-deploy shim + setup-wizard webui 0.10.27
quantumtouch-core framework v0.10.12
CPESIM subscriber simulator (optional, install via About → Toybox) v0.4.15
Installer wrapper 1.2.0-63

Verification (optional)

Every asset ships with a .sha256 sidecar. HTTPS covers transit, so this only guards against on-disk corruption after download.