Skip to main content
edyrmishi
Staff
Staff
February 25, 2026

Technical Tip: Central SNAT enabled: Same-Interface traffic forwarded without NAT

  • February 25, 2026
  • 0 replies
  • 626 views
Description This article describes a scenario where Central SNAT fails to translate the source IP of traffic that enters and exits the FortiGate through the same physical or logical interface. This behavior is typically observed in 'same-interface routing' scenarios where global redirection settings bypass the firewall policy engine.
Scope FortiOS.
Solution

In specific network topologies, traffic may need to be routed back out of the same interface it arrived on. If Central SNAT or Policy-based NAT is required for this traffic, the FortiGate must process the packet through its policy engine (iprope) to evaluate NAT rules.

 

In this scenario, the Test Client’s traffic must be NATed to a specific IP pool address before being forwarded to the destination, even though both the ingress and egress occur on port1.

 

SNAT hairpin.png

 

When traffic enters and exits the same interface, the FortiGate may skip the iprope_central_nat_check if the global setting allow-traffic-redirect is enabled. This setting is designed to allow same-interface forwarding efficiently, but it can cause the firewall to bypass the policy lookup required for NAT.

 

Symptoms in debug flow:
When the issue occurs, the diagnose debug flow will show the packet being routed, but the NAT check is completely missing:

 

FGT201F-4 # 2026-02-24 14:44:40 id=65308 trace_id=9 func=print_pkt_detail line=5813 msg="vd-root:0 received a packet(proto=1, 172.16.60.10:1->4.2.2.2:2048) tun_id=0.0.
0.0 from port1. type=8, code=0, id=1, seq=763."
2026-02-24 14:44:40 id=65308 trace_id=9 func=init_ip_session_common line=5997 msg="allocate a new session-000002d8"
2026-02-24 14:44:40 id=65308 trace_id=9 func=iprope_dnat_check line=5276 msg="in-[port1], out-[]"
2026-02-24 14:44:40 id=65308 trace_id=9 func=iprope_dnat_tree_check line=834 msg="len=0"
2026-02-24 14:44:40 id=65308 trace_id=9 func=iprope_dnat_check line=5288 msg="result: skb_flags-02000000, vid-0, ret-no-match, act-accept, flag-00000000"
2026-02-24 14:44:40 id=65308 trace_id=9 func=vf_ip_route_input_common line=2611 msg="find a route: flag=05000000 gw-192.168.60.2 via port1"
2026-02-24 14:44:40 id=65308 trace_id=10 func=print_pkt_detail line=5813 msg="vd-root:0 received a packet(proto=1, 4.2.2.2:1->172.16.60.10:0) tun_id=0.0.0.0 from port1
. type=0, code=0, id=1, seq=763."
2026-02-24 14:44:40 id=65308 trace_id=10 func=vf_ip_route_input_common line=2611 msg="find a route: flag=00000000 gw-172.16.60.10 via port1"

 

The iprope_central_nat_check is missing here.

Scenario 1: 'allow-traffic-redirect' is ENABLED (Failure):

config system setting
    set allow-traffic-redirect enable
end

 

With this enabled, the FortiGate optimizes same-interface traffic by bypassing policy evaluation. The sniffer shows the source IP (172.16.60.10) exiting the interface without translation:

 

FGT # diagnose sniffer packet any 'host 4.2.2.2 and icmp' 4
port1 in 172.16.60.10 -> 4.2.2.2: icmp: echo request
port1 out 172.16.60.10 -> 4.2.2.2: icmp: echo request <----- No SNAT applied.

 

Scenario 2: 'allow-traffic-redirect' is DISABLED (Success).

 

config system setting
    set allow-traffic-redirect disable
end

 

When disabled, the FortiGate is forced to process the traffic through the firewall policies, triggering the Central SNAT table lookup.

 

FGT201F-4 # diagnose sniffer packet any 'host 4.2.2.2 and icmp' 4 0 l
interfaces=[any]
filters=[host 4.2.2.2 and icmp]
2026-02-24 14:42:04.151708 port1 in 172.16.60.10 -> 4.2.2.2: icmp: echo request
2026-02-24 14:42:04.153608 port1 out 10.10.10.100 -> 4.2.2.2: icmp: echo request
2026-02-24 14:42:04.174100 port1 in 4.2.2.2 -> 10.10.10.100: icmp: echo reply
2026-02-24 14:42:04.174114 port1 out 4.2.2.2 -> 172.16.60.10: icmp: echo reply

 

The debug flow will now confirm the NAT engine is active:

 

FGT201F-4 # 2026-02-24 14:43:25 id=65308 trace_id=1 func=print_pkt_detail line=5813 msg="vd-root:0 received a packet(proto=1, 172.16.60.10:1->4.2.2.2:2048) tun_id=0.0.
0.0 from port1. type=8, code=0, id=1, seq=759."
2026-02-24 14:43:25 id=65308 trace_id=1 func=init_ip_session_common line=5997 msg="allocate a new session-000002a6"
2026-02-24 14:43:25 id=65308 trace_id=1 func=iprope_dnat_check line=5276 msg="in-[port1], out-[]"
2026-02-24 14:43:25 id=65308 trace_id=1 func=iprope_dnat_tree_check line=834 msg="len=0"
2026-02-24 14:43:25 id=65308 trace_id=1 func=iprope_dnat_check line=5288 msg="result: skb_flags-02000000, vid-0, ret-no-match, act-accept, flag-00000000"
2026-02-24 14:43:25 id=65308 trace_id=1 func=vf_ip_route_input_common line=2611 msg="find a route: flag=05000000 gw-192.168.60.2 via port1"
2026-02-24 14:43:25 id=65308 trace_id=1 func=iprope_fwd_check line=766 msg="in-[port1], out-[port1], skb_flags-02000000, vid-0, app_id: 0, url_cat_id: 0"
2026-02-24 14:43:25 id=65308 trace_id=1 func=__iprope_tree_check line=539 msg="gnum-100004, use addr/intf hash, len=2"
2026-02-24 14:43:25 id=65308 trace_id=1 func=__iprope_check_one_policy line=2025 msg="checked gnum-100004 policy-1, ret-matched, act-accept"
2026-02-24 14:43:25 id=65308 trace_id=1 func=__iprope_user_identity_check line=1799 msg="ret-matched"
2026-02-24 14:43:25 id=65308 trace_id=1 func=__iprope_check line=2273 msg="gnum-4e20, check-ffffffffa002f5c0"
2026-02-24 14:43:25 id=65308 trace_id=1 func=__iprope_check_one_policy line=2025 msg="checked gnum-4e20 policy-6, ret-no-match, act-accept"
2026-02-24 14:43:25 id=65308 trace_id=1 func=__iprope_check_one_policy line=2025 msg="checked gnum-4e20 policy-6, ret-no-match, act-accept"
2026-02-24 14:43:25 id=65308 trace_id=1 func=__iprope_check_one_policy line=2025 msg="checked gnum-4e20 policy-6, ret-no-match, act-accept"
2026-02-24 14:43:25 id=65308 trace_id=1 func=__iprope_check line=2290 msg="gnum-4e20 check result: ret-no-match, act-accept, flag-00000000, flag2-00000000"
2026-02-24 14:43:25 id=65308 trace_id=1 func=__iprope_check_one_policy line=2243 msg="policy-1 is matched, act-accept"
2026-02-24 14:43:25 id=65308 trace_id=1 func=iprope_fwd_check line=803 msg="after iprope_captive_check(): is_captive-0, ret-matched, act-accept, idx-1"
2026-02-24 14:43:25 id=65308 trace_id=1 func=iprope_fwd_auth_check line=822 msg="after iprope_captive_check(): is_captive-0, ret-matched, act-accept, idx-1"
2026-02-24 14:43:25 id=65308 trace_id=1 func=iprope_reverse_dnat_check line=1284 msg="in-[port1], out-[port1], skb_flags-02000000, vid-0"
2026-02-24 14:43:25 id=65308 trace_id=1 func=iprope_reverse_dnat_tree_check line=926 msg="len=0"
2026-02-24 14:43:25 id=65308 trace_id=1 func=iprope_central_nat_check line=1307 msg="in-[port1], out-[port1], skb_flags-02000000, vid-0"
2026-02-24 14:43:25 id=65308 trace_id=1 func=__iprope_check_one_policy line=2025 msg="checked gnum-10000d policy-1, ret-matched, act-accept"
2026-02-24 14:43:25 id=65308 trace_id=1 func=get_new_addr line=1205 msg="find DNAT: IP-10.10.10.100, port-60418"
2026-02-24 14:43:25 id=65308 trace_id=1 func=__iprope_check_one_policy line=2243 msg="policy-1 is matched, act-accept"
2026-02-24 14:43:25 id=65308 trace_id=1 func=fw_forward_handler line=980 msg="Allowed by Policy-1: SNAT"
2026-02-24 14:43:25 id=65308 trace_id=1 func=__ip_session_run_tuple line=3400 msg="SNAT 172.16.60.10->10.10.10.100:60418"

 

It can be concluded that whenever such an issue is encountered, the traffic redirect setting must be disabled in the global configuration to ensure that Central SNAT is applied to traffic on the same interface:

 

config system setting
    set allow-traffic-redirect disable
end

 

For IPv6:

The option ‘ipv6-allow-traffic-redirect’ should be disabled.

 

config system setting
    set ipv6-allow-traffic-redirect disable
end

 

Notes:

  • Disabling this option ensures that the FortiGate performs a full policy lookup for same-interface traffic. Consequently, a matching Firewall Policy (IPv4 Policy) needs to exist that allows traffic from the source interface to the same destination interface (in this scenario, Port1 to Port1).
  • As of FortiOS v7.4.10, v7.6.5, v8.0.0, and later, the default setting for allow-traffic-redirect(and the IPv6-equivalent ipv6-allow-traffic-redirect) is set to disable(in earlier FortiOS versions, the default setting for this was enable). Furthermore, upgrading to FortiOS v7.4.10, v7.6.5, v8.0.0 or later versions will modify existing configurations and set these CLI options to disable if they were not already set. For reference, the change is tracked under engineering ticket #1225202 as part of security enhancements. Refer: Changes in default behavior.
    Thought Leadership Security Summit. Outpace New Threats with AI - enhanced defense. Tuesday, Septmeber 15, 8:30 AM - 2:30 PM PT. The Golf Club at Newcastle, WA.
    Fortinet Flag the Hack. Wednesday, August 26, 9:00 AM - 5:00 PM ET, COSM, Atlanta, GA.