Skip to main content

CLI flags

The simulator binary is driven entirely by command-line flags. This page is the authoritative catalog — new flags land here first.

Run the simulator with:

sudo ./nl6 [options]

Root is required because the simulator creates TUN interfaces and manages the nl6sim network namespace. See Network namespace for the namespace details and Quick start for a minimal invocation.

Core flags

FlagTypeDefaultPurpose
-auto-start-ipstringAuto-create devices starting from this IP (e.g. 192.168.100.1).
-auto-countint0Number of devices to auto-create. Requires -auto-start-ip.
-auto-netmaskstring16Netmask (prefix length) for auto-created devices. The fleet is a flat /16 management plane — only the /16 network and broadcast are reserved, so .x.0/.x.255 are ordinary device hosts. Accepts 8 / 16 / 24; an explicit 24 keeps classic per-/24 semantics (skips .0/.255).
-portstring8080HTTP API server port.
-snmp-portint161UDP port for the SNMP listener on each device. Use 1161 to avoid requiring CAP_NET_BIND_SERVICE.
-no-namespaceboolfalseDisable network namespace isolation (run in the root namespace).
-helpShow the help message and exit.
-versionPrint the simulator version string to stdout and exit 0. Runs before any startup side effects (no TUN, no netns, no port binds) so it works from unprivileged shells and inside minimal containers.

SNMPv3 flags

Omit the engine-id flag to run in v2c-only mode.

FlagValuesDefaultPurpose
-snmpv3-engine-idstringEnable SNMPv3 with the specified engine ID (e.g. 0x80001234).
-snmpv3-authnone | md5 | sha1md5SNMPv3 authentication protocol (RFC 3414 USM). Implemented in nl6#624 and verified against net-snmp: the key is derived by §A.2 password-to-key plus localization, and the HMAC is truncated to 12 octets. It also selects the hash used to localize the privacy key (§2.6). Inbound messages are verified, so a wrong password is answered with a usmStatsWrongDigests Report.
-snmpv3-privnone | des | aes128noneSNMPv3 privacy protocol. Requires -snmpv3-auth, since USM defines no privacy-without-authentication level. The key comes from the per-device snmpv3.priv_password REST field, falling back to the auth password — a CLI-started fleet has no separate privacy-password flag and reuses the shared password; DES builds IV = salt XOR pre-IV (RFC 3414 §8.1.1.1) and AES128 builds its IV from the advertised engine boots and time (RFC 3826 §3.1.2.1). Both conformant as of nl6#624.

See SNMP reference for the auth/priv compatibility matrix.

Interface-state scenarios

The -if-scenario flag controls the SNMP admin/oper status reported for all simulated interfaces, so you can reproduce common network conditions without editing resource files.

FlagTypeDefaultPurpose
-if-scenarioint2Interface state scenario: 1=all-shutdown, 2=all-normal, 3=all-failure, 4=pct-failure.
-if-failure-pctint10Percentage of interfaces with oper-down (used with -if-scenario 4, 0–100).
ScenarioNameifAdminStatusifOperStatusUse case
1all-shutdowndown (2)down (2)Planned maintenance, device decommission
2all-normal (default)up (1)up (1)Normal steady-state operations
3all-failureup (1)down (2)Link failures, SFP issues, cable pull
4pct-failureup (1)down for n%Partial outage, staged rollout testing

Scenario 4 uses a deterministic rule (ifIndex % 100 < n) so test runs are reproducible across restarts.

Error / discard scenario

-if-scenario governs which interfaces are up. A companion flag, -if-error-scenario, governs how clean the interfaces that are up behave — the ppm ranges used to derive ifInErrors, ifOutErrors, ifInDiscards, and ifOutDiscards from the live packet counters.

FlagValuesDefaultPurpose
-if-error-scenarioclean | typical | degraded | failingcleanAuto-start-batch default for per-device error / discard counter cycling. REST-created devices default to clean independently (they opt in via if_error_scenario in the POST body).
ScenarioerrPpm rangediscPpm rangeUse case
clean (default)00Pristine lab gear — counters stay at the pre-seeded baseline
typical10 – 10020 – 200Good production gear; faint error/discard growth visible in long-period polls
degraded1 000 – 10 0002 000 – 20 000Congested / faulty optics; 0.1 – 1 % error rate
failing10 000 – 100 00020 000 – 200 000Link-flap / bad cable; 1 – 10 % error rate

Each interface within a device draws its per-direction ppm deterministically from the scenario's band at device creation — so repeated runs with the same auto-start layout produce the same per-interface values. clean (0/0) is the backwards-compatible default and leaves all error/discard counters at their pre-seeded zero.

Unlike -if-scenario, this setting is per-device: every device carries its own scenario, so one simulator can host 100 clean lab devices alongside 5 degraded ones for alert-threshold testing. See if-counters reference.

-if-flap-scenario drives Poisson-distributed link flaps per (device, ifIndex). Mutations go through the interface state engine that powers SNMP ifOperStatus / ifAdminStatus / ifLastChange and gNMI ON_CHANGE subscribers, so all three surfaces see the same value at the same instant.

FlagValuesDefaultScopePurpose
-if-flap-scenarioclean | rare | typical | aggressivecleanseedAuto-start-batch per-device link-flap scenario. REST devices default to clean; opt in via if_flap_scenario POST body.
-if-flap-global-capint (events/sec)0globalSimulator-wide rate ceiling on flap events. 0 is unlimited.
ScenarioMean inter-flapDown durationUse case
clean (default)∞ (no flaps)n/aSteady-state regression testing
rare~6 hours / interfaceuniform 1–10 sLong-running fleets, background variance
typical~15 minutes / interfaceuniform 1–30 sCollector alarm-pipeline stress
aggressive~1 minute / interfaceuniform 1–5 sChaos / churn measurement

See interface state engine reference for the REST control plane (POST /api/v1/devices/{ip}/interfaces/{ifIndex}/{oper,admin}-status), auto-revert semantics, and the cross-protocol consistency contract.

Optical health band

-optical-scenario sets the steady-state health of each coherent optical channel on optical transport device types only (today ciena_waveserver5). It is keyed by OCH component name, never by ifIndex, and it drives the whole receive-side cascade: received power and accumulated noise are two independent dials, osnr = pIn - nAse, and osnr feeds q-valuepre-fec-berfec-uncorrectable-blocks.

FlagValuesDefaultScopePurpose
-optical-scenarioclean | typical | degraded | failingcleanseedAuto-start-batch per-device optical health band. REST devices default to clean; opt in via optical_scenario in the POST body.
ScenarioOSNR (dB)Q (dB)pre-FEC BERUncorrectable blocksUse case
clean (default)18.3011.429.8e-05neverHealthy 400G line; baseline regression testing
typical16.689.801.0e-03neverGood production span with normal margin
degraded15.608.723.2e-03neverVisibly elevated BER that FEC still corrects — the window where a proactive alarm has value
failing10.103.227.4e-02alwaysPast the 2e-2 SD-FEC threshold; genuinely service-affecting

Only failing crosses the FEC threshold, and it does so for every channel across the entire dial period — so fec-uncorrectable-blocks > 0 is a reliable "service-affecting" signal for a collector rule. degraded stays clear of the threshold for every channel, which is what makes the distinction useful.

Setting a non-clean band on a device type that has no optical channels is rejected with 400: the value would silently do nothing, so the contradiction is surfaced rather than accepted. For the same reason optical_scenario is absent from GET /api/v1/devices for non-optical types. A mixed round_robin batch is still accepted — the optical devices take the band and the rest ignore it.

Values are deterministic per (device, channel) and analytic — no per-channel goroutine — so SNMP and gNMI agree byte-for-byte at the same instant. See gNMI reference for the served leaf set.

Export flag scope

Export flags (flow / trap / syslog) fall into two categories:

  • seed — applies only to devices created by the -auto-start-ip batch at startup. Devices subsequently created via POST /api/v1/devices do NOT inherit these values; they must opt in by including a flow / traps / syslog block in the request body.
  • global — applies simulator-wide regardless of how the device was created. Shared sockets, catalogs, rate-limiter, and network-namespace bind policy sit here.

Duration units differ between CLI and REST: CLI flags that express a duration take integer seconds (e.g. -flow-tick-interval 5, -trap-interval 30), while the REST per-device blocks require Go duration strings ("tick_interval": "5s", "interval": "30s"). Passing an integer in the REST body ("interval": 30) is rejected with 400 by design — the two forms are not interchangeable.

See Web API for the per-device block schema and Migration for converting pre-per-device-config invocations.

Flow export flags

See Flow export (operator guide) for prerequisites and collector setup, and Flow export reference for protocol details.

FlagTypeDefaultScopePurpose
-flow-collectorstringseedEnable flow export to this UDP collector (e.g. 192.168.1.10:2055) for the auto-start batch.
-flow-protocolnetflow9 | ipfix | netflow5 | sflownetflow9seedFlow export protocol (alias: sflow5).
-flow-tick-intervalint (seconds)5seedFlow ticker cadence. Sets batching, not volume — see the note below. Applied at construction and not runtime-mutable. The per-device tick_interval is still accepted and not honored (nl6#445).
-flow-active-timeoutint (seconds)30seedCap on how long a still-running flow stays cached before it is exported. Sets a mean, not an exact deadline: each flow's deadline is jittered by ±25 %, so 30 spreads expiry over 22.5s to 37.5s. See Flow export → emission shape.
-flow-inactive-timeoutint (seconds)15seedIdle time after a flow's last packet before it is exported.

| -flow-template-interval | int (seconds) | 60 | global | Template retransmission interval (NetFlow v9 / IPFIX only). | | -flow-sub-agent-id | uint | 0 | seed | sFlow sub_agent_id emitted in every datagram header by the auto-start batch (one value for the whole batch; per-group values via the REST flow.sub_agent_id field). Ignored by non-sFlow protocols. See Flow export reference → sFlow sub-agent id. | | -flow-option-interface-table | if-scoped | system-scoped | — (off) | seed | Emit v9/IPFIX interface option records ("option interface-table") for the auto-start batch: if-scoped carries the ifIndex in the scope with fields 82+83; system-scoped carries it as option field INPUT_SNMP(10) with field 83 only (the IOS-XR shape). Requires -flow-protocol netflow9 or ipfix — other protocols fail startup validation. Per-group shapes via the REST flow.options_interface_table field. See Flow export reference → Interface option records. | | -flow-source-per-device | bool | true | global | Use each device's IP as the UDP source address. |

Tick interval sets batching, not volume

It is natural to reach for -flow-tick-interval to turn flow volume up or down. It is not that knob.

Export volume is set by how many flows exist and how long they live:

records/s ≈ ConcurrentFlows / mean-flow-lifetime
mean-flow-lifetime = mean of min(active-timeout, flow-duration + inactive-timeout)

The tick interval decides how finely that stream is cut into datagrams. A slower tick sends bigger datagrams, not proportionally fewer records. A residual dependence remains, because export polls: a flow sits cached up to one interval past its deadline, worth roughly T/2 on average. It is bounded by the interval and is not a proportional control.

That T/2 is not only a rate effect. It is real cache residency, so scenario pacing divides a requested rate by mean-flow-lifetime + T/2 rather than by the lifetime alone. Omitting it sized every paced cache short and ran every paced run a few percent low (nl6#462).

To change volume, change the device profile's concurrent-flow count or the timeouts.

Before nl6#446 was fixed, this flag was inert (every deployment ticked at 5s) and volume did step with cadence, because the whole cache expired on one tick and then sat empty. Both are fixed; a deployment that set this flag will see a different cadence and every flow deployment will see a different record rate. See Flow export.

SNMP trap / INFORM export flags

See SNMP trap / INFORM export (operator guide) for prerequisites and snmptrapd smoke-test, and SNMP trap reference for wire format and catalog JSON.

FlagTypeDefaultScopePurpose
-trap-collectorstringseedEnable trap export to this UDP collector (e.g. 192.168.1.10:162) for the auto-start batch. Empty disables seeding; REST-created devices can still opt in via the traps block.
-trap-modetrap | informtrapseedNotification mode. TRAP is fire-and-forget; INFORM is acknowledged and retried.
-trap-intervalduration30sseedSimulator-wide mean firing interval (Poisson-distributed, not periodic). Every trap-enabled device fires at this cadence; the per-device interval in a REST traps block is accepted, echoed by GET /api/v1/devices, and not honored (nl6#445). To silence a fleet use -fidelity (or POST /api/v1/fidelity at runtime), not a long interval.
-trap-global-capint (tps)0globalSimulator-wide rate ceiling across fires + INFORM retries. 0 is unlimited.
-trap-catalogstringglobalPath to a JSON catalog; empty uses the embedded universal 5-trap catalog + per-type overlays from resources/<slug>/traps.json. Setting this flag disables per-type overlays — the file becomes the sole catalog for every device.
-trap-communitystringpublicseedSNMPv2c community string. Ignored under -trap-snmp-version=v3 — an SNMPv3 message carries no community string anywhere; nl6 warns at startup if you set it explicitly.
-trap-snmp-versionv2c | v1 | v3v2cseedNotification wire format. v1 emits RFC 1157 Trap-PDUs (tag 0xA4) with the identity derived per RFC 3584 §3.2. v3 emits the same SNMPv2-Trap-PDU as v2c inside an RFC 3414 USM envelope. One per fleet; neither v1 nor v3 can be combined with -trap-mode inform — SNMPv1 defines no InformRequest at all, and an SNMPv3 inform is authoritative at the receiver, which needs an engine-discovery exchange nl6 does not implement.
-trap-snmpv3-userstringseedUSM user name carried in msgUserName. Required when -trap-snmp-version=v3; USM has no anonymous identity.
-trap-snmpv3-authnone | md5 | sha1noneseedUSM authentication protocol for notifications. Also selects the hash that localizes the privacy key (RFC 3414 §2.6). Strict: an unrecognised value is fatal at startup, unlike -snmpv3-auth, which logs and falls back to MD5.
-trap-snmpv3-privnone | des | aes128noneseedUSM privacy protocol for notifications. Requires an authentication protocol — USM defines no privacy-without-authentication security level.
-trap-snmpv3-passwordstringseedUSM authentication password. Required when -trap-snmpv3-auth is not none. Visible in ps — see the warning below.
-trap-snmpv3-priv-passwordstringseedUSM privacy password. Empty reuses -trap-snmpv3-password, matching the poll path's own fallback. Visible in ps — see the warning below.
-trap-source-per-devicebooltrueglobalUse each device's IP as the UDP source address. Required when a device is configured mode=inform — enforced at device-attach time: the attach fails per-device and the device's trapConfig is cleared.
-trap-inform-timeoutduration5sseedPer-retry timeout in INFORM mode.
-trap-inform-retriesint2seedMaximum retransmissions per INFORM before it's declared failed.
These are the only secrets on nl6's command line

-trap-snmpv3-password and -trap-snmpv3-priv-password are the first credentials nl6 accepts as flags — the polling side deliberately has none. A command line is not private: it is readable by every user on the host through ps and /proc/<pid>/cmdline, recorded in shell history, and echoed verbatim by docker inspect and kubectl describe pod.

Use lab credentials only, and never a password that protects anything else. An environment-variable or file form is recorded as follow-up work; until it exists there is no private way to pass these.

There is no -trap-snmpv3-engine-id, and that is deliberate

Each device derives its own authoritative engine ID from its IPv4 address, so two devices sharing a user and password still localize different keys. A configured engine ID would be shared by the whole fleet, which is the shared-identity defect nl6#588 and nl6#599 each corrected once already.

The -trap-snmpv3-* flags are also separate from the -snmpv3-* poll flags on purpose. A device polled over SNMPv3 and a trap received from that same device report two different snmpEngineID values: the poll engine's is fleet-wide (-snmpv3-engine-id), while a notification originator is authoritative for its own engine (RFC 3414 §2.1). Correct, and the first thing that looks like a bug when you debug it — see SNMP trap reference → SNMPv3 notifications.

GET /api/v1/traps/status reports each exporting device's derived engine ID under snmpv3.engine_ids_by_device, which is what a receiver's createUser -e line needs.

gNMI target flags

The gNMI subsystem is always-on by default and serves a read-only OpenConfig interfaces subset over gRPC + TLS on every device. See gNMI target reference for path coverage, subscribe semantics, and gnmic invocation examples.

FlagTypeDefaultScopePurpose
-gnmi-portint9339globalTCP port for the gNMI listener on each device.
-gnmi-disableboolfalseglobalDisable the subsystem; no device listens on the gNMI port.

gNMI dial-out flags

Dial-out reverses the connection direction: the device dials a collector and pushes telemetry over a gNMIReverse.Publish stream. Per-device and opt-in — the fleet can mix dial-in and dial-out devices. See gNMI dial-out reference for wire protocol, modes, TLS, and the per-device gnmi_dialout REST block.

FlagTypeDefaultScopePurpose
-gnmi-modedial-in | dial-outdial-inseedgNMI mode for the auto-start batch. dial-out additionally pushes telemetry to -gnmi-dialout-collector; the dial-in listener keeps serving either way.
-gnmi-dialout-collectorstringseedDial-out collector address (host:port). Required when -gnmi-mode=dial-out.
-gnmi-dialout-flavorstringgnmireverseseedDial-out wire flavor (Arista gNMIReverse is the only shipped flavor).
-gnmi-dialout-encodingjson_ietf | protojson_ietfseedValue encoding for pushed updates.
-gnmi-dialout-sub-modesample | on-changesampleseedSubscription mode: fixed-interval snapshots or interface-state transitions.
-gnmi-dialout-intervalduration10sseedSAMPLE cadence (clamped to a 1s floor).
-gnmi-dialout-tlsbooltrueseedUse TLS to the collector (false = plaintext, Arista -collector_tls=false parity).
-gnmi-dialout-tls-insecureboolfalseseedSkip collector certificate verification (dev only).
-gnmi-dialout-tls-castringseedPEM CA bundle to verify the collector against (empty = system roots).
-gnmi-dialout-mtlsboolfalseseedPresent the shared TLS certificate as a client cert (mutual TLS).

UDP syslog export flags

See UDP syslog export (operator guide) for prerequisites and netcat smoke-test, and Syslog export reference for wire format and catalog JSON.

FlagTypeDefaultScopePurpose
-syslog-collectorstringseedEnable syslog export to this UDP collector (e.g. 192.168.1.10:514) for the auto-start batch. Empty disables seeding; REST-created devices can still opt in via the syslog block.
-syslog-format5424 | 31645424seedWire format. RFC 5424 is structured (recommended); RFC 3164 is legacy BSD. Per-device as of phase 5 — different devices can emit different formats to the same collector; the shared-socket pool is keyed by (collector, format) so streams never interleave.
-syslog-intervalduration10sseedSimulator-wide mean firing interval (Poisson-distributed, not periodic). Every syslog-enabled device fires at this cadence; the per-device interval in a REST syslog block is accepted, echoed by GET /api/v1/devices, and not honored (nl6#445). To silence a fleet use -fidelity (or POST /api/v1/fidelity at runtime), not a long interval.
-syslog-global-capint (rate)0globalSimulator-wide rate ceiling across scheduled fires. On-demand HTTP fires bypass the cap. 0 is unlimited.
-syslog-catalogstringglobalPath to a JSON catalog; empty uses the embedded universal 6-entry catalog + per-type overlays from resources/<slug>/syslog.json. Setting this flag disables per-type overlays — the file becomes the sole catalog for every device.
-syslog-transportudp | tcp | tlsudpseedTransport for the auto-start batch. tls is RFC 5425 (TCP inside TLS, port 6514 by default, octet-counting forced); it verifies the collector and presents no certificate of its own. tcp is RFC 6587 syslog-over-TCP: one connection per device, reconnecting with capped backoff. Per-device via the REST syslog.transport field. See Syslog export → TCP transport.
-syslog-framingoctet-counting | non-transparentoctet-countingseedRFC 6587 framing, used only when the transport is tcp. Under tls it is forced to octet-counting (RFC 5425 §4.3.1) and anything else is rejected. Setting it while the transport is udp is rejected at startup rather than ignored — framing is a stream concept, and echoing back a setting nothing reads is the defect nl6#445 describes.
-syslog-tls-capathseedPEM CA bundle verifying the syslog collector under -syslog-transport tls. Empty uses the host's root store. Read once at startup; the per-device REST config carries the PEM inline (tls.ca_pem) rather than a path, so no HTTP request can name a file for the simulator to open.
-syslog-tls-insecureboolfalseseedSkip verification of the collector's certificate. Development only. Requires -syslog-transport tls.
-syslog-source-per-devicebooltrueglobalUse each device's IP as the source address. Per-device bind failures are non-fatal under udp (unlike INFORM mode on the trap side) — the exporter falls back to the shared socket with a warning. Under tcp there is no shared-socket fallback, so setting this to false makes a TCP attach fail rather than degrade; see Syslog export → TCP transport.

Load-test scenario flags

Global switches for the load-test scenario subsystem. The scenarios themselves are driven over REST (/api/v1/scenarios); these flags shape the whole fleet at startup.

FlagTypeDefaultScopePurpose
-fidelityboolfalseglobalKeep the fleet silent — no autonomous flow / SNMP-trap / syslog / gNMI-dial-out push — except during a running scenario's [T0,T1) window, for a clean measurement window. Devices still answer polls; explicit on-demand fires still go through. Also togglable at runtime via POST /api/v1/fidelity, so bracketing a measurement does not require a restart; this flag is then the startup default rather than the value in force. See Fidelity mode.
-scenario-penuint0globalIANA Private Enterprise Number for PEN-dependent scenario run tags (syslog SD-PARAM, SNMP enterprise varbind). 0 = unset → those levers degrade to window + source-IP isolation.

LLDP topology flag

Pre-load an inter-device LLDP link graph at startup. The graph is also mutable at runtime via POST / DELETE /api/v1/topology. See LLDP topology reference.

FlagTypeDefaultScopePurpose
-topology-configstringglobalPath to a JSON inter-device LLDP link graph ({"links":[{"a":{"ip","ifindex"},"b":{"ip","ifindex"}}]}). Loaded at startup; validation is syntactic only (device / ifIndex are resolved lazily at serve time).

DNS service-discovery flags

nl6 acts as a hidden DNS primary; a CoreDNS secondary transfers the zones. Off by default. See DNS service-discovery reference.

FlagTypeDefaultScopePurpose
-dns-enableboolfalseglobalEnable the DNS service-discovery server.
-dns-domainstringnl6.localglobalForward zone apex (<device-name>.<domain>).
-dns-listenstring:5353globalBind address (host:port) in the container's default netns.
-dns-reverse-zonestring42.10.in-addr.arpaglobalComma-separated in-addr.arpa reverse zone(s). IPs outside get an A but no PTR.
-dns-notifystringglobalComma-separated secondary NOTIFY targets (host:port); empty disables NOTIFY.
-dns-debounceduration1sglobalQuiescence window coalescing a burst of device changes into one serial bump + NOTIFY.

Continuous profiling flags

Off by default: with none of these set and no POST /api/v1/profiling, no profiler runs and /debug/pprof/ answers 503. The gate is also switchable at runtime (POST /api/v1/profiling), so -profiling-pyroscope is the startup default rather than the value in force. See Continuous profiling.

FlagTypeDefaultScopePurpose
-profiling-pyroscopestringglobalPyroscope push URL (http://host:4040 or https://). Starts the pyroscope-go SDK at boot (CPU, goroutines, four heap views, tagged service_name=nl6, version, hostname) and opens the gated /debug/pprof/ surface. An unparseable URL, a scheme other than http/https, or embedded credentials are fatal at startup, after -help and -version and before any subsystem starts. A Pyroscope that is down at boot is not a start failure (the SDK never touches the network at start); it shows as sdk_errors and last_error on GET /api/v1/profiling and as one log line per push. With this flag set, startup also refuses to run while PYROSCOPE_ADHOC_SERVER_ADDRESS is set, which the SDK would silently honour over the flag (without the flag, a runtime push refuses it instead).
-profiling-force-gcbooltrueglobalLet the SDK force a runtime.GC() before a heap snapshot when no collection ran during the upload interval. The default is set from BenchmarkForcedGCOnFleetHeap (~29 ms per GC extrapolated to 30,000 devices, under the 150 ms rule); see the measurement. false sets the SDK's DisableGCRuns.
-profiling-pyroscope-basic-authstringglobalHTTP basic auth for the push as user:pass, both parts non-empty (the SDK sends no Authorization header when either is empty, so user: is refused rather than pushing unauthenticated). Requires -profiling-pyroscope and is sent only to that address (compared normalised): a REST-supplied server_address that differs is pushed to without it. Flag-only, never settable or echoed over REST. The value is visible to every local user through the process arguments (/proc/<pid>/cmdline, docker inspect, shell history); a file or environment form is a listed follow-up in Continuous profiling.
-profiling-pyroscope-tenantstringglobalPyroscope tenant ID (X-Scope-OrgID) for the push. Requires -profiling-pyroscope; flag-only, bound to the flag's address like the basic auth.

Examples

# Start server only (all interfaces up/up by default)
sudo ./nl6

# Auto-create 5 devices starting from 192.168.100.1
sudo ./nl6 -auto-start-ip 192.168.100.1 -auto-count 5

# Custom API port and subnet
sudo ./nl6 -auto-start-ip 10.10.10.1 -auto-count 100 -port 9090

# Non-privileged SNMP port (no CAP_NET_BIND_SERVICE needed)
sudo ./nl6 -auto-start-ip 10.10.10.1 -auto-count 10 -snmp-port 1161

# SNMPv3. Only noAuthNoPriv is reachable: -snmpv3-auth is accepted but not
# implemented, and privacy needs authPriv, so -snmpv3-priv is never exercised
# by a conforming manager (nl6#624).
sudo ./nl6 -snmpv3-engine-id 800000090300AABBCCDD
snmpget -v3 -l noAuthNoPriv -u simadmin -e 800000090300AABBCCDD \
10.42.0.1 1.3.6.1.2.1.1.1.0

# Disable network namespace isolation
sudo ./nl6 -no-namespace -auto-start-ip 192.168.100.1 -auto-count 10

# Maintenance window — all interfaces admin-shutdown
sudo ./nl6 -auto-start-ip 192.168.100.1 -auto-count 10 -if-scenario 1

# Link failure — all interfaces admin-up but oper-down
sudo ./nl6 -auto-start-ip 192.168.100.1 -auto-count 10 -if-scenario 3

# Partial outage — 30% of interfaces oper-down
sudo ./nl6 -auto-start-ip 192.168.100.1 -auto-count 10 \
-if-scenario 4 -if-failure-pct 30