Fortinet white logo
Fortinet white logo

Administration Guide

Adaptive Forward Error Correction

Adaptive Forward Error Correction

Forward Error Correction (FEC) is used to control and correct errors in data transmission by sending redundant data across the VPN in anticipation of dropped packets occurring during transit. The mechanism sends out x number of redundant packets for every y number of base packets.

Adaptive FEC considers link conditions and dynamically adjusts the FEC packet ratio:

  • The FEC base and redundant packet relationship is dynamically adjusted based on changes to the network SLA metrics defined in the SD-WAN SLA health checks. For example, when there is no or low packet loss in the network, FEC can work on a low redundant level sending only one redundant packet for every 10 base packets. As packet loss increases, the number of redundant packets sent can rise accordingly.

  • FEC can be applied only to streams that are sensitive to packet loss. For Example, policies that allow the UDP based VoIP protocol can enable FEC, while TCP based traffic policies do not. This reduces unnecessary bandwidth consumption by FEC.

  • Because FEC does not support NPU offloading, the ability to specify streams and policies that do not require FEC allows those traffic to be offloaded. This means that not all traffic suffers a performance impact.

In this example, an IPsec tunnel is configured between two FortiGates that both have FEC enabled. The tunnel is an SD-WAN zone, and an SLA health-check is used to monitor the quality of the VPN overlay. The intention is to apply FEC to UDP traffic that is passing through the VPN overlay, while allowing all other traffic to pass through without FEC. An FEC profile is configured to adaptively increase redundant levels if the link quality exceeds a 10% packet loss threshold, or the bandwidth exceeds 950 Mbps.

The DMZ interface and IPsec tunnel vd1-p1 are SD-WAN members. FEC is enabled on vd1-p1, and health-check works on vd1-p1.

To configure the FortiGates:
  1. On both FortiGates, enable FEC and NPU offloading on the IPsec tunnel vd1-p1:

    config vpn ipsec phase1-interface
        edit "vd1-p1"
            set npu-offload enable
            set fec-egress enable
            set fec-ingress enable
        next
    end
  2. On FortiGate A, configure SD-WAN:

    The VPN overlay member (vd1-p1) must be included in the health-check and configured as the higher priority member in the SD-WAN rule.

    config system sdwan
        set status enable
        config zone
            edit "virtual-wan-link"
            next
        end
        config members
            edit 1
                set interface "dmz"
                set gateway 172.16.208.2
            next
            edit 2
                set interface "vd1-p1"
            next
        end
        config health-check
            edit "1"
                set server "2.2.2.2"
                set members 2
                config sla
                    edit 1
                    next
                end
            next
        end
        config service
            edit 1
                set name "1"
                set dst "all"
                set src "172.16.205.0"
                set priority-members 2 1                 
            next
        end
    end
  3. On FortiGate A, create a policy to specify performing FEC on UDP traffic, and a policy for other traffic:

    config firewall policy
        edit 1
            set srcintf "port5"
            set dstintf "virtual-wan-link"
            set action accept
            set srcaddr "172.16.205.0"
            set dstaddr "all"
            set schedule "always"
            set service "ALL_UDP"
            set fec enable
        next
        edit 2
            set srcintf "any"
            set dstintf "any"
            set action accept
            set srcaddr "all"
            set dstaddr "all"
            set schedule "always"
            set service "ALL"
        next
    end
  4. On FortiGate A, configure FEC mapping to bind network SLA metrics and FEC base and redundant packets:

    config vpn ipsec fec
        edit "m1"
            config mappings
                edit 1
                    set base 8
                    set redundant 2
                    set packet-loss-threshold 10
                next
                edit 2
                    set base 9
                    set redundant 3
                    set bandwidth-up-threshold 950000
                next
            end
        next
    end

    The mappings are matched from top to bottom: packet loss greater than 10% with eight base and two redundant packets, and then uploading bandwidth greater than 950 Mbps with nine base and three redundant packets.

  5. On FortiGate A, apply the FEC mappings on vd1-p1:

    config vpn ipsec phase1-interface
        edit "vd1-p1"
            set fec-health-check "1"
            set fec-mapping-profile "m1"
            set fec-base 10
            set fec-redundant 1
        next
    end

    The FEC base and redundant values are used when the link quality has not exceeded the limits specified in the FEC profile mapping. If fec-codec is set to xor the base and redundant packet values will not be updated.

To verify the results:
  1. Send TCP and UDP traffic from PC1 to PC2, then check the sessions on FortiGate A:

    # diagnose sys session list
    
    session info: proto=6 proto_state=01 duration=12 expire=3587 timeout=3600 flags=00000000 socktype=0 sockport=0 av_idx=0 use=3
    origin-shaper=
    reply-shaper=
    per_ip_shaper=
    class_id=0 ha_id=0 policy_dir=0 tunnel=/ vlan_cos=0/255
    state=may_dirty npu
    statistic(bytes/packets/allow_err): org=112/2/1 reply=112/2/1 tuples=2
    tx speed(Bps/kbps): 0/0 rx speed(Bps/kbps): 0/0
    orgin->sink: org pre->post, reply pre->post dev=15->102/102->15 gwy=172.16.209.2/172.16.205.11
    hook=pre dir=org act=noop 172.16.205.11:39176->10.1.100.22:5001(0.0.0.0:0)
    hook=post dir=reply act=noop 10.1.100.22:5001->172.16.205.11:39176(0.0.0.0:0)
    pos/(before,after) 0/(0,0), 0/(0,0)
    misc=0 policy_id=2 pol_uuid_idx=719 auth_info=0 chk_client_info=0 vd=0
    serial=00020f7a tos=ff/ff app_list=0 app=0 url_cat=0
    sdwan_mbr_seq=2 sdwan_service_id=1
    rpdb_link_id=ff000001 rpdb_svc_id=0 ngfwid=n/a
    npu_state=0x5000c00
    npu info: flag=0x82/0x81, offload=8/8, ips_offload=0/0, epid=249/74, ipid=74/86, vlan=0x0000/0x0000                          
    vlifid=74/249, vtag_in=0x0000/0x0001 in_npu=1/1, out_npu=1/1, fwd_en=0/0, qid=5/5
    
    session info: proto=17 proto_state=00 duration=0 expire=180 timeout=0 flags=00000000 socktype=0 sockport=0 av_idx=0 use=4
    origin-shaper=
    reply-shaper=
    per_ip_shaper=
    class_id=0 ha_id=0 policy_dir=0 tunnel=/ vlan_cos=0/255
    state=may_dirty fec
    statistic(bytes/packets/allow_err): org=100366/67/1 reply=0/0/0 tuples=2
    tx speed(Bps/kbps): 0/0 rx speed(Bps/kbps): 0/0
    orgin->sink: org pre->post, reply pre->post dev=15->102/102->15 gwy=172.16.209.2/0.0.0.0
    hook=pre dir=org act=noop 172.16.205.11:49052->10.1.100.22:5001(0.0.0.0:0)
    hook=post dir=reply act=noop 10.1.100.22:5001->172.16.205.11:49052(0.0.0.0:0)
    misc=0 policy_id=1 pol_uuid_idx=593 auth_info=0 chk_client_info=0 vd=0
    serial=000210fa tos=ff/ff app_list=0 app=0 url_cat=0
    sdwan_mbr_seq=2 sdwan_service_id=1
    rpdb_link_id=ff000001 rpdb_svc_id=0 ngfwid=n/a
    npu_state=0x5040000
    no_ofld_reason:  non-npu-intf 

    Non-FEC protected TCP traffic is offloaded, while FEC protected UDP traffic is not offloaded

  2. On FortiGate A, check the health-check result and the corresponding FEC base and redundant packets:

    # diagnose sys sdwan health-check
    Health Check(1):
    Seq(2 vd1-p1): state(alive), packet-loss(0.000%) latency(0.168), jitter(0.021), bandwidth-up(999999), bandwidth-dw(999998), bandwidth-bi(1999997) sla_map=0x1
    

    Because bandwidth-up is more than 950000kbps, base and redundant are set to 9 and 3:

    # diagnose vpn tunnel fec vd1-p1
    egress:
        enabled=1 base=9 redundant=3 codec=0 timeout=10(ms)       
        encode=6621 encode_timeout=6621 encode_fail=0
        tx_data=6880 tx_parity=18601
    ingress:
        enabled=1 timeout=50(ms)
        fasm_cnt=0 fasm_full=0
        ipsec_fec_chk_fail=0 complete=0
        rx_data=0 rx_parity=0
        recover=0 recover_timeout=0 recover_fail=0
        rx=0 rx_fail=0
  3. Make packet loss more than 10%, then check the health-check result and the corresponding FEC base and redundant packets again:

    # diagnose sys sdwan  health-check
    Health Check(1):
    Seq(2 vd1-p1): state(alive), packet-loss(15.000%) latency(0.168), jitter(0.017), bandwidth-up(999999), bandwidth-dw(999998), bandwidth-bi(1999997) sla_map=0x0
    

    Because packet loss is more than 10%, entry one in FEC mapping is first matched, and base and redundant are set to 8 and 2:

    # diagnose vpn tunnel fec  vd1-p1
    egress:
        enabled=1 base=8 redundant=2 codec=0 timeout=10(ms)
        encode=6670 encode_timeout=6670 encode_fail=0
        tx_data=6976 tx_parity=18748
    ingress:
        enabled=1 timeout=50(ms)
        fasm_cnt=0 fasm_full=0
        ipsec_fec_chk_fail=0 complete=0
        rx_data=0 rx_parity=0
        recover=0 recover_timeout=0 recover_fail=0
        rx=0 rx_fail=0

Adaptive Forward Error Correction

Adaptive Forward Error Correction

Forward Error Correction (FEC) is used to control and correct errors in data transmission by sending redundant data across the VPN in anticipation of dropped packets occurring during transit. The mechanism sends out x number of redundant packets for every y number of base packets.

Adaptive FEC considers link conditions and dynamically adjusts the FEC packet ratio:

  • The FEC base and redundant packet relationship is dynamically adjusted based on changes to the network SLA metrics defined in the SD-WAN SLA health checks. For example, when there is no or low packet loss in the network, FEC can work on a low redundant level sending only one redundant packet for every 10 base packets. As packet loss increases, the number of redundant packets sent can rise accordingly.

  • FEC can be applied only to streams that are sensitive to packet loss. For Example, policies that allow the UDP based VoIP protocol can enable FEC, while TCP based traffic policies do not. This reduces unnecessary bandwidth consumption by FEC.

  • Because FEC does not support NPU offloading, the ability to specify streams and policies that do not require FEC allows those traffic to be offloaded. This means that not all traffic suffers a performance impact.

In this example, an IPsec tunnel is configured between two FortiGates that both have FEC enabled. The tunnel is an SD-WAN zone, and an SLA health-check is used to monitor the quality of the VPN overlay. The intention is to apply FEC to UDP traffic that is passing through the VPN overlay, while allowing all other traffic to pass through without FEC. An FEC profile is configured to adaptively increase redundant levels if the link quality exceeds a 10% packet loss threshold, or the bandwidth exceeds 950 Mbps.

The DMZ interface and IPsec tunnel vd1-p1 are SD-WAN members. FEC is enabled on vd1-p1, and health-check works on vd1-p1.

To configure the FortiGates:
  1. On both FortiGates, enable FEC and NPU offloading on the IPsec tunnel vd1-p1:

    config vpn ipsec phase1-interface
        edit "vd1-p1"
            set npu-offload enable
            set fec-egress enable
            set fec-ingress enable
        next
    end
  2. On FortiGate A, configure SD-WAN:

    The VPN overlay member (vd1-p1) must be included in the health-check and configured as the higher priority member in the SD-WAN rule.

    config system sdwan
        set status enable
        config zone
            edit "virtual-wan-link"
            next
        end
        config members
            edit 1
                set interface "dmz"
                set gateway 172.16.208.2
            next
            edit 2
                set interface "vd1-p1"
            next
        end
        config health-check
            edit "1"
                set server "2.2.2.2"
                set members 2
                config sla
                    edit 1
                    next
                end
            next
        end
        config service
            edit 1
                set name "1"
                set dst "all"
                set src "172.16.205.0"
                set priority-members 2 1                 
            next
        end
    end
  3. On FortiGate A, create a policy to specify performing FEC on UDP traffic, and a policy for other traffic:

    config firewall policy
        edit 1
            set srcintf "port5"
            set dstintf "virtual-wan-link"
            set action accept
            set srcaddr "172.16.205.0"
            set dstaddr "all"
            set schedule "always"
            set service "ALL_UDP"
            set fec enable
        next
        edit 2
            set srcintf "any"
            set dstintf "any"
            set action accept
            set srcaddr "all"
            set dstaddr "all"
            set schedule "always"
            set service "ALL"
        next
    end
  4. On FortiGate A, configure FEC mapping to bind network SLA metrics and FEC base and redundant packets:

    config vpn ipsec fec
        edit "m1"
            config mappings
                edit 1
                    set base 8
                    set redundant 2
                    set packet-loss-threshold 10
                next
                edit 2
                    set base 9
                    set redundant 3
                    set bandwidth-up-threshold 950000
                next
            end
        next
    end

    The mappings are matched from top to bottom: packet loss greater than 10% with eight base and two redundant packets, and then uploading bandwidth greater than 950 Mbps with nine base and three redundant packets.

  5. On FortiGate A, apply the FEC mappings on vd1-p1:

    config vpn ipsec phase1-interface
        edit "vd1-p1"
            set fec-health-check "1"
            set fec-mapping-profile "m1"
            set fec-base 10
            set fec-redundant 1
        next
    end

    The FEC base and redundant values are used when the link quality has not exceeded the limits specified in the FEC profile mapping. If fec-codec is set to xor the base and redundant packet values will not be updated.

To verify the results:
  1. Send TCP and UDP traffic from PC1 to PC2, then check the sessions on FortiGate A:

    # diagnose sys session list
    
    session info: proto=6 proto_state=01 duration=12 expire=3587 timeout=3600 flags=00000000 socktype=0 sockport=0 av_idx=0 use=3
    origin-shaper=
    reply-shaper=
    per_ip_shaper=
    class_id=0 ha_id=0 policy_dir=0 tunnel=/ vlan_cos=0/255
    state=may_dirty npu
    statistic(bytes/packets/allow_err): org=112/2/1 reply=112/2/1 tuples=2
    tx speed(Bps/kbps): 0/0 rx speed(Bps/kbps): 0/0
    orgin->sink: org pre->post, reply pre->post dev=15->102/102->15 gwy=172.16.209.2/172.16.205.11
    hook=pre dir=org act=noop 172.16.205.11:39176->10.1.100.22:5001(0.0.0.0:0)
    hook=post dir=reply act=noop 10.1.100.22:5001->172.16.205.11:39176(0.0.0.0:0)
    pos/(before,after) 0/(0,0), 0/(0,0)
    misc=0 policy_id=2 pol_uuid_idx=719 auth_info=0 chk_client_info=0 vd=0
    serial=00020f7a tos=ff/ff app_list=0 app=0 url_cat=0
    sdwan_mbr_seq=2 sdwan_service_id=1
    rpdb_link_id=ff000001 rpdb_svc_id=0 ngfwid=n/a
    npu_state=0x5000c00
    npu info: flag=0x82/0x81, offload=8/8, ips_offload=0/0, epid=249/74, ipid=74/86, vlan=0x0000/0x0000                          
    vlifid=74/249, vtag_in=0x0000/0x0001 in_npu=1/1, out_npu=1/1, fwd_en=0/0, qid=5/5
    
    session info: proto=17 proto_state=00 duration=0 expire=180 timeout=0 flags=00000000 socktype=0 sockport=0 av_idx=0 use=4
    origin-shaper=
    reply-shaper=
    per_ip_shaper=
    class_id=0 ha_id=0 policy_dir=0 tunnel=/ vlan_cos=0/255
    state=may_dirty fec
    statistic(bytes/packets/allow_err): org=100366/67/1 reply=0/0/0 tuples=2
    tx speed(Bps/kbps): 0/0 rx speed(Bps/kbps): 0/0
    orgin->sink: org pre->post, reply pre->post dev=15->102/102->15 gwy=172.16.209.2/0.0.0.0
    hook=pre dir=org act=noop 172.16.205.11:49052->10.1.100.22:5001(0.0.0.0:0)
    hook=post dir=reply act=noop 10.1.100.22:5001->172.16.205.11:49052(0.0.0.0:0)
    misc=0 policy_id=1 pol_uuid_idx=593 auth_info=0 chk_client_info=0 vd=0
    serial=000210fa tos=ff/ff app_list=0 app=0 url_cat=0
    sdwan_mbr_seq=2 sdwan_service_id=1
    rpdb_link_id=ff000001 rpdb_svc_id=0 ngfwid=n/a
    npu_state=0x5040000
    no_ofld_reason:  non-npu-intf 

    Non-FEC protected TCP traffic is offloaded, while FEC protected UDP traffic is not offloaded

  2. On FortiGate A, check the health-check result and the corresponding FEC base and redundant packets:

    # diagnose sys sdwan health-check
    Health Check(1):
    Seq(2 vd1-p1): state(alive), packet-loss(0.000%) latency(0.168), jitter(0.021), bandwidth-up(999999), bandwidth-dw(999998), bandwidth-bi(1999997) sla_map=0x1
    

    Because bandwidth-up is more than 950000kbps, base and redundant are set to 9 and 3:

    # diagnose vpn tunnel fec vd1-p1
    egress:
        enabled=1 base=9 redundant=3 codec=0 timeout=10(ms)       
        encode=6621 encode_timeout=6621 encode_fail=0
        tx_data=6880 tx_parity=18601
    ingress:
        enabled=1 timeout=50(ms)
        fasm_cnt=0 fasm_full=0
        ipsec_fec_chk_fail=0 complete=0
        rx_data=0 rx_parity=0
        recover=0 recover_timeout=0 recover_fail=0
        rx=0 rx_fail=0
  3. Make packet loss more than 10%, then check the health-check result and the corresponding FEC base and redundant packets again:

    # diagnose sys sdwan  health-check
    Health Check(1):
    Seq(2 vd1-p1): state(alive), packet-loss(15.000%) latency(0.168), jitter(0.017), bandwidth-up(999999), bandwidth-dw(999998), bandwidth-bi(1999997) sla_map=0x0
    

    Because packet loss is more than 10%, entry one in FEC mapping is first matched, and base and redundant are set to 8 and 2:

    # diagnose vpn tunnel fec  vd1-p1
    egress:
        enabled=1 base=8 redundant=2 codec=0 timeout=10(ms)
        encode=6670 encode_timeout=6670 encode_fail=0
        tx_data=6976 tx_parity=18748
    ingress:
        enabled=1 timeout=50(ms)
        fasm_cnt=0 fasm_full=0
        ipsec_fec_chk_fail=0 complete=0
        rx_data=0 rx_parity=0
        recover=0 recover_timeout=0 recover_fail=0
        rx=0 rx_fail=0