GL-BE9300 4.10.1: every IPv6 RA on WAN reloads firewall + network and flushes the whole conntrack table (VPN policy enabled)

Device: GL-BE9300 (Flint 3), firmware 4.10.1 (build 2026-09-18), OpenWrt 23.05 / QSDK, fw4.

Setup: IPv6 enabled on WAN (mode NAT6, wan6 = DHCPv6 on WAN) behind an ISP ONT that sends periodic Router Advertisements; VPN policy by domain enabled (route_policy.global.enabled=1, two OpenVPN clients). Nothing else unusual.

Summary

Every periodic RA from the upstream router (here every ~3.5–10 min, ~230 times a day) makes the router run /etc/init.d/firewall reload and /etc/init.d/network reload. Because the GL firewall init script ends every reload with echo f > /proc/net/nf_conntrack, all connections of the whole home lose their conntrack state every few minutes, and the network reload causes a ~1 s outage of the wired LAN (also LAN-to-LAN traffic). Nothing actually changes in the configuration at these moments.

Root cause (traced on the device, code quoted from /rom)

  1. RA from the ONT → odhcp6c refreshes the delegated prefix → netifd emits a hotplug event ACTION=ifupdate INTERFACE=wan6 IFUPDATE_PREFIXES=1 (no IFUPDATE_ADDRESSES, no IFUPDATE_DATA). Captured from /proc/<pid>/environ of hotplug-call on 11 of 11 RAs.

  2. /etc/hotplug.d/iface/20-firewall:4 correctly ignores such an event:
    [ "$ACTION" = ifupdate -a -z "$IFUPDATE_ADDRESSES" -a -z "$IFUPDATE_DATA" ] && exit 0

  3. But /etc/hotplug.d/iface/99-vpn-client:18-22 maps every action other than ifup to "down":

    if [ "${action}" = "ifup" ] ;then
    action_type='up'
    else
    action_type='down'
    fi

    and line 35 calls /usr/bin/rtp2.sh interface_status_change wan6 down if_type="wan".

  4. In rtp2.sh, for if_type=wan the down branch is empty (:1418-1419), yet the function unconditionally queues and runs reloads (:1454-1457):

    create_reload_service /etc/init.d/firewall
    

    create_reload_service /etc/init.d/network

    reload_modified_service

  5. /etc/init.d/firewall:32-37 (GL addition, not in upstream firewall4):

    reload_service() {
    

    fw4 reload

    #flush conntrack table

    echo f > /proc/net/nf_conntrack

    }

Process tree captured at the moment of a reload: netifd → hotplug-call iface → rtp2.sh interface_status_change wan6 down if_type="wan" → /etc/init.d/firewall reload → fw4 reload. Every RA was followed ~2–3 s later by nat6: Setting up masquerading nat6 for zone_name="wan" in logread (emitted on each fw4 reload); no reload happened without an RA.

Measured impact

  • nf_conntrack_count 1000–1600 → ~10–50 within 2 s, on every RA.

  • ECM/NSS accelerated connections 459 → 2; CPU ~80% for ~5 s while flows are re-learned.

  • After the flush, inbound packets of existing NATed flows are dropped (WAN zone input DROP) until the LAN side sends something. A TCP session where only the server sends data (client silent) died at the first flush and never recovered. Push channels (FCM on Android TV devices), cloud MQTT of IoT devices and similar long-lived connections stayed silent 40–150 s after each flush.

  • network reload → swconfig dev switch1 load network: ping every 0.2 s from a wired LAN host lost ~5 packets (~1 s) per event to the router, to the Internet and to another wired LAN host (pure LAN-to-LAN traffic through the switch), on every RA.

Expected behaviour

An ifupdate of a WAN interface that only refreshes prefix lifetimes should not reload the firewall or the network and must not flush conntrack — exactly what 20-firewall already does.

Suggested fixes

  1. 99-vpn-client: ignore ifupdate without address/data change (at least for WAN-type interfaces), i.e. the same filter as 20-firewall:4. Local one-line workaround we use, inserted in notify_if_status_change() before arg_cmd=… (line 33):

    [ "$action" = ifupdate ] && [ "$if_type" = wan ] && [ -z "$IFUPDATE_ADDRESSES$IFUPDATE_DATA" ] && return 0
    

    Result on the device: RAs keep coming, the handler is skipped, no firewall/network reloads, no flushes, zero LAN packet loss at RA time, the "silent server" TCP test stays alive.

  2. rtp2.sh interface_status_change: do not reload firewall/network when nothing was changed (the wan/down branch changes nothing).

  3. Consider a targeted conntrack cleanup (by mark / interface / old WAN address) instead of echo f > /proc/net/nf_conntrack on every firewall reload.

Related observations (same code path)

  • rtp2.sh:1320 adds the *_in_new_connmark nft rule without checking whether it exists; the delete at :1324 builds nft delete rule … handle $(… grep … | awk '{print $NF}'), which becomes invalid when there are several matches, so duplicates are never removed. We see 2–3 copies of the same rule in vpn_in_new_mark / wan_in_new_mark.

  • odhcp6c keeps a stale prefix (from a previous ISP prefix, lifetime 0) and re-announces it on every RA; netifd adds/removes its route each time, which alone is enough to set IFUPDATE_PREFIXES.

Possibly related forum topics

  • #69244 GL-BE9000 frequent packet loss with VPN on 4.9.0 firmware

  • #71227 GL-BE10000 / 4.8.4: nightly VPN domain updater reloads network and restarts dnsmasq

  • #71368 Repeatedly being disconnected when network in failover changes

  • #65033 GL-XE3000 dropping connections constantly

How to reproduce

  1. IPv6 enabled on WAN in NAT6 mode (DHCPv6 on wan6), upstream router sending RAs.

  2. VPN → VPN policy by domain enabled (route_policy.global.enabled=1).

  3. Watch logread -f | grep -E "nat6: Setting up" and cat /proc/sys/net/netfilter/nf_conntrack_count: a reload and a near-zero conntrack count follow every RA (ip -6 monitor address dev eth0 shows the RA-driven lifetime refresh 2–3 s earlier).

The trace strongly isolates the interruption to the GL.iNet VPN-policy hotplug path: a prefix-only wan6 ifupdate is treated as down, after which rtp2.sh reloads services even though that branch made no policy change. This is consistent with the IPv6-triggered network-reload symptoms previously reported in the related GL-BE9300 topic, but the exact cause on firmware 4.10.1 still requires staff confirmation.

Your event filter is a narrowly scoped workaround because it excludes only prefix-only WAN updates and preserves address/data updates. However, modifying 99-vpn-client is not officially supported by GL.iNet and may be overwritten by firmware upgrades or a reset; keep a copy of the change and restore the original script before seeking support for unrelated VPN-policy behavior. The duplicate nftables-rule observation should also be checked separately, as it may persist independently of the RA-triggered reload.

This reply was generated by AI. Please verify its accuracy.

GL.iNet Technical Support reviews and responds to relevant threads on business days. Please allow time for a staff response.

Hi,

Thank you for your detailed report, testing, and suggestions.

We have reported this issue to the relevant team for further investigation and improvement.
Thank you again for your support and understanding.