ここ1年ほどネット回線が夜になると劇遅になるのでフレッツ光をPPpoEからIPoEに変えたいとずっと思っていたが、面倒くさいという思いがあって先延ばしにしていた。この度やっと重い腰を上げて乗り換えることにした。
が、当初思ったよりOpenWrtの設定がかんたんではなかったのでここに記録を残すことにした。まだまだPPpoEの契約者も少なく、OpenWrtを使っている人はさらに少ないだろうが、ネットにまとまった手順がなかったので記録せねばと3年ぶりに記事を書くことにした。みなさんお久しぶりです。口調が変わっていても気にしないで。3年も経てば色々忘れてる。

我が家の環境

  • ISP: enひかり(V6プラスオプション)
  • Router: Buffalo WZR-HP-AG300H(OpenWrt 18.06.5 r7897-9d401013fc)
  • フレッツ光からコラボ光へ転用(訪問工事なし)
  • ひかり電話はなし
  • 旧ISPはまた解約しておらずIPv4 PPpoEで接続できる状態
  • OpenWrtのインターフェースはLAN,WAN,WAN6があり、WANは旧ISPで接続中、WAN6は停止中の状態

なお今回解説する手順は JPNEが提供する「v6プラス(MAP-E)」を提供するISPであればどこでも同じになるはずである。

開通日に何が起こるか

当初開通日に接続が勝手に切れると思っていたからそのつもりで仕事を調整していたのだが、結局何も起こらなかった。なので翌日の午後に時間をとって新しい設定をすることにした。

この時点で本当に開通しているのかどうかもわかっていなかった。もしかすると手違いが発生しているのかとか思ったりした。後から調べてわかったのだが、開通はNTT側の設定が切り替わるだけで旧ISPの接続が切れるわけではないのでこちらではいつ開通したのか設定してみないとわからないようだ。DHCPで発行されたIPv6アドレスがJPNEのものであれば開通済みということらしい。

ネイティブIPv6接続

まずはネイティブIPv6接続してみる。

基本的には下記の記事を参考にした。ありがとうございます。
https://blog.misosi.ru/2019/12/02/openwrt-mape/

手順1-1) WAN6インターフェースを作成する

  1. OpenWrt の Web UI にログインする
  2. [Network] – [Interfaces]
  3. WAN6というインターフェースがあるので[Edit]をクリック。(WAN6がなければ作る)
    • General Setup
      • Protocol: DHCPv6 Client
    • Physical Settings
      • Bridge interfaces: off
      • Interface: eth1
    • Firewall Settings
      • Create / Assign firewall-zone: wan
  4. [Save & Apply]

手順1-2) RA や DHCPv6 を LAN 側にリレーするように設定する

  1. OpenWrt に ssh でログイン
  2. /etc/config/dhcpを以下のように編集
> vi /etc/config/dhcp
  :
config dhcp 'lan'  
  :
        option dhcpv6 'relay'
        option ra 'relay'
        option ndp 'relay'
  :
config dhcp 'wan6'  
        option dhcpv6 'relay'
        option ra 'relay'
        option ndp 'relay'
        option master '1'
  :
> uci commit /etc/config/dhcp

自分の場合はlanoption master 1がついていたので、その行を削除しなければならなかった。

手順1-3) WAN6を接続

  1. [Network] – [Interfaces]
  2. WAN6で[Connect]をクリック

接続確認

  1. https://test-ipv6.com/にアクセスし、IPv6 アドレスで通信できていることを確認。

MAP-EでIPv4接続

MAP-EとはIPv4パケットをIPv6パケットにカプセル化してJPNEに送り、JPNEがカプセル化を解いてインターネットに送る、受信も同じくIPv6にカプセル化されたものをJPNEから受信する、という仕組みのようだ。 参照

つまりMAP-EとはクライアントとJPNEの間でトンネルを貼るということみたい。なんとなくわかった。

手順2-1) MAP-Eの手動計算

ちょっとここでMAP-Eのマッピングルールを計算してみる。急ぐ人は飛ばしてください。

計算方法は下記サイトを参考にした。ありがとうございます。(2409240bの誤りと思われる)

https://gato.intaa.net/archives/13173

ここまでで以下の値が手元にある。正しく設定するとこのIPv4アドレスで接続できるはずだ。

名前 説明
IPv6Prefix DHCPv6で発行されたIPv6プレフィックス。WAN6のIPv6アドレスの欄に表示される。 240b:253:cccc:dddd:eeee:ffff:gggg:hhhh/64
IPv6Addr DHCPv6で発行されたIPv6アドレス。 240b:253:cccc:dddd:iiii:jjjj:kkkk:llll
CE MAP-Eで計算したCEアドレス 240b:253:cccc:dddd:mmmm:nnnn:oooo:pppp
IPv4Addr MAP-Eで計算したIPv4アドレス xxx.xxx.xxx.xxx

手順2-2) MAP-Eの各パラメータを計算

下記の計算ツールでMAP-Eの各パラメータを計算する。「IPv6 プレフィックスかアドレスを入力」にIPv6Prefix(WAN6のIPv6アドレス)を入力して計算ボタンを押す。

http://ipv4.web.fc2.com/map-e.html

計算した結果は次項で使う。

手順2-3) mapパッケージのインストール

opkg update
opkg install map

余談だが以下のコマンドを実行するとIPv4アドレスなどを計算できる。値は各自置き換えること。

LEGACY=1 mapcalc * type=map-e,ipv6prefix=240b:252::,prefix6len=31,ipv4prefix=xxx.xxx.xxx.xxx,prefix4len=15,psidlen=8,offset=4,ealen=25

手順2-4) map.shの編集

  1. OpenWrt に ssh でログイン
  2. /lib/netifd/proto/map.shをviで開き#export LEGACY=1のコメントを外す

手順2-5) MAP-Eインターフェースを作成

MAP-E用のインターフェースを作成する。

  1. OpenWrt の Web UI にログインする
  2. [Network] – [Interfaces] - [Add new interface…]
    • General Setup
      • Name of the new interface: wan6_map (何でも良い)
      • Protocol of the new interface: MAP / LW4over6
  3. [Submit]
  4. [Network] – [Interfaces] - [WAN6_MAP] - [Edit]
    • General Setup
      • Type: MAP-E
      • BR / DMR / AFTR: 2404:9200:225:100::64 (JPNEのBRアドレス)
      • IPv4 prefix: 上記サイトで計算したoption ipaddrの値
      • IPv4 prefix length: 上記サイトで計算したoption ip4prefixlenの値
      • IPv6 prefix: 上記サイトで計算したoption ip6prefixの値
      • IPv6 prefix length: 上記サイトで計算したoption ip6prefixlenの値
      • EA-bits length: 上記サイトで計算したoption ealenの値
      • PSID-bits length: 上記サイトで計算したoption psidlenの値
      • PSID offset: 上記サイトで計算したoption offsetの値
    • Advanced Settings
      • Tunnel Link: wan6
    • Firewall Settings
      • Create / Assign firewall-zone: wan
  5. [Save & Apply]

手順2-6) WAN6の設定

  1. OpenWrt の Web UI にログインする
  2. [Network] – [Interfaces]
  3. WAN6というインターフェースがあるので[Edit]をクリック。(WAN6がなければ作る)
    • General Setup
      • Request IPv6-prefix of length: disabled (automaticだとログにeth1: link downとか出て通信が定期的に途切れる。意味はよくわかってない 間違い。詳細は最後に記載した。結局これの必要性は分からないが設定している。)
    • Advanced Settings
      • Custom delegated IPv6-prefix: WAN6のIPv6アドレスと同じ値か、mapcalcの計算結果のRULE_1_IPV6PDの値に/56を付与した文字列(例:240b:253:cccc:dddd::/56)を設定。どちらでも問題ないと思うが自分は後者を設定した。
  4. [Save & Apply]

手順2-7)option encaplimitの設定

  1. OpenWrt に ssh でログイン
  2. /etc/config/networkを以下のように編集
> vi /etc/config/network
  :
config interface 'wan6_map'
  :
        option encaplimit 'ignore'
  :
> uci commit /etc/config/network

※これで5時間ハマった。これがないとWAN6_MAPのTXはカウントされてもRXはカウントされないという状態になる。おそらくパケットが壊れた状態になると思われる。下記の記事と同じ現象と思う。

https://emeth.jp/diary/?p=370

手順2-8) WAN6_MAPを接続

いよいよ接続です。

  1. [Network] – [Interfaces]
  2. WAN6_MAPの[Connect]をクリック

接続確認

  • WAN6_MAPの状態のIPv4の項にMAP-Eで計算したIPv4アドレスが表示されることを確認
  • OpenWrtのインターフェース一覧に、トンネル用のインターフェース(Virtual dynamic interface (Static address))が自動的に追加され、IPv6の項にCEアドレスが表示されることを確認
  • https://test-ipv6.com/にアクセスし、管理されたトンネルメカニズム(6RD)を使用してIPv4経由でIPv6を転送しているようです。と表示されることを確認。
  • https://kakunin.net/kun/にアクセスし、プロバイダー名に*****.enabler.ne.jpと表示されることを確認。

システムログにLocal address not yet configured!と出る

推測だが、Local address not yet configured!は接続開始時にまだローカルアドレスが定まっていないために起こる一時的なエラーと思われる。接続後は発生しないようだ。

設定ファイル

最後に自分の設定ファイルからwan6wan6_mapの設定値を貼っておく。

/etc/config/network

config interface 'wan6'
        option proto 'dhcpv6'
        option reqaddress 'try'
        option ifname 'eth1'
        option reqprefix 'no'
        option ip6prefix '240b:253:cccc:dddd::/56'

config interface 'wan6_map'
        option proto 'map'
        option type 'map-e'
        option peeraddr '2404:9200:225:100::64'
        option ipaddr 'xxx.xxx.xxx.xxx'
        option ip4prefixlen '15'
        option ip6prefix 'aaaa:bbbb::'
        option ip6prefixlen '31'
        option ealen '25'
        option psidlen '8'
        option offset '4'
        option encaplimit 'ignore'
        list tunlink 'wan6'

速度計測

下記サイトで夜9時半に90Mbps程。いままではこの時間は3Mbpsとかだったので劇的改善である。しかもレイテンシも15msとか上出来な値。昼間は100Mbps。旧ISPでは昼間は250Mbpsとかでてたので負けてるが、最大速度よりも一定速度が常に出るほうがありがたい。

https://fast.com/ja/

MAP-Eはルーターへの負荷が高いとのことなので、完全に推測だがルーターの処理能力がボトルネックになっているのかもしれない。

SNATを240ポート使えるように調整

しばらく使っているとポート不足により通信できない状態になった。

iptables -t nat -L -vで見ると最初のポートブロックしか使われていない。
下記サイトの通り設定するとうまく分散できた。

https://gist.github.com/anonymous/0fdec75fa20a7f1ce4806391d6b0429b

手順3-1) iptables-mod-ipoptをインストール

opkg update
opkg install iptables-mod-ipopt

手順3-2) firewall.userを編集

  1. /etc/firewall.userを以下のように編集
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet  0 -j MARK --set-mark 10
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet  1 -j MARK --set-mark 11
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet  2 -j MARK --set-mark 12
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet  3 -j MARK --set-mark 13
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet  4 -j MARK --set-mark 14
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet  5 -j MARK --set-mark 15
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet  6 -j MARK --set-mark 16
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet  7 -j MARK --set-mark 17
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet  8 -j MARK --set-mark 18
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet  9 -j MARK --set-mark 19
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet 10 -j MARK --set-mark 20
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet 11 -j MARK --set-mark 21
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet 12 -j MARK --set-mark 22
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet 13 -j MARK --set-mark 23
iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet 14 -j MARK --set-mark 24

iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet  0 -j MARK --set-mark 10
iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet  1 -j MARK --set-mark 11
iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet  2 -j MARK --set-mark 12
iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet  3 -j MARK --set-mark 13
iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet  4 -j MARK --set-mark 14
iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet  5 -j MARK --set-mark 15
iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet  6 -j MARK --set-mark 16
iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet  7 -j MARK --set-mark 17
iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet  8 -j MARK --set-mark 18
iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet  9 -j MARK --set-mark 19
iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet 10 -j MARK --set-mark 20
iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet 11 -j MARK --set-mark 21
iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet 12 -j MARK --set-mark 22
iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet 13 -j MARK --set-mark 23
iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --packet 14 -j MARK --set-mark 24

手順3-3) map.shを編集

  1. /lib/netifd/proto/map.shを以下のように編集
#$ diff -c /lib/netifd/proto/map.sh.orig /lib/netifd/proto/map.sh

*** 135,140 ****
--- 135,141 ----
  	      json_add_string snat_ip $(eval "echo \$RULE_${k}_IPV4ADDR")
  	    json_close_object
  	  else
+     	local mark=10
  	    for portset in $(eval "echo \$RULE_${k}_PORTSETS"); do
                for proto in icmp tcp udp; do
  	        json_add_object ""
***************
*** 142,152 ****
--- 143,155 ----
  	          json_add_string target SNAT
  	          json_add_string family inet
  	          json_add_string proto "$proto"
+ 	          json_add_string mark "$mark"
                    json_add_boolean connlimit_ports 1
                    json_add_string snat_ip $(eval "echo \$RULE_${k}_IPV4ADDR")
                    json_add_string snat_port "$portset"
  	                json_close_object
              done
+             mark=`expr $mark + 1`
  	    done
  	  fi
  	  if [ "$type" = "map-t" ]; then

確認

iptables -t nat -L -vですべてのポートブロックが使われていることを確認。

雑感

IPoEによる混雑の解消効果は素晴らしいし満足しているが、OpenWrtでのMAP-E設定はかなり敷居が高い。OpenWrtによるMAP-Eの動作はまだ自分の中で不安があるので、しばらく様子を見たいと思う。

しばらく運用していると、以下のようなログが出てリンクが切れることが頻発した。頻度としては通信しているとランダムに発生し、数時間発生しないときもあれば連続で発生するときもある。ただし再現性がないので確実に発生させる手順は不明。

eth1: link down
ar71xx: pll_reg 0xb8050014: 0x110000

発生すると数十秒で復帰するが、正直通常使用できる状態ではない。ネットを探しても同じような問題はいくつかあるが解決しなかった。これは困った。
こりゃ素直にv6プラス対応ルーター買うかと思って実際にWSR-1166DHPL/Nを注文した。この問題で何日も費やすリスクを考えたら5000円出して金で解決できるなら安いもんだ。

[asin:B07ZGTF6VL:detail]

注文した後、IPoEは使えないと思ってPPpoEだけで運用していたが、それでも発生することに気づいた!!これは。。。そういえば今回の作業にあたってOpenWrtを最新にバージョンアップしていたが、それが原因かもと思い、元のバージョンにダウングレードしてみることにした。1つ前の18.06.4にしてみたがダメ。たしかもともとは18.06.1だったと思いそれに戻すと見事に治った。いまのところ4日間元気に稼働中。

ということで新しいルーターは無駄になってしまった。。

2019/12/27 追記 新しいルーターに移行しました

6日目に再発しました。

どうやらハードに問題があるみたい。

https://forum.openwrt.org/t/archer-c7v4-random-eth0-link-down/20740/11

回避するパッチは存在するようだが、手元に新しいルーターがある以上、これ以上コイツの問題に付き合うつもりはない。ということで新しいルーターに移行することにしました。

ここで新しいルーターの設定方法は説明しないが、設定の所要時間は3分だった。「v6プラスを使用する」を選んで設定保存するだけ。かんたんすぎる。。

改めて速度計測してみると、なんと昼間で300Mbps、夜9時頃でも260Mbps出る。レイテンシは15msと変わらず。やはりハードの性能がネックになっているのかもしれない。

新しいルーターはいまのところ3日間ほどネットも無線も問題なく稼働している。またなにかあれば報告する。