New features

AAA as system of record [console]

Local AAA is now the authoritative subscriber store, not a view over controller
config. subscriber_id is treated as an exact opaque key everywhere — never
folded, never case-normalised, never inferred from a locator. Enforcement
overlays converge on every reconcile pass rather than drifting until something
rewrites them, and a subscriber the console does not manage has its overlays
left alone.

Data-cap enforcement [console]

An operator sets a monthly cap and a consequence; the box applies it. The
subscriber drawer carries a data-cap panel showing the policy, the usage against
it and the grant history. Disabling enforcement clears every overlay rather than
leaving the last one in force.

Static IP assignment [console]

Assign a fixed address from the subscriber drawer. A conflicting address is
rejected before it is written rather than after. "Not mentioned" and "unassign
me" are now distinguishable, which they were not — an update that simply did not
mention an address used to read as a request to remove it.

Per-subscriber raw rate [console]

A raw per-subscriber rate, expressed as a plan, settable from the subscriber
drawer — with the consequence for that subscriber's cap stated on the same
screen rather than discovered later.

Subscriber sessions [console]

An account's live sessions are listed on its own page, and an operator can end
them from there.

Support bundle [console]

One button produces a diagnostic bundle for a ticket. It leads with a written
summary rather than a directory dump, and does its own first-pass triage: GRUB
drift, a licensed box mislabelled free_baseline, a packet capture that caught
nothing, VPP workers against rx-queues, retained config revisions.

It collects intent as well as running state — what the operator meant to
configure, not only what is currently live — and runs detached, because an
in-worker collection thread used to take the dashboard down with it.

New in this release: the controller's cumulative health counters. GET /bng/health is point-in-time and structurally cannot say the dataplane
connection has dropped four times today; the bundle samples it three times at
ten-second intervals, so it catches a flap only if one happens inside that
window. connection_lost_count states it for the whole uptime.

Add-on lifecycle [console]

Update checking that knows when to stay quiet, install from an uploaded tarball
for an offline box, a catalogue whose URL an offline mirror can own, and
retention of one previous artifact so a failed update can roll back without a
download.

Health page

The VPP card now qualifies "Connected" with how often the connection has
dropped, and goes amber when connected-but-flapping. A green pill over a link
that dropped four times reads as "nothing to see here" to the operator who is on
the phone about it.


Alerting and the metrics reference

Six new Prometheus alert rules ship in the bundle, covering data-cap
enforcement — which previously had none, despite being the subsystem that
throttles paying subscribers:

alert fires when
BngCapEvaluationStopped the evaluation loop has died — no caps applied, lifted or rolled over
BngCapOverlayFailing a cap was decided but the push to the controller failed
BngCapEnforcementSpike mass enforcement against the recent baseline
BngAccountingRecordsQuarantined a record could not be parsed, so it will not be billed
BngAaaUnmanagedSubscribers subscribers exist on the box that the console does not manage
BngAaaPartialPushPersisting pending provisioning pushes have stopped draining

BngSessionCapApproaching is also fixed: in the alpha it could never
fire, which is worse than no alert because it reads as coverage.

docs/metrics/prometheus-metrics.md now documents all 36 exported metric
families, up from 18. Everything the 1.4.0 subsystems added — data caps, the
accounting drain, AAA reconcile — was previously undocumented, which left half
the /metrics surface unusable for building your own dashboards. The reference
now also states which families are emitted on the 60-second accounting-drain
tick rather than the 5-second sampler tick, since that changes what a sensible
rate() window looks like.


From the controller [controller]

Delivered upstream in controller 1.4.0 and available to every console in this
release:

  • Faster subscriber onboarding. The DHCP onboarding path runs on a dedicated
    worker pipeline with request batching and de-duplication, raising the sustained
    rate at which subscribers can join and smoothing bursts.
  • Reboot resilience. After a bridge or controller restart, DHCP punting
    re-subscribes correctly and health reports the real state rather than
    reporting OK while delivering nothing.
  • Session recovery. A session the data plane retained through a recovery
    cycle is re-adopted rather than dropped, removing a class of divergence
    between the controller and the data plane.
  • Accounting across an unclean restart. Open accounting records are
    reconciled and tagged correctly rather than being left open.
  • Captive-portal refinements. A short portal lease settles activation
    faster, and additional TCP ports can be opened through the walled garden.