FortiGate SD-WAN Neighbors and Route-Map-Out-Preferable

FortiGate has built in SD-WAN functionality that can be used with both direct internet access and site-to-site VPNs.  There is no license for this functionality and it only needs to be configured with rules that are relevant to your organization.  SD-WAN is a critical piece of Fortinet’s IPsec site-to-site functionality and ensures only healthy links are used for communication.  ADVPN can be layered on top of IPsec SD-WAN to allow for spoke-to-spoke communication via direct shortcuts rather than hair pinning through the hub in traditional hub and spoke topologies.

Fortinet utilizes two proprietary functions to achieve SD-WAN with link monitoring in IPsec configuration – Route Map Preferable and Route Priority.  Route Map Preferable allows for two route-maps to be applied to a BGP neighbor.  If the SD-WAN member health check is alive and within your defined SLA route-map-out-preferable will be utilized.  If the health check exceeds the SLA or completely fails FortiGate will fall back to the route-map specified in the standard route-map-out statement.  BGP communities are tied to these route-maps at the spoke and advertised to the hub.  The hub maps the received communities to Route Priority and inserts them into the routing table.  Route Priority allows the hub to insert multiple otherwise equal routes into the routing table but still prefer the route with the lowest Route Priority.

One additonal Fortinet technology worth mentioning is FortiManager (FMG).  This lab was constructed manually but FortiManager enables this deployment at scale.  FMG has templates to build this configuration for multiple hubs and spokes as needed.  It also leverages variables to be able to reduce spoke configuration in FMG.  Spoke details can be imported via CSVs and then added to the SD-WAN templates.  FMG centralizes policy management for the spokes allowing one package to be created vs creating the same policies on spokes.

Topology

The topology used in this demonstration involves two FortiGates directly connected with two links.  This is representative of a spoke FG connecting to a hub FG via two transports – 1 may be standard internet connectivity via a local ISP and the second may be cellular backup.  IPsec tunnels are then constructed as overlay networks. BGP peering is achieved through the IPsec tunnels.

IPsec

Normal operation in this lab prefers the ISP tunnel but to enable fast failover the IPsec tunnel and BGP peering can be established via cellular concurrently.  The hub is configured to accept dial up connections from spokes to help simplify configuration.  This means that only the spokes need to be configured with the public IP address of the hub in the phase-1 tunnel configuration.  If the spokes have a standard ISP and cellular connections their IP addresses may not be reserved and may change periodically which would require editing of the hub tunnel configuration without this feature. It would also mean hubs would need each spoke configured as an IPsec peer manually.

The hub is configured to hand out IP addressing for spoke tunnels like DHCP; this further simplifies the IPsec configuration on the spokes eliminating the need to IP address the tunnels manually. BGP peering is then built on the IPsec tunnels.

Spoke Config

config vpn ipsec phase1-interface
    edit "Hub1-VPN1"
        set interface "port2"
        set ike-version 2
        set peertype any
        set net-device disable
        set mode-cfg enable
        set proposal aes256-sha256
        set dhgrp 20 21
        set network-overlay enable
        set network-id 1
        set transport auto
        set remote-gw 10.1.1.1
        set psksecret <psk here>
    edit "Hub1-VPN2"
        set interface "port3"
        set ike-version 2
        set peertype any
        set net-device disable
        set mode-cfg enable
        set proposal aes256-sha256
        set dhgrp 20 21
        set network-overlay enable
        set network-id 2
        set transport auto
        set remote-gw 10.2.1.1
        set psksecret <psk here>
    next
end
config vpn ipsec phase2-interface
    edit "Hub1-VPN1"
        set phase1name "Hub1-VPN1"
        set proposal aes256-sha256
        set dhgrp 20 21
    next
    edit "Hub1-VPN2"
        set phase1name "Hub1-VPN2"
        set proposal aes256-sha256
        set dhgrp 20 21
    next
end

Hub Config

config vpn ipsec phase1-interface
    edit "VPN1"
        set type dynamic
        set interface "port2"
        set ike-version 2
        set peertype any
        set net-device disable
        set mode-cfg enable
        set proposal aes256-sha256
        set dpd on-idle
        set dhgrp 20 21
        set network-overlay enable
        set network-id 1
        set transport auto
        set ipv4-start-ip 169.254.96.1
        set ipv4-end-ip 169.254.96.252
        set ipv4-netmask 255.255.255.0
        set psksecret <psk here>
    next
    edit "VPN2"
        set type dynamic
        set interface "port3"
        set ike-version 2
        set peertype any
        set net-device disable
        set mode-cfg enable
        set proposal aes256-sha256
        set dpd on-idle
        set dhgrp 20 21
        set network-overlay enable
        set network-id 2
        set transport auto
        set ipv4-start-ip 169.254.97.1
        set ipv4-end-ip 169.254.97.252
        set ipv4-netmask 255.255.255.0
        set psksecret <psk here>
        set dpd-retryinterval 60
    next
end
config vpn ipsec phase2-interface
    edit "VPN1"
        set phase1name "VPN1"
        set proposal aes256-sha256
        set dhgrp 20 21
    next
    edit "VPN2"
        set phase1name "VPN2"
        set proposal aes256-sha256
        set dhgrp 20 21
    next
end

SD-WAN

The spoke is configured with a health check against a loopback configured on the hub FG.  There is no need to configure a route from the spoke to hub loopback; SD-WAN will use the member IP addresses as the source IP and use the SD-WAN member interface for the health check automatically. The health check can be configured with an acceptable SLA for your use case and will mark the SD-WAN out of SLA accordingly.

Once BGP neighbors are configured, SD-WAN neighbors can be configured. SD-WAN neighbors are configured with the same BGP neighbor IP addresses (IPsec tunnel IPs at Hub), health check, and SLA.  SD-WAN neighbors must be configured on the FG CLI. SD-WAN neighbors allow for the use of route-map-out and route-map-out preferable.

There is no SD-WAN configuration for hubs; the hub relies on the advertised BGP communities by the spoke for route priority application and path selection. Setting the preferred IPsec tunnel at the spoke and then using the dynamic route-map community assignment allows for the same path to be used at both ends of the topology preventing asymmetric routing.

Spoke Config

config system sdwan
    set status enable
    config zone
        edit "virtual-wan-link"
        next
        edit "Hub1"
        next
    end
    config members
        edit 1
            set interface "Hub1-VPN1"
            set zone "Hub1"
        next
        edit 2
            set interface "Hub1-VPN2"
            set zone "Hub1"
        next
    end
    config health-check
        edit "Hub1HC"
            set server "172.16.1.1"
            set update-static-route disable
            set members 1 2
            config sla
                edit 1
                    set link-cost-factor latency jitter packet-loss
                    set latency-threshold 50
                    set jitter-threshold 20
                    set packetloss-threshold 2
                next
            end
        next
    end
    config neighbor
        edit "169.254.96.253"
            set member 1
            set health-check "Hub1HC"
            set sla-id 1
        next
        edit "169.254.97.253"
            set member 2
            set health-check "Hub1HC"
            set sla-id 1
        next
    end
end

Route-Maps and Community-Lists

The spoke configuration uses three route-maps to set a community on routes before advertising them to the hub.  When SLAs are met, the advertised routes are set to community 65000:1 for ISP and 65000:2 for cellular via route-maps Priority-1 and Priority-2 respectively. If the SLA is exceeded on either tunnel the community is changed to 65000:9999 via the Priority-9999 route-map. The route-map default in BGP is Priority-9999 and the route-map-out-preferable is Priority-1 for ISP and Priority-2 for cellular. Route-map-out-preferable will be used if the link is performing within the SD-WAN SLA configured.

The hub configuration utilizes a community-list to interpret the spoke communities.  It then has route-map-in configured for BGP neighbors to match the community-list and then set the route priority that matches.

Spoke Config

config router route-map
    edit "Priority_9999"
        config rule
            edit 1
                set set-community "65000:9999"
                unset set-ip-prefsrc
            next
        end
    next
    edit "Priority_1"
        config rule
            edit 1
                set set-community "65000:1"
                unset set-ip-prefsrc
            next
        end
    next
    edit "Priority_2"
        config rule
            edit 1
                set set-community "65000:2"
                unset set-ip-prefsrc
            next
        end
    next
end

Hub Config

config router community-list
    edit "Priority_1"
        config rule
            edit 1
                set action permit
                set match "65000:1"
            next
        end
    next
    edit "Priority_2"
        config rule
            edit 1
                set action permit
                set match "65000:2"
            next
        end
    next
    edit "Priority_9999"
        config rule
            edit 1
                set action permit
                set match "65000:9999"
            next
        end
    next
end
config router route-map
    edit "RM-VPN-Priority"
        config rule
            edit 1
                set match-community "Priority_1"
                unset set-ip-prefsrc
                set set-priority 1
            next
            edit 2
                set match-community "Priority_2"
                unset set-ip-prefsrc
                set set-priority 2
            next
            edit 3
                set match-community "Priority_9999"
                unset set-ip-prefsrc
                set set-priority 9999
            next
        end
    next
end

BGP

Spokes are configured to peer with the IPsec tunnel headend IP addresses at the Hub.  The Hub BGP configuration accepts peering requests within the tunnel IP subnet to compliment the automatic addressing of spoke IPsec tunnels.  This means that static neighbor configuration is eliminated at the Hub.  Hubs are also configured with multi-path support so that the multiple routes received via the IPsec tunnels of a spoke can exist in the hub routing table.  Without this configuration only one route would be added to the routing table via the BGP route selection process.  Although the traditional metrics for ECMP will be met, only the route with the lowest route priority will be utilized in FG. The spoke configuration also lists the two route-map-out statements discussed earlier that will align with our SD-WAN health checks.  Spoke advertisement interval is reduced to 1 second to enable quick notification for a route that has a route-map changed.  FortiGate will wait 30 seconds by default to advertise a BGP route change and will cause an undesired delay. 

Spoke Config

config router bgp
    set as 65000
    config neighbor
        edit "169.254.96.253"
            set advertisement-interval 1
            set capability-graceful-restart enable
            set link-down-failover enable
            set soft-reconfiguration enable
            set description "Hub1-VPN1"
            set interface "Hub1-VPN1"
            set remote-as 65001
            set route-map-out "Priority_9999"
            set route-map-out-preferable "Priority_1"
            set connect-timer 10
        next
        edit "169.254.97.253"
            set advertisement-interval 1
            set capability-graceful-restart enable
            set link-down-failover enable
            set soft-reconfiguration enable
            set description "Hub1-VPN2"
            set interface "Hub1-VPN2"
            set remote-as 65001
            set route-map-out "Priority_9999"
            set route-map-out-preferable "Priority_2"
            set connect-timer 10
        next
    end
    config network
        edit 1
            set prefix 172.17.1.0 255.255.255.0
        next
    end
    config redistribute "connected"
    end
    config redistribute "rip"
    end
    config redistribute "ospf"
    end
    config redistribute "static"
    end
    config redistribute "isis"
    end
    config redistribute6 "connected"
    end
    config redistribute6 "rip"
    end
    config redistribute6 "ospf"
    end
    config redistribute6 "static"
    end
    config redistribute6 "isis"
    end
end

Hub Config

config router bgp
    set as 65001
    set ebgp-multipath enable
    config neighbor-group
        edit "VPN1"
            set capability-graceful-restart enable
            set link-down-failover enable
            set next-hop-self enable
            set soft-reconfiguration enable
            set remote-as 65000
            set route-map-in "RM-VPN-Priority"
        next
        edit "VPN2"
            set capability-graceful-restart enable
            set link-down-failover enable
            set next-hop-self enable
            set soft-reconfiguration enable
            set remote-as 65000
            set route-map-in "RM-VPN-Priority"
        next
    end
    config neighbor-range
        edit 1
            set prefix 169.254.96.0 255.255.255.0
            set neighbor-group "VPN1"
        next
        edit 2
            set prefix 169.254.97.0 255.255.255.0
            set neighbor-group "VPN2"
        next
    end
    config redistribute "connected"
    end
    config redistribute "rip"
    end
    config redistribute "ospf"
    end
    config redistribute "static"
    end
    config redistribute "isis"
    end
    config redistribute6 "connected"
    end
    config redistribute6 "rip"
    end
    config redistribute6 "ospf"
    end
    config redistribute6 "static"
    end
    config redistribute6 "isis"
    end
end

Lab Environment

The spoke FG is configured with a health check in Network & Interfaces > SD-WAN. The IP address specified for the server is the loopback on the hub FG. Both links are meeting their SLA currently:

Checking the hub routing table reflects both routes in the table with route priorities of 1 for the ISP tunnel and 2 for cellular tunnel. The hub will use the route with the lowest priority despite both being in the table.

On the hub, I created a policy to block traffic from the ISP IPsec tunnel to the health check loopback. This causes the health check on the ISP tunnel to fail at the spoke.  The spoke BGP configuration then changes from route-map-out-preferable to the standard route-map-out with the higher community.  The hub receives this new community and changes the route priority accordingly.  Both routes still exist in the routing table since the actual IPsec tunnel between the spoke and hub via the ISP is up. However, the ISP tunnel will no longer be used since it does not meet the SLA and the cellular tunnel with route priority two will be used.

Finally, after disabling the policy that blocked the ISP health check it returns to meeting the SLA again and the route-map-out-preferable is utilized. The hub routing table shows the preferred priorities again.

Route-map-out and route-map-out-preferrable are powerful tools and can be used for more than swapping communities.  This solution at scale allows for dynamic connections across sites with the best performing links being utilized to provide the best end user experience. The relevant configuration sections have been added to my GitHub.

Scroll to Top