Hub and Spoke VPN tunnels routed via BGP

The following is an example of BGP dynamic routing in a hub and spoke, or star, VPN topology.

Tunnel configuration

For details on how to configure the hub and spoke IPsec policy, refer to Case no. 1: internal traffic via IPsec tunnels in the IPsec VPN - Hub and Spoke Configuration technical note.

In our example, the way the settings differ from the procedure is in the configuration of traffic endpoints through virtual interfaces, instead of remote networks in the IPsec policy:

Main site

TunnelA
Local network: ipsec1 interface (172.16.0.1)
Peer:

Site_SpokeA

Remote network: Remote_tunnelA (172.16.0.2)
TunnelB
Local network: ipsec2 interface (172.16.0.5)
Peer:

Site_SpokeB

Remote network: Remote_tunnelB (172.16.0.6)

Spoke A

Local network: ipsec1 interface (172.16.0.2)
Peer:

Site_FW_Hub

Remote network: Remote_tunnelA (172.16.0.1)

Spoke B

Local network: ipsec1 interface (172.16.0.6)
Peer:

Site_FW_Hub

Remote network: Remote_tunnelB (172.16.0.5)

BGP configuration of the main site (Hub)

protocol direct { } protocol kernel { learn;# Learn all alien routes from the kernel persist;# Don't remove routes on bird shutdown scan time 20;# Scan kernel routing table every 20 seconds ipv4 { import all;# Default is import all export all;# Default is export none preference 254;# Protect existing routes }; } # This pseudo-protocol watches all interface up/down events. protocol device { scan time 10;# Scan interfaces every 10 seconds } filter f_import { if source = RTS_BGP then accept; else reject; } filter f_export { # local shared networks and BGP routes if( (net = 192.168.0.0/24) || (source = RTS_BGP) ) then accept; else reject; } router id <ip_pub_hub>; template bgp star { local as 65000; ipv4 { import filter f_import; export filter f_export; next hop self; }; hold time 5; multihop; rr client; } protocol bgp router_spokeA from star { neighbor 172.16.0.2 as 65000; source address 172.16.0.1; } protocol bgp router_spokeB from star { neighbor 172.16.0.6 as 65000; source address 172.16.0.5; }

BGP configuration of satellite site Spoke A

protocol direct {
}

protocol kernel {
	learn;# Learn all alien routes from the kernel
	persist;# Don't remove routes on bird shutdown
	scan time 20;# Scan kernel routing table every 20 seconds
	ipv4 {
	     import all;# Default is import all
	     export all;# Default is export none
	     preference 254;# Protect existing routes
	};
}

protocol device {
	scan time 10;# Scan interfaces every 10 seconds
}

filter filter_export_net {
	if(net = 192.168.1.0/24) then {
	accept;
	}
	else reject;
}

router id  <ip_pub_spokeA>;

protocol bgp router_tunnel1 {
	local as 65000;
	neighbor 172.16.0.1 as 65000;
	hold time 5;
	multihop;
	ipv4{
	     import all;
	     export filter filter_export_net;
	};
source address 172.16.0.2;
}

BGP configuration of satellite site Spoke B

protocol direct {
}

protocol kernel {
	learn;# Learn all alien routes from the kernel
	persist;# Don't remove routes on bird shutdown
	scan time 20;# Scan kernel routing table every 20 seconds
	ipv4 {
	     import all;# Default is import all
	     export all;# Default is export none
	     preference 254;# Protect existing routes
	};
}

protocol device {
	scan time 10;# Scan interfaces every 10 seconds
}

filter filter_export_net {
	if(net = 192.168.2.0/24) then {
	accept;
	}
	else reject;
}

router id  <ip_pub_spokeB>;

protocol bgp router_tunnel2 {
	local as 65000;
	neighbor 172.16.0.5 as 65000;
	hold time 5;
	multihop;
	ipv4{
	     import all;
	     export filter filter_export_net;
	};
	source address 172.16.0.6;
}

Verification of routing tables

Routing table on the main site (Hub):

bird> show route
0.0.0.0/0		via 10.60.0.254 on em0 [kernel1 10:16] * (254)
10.60.3.127/32		dev lo0 [kernel1 10:16] * (254)
192.168.0.0/24		dev em1 [direct1 10:16] * (240)
192.168.1.0/24 	dev em2 [direct1 10:16] * (240)
192.168.1.0/24		via 172.16.0.2 on enc1 [router_tunnelA 10:22]*(100/0)[AS65001i]
192.168.2.0/24		via 172.16.0.6 on enc1 [router_tunnelB 10:21]*(100/0)[AS65002i]
192.168.0.254/32	dev lo0 [kernel1 10:16] * (254)
192.168.1.254/32	dev lo0 [kernel1 10:16] * (254)
172.16.0.0/30		dev lo1 [direct1 10:16] * (240)
10.60.0.0/16		dev em0 [direct1 10:16] * (240)
172.16.0.4/30		dev lo2 [direct1 10:16] * (240)

Routing table on spokeA:

bird> show route
0.0.0.0/0	via 10.60.0.254 on em0 [kernel1 13:32] * (254)
192.168.0.0/24	via 172.16.0.1 on enc1 [router_tunnelA 13:32] * (100/0) [i]
192.168.2.0/24	via 172.16.0.1 on enc1 [router_tunnelA 13:32] * (100/0) [i]
192.168.1.0/24	dev em1 [direct1 13:32] * (240)
172.16.0.0/30	dev lo1 [direct1 13:32] * (240)
10.60.3.128/32	dev lo0 [kernel1 13:32] * (254)
10.60.0.0/16	dev em0 [direct1 13:32] * (240)