Intro to BGP and OSPF

We wanted to create a bgp setup with ospf

This looks roughly like this:

Overview BGP-OSPF

Target description

This post might be relevant for you if you have the following problem to solve:

Given:

  • public ipv4 address or subnet
  • uplink host which talks BGP to us (created in this tutorial)

Target: announce our network prefix to our internal OSPF network, through a backbone router, which talks BGP to uplink (bgp-test01).

Intermediate steps:

  • This means, we need to create a separated network with routing for our internal nodes (here represented by bgp-test02 and bgp-test03).
    • This network is called 192.168.17.0/24 in our example
  • Setup a OSPF session between the bgp-test02 and bgp-test03 (our actual client which will be exposed by our ipv4)
  • Setup a BGP session between bgp-test01 and bgp-test02
    • The peering ips are 10.100.0.10 and 10.100.0.20 in our example
  • fix import and exports of bird config
  • profit

Create network

  1. bgp-test01 has two interfaces
    • public ipv4
    • bgp communication 10.100.0.10/24
  2. bgp-test02 has two interfaces
    • bgp communication 10.100.0.20/24
    • OSPF communication 192.168.17.2/24
  3. bgp-test03 hast one interface:
    • OSPF communication 192.168.17.2/24

OSPF

First we need to set up a the OSPF session using bird on the hosts.

We therefore write the following sketch into each /etc/bird/bird.conf:

router id 10.100.0.10; # <- can be any unique ID per VM

protocol ospf {
    import all;
    export all;

    # Define OSPF areas
    area 0 {
      interface "eth1" {
          cost 10;
          type broadcast;
          hello 5; retransmit 2; wait 10; dead 20;
          authentication simple;
          password "pass";
      # manual costs
      };
    };
};

BGP

bgp-test01

For BGP we add a filter and a peer:


protocol kernel {
	metric 00;
	scan time 60;
	import all;
	learn;
	export all;   # Actually insert routes into the kernel routing table
}


filter is_picopeer {
	# if net ~ 192.168.17.0/24 then accept; # for debugging
	if net ~ 5.145.135.156/32 then accept;
	reject;
};


protocol bgp peer2 {
	local as 64512;
	neighbor 10.100.0.20 as 64513;
	import filter is_picopeer;
	export all;
}

protocol static {
  #  ipv4;
    route 5.145.135.128/27 via 10.100.0.10;
    export all;
}

We import the announced routes from the other peer, if the announcment is part of the allowed public ipv4 subnet. Therefore, we create a filter to check if the announcement is part of the subnet. On the other hand we need to announce a route from our peering node to our side. We therefore create a static route, which routes our whole subnet via our BGP peering address.

bgp-test02

On the other node, we also add the bgp peering to bgp-test01. We import all routes from the upstream bgp-test01 router (except the blocks we manage - but this is not done yet). And export the routes of our public ip block.

filter export_subnets {
	if net ~ [ 5.145.135.156/32 ] then {
		accept;
	}
	reject;
}

protocol bgp peer1 {
	local as 64513;
	neighbor 10.100.0.10 as 64512;
	export filter export_subnets;
	import all; # todo only !export_subnets
}

Fix Exports

You might need to tweak som export and imports of the kernel on your nodes. You can do this using birdc show route and ip r. For OSPF birdc show ospf topology is also very helpful. To see the current state of BGP there is only birdc show proto?

Final configuration

This shows the three final configurations for our setup.

bird.conf of bgp-test01
router id 10.100.0.10;

protocol kernel {
	metric 00;
	scan time 60;
	import all;
	learn;
	export all;   # Actually insert routes into the kernel routing table
}

# The Device protocol is not a real routing protocol. It doesn't generate any
# routes and it only serves as a module for getting information about network
# interfaces from the kernel. 
protocol device {
	scan time 60;
}

filter is_picopeer {
	if net ~ 192.168.17.0/24 then accept;
	if net ~ 5.145.135.156/32 then accept;
	reject;
};


protocol bgp peer2 {
	local as 64512;
	neighbor 10.100.0.20 as 64513;
	import filter is_picopeer;
	export all;
}

protocol static {
    route 5.145.135.128/27 via 10.100.0.10;
    export all;
}
bird.conf of bgp-test02
router id 10.100.0.20;

protocol kernel {
	metric 0;
	scan time 60;
	import all;
	export all;   # Actually insert routes into the kernel routing table
}

# The Device protocol is not a real routing protocol. It doesn't generate any
# routes and it only serves as a module for getting information about network
# interfaces from the kernel. 
protocol device {
	scan time 60;
}

protocol direct {
	interface "lo";
}

filter export_subnets {
	if net ~ [ 5.145.135.156/32 ] then {
		accept;
	}
	reject;
}

protocol bgp peer1 {
	local as 64513;
	neighbor 10.100.0.10 as 64512;
	export filter export_subnets;
	import all;
}


# Enable OSPF protocol
protocol ospf {
    # Define OSPF areas
    import all;
    export all;

    area 0 {
      interface "eth1" {
          cost 10;
          type broadcast;
          hello 5; retransmit 2; wait 10; dead 20;
          authentication simple;
          password "pass";
      # manual costs
      };
    };
};
bird.conf of bgp-test03
router id 10.100.0.30;

# The Kernel protocol is not a real routing protocol. Instead of communicating
# with other routers in the network, it performs synchronization of BIRD's
# routing tables with the OS kernel.
protocol kernel {
	metric 0;
	scan time 60;
	import none;
	export all;   # Actually insert routes into the kernel routing table
}

# The Device protocol is not a real routing protocol. It doesn't generate any
# routes and it only serves as a module for getting information about network
# interfaces from the kernel. 
protocol device {
	scan time 60;
}

protocol direct {
	interface "lo";
}


# Enable OSPF protocol
protocol ospf {
    # Define OSPF areas
    import all;
    export all;

    area 0 {
      interface "eth1" {
          cost 10; 
          type broadcast;
          hello 5; retransmit 2; wait 10; dead 20;
          authentication simple;
          password "pass";
      # manual costs
      };
    };
};