FreeBSDルーターでDS-Lite

前回はIPoE開通までだったので、今回はDual-Stack Lite (以下DS-Lite)でIPv4 over IPv6なトンネルを作成して名前通りデュアルスタックな状態にする。

先ずはIPv4のLANを作る。もちろん既に存在するなら新たに作る必要はない。

/etc/rc.conf (IPv4 LAN側アドレス設定部分のみ)
1
2
network_interfaces="lo0 em1"
ifconfig_em1="inet 192.168.0.1 netmask 255.255.255.0"

em1はLAN側のNIC。上では192.168.0.0/24なネットワークでルーターのLAN側IPアドレスを192.168.0.1とした。

次が本題。
IPv4 over IPv6なトンネルを作成する。
トンネルというからには「何処から」「何処に」が肝心。トンネルの入口と出口ね。DS-Liteの設定ではこれが解ってないと話にならない。
DS-LiteではCPE(ユーザー側ルーター機器など)のBasic Bridging BroadBand(B4)の「WAN側IPv6アドレス」から相手先はVNE(ISP)のAddress Family Transition Router (AFTR)のIPv6アドレスとなる。
で、So-netの場合はSo-netのAFTRというのは存在せず、So-netから依頼されてIPoE,DS-Liteの提供を行っているVNEインターネットマルチフィードのTransixサービスのAFTRとなる。So-netは完全に丸投げしているので情報の取得もインターネットマルチフィード/Transixのウェブサイトからとなるのだけど、残念ながらそっけないというか何も知らない人はどうしろっていうの?っていう程度の情報しかない。
取り敢えず、「DS-Lite 接続確認機種情報」の「Cisco 1812J」向け説明ページを見るとAFTRの情報が載っている。

フレッツ回線を契約した方の地域のNTTから2つあるどちらか1つを好みで選ぶ。

  • NTT東日本エリア
    • 2404:8e00::feed:100
    • 2404:8e00::feed:101
  • NTT西日本エリア
    • 2404:8e01::feed:100
    • 2404:8e01::feed:101

2017年3月31日現在の情報 (変更される可能性があるので注意)

FreeBSDの場合はトンネルデバイスにはGIF (generic tunnel interface)を使用(作成)する。
そして、トンネルの入口/出口の指定を行い、GIFインターフェースを起動し、ルーティング(IPv4のデフォルトのルートがあるならば消して新たにトンネルデバイスのインターフェースに向ける)を行う。

手動だと以下。

# ifconfig gif0 create
# ifconfig gif0 inet6 tunnel  WAN側IPv6アドレス  AFTRのアドレス  prefixlen 128
# ifconfig gif0 up
# route delete default
# route add default -iface gif0
# sysctl net.inet.ip.forwarding=1

DS-Liteのユーザー側B4はトンネリング(カプセル化)とそこにパケットを向けるルーティング追加だけという非常に簡単なものなので、ここまでで一応DS-Liteで通信出来ている筈。
ただし、LAN内の端末全てで個別に手動で名前解決の設定を入れているのでなければ使えないなどトラブる筈。
LAN内の端末がIPv4とIPv6の両方で正常に名前解決できるようDHCP等の整備も忘れずに。(重要)

関連記事: FreeBSD mpd5でIPv6接続 (PPPoE) その3

正常に動いたら上で手動でやったのを設定ファイルに書く。

/etc/rc.conf
1
2
3
4
cloned_interfaces="gif0"
ipv6_ifconfig_gif0="tunnel WAN側IPv6アドレス AFTRのアドレス prefixlen 128 mtu 1500"
defaultrouter="-iface gif0"
gateway_enable="YES"

2行目は最後の部分MTU未指定だと勝手に1280になるみたい。
4行目は sysctl net.inet.ip.forwarding=1 と同じ。

GIF関係は/etc/rc.confへの設定の書き方がFreeBSD10から完全に変わってて、しかも古い書き方は受け付けてくれないみたい。なまじ古い書き方の方を覚えていたもんだから今回ここでどエラく躓いた。手動コマンド打ちの方は(以前とコマンドが変わってないから)上手くいったが/etc/rc.confに書くと動いてくれないの何で?みたいな。簡単だからと高を括ってたら大失敗。

とはいえ、既にIPv4なLANがあれば設定4行追加でいけるというのだから簡単は簡単。
ファイアウォールで悩むかもだけど。

システムを再起動して正常に動くことを確認。

ipv6 test
http://ipv6-test.com/speedtest/でテストしてみる。
当然だけどIPv4, IPv6の両方がテスト出来なければおかしい。また、上の画像のようにISPの項目の表示名がTransixとかMf-native6*のようになる筈。ここがSo-netとかになってたらPPPoEで繋がってる。

IPoE, DS-Liteと同時に従来のPPPoEのIPv4,IPv6も使えるのでDS-Liteにしたら外から自宅のネットワークに繋げなくなるのが困るという場合でも大丈夫。もちろん設定は必要。

あと、DS-LiteはISPでNATをやってると聞くと、LAN内で自分でIPv4アドレス勝手に割り振るんじゃなくてISPから与えられたIPアドレスを使わなきゃならないんじゃないかと思っちゃたりする?けど、上みたいな感じなので既にLANで環境がある場合も一安心。

関連記事:

NanoPi NEOの時刻のズレを直したい

時計

5つ前のPPSの記事でやったようなことで普通のPCならPPSを時刻ソースとしてNTPサーバが一応正常に動く筈なんだけど、NanoPi NEOだと数分でNMEAとPPSの両方の同期が切れてしまう。
でも、ネットワーク上の他のNTPサーバとの同期は切れないんだよなぁ。そこが解せん。
何故かなと調べてたらRTCの時刻のズレ方がとんでもない凄さ。使用中なら20分で5分、アイドル状態放置でも8時間で45分ほどズレてしまう。RTCの時刻を表示する度にどんどんズレてくのでウワァって感じ。カーネルビルドのオプション指定間違えてるのだろうか?

# ppswatch -a /dev/pps0
trying PPS source "/dev/pps0"
found PPS source "/dev/pps0"
timestamp: 1490575231, sequence: 37551, offset:  1276715
timestamp: 1490575232, sequence: 37552, offset:  1279569

眺めているとoffsetの値が急激に増大または減少する。さらには増大してるかと思ったら突然減少に反転、或いはその反対ということも起こる。これはおかしい?
RTCを狂わせてる原因は何かしら?

$ lsmod
Module                  Size  Used by
cfg80211              192770  0 
bluetooth             263753  0 
rfkill                 10928  2 bluetooth,cfg80211
evdev                   9979  0 
sun8i_ths               3134  0 
gpio_keys               8517  0 
cpufreq_dt              3522  0 
uio_pdrv_genirq         3354  0 
uio                     8012  1 uio_pdrv_genirq
thermal_sys            43232  2 cpufreq_dt,sun8i_ths
pps_gpio                2897  1 
g_serial                3737  0 
libcomposite           34692  1 g_serial
fuse                   70718  1 

どう見てもcfg80211やbluetoothなど幾つかは要らない。
そこで /etc/modprobe.d/fbdev-blacklist.conf に追記

1
2
3
blacklist bluetooth
blacklist cfg80211
blacklist evdev
# systemctl list-unit-files
UNIT FILE                                  STATE
中略
bluetooth.service                          enabled
中略
dbus-org.freedesktop.nm-dispatcher.service enabled
中略
fake-hwclock.service                       enabled
後略

こいつらも停めてしまうことにする。

# systemctl stop bluetooth.service
# systemctl disable  bluetooth.service
# systemctl stop dbus.service
# systemctl disable dbus.service
# systemctl stop fake-hwclock.service
# systemctl disable fake-hwclock.service

さて、一番アヤシイのはCPUのクロックがコロコロ変わること。これを固定させたい。
まずは状態を確認。

$ cpufreq-info
cpufrequtils 008: cpufreq-info (C) Dominik Brodowski 2004-2009
Report errors and bugs to cpufreq@vger.kernel.org, please.
analyzing CPU 0:
  driver: cpufreq-dt
  CPUs which run at the same hardware frequency: 0 1 2 3
  CPUs which need to have their frequency coordinated by software: 0 1 2 3
  maximum transition latency: 4.24 ms.
  hardware limits: 120 MHz - 1.01 GHz
  available frequency steps: 120 MHz, 240 MHz, 312 MHz, 480 MHz, 624 MHz, 816 MHz, 1.01 GHz
  available cpufreq governors: conservative, ondemand, userspace, powersave, performance, schedutil
  current policy: frequency should be within 816 MHz and 816 MHz.
                  The governor "performance" may decide which speed to use
                  within this range.
  current CPU frequency is 816 MHz (asserted by call to hardware).
  cpufreq stats: 120 MHz:0.00%, 240 MHz:0.00%, 312 MHz:0.00%, 480 MHz:0.01%, 624 MHz:0.00%, 816 MHz:97.42%, 1.01 GHz:2.58%  (2)

以下、CPUのコア数分の表示が行われる。

CPUのクロックは120 MHz, 240 MHz, 312 MHz, 480 MHz, 624 MHz, 816 MHz, 1.01 GHzが指定できると書かれているが、1.01GHzは数字を丸めたっぽい。

$ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies
120000 240000 312000 480000 624000 816000 1008000

指定可能な最大のクロックは1008000だ。←指定するときはこの数字でないと弾かれる(というか指定可能などれか近いのになる)

# cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors
conservative ondemand userspace powersave performance schedutil

使用可能なガバナーは6つ、これはcpufreq-infoまたはcpufreq-info -gで表示されるものと同じ。

システム起動中の指定変更にはcpufreq-setを使うということになっているが、システム起動時用の設定ファイルとしては/etc/default/cpufrequtilsが用意されているようだ。

1
2
3
4
ENABLE=true
MIN_SPEED=0
MAX_SPEED=0
GOVERNOR=performance

システムを再起動してみる。

現在の設定を確認する。

# cpufreq-info -p
120000 1008000 performance

表示上は最低クロックが12000最大クロックが1008000となっているが、ガバナーが指定された最大値固定のperformanceなので1008000以外にはならない(ことになっている)。

暫く使った後に本当にクロックが固定されているか確認する。

# cpufreq-info -s
120000:0, 240000:0, 312000:0, 480000:0, 624000:0, 816000:0, 1008000:33629  (1)

1008000以外の使用が0ということなので固定されていると見てよさそう。クロックの後の数字の単位は不明。

1
2
3
4
ENABLE=true
MIN_SPEED=0
MAX_SPEED=816000
GOVERNOR=performance

最大速度を中間の値(816000)で指定してみた。

$ cpufreq-info -s
120000:0, 240000:0, 312000:0, 480000:2, 624000:0, 816000:14583, 1008000:439  (2)

816000以外で動かない筈だが、システム起動中の固定設定になる前に1008000で動いた時間があるようだ。480000にも2というのがあるがこれは無視して良さそう。
もちろん、performanceガバナーが有効になった後は816000以外では動かないはずなのでこの後にcpufreq-info -sで表示すると816000以外では数値は増えない(筈)。

同様にMIN_SPEEDを指定してpowersaveガバナーを使用するとMIN_SPEEDのクロックで固定される。MIN_SPEEDが0なら選択可能な一番低いクロックで固定。

ondemandとconservativeガバナーを選択した場合はクロックの切り替わりの挙動が異なるようだが、どちらも負荷に応じてMIN_SPEEDからMAX_SPEEDの間でクロック可変となる。MIN_SPEEDとMAX_SPEEDを0指定にしていれば選択可能な一番低いクロックから選択可能な一番高いクロックの間で可変。

で、NanoPi NEOのCPU(っていうかH3の)のカタログスペック上の最大値って1.2GHz (1200000)じゃなかったっけ?
以前の記事の古いカーネルでは1.2GHzまで使えたけどカーネル4.10系では2017年3月30日時点では1GHzまでらしい。
もっともクロック最大でブン回すと熱が出るのでこの手のSBCだと寧ろ使用する機能に影響しない範囲で如何に低いクロックを設定するかに苦心するところだろうけど。

さて、CPUクロックを固定してみたが、RTCのズレ具合は改善しただろうか?

全然ダメ

殆ど全くというレベルで改善していない。何だろうCPU動くたびに仕事量に応じてズレてるとしか思えない。

そういえばtimedatectlにRTCをNTPに同期させてくれる機能ってのが付いてたような。

$ timedatectl status
      Local time: Tue 2017-03-30 13:04:38 JST
  Universal time: Tue 2017-03-30 04:04:38 UTC
        RTC time: Tue 2017-03-30 04:04:38
       Time zone: Asia/Tokyo (JST, +0900)
     NTP enabled: no
NTP synchronized: no
 RTC in local TZ: no
      DST active: n/a


# timedatectl set-ntp yes   ←RTCをNTPに同期させる


$ timedatectl status
      Local time: Tue 2017-03-30 13:04:58 JST
  Universal time: Tue 2017-03-30 04:04:58 UTC
        RTC time: Tue 2017-03-30 04:04:57
       Time zone: Asia/Tokyo (JST, +0900)
     NTP enabled: yes
NTP synchronized: yes
 RTC in local TZ: no
      DST active: n/a

表示上はRTCの時刻のズレ方がメチャクチャというのは直った。でも、ぴったり合うというわけでもないみたい。
そして、相変わらずNTPのソースとしてのNMEAとPPSは同期してくれない、もしくは同期してもすぐに切れてそのまま。
やはり見かけじゃない部分でRTC自体がズレていて本来正しい方のNMEAとPPSの時刻を異常と思って同期を切ってると考えるのが正しいよねぇ。でも、他のNTPサーバとの同期は切れないのは何で?
こうなるとRTCモジュールを買ってみるしかない?でも負けたみたいで嫌だなぁ。
引き続き他の対策も考えたい。

関連記事:

Up