Quagga is an open source routing software suite. In this tutorial, I will focus on how to turn a Linux system into a BGP router, or use quagga to demonstrate how to set up BGP peer-to-peer with other BGP routers.
Before we go into details, some background knowledge of BGP is necessary. Border gateway protocol (BGP) is the practical standard of Internet inter domain routing protocol. In BGP terminology, the global Internet is composed of thousands of associated autonomous systems (as), each of which represents a network management domain provided by each specific operator (it is said that former US President George Bush has his own as number).
In order to reach the global routing, each as needs to know how to reach other as in the Internet. At this time, BGP is needed to play this role. BGP is a language for as to exchange routing information with neighboring as. These routing information are usually called BGP lines or BGP prefixes. It includes as number (ASN) and related IP address block. Once all BGP lines are learned and recorded by the local BGP routing table, each as will know how to reach any public IP of the Internet.
The ability to route between different domains (as) is the main reason why BGP is called external gateway protocol (EGP) or inter domain protocol. For example, some routing protocols, such as OSPF, IS-IS, rip and EIGRP, are internal Gateway Protocols (IGPS) or intra domain routing protocols, which are used to deal with routing in a domain
Test plan
In this tutorial, let’s use the following topology.
Let’s assume that operator a wants to establish a BGP to exchange routes with operator B. The details of their as number and IP address space are as follows:
Operator A: ASN (100), IP address space (100.100.0.0 / 22), IP address assigned to eth1 network card of BGP router (100.100.1.1)
Operator B: ASN (200), IP address space (200.200.0.0 / 22), IP address assigned to eth1 network card of BGP router (200.200.1.1)
Router A and router B use 100.100.0.0/30 subnet to connect to each other. Theoretically, any subnet is reachable and interconnected from the operator. In the real scene, it is recommended to use the public IP address space with a mask of 30 bits to realize the connection between operator A and operator B.
Installing quagga in CentOS
If quagga is not installed, we can use Yum to install quagga.
The code is as follows:
If you are using centos7, you need to apply a policy to set SELinux. Otherwise, SELinux will prevent zebra daemons from writing to its configuration directory. If you are using centos6, you can skip this step.
The code is as follows:
The quagga software suite contains several daemons that can work together. Regarding BGP routing, we will focus on establishing the following two daemons.
Zebra: a core daemon for kernel interfaces and static routing
Bgpd: a BGP daemon
Configure logging
After quagga is installed, the next step is to configure zebra to manage the network interface of BGP router. Let’s start the first step by creating a zebra configuration file and enabling logging.
The code is as follows:
In centos6 system:
The code is as follows:
# chkconfig zebra on
In centos7 system:
The code is as follows:
# systemctl enable zebra
Quagga provides a unique command-line tool called vtysh. You can enter commands that are compatible and supported by router manufacturers such as Cisco and juniper. We will use the vtysh shell to configure BGP routing for the rest of the tutorial.
Start the vtysh shell command, enter:
The code is as follows:
The prompt will be changed to the host name, which indicates that you are in the vtysh shell.
The code is as follows:
Now we will use the following command to configure the log file for Zebra:
The code is as follows:
Router-A(config)# log file /var/log/quagga/quagga.log
Router-A(config)# exit
Permanently save zebra configuration:
The code is as follows:
Operate the same procedure in router B.
Configure peer IP address
Next, we will configure the peer IP address on the available interfaces.
The code is as follows:
. . . . .
Interface eth1 is up, line protocol detection is disabled
. . . . .
Configure parameters of eth0 interface:
The code is as follows:
site-A-RTR(config)# interface eth0
site-A-RTR(config-if)# ip address 100.100.0.1/30
site-A-RTR(config-if)# description “to Router-B”
site-A-RTR(config-if)# no shutdown
site-A-RTR(config-if)# exit
Continue to configure parameters of eth1 interface:
The code is as follows:
site-A-RTR(config-if)# ip address 100.100.1.1/24
site-A-RTR(config-if)# description “test ip from provider A network”
site-A-RTR(config-if)# no shutdown
site-A-RTR(config-if)# exit
Now confirm the configuration:
The code is as follows:
<p> Interface eth0 is up, line protocol detection is disabled
Description: “to Router-B”
inet 100.100.0.1/30 broadcast 100.100.0.3
Interface eth1 is up, line protocol detection is disabled
Description: “test ip from provider A network”
inet 100.100.1.1/24 broadcast 100.100.1.255</p>
eth0 up unknown “to Router-B”
eth1 up unknown “test ip from provider A network”
If everything looks ok, don’t forget to save the configuration.
The code is as follows:
Similarly, repeat the configuration at router B.
Before we go on to the next step, confirm that each other’s IP can be pinged.
The code is as follows:
<p> PING 100.100.0.2 (100.100.0.2) 56(84) bytes of data.
64 bytes from 100.100.0.2: icmp_seq=1 ttl=64 time=0.616 ms
Next, we will continue to configure BGP peer and prefix settings.
Configure BGP peer
The quagga daemons are responsible for BGP services called bgpd. First, let’s prepare its configuration file.
The code is as follows:
In centos6 system:
The code is as follows:
# chkconfig bgpd on
In centos7:
The code is as follows:
# systemctl enable bgpd
Now, let’s go to quagga’s shell.
The code is as follows:
The first step is to confirm that there is no configured BGP session. In some versions, we may find a BGP session with as number 7675. Since we don’t need this session, remove it.
The code is as follows:
<p> … … …
router bgp 7675
bgp router-id 200.200.1.1
… … …
We will remove some pre configured BGP sessions and set up the one we need instead.
The code is as follows:
Router-A(config)# no router bgp 7675
Router-A(config)# router bgp 100
Router-A(config)# no auto-summary
Router-A(config)# no synchronizaiton
Router-A(config-router)# neighbor 100.100.0.2 remote-as 200
Router-A(config-router)# neighbor 100.100.0.2 description “provider B”
Router-A(config-router)# exit
Router-A(config)# exit
Router-A# write
Router B will be configured in the same way. The following configuration is provided as a reference.
The code is as follows:
Router-B(config)# no router bgp 7675
Router-B(config)# router bgp 200
Router-B(config)# no auto-summary
Router-B(config)# no synchronizaiton
Router-B(config-router)# neighbor 100.100.0.1 remote-as 100
Router-B(config-router)# neighbor 100.100.0.1 description “provider A”
Router-B(config-router)# exit
Router-B(config)# exit
Router-B# write
When the relevant routers are configured, the peer between the two routers will be established. Now let’s confirm by running the following command:
The code is as follows:
From the output, we can see the “state / pfxrcd” section. If the peer is turned off, the output will show “idle” or “active”. Remember, the word ‘active’ always has a bad meaning in routers. It means that routers are actively looking for neighbors, prefixes or routes. When the peer is in the up state, the output state in “state / pfxrcd” will receive the prefix number from the special neighbor.
In the output of this example, BGP peer is only in the up state between as100 and AS200. So no prefix has been changed, so the value of the rightmost column is 0.
Configure prefix advertisement
As mentioned at the beginning, as 100 will use 100.100.0.0/22 as an announcement. In our example, as 200 will also use 200.200.0.0/22 as an announcement. These prefixes need to be added to BGP configuration as follows.
In router-a:
The code is as follows:
Router-A(config)# router bgp 100
Router-A(config)# network 100.100.0.0/22
Router-A(config)# exit
Router-A# write
In router-b:
The code is as follows:
Router-B(config)# router bgp 200
Router-B(config)# network 200.200.0.0/22
Router-B(config)# exit
Router-B# write
At this point, the two routers start advertising prefixes as needed.
Test prefix notification
First, let’s see if the number of prefixes has changed.
The code is as follows:
To see more prefix details received, we can use the following command to display the total number of prefixes received by neighbor 100.100.0.2.
The code is as follows:
To see which prefix we received from our neighbors:
The code is as follows:
We can also view all BGP routers:
The code is as follows:
The above commands can be used to check which router is learned in the router table through BGP.
The code is as follows:
Code: K – kernel routing, C – linked, s – static, R – routing information protocol, O – open shortest path first protocol,
I – routing protocol from intermediate system to intermediate system, B – border gateway protocol, > – select route, * – FIB route
The code is as follows:
C>* 100.100.1.0/24 is directly connected, eth1
B>* 200.200.0.0/22 [20/0] via 100.100.0.2, eth0, 00:06:45</p>
<p> Router-A# show ip route bgp </p>
<p> B>* 200.200.0.0/22 [20/0] via 100.100.0.2, eth0, 00:08:13
The routes learned by BGP will also appear in the Linux routing table.
The code is as follows:
<p> 100.100.0.0/30 dev eth0 proto kernel scope link src 100.100.0.1
100.100.1.0/24 dev eth1 proto kernel scope link src 100.100.1.1
200.200.0.0/22 via 100.100.0.2 dev eth0 proto zebra
Finally, we will use the ping command to test connectivity. The result will be successful Ping.
The code is as follows:
All in all, this tutorial will focus on how to run a basic BGP router in CentOS system. This tutorial allows you to start learning about BGP configuration, some more advanced settings, such as setting filters, BGP attribute adjustment, local priority and pre path preparation. I will cover these topics in the following tutorials.
I hope this tutorial can help you.