Cumulus Basics Part III - static routing and OSPF
In this post, we will look at an introduction to routing on Cumulus Linux, with static routing and OSPF.
Introduction
Initially, Cumulus OS used the Quagga suite for routing capability. However, more recently, there has been a general adoption of a fork of Quagga called FRRouting (FRR) - Cumulus now includes FRR instead of Quagga. Like always, you can either edit the files directly or using Cumulus' NCLU to enable the respective routing features as well.
Topology
We'll be using the following network topology for this post:
Routing configuration is stored in /etc/frr/frr.conf (like how interface configuration is stored in /etc/network/interfaces). It is important to note that the protocols under FRR run as deamons on the OS and are not enabled by default. To see the list of daemons and their status, you can view the /etc/frr/daemons file:
cumulus@SW1:~$ cat /etc/frr/daemons
zebra=yes
bgpd=no
ospfd=no
ospf6d=no
ripd=no
ripngd=no
isisd=no
pimd=no
ldpd=no
nhrpd=no
eigrpd=no
babeld=no
sharpd=no
pbrd=no
'zebra' is the IP routing manager and controls things like static routes. It provides kernel routing table updates, interface lookups, and redistribution of routes between different routing protocols (quoted from 'http://docs.frrouting.org/en/latest/zebra.html').
Let's configure some static routes to provide connectivity between PC1 and PC2. The option to add static routes comes under 'net add routing':
cumulus@SW1:~$ net add routing
agentx : Enable SNMP support for OSPF, OSPFV3, and BGP4 MIBS
as-path : AS_PATH attribute
community-list : Add a community list entry
defaults : Set of configuration defaults used
enable : To make able
extcommunity-list : An extended community list
import-table : Import routes from non-main kernel table
large-community-list : BGP large community-list
line : A terminal line
log : Logging control
mroute : Static unicast routes in MRIB for multicast RPF lookup
password : Set a password
prefix-list : Filter updates to/from this neighbor
protocol : Filter routing info exchanged between zebra and protocol
ptm-enable : Enable neighbor check with specified topology
route : Static routes
route-map : Route-map
service : Service
zebra : Zebra information
Among other things, you can debug zebra, create route-maps from here as well. To serve the purpose of this topology, we simply need to create a static route for 20.1.1.0/24 on SW1 with a next hop of SW2 and a static route for 10.1.1.0/24 on SW2 with a next hop of SW1.
cumulus@SW1:~$ net add routing route 20.1.1.0/24 172.16.12.2
cumulus@SW1:~$ net commit
--- /run/nclu/frr/frr.conf.scratchpad.baseline 2019-04-29 14:28:53.585648028 +0000
+++ /run/nclu/frr/frr.conf.scratchpad 2019-04-29 14:28:53.585648028 +0000
@@ -1,9 +1,11 @@
frr version 4.0+cl3u8
frr defaults datacenter
hostname SW1
username cumulus nopassword
service integrated-vtysh-config
log syslog informational
line vty
end
+ip route 20.1.1.0/24 172.16.12.2
+end
net add/del commands since the last "net commit"
================================================
User Timestamp Command
------- -------------------------- ---------------------------------------------
cumulus 2019-04-29 14:28:53.587527 net add routing route 20.1.1.0/24 172.16.12.2
cumulus@SW2:~$ net add routing route 10.1.1.0/24 172.16.12.1
cumulus@SW2:~$ net commit
--- /run/nclu/frr/frr.conf.scratchpad.baseline 2019-04-29 14:29:37.915465608 +0000
+++ /run/nclu/frr/frr.conf.scratchpad 2019-04-29 14:29:37.915465608 +0000
@@ -1,9 +1,11 @@
frr version 4.0+cl3u8
frr defaults datacenter
hostname SW2
username cumulus nopassword
service integrated-vtysh-config
log syslog informational
line vty
end
+ip route 10.1.1.0/24 172.16.12.1
+end
net add/del commands since the last "net commit"
================================================
User Timestamp Command
------- -------------------------- ---------------------------------------------
cumulus 2019-04-29 14:29:37.918018 net add routing route 10.1.1.0/24 172.16.12.1
The changes made to /etc/frr/frr.conf are highlighted in the previous outputs (in blue). PC1 can ping PC2 now:
PC-1> ping 20.1.1.1
84 bytes from 20.1.1.1 icmp_seq=1 ttl=62 time=8.933 ms
84 bytes from 20.1.1.1 icmp_seq=2 ttl=62 time=1.999 ms
84 bytes from 20.1.1.1 icmp_seq=3 ttl=62 time=2.573 ms
84 bytes from 20.1.1.1 icmp_seq=4 ttl=62 time=2.043 ms
84 bytes from 20.1.1.1 icmp_seq=5 ttl=62 time=2.237 ms
Pretty straightforward, wasn't it?
I am going to undo these changes now and move towards a routing protocol like OSPF instead.
cumulus@SW1:~$ net del routing route 20.1.1.0/24 172.16.12.2
cumulus@SW1:~$ net commit
cumulus@SW2:~$ net del routing route 10.1.1.0/24 172.16.12.1
cumulus@SW2:~$ net commit
Let's bring up OSPF now.
// SW1 configuration
cumulus@SW1:~$ net add ospf router-id 1.1.1.1
cumulus@SW1:~$ net add interface swp2 ospf area 0
cumulus@SW1:~$ net add interface swp2 ospf network point-to-point
cumulus@SW1:~$ net add interface swp1 ospf area 0
cumulus@SW1:~$ net add interface swp1 ospf passive
cumulus@SW1:~$ net commit
// SW2 configuration
cumulus@SW2:~$ net add ospf router-id 2.2.2.2
cumulus@SW2:~$ net add interface swp2 ospf area 0
cumulus@SW2:~$ net add interface swp2 ospf network point-to-point
cumulus@SW2:~$ net add interface swp1 ospf area 0
cumulus@SW2:~$ net add interface swp1 ospf passive
cumulus@SW2:~$ net commit
Verify that OSPF is up and that the LSDB has the correct information:
cumulus@SW1:~$ net show ospf neighbor
Neighbor ID Pri State Dead Time Address Interface RXmtL RqstL DBsmL
2.2.2.2 1 Full/DROther 36.571s 172.16.12.2 swp2:172.16.12.1 0 0 0
cumulus@SW2:~$ net show ospf neighbor
Neighbor ID Pri State Dead Time Address Interface RXmtL RqstL DBsmL
1.1.1.1 1 Full/DROther 35.519s 172.16.12.1 swp2:172.16.12.2 0 0 0
cumulus@SW1:~$ net show ospf database
OSPF Router with ID (1.1.1.1)
Router Link States (Area 0.0.0.0)
Link ID ADV Router Age Seq# CkSum Link count
1.1.1.1 1.1.1.1 79 0x80000006 0x470d 3
2.2.2.2 2.2.2.2 100 0x80000006 0x1e27 3
cumulus@SW1:~$ net show ospf database router 1.1.1.1
OSPF Router with ID (1.1.1.1)
Router Link States (Area 0.0.0.0)
LS age: 89
Options: 0x2 : *|-|-|-|-|-|E|-
LS Flags: 0x3
Flags: 0x0
LS Type: router-LSA
Link State ID: 1.1.1.1
Advertising Router: 1.1.1.1
LS Seq Number: 80000006
Checksum: 0x470d
Length: 60
Number of Links: 3
Link connected to: another Router (point-to-point)
(Link ID) Neighboring Router ID: 2.2.2.2
(Link Data) Router Interface address: 172.16.12.1
Number of TOS metrics: 0
TOS 0 Metric: 100
Link connected to: Stub Network
(Link ID) Net: 172.16.12.0
(Link Data) Network Mask: 255.255.255.0
Number of TOS metrics: 0
TOS 0 Metric: 100
Link connected to: Stub Network
(Link ID) Net: 10.1.1.0
(Link Data) Network Mask: 255.255.255.0
Number of TOS metrics: 0
TOS 0 Metric: 100
cumulus@SW1:~$ net show ospf database router 2.2.2.2
OSPF Router with ID (1.1.1.1)
Router Link States (Area 0.0.0.0)
LS age: 114
Options: 0x2 : *|-|-|-|-|-|E|-
LS Flags: 0x6
Flags: 0x0
LS Type: router-LSA
Link State ID: 2.2.2.2
Advertising Router: 2.2.2.2
LS Seq Number: 80000006
Checksum: 0x1e27
Length: 60
Number of Links: 3
Link connected to: another Router (point-to-point)
(Link ID) Neighboring Router ID: 1.1.1.1
(Link Data) Router Interface address: 172.16.12.2
Number of TOS metrics: 0
TOS 0 Metric: 100
Link connected to: Stub Network
(Link ID) Net: 172.16.12.0
(Link Data) Network Mask: 255.255.255.0
Number of TOS metrics: 0
TOS 0 Metric: 100
Link connected to: Stub Network
(Link ID) Net: 20.1.1.0
(Link Data) Network Mask: 255.255.255.0
Number of TOS metrics: 0
TOS 0 Metric: 100
SW1 and SW2 should have installed 10.1.1.0/24 and 20.1.1.0/24 respectively into RIB/FIB as well.
cumulus@SW1:~$ net show route ospf
RIB entry for ospf
==================
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR,
> - selected route, * - FIB route
O 10.1.1.0/24 [110/100] is directly connected, swp1, 00:02:52
O>* 20.1.1.0/24 [110/200] via 172.16.12.2, swp2, 00:02:42
O 172.16.12.0/24 [110/100] is directly connected, swp2, 00:02:52
cumulus@SW2:~$ net show route ospf
RIB entry for ospf
==================
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR,
> - selected route, * - FIB route
O>* 10.1.1.0/24 [110/200] via 172.16.12.1, swp2, 00:03:51
O 20.1.1.0/24 [110/100] is directly connected, swp1, 00:04:21
O 172.16.12.0/24 [110/100] is directly connected, swp2, 00:04:21
The only thing left to verify is the connectivity from PC1 to PC2.
PC-1> ping 20.1.1.1
84 bytes from 20.1.1.1 icmp_seq=1 ttl=62 time=3.140 ms
84 bytes from 20.1.1.1 icmp_seq=2 ttl=62 time=2.152 ms
84 bytes from 20.1.1.1 icmp_seq=3 ttl=62 time=2.563 ms
84 bytes from 20.1.1.1 icmp_seq=4 ttl=62 time=2.020 ms
84 bytes from 20.1.1.1 icmp_seq=5 ttl=62 time=3.031 ms
Works like a charm! In our next post, we'll take a look at implementing BGP with OSPF as an IGP on Cumulus VX.