Skip to main content

Routing Configuration

Configure the control plane: the IGP (IS-IS) that carries router loopback reachability, and BGP that announces subscribers and peers with upstream.

Overview

AthenaBNG uses a two-plane routing design:

  • IS-IS is the IGP. Its only job is to carry the router loopback reachability (IPv4 /32 and, dual-stack, IPv6 /128) across the core so that iBGP can peer loopback-to-loopback. Subscribers are not in the IGP.
  • BGP carries subscribers and upstream peering. Subscriber reachability is announced as a route policy over BGP — per-/32 host routes for IPv4, and a single summary aggregate for IPv6.
  • OSPF is still supported (routing.ospf) but IS-IS is the recommended and current IGP. See BGP/OSPF Integration for the OSPF-to-IS-IS migration story.
  • Static routes (routing.static_routes) can be added for anything the dynamic protocols don't cover.

The routing section has four sub-sections: bgp, isis, ospf, and static_routes. The router identities it depends on live under system.

Router identity (system)

Routing keys off two system-level fields:

system:
router_id: "10.255.0.4" # IPv4 loopback — BGP router-id + IS-IS export
router_id_v6: "2001:df4:2040::4" # optional IPv6 loopback for the dual-stack plane
router_id

The IPv4 loopback. Placed on lo as a /32, used as the BGP router-id, the IS-IS export target, and (by default) the RADIUS NAS-IP. It is always excluded from subscriber prefixes so it is only ever reachable via the IGP.

Type: IPv4 address Required: Yes

router_id_v6

Optional IPv6 loopback for the dual-stack control plane. When set it is placed on lo as a /128 and announced into IS-IS, giving v6 next-hops (and v6 iBGP peers) reachability. Leave unset for IPv4-only deployments — all v6 rendering is gated off.

Type: IPv6 address Required: No Default: unset

isis

IS-IS is a single, dual-stack (IPv4 + IPv6) protocol instance, single-topology, metric-style wide. It advertises only the loopback(s).

routing:
isis:
enabled: true
net: "49.0001.0000.0000.0004.00"
level: level-2
ipv6: true
announce_loopback: true
redistribute_subscriber_routes: false
interfaces:
- name: upstream0
circuit_type: level-2
network_type: point-to-point
metric: 10
enabled

Enable IS-IS.

Type: Boolean Default: false

net

Network Entity Title (NET) — the IS-IS system identity. Format AA.NNNN.SSSS.SSSS.SSSS.00 (area, 6-byte system-id, NSEL 00). Each router needs a unique system-id.

Type: String Required: Yes (if IS-IS enabled) Example: 49.0001.0000.0000.0004.00

level

IS type / level for the instance.

Type: String Default: level-2 Valid values: level-1, level-2, level-1-2

ipv6

Advertise the IPv6 address-family in addition to IPv4 (single dual-stack instance).

Type: Boolean Default: true

announce_loopback

Announce the router loopback into IS-IS — this is the IGP's whole purpose in this design. The IPv4 /32 is exported with redistribute ipv4 connected … route-map ISIS-EXPORT (matched to router_id/32 only). The IPv6 /128, when system.router_id_v6 is set, is advertised via a passive interface lo stanza (ipv6 router isis + isis passive) rather than redistribute ipv6 connected — FRR isisd does not emit loopback /128s through redistribute the way it does for IPv4, so the loopback is activated passively (no hellos, just its address).

Type: Boolean Default: true

redistribute_subscriber_routes

Redistribute connected/static/kernel (subscriber) routes into IS-IS. Off by default — subscribers go over BGP, not the IGP. Enable only if you deliberately want subscriber host routes in IS-IS too.

Type: Boolean Default: false

interfaces

Per-interface IS-IS activation. Each entry activates ip router isis (and ipv6 router isis when ipv6: true) on the named interface.

interfaces:
- name: upstream0
circuit_type: level-2 # level-1 | level-2 | level-1-2 (optional)
network_type: point-to-point # point-to-point | broadcast (optional)
metric: 10 # optional
passive: false # advertise subnet, send no hellos (optional)
  • name — interface name (required).
  • circuit_type — per-interface level (optional).
  • network_typepoint-to-point avoids DIS election on P2P core links (optional).
  • metric — IS-IS metric (optional).
  • passive — advertise the interface subnet but send no hellos (optional).

bgp

BGP announces subscribers and peers upstream. Neighbours may be IPv4 or IPv6 addresses; iBGP peers loopback-to-loopback with update-source lo.

routing:
bgp:
enabled: true
asn: 64512
neighbors:
- address: "10.255.0.1" # IPv4 loopback of the peer
remote_as: 64512
description: "BDR1 (iBGP)"
update_source: "lo"
- address: "2001:df4:2040::1" # IPv6 loopback of the peer
remote_as: 64512
description: "BDR1 (iBGP v6)"
update_source: "lo"
announce_subscriber_routes: true
subscriber_networks:
- "100.64.0.0/10"
host_routes_only: true
community: "64512:100"
announce_subscriber_routes_v6: true
subscriber_networks_v6:
- "2001:df4:2040:1000::/52"
enabled

Enable BGP.

Type: Boolean Default: false

asn

Local Autonomous System Number.

Type: Integer (1–4294967295) Required: Yes (if BGP enabled)

Private ranges: 64512–65534 (16-bit), 4200000000–4294967294 (32-bit).

neighbors

BGP neighbour list. Each neighbour:

  • address — neighbour IP, IPv4 or IPv6 (required). IPv6 addresses are placed in a separate v6 peer-group automatically.
  • remote_as — neighbour ASN (required). Equal to asn for iBGP.
  • description — free-text label (optional).
  • update_source — source interface/address for the session (optional). For loopback-to-loopback iBGP set this to lo.
announce_subscriber_routes

Announce IPv4 subscriber routes over BGP.

Type: Boolean Default: true

When on, subscriber host routes are redistributed (connected/static/kernel) into the IPv4 unicast AF through the SUB-ROUTES-TO-BGP route-map.

subscriber_networks

Supernets subscriber IPv4 addresses are drawn from. BGP only announces host routes that fall within these. Empty (default) = any prefix, subject to host_routes_only. The router loopback is always excluded.

Type: List of CIDR Default: [] (any)

host_routes_only

Only announce /32 host routes. Set false to announce the configured subscriber_networks at their natural prefix length instead (a summarised announcement).

Type: Boolean Default: true

community

BGP community string to tag announced subscriber routes with (applied in both the v4 and v6 route-maps). send-community behaviour follows FRR defaults.

Type: String Default: unset Example: "64512:100"

announce_subscriber_routes_v6

Announce subscriber IPv6 (delegated prefixes) over BGP's IPv6 unicast AF. Off by default. When on, the template adds the v6 address-family, a separate UPSTREAM6 peer-group for IPv6 neighbours, no bgp default ipv4-unicast (so a v6 peer is not auto-activated for v4), and the aggregate-only announcement described below.

Type: Boolean Default: false

subscriber_networks_v6

IPv6 supernets subscriber delegated prefixes are drawn from. Unlike IPv4, only the aggregate is announced — each entry renders aggregate-address <net> summary-only, and a matching ipv6 route <net> blackhole gives the aggregate a contributing route so it originates even with zero active subscribers (and discards traffic to unallocated space). Per-customer /56//60 more-specifics forward locally but are suppressed from BGP. The v6 loopback is always excluded.

Type: List of CIDR Default: []

ospf

Legacy IGP option. Prefer IS-IS. When enabled it redistributes the loopback (via CONNECTED-TO-OSPF, matched to interface lo) and static routes.

routing:
ospf:
enabled: false
area: "0.0.0.0"
networks:
- "10.255.0.0/24"
passive_interfaces:
- "upstream0"
  • enabled — Boolean, default false.
  • area — OSPF area for the network statements. Default 0.0.0.0.
  • networks — list of networks to run OSPF on (each added as network <net> area <area>).
  • passive_interfaces — interfaces to advertise but send no hellos on.

static_routes

Static routes redistributed into the IGP and BGP where policy allows.

routing:
static_routes:
- prefix: "192.0.2.0/24"
next_hop: "10.255.0.1"
- prefix: "198.51.100.0/24"
interface: "upstream0"
  • prefix — destination CIDR (required).
  • next_hop — gateway IP (optional).
  • interface — egress interface (optional).

Example configurations

Dual-stack core (IS-IS + iBGP)

system:
router_id: "10.255.0.4"
router_id_v6: "2001:df4:2040::4"

routing:
isis:
enabled: true
net: "49.0001.0000.0000.0004.00"
level: level-2
ipv6: true
interfaces:
- name: upstream0
network_type: point-to-point
metric: 10
bgp:
enabled: true
asn: 64512
neighbors:
- address: "10.255.0.1"
remote_as: 64512
update_source: "lo"
- address: "2001:df4:2040::1"
remote_as: 64512
update_source: "lo"
announce_subscriber_routes: true
subscriber_networks: ["100.64.0.0/10"]
announce_subscriber_routes_v6: true
subscriber_networks_v6: ["2001:df4:2040:1000::/52"]

IPv4-only

system:
router_id: "10.255.0.4"

routing:
isis:
enabled: true
net: "49.0001.0000.0000.0004.00"
interfaces:
- name: upstream0
network_type: point-to-point
bgp:
enabled: true
asn: 64512
neighbors:
- address: "10.255.0.1"
remote_as: 64512
update_source: "lo"
announce_subscriber_routes: true
subscriber_networks: ["203.0.113.0/24"]

With router_id_v6 unset and announce_subscriber_routes_v6 off, the rendered FRR is byte-identical to a pre-IPv6 build.

Configuration via CLI

abng> configure
abng# set system router_id 10.255.0.4
abng# set system router_id_v6 2001:df4:2040::4
abng# set routing isis enabled true
abng# set routing isis net 49.0001.0000.0000.0004.00
abng# set routing bgp enabled true
abng# set routing bgp asn 64512
abng# set routing bgp neighbors[0] address 10.255.0.1
abng# set routing bgp neighbors[0] remote_as 64512
abng# set routing bgp neighbors[0] update_source lo
abng# set routing bgp announce_subscriber_routes_v6 true
abng# commit

Rendered FRR (concepts)

The commit pipeline renders frr.conf from the config above. The key pieces:

! Loopback carries both identities; the v6 /128 is announced into IS-IS passively
interface lo
ip address 10.255.0.4/32
ipv6 address 2001:df4:2040::4/128

! IGP: loopback-only export
ip prefix-list ISIS-LOOPBACK seq 5 permit 10.255.0.4/32
router isis AthenaBNG
net 49.0001.0000.0000.0004.00
is-type level-2
metric-style wide
redistribute ipv4 connected level-2 route-map ISIS-EXPORT
interface lo
ipv6 router isis AthenaBNG
isis passive

! IPv4 subscribers: per-/32 host routes, loopback excluded
ip prefix-list SUBSCRIBER-PREFIXES seq 5 deny 10.255.0.4/32
ip prefix-list SUBSCRIBER-PREFIXES seq 10 permit 100.64.0.0/10 ge 32 le 32

! IPv6 subscribers: aggregate only, with a blackhole contributor
ipv6 route 2001:df4:2040:1000::/52 blackhole

router bgp 64512
bgp router-id 10.255.0.4
no bgp default ipv4-unicast
neighbor UPSTREAM peer-group
neighbor UPSTREAM6 peer-group
neighbor 10.255.0.1 peer-group UPSTREAM
neighbor 10.255.0.1 remote-as 64512
neighbor 10.255.0.1 update-source lo
neighbor 2001:df4:2040::1 peer-group UPSTREAM6
neighbor 2001:df4:2040::1 remote-as 64512
neighbor 2001:df4:2040::1 update-source lo
address-family ipv4 unicast
redistribute connected route-map SUB-ROUTES-TO-BGP
neighbor UPSTREAM activate
exit-address-family
address-family ipv6 unicast
aggregate-address 2001:df4:2040:1000::/52 summary-only
neighbor UPSTREAM6 activate
neighbor UPSTREAM6 next-hop-self
exit-address-family

Verification

abng> show bgp summary
abng> show routes
sudo vtysh -c "show isis neighbor"
sudo vtysh -c "show isis database"
sudo vtysh -c "show bgp ipv4 unicast"
sudo vtysh -c "show bgp ipv6 unicast"

Validation rules

FieldValidation
system.router_idValid IPv4 address
system.router_id_v6Valid IPv6 address (optional)
isis.enabledBoolean
isis.netValid NET (required if IS-IS enabled)
isis.levellevel-1 | level-2 | level-1-2
isis.interfaces[].network_typepoint-to-point | broadcast
bgp.asnInteger 1–4294967295
bgp.neighbors[].addressValid IPv4 or IPv6 address
bgp.neighbors[].remote_asInteger 1–4294967295
bgp.subscriber_networks[]Valid IPv4 CIDR
bgp.subscriber_networks_v6[]Valid IPv6 CIDR
ospf.areaValid area id

Best practices

  1. IGP scope — keep IS-IS loopback-only (redistribute_subscriber_routes: false); let BGP carry subscribers.
  2. Loopback identities — set both router_id and router_id_v6 for dual-stack; peer iBGP loopback-to-loopback with update_source: lo.
  3. P2P core links — use network_type: point-to-point on IS-IS core interfaces to skip DIS election.
  4. IPv6 announcement — announce the aggregate (subscriber_networks_v6), never the per-customer more-specifics.
  5. ASN — private ranges (64512–65534 or 4200000000+) unless you hold a public ASN.
  6. Monitoring — watch BGP session state, IS-IS adjacencies, and route counts.

Troubleshooting

iBGP session not establishing

  1. Confirm the peer loopback is reachable via IS-IS: sudo vtysh -c "show isis database", then ping <peer-loopback>.
  2. Confirm update_source: lo on both ends.
  3. For a v6 peer, confirm router_id_v6 is set and the v6 loopback is in IS-IS.

Subscriber routes not advertised

  1. IPv4: check announce_subscriber_routes and that the subscriber IP falls within subscriber_networks; sudo vtysh -c "show bgp ipv4 unicast".
  2. IPv6: the per-customer prefixes are intentionally suppressed — verify the aggregate instead: sudo vtysh -c "show bgp ipv6 unicast 2001:df4:2040:1000::/52".

IS-IS adjacency down

  1. sudo vtysh -c "show isis neighbor".
  2. Confirm the interface is listed under isis.interfaces and both ends agree on network_type and level.

Next steps