Richard Bernecker

Random Solutions to Random Problems

Configuring FRR BGP Peering Over GRE

If you need to setup routing on Linux, FRRouting (FRR) is a classic software package that supports the majority of routing protocols. Most major Linux distributions will have a version of FRR available from their official repositories. In my case, I’ll be using CentOS Stream 9 going forward.

In CentOS, FRR can be installed using the following command. Alternative install options are detailed in the install documentation. Once installed, we need to setup the daemons configuration file as discussed here. A working example for BGP is listed below

sudo dnf install frr frr-selinux

Example FRR daemon config file

Location: /etc/frr/daemons


zebra_options="   -A" -s 90000000"
bgpd_options="    -A"
ospfd_options="   -A"
ospf6d_options="  -A ::1"
ripd_options="    -A"
ripngd_options="  -A ::1"
isisd_options="   -A"
pimd_options="    -A"
nhrpd_options="   -A"
eigrpd_options="  -A"
sharpd_options="  -A"
staticd_options=" -A"
pbrd_options="    -A"
bfdd_options="    -A"
fabricd_options=" -A"
vrrpd_options="   -A"
pathd_options="   -A"

Once we’ve edited the daemons config file, we need to ensure that the services file has the following entries:

Location: /etc/services

#Ports numbered 2600 through 2606 are used by the zebra package without being registered. The primary names are the registered names, and the unregistered names used by zebra are listed as aliases.
hpstgmgr        2600/tcp        zebrasrv        # HPSTGMGR
hpstgmgr        2600/udp                        # HPSTGMGR
discp-client    2601/tcp        zebra           # discp client
discp-client    2601/udp                        # discp client
discp-server    2602/tcp        ripd            # discp server
discp-server    2602/udp                        # discp server
servicemeter    2603/tcp        ripngd          # Service Meter
servicemeter    2603/udp                        # Service Meter
nsc-ccs         2604/tcp        ospfd           # NSC CCS
nsc-ccs         2604/udp                        # NSC CCS
nsc-posa        2605/tcp        bgpd            # NSC POSA
nsc-posa        2605/udp                        # NSC POSA
netmon          2606/tcp        ospf6d          # Dell Netmon
netmon          2606/udp                        # Dell Netmon

We also need to ensure that IPv4 packet forwarding is enabled in the kernel so that our routing works properly. You’ll also want to enable IPv6 forwarding if you’ll be routing v6 traffic. Running the below commands will set both the running and persistent configs for v4 packets.

sysctl -w net.ipv4.ip_forward=1
echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf

Now that the foundational FRR configuration is done, we can setup our BGP peering. At this point, I assume that you already have a GRE tunnel setup with a BGP peering address assigned to it. If not, please see my guide here.

FRR includes vtysh that facilitates edits to the running config as described here. For brevity, I’ll include a sample configuration file below rather than running through each equivalent command in vtysh. The majority of commands in vtysh will follow the structure indicated in the config file.

frr version 8.3.1
frr defaults traditional
hostname 87c87s7c.members.linode
log syslog informational
no ipv6 forwarding
ip route eth0
router bgp 12345
 neighbor somedude peer-group
 neighbor somedude remote-as 67890
 neighbor somedude capability dynamic
 neighbor peer-group somedude
 neighbor description "This is my neighbor"
 neighbor ebgp-multihop 10
 neighbor update-source
 address-family ipv4 unicast
  neighbor somedude prefix-list ANNOUNCE out
ip prefix-list ANNOUNCE seq 5 permit
ip prefix-list ANNOUNCE seq 10 deny any

Looking at this configuration, there are several lines worth covering:

  • ip route eth0
    • Defines the local route for the prefix we want to announce over our BGP peering session. In this case we want all traffic for to be directed to interface eth0.
  • router bgp 12345
    • Defines the ASN we want to use for BGP peering.
  • neighbor somedude peer-group
    • Defines a group of BGP peers that we will peer with. This group is named “somedude” in our example.
  • neighbor somedude remote-as 67890
    • Assigns what ASN we expect to see from the BGP peers within the “somedude” peer group.
  • neighbor somedude capability dynamic
    • Allows FRR to negotiate dynamic capabilities with peers in the “somedude” group.
  • neighbor peer-group somedude
    • Defines a BGP neighbor at and adds them into the “somedude” peer group.
  • neighbor ebgp-multihop 10
    • Enables multi-hop support for this eBGP peer with a max supported distance of 10 hops. The peering session will not establish despite being directly connected with a GRE Tunnel. Some router OSs exhibit this same behavior, i.e Arista.
  • neighbor update-source
    • Sets what source IP to use for sending BGP traffic to neighbor Must be set to ensure that the IP assigned to our GRE tunnel is used. The BGP session will not establish if this line is omitted.
  • address-family ipv4 unicast
    • Begins the configuration block that details which prefixes we wish to announce from our local ASN.
  • network
    • Defines what prefix we want to announce out via BGP.
  • neighbor somedude prefix-list ANNOUNCE out
    • Assigns the “ANNOUNCE” prefix-list as outbound policy for the “somedude” neighbor group.
    • Announcements will not go out if FRR does not have an explicitly assigned outbound policy.
  • ip prefix-list ANNOUNCE seq 5 permit
    • Allow to be announced out as part of the “ANNOUNCE” prefix-list.
  • ip prefix-list ANNOUNCE seq 10 deny any
    • Prevent any other prefixes from being announced out over BGP.

We can validate that everything works once the running config has been setup correctly. The following commands are run in vtysh.

show bgp neighbors
show ip bgp neighbors advertised-routes

Once we’ve validated that peering is working, we can write the config to disk with:

write mem

That’s it! You’ve setup BGP peering over a GRE tunnel in FRR. You can exit vtysh.