GL-BE3600でMAP-E(v6プラス)が無線LANクライアントだけ通信できない問題の原因と対策

GL-iNet GL-BE3600のハードウェアアクセラレーションが、dev パラメータ付きで作成された ipip6 トンネルデバイスを誤ってオフロードし、無線LANクライアントのTCPデータ転送が壊れる。MAP-Eの map.sh はトンネル作成時に常に dev を指定するため、MAP-E環境では無線LANクライアントのIPv4通信がほぼ全滅する。有線LANクライアントは影響を受けない。

ワークアラウンドはハードウェアアクセラレーションの無効化。

環境

症状

MAP-Eを設定後、無線LANクライアントからIPv4のWebサイトにアクセスできない。有線LANクライアントからは問題なくアクセスできる。IPv6通信およびUDP(DNS等)は無線でも正常に動作する。

調査の過程

MAP-Eの設定確認

まず疑ったのはMAP-E自体の設定ミス。以下を確認したがすべて正常だった。

TCPだけが壊れている

dig @8.8.8.8 でUDPのDNS解決は成功するが、curl でHTTPアクセスするとタイムアウトする。ここでUDP vs TCPの切り分けが決定的だった。

tcpdumpでの観察

map-wan インターフェース上のtcpdumpで、TCPの3-way handshake(SYN → SYN-ACK → ACK)は成功し、HTTP GETリクエストも送信されていた。しかしサーバーからのレスポンスデータが返ってこない。

17:13:15.824011 IP 192.168.8.202.55100 > 142.250.196.100.80: Flags [P.], length 77: HTTP: GET / HTTP/1.1
(ここでサーバーからのレスポンスが来るはずだが来ない)
17:13:20.811169 IP 192.168.8.202.55100 > 142.250.196.100.80: Flags [F.], length 0
(5秒後にクライアントがタイムアウトでFIN)

br-lanでの観察が決定的だった

br-lan(ブリッジ)上でtcpdumpを取ると、サーバーからのレスポンスパケットは実は届いていることがわかった。ただし、約7秒遅延して到着しており、クライアントのタイムアウト後だった。

17:13:15.824  → HTTP GET送信
17:13:20.811  → クライアントがFIN(5秒タイムアウト)
17:13:22.635  ← HTTPレスポンスがbr-lanに到着(7秒遅延)
17:13:22.644  → クライアントがRST(既に切断済み)

つまり、パケットはルーター内部のどこかで滞留していた。

ハードウェアアクセラレーションが原因

GL-iNetの管理パネルで「ネットワークアクセラレーション」を無効化したところ、無線LANクライアントからのTCP通信が即座に復活した。

原因の特定

MAP-E固有の問題なのか、より一般的な問題なのかを切り分けるため、MAP-Eを使わずにシンプルな ipip6(IPv4-in-IPv6)トンネルを手動で作成してテストした。

再現条件

ip -6 tunnel add でトンネルを作成する際の dev パラメータの有無が決定的だった。

# これだとHWアクセラレーション有効でも問題なし
ip -6 tunnel add test-tun mode ip6tnl \
    local $LOCAL_V6 remote $REMOTE_V6 encaplimit none

# これだとHWアクセラレーション有効時に無線TCPが壊れる
ip -6 tunnel add test-tun mode ip6tnl \
    local $LOCAL_V6 remote $REMOTE_V6 dev eth1 encaplimit none

dev パラメータでトンネルを物理インターフェースにバインドすると、ハードウェアオフロード対象になる。このオフロードパスで無線→トンネル方向のTCPデータパケットの処理にバグがある。

MAP-Eの map.sh はトンネル作成時に常に dev パラメータを指定するため(WAN側物理インターフェースにバインドする)、MAP-E環境では必ずこの問題に遭遇する。

影響範囲のまとめ

条件HWアクセラ結果
MAP-E無効✅ 正常
MAP-Eソフトウェア✅ 正常
MAP-Eハードウェア❌ 無線TCPのみ異常
ip6tnl(devなし)ハードウェア✅ 正常
ip6tnl(devあり)ハードウェア❌ 無線TCPのみ異常

ワークアラウンド

GL-iNet管理パネルの「ネットワーク」→「ネットワークアクセラレーション」で以下のいずれかを選択する。

  1. 無効化 — 確実。BE3600のSoC性能なら一般家庭の帯域では問題ないはず
  2. ソフトウェアアクセラレーションに変更 — HWほどではないがある程度の高速化が得られる

おまけ: ニチバンベンチ問題への対策

MAP-Eの設定が正しく動作するようになった後、もう一つの問題に対処した。OpenWrtのMAP-E実装(map.sh)が生成するSNATルールでは、先頭のポートセット(16ポート)にトラフィックが集中し、残りのポートセットが全く使われない。

v6プラスでは15セット×16ポート=240ポートが割り当てられるが、デフォルトでは実質16ポートしか使えていない。同時接続が増えるとポート枯渇が発生し、特定のWebサイト(かつてのニチバン社のサイトが有名)の表示が極端に遅くなる。

nftablesの numgen を使ったラウンドロビン分散で対策した。詳細はwistnkiさんの記事が詳しい。

# ポートセット分散の核心部分
nft add rule ip mape_nat POSTROUTING \
    oifname "map-wanmap" \
    meta l4proto { tcp, udp, icmp } \
    mark set numgen inc mod 15 offset 0x11 counter

これにより接続ごとに15のポートセットへラウンドロビンで振り分けられ、240ポートをフルに活用できるようになった。

参考リンク

免責

本記事はClaude Opus 4.6とのデバッグセッションを元にOpus 4.6が書き起し、一部手を加えたものです。