Update May 6, 2018: Switched to BIRD v2, installed in a Docker image.

When you like to test, how a topology behaves with lots of routes, it’s not that easy to generate them. If you need some few hundred you can use static routes in a router and export them into a routing protocol. But if you need more (and don’t want to connect to a live network) PC based routing software gets handy.

In the following I’m using BIRD (see The BIRD Internet Routing Daemon Project) to generate 20.000 OSPF and 1.000.000 BGP routes.

GNS3 Project

I’m using my BIRD v2 docker image ehlers/bird2 and two IOU router for this test.

GNS3 project

For working with that many routes I have to increase the memory size. Both IOU router were changed to use 1024 MB of RAM (select both IOU routers / right click / configure).

IOU device config

BIRD appliance base configuration

In GNS3 edit the network configuration of the bird2 device:

# Static config for eth0
auto eth0
iface eth0 inet static
	address 10.1.2.2
	netmask 255.255.255.0
	broadcast 10.1.2.255
	gateway 10.1.2.1
#	up echo nameserver 10.1.2.1 > /etc/resolv.conf

# dummy interfaces for announced subnets
auto lo:1
iface lo:1 inet static
	address 11.0.0.0
	netmask 255.0.0.0

auto lo:2
iface lo:2 inet static
	address 12.0.0.0
	netmask 255.0.0.0

Configuring 11.0.0.0/8 and 12.0.0.0/8 as secondary loopback addresses allows us to ping these networks.

IOU base configuration

After configuring the IP addresses all devices should be able to ping it’s neighbor.

IOU1:

interface Loopback0
 ip address 172.16.1.1 255.255.255.255
!
interface Ethernet0/0
 description link to IOU2
 ip address 10.1.1.1 255.255.255.0
 no shutdown
!
interface Ethernet0/1
 description link to bird appliance
 ip address 10.1.2.1 255.255.255.0
 no shutdown
!

IOU2:

interface Loopback0
 ip address 172.16.1.2 255.255.255.255
!
interface Ethernet0/0
 description link to IOU1
 ip address 10.1.1.2 255.255.255.0
 no shutdown
!

IOU routing protocol configuration

Very basic setup of OSPF and BGP.

The networks 20.1.1.0/24 and 20.1.2.0/24 are announced via BGP, to have a route even without BIRD.

IOU1:

router ospf 1
 router-id 172.16.1.1
 passive-interface Loopback0
 network 0.0.0.0 255.255.255.255 area 0
!
router bgp 65000
 bgp log-neighbor-changes
 network 20.1.1.0 mask 255.255.255.0
 neighbor 10.1.2.2 remote-as 65099
 neighbor 172.16.1.2 remote-as 65000
 neighbor 172.16.1.2 update-source Loopback0
!
ip route 20.1.1.0 255.255.255.0 Null0

IOU2:

router ospf 1
 router-id 172.16.1.2
 passive-interface Loopback0
 network 0.0.0.0 255.255.255.255 area 0
!
router bgp 65000
 bgp log-neighbor-changes
 network 20.1.2.0 mask 255.255.255.0
 neighbor 172.16.1.1 remote-as 65000
 neighbor 172.16.1.1 update-source Loopback0
!
ip route 20.1.2.0 255.255.255.0 Null0

BIRD routing protocol configuration

This configuration reads static routes from /etc/bird/static2ospf resp. /etc/bird/static2bgp and announces them via OSPF resp. BGP. Additionally 4 internal OSPF routes are advertised. The routes are not announced to the linux kernel, linux knows only the default route from the docker network configuration.

Initially we create only 10 OSPF and 10 BGP routes. We want to check, that everything works, before the big test starts.

root@bird2-1:/etc/bird# cat > bird.conf
log "/var/log/bird.log" all;

router id 172.16.1.100;

protocol device {
}

ipv4 table ospf_routes;
protocol static {
	ipv4 {			# IPv4 channel for ospf_routes table
		table ospf_routes;
	};
	include "/etc/bird/static2ospf";
}

ipv4 table bgp_routes;
protocol static {
	ipv4 {			# IPv4 channel for bgp_routes table
		table bgp_routes;
	};
	include "/etc/bird/static2bgp";
}

protocol ospf ospf1 {
 	ipv4 {
		table ospf_routes;
		import all;
		export filter {
			if source = RTS_STATIC then {
				ospf_metric1 = 1000;	# for E1 routes
				# ospf_metric2 = 1000;	# for E2 routes
				accept;
			}
			reject;
		};
	};

	area 0 {
		# announce some internal routes
		stubnet 11.255.0.0/32;
		stubnet 11.255.0.1/32;
		stubnet 11.255.0.2/32;
		stubnet 11.255.0.3/32;

		# use all ethernet interfaces
		interface "eth*" {
		};
	};
}

protocol bgp bgp1 {
	local as 65099;
	neighbor 10.1.2.1 as 65000;

	ipv4 {			# regular IPv4 unicast (1/1)
		table bgp_routes;
		import all;
		export filter {
			if source = RTS_STATIC then {
				# Artificially increase path length
				# by advertising local AS number twice
				bgp_path.prepend(65099);
				accept;
			}
			reject;
		};
	};
}
root@bird2-1:/etc/bird# create_routes
Usage: create_routes <start IP> <count> [<output file>]
root@bird2-1:/etc/bird# create_routes 11.0.0.0 10 static2ospf
root@bird2-1:/etc/bird# create_routes 12.0.0.0 10 static2bgp
root@bird2-1:/etc/bird#

Tests

With birdc configure soft we instruct BIRD to reread the configuration. IOU1 tells us, that the BIRD appliance is detected as a new OSPF and BGP neighbor.

*Mar  9 13:52:56.424: %BGP-5-ADJCHANGE: neighbor 10.1.2.2 Up
*Mar  9 13:52:57.430: %OSPF-5-ADJCHG: Process 1, Nbr 172.16.1.100 on Ethernet0/1 from LOADING to FULL, Loading Done

Furthermore both IOU1 and IOU2 should see the BIRD routes and should be able to ping them.

IOU2#sh ip route
Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
       D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area
       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
       E1 - OSPF external type 1, E2 - OSPF external type 2
       i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
       ia - IS-IS inter area, * - candidate default, U - per-user static route
       o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP
       a - application route
       + - replicated route, % - next hop override

Gateway of last resort is not set

      10.0.0.0/8 is variably subnetted, 3 subnets, 2 masks
C        10.1.1.0/24 is directly connected, Ethernet0/0
L        10.1.1.2/32 is directly connected, Ethernet0/0
O        10.1.2.0/24 [110/20] via 10.1.1.1, 00:50:13, Ethernet0/0
      11.0.0.0/32 is subnetted, 14 subnets
O E1     11.0.0.0 [110/1020] via 10.1.1.1, 00:25:42, Ethernet0/0
O E1     11.0.0.1 [110/1020] via 10.1.1.1, 00:25:42, Ethernet0/0
O E1     11.0.0.2 [110/1020] via 10.1.1.1, 00:25:42, Ethernet0/0
O E1     11.0.0.3 [110/1020] via 10.1.1.1, 00:25:42, Ethernet0/0
O E1     11.0.0.4 [110/1020] via 10.1.1.1, 00:25:42, Ethernet0/0
O E1     11.0.0.5 [110/1020] via 10.1.1.1, 00:25:42, Ethernet0/0
O E1     11.0.0.6 [110/1020] via 10.1.1.1, 00:25:42, Ethernet0/0
O E1     11.0.0.7 [110/1020] via 10.1.1.1, 00:25:42, Ethernet0/0
O E1     11.0.0.8 [110/1020] via 10.1.1.1, 00:25:42, Ethernet0/0
O E1     11.0.0.9 [110/1020] via 10.1.1.1, 00:25:42, Ethernet0/0
O        11.255.0.0 [110/30] via 10.1.1.1, 00:25:42, Ethernet0/0
O        11.255.0.1 [110/30] via 10.1.1.1, 00:25:42, Ethernet0/0
O        11.255.0.2 [110/30] via 10.1.1.1, 00:25:42, Ethernet0/0
O        11.255.0.3 [110/30] via 10.1.1.1, 00:25:42, Ethernet0/0
      12.0.0.0/32 is subnetted, 10 subnets
B        12.0.0.0 [200/0] via 10.1.2.2, 00:25:49
B        12.0.0.1 [200/0] via 10.1.2.2, 00:25:49
B        12.0.0.2 [200/0] via 10.1.2.2, 00:25:49
B        12.0.0.3 [200/0] via 10.1.2.2, 00:25:49
B        12.0.0.4 [200/0] via 10.1.2.2, 00:25:49
B        12.0.0.5 [200/0] via 10.1.2.2, 00:25:49
B        12.0.0.6 [200/0] via 10.1.2.2, 00:25:49
B        12.0.0.7 [200/0] via 10.1.2.2, 00:25:49
B        12.0.0.8 [200/0] via 10.1.2.2, 00:25:49
B        12.0.0.9 [200/0] via 10.1.2.2, 00:25:49
      20.0.0.0/24 is subnetted, 2 subnets
B        20.1.1.0 [200/0] via 172.16.1.1, 00:47:19
S        20.1.2.0 is directly connected, Null0
      172.16.0.0/32 is subnetted, 2 subnets
O        172.16.1.1 [110/11] via 10.1.1.1, 00:50:13, Ethernet0/0
C        172.16.1.2 is directly connected, Loopback0
IOU2#ping 11.0.0.0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 11.0.0.0, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/1 ms
IOU2#ping 12.0.0.0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 12.0.0.0, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/4/6 ms
IOU2#

Now we increase the number of routes to 20.000 external OSPF and 1.000.000 BGP routes.

root@bird2-1:/etc/bird# create_routes 11.0.0.0 20000 static2ospf
root@bird2-1:/etc/bird# create_routes 12.0.0.0 1000000 static2bgp
root@bird2-1:/etc/bird# birdc configure soft
BIRD 2.0.2 ready.
Reading configuration from /etc/bird/bird.conf
Reconfigured
root@bird2-1:/etc/bird#

After a short time the routes should have been distributed.

IOU2#show ip route summary
IP routing table name is default (0x0)
IP routing table maximum-paths is 32
Route Source    Networks    Subnets     Replicates  Overhead    Memory (bytes)
connected       0           3           0           204         540
static          0           1           0           68          180
application     0           0           0           0           0
ospf 1          0           20006       0           1360408     3681104
  Intra-area: 6 Inter-area: 0 External-1: 20000 External-2: 0
  NSSA External-1: 0 NSSA External-2: 0
bgp 65000       0           1000001     0           68000068    180000180
  External: 0 Internal: 1000001 Local: 0
internal        5                                               40801500
Total           5           1020011     0           69360748    224483504
IOU2#ping 11.0.78.31
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 11.0.78.31, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/2/5 ms
IOU2#ping 12.15.66.63
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 12.15.66.63, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/4/6 ms
IOU2#

But show memory statistics shows, that the IOU memory is almost exhausted, only 32 MB RAM are free. For a bigger number of routes the IOUs need more RAM configured.

IOU2#show memory statistics
                Head    Total(b)     Used(b)     Free(b)   Lowest(b)  Largest(b)
Processor   C0C1C008   912777928   880592384    32185544    32184504    31713900