Netvyn BNG — CLI User Guide¶
The operator command reference for the Netvyn carrier-grade broadband network gateway.
The Netvyn CLI is a Huawei-style two-view command line, launched with the bng-cli
process. You start in an operational user view (<Netvyn-BNG>) for show,
ping, and traceroute, and enter system-view ([Netvyn-BNG]) to configure the
box. Configuration is staged in a candidate and applied atomically with commit,
with rollback, save, and load completing a Cisco/Juniper-style transaction model.
TAB completion and keyword abbreviation are available at every prompt.
Table of Contents¶
- Configuration Modes
- Command Syntax
- Context Help
- Interface Commands
- PPPoE Commands
- IPoE Commands
- Routing Commands
- Firewall Commands
- NAT / CGNAT Commands
- QoS Commands
- RADIUS Commands
- Monitoring Commands
- Debug Commands
- Show Commands Reference
- Configuration Examples
- Best Practices
show interfacedetail
1. Configuration Modes¶
1.1 User view vs. system-view¶
The Netvyn CLI has two operating contexts, and the prompt always tells you where you are.
| Prompt | Context | What you can do |
|---|---|---|
<Netvyn-BNG> |
User view (operational) | show / display, ping, traceroute, and the transaction verbs |
[Netvyn-BNG] |
System-view (configuration) | Everything above, plus config edits |
The view is where you are; your role governs what you may run (see §12.5). A
readoperator can enter system-view but is still refused config edits;system …CPU/topology commands need thefullrole.
Enter configuration mode with system-view and leave it with return (or quit
from the config root):
<Netvyn-BNG> system-view
[Netvyn-BNG]
[Netvyn-BNG] return
<Netvyn-BNG>
Global verbs — show, display, the transaction verbs (commit / rollback /
save / load), and the diagnostics ping / traceroute — resolve from any
context, including the user view. You do not need system-view to run a ping
or a show.
1.2 Configuration views¶
Within system-view, related configuration is grouped into views. Entering a view changes the prompt and lets you drop the leading keyword:
[Netvyn-BNG] nat → [Netvyn-BNG-nat]
[Netvyn-BNG-nat] enable (interpreted as: nat enable)
[Netvyn-BNG-nat] quit → [Netvyn-BNG]
There are two kinds of view:
- Keyword views —
system,ppp,dhcp,nat,firewall,radius,routing,arp. - Object (name-keyed) views —
interface <name>,pool <name>. The name may be new (which creates the object) or existing (which edits it); the prompt carries the name, e.g.[Netvyn-BNG-pool-default].
quit steps up one level. Every command can also be typed in full from the config
root without entering its view — nat enable works directly at [Netvyn-BNG].
1.3 The candidate / running / startup model¶
Configuration edits stage into a candidate. Nothing applies to the live system
until you commit. This mirrors the Cisco/Juniper transaction model and is the same
contract used by the GUI and monitoring API.
There are three configuration stores:
- Candidate — your staged, not-yet-applied edits.
- Running — the configuration currently applied and forwarding traffic.
- Startup — the saved configuration that survives a reboot.
1.4 Transaction verbs¶
| Command | Effect | Timing |
|---|---|---|
commit |
Validate the candidate and apply it to running | Immediate |
commit confirmed [<minutes>] |
Apply now, auto-revert in <minutes> (default 10) unless confirmed |
Immediate |
confirm |
Keep a pending commit confirmed (cancel the auto-revert) |
Immediate |
rollback |
Discard candidate edits | Immediate |
save |
Write running → startup (survives reboot) | Immediate |
load |
Read startup into the candidate | Immediate |
commit confirmed is the safety net for risky changes: if a change cuts off your own
management access, doing nothing restores the previous running config automatically
after the timer expires. If the change is good, run confirm to make it permanent.
1.5 Apply timing¶
Most configuration takes effect at commit. Many high-value knobs apply live on
commit without dropping subscriber sessions — for example nat policy, firewall
enable / urpf, pool add/remove, ip / ipv6 address add/remove, ppp interface
and dhcp interface add/remove, qos subscriber-profile / qos assign, arp
tuning, and ip route / ipv6 route (including the default-gateway row). A smaller
set of changes — firewall mangle/filter rules, radius settings,
ipv6 pool reshapes — take effect on restart (nat pool edits apply live for NEW sessions). Each section below notes its own
apply timing, and Section 16 summarizes the rules.
1.6 Pending changes on exit¶
The CLI guards against walking away from unpersisted configuration:
- Leaving system-view (
return/exit/end, orquitat the config root) with uncommitted edits promptscommit them before exiting? [Y/N/C]—Ycommits,Ndiscards (rollback),Cstays in the view. - Leaving the CLI (
quitfrom the user view) re-checks both halves: any uncommitted edits prompt to commit, then a committed-but-unsaved running config promptsSave to startup before exiting? [Y/N]so the change survives a reboot.
One-shot invocations (bng-cli <command>) never prompt.
2. Command Syntax¶
2.1 Notation conventions¶
This guide uses the following conventions in command descriptions:
| Notation | Meaning |
|---|---|
<value> |
A required parameter you supply (e.g. <name>, <ip>) |
[value] |
An optional parameter or keyword |
a\|b\|c |
A choice — pick exactly one of the listed keywords |
[<name>...] |
The parameter may be repeated (a list) |
| plain text | A literal keyword you type verbatim |
For example:
ping <dst> [source <ip>] [count <n>] [df] [fast]
<dst> is required; source, count, df, and fast are all optional.
2.2 Keyword abbreviation¶
Any unambiguous keyword prefix is accepted. Typing time udp 30 in the NAT view is
expanded to timeout udp 30. Ambiguous prefixes are rejected with the list of
candidates — at the config root, co is ambiguous between commit and confirm, so
use com or con.
2.3 TAB completion¶
Press TAB to complete a unique keyword prefix. If the prefix is not unique,
nothing is completed and you can use ? (Section 3) to see the candidates.
3. Context Help¶
3.1 The ? key¶
Press ? at any point on the command line to list what is valid at the cursor —
matching keywords, plus a <hint> describing any expected variable. ? is
context-sensitive: the choices reflect your current view.
Listings are alphabetical at every level — keywords A→Z with <variable> hints
last, and live values (interface, pool, and account names) sorted the same way. TAB
candidate lists follow the same order.
3.2 TAB¶
TAB completes a unique prefix (Section 2.3). Used together with ?, it lets you build
a command interactively without memorizing the full grammar.
3.3 Per-view help¶
Because the prompt reflects your view, ? inside a view shows only the commands valid
there. Enter the nat view and ? lists NAT knobs; enter qos and it lists QoS
objects. quit returns to the parent context and its help set.
3.4 Reviewing configuration¶
Three commands let you inspect configuration state at any time:
show pending uncommitted candidate changes (drives the * prompt marker)
show running the applied configuration
show candidate running with the candidate overlay
display current-configuration is an alias that normalizes to show running.
show running / show candidate print a tree: modules and keys alphabetical,
one nesting level per path component, ordered lists (filter:, policy:, server:
…) shown as numbered rows in their configured order (rule position is semantic,
so rows are never re-sorted). In the candidate view, staged lines carry a trailing
*. Details worth knowing:
pool
default = 100.64.0.2 100.64.0.254 100.64.0.1 # <name> = <range>; a successor
temp = 10.10.10.2 10.10.12.250 10.10.10.1 next Disabled # rides inline; 'next
dns = 103.102.59.2 8.8.4.4 # = none' is not shown
service # both on-box services group here (matches the CLI)
api # live-managed (api.conf, no commit) — still shown
enable = on
listen = 0.0.0.0:8090
allow:
(empty)
telnet # staged config (commit applies, save persists)
allow:
[1] 192.10.10.0/30
listen = 0.0.0.0:2008
Unset scalar values print as (not set), empty lists as (empty).
4. Interface Commands¶
VLAN / QinQ sub-interfaces and trunks (bonds) are created under the physical port
they belong to — the port you run add on is the parent (for a VLAN) or the member
(for a trunk). This mirrors MikroTik/Huawei/Cisco: you add sub-objects to an interface.
# VLAN / QinQ sub-interfaces (parent = the <port> you run 'add' on)
interface <port> add vlan <name> <svlan> single-tag 802.1Q sub-interface
interface <port> add vlan <name> <svlan> <cvlan> QinQ 802.1ad sub-interface
interface <port> del vlan <name> delete a VLAN/QinQ sub-interface
# Trunks / 802.3ad bonding (see §4.2)
interface add trunk <name> [mode 8023ad|active-backup|balance-xor] create a trunk
interface <port> add trunk <name> attach this port as a member
interface <port> del trunk <name> detach this port
interface del trunk <name> destroy the trunk
# Port attributes
interface <port> description <text> | mtu <68..9600>
interface <port> shutdown | no shutdown admin down / up (live)
interface identify <name> [duration <s>] blink the port LED to locate it
(omit duration = blink until 'identify stop')
interface identify stop <name> stop an active blink
VLAN and trunk edits stage into the candidate — commit then save (VLAN applies
live on commit; a trunk is built on the next restart, see §4.2).
4.1 Local IP addressing¶
Local IP addresses are a separate top-level command set. An interface may carry multiple addresses — one primary plus secondaries:
ip address add <if> <ip/prefix> add a local address (e.g. 103.102.59.6/30)
ip address add <if> <ip/prefix> secondary add a secondary address
ip address remove <if> <ip/prefix> remove an address
show ip address [<if>] list local addresses (role: primary/secondary)
show ipv6 address [<if>] list local IPv6 addresses
The first non-secondary address on an interface is its primary — the source for
self-originated traffic and the box's WAN ARP/ICMP identity. Removing the primary
promotes the next remaining address on that interface. ip address add / remove
stage into the candidate and apply live on commit (no restart), and save
persists them. These are L3 host addresses, not routed subnets.
The show interface family:
show interface physical DPDK ports only (MAC/admin/oper/speed/type)
show interfaces EVERYTHING in ONE table — one row per interface:
Name Type(ether|vlan|trunk) PCI Parent VLAN MAC Port State Speed Desc
show interface <name> full detail page for one port
show interface stats live per-port NIC counters (link/mtu/rx/tx/err/drop)
show vlan VLAN/QinQ sub-interfaces only (also 'show interface vlan')
show vlan stats per-VLAN rx/tx packets + bytes (its OWN traffic, not the parent port's)
show interface bonding 802.3ad/LACP bonds + live member state (§4.2)
show interface vlan stats reports each sub-interface's dedicated counters — the fast path
attributes a subscriber's packets to the VLAN it arrived on, so this is real per-VLAN
traffic rather than a share of the parent port. link / speed / mtu are the parent
physical port's, since a VLAN shares the wire.
Upstream worker spread (show interface <name>). The per-port detail page reports
three RSS rows that explain how upstream traffic is distributed across workers:
| Row | Meaning |
|---|---|
RSS Supported |
Hash types the NIC advertises (a bitmask of RTE_ETH_RSS_*) |
RSS Active |
Hash types actually programmed on this port |
PPPoE RSS |
Whether the inner-IP-over-PPPoE rte_flow rule is installed |
This matters because plain RSS cannot see inside PPPoE (ethertype 0x8864) — without
inner-IP steering every upstream PPPoE packet lands on one queue, and therefore one
worker. rule installed is not a promise of spreading: the Intel 82599 / X520
(ixgbe) accepts the rule but does not steer on it (the silicon can't parse past PPPoE),
so upstream stays on worker 0. Confirm the real spread with show health under load.
When the NIC can't spread PPPoE in hardware, the software dispatcher (§4.3) does it.
4.2 Link bonding (802.3ad / LACP)¶
Aggregate two or more physical ports into one logical link. Standards-based 802.3ad (LACP) interoperates with any conformant switch — Huawei Eth-Trunk, Cisco port-channel, Juniper LAG, etc. — plus static modes for switches without LACP.
A trunk is built up one port at a time, under the interface command: create the
trunk, then attach each physical port to it by name.
interface add trunk <name> [mode 8023ad|active-backup|balance-xor] create the trunk
interface <port> add trunk <name> attach a member
interface <port> del trunk <name> detach a member
interface del trunk <name> destroy the trunk
show interface bonding show bonds + live LACP state
Members are interface names (e.g. ether1) — the daemon resolves each to the stable
PCI address stored in bond.conf. Modes:
| Mode | Use |
|---|---|
8023ad |
802.3ad LACP (default) — needs LACP on the switch; active-active load share |
active-backup |
one active member, others standby — no switch config needed |
balance-xor |
static L3+L4-hash load share — no LACP |
Trunk edits follow the normal candidate/commit/save model: they stage into the
candidate (review with show pending), commit records the change, and save writes
bond.conf. The one difference from most config is the apply timing: a bond must be
built before the ports are queued, so commit does not build it live — the bond is created
on the next restart (the same apply-on-restart contract as the CPU plan). Once built,
the bond appears as a single port everywhere (show interfaces, RSS, workers, access/WAN
role). Example:
[Netvyn-BNG] interface add trunk bond0 mode 8023ad
staged: trunk bond0 mode 8023ad created (no members yet) — attach ports with 'interface <port> add trunk bond0', then 'commit' + 'save' and RESTART bng
[Netvyn-BNG] interface ether1 add trunk bond0
staged: add ether1 (0000:03:00.0) to trunk bond0 ('commit' + 'save', then RESTART bng to (re)build the bond)
[Netvyn-BNG] interface ether2 add trunk bond0
staged: add ether2 (0000:03:00.1) to trunk bond0 ('commit' + 'save', then RESTART bng to (re)build the bond)
[Netvyn-BNG] commit
[Netvyn-BNG] save
[Netvyn-BNG] show interface bonding
bond bond0 port 3 mode 802.3ad (LACP) policy l34
members 2, active 2
member 0000:03:00.0 port 1 link up 10000Mbps lacp collecting/distributing
member 0000:03:00.1 port 2 link up 10000Mbps lacp collecting/distributing
Optional bond.conf tuning (edit the file): lacp-rate slow|fast (partner timeout, slow
= 30 s, the interop default), xmit-policy l2|l23|l34 (TX hash, default l34).
4.3 Software PPPoE RSS (dispatch)¶
On a NIC that can't RSS inside PPPoE (the X520 — see the PPPoE RSS row above), all
upstream PPPoE lands on worker 0. The software dispatcher makes worker 0 hash each
upstream PPPoE frame by subscriber IP and fan it out to the other workers — a
software stand-in for hardware PPPoE RSS. Opt-in, OFF by default (baseline is
byte-identical).
system dispatch enable|disable turn the software fan-out on/off
dispatch show the live state
show health per-worker busy-cycle (confirm the spread)
Staged like the power toggle: commit applies live, save persists to system.conf.
Worker 0 still parses every upstream packet (a single-core cost), so it evens the load
but does not scale past one dispatcher core.
Hardware PPPoE RSS by NIC¶
show interface <name> reports a PPPoE RSS row. What it can say, and why:
| NIC | Result | Why |
|---|---|---|
Intel X520 (ixgbe) |
not installed (PMD rejected) |
The parser has no concept of PPPoE. Nothing to configure. |
Intel X710 / XL710 (i40e) |
not installed (PMD rejected) |
See below — not currently reachable. |
Intel E810 (ice) |
rule installed |
Supports the inner-IP RSS rule directly. |
On the 700 series this is a dead end today, and the reason is worth recording so it
is not re-investigated. The daemon installs an rte_flow rule matching
ETH / [VLAN] / PPPOES / IP with an RSS action on the inner IP. On i40e that is
refused at rte_flow_validate with Pattern not supported — the flow parser does
not accept a PPPOES item in an RSS rule, even with Intel's PPPoE DDP profile loaded.
(An earlier form of the rule that also carried a queue list was refused first with
RSS Queues not supported when pattern specified; removing the queue list moved the
error on but did not fix it.) The profile itself loads correctly on firmware new enough
to take it — it is the rule mechanism, not the profile, that i40e rejects.
The only route on this hardware is Intel's PCTYPE mapping API
(rte_pmd_i40e_flow_type_mapping_update plus an rss_hf change, seeded from the
profile's own packet types), which is a different mechanism and is not implemented.
Until it is, system dispatch enable is the answer on 700-series ports.
A ddp-profile <path> key exists in system.conf (file only — there is no CLI command)
that loads an Intel DDP profile at port init. It is unset by default and, given the
above, currently buys nothing on its own. It applies on restart, only touches
net_i40e ports, and is never fatal: a missing, unreadable or rejected profile leaves
PPPoE RSS off and logs the reason.
Whatever the outcome, the reason appears once per port in the diagnostic log:
show log
port 1: PPPoE RSS not installed -- validate rejected (type=13): Pattern not supported
5. PPPoE Commands¶
PPPoE / LCP configuration lives in the ppp view.
ppp interface add|remove <name> [<name>...] PPPoE access interface(s)
ppp mru <bytes> max receive unit (PPPoE max 1492)
ppp auth-protocol pap,chap,mschap,mschap2 allowed auth method set (comma list; default pap)
ppp secret add <user> <pass> [<local-ip> [<remote-ip>]] local credential (checked before RADIUS)
ppp secret remove <user> remove a local credential
ppp aaa on|off local-store miss policy: on = RADIUS (default), off = strict reject
ppp lcp-echo interval <secs> failure <count> dead-peer keepalive (interval 0 = off)
ppp setup-timeout <secs> half-open reap timeout (default 60)
ppp session-timeout <secs> hard session lifetime (0 = unlimited)
ppp pool <name> IPv4 framed-address pool (pool.conf) — RADIUS-less fallback
ppp ipv6 enable|disable negotiate IPv6CP (default enable; disable = v4-only)
ppp ipv6 pool <name> NA /64 framed-prefix pool — RADIUS-less fallback
ppp ipv6 pd-pool <name> PD delegated-prefix pool — RADIUS-less fallback
ppp undo <mru|auth-protocol|aaa|lcp-echo|setup-timeout|session-timeout|pool|ipv6|ipv6-pool|ipv6-pd-pool>
IPv4 pool. ppp pool <name> selects which pool.conf pool a PPPoE session draws its
framed IPv4 address from when RADIUS supplies no Framed-IP-Address and no Framed-Pool.
Precedence: RADIUS Framed-Pool → ppp pool <name> → the pool named default. Empty name
or ppp undo pool clears it (back to default). Shown in show ppp as pool.
Access interfaces are a list: add / remove stage into the candidate, commit
applies live, and save persists. Multiple names may be given per command.
Authentication. ppp auth-protocol takes a comma-separated set of allowed methods.
The BNG proposes the strongest listed method and downgrades on NAK to any other listed
method, refusing the rest.
Local credentials (chap-secrets). ppp secret add stores a username/password checked
before RADIUS for PAP and CHAP-MD5 (the MS-CHAP variants stay RADIUS-relayed). A
listed user is authoritative: a wrong password rejects rather than falling through to
RADIUS. The optional <local-ip> pins our gateway address on the link and <remote-ip>
pins the peer's framed IP (otherwise the pool/RADIUS supplies them). ppp aaa picks what
happens on a local-store miss: on (default) forwards to RADIUS as before, off is
local-only strict mode — unknown users are rejected, so a RADIUS-less box authenticates
exactly its listed users. Rows persist as secret lines in ppp.conf (staged —
commit applies live, save persists); show ppp lists the store (passwords masked).
MS-CHAP / MS-CHAPv2 and encryption. The MS-CHAP methods authenticate via RADIUS (the server needs its
mschapmodule); the NAS relays the challenge/response and never sees the password. Because the BNG does not negotiate MPPE encryption, clients using MS-CHAP must be configured for optional, not required, encryption — a client that requires MPPE will bring the session up, find no encryption, and drop into a re-dial loop. PAP is unaffected.
5.1 IPv6 pool fallback¶
ppp ipv6 pool and pd-pool name an IPv6 prefix pool (see Section 6.4) used only when
RADIUS returns no v6 prefix. Precedence is RADIUS-first: a RADIUS Framed-IPv6-Prefix
(NA /64) or Delegated-IPv6-Prefix (PD) always wins, and the pool is drawn only when
RADIUS returns none. RADIUS may also select which pool by name, in order: (1) the
Netvyn IPv6 pool VSAs; (2) the unified Framed-Pool (attribute 88) name, so one policy
name walls off both stacks (e.g. Framed-Pool=Expired places the user in the v4 and
v6 Expired pool — the classic walled-garden with no separate v6 attribute); (3) the
ppp ipv6 pool / pd-pool config name. An empty name or undo falls back to the pool
named default. These knobs apply live on commit to new sessions; existing sessions
keep their prefixes. ppp ipv6 disable skips IPv6CP entirely (v4-only). Pool
utilization is show ipv6 pool.
6. IPoE Commands¶
IPoE / DHCP configuration lives in the dhcp view.
dhcp mode off|dhcp|ipoe|both off = PPPoE only [default]
dhcp interface add <name> [<name>...] add IPoE access interface(s) to the serve-set
dhcp interface remove <name> [<name>...] remove access interface(s) from the serve-set
dhcp auth mac|ip|option82|none RADIUS identity (default mac → User-Name = MAC)
dhcp auth-password <secret> MAC-auth password
dhcp mac-format colon|hyphen|bare MAC string form (default colon)
dhcp pool <name> fallback address pool
dhcp lease-time <secs> DHCP lease (default 600)
dhcp undo <mode|auth|mac-format|pool|lease-time>
The IPoE access serve-set is an explicit list. Names are physical interfaces or
VLAN sub-interfaces and are VLAN-aware. With no interface listed, IPoE/DHCP is served on
nothing. add / remove stage into the candidate, commit applies live, and save
persists. Multiple names may be given per command (space- or comma-separated).
6.1 Framed-IP pools¶
Framed-IP address pools live in the pool <name> view:
pool <name> range <start> <end> gateway <gw> [prefix <len>] define range r0 (creates the pool)
pool <name> range add <start> <end> gateway <gw> [prefix <len>] add a parallel range (live)
pool <name> range delete <start> delete a range by its start address
pool <name> next <successor-pool> overflow into another pool when full (or 'none')
pool <name> remove delete the pool (in-use pools retire then drain)
pool <name> undo next
A pool holds up to 16 ranges, used in parallel. Ranges are drawn
round-robin — consecutive subscribers land in r0, r1, r2, r0, … rather than
filling r0 first — and each range keeps its own gateway and prefix, so one
pool may span several subnets. DHCP and IPCP answer with the gateway/netmask of
the range the address actually came from, not the pool's first range. A full or
retired range is skipped; the pool is "full" only when every range is exhausted,
which is the point at which next takes over. The two mechanisms are
independent:
ipoe_pool ipoe_pool2
r0 ── r1 ── r2 ──all full──> r0 ── r1 ── ...
\___ parallel ___/ \___ parallel ___/
show pool prints one row per range (r0, r1, …) plus a pool total.
Live-grow. Adding a range applies live on commit: the new addresses join
the round-robin immediately, with no restart and no disturbance to bound
subscribers (each range owns its own slice of the pool bitmap, so existing
allocations are untouched). This is the supported way to grow a pool under load.
Redefining r0 on an existing pool still applies on restart — a live
reshape of a range that is already serving addresses would orphan them — so
pool <name> range <start> … on a live pool commits successfully but changes
nothing until the daemon restarts. Use range add when you mean "more
capacity now".
Deleting a range is by start address, not index — indexes shift when a
range is removed, start addresses do not. A range with subscribers still bound
is retired rather than dropped: no new allocations, existing addresses keep
working, and it disappears once drained ([range retired] in show pool). A
pool's last live range cannot be deleted; remove the pool instead.
Validation. A range is rejected at commit if it overlaps any other range
in any pool, if it spans more than one subnet of its prefix (e.g.
10.0.0.2-10.0.0.8 prefix 29, which straddles the .0/29 and .8/29
boundary), if its gateway falls outside its own subnet, or if it would push the
pool past 16 ranges or 65536 addresses. Overlap is rejected because the
allocator locates an address by range when freeing it — two ranges covering
one address would make ownership ambiguous.
Rejections at staging time (bad prefix, gateway outside the subnet) print at the prompt. Rejections at apply time (overlap with a range the allocator already holds) are reported as
commit failed: 0 applied, 1 failedwith the reason in the daemon log —journalctl -u bng | grep "config: pool".
6.2 Subscriber DNS¶
DNS is shared by every framed-IP pool, so it is configured globally, not per pool:
ip dns <primary> [secondary] IPv4 subscriber DNS (IPCP + DHCP option 6)
ip dns none clear IPv4 DNS
ipv6 dns <primary> [secondary] IPv6 subscriber DNS (RA RDNSS + DHCPv6)
ipv6 dns none clear IPv6 DNS
show ip dns show the live IPv4 subscriber DNS
show ipv6 dns show the live IPv6 subscriber DNS
Both apply live on commit and are persisted by save. IPv4 DNS is handed out in
IPCP and DHCP option 6. IPv6 DNS is delivered both as the RA RDNSS option (for SLAAC
clients) and via DHCPv6, so any CPE learns it.
6.3 DHCP mode¶
DHCP mode both serves both DHCP and IPoE-authenticated subscribers; dhcp and
ipoe restrict to one; off disables IPoE entirely (PPPoE only).
6.4 IPv6 prefix pools¶
Named IPv6 prefix blocks the box carves per-subscriber prefixes from when RADIUS returns
no v6 prefix. A pool is role-neutral — the reference site decides how a drawn prefix
is used (ppp ipv6 pool / dhcpv6 pool → framed /64 NA/SLAAC; ppp ipv6 pd-pool /
dhcpv6 pd-pool → delegated PD prefix), so the same pool can be referenced either way.
Distinct pools must not overlap.
ipv6 pool <name> <base>/<plen> assign <plen> create/replace a named IPv6 prefix pool
ipv6 pool <name> remove delete the pool
show ipv6 pool pool utilization (base/assign, in-use, free)
assign must be longer than the base prefix length; the number of assignable prefixes
is 2^(assign − base), capped at 65536. A pool named default (else the first pool
defined) is the one an empty pool reference draws from. ipv6 pool stages into the
candidate and commit applies it live — a new pool is drawable immediately. Removing
or reshaping a pool that still has live allocations keeps the old shape until restart so
no subscriber's prefix is orphaned. save persists the pool set.
6.5 DHCPv6-PD knobs¶
IPoE IPv6 prefix-delegation parameters live in the dhcpv6 view — the IPoE twin of §5.1's
ppp ipv6 pool / pd-pool:
dhcpv6 mode off|on|pd serve IA_PD (default off; 'pd' is an alias of 'on')
dhcpv6 t1 <secs> IA_PD T1 renew timer (default 3600)
dhcpv6 t2 <secs> IA_PD T2 rebind timer (default 5400)
dhcpv6 preferred-lifetime <secs> prefix preferred lifetime (default 604800)
dhcpv6 valid-lifetime <secs> prefix valid lifetime (default 2592000)
dhcpv6 pool <name> IPoE NA /64 pool — RADIUS-less fallback (§6.4)
dhcpv6 pd-pool <name> IPoE PD delegated-prefix pool — RADIUS-less fallback (§6.4)
dhcpv6 undo <mode|t1|t2|preferred-lifetime|valid-lifetime|pool|pd-pool>
The delegated prefix is the subscriber's RADIUS Delegated-IPv6-Prefix; dhcpv6 pool /
pd-pool are drawn only when RADIUS returns none. All apply live on commit to
new/renewing bindings; save persists them to dhcpv6.conf. Inspect with show dhcpv6.
7. Routing Commands¶
Routing is one command family per address family. The default gateway is simply the
0.0.0.0/0 route (IPv6: ::/0) — there is no separate WAN/LAN concept. ip route is
IPv4-only and ipv6 route is IPv6-only; the ipv6 keyword is compulsory.
ip route add <a.b.c.d/p> gateway <ip> [interface <name>] [distance <n>] [metric <n>] [weight <n>]
ip route add <a.b.c.d/p> interface <name> [distance <n>] [metric <n>] [weight <n>]
ip route add <a.b.c.d/p> <ip> [distance <n>] [metric <n>] [weight <n>] (bare-gateway shorthand)
ip route delete <a.b.c.d/p> [gateway <ip>]
ipv6 route add <x::y/p> gateway <ip6> [interface <name>] [distance <n>] [metric <n>] [weight <n>]
ipv6 route add <x::y/p> interface <name> [distance <n>] [metric <n>] [weight <n>]
ipv6 route add <x::y/p> <ip6> [distance <n>] [metric <n>] [weight <n>] (bare-gateway shorthand)
ipv6 route delete <x::y/p> [gateway <ip6>]
- Default gateway —
ip route add 0.0.0.0/0 <gw>(IPv6:ipv6 route add ::/0 <gw6>). - Bare gateway — the next-hop may be given with no
gatewaykeyword:ip route add 10.4.4.0/29 10.20.50.1. - distance — administrative distance; the lowest live distance wins across sources
(connected 0, RADIUS 5, static 10, DHCP 15, BGP 20, OSPF 110).
0= the source's own default (static = 10). - metric — tie-break within one distance (lower wins).
- weight — ECMP share among equal-distance routes to the same prefix (default 1).
- Egress is derived from the gateway — the next-hop lives in exactly one connected
subnet, so you never state the egress interface for a gateway route.
interface <name>with no gateway makes a connected/link route out that interface.
ip route add / delete stage into the candidate and apply live on commit: the RIB
reconciles without dropping sessions (the default row re-points the gateway), and save
persists the routing table.
7.1 Inspecting the RIB / FIB¶
show ip route [detail] the IPv4 RIB — prefix, gateway, source, distance, metric,
weight, selection flags (S selected, R resolved, r recursive, i inactive)
show ip fib the selected route per prefix: prefix, nexthop, egress,
configured-nh, resolved-nh, state
show ip nexthop the nexthop table (egress port + resolved gateway MAC)
show ipv6 route [detail] | show ipv6 fib | show ipv6 nexthop the IPv6 twins
routing show routing knobs (recursive-via-default state)
7.2 Recursive resolution¶
A static route whose gateway is not on a connected subnet resolves recursively
through the covering route (flagged r in show ip route). show ip fib exposes both
the configured-nh (the route's own gateway) and the resolved-nh (the terminal
on-link gateway the recursion reached); they differ exactly when the route is recursive.
routing recursive-via-default <enable|disable> allow/deny recursion via the default route
Recursion through the default route is allowed by default (loop-guarded, capped at 8
hops). disable makes an off-net static gateway resolve to blackhole instead — a live
toggle that re-resolves the RIB immediately.
7.3 Live default-gateway re-point¶
The default gateway is simply the 0.0.0.0/0 route, so it is set with the normal
ip route command — there is no separate default-gw verb:
ip route add 0.0.0.0/0 gateway <ip> set / change the default gateway
ip route delete 0.0.0.0/0 remove the default gateway
show ip route (the 0.0.0.0/0 row is the default gw)
The edit stages into the candidate; on commit the daemon ARPs the new gateway and swaps
forwarding only once the new gateway answers (resolve-then-swap), so live sessions are
preserved. save persists it to routing.conf.
8. Firewall Commands¶
The IPv4 firewall is a stateful ACL, configured in the firewall view.
firewall enable | disable disable = default policy ACCEPT (enable is live)
firewall urpf strict | disable BCP38 reverse-path source verify / anti-spoof (live on commit)
firewall undo enable
8.0a Mangle — packet rewriting (runs first)¶
The firewall is two ordered lists. mangle runs first and every matching
rule runs (no verdict, no first-match), then filter decides accept/drop.
That ordering is what makes a rewrite reliable regardless of what filter later
does with the packet.
firewall mangle add <rule>
firewall mangle insert <N> <rule>
firewall mangle delete <N>
firewall mangle move <N> <M>
<rule> = <change-mss <mtu> | mark <n> | passthrough | return | accept>
[chain prerouting|forward|input|output|postrouting]
[<the same matches the filter list takes>]
| Action | Effect |
|---|---|
change-mss <mtu> |
Clamp the TCP MSS on SYN to mtu-40. This is TCP MSS clamping — PPPoE access needs change-mss 1492. |
mark <n> |
Set the conntrack mark. No consumer reads it yet, so today it is observable but inert. |
passthrough |
Do nothing but count the match — a pure counter/probe rule. |
return / accept |
Stop the mangle pass here (the filter list still runs). |
⚠️
firewall mss-clampwas removed. MSS clamping used to be a scalar that silently synthesized two hidden rules. It is now an explicit rule you can see, count, and reorder. A firewall.conf carryingmss-clamp <mtu>will log an error at boot and will NOT clamp — migrate before upgrading:firewall mangle add change-mss 1492 chain forward proto tcp commit save
show firewall lists the mangle rules with their own hit counters, and
clear counters mangle [<n>] resets them.
8.1 Filter — the verdict¶
Ordered filter list, spread over three chains (chain forward|input|output). The
FORWARD chain is evaluated once per direction (subscriber→network and
network→subscriber), so a forward rule with no dir applies to both:
firewall filter add <rule>
firewall filter insert <N> <rule> insert at 1-based index N
firewall filter delete <N>
firewall filter move <N> <M> move rule N to index M
<rule> = <accept|drop|reject|return>
[chain forward|input|output] forward = transit (default)
[dir up|down] forward chain only
[proto tcp|udp|icmp]
[src-address <a.b.c.d[/len]>] [dst-address <a.b.c.d[/len]>]
[sport <ports>] [dport <ports>] 80 | 80,443 | 8000-8100 |
53,80,8000-8100 (max 8 ranges)
[state new|established]
[src-list <name>] [dst-list <name>]
[limit <rate> [burst <n>] [per-src]]
Match keywords are freely composable — write as many as the rule needs, in any
order; the commit-time validator is the authority. Host bits in an address are
masked off on commit, so src-address 10.1.2.3/24 canonicalizes to 10.1.2.0/24.
8.0 Chains, direction, and connection state¶
| Chain | What traverses it |
|---|---|
forward (default) |
Transit traffic: subscriber ↔ network. Evaluated in both directions. |
input |
Packets addressed to the BNG itself — management, API, CLI-over-IP, ping. The lock-down chain for the box's own services. |
output |
IP traffic the BNG originates — its own UDP (RADIUS and friends) and the management TCP stack. Link protocols (ARP/ND/PPPoE/DHCP) are not IP-filterable and never traverse it, same as iptables. |
| Action | Meaning |
|---|---|
accept |
Permit; stop matching. |
drop |
Discard silently; stop matching. |
reject |
Discard with an ICMP/RST; stop matching. |
return |
Stop matching and apply the default policy (accept) — the escape hatch that skips the rest of the list. |
| Match | Meaning |
|---|---|
(no dir) |
Both directions — the rule is evaluated on upstream and downstream packets |
dir up |
Subscriber → network only |
dir down |
Network → subscriber only |
state <list> |
Connection state — a comma list of the five values below |
src-address / dst-address |
Address or prefix; host bits masked off on commit |
sport / dport |
One port, a comma list, and/or lo-hi ranges — up to 8 ranges in a single rule (needs proto tcp or proto udp) |
| State | Matches |
|---|---|
new |
No tracked flow yet (the first packet of a connection) |
established |
The flow's reply has been seen (shared NAT conntrack, incl. the UDP EIM mapping) |
related |
An ICMP error whose embedded datagram belongs to a tracked flow (RFC 5508) — unreachable / time-exceeded / PMTUD about a connection you already allowed |
invalid |
Cannot belong to any known flow: a mid-stream TCP segment (no SYN) with no conntrack entry, or an ICMP error matching nothing |
untracked |
Conntrack does not apply — NAT is off for this subscriber (routed public / bypass) or globally. These are not new; match them with untracked. |
States combine: state established,related is the standard "allow the replies and
the ICMP errors about them" rule.
The inbound lockdown — allow anything the subscriber starts, block the rest:
firewall filter add accept dir up # anything the subscriber initiates
firewall filter add accept state established # replies to it
firewall filter add drop dir down # unsolicited inbound
commit
Multi-port and address examples — one rule where several used to be needed:
# lock management down to the NOC prefix (INPUT chain)
firewall filter add accept chain input proto tcp dport 22,8090 src-address 10.10.0.0/16
firewall filter add drop chain input proto tcp dport 22,8090
# block a set of outbound ports for one subscriber range
firewall filter add drop dir up proto tcp dport 25,135,139,445,3389 src-address 100.64.0.0/10
# the BNG's own RADIUS traffic may only reach the AAA server (OUTPUT chain)
firewall filter add accept chain output proto udp dport 1812,1813 dst-address 10.20.0.5/32
⚠️ State needs conntrack. It resolves through the NAT flow table, so it works for CGNAT/SNAT subscribers. A subscriber on a routed public IP with NAT bypassed has no conntrack entry: those packets match
untracked(notnew), so gate them withuntracked,dir, or an address/port match. Upstream the ACL runs pre-NAT and probes the flow read-only, so adropnever consumes a CGNAT port.
Apply timing: everything here is live on commit — firewall enable,
firewall urpf, and the mangle + filter rule lists (the compiled rule set is
rebuilt and published atomically; per-rule hit counters restart at zero when the
list changes). save persists to firewall.conf. show firewall lists
per-rule hit counters; show firewall drops shows the ACL verdict total and the uRPF
anti-spoof discard total. clear counters firewall [<n>] zeroes per-rule counters
(immediate).
8.2 Rate limiting (anti-scan / SYN-flood / brute-force)¶
A filter rule can carry a token-bucket rate limit, appended after the match keywords:
firewall filter add <accept|drop|reject> [...matches...] limit <rate> [burst <n>] [per-src]
limit <rate>— packets per second the rule is allowed to match (1..1000000000).burst <n>— bucket depth (max tokens); the size of a momentary burst before metering bites. Default =rate.per-src— meter each source IP independently (a per-worker direct-mapped cache). Without it,limitis a per-rule aggregate across all sources.
The rule matches only while a token is available; over the limit it falls through to
the next rule. So the idiom is an accept ... limit immediately followed by a
drop — accept up to the rate, drop the excess. This is the anti-scan / SYN-flood /
brute-force control the routed public ranges need (a port scanner opens many new
connections from one source → per-src on state new caps them):
# cap new inbound TCP to 20/s per source, drop the overflow
firewall filter add accept proto tcp state new limit 20 burst 40 per-src
firewall filter add drop proto tcp state new
# throttle SSH brute-force to 3 new conns/s per source
firewall filter add accept proto tcp dport 22 state new limit 3 burst 5 per-src
firewall filter add drop proto tcp dport 22 state new
⚠️ The bucket is per-worker. RSS spreads a source's flows across all workers, so for spread traffic the effective aggregate is ≈
n_workers × rate; for a single-flow flood (one 5-tuple → one worker) it is exact. Size<rate>with that in mind. Like all filter-rule edits, alimitchange applies live on commit (savepersists).show firewallprints the limit next to the rule.
8.3 Address lists¶
A named address list is a set of addresses that rules match against with
src-list / dst-list — the same idea as a RouterOS address-list. One rule can then
cover thousands of addresses, and the membership changes without touching the rule.
firewall address-list add <name> <ip|cidr> [timeout <secs>]
firewall address-list remove <name> <ip|cidr>
show firewall address-list [<name>] entries (host + subnet); no name = every list
Three things populate a list:
| Source | Behaviour |
|---|---|
| RADIUS | The Netvyn-Firewall-Address-List VSA (attr 33) tags the subscriber's framed IP into the named list for the life of the session — added at session-up, removed on teardown. Works for PPPoE and IPoE. |
| Operator | firewall address-list add|remove above. |
| Rules | A rule action can add the packet's source/destination to a list. |
A bare address is a host entry (/32); a.b.c.d/len is a subnet entry matched
by longest prefix. timeout gives a host entry a TTL — without it the entry is
permanent (that is how RADIUS session tags and static entries are stored, removed
explicitly rather than aged out). Subnets are always permanent. The list is created
automatically on first use.
These edits are LIVE and IMMEDIATE — unlike filter rules, they do not stage into the candidate and need no
commit. That is deliberate: they are the same code path RADIUS uses to tag a subscriber mid-session. For entries that must survive a restart, putaddress-list <name> <ip|cidr>lines infirewall.conf.
Example — drop everything sourced from a quarantine set that RADIUS populates:
[Netvyn-BNG] firewall filter add drop src-list quarantine
[Netvyn-BNG] commit
<Netvyn-BNG> show firewall address-list quarantine
8.3 IPv6 firewall¶
The IPv6 firewall is a completely separate, stateless engine — its own rule table,
per-rule counters, enable gate, and uRPF flag. A v4 rule never sees a v6 packet and
vice-versa. Because IPv6 is never NAT'd, there is no state match and no mangle list.
firewall enable6 | disable6 arm / bypass the v6 ACL (live on commit; default disabled = ACCEPT)
firewall urpf6 strict | disable v6 reverse-path anti-spoof, separate from v4 (live on commit; default disable)
Ordered v6 filter list, where
<rule> = accept|drop|reject [proto tcp|udp|icmp6|<n>] [src <pfx>/<plen>] [dst <pfx>/<plen>] [dport <n>] [sport <n>] [icmp6-type <n>]:
firewall filter6 add <rule>
firewall filter6 insert <N> <rule>
firewall filter6 delete <N>
firewall filter6 move <N> <M>
Apply timing: everything here is live on commit — enable6, urpf6, and
filter6 rule changes (rule set rebuilt + published atomically; per-rule counters
restart at zero when the list changes). show firewall6 lists the v6 rules with per-rule hit
counters and uRPF state; show firewall6 drops shows the v6 drop/reject totals.
clear counters firewall6 [<n>] zeroes the v6 per-rule counters (immediate).
v6 uRPF defaults OFF. Leave
urpf6 disableuntil subscriber v6 reverse-routes are installed in the RIB; a strict v6 check otherwise drops a legitimate static v6 host on a subscriber's circuit. This is why v6 anti-spoof is a separate toggle from v4.
9. NAT / CGNAT Commands¶
NAT / CGNAT configuration lives in the nat view.
nat enable | disable disable = fast path is plain forwarding
nat conntrack-max <count> LIVE admission ceiling (default 1048576)
nat conntrack-capacity <count> flow-table ALLOCATION; applies on restart
nat timeout <type> <seconds> type ∈ tcp-established|tcp-closing|tcp-close|
tcp-syn|udp|udp-stream|udp-eim-reserve|icmp
nat udp-mapping endpoint-independent|symmetric RFC 4787 (default EIM/EIF)
nat pool add <name> <ip-lo>-<ip-hi> ports <lo>-<hi> block <size> [deterministic|dynamic]
nat pool remove <name> CGNAT public pool (name-keyed)
nat undo <enable|conntrack-max|conntrack-capacity|udp-mapping|timeout <type>>
conntrack-max and conntrack-capacity are two different things. capacity is what
gets allocated at startup — the conntrack arena, its hash and the free-id ring — and
cannot change without a restart, because the workers index those structures lock-free on
every packet. conntrack-max is only the admission ceiling: a comparison against the
in-use count, so commit applies it immediately with no reallocation and no restart.
Size capacity generously from the hugepages you provisioned (headroom costs only
memory) and tune conntrack-max live. Raising the ceiling past capacity clamps it and
says so. A nat.conf that sets only conntrack-max still behaves exactly as before — it
sets both.
nat conntrack-capacity 2000000 # allocate for 2M flows (restart)
nat conntrack-max 800000 # admit at most 800k (live)
show nat statistics reports both, and counts admission refusals (limit refusals)
separately from arena and hash-insert failures — three different causes that used to be
reported identically as "conntrack table full".
CGNAT public pools (nat pool add / remove) are keyed by name (order is
irrelevant). block must be a power of two; deterministic emits one compliance log per
block (RFC 7422). Pools stage into the candidate and apply live on commit for NEW
sessions — existing sessions keep the block they hold until re-login, and a pool's
index is boot-stable and embedded in every outstanding CGNAT block, so the table is
rebuilt at boot rather than mutated live. commit records the running set, save
persists it, and the new pool loads at the next restart. Referencing a brand-new pool
from a nat policy rule requires the pool to be live first (restart).
9.1 NAT policy list¶
An ordered, first-match policy list that applies live:
nat policy add nat-rule <cidr> pool <name>|bypass
nat policy add snat <cidr> to <target>
nat policy insert <N> nat-rule …|snat … insert at 1-based index N
nat policy delete <N> delete rule at index N
nat policy move <N> <M> move rule N to index M
9.2 Destination NAT (port forward)¶
nat policy handles inside → outside (SNAT/CGNAT). DSTNAT is its mirror —
outside → inside — so a service behind CGNAT can be reached from the Internet. It is
an ordered, first-match list with the same editor shape, and it applies live:
nat dstnat add <rule>
nat dstnat insert <N> <rule> insert at 1-based index N
nat dstnat delete <N>
nat dstnat move <N> <M>
show nat dstnat rules + per-rule forwards and up/down pkts/bytes
where <rule> =
<public-ip> [proto tcp|udp|any] [dport <port>] to <inside-ip> [to-port <port>] [disable]
| Form | Meaning |
|---|---|
Port-based — dport given |
public-ip:port → inside-ip:port. to-port defaults to the matched dport. |
Address-based — dport omitted |
The whole public IP (all ports) → the inside host. Only valid when that subscriber is the sole owner of the IP. |
[Netvyn-BNG] nat dstnat add 203.0.113.5 proto tcp dport 8080 to 100.64.0.9 to-port 80
[Netvyn-BNG] commit
Return traffic needs no rule. The first inbound packet creates a conntrack entry
whose reply key is the inside→peer tuple, so the subscriber's replies are automatically
translated back to the public ip:port on the way out.
Ownership is enforced. The BNG verifies that the inside subscriber genuinely owns the public
ip[:port]from its deterministic CGNAT block. A rule pointing at another subscriber's public IP simply never forwards — one customer can never hijack another's public address. The forward is also inactive while the subscriber is offline.Choose a port outside the dynamic range. The forwarded public port is not reserved in the CGNAT port allocator, so pick a service port that the same subscriber's outbound flows will not be assigned.
9.3 Source / Destination NAT (unified view)¶
Source NAT (snat) and destination NAT (dstnat) are two existing engines — there is
no separate "nat rule" command. The WebUI presents them as one merged "Source / Dest NAT"
list (action = srcnat/dstnat) for convenience, routing each edit back to the underlying
engine; on the CLI you use the two commands directly:
nat policy add snat <inside-cidr> to <target> # srcnat: rewrite source (see §9.1)
nat dstnat add <rule> # dstnat: rewrite destination (see §9.2)
nat policy is otherwise CGNAT-only (nat-rule <cidr> pool|bypass); its snat rows are
the source-NAT half of the merged view. Both apply live on commit and save to nat.conf.
Per-rule counters:
dstnatrules now carry live up/down packet+byte counters (bumped on every packet via the conntrack entry's recorded rule index) — see them inshow nat dstnatand the WebUI's Traffic column. Still planned (Phase 2b): the same counters forsnatrules, and richer 5-tuple matching — lettingsnatalso match dst/dst-port anddstnatalso match src (extending the two commands, not a new engine). The merged WebUI list already shows the Src/Dst IP:port columns; the extra match fields activate once that extension lands.
9.4 IPv4 fragment handling¶
cgnat fragments mode <drop|cache|reassembly> IPv4 fragment handling (default cache; live)
cgnat fragments timeout <secs> fragment-cache entry lifetime (default 30s)
cgnat fragments rss <enable|disable> ⟳ hash UDP on the IP 2-tuple so a datagram's
fragments co-locate on one worker (default
disable; APPLIES ON RESTART — RSS is set at
port init). Persist with 'save'.
show cgnat fragments fragment counters + rss-colocate state
Large-UDP applications (e.g. RDP-UDP). Non-first fragments carry no L4 header, so plain NAPT drops them and the datagram never reassembles — large-UDP apps freeze.
cachemode (the default) records the first fragment's translation and applies the same IP rewrite to the trailing fragments (virtual reassembly, RFC 6888 REQ-11), with no physical reassembly cost.dropis the old behavior;reassemblyis an accepted alias ofcache.
rss enable— the fragment cache is per-lcore, so all fragments of a datagram must reach the same worker. By default the NIC hashes a datagram's first fragment on the UDP 4-tuple (it has the L4 header) but the trailing fragments on the IPv4 2-tuple — splitting them across workers, so the trailing fragment misses the cache and the datagram is lost (seen as ~13–40% loss on >MTU UDP; TCP and sub-MTU UDP are unaffected).rss enabledrops UDP to the 2-tuple so first + trailing co-locate. Trade-off: UDP between one IP pair no longer spreads across workers (TCP keeps its 4-tuple spread). Because the RSS hash is fixed when the ports come up, this applies on restart —commit+save, then restart the daemon.show cgnat fragmentsshows the currentrss-colocatestate.
9.5 Diagnosing a one-way UDP freeze¶
When a subscriber's TX drops to 0 while RX stays high (client sending, replies not
arriving), show nat statistics splits the reason at the point a WAN reply is
reverse-translated:
- translation misses — reply hit a public ip:port with no mapping (outside port released/reallocated).
- stale-mapping drops — mapping belongs to a dead session.
- expired-mapping hits — mapping idle past its timeout (GC lag).
- fragment-miss drops — out-of-order fragment with no first fragment cached.
- translation hits — delivered. If this climbs while TX is still 0, the loss is downstream of NAT.
show nat session [<ip>] and show nat flow [<ip>] dump the live conntrack per flow —
subscriber, private ip:port, public ip:port, peer, mapping state, and timeout
remaining — and <ip> filters to one subscriber (by private or public IP).
show nat statistics detail additionally lists recent misses (the exact public
ip:port WAN replies hit with no mapping) and fragment counters.
Procedure: run clear counters nat at the start of a freeze, let it run ~30 s, then
show nat statistics detail and note which counter climbs before applying a fix.
9.6 Port-block occupancy (show nat block[s]) — sizing the pool¶
How full is a subscriber's port block, and how full is the pool? The per-block free bitmap is the ground truth (1 bit = 1 outside port in use), so this is exact and cheap:
show nat block <private-ip> one subscriber's block: public IP, port range,
ports used/free, utilization %, quarantined EIM
ports, and the pool math (subs per public IP,
total blocks). Warns at >=90% full.
show nat blocks per-pool summary (blocks allocated vs capacity,
average + busiest ports/block) and the 10 busiest
blocks — the "who is about to exhaust" view.
Example — a subscriber on a ports 1024-65535 block 8192 pool:
<Netvyn-BNG> show nat block 100.64.0.2
private-ip user public-ip ports used util quar pool
100.64.0.2 krishna@pppoe 103.x.x.10 1024-9215 611/8192 7% 0 cgnat1
(pool 'cgnat1': ports 1024-65535 block 8192 -> 7 subscribers/public-IP x 8 IP(s) = 56 blocks total)
Reading it for sizing: util near 100% on individual subscribers → raise the
pool's block size (fewer subs per IP, more ports each); blocks allocated
in show nat blocks near the pool's capacity → add public IPs to the range
(or shrink the block size). Exhaustion events (drops) are the "no free outside
port" counter in show nat statistics / nat-alloc-fail in show drops. Pool
changes stage with nat pool add|remove and apply live on commit for new
sessions (existing sessions keep their block; reshaping an in-use pool's IP/port
range still needs a restart). Freed blocks are reclaimed for the next login, so
session churn no longer leaks pool slices.
10. QoS Commands¶
QoS is built from three objects, configured in the qos view:
- A queue profile is the scheduler discipline only (
pfifo/tb/fq_codel/fq_pie/cake+ tuning). It carries no rate. (fq_pieis the native rte_sched PIE discipline;fq_codelandcakeapproximate their namesakes on the same PIE core, so the fq-family tuning keys are identical.) - A subscriber profile owns the rate (down/up) plus an optional local priority, and points at a queue profile.
- An assignment binds a prefix to a subscriber profile.
A subscriber's effective QoS resolves as: a matching assignment (longest prefix) → its subscriber profile's rate + priority + queue profile; else the RADIUS rate on the per-service default queue profile (PPPoE vs. IPoE); else the service default at the port rate.
All four collections are index-addressable lists, and rows can equally be addressed
by name (queue/subscriber profiles) or by CIDR (assignments) wherever an index
is expected — modify fq ..., delete testip, move 10.20.50.4/32 1. Edits stage
into the candidate; commit applies live (re-binding and re-queuing matching live
subscribers); save normalizes the QoS configuration to canonical form.
Completion is discipline-aware. After a discipline (
add x fq_pie ?) the CLI offers only that discipline's keys; after a profile name (qos queue-profile fq ?ormodify fq ?) it asks the daemon for the profile's actual discipline and scopes the key list to it (falls back to the full set for an index selector).
10.1 Live queue-profile changes — applied on commit¶
A queue profile's own discipline / qsize / AQM layout is fixed when a port is built, so
the daemon keeps parallel scheduler generations. Editing a queue profile and running
commit builds a new generation from the committed config alongside the running one —
live, no restart, and no separate qos retune step (that command has been removed;
commit does the work, and it applies the in-memory candidate rather than re-reading
qos.conf):
show qos generations which generation is current + how many subscribers ride each
- New sessions bind to the new generation immediately.
- Existing sessions keep forwarding on the old generation and migrate gradually — on reauth/reconnect and via a controlled background rebind (~64 subscribers / 20 ms).
- The old generation is freed once no subscriber references it (
show qos generationsshows it drain to 0, then(free)). - Only one rebuild in flight: if a committed change can't get a free generation slot (the predecessor is still draining), the profile re-point applies but the qsize/AQM rebuild is deferred — retire the draining generation and re-commit.
- Scope: tuning existing profiles in place. Structural changes (adding/removing/ reordering profiles, port rate, max-pipes) still need a restart.
10.2 Queue profiles¶
qos queue-profile add <name> <tb|pfifo|fq_codel|fq_pie|cake> [tuning...]
(fq_pie = flow queues + the native PIE AQM;
same tuning keys as fq_codel)
qos queue-profile <name> <key> <val> [...] (EDIT BY NAME: merge keys onto the profile,
e.g. `qos queue-profile fq target 8000`;
a discipline after the name redefines the row)
qos queue-profile modify <N|name> <key> <val> [...] (merge just those keys)
qos queue-profile modify <N|name> <disc> [tuning...] (redefine, name kept)
qos queue-profile modify <N|name> <name> <disc> [tuning...] (full row; renames if the name differs)
qos queue-profile insert <N> <name> <disc> [tuning...]
qos queue-profile delete <N|name> (refused if referenced by a sub-profile / service default)
qos queue-profile move <N|name> <M>
qos subscriber-profile <name> <key> <val> [...] (same merge-edit, e.g.
`qos subscriber-profile testip rate-down 100M rate-up 100M`)
Queueing (qsize/AQM/discipline) takes effect on commit (Section 10.1) — no
restart. commit stages the model and activates it (builds a new scheduler
generation from the committed config); save persists it to qos.conf. The
shaper is a token-bucket with optional WRED/PIE AQM, so some Linux tc-style knobs are
advisory — stored, shown in show qos with (advisory), and round-tripped, but not
enforced by the data plane. AQM knobs (target / interval / rtt / ecn) run only
when AQM is enabled in the build and aqm enable is set; otherwise the discipline is
tail-drop and those knobs are inert.
Fields by discipline — only the keys valid for a discipline are accepted:
| Discipline | Key | Value | Effect |
|---|---|---|---|
| all | qsize |
packets (pow2) | ✅ Best-effort buffer depth. Keep generous — a too-small qsize starves a single TCP flow below its rate. |
| tb | burst |
bytes (k/M) | ✅ Micro-burst allowed before shaping bites |
| tb | limit |
<ms>ms |
✅ Max queue latency when the bucket empties |
| fq_codel / fq_pie / cake | flows |
count | ⚠️ Advisory |
| fq_codel / fq_pie / cake | target |
<us> / <ms>ms |
✅ (AQM) PIE latency target |
| fq_codel / fq_pie / cake | interval |
<us> / <ms>ms |
✅ (AQM) PIE update interval |
| fq_codel / fq_pie / cake | ecn |
on/off |
✅ (AQM) ECN-mark vs. drop |
| fq_codel / fq_pie / cake | quantum |
bytes | ⚠️ Advisory |
| fq_codel / fq_pie / cake | memory |
bytes | ⚠️ Advisory |
| fq_codel / fq_pie / cake | ce-threshold |
<us> |
⚠️ Advisory |
| cake | overhead |
bytes | ✅ Per-packet link-overhead compensation |
| cake | rtt |
<ms> |
✅ Feeds the PIE target when target is unset |
| cake | diffserv |
besteffort|diffserv3|diffserv4|diffserv8 |
✅ Tin count |
| cake | flow-mode |
triple-isolate|flows|hosts|src-host|dst-host|dual-src-host|dual-dst-host |
⚠️ Advisory |
| cake | ack-filter / wash / nat / autorate |
on/off |
⚠️ Advisory |
Examples:
qos queue-profile fq target 8000 # merge-edit by name: change one key
qos queue-profile modify fq qsize 512 burst 16k # merge several keys
qos queue-profile fq cake qsize 4096 rtt 100 # redefine fq as cake (name kept)
qos queue-profile add fqpie fq_pie qsize 4096 target 15ms interval 15ms ecn on
qos queue-profile add cake0 cake qsize 4096 target 5ms interval 100ms overhead 18 rtt 100 diffserv diffserv4 flow-mode triple-isolate ack-filter on wash on
qos subscriber-profile testip queue-profile fqpie # move a plan onto the new queue type
commit ; save
10.3 Pipe budget¶
qos max-pipes <n> subscriber pipe budget (power of two)
Every subscriber that is shaped holds one scheduler pipe, and pipes are pre-allocated.
If max-pipes is below your peak concurrent session count, the subscribers past it get
no shaper at all — full port rate, rate plans unenforced. Set it above your licensed
session count.
commit applies it live: a new scheduler generation is built from the updated config,
new sessions bind to it, and existing subscribers drain across in bursts of 64 every 20 ms
until the old generation empties and is reclaimed. No restart, no session loss. If the new
generation cannot be allocated — not enough hugepage memory, or the previous generation is
still draining — the value is rolled back and the box keeps shaping at the old budget.
Must be a power of two (rte_sched): 256, 512, 1024, 2048, 4096, 8192, 16384.
Memory scales linearly, and the multiplier is not obvious:
subports x max_pipes x 16 queues x qsize x 8 bytes
Each queue profile gets its own subport, and every subport enables the full
max-pipes — including profiles no subscriber uses. Deleting unused queue profiles from
qos.conf cuts pipe memory proportionally, and qsize is the other large factor. Five
profiles at qsize 4096 costs roughly 15x what two profiles at qsize 512 costs for the
same pipe count.
show qos reports the budget, the static-binding reserve and the active session count,
warns within 10% of the cap, and reports loudly if any session ever installs without a
pipe.
10.4 Overhead compensation¶
qos overhead-compensation <pct> shape each pipe <pct> above plan so goodput ≈ plan (0..100)
A shaper counts the full L1/L2 (+PPPoE) frame, but a speed test measures TCP payload — so
a 300M pipe reads ~268M. qos overhead-compensation shapes each pipe that percentage
above its plan so goodput matches the plan (~8–12%; PPPoE nearer 12, IPoE nearer 8;
0 = exact plan). It stages into the candidate: commit applies it live — sets the
global and rebinds every installed subscriber's pipes at their current rate so the new
margin takes effect immediately — and save persists the overhead-compensation line to
qos.conf. show qos shows the active value. (The overhead-compensation <pct> line in
qos.conf is still read at boot; the CLI verb is the live equivalent.)
10.5 Subscriber profiles¶
qos subscriber-profile add <name> rate-down <r> rate-up <r> [queue-profile <qp>] [priority <1-8>]
qos subscriber-profile <name> <key> <val> [...] (EDIT BY NAME: merge keys, e.g.
`qos subscriber-profile testip rate-down 100M rate-up 100M`
or `... testip queue-profile fqpie`)
qos subscriber-profile modify <N|name> <key> <val> [...] (same merge; full row also accepted)
qos subscriber-profile insert <N> <name> rate-down <r> rate-up <r> [queue-profile <qp>] [priority <1-8>]
qos subscriber-profile delete <N|name>
qos subscriber-profile move <N|name> <M>
<r>accepts k/M/G (100M,2G,512k);rate <tx>/<rx>is also accepted.queue-profile <qp>must name an existing queue profile; omitted or-inherits the per-service default.priority <1-8>is a local priority (1 = served first under congestion, 8 = last) applied when this profile backs a static assignment — the configured equivalent of RADIUSNetvyn-Priority. A static assignment and its priority resolve first, overriding any RADIUS rate/priority. Omitted = unset (default weight).
10.6 Assignments¶
qos assign add <cidr> subscriber-profile <name>
qos assign insert <N> <cidr> subscriber-profile <name>
qos assign delete <N|cidr> (e.g. `qos assign delete 10.20.50.4/32`)
qos assign move <N|cidr> <M>
<cidr>is IPv4 or IPv6: a host (10.20.50.3→/32,2001:db8::1→/128) or a prefix (100.64.10.0/24,2001:db8:100::/40).<name>must reference an existing subscriber profile.- Resolution is v4-first: a dual-stack subscriber matches through its framed IPv4; the v6 assignments are consulted only when no v4 assignment matched. A v6 assignment matches the subscriber's framed v6 or its delegated (PD) prefix.
- Both families share the subscriber's one shaper pipe per direction — the plan rate is the combined v4+v6 throughput.
10.7 Service default queue type¶
Which queue profile PPPoE / IPoE subscribers run on by default:
qos service ppp <queue-profile>
qos service ipoe <queue-profile>
These stage into the candidate; commit applies live — the service default switches
and every installed subscriber whose resolved queue profile changed is re-queued on the
spot at its current rate (RADIUS rates untouched). Subscribers pinned to a queue profile
through an assignment keep that pin (assignment > service default).
Referential integrity. References resolve against the running config, so a referenced object must be committed first: a subscriber profile's queue-profile must exist, an assignment's subscriber-profile must exist, and a subscriber profile still referenced by an assignment cannot be deleted. To add a new subscriber profile and an assignment that references it, commit the subscriber profile first. State is
show qos(all three objects + service defaults) andshow qos bindings(resolved effective QoS per live subscriber, with source: RADIUS / static / default). All rates display auto-scaled (512k/50M/52.4M/2G) — non-round values (e.g. a RADIUS rate delivered in kbps) get one decimal instead of a raw kbps figure.
11. RADIUS Commands¶
RADIUS client configuration lives in the radius view and applies live on commit
(the client rebuilds in place — servers re-resolved, scalars updated). The one exception
is coa-port, whose listener re-binds only at boot.
radius server add <host> secret <s> [auth-port <n>] [acct-port <n>] (default ports 1812/1813)
radius server insert <N> <host> secret <s> [auth-port <n>] [acct-port <n>]
radius server delete <N>
radius server move <N> <M>
radius nas-ip <ip> NAS-IP-Address (or 'none')
radius nas-id <id> NAS-Identifier (or 'none')
radius timeout <secs> per-try timeout (default 2)
radius retries <n> retransmits before failover (default 3)
radius coa-port <port> CoA/Disconnect port (default 3799; re-binds at boot)
radius interim-interval <secs> interim acct interval (0 = off)
radius dict-path <path> dictionary tree path
radius message-authenticator off|on|require RFC 2869 attr 80 (default on)
radius undo <nas-ip|nas-id|timeout|retries|coa-port|interim-interval|dict-path|
message-authenticator>
The server list is index-addressable; insert / delete / move reorder failover
priority. Live RADIUS state and counters are shown with show radius [statistics].
11.1 Message-Authenticator¶
Message-Authenticator (RFC 2869, attribute 80) is an HMAC-MD5 signature over the
whole packet keyed with the shared secret. It provides integrity and authenticity —
it is not encryption, and the digest itself travels in cleartext.
| Mode | Behaviour |
|---|---|
off |
Never sent, never checked (legacy) |
on (default) |
Sign every Access-Request; verify any reply that carries a signature |
require |
As on, and additionally drop any Access-* reply that lacks or fails one |
Keep this on. RADIUS/UDP's Response Authenticator is raw MD5, which is chosen-prefix collidable — an attacker positioned between the BNG and the RADIUS server can forge an Access-Accept out of an Access-Reject and authenticate a subscriber who should have been denied (CVE-2024-3596, "BlastRADIUS"). HMAC-MD5 is unaffected, so attribute 80 is the mitigation. There is a second, more mundane reason: modern RADIUS servers (FreeRADIUS 3.2.5+) increasingly require attribute 80 on requests, and with this off such a server silently drops every request the BNG sends — which presents as a total authentication outage rather than a protocol error.
show radius reports the mode; show radius statistics adds a
bad-msg-authent. counter — replies dropped because the signature was missing or
wrong (a forgery, or simply a shared-secret mismatch). Watch it after enabling, and only
move to require once it stays at zero.
Only
User-Password,Tunnel-Passwordand the MS-MPPE keys are obfuscated in RADIUS. Everything else — User-Name, NAS-IP, Framed-IP,Class, and all Netvyn VSAs — is plaintext on the wire. Attribute 80 does not change that; it only makes tampering detectable.
12. Monitoring Commands¶
12.1 Vendor monitoring API¶
A read-only framed-TCP API served by the daemon itself, for a billing portal or NOC dashboard to poll session, interface, resource and health statistics over one persistent TCP connection (not HTTP — see docs/vendor-tcp-api.md for the published wire protocol, message types and a reference client).
service api enable | disable start / stop the API (live)
service api listen <host:port> set the listen address (live rebind), e.g. 0.0.0.0:8090
service api allow <cidr> add a source prefix to the ACL
service api no allow <cidr> remove a source prefix from the ACL
show api state, listen address, auth mode, allowed sources
api applies immediately (it is not staged behind commit). Clients must
authenticate with an operator account (the AUTH command carries username +
password — the same RBAC user store as the CLI/GUI; any role may read, so create a
dedicated read-role account for the portal with system user add monitor read <pw>).
Client connects, AUTH attempts and failures appear in show log api and the audit
trail. Access is additionally restricted by the allowed-source ACL — an empty ACL
means "any source", so add prefixes before exposing the port. Commands:
SESSION_STATS (counts), SESSION_INFO (one session's tx/rx by username — the
table is never dumpable), INTERFACE_LIST, INTERFACE_STATS, RESOURCES,
HEALTH — all strictly read-only; there are no configuration or control
operations.
12.2 Telnet CLI service¶
A native Telnet server on the BNG's own (DPDK) IPs: telnet <bng-ip> gives the
operator a real bng-cli shell — each session spawns bng-cli on a pseudo-terminal,
so login, RBAC, audit, idle logout, the Huawei-style views, TAB/? completion and
history are all the genuine article (no second command parser, no second credential
store).
service telnet enable start the service (DISABLED by default)
service telnet disable
service telnet listen <ip[:port] | port> bind (default 0.0.0.0:23 = any router IP)
forms: `0.0.0.0:2008` · `2008` (port only) · `10.0.0.1 2008`
service telnet allow <cidr> ACL a management prefix — checked BEFORE the login prompt
service telnet no allow <cidr>
service telnet max-sessions <1-16> concurrent session cap
show telnet status, listen, shell, sessions, idle, ACL
All telnet settings stage into the candidate: commit applies them live (the
listener rebinds on the spot) and save persists them to telnet.conf — the standard
model, same as the rest of the configuration.
Requires the bng-cli binary installed at /usr/local/bin/bng-cli (the normal install
location; PATH fallback). Ending the shell (quit from user view, or bng-cli's idle
logout) closes the telnet connection.
⚠️ Telnet is plaintext — operator passwords travel unencrypted. The service is disabled by default; enable it only with an
allowACL restricting it to the management network, and never expose it toward subscribers or the Internet. A denied source is dropped before any banner is sent.
12.3 Compliance / IPDR logging¶
Compliance and per-flow CGNAT logging is configured in the system view:
system ipdr enable|disable compliance (session/block) log
system ipdr file <path> session/block log file
system ipdr flow enable|disable per-flow CGNAT translation log (v4 CGNAT flows + v6 TCP connection-starts)
system ipdr flow prefix <tag> collector line tag
system ipdr flow dir <dir> daily per-flow file dir
system ipdr flow disk enable|disable local disk sink on/off (keeps dir; disable = remote-only)
system ipdr flow skip-dns omit UDP/53 from the per-flow log
system ipdr flow log-dns include UDP/53 (undo skip-dns)
system ipdr flow remote <host:port> UDP collector for the per-flow log
show ipdr compliance + per-flow CGNAT log config and drop counters
ipdr enable / disable, ipdr file, and the per-flow prefix / dir / disk /
remote / skip-dns / log-dns knobs apply live on commit — a collector can be
re-pointed without dropping traffic. Only ipdr flow enable / disable takes effect on
restart. save persists in every case. When the per-flow log is enabled it also captures
IPv6 subscriber-initiated TCP connection starts (IPv6 has no CGNAT/conntrack). show
ipdr prints the disk state, the IPv6 capture state, and separate v4 / v6 drop counters.
12.4 System and platform state¶
show version build version + DPDK version + uptime
show topology lcore / worker / port plan (the live CPU plan)
show system CPU-plan knobs (control-cores, workers, ht-policy)
show health node vitals: uptime, per-core CPU %, memory, power + dispatch state
show power adaptive-polling state: adaptive on/off, nap-us, per-worker nap counts
show interface bonding 802.3ad/LACP + static bonds + live member state (§4.2)
dispatch software PPPoE RSS on/off state (§4.3)
show drops [<interface>] fast-path forward + drop counters (optionally one interface)
show statistics [<interface>] alias for show drops
12.5 Power management (adaptive polling)¶
The forwarding workers poll their NICs continuously, so each worker core reads 100 % in the OS regardless of traffic — and burns the matching power even at idle. Adaptive polling lets an idle worker nap briefly instead of hot-spinning, so an idle core draws power proportional to load. It is opt-in and OFF by default — with it off the data plane is byte-identical to the validated hot-poll baseline.
Set it from the system view (staged like any other config change):
system power adaptive enable|disable turn adaptive polling on/off
system power nap <1-5000> idle nap length in microseconds (default 50)
power show the live runtime state
show power dedicated read-only view (adaptive, nap-us, nap counts)
These stage into the candidate: run commit to apply live, then save to persist
to system.conf so the setting survives a restart. Example:
[Netvyn-BNG] system power adaptive enable
staged: system power adaptive enable ('commit' to apply, 'save' to persist)
[Netvyn-BNG] commit
[Netvyn-BNG] save
Both show version and show health print uptime as raw seconds plus a human-readable
form — uptime 3661 (1hr 1min 1sec) — so it stays script-parseable (the seconds come
first) while an operator reads it at a glance (45sec, 1min 1sec, 1hr 1min 1sec,
2d 3hr 4min 5sec; leading zero units are dropped).
show health reports the live state on one line; show power gives the dedicated
view with per-worker nap counts:
[Netvyn-BNG] show health
...
power-adaptive on nap-us 50 naps 1843201
[Netvyn-BNG] show power
adaptive enable
nap-us 50
naps 1843201
state idle workers nap (power proportional to load)
worker 0 naps 921605
worker 1 naps 921596
Trade-off: the nap is timer-based, so after an idle gap the first packet sees a wake
latency ≈ the nap length (no cost under load — the nap never fires when traffic is
flowing). For latency-strict deployments leave it off, or use a small nap value.
Available on every platform; the deeper power backends (RX-interrupt sleep, CPU
frequency scaling) are Linux-bare-metal roadmap items.
12.6 Operator accounts¶
Operator (CLI / GUI / API) accounts are separate from subscribers. The three assignable roles are:
read— view-only:show/display,ping,traceroute,whoami, and changing your own password.write— adds configuration edits (nat,firewall,interface,pool,qos,radius,routing, …) plus subscriber actions (disconnect,coa) and the transaction verbs (commit/save/rollback).full— the top assignable role (the effective "superadmin"). Required additionally forsystem …CPU/topology configuration (control-cores, max-workers, ht-policy), operator-account management (system user add/system user delete,disconnect user-session,aaa enable|disable), andlicense/reboot/shutdown/factory-reset/maintenance. Baresystemandshow system …stayread.
(A fourth role, engineering, is internal-only and can never be assigned.)
whoami your own username + role (any role)
system user change <name> <new-password> set an account's password (own: any role; other: full)
system user add <name> <role> <password> [<description>] create an account (full)
system user delete <name> remove an account (full)
disconnect user-session <id> revoke a login (id from 'show user-sessions') (full)
show users local operator accounts (read)
show user-sessions active operator logins (read)
Password rules. At least 8 characters, drawn from at least 3 of the 4 classes (lower-case, upper-case, digit, other), and no spaces. The password may not contain the username. Hashing is Argon2id, and repeated failures lock the account for a period, so a short password is not as exposed as the length alone suggests — but 8 is a floor, not a recommendation.
Whose password. system user change takes the account name first, and TAB completes
it from the existing accounts:
system user change alice N3wPa55!
Changing your own password is allowed in any role. Changing someone else's
requires full. The account name is required — system user change alice on its own is
rejected rather than treated as a password, so a forgotten second argument cannot
silently reset your own password to the other operator's name.
The historical single-argument form still works for self-service and is what passwd
maps to:
passwd N3wPa55!
These are operational commands — they apply immediately and are not staged behind
commit. The account-changing actions (system user add, system user delete, system user change,
disconnect user-session) are recorded in the auth log (show auth log) alongside
login and logout events — not the config audit trail. whoami and the show variants are
not audited. Changing your own password drops your live sessions and forces a re-login.
First login. An account still on its initial password is in a forced first-login state:
until you change it, the only commands accepted are system user change / passwd,
whoami, config status, help, and logout — any other configuration or show is
rejected with "default password in use — run 'system user change' before configuring."
whoami flags the state, and the login banner returns first-login.
Either spelling clears it — your own name with the two-argument form, or passwd:
system user change admin N3wPa55!
passwd N3wPa55!
Delegated login (RADIUS). Operators that are not in the local store can be authenticated against a RADIUS realm instead:
aaa enable | disable delegate unknown-user login to RADIUS (default disable) (full)
show aaa delegated-login state (read)
The realm's server and secret live in aaa.conf. On acceptance the server must return a
Netvyn-Admin-Role VSA naming the role — an Access-Accept with no recognised role is
denied, so a misconfigured realm can never silently grant access. Local accounts are
always tried first, so aaa enable cannot lock you out of an existing local login.
13. Debug Commands¶
13.1 Diagnostic log¶
The diagnostic log is captured into an always-on in-memory ring, so you read recent history straight from memory with no file to tail:
show logging diagnostic log config: global level, sink, per-module levels
show log last 200 lines from every module
show log <module> filter by module (radius, nat, pppoe, smgr, …)
show log <module> last <n> tail <n> lines for one module
show log last <n> tail <n> lines across all modules
clear log empty the ring
log level <module> <lvl> set one module's level LIVE (immediate) and persist it
log level all <lvl> set every module live (transient global sweep)
log level … is operational/immediate (no commit): a named module's level applies at
once and is persisted; all is a live-only global sweep. Levels are
off | critical | error | warning | notice | info | debug. To persist the global level,
use system logging level <lvl> + commit.
The global diagnostic level and sink are set in the system view:
system logging level <off|critical|error|warning|notice|info|debug> (default info)
system logging output memory|stdout|stderr|file <path> (default memory)
memory (the default) keeps everything in the ring for show log; a stream sink is an
optional passthrough. These apply live on commit.
13.2 Packet flow trace¶
The flow trace follows a packet through the fast path so you can see exactly where a flow
is classified, translated, shaped, or dropped. It works like tcpdump -G: one command
filters, captures for a fixed window, prints the matching flow, and auto-cleans up — the
operator never needs a separate show or off.
debug trace packet src <ip> flow FROM this source
debug trace packet dst <ip> flow TO this destination
debug trace packet src <ip> dst <ip> a directional flow (src AND dst)
debug trace packet ip <ip> <ip> as src OR dst (either direction)
debug trace packet ... drops only DROPPED packets (append to any filter)
debug trace packet ... for <1-30> capture window in seconds (default 5)
debug trace packet off abort a running capture early
show debug packets re-read the last capture (per-flow L4 detail: see below)
show debug trace re-read the per-stage pipeline path
Default window is 5 s (for omitted). Valid range 1–30 s; outside it returns
invalid duration (1-30 seconds allowed). A src filter shows packets from that IP, a
dst filter shows packets to it. Example:
[Netvyn-BNG] debug trace packet src 100.64.0.2 for 10
capturing packets from src=100.64.0.2 for 10 seconds..........
filter: src=100.64.0.2
src:port dst:port prot len flags ttl tcp(win/mss/ws | s=seq a=ack) in>out nat result
100.64.0.2:51001 142.250.4.100:443 tcp 60 ....S. 63 w64240/mss1452/ws8 1>0 snat forwarded
100.64.0.2:51001 142.250.4.100:443 tcp 52 .A.... 63 w2058 s3428... a119... 1>0 snat forwarded
100.64.0.2:5000 1.1.1.1:53 udp 64 - 63 - 1>0 snat forwarded
3 packet(s) captured (len=on-wire IP bytes; flags=UAPRSF; SYN shows mss/window-scale)
flow trace completed.
Each captured packet now carries per-flow L4 detail, captured at RX so it reflects the real segment sizes and TCP behaviour a subscriber's flow negotiated (useful for comparing a phone's download against a laptop's, or spotting a black-hole, without a span port):
src:port/dst:port— L4 ports for TCP/UDP.len— on-wire IP total length (the number that matters for MTU/PMTUD).flags— TCP flag field, tcpdump-styleUAPRSF(.= clear).tcp(...)— on a SYN, the receive window +mss/window-scale option (w64240/mss1452/ws8); on data/ACK packets, the window pluss=sequence anda=ack (repeateda=on ACKs = duplicate ACKs → downstream loss; repeateds=on data = retransmits).in>out— ingress > egress port (-= egress not yet chosen at capture time).nat—snat/reverse/miss/none;result—forwardedor adrop:*reason.
Filter direction matters with NAT. Capture happens at RX, before NAT. Upstream packets carry the subscriber's inside IP (e.g.
100.64.0.3); downstream replies are addressed to the public pool IP and are only un-NAT'd after capture. So to see a subscriber's download, filter on their public IP (debug trace packet ip <pool-ip>), not the inside IP.
After printing, the trace auto-disarms and clears (back to idle). Use
debug trace packet off only to abort a long capture before its window elapses.
The drops modifier finds a rare drop under load: without it, a high-volume forwarded
flow floods the 1024-entry ring and overwrites the rare dropped packets; with it only
dropped packets are captured (their real src → dst + reason), so debug trace packet drops
surfaces exactly which flows hit ttl-expired / nat-fail / no-route. Narrow it with a
src/dst filter (debug trace packet src 100.64.0.3 drops for 15) on a busy box — an
unfiltered drops still stage-traces every packet.
Use the trace to confirm a subscriber's packets take the expected path (classification →
routing → NAT → QoS → egress). Combine it with show nat session <ip> (Section 9.3) when
diagnosing a translation problem for one subscriber.
14. Show Commands Reference¶
A consolidated reference of the show command family. show is immediate — it reads
running state and live tables and never touches the candidate.
| Command | Shows |
|---|---|
show version |
Build version |
show topology |
lcore / worker / port plan (live CPU plan) |
show system |
CPU-plan knobs (control-cores, workers, ht-policy) |
show sessions |
Active PPPoE/IPoE sessions in one unified table (ip, if, rx/tx) |
show ppp |
Running PPP/PPPoE config |
show dhcp |
Running IPoE/DHCP config |
show pool |
Running framed-IP pools + DNS |
show interface |
One-line summary of every physical DPDK port (admin/oper/speed/type/description) |
show interfaces |
Everything: physical ports + VLAN/QinQ sub-interfaces + trunks/bonds |
show interface <name> |
Full per-port page: state, hardware, DPDK, counters, hardware xstats, transceiver identity + live DDM (see §17) |
show interface stats |
Live per-port NIC counters (rx/tx pkts+bytes, err, drop) — one row per physical port |
show interface vlan |
Configured VLAN/QinQ sub-interfaces |
show interface vlan stats |
Per-VLAN rx/tx packets + bytes (each sub-interface's own traffic) |
show interface bonding |
802.3ad/LACP + static bonds: mode, TX policy, members + live LACP state (§4.2) |
show ip address [<if>] |
Local interface IPv4 addresses (primary + secondaries) |
show ipv6 address [<if>] |
Local interface IPv6 addresses |
show ip dns / show ipv6 dns |
Live subscriber DNS |
show nat |
NAT/CGNAT state: conntrack, timeouts, pools, policy |
show nat session [<ip>] |
Per-flow conntrack dump (filter by subscriber IP) |
show nat flow [<ip>] |
Active per-peer connections (subset of nat session) |
show nat statistics [detail] |
NAT counters + downstream translation counters + recent misses |
show nat block <private-ip> |
One subscriber's port block: used/free vs block size |
show nat blocks |
Per-pool block occupancy summary + busiest blocks |
show nat dstnat |
Destination-NAT (port-forward) rules + per-rule forward counts |
show cgnat fragments |
IPv4 fragment counters |
show firewall [drops] |
v4 firewall state + per-rule counters (drops = discard totals) |
show firewall address-list [<name>] |
Named address-list entries (host + subnet, with TTL) |
show firewall6 [drops] |
v6 firewall state + per-rule counters (separate, stateless) |
show radius [statistics] |
RADIUS servers + scalars (or counters + RTT) |
show arp [config] |
ARP keepalive watch table (or config for tunables) |
show ip route [detail] |
IPv4 RIB (gateway, source, distance, metric, weight, flags) |
show ipv6 route [detail] |
IPv6 RIB |
show ip fib / show ipv6 fib |
Selected route per prefix programmed into the data plane |
show ip nexthop / show ipv6 nexthop |
Nexthop table (egress port + resolved gateway MAC) |
show nexthops |
Default-gw + configured next-hop summary |
show ipv6 pool |
IPv6 prefix pool utilization |
show logging |
Diagnostic log config (global level, sink, per-module levels) |
show log [<module>] [last <n>] |
In-memory diagnostic log buffer |
show ipdr |
Compliance + per-flow CGNAT log config |
show api |
Vendor monitoring API: state, listen address/port, auth mode, allowed-source ACL |
show qos [bindings] |
Queue + subscriber profiles + assignments (bindings = resolved per-subscriber) |
show qos sub <id> |
Per-subscriber QoS detail (rates, octets, shaper drops, queue depth) |
show qos generations |
Live scheduler generations (commit-rebuild drain state) |
show subscribers |
Alias of show qos bindings |
show drops [<interface>] |
Fast-path forward + drop counters |
show statistics [<interface>] |
Alias for show drops |
show license [detail\|usage\|server] |
License state / caps / expiry |
show history |
Recent state-changing commands with provenance: time, user, source-IP (the client device, local for an on-box CLI), channel (cli/gui/rest), command |
show users |
Local operator accounts |
show user-sessions |
Active operator logins |
show audit log [<n>] |
Config-change audit trail (who/what/when/source/result) |
show audit session <sid> |
Audit records for one operator session |
show audit user <name> |
Audit records for one operator |
show auth log [<n>] |
Auth events (login / logout / denied / timeout / user-mgmt) |
show pending |
Uncommitted candidate changes |
show running |
Applied configuration |
show candidate |
Running + candidate overlay |
14.1 Operational actions¶
These act on live state immediately, without the candidate/commit transaction:
clear counters firewall|firewall6|nat [<n>] reset per-rule / per-pool traffic counters
clear log empty the in-memory diagnostic log buffer
clear session ip <a.b.c.d> disconnect a subscriber by framed IPv4
clear session user <name> disconnect by username (PPPoE user / IPoE MAC)
clear session acct-session-id <id> disconnect by Acct-Session-Id (PPPoE only)
clear session interface <name> disconnect every session on an access interface
clear session all disconnect every subscriber session (confirms first)
clear session tears down live subscriber session(s) and reuses the RADIUS
Disconnect-Message path (Acct-Stop, session removal, IP/NAT release). Single selectors
(user / ip / acct-session-id) are synchronous; all and interface tear down in
bounded batches and return immediately — watch progress with show sessions.
clear session all prompts for confirmation before it runs.
14.2 Diagnostics¶
ping <dst> [source <ip>] [count <n>] [interval <ms>] [size <bytes>] [ttl <n>] [timeout <ms>] [df] [fast]
traceroute <dst> [source <ip>] [max-hops <n>] [queries <n>] [timeout <ms>] [size <bytes>]
Both run straight from the user-view prompt. The source address is auto-selected by route
(the egress interface's address) unless source overrides it. df sets the don't-
fragment bit; fast uses a 100 ms ping interval and blocks until done.
15. Configuration Examples¶
Each example is a copy-pasteable sequence ending in commit (and save where the change
should survive a reboot). Run them from system-view unless noted.
15.1 A PPPoE service¶
Bring up PPPoE on two access interfaces with CHAP authentication, IPv6 enabled, and a RADIUS-less IPv6 fallback pool:
system-view
ppp interface add access0 access1
ppp mru 1492
ppp auth-protocol chap,pap
ppp lcp-echo interval 30 failure 3
ppp ipv6 enable
ppp ipv6 pool default
commit
save
15.2 An IPoE service¶
Serve IPoE/DHCP with MAC-based RADIUS identity on one access interface, with a fallback pool and DNS:
system-view
dhcp mode ipoe
dhcp interface add access2
dhcp auth mac
dhcp auth-password s3cr3t-mac-pw
dhcp mac-format colon
dhcp lease-time 3600
dhcp pool default
quit
ip dns 1.1.1.1 8.8.8.8
commit
save
15.3 A framed-IP pool¶
Define a pool and its gateway, then commit:
system-view
pool default range 100.64.10.10 100.64.10.250 gateway 100.64.10.1 prefix 24
quit
commit
save
15.4 CGNAT¶
Enable CGNAT with a public pool, a policy that translates the private range, and the default fragment-cache mode. The public pool loads on the next restart:
system-view
nat enable
nat conntrack-max 2097152
nat udp-mapping endpoint-independent
nat pool add pub1 203.0.113.10-203.0.113.20 ports 1024-65535 block 512 deterministic
nat policy add nat-rule 100.64.0.0/10 pool pub1
cgnat fragments mode cache
commit
save
15.5 A QoS plan¶
Create a queue profile, a 100M residential subscriber profile, and bind it to a pool prefix. Because references resolve against the running config, commit the profiles before the assignment:
system-view
qos queue-profile add res-fq fq_codel qsize 4096 target 5ms interval 100ms ecn on
qos subscriber-profile add res-100 rate-down 100M rate-up 100M queue-profile res-fq
commit
qos assign add 100.64.10.0/24 subscriber-profile res-100
commit
save
15.6 A firewall rule¶
Enable the stateful firewall with uRPF anti-spoof, permit established traffic, and drop new inbound Telnet. Everything applies live on commit:
system-view
firewall enable
firewall urpf strict
firewall filter add accept state established
firewall filter add drop proto tcp dport 23 state new
commit
save
16. Best Practices¶
-
Use
commit confirmedfor risky changes. Any edit that could cut off your own management path — routing, default gateway, firewall enable/uRPF — should be applied withcommit confirmed [<minutes>]. If you lose access, the box auto-reverts; if the change is good, runconfirm. -
Commit at the editing boundary, save at the box boundary.
commitis what applies your candidate to running;saveis what makes running survive a reboot. Commit when you finish editing a change, and save once you have verified it behaves. A committed- but-unsaved change is live but will be lost on reboot. -
Verify before you save. After
commit, confirm the change with the relevantshowcommand (show sessions,show nat statistics,show qos bindings,show ip route) before runningsave. -
Mind apply timing. Changes that apply on restart — reshaping an in-use
nat pool's IP/port range,ipv6 poolreshapes, bonding/trunks, and thesystemCPU-plan knobs — will not affect live traffic oncommitalone. Schedule the restart. (nat pooladd/remove and block-size changes apply live for new sessions, and anat policyrule can reference a pool committed in the same session.) -
Commit referenced objects first. QoS and other references resolve against the running config. Commit a queue profile before a subscriber profile that names it, and a subscriber profile before an assignment that binds it.
-
Commit, don't restart, for QoS tuning. For in-place queue-profile changes (qsize, AQM, discipline tuning),
commitapplies them live (thensave) — new sessions bind immediately and existing sessions migrate gradually with no forwarding interruption. Reserve restarts for structural QoS changes. -
Roll back cleanly. If a candidate is wrong before you commit,
rollbackdiscards it entirely. There is no need to hand-undo staged edits. -
Establish a diagnostic baseline. Before chasing an intermittent problem (a one-way UDP freeze, packet loss), run
clear counters nat/clear counters firewall, let traffic run, then read the counters — a moving counter after a known start point is far easier to interpret than a lifetime total. -
Keep uRPF scoped correctly. IPv4
urpf strictis safe once subscriber routes are in the RIB. IPv6urpf6defaults OFF and should stay off until subscriber v6 reverse- routes are installed, or it will drop legitimate static v6 hosts.
17. show interface detail¶
The interface commands form a small hierarchy, in the style of IOS / JunOS / VRP:
show interface one line per physical port (the summary table)
show interface <name> the full operational page for one port
show interface stats live per-port NIC counters (rx/tx/err/drop table)
17.1 Summary¶
show interface
Interface Admin Oper Speed Type Description
---------------------------------------------------------
ether1 up up 10G SFP+ Uplink-Core
ether2 up up 10G DAC BNG-Blaster
ether3 up up 100M RJ45 Management
Type is EEPROM-backed when a module answers (SFP+, SFP, DAC, AOC) and
falls back to a driver-family guess for copper ports. Admin reflects an
operator interface <name> shutdown; Oper is the live PMD link state.
17.2 Per-interface page — show interface <name>¶
One command returns the complete health picture of a port, so an operator never has to stitch several commands together:
- General — description, admin/oper state, port id, driver, PCI address, NUMA node, MAC, MTU, speed, duplex, autoneg, flow-control, media, any bound IPv4 address.
- DPDK — rx/tx queue counts, descriptor ring sizes, socket, RSS, promiscuous and all-multicast state.
- Total Counters — rx/tx packets + bytes, rx/tx errors, ring-missed and no-mbuf drops (the ethdev basic stats).
- RX / TX Statistics (hardware) — curated per-PMD xstats (CRC, length,
undersize/oversize, fragment, jabber, pause, broadcast/multicast). A counter
the PMD does not provide shows
-; any remaining non-zero hardware counter is listed under Other Non-Zero Hardware Counters so nothing is hidden. - Transceiver — for an SFP/SFP+ optic: module type, vendor + OUI, part number, serial, revision, date code, connector, wavelength, reach; then live DDM (temperature, voltage, TX bias, TX/RX optical power in dBm) with active alarm flags, followed by the full alarm/warning threshold table. A DAC is identified as Passive/Active DAC with vendor + length; a copper port shows no module.
The module EEPROM identity + thresholds are cached per port (1 h, warmed at
boot) because the NIC reads them over slow I2C; only the small live-DDM block is
read on each call, so the page returns in milliseconds. This makes the command a
first-line optical-link diagnostic — a weak or dirty fibre shows immediately as
a low RX-power reading and an rxpwr-low alarm, without leaving the CLI.
Reserved sections (traffic rates, link-since / last-up-down, QoS, LLDP, LACP) are stubbed in the layout and populate in later releases.
Appendix B — Commands that apply only on a daemon restart¶
Almost every command applies live on commit. The exceptions below change
state that is fixed when the daemon boots (lcore layout, port RSS hash, CGNAT
pool/port-block allocation, rte_sched disciplines), so they take effect only
after a restart. For all of them: commit records the change and save persists
it to the .conf; the running data path does not change until you restart.
CPU / lcore plan — re-plans the worker layout at boot:
system control-cores <n>
system control-cores <isolate|shadow> (ht-policy)
system undo control-cores
system undo max-workers-per-10g
system undo ht-policy
CGNAT conntrack allocation & in-use pool reshapes — the flow table is allocated
at init; nat pool add/remove and block-size changes apply live for NEW sessions, but
reshaping the IP/port range of a pool that still holds live blocks waits for restart.
(nat conntrack-max is NOT here — it is the live admission ceiling and applies on
commit. Only the allocation needs a restart.)
nat conntrack-capacity <count> (and: nat undo conntrack-capacity)
pool <name> range <start-ip> <end-ip> gateway <gw-ip> [prefix <len>]
pool <name> next <successor-pool> (and: pool <name> undo next)
pool <name> remove
QoS queue profiles — the rte_sched discipline/qsize/AQM is built into the subports at boot. NOTE: a committed queue-profile edit rebuilds the scheduler live (a new generation, no restart), so no restart is needed:
qos queue-profile add|insert <N> <name> <pfifo|tb|fq_codel|fq_pie|cake> [tuning...]
qos queue-profile <name> <key> <val> [...] (merge-edit by name)
qos queue-profile modify <N|name> ... (keys merge | disc redefines | full row)
qos queue-profile delete <N|name>
qos queue-profile move <N|name> <M>
Fragment RSS co-location — the port RSS hash is set at port configure:
cgnat fragments rss <enable|disable>
Everything not listed here applies live on commit (interface/IP/route, PPPoE/IPoE,
DHCP, firewall, nat policy/rule/snat/dstnat/timeouts/udp-mapping, RADIUS,
qos subscriber-profiles/assignments/service, ARP, power, dispatch, logging, IPDR).
show, debug, clear, ping, traceroute and account/session actions run
immediately (no commit).
Appendix A — Complete Command Index¶
Every command in the grammar (generated from cli/cli_tree.c). Markers: ⟳ = takes effect only after a daemon restart (Appendix B); ⊘ = hidden (executable if typed in full, but never offered by ?/TAB — superadmin/advanced). Everything else applies live on commit (or immediately, for show/debug/actions). <...> = a value you supply.
Rule bodies (
firewall filter [6] add|insert … <action>,nat dstnat add|insert … <rule>) are shown as the action/base only.firewall filtermatch keywords chainproto → dport → state(src-list/dst-list standalone);nat dstnat <rule>=<public-ip> [proto tcp|udp|any] [dport <n>] to <inside-ip> [to-port <n>] [disable]— both are TAB-completable step by step (see §8, §9.2).
show¶
show aaa
show api
show arp
show arp cache
show arp config
show audit log
show audit log <n>
show audit session <sid>
show audit user <user>
show auth log
show auth log <n>
show candidate
show cgnat fragments
show debug packets
show debug trace
show dhcp
show dhcpv6
show drops
show drops <interface>
show firewall
show firewall address-list
show firewall address-list <name>
show firewall drops
show firewall6
show firewall6 drops
show health
show history
show interface
show interface <name>
show interface bonding
show interface statistics
show interface stats
show interface vlan
show interface vlan statistics
show interface vlan stats
show interfaces
show ip address
show ip address <interface>
show ip dns
show ip fib
show ip nexthop
show ip route
show ip route detail
show ipdr
show ipv6 address
show ipv6 address <interface>
show ipv6 dns
show ipv6 fib
show ipv6 neighbor
show ipv6 nexthop
show ipv6 pool
show ipv6 route
show ipv6 route detail
show license
show license detail
show license server
show license usage
show log
show log <module>
show log <module> last <n>
show log last <n>
show logging
show mempool
show nat
show nat block <ip>
show nat blocks
show nat dstnat
show nat flow
show nat flow <ip>
show nat fragments
show nat session
show nat session <ip>
show nat statistics
show nat statistics detail
show nexthops
show pending
show pool
show power
show ppp
show qos
show qos bindings
show qos generations
show qos sub <sub-id>
show radius
show radius statistics
show running
show sessions
show statistics
show statistics <interface>
show system
show topology
show user-sessions
show users
show version
show vlan
show vlan statistics
show vlan stats
interface¶
interface <name> add trunk <name>
interface <name> add vlan <name> <svlan>
interface <name> add vlan <name> <svlan> <cvlan>
interface <name> del trunk <name>
interface <name> del vlan <name>
interface <name> description <text>
interface <name> mtu <n>
interface <name> no shutdown
interface <name> shutdown
interface add trunk <name>
interface add trunk <name> mode 8023ad
interface add trunk <name> mode active-backup
interface add trunk <name> mode balance-xor
interface del trunk <name>
interface identify <name>
interface identify <name> duration <s>
interface identify stop <name>
ip¶
ip address add <interface> <a.b.c.d/p>
ip address add <interface> <a.b.c.d/p> secondary
ip address remove <interface> <a.b.c.d/p>
ip dns <primary>
ip dns <primary> <secondary>
ip dns none
ip route add <cidr> <gateway-ip>
ip route add <cidr> <gateway-ip> distance <distance>
ip route add <cidr> <gateway-ip> distance <distance> metric <metric>
ip route add <cidr> <gateway-ip> distance <distance> metric <metric> weight <weight>
ip route add <cidr> <gateway-ip> distance <distance> weight <weight>
ip route add <cidr> <gateway-ip> metric <metric>
ip route add <cidr> <gateway-ip> metric <metric> weight <weight>
ip route add <cidr> <gateway-ip> weight <weight>
ip route add <cidr> gateway <ip>
ip route add <cidr> gateway <ip> distance <distance>
ip route add <cidr> gateway <ip> distance <distance> metric <metric>
ip route add <cidr> gateway <ip> distance <distance> metric <metric> weight <weight>
ip route add <cidr> gateway <ip> distance <distance> weight <weight>
ip route add <cidr> gateway <ip> interface <name>
ip route add <cidr> gateway <ip> interface <name> distance <distance>
ip route add <cidr> gateway <ip> interface <name> distance <distance> metric <metric>
ip route add <cidr> gateway <ip> interface <name> distance <distance> metric <metric> weight <weight>
ip route add <cidr> gateway <ip> interface <name> distance <distance> weight <weight>
ip route add <cidr> gateway <ip> interface <name> metric <metric>
ip route add <cidr> gateway <ip> interface <name> metric <metric> weight <weight>
ip route add <cidr> gateway <ip> interface <name> weight <weight>
ip route add <cidr> gateway <ip> metric <metric>
ip route add <cidr> gateway <ip> metric <metric> weight <weight>
ip route add <cidr> gateway <ip> weight <weight>
ip route add <cidr> interface <name>
ip route add <cidr> interface <name> distance <distance>
ip route add <cidr> interface <name> distance <distance> metric <metric>
ip route add <cidr> interface <name> distance <distance> metric <metric> weight <weight>
ip route add <cidr> interface <name> distance <distance> weight <weight>
ip route add <cidr> interface <name> metric <metric>
ip route add <cidr> interface <name> metric <metric> weight <weight>
ip route add <cidr> interface <name> weight <weight>
ip route delete <cidr>
ip route delete <cidr> gateway <ip>
ipv6¶
ipv6 address add <interface> <addr/plen>
ipv6 address add <interface> <addr/plen> secondary
ipv6 address remove <interface> <addr/plen>
ipv6 dns <primary>
ipv6 dns <primary> <secondary>
ipv6 dns none
ipv6 pool <name> <base>/<plen> assign <assign-plen>
ipv6 pool <name> remove
ipv6 route add <cidr> <gateway-ip>
ipv6 route add <cidr> <gateway-ip> distance <distance>
ipv6 route add <cidr> <gateway-ip> distance <distance> metric <metric>
ipv6 route add <cidr> <gateway-ip> distance <distance> metric <metric> weight <weight>
ipv6 route add <cidr> <gateway-ip> distance <distance> weight <weight>
ipv6 route add <cidr> <gateway-ip> metric <metric>
ipv6 route add <cidr> <gateway-ip> metric <metric> weight <weight>
ipv6 route add <cidr> <gateway-ip> weight <weight>
ipv6 route add <cidr> gateway <ip>
ipv6 route add <cidr> gateway <ip> distance <distance>
ipv6 route add <cidr> gateway <ip> distance <distance> metric <metric>
ipv6 route add <cidr> gateway <ip> distance <distance> metric <metric> weight <weight>
ipv6 route add <cidr> gateway <ip> distance <distance> weight <weight>
ipv6 route add <cidr> gateway <ip> interface <name>
ipv6 route add <cidr> gateway <ip> interface <name> distance <distance>
ipv6 route add <cidr> gateway <ip> interface <name> distance <distance> metric <metric>
ipv6 route add <cidr> gateway <ip> interface <name> distance <distance> metric <metric> weight <weight>
ipv6 route add <cidr> gateway <ip> interface <name> distance <distance> weight <weight>
ipv6 route add <cidr> gateway <ip> interface <name> metric <metric>
ipv6 route add <cidr> gateway <ip> interface <name> metric <metric> weight <weight>
ipv6 route add <cidr> gateway <ip> interface <name> weight <weight>
ipv6 route add <cidr> gateway <ip> metric <metric>
ipv6 route add <cidr> gateway <ip> metric <metric> weight <weight>
ipv6 route add <cidr> gateway <ip> weight <weight>
ipv6 route add <cidr> interface <name>
ipv6 route add <cidr> interface <name> distance <distance>
ipv6 route add <cidr> interface <name> distance <distance> metric <metric>
ipv6 route add <cidr> interface <name> distance <distance> metric <metric> weight <weight>
ipv6 route add <cidr> interface <name> distance <distance> weight <weight>
ipv6 route add <cidr> interface <name> metric <metric>
ipv6 route add <cidr> interface <name> metric <metric> weight <weight>
ipv6 route add <cidr> interface <name> weight <weight>
ipv6 route delete <cidr>
ipv6 route delete <cidr> gateway <ip>
routing¶
routing
routing recursive-via-default disable
routing recursive-via-default enable
ppp¶
ppp auth-protocol <methods>
ppp interface add <name>
ppp interface remove <name>
ppp ipv6 disable
ppp ipv6 enable
ppp ipv6 pd-pool <name>
ppp ipv6 pool <name>
ppp lcp-echo interval <secs>
ppp lcp-echo interval <secs> failure <count>
ppp mru <bytes>
ppp pool <name>
ppp session-timeout <secs>
ppp setup-timeout <secs>
ppp undo auth-protocol
ppp undo ipv6
ppp undo ipv6-pd-pool
ppp undo ipv6-pool
ppp undo lcp-echo
ppp undo mru
ppp undo pool
ppp undo session-timeout
ppp undo setup-timeout
dhcp¶
dhcp auth ip
dhcp auth mac
dhcp auth none
dhcp auth option82
dhcp auth-password <secret>
dhcp interface add <name>
dhcp interface remove <name>
dhcp lease-time <secs>
dhcp mac-format bare
dhcp mac-format colon
dhcp mac-format hyphen
dhcp mode both
dhcp mode dhcp
dhcp mode ipoe
dhcp mode off
dhcp pool <name>
dhcp undo auth
dhcp undo lease-time
dhcp undo mac-format
dhcp undo mode
dhcp undo pool
dhcpv6¶
dhcpv6 mode off
dhcpv6 mode on
dhcpv6 mode pd
dhcpv6 pd-pool <name>
dhcpv6 pool <name>
dhcpv6 preferred-lifetime <secs>
dhcpv6 t1 <secs>
dhcpv6 t2 <secs>
dhcpv6 undo mode
dhcpv6 undo pd-pool
dhcpv6 undo pool
dhcpv6 undo preferred-lifetime
dhcpv6 undo t1
dhcpv6 undo t2
dhcpv6 undo valid-lifetime
dhcpv6 valid-lifetime <secs>
arp¶
arp interval <secs>
arp retry <count>
arp undo interval
arp undo retry
pool¶
⟳ pool <name> next <successor-pool>
⟳ pool <name> range <start-ip> <end-ip> gateway <gw-ip>
⟳ pool <name> range <start-ip> <end-ip> gateway <gw-ip> prefix <len>
⟳ pool <name> remove
⟳ pool <name> undo next
firewall¶
firewall address-list add <name> <ip|cidr>
firewall address-list add <name> <ip|cidr> timeout <secs>
firewall address-list remove <name> <ip|cidr>
firewall address-list remove <name> <ip|cidr> timeout <secs>
firewall disable
firewall disable6
firewall enable
firewall enable6
firewall filter add accept
firewall filter add drop
firewall filter add reject
firewall filter delete <N>
firewall filter insert <N> accept
firewall filter insert <N> drop
firewall filter insert <N> reject
firewall filter move <N> <M>
firewall filter6 add accept
firewall filter6 add drop
firewall filter6 add reject
firewall filter6 delete <N>
firewall filter6 insert <N> accept
firewall filter6 insert <N> drop
firewall filter6 insert <N> reject
firewall filter6 move <N> <M>
firewall mangle add <rule>
firewall mangle delete <N>
firewall mangle insert <N> <rule>
firewall mangle move <N> <M>
firewall undo enable
firewall urpf disable
firewall urpf strict
firewall urpf6 disable
firewall urpf6 strict
nat¶
⟳ nat conntrack-capacity <count>
nat conntrack-max <count>
nat disable
nat dstnat add <rule>
nat dstnat delete <N>
nat dstnat insert <N> <rule>
nat dstnat move <N> <M>
nat enable
nat policy add nat-rule <cidr> bypass
nat policy add nat-rule <cidr> pool <name>
nat policy add snat <cidr> to <target>
nat policy delete <N>
nat policy insert <N> nat-rule <cidr> bypass
nat policy insert <N> nat-rule <cidr> pool <name>
nat policy insert <N> snat <cidr> to <target>
nat policy move <N> <M>
⟳ nat pool add <name> <ip-lo-hi> ports <lo-hi> block <size> deterministic
⟳ nat pool add <name> <ip-lo-hi> ports <lo-hi> block <size> dynamic
⟳ nat pool remove <name>
nat rule <cidr> bypass
nat rule <cidr> pool <name>
nat snat <cidr> to <target>
nat timeout icmp <seconds>
nat timeout tcp-close <seconds>
nat timeout tcp-closing <seconds>
nat timeout tcp-established <seconds>
nat timeout tcp-syn <seconds>
nat timeout udp <seconds>
nat timeout udp-eim-reserve <seconds>
nat timeout udp-stream <seconds>
nat udp-mapping endpoint-independent
nat udp-mapping symmetric
⟳ nat undo conntrack-max
nat undo enable
nat undo timeout icmp
nat undo timeout tcp-close
nat undo timeout tcp-closing
nat undo timeout tcp-established
nat undo timeout tcp-syn
nat undo timeout udp
nat undo timeout udp-eim-reserve
nat undo timeout udp-stream
nat undo udp-mapping
cgnat¶
cgnat fragments mode cache
cgnat fragments mode drop
cgnat fragments mode reassembly
⟳ cgnat fragments rss disable
⟳ cgnat fragments rss enable
cgnat fragments timeout <seconds>
qos¶
qos assign add <cidr> subscriber-profile <name>
qos assign delete <N|cidr>
qos assign insert <N> <cidr> subscriber-profile <name>
qos assign move <N|cidr> <M>
⟳ qos queue-profile add <name> cake
⟳ qos queue-profile add <name> fq_codel
⟳ qos queue-profile add <name> fq_pie
⟳ qos queue-profile add <name> pfifo
⟳ qos queue-profile add <name> tb
qos queue-profile <name> <key> <val> [...] (merge-edit by name)
qos queue-profile <name> <disc> [tuning...] (redefine by name)
⟳ qos queue-profile delete <N|name>
⟳ qos queue-profile insert <N> <name> <disc> [tuning...]
qos queue-profile modify <N|name> <key> <val> [...]
qos queue-profile modify <N|name> <disc> [tuning...]
qos queue-profile modify <N|name> <name> <disc> [tuning...]
⟳ qos queue-profile move <N|name> <M>
qos max-pipes <n>
qos overhead-compensation <pct>
qos service ipoe <queue-profile>
qos service ppp <queue-profile>
qos subscriber-profile add <name> rate-down <r> rate-up <r>
qos subscriber-profile add <name> rate-down <r> rate-up <r> queue-profile
qos subscriber-profile add <name> rate-down <r> rate-up <r> queue-profile <qp>
qos subscriber-profile add <name> rate-down <r> rate-up <r> queue-profile <qp> priority
qos subscriber-profile add <name> rate-down <r> rate-up <r> queue-profile <qp> priority <1-8>
qos subscriber-profile <name> <key> <val> [...] (merge-edit by name: rate-down/rate-up/queue-profile/priority)
qos subscriber-profile modify <N|name> <key> <val> [...]
qos subscriber-profile delete <N|name>
qos subscriber-profile insert <N> <name> rate-down <r> rate-up <r>
qos subscriber-profile insert <N> <name> rate-down <r> rate-up <r> queue-profile
qos subscriber-profile insert <N> <name> rate-down <r> rate-up <r> queue-profile <qp>
qos subscriber-profile insert <N> <name> rate-down <r> rate-up <r> queue-profile <qp> priority
qos subscriber-profile insert <N> <name> rate-down <r> rate-up <r> queue-profile <qp> priority <1-8>
qos subscriber-profile move <N|name> <M>
radius¶
radius coa-port <port>
radius dict-path <path>
radius interim-interval <secs>
radius message-authenticator off
radius message-authenticator on
radius message-authenticator require
radius nas-id <id>
radius nas-ip <ip>
radius retries <n>
radius server add <host> secret <secret>
radius server add <host> secret <secret> auth-port <port>
radius server add <host> secret <secret> auth-port <port> acct-port <port>
radius server delete <N>
radius server insert <N> <host> secret <secret>
radius server insert <N> <host> secret <secret> auth-port <port>
radius server insert <N> <host> secret <secret> auth-port <port> acct-port <port>
radius server move <N> <M>
radius timeout <secs>
radius undo coa-port
radius undo dict-path
radius undo interim-interval
radius undo message-authenticator
radius undo nas-id
radius undo nas-ip
radius undo retries
radius undo timeout
system¶
⟳ system control-cores <n>
system ht-policy isolate
system ht-policy shadow
system ipdr disable
system ipdr enable
system ipdr file <path>
system ipdr flow dir <dir>
system ipdr flow disable
system ipdr flow disk disable
system ipdr flow disk enable
system ipdr flow enable
system ipdr flow prefix <tag>
system ipdr flow remote <host:port>
system ipdr flow skip-dns
system logging level critical
system logging level debug
system logging level error
system logging level info
system logging level notice
system logging level off
system logging level warning
system logging output file <path>
system logging output memory
system logging output stderr
system logging output stdout
system max-workers-per-10g <n>
⟳ system undo control-cores
⟳ system undo ht-policy
system undo ipdr enable
system undo ipdr file
system undo ipdr flow
system undo ipdr flow dir
system undo ipdr flow prefix
system undo ipdr flow remote
system undo ipdr flow skip-dns
system undo logging level
system undo logging output
⟳ system undo max-workers-per-10g
system dispatch¶
dispatch
system dispatch disable
system dispatch enable
system power¶
power
system power adaptive disable
system power adaptive enable
system power nap <us>
license¶
⊘ license activate <key>
⊘ license install <file>
⊘ license reload
license request
license request export <file>
service api¶
service api allow <cidr>
service api disable
service api enable
service api listen <host:port>
service api no allow <cidr>
service telnet¶
service telnet allow <cidr>
service telnet deny <cidr>
service telnet disable
service telnet enable
service telnet listen <ip:port | port | ip>
service telnet max-sessions <n>
service telnet no allow <cidr>
service telnet no deny <cidr>
aaa¶
aaa disable
aaa enable
log¶
log level <module> <level>
log level all <level>
system user¶
system user add <name> full <password>
system user add <name> full <password> <description>
system user add <name> read <password>
system user add <name> read <password> <description>
system user add <name> write <password>
system user add <name> write <password> <description>
system user change <name> <new-password>
system user delete <name>
disconnect¶
disconnect user-session <id>
clear¶
clear counters firewall
clear counters firewall <number>
clear counters firewall6
clear counters firewall6 <number>
clear counters nat
clear counters nat <number>
clear debug
clear debug packets
clear log
clear session acct-session-id <id>
clear session all
clear session interface <name>
clear session ip <a.b.c.d>
clear session user <name>
debug¶
debug trace packet drops
debug trace packet drops for <seconds>
debug trace packet dst <ip>
debug trace packet dst <ip> drops
debug trace packet dst <ip> drops for <seconds>
debug trace packet dst <ip> for <seconds>
debug trace packet ip <ip>
debug trace packet ip <ip> drops
debug trace packet ip <ip> drops for <seconds>
debug trace packet ip <ip> for <seconds>
debug trace packet off
debug trace packet src <ip>
debug trace packet src <ip> drops
debug trace packet src <ip> drops for <seconds>
debug trace packet src <ip> dst <ip>
debug trace packet src <ip> dst <ip> drops
debug trace packet src <ip> dst <ip> drops for <seconds>
debug trace packet src <ip> dst <ip> for <seconds>
debug trace packet src <ip> for <seconds>
ping¶
ping <dst-ip>
traceroute¶
traceroute <dst-ip>
commit¶
commit
commit confirmed
commit confirmed <minutes>
confirm¶
confirm
rollback¶
rollback
save¶
save
load¶
load
display¶
display current-configuration
whoami¶
whoami
Related documentation: README · CLI Guide · Vendor API · Internal docs