How to buy Partners Documentation Support Log in
BNG & LNS / Outgrowing a MikroTik BNG: move the edge, keep the billing

Engineering · 14 Oct 2026

Outgrowing a MikroTik BNG: move the edge, keep the billing

When RouterOS PPPoE and NAT stop scaling, you can swap just the NAS for Netavo and leave PHPNuxBill, Splynx and FreeRADIUS exactly as they are.

MigrationMikroTikRADIUSCGNAT

Plenty of growing ISPs and WISPs run their whole subscriber edge on MikroTik: a RouterOS box terminates PPPoE, a billing panel such as PHPNuxBill or Splynx drives FreeRADIUS, and NAT is a masquerade rule. It works, and it is cheap to start. When one box stops keeping up, you can replace it without rebuilding everything around it.

Because Netavo BNG is a standard RADIUS NAS, you can replace the termination and NAT when they come under strain and keep the billing stack and RADIUS you already run. Your plans, speed profiles and the panel your staff use do not change.

Where RouterOS runs out of road

RouterOS termination is CPU-bound: PPPoE encapsulation, per-session queues and NAT all compete for the same cores, so a single box tops out well before a software BNG on a commodity x86 server does, and the usual fix, sharding subscribers across more RouterOS boxes, multiplies the things you operate. Three limits tend to bite first:

  • PPPoE session scale. Session count and per-session shaping are limited by CPU. Adding boxes adds RADIUS clients, routing, and failover to manage.
  • Carrier NAT. masquerade and /ip firewall nat lean on the connection-tracking table. As subscriber count climbs you hit table and CPU limits. For compliance, there is a further problem: you have no deterministic, logged mapping of subscriber to public address and port range. Answering an abuse or lawful-request query from connection-tracking state is painful.
  • PE integration. MPLS/L3VPN, BGP to the core and clean VRF separation are not what RouterOS is built for at the edge.

The shape of the migration

Replace the NAS while keeping your billing and RADIUS.

Point FreeRADIUS at Netavo instead of the MikroTik box, and tell Netavo to honour the rate attributes your billing already sends. The Mikrotik-Rate-Limit VSA that PHPNuxBill, Splynx and most RouterOS-oriented panels emit is understood natively:

"auth": {
  "driver": "radius",
  "radius": {
    "servers": [ { "host": "10.20.0.5", "port": 1812, "secret": "op://netavo/radius/secret" } ],
    "nasIdentifier": "bng1",
    "rateAttributeMode": "mikrotik"
  }
},
"accounting": { "driver": "radius", "interimIntervalSeconds": 300 }

With rateAttributeMode set to mikrotik, a reply carrying Mikrotik-Rate-Limit = "20M/100M" applies the same up/down shaping it did on RouterOS, without per-plan configuration on the BNG or changes to how your panel defines packages. (The default, auto, also understands the Netavo and Broadband-Forum rate VSAs, so a mixed estate works too.)

Mapping the RouterOS constructs

RouterOS Netavo Notes
/interface pppoe-server server pppoe.enabled, subscribers.accessNnis Sessions arrive on the access NNI; no per-interface server instances
PPP profile rate-limit, /queue trees Mikrotik-Rate-Limit VSA via rateAttributeMode: "mikrotik" Per-subscriber shaping comes from the RADIUS reply, not box config
/ip pool addressPools Typed by family; dual-stack is one pool set
/ip firewall nat masquerade / CGNAT integrated netavo-cgn Deterministic port-block allocation, logged per subscriber
/radius incoming (CoA) RFC 5176 CoA / Disconnect Mid-session plan change and forced logout, unchanged

PPPoE termination

On RouterOS you run a PPPoE server per interface. On Netavo you name the access ports and the wholesale hand-off, and sessions come up against RADIUS:

"dataPlane": {
  "subscriberInterfaces": [
    { "ifname": "eno1", "pci": "0000:04:00.0", "rxQueues": 4,
      "accessProtocols": ["pppoe"], "spray": "auto" }
  ]
},
"pppoe": { "enabled": true, "acName": "bng1" }

Address pools

A RouterOS /ip pool becomes a typed Netavo pool. You can add IPv6 at the same time: a routed WAN prefix and a delegated prefix need two more pools:

"addressPools": [
  { "name": "cgn-inside", "family": "ipv4",
    "subnets": [ { "prefix": "100.64.0.0/10" } ] },
  { "name": "res-v6-pd", "family": "ipv6-pd", "delegationLength": 56,
    "subnets": [ { "prefix": "2a0e:9f81:100::/44", "announce": true } ] }
]

Carrier NAT you can answer questions about

This is usually the real reason to move. Instead of a masquerade rule and a connection-tracking table, netavo-cgn allocates each subscriber a deterministic block of public ports. A single logged line containing the subscriber, public address, port range and time answers an abuse report or a lawful request, and the block maths is predictable rather than whatever the conntrack table happened to hold. CGN runs on the same box as the BNG, or as a standalone role if you want to keep NAT separate from termination.

What stays on MikroTik

The replacement covers the BNG role. You can keep RouterOS elsewhere in the network.

  • RouterOS is still a fine small-site router, CPE and L2 switch. Your access and aggregation layer does not have to change.
  • Your billing panel (PHPNuxBill, Splynx or otherwise) is untouched. Netavo does not replace it; it is the NAS your billing already knows how to drive.
  • Firewall scripting, hotspot portals and site-specific RouterOS logic stay where they are. Only subscriber termination and NAT move to the BNG.

Try it against your own RADIUS

The free evaluation build is the production build, licensed for up to 50 concurrent subscribers with every feature enabled. Stand it up on a VM, point a test FreeRADIUS instance (or a staging copy of your panel) at it, and bring a handful of real PPPoE sessions up with your existing Mikrotik-Rate-Limit replies before you touch production. Start at netavobng.com/evaluation; the configuration reference is in the manual.

More from Engineering