# A worked example; the fields are documented in # crates/server/proto/config.proto. router_id: "10.0.0.1" local_asn: 65000 # Where to accept BGP connections. Port 179 needs privileges; pick another # port to run unprivileged against a peer that dials a custom port. listen_endpoints { address: "127.0.0.1" port: 179 } listen_endpoints { address: "::1" port: 179 } # A peer we connect to and accept connections from. Connections from any # other address are closed unread, unless accept_unconfigured_peers is set, # which is for a closed test network only. peers { name: "r1" endpoint { address: "127.0.0.1" port: 1791 } remote_asn: 65001 hold_time_seconds: 30 # Offer only these families to the peer. Left out, all are offered. address_families: IPV4_UNICAST address_families: IPV6_UNICAST # Take several routes for a prefix from this peer, if it offers to send # them (ADD-PATH). Also ADD_PATH_SEND and ADD_PATH_BOTH. Off by default. add_path: ADD_PATH_RECEIVE # What the peer is to us: PROVIDER, CUSTOMER, PEER, ROUTE_SERVER or # ROUTE_SERVER_CLIENT. With it the peer must not claim to be something # else (RFC 9234), routes are marked "only to customer" and leaks of # marked routes are refused; and with a validator that has ASPAs, the # AS paths of the peer's routes are verified. # role: PEER # Refuse the peer if its OPEN does not say what it is. # require_role: true # Which of the peer's routes are taken. Without this block the general # checks still apply: no private or reserved prefixes or AS numbers, # nothing longer than /24 or /48, no default route, and a path that # begins with the peer's AS. This example is a test network that uses # exactly such prefixes and AS numbers, so it takes them. import { # More routes than this ends the session and keeps the peer down # for hold_down_seconds (600 unless set). max_prefixes: 1000 accept_bogons: true # A route's next hop has to be the peer itself. The test peer of # this example is at 127.0.0.1, which nothing can be sent by way # of, and names another address; so here any is taken. accept_third_party_next_hop: true # For a real peer: the prefixes and origin ASes it may announce, # as generated from the routing registries. # prefixes { prefix: "193.0.0.0/21" max_length: 24 } # origin_asns: 3333 # And then the operator's own rules: a function of the policy # script (see `policy` below), which may refuse the route or mark # and rank it. # function: "from_peer" } # What the peer is told also goes through a function of the script. # export { function: "to_peer" } } connect_retry_seconds: 5 # Let a restarted peer replace a stale Established session immediately # (RFC 4271 CollisionDetectEstablishedState). Default false. collision_detect_established_state: false # Routes this router originates, announced to every peer. originate { prefix: "10.100.0.0/16" } originate { prefix: "2001:db8:100::/48" med: 50 communities: "65000:100" large_communities: "65000:1:2" } # The operator's own rules for routes, as a script beside this file; see # policy.rhai here for an example, and "Policy scripts" in # bin/bgp/README.md. `bgp --check` reads it and says what is wrong. # policy { path: "policy.rhai" } # Validation with the RPKI: refuse routes whose origin AS is not the one the # holder of the addresses authorised, and, from peers with a role, routes # whose AS path is a leak. Point it at a validator's RTR server. # rpki { caches { address: "127.0.0.1" port: 3323 } } # Put the best route of every prefix in the kernel's routing table, so that # this machine forwards by them (Linux; needs CAP_NET_ADMIN). Routes are # marked "proto bgp"; table and metric default to 254 (main) and 20. # kernel {} # Read-only status page, JSON API and metrics. It has no authentication: # keep it on loopback or behind a reverse proxy. http_endpoint { address: "127.0.0.1" port: 8080 }