GL-BE3600でMAP-E(v6プラス)が無線LANクライアントだけ通信できない問題の原因と対策
GL-iNet GL-BE3600のハードウェアアクセラレーションが、dev パラメータ付きで作成された ipip6 トンネルデバイスを誤ってオフロードし、無線LANクライアントのTCPデータ転送が壊れる。MAP-Eの map.sh はトンネル作成時に常に dev を指定するため、MAP-E環境では無線LANクライアントのIPv4通信がほぼ全滅する。有線LANクライアントは影響を受けない。
ワークアラウンドはハードウェアアクセラレーションの無効化。
環境
- ルーター: GL-iNet GL-BE3600(ファームウェア v4.8.3)
- 回線: ドコモ光 + v6プラス(MAP-E / JPNE)
症状
MAP-Eを設定後、無線LANクライアントからIPv4のWebサイトにアクセスできない。有線LANクライアントからは問題なくアクセスできる。IPv6通信およびUDP(DNS等)は無線でも正常に動作する。
調査の過程
MAP-Eの設定確認
まず疑ったのはMAP-E自体の設定ミス。以下を確認したがすべて正常だった。
ifstatus wanmap— IPv4アドレス、ポートセット、ファイアウォールゾーン割り当てすべてOKnft list ruleset— fw4がSNATルールを正しく生成・適用済みconntrack— SNATポートが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管理パネルの「ネットワーク」→「ネットワークアクセラレーション」で以下のいずれかを選択する。
- 無効化 — 確実。BE3600のSoC性能なら一般家庭の帯域では問題ないはず
- ソフトウェアアクセラレーションに変更 — 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ポートをフルに活用できるようになった。
参考リンク
- OpenWrt 22.03/23.05 で MAP-E のポートセット全部使う(wistnki)
- LinuxルーターのMAP-Eで良い感じにNATポートを使い回す方法(turgenev)
- fakemanhk/openwrt-jp-ipoe — map.shのnumgen対応パッチ
- OpenWrt Forum: MAP portsets not fully utilized — connlimit問題の詳細分析
- OpenWrt Issue #11972: MAP-E is not compatible with fw4/nftables
免責
本記事はClaude Opus 4.6とのデバッグセッションを元にOpus 4.6が書き起し、一部手を加えたものです。