// DevOps

BGP on Keenetic: how to set up dynamic routing via Entware and FRR

Published on 2026-05-30

BGP is usually associated with carrier equipment and Linux servers, but in small distributed networks it is useful even on an office router: neighboring sites automatically learn about new subnets, and when a tunnel fails routes are rebuilt without manual edits.

In the official list of components for KeeneticOS 5.x there is neither BGP nor OSPF. The protocol on Keenetic is run as a third-party daemon in the OPKG/Entware environment. Entware repository has ready packages for BIRD and Quagga; FRR is not distributed as a ready package and must be built by yourself. This article covers all three options and an option with a separate machine next to the router.

BGP runs over TCP, port 179. You must not open it on the external interface without filtering: that’s a direct path to attacks on the router control plane. Keenetic support allows installing Entware packages, but does not provide configuration help — everything is done on your own.

Diagram

             ┌──────────────────────┐
             │  Upstream / VPS / DC │
             │  AS 65001            │
             │  10.255.0.1          │
             └──────────┬───────────┘
                        │
                  WireGuard / GRE / IPIP
                        │
             ┌──────────▼───────────┐
             │      Keenetic         │
             │  KeeneticOS + Entware │
             │  BIRD / Quagga / FRR  │
             │  AS 65010             │
             │  10.255.0.2           │
             └──────────┬───────────┘
                        │
                 LAN 192.168.10.0/24

Keenetic here is a small border router for the site. It receives from the central node a default route or a limited set of prefixes, advertises its local network and rebuilds routes between backup tunnels. The router will not handle the full Internet table (over a million prefixes) — it’s an embedded device with limited CPU and memory.

When this makes sense

  1. Site-to-site connectivity over VPN. Several offices are connected by WireGuard or GRE tunnels; BGP informs neighbors about new and changed subnets.
  2. Backup tunnels. Primary and backup links: BGP switches routes when the session goes down, without custom scripts.
  3. Lab bench. Learning BGP together with VyOS, MikroTik or Cisco on an inexpensive router.

Bad idea — accepting full table from a provider, building your network core on a Keenetic, using it as a route reflector for many clients, or advertising BGP to the outside without filters.

Options

VariantWhat to installProsCons
A. Separate Linux machineFRR from distribution packagesreliable, regular updates, router not loadedrequires an extra machine
B. BIRD on Keeneticbird2 from Entwareready package, lightweight daemonits own configuration syntax
C. Quagga on Keeneticquagga-* from Entwareready packages, vtysh syntax like Ciscoproject unmaintained since 2018
D. FRR on Keeneticcustom buildmodern stack, vtyshbuild and recipe adjustments, all maintenance on you

We recommend Variant A for production networks: FRR on a mini-PC, in an LXC container or VM next to the router, and only a static route to it on the Keenetic.

Keenetic ── LAN ── Linux with FRR ── VPN/BGP ── Upstream

Below — variants B, C and D on the router itself.

Prepare Keenetic

Step 1. Install Entware

In the web interface: Management → General settings → Change component set, component “Support for open packages (OPKG)”. Storage — USB drive formatted EXT4 or, on models with KeeneticOS 3.7 and newer, internal memory. The installer archive is chosen by the router CPU architecture (mipsel, mips or aarch64); for internal storage installation is executed with a command like:

(config)> opkg disk storage:/ https://bin.entware.net/aarch64-k3.10/installer/aarch64-installer.tar.gz

Step 2. Enter Entware environment and update packages

(config)> exec sh
bash
opkg update
opkg upgrade

Check what’s available for your architecture:

bash
opkg list | grep -E '^(bird|quagga|frr)'

As of September 2026 the output will include bird2, bird3 and quagga-* packages, and frr will not be present — FRR is not in the Entware binary repository.

Source data for all examples:

  • Keenetic AS — 65010, central node AS — 65001;
  • Keenetic tunnel address — 10.255.0.2, central node — 10.255.0.1;
  • Keenetic local network — 192.168.10.0/24.

Variant B. BIRD

bash
opkg install bird2 bird2c

The package installs the daemon /opt/sbin/bird, the console /opt/sbin/birdc, configuration /opt/etc/bird.conf (example from BIRD distribution) and the startup script /opt/etc/init.d/S70bird.

Replace the contents of /opt/etc/bird.conf:

router id 10.255.0.2;

protocol device { }

# LAN interface networks — so there is something to announce.
# Check the interface name with the command ip -4 addr.
protocol direct {
    ipv4;
    interface "br0";
}

# Into the kernel — only routes learned via BGP.
protocol kernel {
    ipv4 {
        export where source = RTS_BGP;
    };
}

filter lan_out {
    if net ~ [ 192.168.10.0/24 ] then accept;
    reject;
}

filter from_upstream {
    if net ~ [ 0.0.0.0/0, 10.0.0.0/8{8,24}, 172.16.0.0/12{12,24} ] then accept;
    reject;
}

protocol bgp upstream {
    local 10.255.0.2 as 65010;
    neighbor 10.255.0.1 as 65001;
    ipv4 {
        import filter from_upstream;
        export filter lan_out;
    };
}

Start and check:

bash
/opt/etc/init.d/S70bird start
birdc show protocols
birdc show route protocol upstream

Session should be in state Established. The S70bird script starts automatically with other Entware services.

Variant C. Quagga

bash
opkg install quagga-zebra quagga-bgpd quagga-vtysh

Configuration is in /opt/etc/quagga/, startup script — /opt/etc/init.d/S50quagga. The script starts those daemons for which a <daemon>.conf file exists, so both zebra.conf and bgpd.conf are required. Daemons run by default under user network: if it does not exist in the Entware system, startup will fail — create the user or edit the script.

/opt/etc/quagga/zebra.conf:

hostname keenetic-zebra
log file /opt/var/log/zebra.log

/opt/etc/quagga/bgpd.conf:

hostname keenetic-bgpd
log file /opt/var/log/bgpd.log
!
ip prefix-list PL-LAN seq 10 permit 192.168.10.0/24
ip prefix-list PL-IN seq 10 permit 0.0.0.0/0
ip prefix-list PL-IN seq 20 permit 10.0.0.0/8 le 24
!
router bgp 65010
 bgp router-id 10.255.0.2
 network 192.168.10.0/24
 neighbor 10.255.0.1 remote-as 65001
 neighbor 10.255.0.1 prefix-list PL-IN in
 neighbor 10.255.0.1 prefix-list PL-LAN out
bash
/opt/etc/init.d/S50quagga start
vtysh -c 'show ip bgp summary'

Quagga is the predecessor of FRR; the last changes in its repository are dated February 2018. It is sufficient for labs and simple setups, but it no longer receives security fixes.

Variant D. Custom-build FRR

Why there is no ready package

The FRR 10.4.1 build recipe is present in Entware sources (repository entware-packages, directory net/frr), but it was ported from OpenWrt without adaptation: configuration is installed to /etc/frr, binaries to /usr/sbin and /usr/bin, and the startup script is designed for the OpenWrt init system. On Keenetic third-party software lives in /opt, so the recipe must be adjusted before building. In OpenWrt the current package version is already 10.6.1.

Build

Build takes place on a Linux machine with OpenWrt build dependencies and at least 7 GB free space (according to Entware wiki):

bash
git clone https://github.com/Entware/Entware.git && cd Entware
make package/symlinks
cp -iv configs/mipsel-3.4.config .config   # or aarch64-3.10, mips-3.4 — according to router architecture
make -j$(nproc) tools/install
make -j$(nproc) toolchain/install
make -j$(nproc) target/compile

Before building the package itself fix the recipe feeds/packages/net/frr/Makefile (path inside the build tree may differ — find the net/frr directory):

  1. in the --sysconfdir and --localstatedir parameters replace /etc/frr and /var/run/frr with /opt/etc/frr and /opt/var/run/frr;
  2. in the install sections replace /usr/sbin, /usr/bin, /usr/lib and /etc/frr with the corresponding directories under /opt;
  3. do not use the OpenWrt startup script — a custom one is provided below.

Then select packages frr, frr-zebra, frr-bgpd, frr-vtysh, frr-watchfrr in make menuconfig and build:

bash
make package/frr/compile

The frr-bgpd subpackage recipe specifies the kernel option CONFIG_TCP_MD5SIG (needed for BGP passwords). If it is not selectable in menuconfig, the dependency is the reason. Whether BGP passwords will work on the router is decided by the Keenetic kernel, not by the build.

Resulting .ipk files will appear in the bin/ directory of the build tree. FRR build will also produce the libyang library — it is not in the Entware binary repository and its package must be copied to the router as well. Other dependencies (libjson-c, libprotobuf-c, libreadline, libcap and others) are installed from the Entware repository.

Install on the router

bash
opkg install ./libyang_*.ipk ./frr_*.ipk ./frr-zebra_*.ipk ./frr-bgpd_*.ipk ./frr-vtysh_*.ipk

FRR is built with user and group network (--enable-user=network): if they do not exist in the Entware system the daemons will not start — create them or build with root.

FRR configuration

/opt/etc/frr/frr.conf:

frr defaults traditional
hostname keenetic-bgp
log file /opt/var/log/frr/frr.log informational
service integrated-vtysh-config
!
ip prefix-list PL-LAN seq 10 permit 192.168.10.0/24
ip prefix-list PL-LAN seq 999 deny 0.0.0.0/0 le 32
!
ip prefix-list PL-IN seq 10 permit 0.0.0.0/0
ip prefix-list PL-IN seq 20 permit 10.0.0.0/8 le 24
ip prefix-list PL-IN seq 30 permit 172.16.0.0/12 le 24
ip prefix-list PL-IN seq 999 deny 0.0.0.0/0 le 32
!
route-map RM-IN permit 10
 match ip address prefix-list PL-IN
!
route-map RM-OUT permit 10
 match ip address prefix-list PL-LAN
!
router bgp 65010
 bgp router-id 10.255.0.2
 neighbor 10.255.0.1 remote-as 65001
 neighbor 10.255.0.1 description upstream-vps
 neighbor 10.255.0.1 timers 10 30
 !
 address-family ipv4 unicast
  network 192.168.10.0/24
  neighbor 10.255.0.1 route-map RM-IN in
  neighbor 10.255.0.1 route-map RM-OUT out
 exit-address-family
!
line vty

In frr defaults traditional FRR does not require a policy for an eBGP neighbor, but still define filters explicitly: they protect your network from mistakes on the other side. It’s better to set bgp router-id manually — do not rely on automatic selection based on router interface addresses.

BGP advertises a network from network only if that prefix exists in the kernel routing table:

bash
ip route show 192.168.10.0/24

Autostart

/opt/etc/init.d/S80frr:

bash
#!/bin/sh

PATH=/opt/sbin:/opt/bin:/sbin:/bin:/usr/sbin:/usr/bin
RUN_DIR=/opt/var/run/frr

start() {
  mkdir -p "$RUN_DIR" /opt/var/log/frr
  for d in mgmtd zebra bgpd; do
    pidof "$d" >/dev/null || "$d" -d -A 127.0.0.1
  done
  sleep 2
  vtysh -b          # load /opt/etc/frr/frr.conf into all daemons
}

stop() {
  for d in bgpd zebra mgmtd; do
    pid=$(pidof "$d") && kill "$pid"
  done
}

case "$1" in
  start) start ;;
  stop) stop ;;
  restart) stop; sleep 2; start ;;
  *) echo "Usage: $0 {start|stop|restart}"; exit 1 ;;
esac
bash
chmod +x /opt/etc/init.d/S80frr
/opt/etc/init.d/S80frr start

mgmtd in FRR 10 is the configuration management service; it is started together with zebra.

Configure the opposite side (Linux with FRR)

frr defaults traditional
hostname upstream-vps
log syslog informational
service integrated-vtysh-config
!
ip prefix-list FROM-KEENETIC seq 10 permit 192.168.10.0/24
ip prefix-list FROM-KEENETIC seq 999 deny 0.0.0.0/0 le 32
!
ip prefix-list TO-KEENETIC seq 10 permit 0.0.0.0/0
ip prefix-list TO-KEENETIC seq 999 deny 0.0.0.0/0 le 32
!
router bgp 65001
 bgp router-id 10.255.0.1
 neighbor 10.255.0.2 remote-as 65010
 neighbor 10.255.0.2 description keenetic-router
 !
 address-family ipv4 unicast
  neighbor 10.255.0.2 prefix-list FROM-KEENETIC in
  neighbor 10.255.0.2 prefix-list TO-KEENETIC out
  neighbor 10.255.0.2 default-originate
 exit-address-family

default-originate gives the neighbor a default route even if it is not present in the BGP table of the server itself. Enable IP forwarding:

bash
sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.d/99-forwarding.conf

Checks

What to checkBIRDQuagga / FRR
Session statebirdc show protocolsvtysh -c 'show bgp summary'
Received routesbirdc show route protocol upstreamvtysh -c 'show ip bgp'
Routes in the kernelip routeip route show proto bgp (FRR)

Desired session state — Established.

Typical errors

  1. opkg install frr — “Unknown package”. A ready FRR is not in Entware: use BIRD or Quagga, or build FRR yourself.
  2. Session stuck in Active or Connect. Check TCP 179 connectivity to the neighbor (nc -vz 10.255.0.1 179) and the KeeneticOS firewall on the tunnel interface.
  3. Session Established but no routes. Error in filters or prefix-lists on one of the sides.
  4. After reboot nothing works. Daemons start only after Entware storage is mounted; check that the drive is attached and scripts in /opt/etc/init.d ran.
  5. Daemon does not start because of the user. Quagga and FRR by default run as network — the user must exist.

Limitations

  • Routes are outside KeeneticOS awareness. The third-party daemon writes routes directly into the Linux kernel table. KeeneticOS manages its own tables, connection policies and Multi-WAN and does not display these routes in the web interface. Keenetic documentation does not describe this setup, so after changing router settings verify that routes are present and traffic goes through the intended interface.
  • Dependence on storage. If the flash drive with Entware fails or is unmounted, the routing daemon stops together with it.
  • Resources. Frequent route changes by a neighbor (flapping) load the weak router CPU and interfere with its other functions.

Summary

BGP on Keenetic via Entware is a practical tool for small distributed networks and labs. The easiest start is with BIRD: the package is ready and lightweight. Quagga suits those accustomed to Cisco syntax, but the project is abandoned. FRR on the router itself is possible only via custom build and remains an option for enthusiasts. For production networks it is more reliable to move FRR to a separate Linux machine next to the router and keep Keenetic only for Internet connectivity.

// Contact

Need help?

Get in touch with me and I'll help solve the problem

I reply within one business day (03:00-13:00 GMT)

Или оставьте заявку здесь:

Confirm that you are not a bot.

Write and get a quick reply