Getting the simplest OSPF network to work.

I struggled (and failed) to get OSPF routing to work with IPV6, so I tried with IP V4. This only took a couple of hours to get working. But I could not find any documentation which had baby steps to show you how it works, and what any output means.

This blog post is getting two Linux machines and z/OS to work with IPV4 and OSPF routing.

Some other blog articles give examples of the commands you can use to explore the configuration, and find what is running where.

What is OSPF

OSPF is a routing protocol where a router knows the topology of the network – rather than just the next hop. As the network changes, the changes are sent to the routers and their picture of the network is updated. OSPF scales to large number of routers.

My configuration

I used the frr (Free Range Routing) package which has routing capabilities for OSPF, OSPF6, RIP etc.

The laptop had

  • ip v4 address 10.1.0.2/24
  • routes
    • 10.1.0.0/24 dev enp0s31f6 proto kernel scope link src 10.1.0.2 metric 100
    • 10.1.0.0/24 via 10.1.0.2 dev enp0s31f6 proto static metric 100
    • 10.1.1.0/24 via 10.1.0.3 dev enp0s31f6
  • ospf router id 1.2.3.4

The server had

  • ip v4 address 10.1.0.3/24
  • routes
    • 10.1.0.0/24 dev eno1 proto kernel scope link src 10.1.0.3 metric 100
    • 10.1.0.0/24 via 10.1.0.3 dev eno1 proto static metric 100
  • ospf router-id 9.2.3.4

The z/OS system has

  • ip v4 address 10.1.1.2
  • routes
    • 10.1.0.0/24 via 10.1.1.1 on ETH1
    • 10.1.1.0/24 dev tap0 proto kernel scope link src 10.1.1.1
  • ospf router-id 10.1.1.2

Laptop frr.conf configuration file

The configuration file is described here.

frr version 7.2.1
frr defaults traditional
hostname laptop
log file /var/log/frr/frr.log
log timestamp precision 6

hostname laptop
service integrated-vtysh-config
...

!
interface enp0s31f6
 description colins ospf
 ip address 10.1.0.2 peer 10.1.0.3/24
 ip ospf area 0.0.0.0

!
router ospf
 ospf router-id 1.2.3.4

line vty

Server frr.conf configuration file

frr version 7.2.1
frr defaults traditional
hostname colin-ThinkCentre-M920s
log file /var/log/frr/frr.log
log timestamp precision 6
hostname Server
service integrated-vtysh-config

interface eno1
 description colins ospf
 ip address 10.1.0.3 peer 10.1.0.2/24
 ip ospf area 0.0.0.0

!
router ospf
 ospf router-id 9.2.3.4
!
line vty

z/OS configuration

TCPIP configuration file – defining ETH1

DEVICE PORTA  MPCIPA 
LINK ETH1  IPAQENET PORTA 
HOME 10.1.1.2 ETH1 
PORT 
   520 UDP OMP2                ; RouteD Server 
BEGINRoutes 
;     Destination   SubnetMask    FirstHop       LinkName  Size 

ROUTE 10.0.0.0    255.0.0.0           =        ETH1 MTU 1492 
ROUTE DEFAULT                     10.1.1.1     ETH1 MTU 1492 
ROUTE 10.1.0.0    255.255.255.0   10.1.1.1     ETH1 MTU 1492 
ROUTE 10.1.1.0    255.255.255.0       =        ETH1 MTU 1492 
ENDRoutes 
ITRACE OFF 
IPCONFIG NODATAGRAMFWD 
UDPCONFIG RESTRICTLOWPORTS 
TCPCONFIG RESTRICTLOWPORTS 
TCPCONFIG TTLS 
START PORTA 

JFPORTCP4 Interface configuration

This is in member USER.Z24C.TCPPARMS(jFACE41)

INTERFACE JFPORTCP4 
    DEFINE IPAQENET 
    CHPIDTYPE OSD 
    IPADDR 10.1.3.2 
    PORTNAME PORT2 

activate and start this using

v tcpip,tcpip,obeyfile,USER.Z24C.TCPPARMS(jFACE41) 

v tcpip,tcpip,sta,jfportcp4

OMPROUTE procedure

//OMPROUTE PROC 
// SET PO='POSIX(ON)' 
//OMPROUTE EXEC PGM=OMPROUTE,REGION=0M,TIME=NOLIMIT, 
// PARM=('&PO.,ENVAR("_CEE_ENVFILE_S=DD:STDENV")/ -6t2 -6d2') 
//OMPCFG DD DISP=SHR,DSN=USER.Z24C.TCPPARMS(&SYSJOBNM) 
//STDENV DD DISP=SHR,DSN=USER.Z24C.TCPPARMS(ENV&SYSJOBNM) 
//SYSPRINT DD SYSOUT=* 
//SYSOUT   DD SYSOUT=* 
//SYSTCPD DD DISP=SHR,DSN=ADCD.Z24C.TCPPARMS(TCPDATA) 
//CEEDUMP  DD SYSOUT=*,DCB=(RECFM=FB,LRECL=132,BLKSIZE=132) 
//  PEND 

and started with

S OMPROUTE,jobname=omp1

USER.Z24C.TCPPARMS(ENV&SYSJOBNM)

RESOLVER_CONFIG=//'ADCD.Z24C.TCPPARMS(TCPDATA)' 
OMPROUTE_DEBUG_FILE=/tmp/logs/omproute.debug 
OMPROUTE_IPV6_DEBUG_FILE=/tmp/logs/omprout6.debug 
OMPROUTE_DEBUG_FILE_CONTROL=1000,5 

OMPROUTE configuration USER.Z24C.TCPPARMS(OMP1)

ospf  RouterID=10.1.1.2; 
                                           
ospf_interface IP_address=10.1.1.2 
      name=ETH1 
      subnet_mask=255.255.255.0 
      ; 
ospf_interface IP_address=10.1.3.2 
      name=JFPORTCP4 
      subnet_mask=255.255.255.0 
      ; 

Startup joblog messages

EZZ7800I OMP1 STARTING
EZZ8171I OMP1 IPV4 OSPF IS USING CONFIGURED ROUTER ID 10.1.1.2 FROM OSPF STATEMENT
EZZ7898I OMP1 INITIALIZATION COMPLETE
EZZ8100I OMP1 SUBAGENT STARTING

OSPF on Linux with frr: the basic commands

This article follows on from getting the simplest example of OSPF working. It gives the frr commands to display useful information.

How to extract useful information

This article is a good introduction in drawing the network based on the information from OSPF.

Filter the output

With the frr show commands you can use regular expressions to filter the output data.

show ip ospf database route | include address|router

gives

laptop# show ip ospf database route  | include address|router
  LS Type: router-LSA
     (Link ID) Designated Router address: 10.1.0.3
     (Link Data) Router Interface address: 10.1.0.2
  LS Type: router-LSA
     (Link ID) Designated Router address: 10.1.0.3
     (Link Data) Router Interface address: 10.1.0.3
     ...

You can also issue the sudo vtysh -c “show ip database route” | …. and use standard Linux facilities like grep, less and sort.

Use JSON

You can display the output in JSON format, for example

show ip ospf route json

gives

Server# show ip ospf route json 
{ "10.1.0.0/24": { "routeType": "N", "cost": 100, "area": "0.0.0.0", "nexthops": [ { "ip": " ", "directly attached to": "eno1" } ] }... }

With JSON you can find out the field names for example “cost” has a value 100.

Options and flags

Many commands give options and flags, such as

Options: 0x2 : *|-|-|-|-|-|E|-
LS Flags: 0x6

I’ve collected some interpretation on these here.

I want to…


frr commands

show ip ospf

 OSPF Routing Process, Router ID: 1.2.3.4
 ...
 Number of areas attached to this router: 1
 Area ID: 0.0.0.0 (Backbone)
   Number of interfaces in this area: Total: 1, Active: 1
   Number of fully adjacent neighbors in this area: 1
   Area has no authentication
   SPF algorithm executed 4 times
   Number of LSA 5
   Number of router LSA 3. Checksum Sum 0x000109da
   Number of network LSA 2. Checksum Sum 0x000139df
   Number of summary LSA 0. Checksum Sum 0x00000000
   ...

There are 3 router Link States, and 2 network Link States; they are displayed below:

show ip ospf database

OSPF Router with ID (1.2.3.4)
  Router Link States (Area 0.0.0.0)
    Link ID         ADV Router      Age  Seq#       CkSum  Link count
    1.2.3.4        1.2.3.4          288 0x80000003 0x15a9 1
    9.2.3.4        9.2.3.4          288 0x80000007 0x56f1 2
    10.1.1.2       10.1.1.2        1078 0x8000001e 0x9d40 1
  Net Link States (Area 0.0.0.0)
    Link ID         ADV Router      Age  Seq#       CkSum
    10.1.0.3       9.2.3.4          289 0x80000001 0x7ba2
    10.1.1.2       10.1.1.2        1082 0x80000003 0xbe3d

show ip ospf database router self-originate

This shows the links attached to this OSPF environment.

OSPF Router with ID (9.2.3.4)
Router Link States (Area 0.0.0.0)
Link State ID: 9.2.3.4 
Number of Links: 2
  Link connected to: Stub Network
  (Link ID) Net: 10.1.0.0
  (Link Data) Network Mask: 255.255.255.0

  Link connected to: a Transit Network
  (Link ID) Designated Router address: 10.1.1.2
  (Link Data) Router Interface address: 10.1.1.1

show ip ospf database router

  OSPF Router with ID (1.2.3.4)
  Router Link States (Area 0.0.0.0)
===================================
  LS age: 387
  Options: 0x2  : *|-|-|-|-|-|E|-
  LS Flags: 0x3  
  Flags: 0x0
  LS Type: router-LSA
  Link State ID: 1.2.3.4 
  Advertising Router: 1.2.3.4
  ...
  Length: 36

  Number of Links: 1

  Link connected to: a Transit Network
    (Link ID) Designated Router address: 10.1.0.3
    (Link Data) Router Interface address: 10.1.0.2
   ...
===================================
  LS Type: router-LSA
  Link State ID: 9.2.3.4 
  Advertising Router: 9.2.3.4
 
 Number of Links: 2
 Link connected to: a Transit Network
  (Link ID) Designated Router address: 10.1.0.3
  (Link Data) Router Interface address: 10.1.0.3

 Link connected to: a Transit Network
  (Link ID) Designated Router address: 10.1.1.2
  (Link Data) Router Interface address: 10.1.1.1
===================================
  LS Type: router-LSA
  Link State ID: 10.1.1.2 
  Advertising Router: 10.1.1.2
  Number of Links: 1
  Link connected to: a Transit Network
   (Link ID) Designated Router address: 10.1.1.2
   (Link Data) Router Interface address: 10.1.1.2 

show ip ospf database router 9.2.3.4

laptop# show ip ospf database router 9.2.3.4
OSPF Router with ID (1.2.3.4)
Router Link States (Area 0.0.0.0)
LS Type: router-LSA
Link State ID: 9.2.3.4 
Advertising Router: 9.2.3.4
Number of Links: 2
  Link connected to: a Transit Network
  (Link ID) Designated Router address: 10.1.0.3
  (Link Data) Router Interface address: 10.1.0.3

  Link connected to: a Transit Network
  (Link ID) Designated Router address: 10.1.1.1
  (Link Data) Router Interface address: 10.1.1.1 

show ip ospf database network

laptop# show ip ospf database network 

  OSPF Router with ID (1.2.3.4)
  Net Link States (Area 0.0.0.0)
  ====   
  LS age:
  LS Type: network-LSA
  Link State ID: 10.1.0.3 (address of Designated Router)
  Advertising Router: 9.2.3.4
 
  Network Mask: /24
    Attached Router: 1.2.3.4
    Attached Router: 9.2.3.4
  ====
  LS age:...
  LS Type: network-LSA
  Link State ID: 10.1.1.2 (address of Designated Router)
  Advertising Router: 10.1.1.2
  Network Mask: /24
    Attached Router: 10.1.1.2
    Attached Router: 9.2.3.4

show ip ospf route

Server# show ip ospf route
============ OSPF network routing table ============
N    10.1.0.0/24           [100] area: 0.0.0.0
                           directly attached to eno1
N    10.1.1.0/24           [10000] area: 0.0.0.0
                           directly attached to tap0
N    10.1.3.0/24           [10000] area: 0.0.0.0
                           directly attached to tap2
N    11.1.0.2/32           [200] area: 0.0.0.0
                           via 10.1.0.2, eno1

Where

  • N is the route type,
    • N, Network, Intra area
    • N IA, network, Inter area
    • D IA, Discard Inter area
  • 10.1.0.0.24 is the IP address
  • [] is the cost
  • 0.0.0.0 is the area

show ip ospf interface enp0s31f6

This command shows the interface on the local system. I’ve displayed what I think is important. There are many more parameters, and it is missing the description from the configuration file!

enp0s31f6 is up
  ... 
  ifindex 2, MTU 1500 bytes, BW 1000 Mbit <UP,BROADCAST,RUNNING,MULTICAST>
  Internet Address 10.1.0.2/24, Broadcast 10.1.0.255, Area 0.0.0.0
  Router ID 1.2.3.4, Network Type BROADCAST, Cost: 100
  Designated Router (ID) 9.2.3.4 Interface Address 10.1.0.3/24
  Backup Designated Router (ID) 1.2.3.4, Interface Address 10.1.0.2
  Neighbor Count is 1, Adjacent neighbor count is 1
  ...

show ip ospf interface traffic

Interface HELLO   DB-Desc LS-Req LS-Update LS-Ack Packets      
          Rx/Tx   Rx/Tx   Rx/Tx  Rx/Tx     Rx/Tx  Queued       
----------------------------------------------------------
enp0s31f6 128/129 4/3     1/1    11/5      4/10   0

show ip ospf router-info

This just shows a setting – or Router Information is disabled on this router.

show ip route

The output below shows there is one OSPF defined route (which has been active for 1 hour 9:51 minutes). (There are other routes defined.)

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, F - PBR,
       f - OpenFabric,
       > - selected route, * - FIB route, q - queued, r - rejected, b - backup
       t - trapped, o - offload failure

K>* 0.0.0.0/0 [0/600] via 192.168.1.254, wlp4s0, 01:10:41
O   10.1.0.0/24 [110/100] is directly connected, enp0s31f6, weight 1, 01:10:41
K * 10.1.0.0/24 [0/100] via 10.1.0.2, enp0s31f6, 01:10:41
C>* 10.1.0.0/24 is directly connected, enp0s31f6, 01:10:41
O   10.1.1.0/24 [110/10100] via 10.1.0.3, enp0s31f6, weight 1, 01:09:51
K>* 10.1.1.0/24 [0/0] via 10.1.0.3, enp0s31f6, 01:10:41
K>* 10.2.1.0/24 [0/0] is directly connected, enp0s31f6, 01:10:41
K>* 10.3.1.0/24 [0/0] via 10.1.0.3, enp0s31f6, 01:10:41
K>* 169.254.0.0/16 [0/1000] is directly connected, virbr0 linkdown, 01:10:41
C>* 192.168.1.0/24 is directly connected, wlp4s0, 01:10:41

show ip rpf

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, F - PBR,
       f - OpenFabric,
       > - selected route, * - FIB route, q - queued, r - rejected, b - backup
       t - trapped, o - offload failure

C>  10.1.0.0/24 is directly connected, enp0s31f6, 01:12:22
C>  192.168.1.0/24 is directly connected, wlp4s0, 01:12:22

Options and flags

You get information displayed like

Options: 0x2  : *|-|-|-|-|-|E|-
LS Flags: 0x6  

Where the options are: See Wikipedia.

  • * reserved
  • O – router’s willingness to receive and forward Opaque-LSAs
  • DC – Handling of Demand Circuits
  • EA” : “-“, describes the router’s willingness to receive and forward External Attributes LSAs
  • N/P – if area is NSSA.
  • MC – Multicast datagrams forwarded
  • E – external link advertisements are not flooded into OSPF
  • M/T – Multi-Topology (MT) Routing in OSPF
  • T – router’s TOS capability

and flags are:

  • SELF 0x01
  • SELF_CHECKED 0x02
  • RECEIVED 0x04
  • APPROVED 0x08
  • DISCARD 0x10
  • LOCAL_XLT 0x20
  • PREMATURE_AGE 0x40
  • IN_MAXAGE 0x80

Other information

ip -4 route

colinpaice@colinpaice:~$ ip -4 route
default via 192.168.1.254 dev wlp4s0 proto dhcp metric 600 
10.1.0.0/24 dev enp0s31f6 proto kernel scope link src 10.1.0.2 metric 100 
10.1.0.0/24 via 10.1.0.2 dev enp0s31f6 proto static metric 100 
10.1.1.0/24 via 10.1.0.3 dev enp0s31f6 
10.2.1.0/24 dev enp0s31f6 scope link 
10.3.1.0/24 via 10.1.0.3 dev enp0s31f6 
169.254.0.0/16 dev virbr0 scope link metric 1000 linkdown 
192.168.1.0/24 dev wlp4s0 proto kernel scope link src 192.168.1.222 metric 600 
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown 

Understanding what OSPF does from the data flows.

I found that understanding the flows between to OSPF nodes helped me understand OSPF.

I used Wireshark to trace the data sent from my OSPF router with id 9.2.3.4.

There are four basic flows

  1. My router sending configuration information to the remote router
  2. The remote router sending acknowledgments back to my router
  3. The remote router sending configuration information to my router (the same as 1. above, but in the opposite direction)
  4. My router sending acknowledgements back to the remote router (the same as 2., but in the opposite direction).

It looks like a lot of data flowing – but I focused on my router sending information to the remote router.

Background information

Link state information helps others build a map of the configuration. This gives status information about the links.

Each router sends “new” information to the remote end of the connection; for example a Link State Update. The remote end acknowledges these with a Link State Acknowledgement.

While the local router is sending stuff to the remote router, the remote router is sending it’s configuration information to the local router.

Once the configuration information has been exchanged, and the configuration information stabilises, there is still a periodic “Hello Packet” between each router. This is a heartbeat to tell the remote end that the local end is still alive. The “Hello Packet” is sent out typically every 10 seconds. Updates are sent out around the “Hello Packet” time, so changes typically propagate through the network, 10 seconds a hop.

Information is exchanged via Link State Advertisement (LSA) which advertises the state of a link.

  • LSA type 1 is for routers, it contains information about routers
  • LSA type 2 is for networks, it contains information about IP addresses

Stub areas.

If you had all boxes in one big area – every box will know about other boxes. This may not scale well.

You can create areas, for example an area could be a country. Areas are connected together through the backbone area, area 0. An area, such as area1, can have information such as for addresses in area 17, go via the default routing to the backbone, and let the router where area 1 joins the backbone area sort out the routing.

Nodes in area 1need fewer definitions – as the definitions just say “go by the backbone”

Summary

I restarted my laptop, and it joined the network.
It’s configuration was

OSPF router id 1.2.3.4

Somewhere else in the network a node received two flows

  • Flow 1
    • I am router, 9.2.3.4
    • Type 1 Router-LSA. I have 3 direct connections
      • Remote end’s IP address 10.1.1.2, my address 10.1.1.1
      • Remote end’s IP address 10.1.3.2, my address 10.1.3.1
      • Remove end’s IP address 10.1.0.3, my address 10.1.0.3
    • Type 2- Network LSA
      • Attached routers 1.2.3.4 and 9.2.3.4
  • Flow 2
    • I am router 1.2.3.4
    • Type 1 Router LSA
      • I have IP address 10.1.0.0 type stub
      • I have IP address 12.1.0.1 type stub.

If the configuration changes, such as a new address is added to the node, the data broadcast is the current configuration.

Each system supporting OSPF gets the same information and can build up a database of the network, and can make informed routing decisions.

Changing the configuration

Adding an address to a link

I used the command

sudo ip -4 addr add 12.12.0.1 dev enp0s31f6

to add an additional IP address to the Ethernet connection on my laptop. The command

ip -4 addr gave

enp0s31f6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    inet 10.1.0.2/24 brd 10.1.0.255 scope global noprefixroute enp0s31f6
       valid_lft forever preferred_lft forever
    inet 12.13.0.1/32 scope global enp0s31f6
       valid_lft forever preferred_lft forever
    inet 12.14.0.1/32 scope global enp0s31f6
       valid_lft forever preferred_lft forever
    inet 12.12.0.1/32 scope global enp0s31f6
       valid_lft forever preferred_lft foreverd

This cause a flow to the z/OS system, saying “this is all the IP addresses I know about”.

LS Update Packet
 Number of LSAs: 1
 LSA-type 1 (Router-LSA), len 72
  LS Type: Router-LSA (1)
  Link State ID: 1.2.3.4
  Advertising Router: 1.2.3.4
   Number of Links: 4
    Type: Transit  ID: 10.1.0.3        Data: 10.1.0.2        Metric: 100
     Type: Stub     ID: 12.13.0.1      Data: 255.255.255.255 Metric: 100
     Type: Stub     ID: 12.14.0.1      Data: 255.255.255.255 Metric: 100
     Type: Stub     ID: 12.12.0.1      Data: 255.255.255.255 Metric: 100

The transit address was the original address.

The stub address(es) were added manually.

Deleting an address to a link

I used the command

sudo ip -4 addr del 12.12.0.1 dev enp0s31f6

to remove the link I had previously added.

This cause a flow to the z/OS system, saying “this is all the IP addresses I know about” – omitting the address I had just deleted.

LS Update Packet
 Number of LSAs: 1
 LSA-type 1 (Router-LSA), len 72
  LS Type: Router-LSA (1)
  Link State ID: 1.2.3.4
  Advertising Router: 1.2.3.4
   Number of Links: 4
     Type: Transit ID: 10.1.0.3  Data: 10.1.0.2        Metric: 100
     Type: Stub    ID: 12.13.0.1 Data: 255.255.255.255 Metric: 100
     Type: Stub    ID: 12.14.0.1 Data: 255.255.255.255 Metric: 100
     Type: Stub    ID: 12.12.0.1 Data: 255.255.255.255 Metric: 100

One way flows in more detail

The “Hello packet”

  • I have Source OSPF router 9.2.3.4, area 0.0.0.0

DB Description

Source OSPF router 9.2.3.4, area 0.0.0.0

DB Description

“I know about…”

Source ospf router 9.2.3.4, area 0.0.0.0

  • LSA-type 1 (Router-LSA) Link State ID 1.2.3.4 advertising 1.2.3.4
  • LSA-type 1 (Router-LSA) Link State ID 9.2.3.4 advertising 9.2.3.4
  • LSA-type 1 (Router-LSA) Link State ID 10.1.1.2 advertising 10.1.1.2
  • LSA-type 2 (Network-LSA) Link State ID 10.1.0.2 advertising 1.2.3.4
  • LSA-type 2 (Networ-kLSA) Link State ID 10.1.1.2 advertising 10.1.1.2

Link state update

“Here is information about the links and the IP addresses”.

Source router 9.2.3.4, Area 0.0.0.0

  • LSA-type 1 (Router-LSA) Link State ID 1.2.3.4 advertising 1.2.3.4
    • Links: Type Transit ID 10.1.0.2 Data 10.1.0.2 Metric 100
  • LSA-type 1 (Router-LSA) Link State ID 9.2.3.4 advertising 9.2.3.4
    • Links: Type Transit ID 10.1.0.2 Data 10.1.0.3 Metric 100
    • Links: Type Stub ID 10.1.1.0 Data 255.255.255.0 Metric 1000
  • LSA-type 1 (Router-LSA) Link State ID 10.1.1.2 advertising 10.1.1.2
    • Links: Type Transit ID 10.1.1.1 Data 10.1.1.2 Metric 1
  • LSA-type 2 (Network-LSA) Link State ID 10.1.0.2 advertising 1.2.3.4
    • Attached router: 1.2.3.4
    • Attached router 9.2.3.4
  • LSA-type 2 (Network-LSA) Link State ID 10.1.1.2 Advertising 10.1.1.2
    • Attached router 10.1.1.2
    • Attached router 9.2.3.4

DB Description

I have OSPF router 9.2.3.4, Area 0.0.0.0

I support external routing

Link state update (2)

Source router 9.2.3.4, Area 0.0.0.0

Link State Type Router

  • LSA-type 1 (Router-LSA) Link State ID 9.2.3.4 advertising 9.2.3.4
    • Links: Type Transit ID 10.1.0.2 Data 10.1.0.3 Metric 100
    • Links: Type Transit ID 10.1.1.1 Data 10.1.1.1 Metric 1000
  • LSA-type 1 (Router-LSA) Link State ID 10.1.1.1 advertising 9.2.3.4
    • Attached router: 9.2.3.4
    • Attached router: 10.1.1.2

Hello Packet

Periodically (every 10 or so seconds) there is a Hello Packet flow, which acts as a heartbeat to let the remote end the know the local end is still alive.

Authenticating ospf

This is another of those little tasks that look simple but turn out to be more a little more complex than it first looked.

Authentication in OSPF is performed by sending authentication data in every flow. This can be a password (not very secure) or an MD5 check sum, based on a shared password and sequence number. The receiver checks the data sent is valid, and matches the data it has.

Enabling authentication on Linux

To do any authentication you need to enable it at the area level.

router ospf
  ospf router-id 9.2.3.4
  area 0.0.0.0 authentication

This turns it on for all interfaces – defaulting to password based with a null password. I did this and my connections failed because the two ends of the link were configured differently.

I first had to configure ip ospf authentication null for all interfaces, then enable area authenticate, and the the connections to other systems worked.

interface tap2
   ip ospf area 0.0.0.0
   ip ospf authentication null

interface ...

router ospf
  ospf router-id 9.2.3.4
  area 0.0.0.0 authentication

I could then enable the authentication on an interface by interface basis.

If there is a mismatch,

  • z/OS will report a mismatch,
  • frr quietly drops the packet. I enabled packet trace.

debug ospf packet hello

I got out a trace

OSPF: ... interface enp0s31f6:10.1.0.2: auth-type mismatch, local Null, rcvd Simple
OSPF: ... ospf_read[10.1.0.3]: Header check failed, dropping.

The router ospf … area … authentication is the master switch.

To define authentication on a link, you have to change both ends, then activate the change at the same time at each end.

On z/OS

I could not find how to get OMPROUTE to reread its configuration file after I updated and OSPF entry. There is an option

f OMP1,reconfig

but the documentation says

RECONFIG
Reread the OMPROUTE configuration file. This command ignores all statements in the configuration file except new OSPF_Interface, RIP_Interface, Interface, IPv6_RIP_Interface, and IPv6_Interface
statements.

and I got messages like

EZZ7821I Ignoring duplicate OSPF_Interface statement for 10.1.1.2

For z/OS OMPROUTE to communicate with frr (and CISCO routers) I had to specify the z/OS definition Authentication_… for example

ospf_interface IP_address=10.1.1.2 
      name=ETH1 
      subnet_mask=255.255.255.0 
      Authentication_type=PASSWORD 
      Authentication_Key="colin" 
      ;    

Then stop and restart OMPROUTE.

Using password (or not)

If you use a password, then it flows in clear text. Anyone sniffing your network will see it. It should not be used to protect your system.

On frr

You need router ospf area … authentication. If you have area … authentication message-digest then the password authentication statement on the interface is ignored.

router ospf
  ospf router-id 9.2.3.4
  router-info area
  area 0.0.0.0 authentication

interface tap0
   ip ospf authentication colin
   ...

On z/OS

ospf_interface IP_address=10.1.3.2 
      name=JFPORTCP4 
      subnet_mask=255.255.255.0 
      Authentication_type=PASSWORD 
      Authentication_Key="colin" 
      ; 

Using MD5

Background

An MD5 checksum is calculated from

  • the key – a string of up to 16 bytes
  • key id – an integer in the range 0-255. In the future this key could be used to specify which checksum algorithm to use. Currently only its value is used only as part of the check sum calculation.
  • the increasing sequence number of the flow.

This checksum is calculated and the sequence number and checksum are sent as part of each flow. The remote end performs the same calculation, with the same data, and the checksum value should match.

Because the sequence number changes with every flow, the checksum value changes with every flow. This prevents replay attacks.

The key must be the same on both ends of the connection. Because frr and hardware routers are based in ASCII, an ASCII value must be specified when using z/OS and these routers.

On frr

router ospf
  ospf router-id 9.2.3.4
  area 0.0.0.0 authentication 

interface tap0
   ip ospf authentication message-digest
   ip ospf message-digest-key 3 md5 AAAAAAAAAAAAAAAA

On z/OS

ospf_interface IP_address=10.1.1.2 
      name=ETH1 
      subnet_mask=255.255.255.0 
      Authentication_type=MD5 
      Authentication_Key=0X41414141414141414141414141414141 
      Authentication_Key_ID=3 
      ;
     ;     Authentication_Key=A"AAAAAAAAAAAAAAAA" 

You can either specify the ASCII value A”A…” or as hex “0x4141…” where 0x41 is the value of A in ASCII.

The z/OS documentation is not very clear. My edited version is

Authentication_Key
The value of the authentication key for this interface. This value must be the same for all routers attached to a common medium a link. The coding of this parameter depends on the authentication type being used on this interface.

For authentication type MD5, code the 16-byte authentication key used in the md5 processing for OSPF routers attached to this interface.

This value must be the same at each end.

If the router at the remote end is ASCII based, for example CISCO or Extreme routers, or the frr package on Linux, this value must be specified in ASCII.

You can specify a value in ASCII as A”ABCD…” or as hexadecimal 0x41424344…”, were 41424344 is the ASCII for ABCD.

For non ASCII routers you can specify an ASCII or hexadecimal value.   You can use pwtokey to generate a suitable hexadecimal key from a password.


Using frr (routing program) on Linux

It took me a day to get frr (Free Range Routing) working on Linux. Some of this was due to missing documentation, and getting it started was a problem until I found the golden path which worked.

What is frr?

frr is an offshoot of quagga, which provides ospf, and rip services etc for IP routing on Linux.

Install frr

I used

sudo apt install frr frr-doc

This creates a userid frr, a group frr and may connect your userid to the group.

Check this with

grep frr /etc/group

This gave me

frrvty:x:146:frr
frr:x:147:

I added myself to the group, so I could edit the configuration files

sudo usermod -a -G frr colin

This does not take effect until next time you logon. In the mean time you can use sudo… to access the files.

It may start up every reboot. To disable this use

sudo systemctl disable frr

and

sudo systemctl enablr frr

to restart at reboot.

You can use

sudo /etc/init.d/frr start

sudo /etc/init.d/frr stop

sudo /etc/init.d/frr restart

Configuration files

You need several configuration files, in /etc/frr. I had to use

sudo nano /etc/frr/…

because gedit did not work in sudo mode.

Make changes; use ctrl-s to save, and ctrl-x to exit.

/etc/frr/daemons

This file says which daemons to start. I was only interested in ripngd, and the parameters to pass to the daemons.

I think the comments about the config apply to the frr.conf and vtysh.conf.

# This file tells the frr package which daemons to start.
#
# Sample configurations for these daemons can be found in
# /usr/share/doc/frr/examples/.
#
# ATTENTION:
#
# When activating a daemon for the first time, a config file, even if it is
# empty, has to be present *and* be owned by the user and group "frr", else
# the daemon will not be started by /etc/init.d/frr. The permissions should
# be u=rw,g=r,o=.
# When using "vtysh" such a config file is also needed. It should be owned by
# group "frrvty" and set to ug=rw,o= though. Check /etc/pam.d/frr, too.
#
# The watchfrr and zebra daemons are always started.
#
bgpd=no
ospfd=no
ospf6d=no
ripd=no
ripngd=yes
isisd=no
pimd=no
ldpd=no
nhrpd=no
eigrpd=no
babeld=no
sharpd=no
pbrd=no
bfdd=no
fabricd=no
vrrpd=no

#
# If this option is set the /etc/init.d/frr script automatically loads
# the config via "vtysh -b" when the servers are started.
# Check /etc/pam.d/frr if you intend to use "vtysh"!
#
vtysh_enable=yes
#zebra_options="  -A 127.0.0.1 -s 90000000 --config_file /etc/frr/frr.conf"
zebra_options="  -A 127.0.0.1 -s 90000000 "
bgpd_options="   -A 127.0.0.1"
ospfd_options="  -A 127.0.0.1"
ospf6d_options=" -A ::1"
ripd_options="   -A 127.0.0.1"
ripngd_options=" -A ::1 "
isisd_options="  -A 127.0.0.1"
pimd_options="   -A 127.0.0.1"
ldpd_options="   -A 127.0.0.1"
nhrpd_options="  -A 127.0.0.1"
eigrpd_options=" -A 127.0.0.1"
babeld_options=" -A 127.0.0.1"
sharpd_options=" -A 127.0.0.1"
pbrd_options="   -A 127.0.0.1"
staticd_options="-A 127.0.0.1"
bfdd_options="   -A 127.0.0.1"
fabricd_options="-A 127.0.0.1"
vrrpd_options="  -A 127.0.0.1"

#
# This is the maximum number of FD's that will be available.
# Upon startup this is read by the control files and ulimit
# is called.  Uncomment and use a reasonable value for your
# setup if you are expecting a large number of peers in
# say BGP.
#MAX_FDS=1024

# The list of daemons to watch is automatically generated by the init script.
#watchfrr_options=""

# for debugging purposes, you can specify a "wrap" command to start instead
# of starting the daemon directly, e.g. to use valgrind on ospfd:
#   ospfd_wrap="/usr/bin/valgrind"
# or you can use "all_wrap" for all daemons, e.g. to use perf record:
#   all_wrap="/usr/bin/perf record --call-graph -"
# the normal daemon command is added to this at the end.

/etc/frr/vtysh.conf

This provides configuration information for the command tool:

service integrated-vtysh-config
hostname laptop
password  zebra
log file /var/frr/vtysh.log debug
  • service integrated-vtysh-config this says use one config file (/etc/frr/frr.conf) rather than one per daemon (as used in quagga)
  • hostname laptop when using vtysh it puts this value at the start of each line (so you know which system you are working with)
  • password zebra I do not know when this is used
  • log file /var/frr/vtysh.log debug I do not know when this is used.

You may want to omit the password.

/etc/frr/frr.conf

The option service integrated-vtysh-config above says use one configuration file (the integrated option) /etc/frr/frr.conf . If service integrated-vtysh-config is not specified, you need one config file per daemon.

frr version 7.2.1
frr defaults traditional
hostname Router
log file /var/log/frr/frr.log
log timestamp precision 3
ipv6 forwarding
hostname colinpaice
hostname vtysh3
service integrated-vtysh-config
!
debug ripng events
debug ripng packet
!
enable password zebra
password zebra
!
router ripng
  network enp0s31f6
  network wlp4s0
!
line vty
!
  • log file /var/log/frr/frr.log You can write to the syslog daemon or to a file. It defaults to log syslog informational See logging below.
  • log timestamp precision 3 Records written to the log have millisecond accuracy (6 gives microseconds). I changed this when trying to get frr to work, to check the config file was being picked up
  • debug ripng events this writes information such as time expired to the log.
  • debug ripng packet this prints out the data sent and received, for example the addresses.
  • enable password zebra
  • password zebra
  • router ripng this is configuration for the ripng daemon.
    • network enp0s31f6
    • network wlp4s0

Structure of the file

Within the config file you can have

interface enp0s31f6
   ip ospf area 0.0.0.0
   ip ospf hello-interval 30
   description colins ospf first


interface enp0s31f6
 description colins ospf second

if you use vtysh

laptop# show interface enp0s31f6 
Interface enp0s31f6 is up, line protocol is up
  Link ups:       0    last: (never)
  Link downs:     0    last: (never)
  vrf: default
  Description: colins ospf second

In this case the second definition overrides the first definition.

With a ip ospf area 0.1.0.0 in the second definition I got message

Must remove previous area config before changing ospf area 
line 33: Failure to communicate[13] to ospfd, line:  ip ospf area 0.1.0.0

Starting and stopping frr

frr starts even though the configuration has problems, and does not provide any diagnostic information.

To check the configuration file syntax

sudo vtysh -m -f /etc/frr/frr.conf

This displays the file, and reports any errors.

Once frr has started there is a command

sudo vtysh -c “show startup-config”

which is meant to display the contents of the start up configuration file. For me this produced no output.

The following command does display the running configuration.

sudo vtysh -c “show running-config”

Starting frr.

The documentation says

Integrated configuration mode
Integrated configuration mode uses a single configuration file, frr.conf, for all daemons. This replaces the individual files like zebra.conf or bgpd.conf.
frr.conf is located in /etc/frr. All daemons check for the existence of this file at startup, and if it exists will not load their individual configuration files. Instead, vtysh -b must be invoked to process frr.conf and apply its settings to the individual daemons.

It looks like the configuration file is not used until vtysh -b has been issued; vtysh sends the configuration file to the daemons.

I used a script

sudo rm /var/log/frr/frr.log
sudo touch /var/log/frr/frr.log
sudo chown frr:frr /var/log/frr/frr.log

sudo /etc/init.d/frr stop 
sleep 1s
sudo /etc/init.d/frr start 
sudo systemctl start ripngd.service
sleep 1s
sudo /etc/init.d/frr status

sleep 1s
less /var/log/frr/frr.log*
ls -ltr /var/log/frr/
  • I could have used sudo /etc/init.d/frr restart instead of stop and start.
  • The log file must exist, and have the correct owner:group.

When I ran vtysh -b I got messages

can’t open logfile /var/log/frr/frr.log
line 4: Failure to communicate[13] to zebra, line: log file /var/log/frr/frr.log

Configuration file[/etc/frr/frr.conf] processing failure: 13

which basically means the file does not exist, or has the wrong owner.

When running I had the following threads running

colinpaice@colinpaice:~$ ps -ef |grep frr
root 5107 1 0 09:09 ? 00:00:00 /usr/lib/frr/watchfrr -d zebra ripngd staticd
frr  5124 1 0 09:09 ? 00:00:00 /usr/lib/frr/zebra -d -A 127.0.0.1 -s 90000000
frr  5129 1 0 09:09 ? 00:00:00 /usr/lib/frr/ripngd -d -A ::1
frr  5133 1 0 09:09 ? 00:00:00 /usr/lib/frr/staticd -d -A 127.0.0.1
 

Displaying and configuring frr.

You can use the command

sudo vtysh

or

sudo vtysh -c “show running-config”

To execute commands to frr.

If configured you can use commands

telnet localhost zebra

but vtysh is easier to type.

You can issue

sudo vtysh -c “show ?”

to show the options on the show command.

sudo vtysh -c “show ipv6 ripng”

gave me

Codes: R - RIPng, C - connected, S - Static, O - OSPF, B - BGP
Sub-codes:
      (n) - normal, (s) - static, (d) - default, (r) - redistribute,
      (i) - interface, (a/S) - aggregated/Suppressed

   Network      Next Hop                      Via     Metric Tag Time
C(i) 2a00:23c5:978f:6e01::/64 
                  ::                          self       1    0  

Displaying is not that easy

I had defined an interface with

interface enp0s31f6
   ipv6 ospf6 instance-id 1
   ipv6 nd prefix 2001:db8:5099::/64
   ipv6 ospf6 network point-to-point
   ipv6 ospf6 advertise prefix-list 2001:db8:2::/64
   ipv6 ospf6 advertise prefix-list 2001::/64
   ip ospf area 0.0.0.0
   ip ospf hello-interval 30
   description colins ospf first

interface enp0s31f6
 description colins ospf second

When I had the ospf daemon running, but not the ospf6 daemon, the show running command gave

interface enp0s31f6
 description colins ospf second
 ip ospf area 0.0.0.0
 ip ospf hello-interval 30
 ipv6 nd prefix 2001:db8:5099::/64
!

When both daemons were running the show running command gave

interface enp0s31f6
 description colins ospf second
 ip ospf area 0.0.0.0
 ip ospf hello-interval 30
 ipv6 nd prefix 2001:db8:5099::/64
 ipv6 ospf6 advertise prefix-list 2001::/64
 ipv6 ospf6 instance-id 1
 ipv6 ospf6 network point-to-point

including the ospf6 information.

The show interface enp0s31f6 command gave

Interface enp0s31f6 is up, line protocol is up
  Link ups:       0    last: (never)
  Link downs:     0    last: (never)
  vrf: default
  Description: colins ospf second
  index 2 metric 0 mtu 1500 speed 1000 
  flags: <UP,BROADCAST,RUNNING,MULTICAST>
  Type: Ethernet
  HWaddr: 8c:16:45:36:f4:8a
  inet 10.1.0.2/24
  inet6 2001:db8::1/128
  inet6 fe80::78e8:9e55:9f3f:768/64
  Interface Type Other

This has some information from my configuration (description) and information from querying the system ( HWaddress, ip addresses).

Logging

If you are logging to syslogd, either by design or default, if you remove the log file, and restart frr you may get messages like

Jan 03 08:51:31 colin-ThinkCentre-M920s systemd[1]: Started FRRouting.
can't open logfile /var/log/frr/frr.log
line 7: Failure to communicate[13] to zebra, line: log file /var/log/frr/frr.log debug 

You need to restart the syslogd daemon, for example

systemctl restart rsyslog.service

If you are logging to syslogd, there is an frr file /etc/rsyslog.d/45-frr.conf which defines the log file as

$outchannel frr_log,/var/log/frr/frr.log

The log file filling up

After day’s usage I noticed the files in the log directory:

ls -ltr  /var/log/frr/
total 1720
-rw-r--r-- 1 frr frr   51171 Jan  4 18:40 frr.log.1.gz
-rw-r--r-- 1 frr frr 1701760 Jan  6 16:37 frr.log

it looks like it does log maintenance, and compresses old logs.

Configuring frr on Linux

The FRR package is “a fully featured, high performance, free software IP routing suite.
It implements all standard routing protocols such as BGP, RIP, OSPF, IS-IS and more (see Feature Matrix), as well as many of their extensions”. The package was developed from the zebra and quagga packages.

This looks an excellent package which works well. There is a lot of good documentation, but the documentation is not entirely accurate, and some of the examples do not work.

Looking at the code helped, but I found that that using the administration tool, almost does away with the need for documentation to configure frr – but the path is not obvious.

I’ll give the steps I took to configure router ospf6 in frr.

I’m assuming you have frr active, and

sudo frr -m -f /etc/frr/frr.conf

runs with no errors. This checks the syntax of the configuration file (/etc/frr/frr.con).

Copy this configuration file, because when frr configuration writes the configuration file, the file is replaced, and may be missing stuff.

Invoke the configuration tool.

sudo vtysh

This gives me

Hello, this is FRRouting (version 7.2.1).
Copyright 1996-2005 Kunihiro Ishiguro, et al.

laptop# 

where laptop was the hostname name I specified in the /etc/frr/vtysh.conf file. This is a useful facility when you are using multiple systems.

You can use the up arrow and down arrow to scroll through the command history.

You can use ? to display available commands and options.

Configuring the ospf6 router

#configure terminal
#router ospf6

This gives

laptop(config-ospf6)#

so you know you are in the configuration of the ospf6 router.

  • A question mark ? – gives the available commands (and options).
  • There is command-complete so you only need to type the first few characters followed by tab for it to complete the command. For example if “¬” is the tab key, list p¬ gives list permutations. Interface ¬ gives the name of the interfaces so int¬ e¬ completes to interface enp0s31f6; int¬ e¬ ¬ gives interface enp0s31f6 area.
  • The list command gives a short summary of the commands and options, for example
interface IFNAME area A.B.C.D
...
ospf6 router-id A.B.C.D

Capital letters indicate where you specify values.

If you do not know which command option to use, you can use ?.

laptop(config-ospf6)# ?
  area                   OSPF6 area parameters
  auto-cost              Calculate OSPF interface cost according to bandwidth
  distance               Administrative distance
  end                    End current mode and change to enable mode
  exit                   Exit current mode and down to previous mode
  find                   Find CLI command matching a regular expression
  interface              Enable routing on an IPv6 interface
  list                   Print command list
  log-adjacency-changes  Log changes in adjacency state
  no                     Negate a command or set its defaults
  ospf6                  Open Shortest Path First (OSPF) for IPv6
  output                 Direct vtysh output to file
  quit                   Exit current mode and down to previous mode
  redistribute           Redistribute
  stub-router            Make router a stub router
  timers                 Adjust routing timers

laptop(config-ospf6)#ospf6 ?

gave

laptop(config-ospf6)# router-id Configure OSPF6 Router-ID

this means the command is ospf6 router…. and the description of the name is Configure OSPF6 Router-ID.

laptop(config-ospf6)#ospf6 router ?

gave

laptop(config-ospf6)# A.B.C.D specify by IPv4 address notation(e.g. 0.0.0.0)

so the command is ospf6 router A.B.C.D

ospf6 router-id 2.2.2.2

this worked with no error messages.

To get out of config-ospf6# use

end

this gets you out of config-ospf6 and back to

laptop# 

You can display the current status

laptop# write terminal

to save it to file

write file

gave

laptop# write file
Note: this version of vtysh never writes vtysh.conf
Building Configuration...
Integrated configuration saved to /etc/frr/frr.conf
[OK]
laptop# 

Note: I had the ospf6 agent running, and had stopped the rip agent. The rip configuration was not written to the file! You can use your backed up copy and re-enter it.

To exit vtysh

laptop# quit

Displaying current status

You can use the show command to display information from frr. It works the same way. show ? gives you the command syntax. It has command-completion.

One-liner commands

You can use sudo vtysh -c “show ipv6…” to display one command (and then pipe it into grep for example).