MikroTik RouterOS 7 BGP: Templates, Connections and Sessions - 夜莺博客

MikroTik RouterOS 7 BGP: Templates, Connections and Sessions

RouterOS v7 threw away the v6 BGP configuration model. There is no /routing bgp instance and no per-peer peer menu any more; instead you get a strict split between connections (how the session is built), templates (protocol behaviour) and sessions (the live state, read-only). Anyone migrating from v6 needs the mapping, and anyone deploying fresh needs to know which menu holds which knob.

The mental model

  • Template — all BGP protocol parameters: local AS, address families, filters, hold time, next-hop handling, BFD. Templates can inherit from other templates.
  • Connection — the transport and identity of a peer: remote address, which template to use, whether to connect and/or listen, and the local role.
  • Session — the live state of each peer (established, idle, active), used for monitoring, not configuration.
/routing/bgp/template set default as=65533
/routing/bgp/template add name=myAsTemplate as=65500 output.filter-chain=myAsFilter
/routing/bgp/template set default template=myAsTemplate

The default template must have your own AS set before anything works — this is the single most common v7 stumbling block. Router IDs come from /routing id; by default RouterOS picks the highest IP on an interface.

eBGP to an upstream

/routing/bgp/template
add name=ebgp-tpl as=65500 output.network=bgp-networks     input.filter-chain=ebgp-in output.filter-chain=ebgp-out

/routing/bgp/connection
add name=peer-AS64500 remote.address=203.0.113.1 remote.as=64500     local.role=ebgp templates=ebgp-tpl     connect=yes listen=yes

connect and listen control who initiates: both sides listening means either can open the session, which is usually what you want on a peering link. For multihop sessions, set local.address explicitly — that is the v7 equivalent of v6’s update-source.

iBGP and address families

/routing/bgp/template
add name=ibgp-tpl as=65500     afi=ip,ipv6,l2vpn,evpn     nexthop-choice=propagate     use-bfd=yes

/routing/bgp/connection
add name=peer-RR-01 remote.address=10.0.0.2 remote.as=65500     local.role=ibgp templates=ibgp-tpl     multihop=yes local.address=10.0.0.1

RouterOS v7 supports afi=ip,ipv6,l2vpn,l2vpn-cisco,vpnv4,vpnv6,evpn, which means the same platform can act as an EVPN PE or an L3VPN speaker. nexthop-choice matters in iBGP deployments: the default follows RFC 4271 behaviour, while propagate keeps the received next hop, which is what you want when the RR should not become a transit hop.

Filters, BFD and monitoring

/routing/filter/rule
add chain=ebgp-in rule="if (bgp-med ... ) { ... }"
# v7 filters are expression based; chain contents are referenced from the template

/routing/bgp/session print
/routing/bgp/session print detail where established=no
/routing/stats

use-bfd=yes in the template turns on BFD for failure detection, so a link that stops forwarding without dropping the TCP session is detected in milliseconds rather than after the hold time. For monitoring, /routing/bgp/session print shows the live peers, and /routing/stats exposes counters for all routing processes. Keep the output-filter chain strict: RouterOS will happily advertise more than you intended if the template’s output.network list references an address list you forgot to prune.

Related reading: Huawei VRP common commands and troubleshooting, BGP session stuck in Idle/Active and BGP communities configuration examples.

What Changed from v6 to v7

RouterOS v6 exposed BGP as one flat menu tree: an instance holding global parameters, and a peer entry per neighbour mixing transport, policy and address-family settings together. v7 splits the same information across three menus with different lifetimes. The mapping below is the fastest way to translate an existing v6 configuration:

  • /routing bgp instance and /routing bgp peer → /routing/bgp/template (protocol behaviour) plus /routing/bgp/connection (transport and identity).
  • Per-peer remote-as → remote.as on the connection, or as on the template if all peers share the local AS.
  • update-source → local.address on the connection.
  • router-id on the instance → global /routing id.
  • v6 filter chains in /routing filter → v7 /routing/filter/rule with expression-based rules referenced from the template.
  • v6 multihop and nexthop-choice remain, but live on the connection and template respectively.

Nothing in v7 is optional bookkeeping. Once the default template carries your AS number, every connection that does not name its own template inherits that behaviour, and a connection that inherits the wrong AS produces a session that stays in Active forever with no obvious error. That single fact is worth putting at the top of any migration notes.

Templates in Depth: Inheritance and Defaults

Templates hold protocol state that describes how the router speaks BGP. The default template is special: it is the fallback for every connection that does not specify one, and it must have the local AS number set before anything can work.

/routing/bgp/template set default as=65533
/routing/bgp/template add name=myAsTemplate as=65500 output.filter-chain=myAsFilter
/routing/bgp/template set default template=myAsTemplate

The second and third lines are the inheritance idiom worth understanding. Adding a named template and then pointing the default template at it means new connections pick up the named template's behaviour unless they override it. Template parameters include as, afi, nexthop-choice, use-bfd, hold-time, keepalive-time, multihop where relevant, and the input/output filter chains. Because filters are attached to the template rather than to the peer, two peers that need different policy must use two templates — which is exactly the design v7 encourages and v6 made awkward.

Connections in Depth: connect, listen and local.role

A connection answers three questions: where the peer is, which template describes the session, and who initiates. The connect and listen properties control both directions independently:

  • connect=yes listen=yes — either side may open the session. The usual choice on a peering link, because it survives a flap on either end without waiting.
  • connect=yes listen=no — this router initiates only. Appropriate when the peer must be the listener, for example behind a device that will not accept inbound TCP 179.
  • connect=no listen=yes — passive. The session exists only when the peer dials in, which is common for route collectors and looking glasses.

local.role defines the relationship and therefore the AS-path handling: ebgp for external peers, ibgp for internal ones. Setting the wrong role does not immediately kill the session; it produces subtly wrong path selection and next-hop behaviour, which is far harder to diagnose than a session that never comes up.

/routing/bgp/connection
add name=peer-AS64500 remote.address=203.0.113.1 remote.as=64500 \
    local.role=ebgp templates=ebgp-tpl connect=yes listen=yes

For multihop sessions — iBGP over a loopback, or eBGP to a peer more than one hop away — set local.address explicitly. This is the v7 equivalent of v6's update-source, and it must be an address that the peer can reach and that is stable across interface flaps.

Address Families Explained

RouterOS v7 supports afi=ip,ipv6,l2vpn,l2vpn-cisco,vpnv4,vpnv6,evpn, and the address family is a template property, so two AFI sets mean two templates. What each one is for:

  • ip and ipv6 — the ordinary unicast families, active by default on most templates.
  • vpnv4 and vpnv6 — MPLS L3VPN, used between PE and route reflector or PE and PE.
  • l2vpn and l2vpn-cisco — BGP-signalled pseudowires, carrying Layer 2 across an MPLS core. The -cisco variant exists for interworking with Cisco's encoding.
  • evpn — Ethernet VPN, the modern control plane for data-centre fabrics and for multihoming with all-active access.

A template carrying families the peer does not support does not fail cleanly; the negotiation simply does not agree on that family and the routes never appear. When a session is up but a specific prefix is missing, checking the negotiated families on both ends is faster than reading filters. RouterOS's EVPN support makes the same box usable as a fabric PE, and the design tradeoffs there are covered in SR-MPLS versus SRv6.

v7 Routing Filters and Chains

v6 filter lists were a sequence of matching rules. v7 filters are an expression language with a chain model, closer to a small scripting language than to an ACL:

/routing/filter/rule
add chain=ebgp-in rule="if (bgp-med ... ) { ... }"
add chain=ebgp-out rule="if (dst in 192.168.0.0/16 && dst-len > 24) { reject }"
# chains are referenced from the template, not from the peer
/routing/bgp/template set ebgp-tpl input.filter-chain=ebgp-in output.filter-chain=ebgp-out

Two habits prevent most filter accidents. First, keep the output chain closed: RouterOS will happily advertise anything the template's output.network list grants, and a stale address list that was never pruned is how an internal prefix ends up on the internet. Second, give input and output chains distinct names per relationship — an inbound chain reused as an outbound chain is a policy leak waiting for a maintenance window. A related trap on Cisco and Junos is documented in BGP communities configuration examples.

BFD for Fast Failure Detection

Without BFD, a BGP session notices a dead path when the hold timer expires, which with a 180-second default is three minutes of blackholing. BFD runs a lightweight sub-second protocol underneath the session and tears it down when the forwarding path stops working, which is the difference between a reroute in milliseconds and a reroute in minutes.

/routing/bgp/template set ebgp-tpl use-bfd=yes
/routing/bgp/session print where bfd=yes

Enable BFD on both ends of the session and be aware of what it costs: BFD is a continuous stream of small packets, so it is a poor fit for a metered link at scale, and a flapping BFD session will withdraw and re-advertise prefixes rapidly enough to be visible as instability in the IGP or in downstream peers. Where the session runs across a tunnel, the tunnel must carry BFD traffic end to end or the detection interval will not hold.

Complete Worked Example: eBGP Upstream plus iBGP Reflector

Combining the pieces into a single configuration makes the split clearer. The router peers with an upstream via eBGP, acts as a route reflector client toward two internal routers, and drops its own networks into BGP through an output chain:

# 1. Global router ID
/routing id set id=10.0.0.1

# 2. Templates
/routing/bgp/template add name=ebgp-tpl as=65500 afi=ip \
    output.filter-chain=ebgp-out input.filter-chain=ebgp-in
/routing/bgp/template add name=ibgp-tpl as=65500 afi=ip \
    nexthop-choice=propagate use-bfd=yes

# 3. Connections
/routing/bgp/connection add name=peer-AS64500 remote.address=203.0.113.1 \
    remote.as=64500 local.role=ebgp templates=ebgp-tpl connect=yes listen=yes
/routing/bgp/connection add name=rr-client-01 remote.address=10.0.0.11 \
    remote.as=65500 local.role=ibgp templates=ibgp-tpl multihop=yes \
    local.address=10.0.0.1 connect=yes listen=yes

# 4. Own networks advertised
/ip firewall address-list add list=bgp-nets address=198.51.100.0/24
/routing/bgp/template set ebgp-tpl output.network=bgp-nets

The important line for iBGP is nexthop-choice=propagate. The default follows RFC 4271 behaviour; propagate keeps the next hop the route was received with, which is what you want when the reflector should not become a transit hop itself. Get this wrong on a reflector and traffic follows a suboptimal path, or loops, depending on the topology. Combined with the connection-level local.role=ibgp, the reflector relationship is complete without any per-peer policy duplication.

Monitoring and Troubleshooting

/routing/bgp/session print
/routing/bgp/session print detail where established=no
/routing/bgp/connection print detail
/routing/stats
/log print where topics~"bgp"

The session menu is read-only live state: established, idle, active, the negotiated capabilities and counters. A session flapping between active and idle means TCP is not completing, which points at transport rather than policy — wrong local.address, a firewall rule dropping TCP 179, or a multihop session where the peer expects a directly connected source. /routing/stats exposes counters for the routing processes, useful for spotting a filter that is rejecting more than you intended. The generic version of that debugging workflow, applicable to any BGP speaker, is in BGP session stuck in Idle or Active and Junos traceoptions for BGP.

Logging on RouterOS is also part of the workflow, not an afterthought: adding bgp to a log topic and pointing it at a memory or disk action gives you the events that explain a flap after the fact. Select a topic filter rather than logging everything, or the useful lines disappear into noise.

Migration Checklist from RouterOS v6

  • Set the router ID globally with /routing id before touching BGP.
  • Create a template per policy set, then set as on the default template.
  • Recreate each v6 peer as a connection, choosing local.role deliberately.
  • Translate update-source to local.address, and confirm the address is reachable from the peer.
  • Port filter lists into /routing/filter/rule chains and reference them from templates.
  • Decide on BFD per relationship rather than globally.
  • Verify with /routing/bgp/session print that every expected peer is established before removing the old configuration.

For the operational basics of getting around the CLI during the migration, the command families are largely shared across vendors; Huawei VRP common commands is a useful cross-reference for the show-and-display equivalents. Where the same router also announces service addresses to Kubernetes, note that MetalLB Layer2 versus BGP uses the same BGP machinery on the cluster side.

原文链接:https://help.mikrotik.com/docs/spaces/ROS/pages/30474256/Moving+from+ROSv6+to+v7+with+examples