前回の続き。
実験環境は、RAでIPv6のアドレスが来る環境。6lowpan で繋がるデバイスには nRF51 IoT SDK でもやっているように radvd でアドレスを渡してみたい。お約束のように eth0 が上位回線側につながっている。Linux kernel 4.0.9。
radvd は上位から渡された RA と同じ空間を、そのまま 6lowpan 側に与えてアドレスを採番して、nexthop/neighbor で経路制御する方向。
router 側と host 側の二つにパートが分かれる。bluetooth のアドレスは、例として host 側 88:77:66:55:44:33 と router 側 00:11:22:33:44:55 を使っている。
host 側
素朴に bluetooth の準備をしておく。
modprobe bluetooth_6lowpan
echo 1 > /sys/kernel/debug/bluetooth/6lowpan_enable
hciconfig hci0 up leadv
router 側
echo 2 > /proc/sys/net/ipv6/conf/eth0/accept_ra
ipv6 の forwarding を 1 にすると ::/0 の経路が毎回消えて、困っていたのだけれど、実は accept_ra に 2 を設定できるらしい。そうすると上位から来たRAの経路がそのまま使える。ちゃんとドキュメントにも書いてあるけど、最初気が付かない。
echo 1 > /proc/sys/net/ipv6/conf/default/forwarding
echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
forwarding は all に対して有効にして、forwarding したくないものは個別に netfilter で設定しろ、という記事も見かけたけど、本当かなぁ。とりあえず攻撃を受けるような環境ではないので、そのまま。
echo 1 > /proc/sys/net/ipv6/conf/default/proxy_ndp
echo 1 > /proc/sys/net/ipv6/conf/all/proxy_ndp
上位ルータから host 側の戻りパケットを router 側が吸い込めるように proxy_ndp を使う。(*2)
/etc/radvd.conf はとりあえず nRF51 IoT SDK と同じで、prefix だけ与えられたものに変更しておく。
systemctl start radvd
そして bluetooth 6lowpan の接続。
modprobe bluetooth_6lowpan
echo 1 > /sys/kernel/debug/bluetooth/6lowpan_enable
hciconfig hci0 up
hcitool lescan # address 確認
echo "connect 88:77:66:55:44:33 1" > /sys/kernel/debug/bluetooth/6lowpan_control
ip link
接続できたら bt0 という netdev が見えるようになっているはず。
host 側
こちら側にも bt0 というインターフェースができていて、アドレスが付いていることを確認する。アドレスは link local である fe80::8a77:66ff:fe55:4433 と、global scope の <some_prefix>:8a77:66ff:fe55:4433 の両方がついているはず。
link local での疎通を確認しておく。
ping6 -I bt0 fe80::211:22ff:fe33:4455
router 側
まだこの辺は自動化する方法がよく分かっていない…。(*1)
bt0 には global アドレスが振られていないので、手作業で与えておく(無くてもよい)。与えるべきアドレスは fe80:: を読み替えたもの、と考えれば簡単。EUI-64 (= ff:fe を差し込んで、mac address 7 bit 目の global/local のフラグを立てる)が下 64 bit になる。
ip -6 addr add <some_prefix>:211:22ff:fe33:4455 dev bt0
経路情報を手作業で入れる。
route -A inet6 add <some_prefix>:211:22ff:fe33:4455 dev bt0
ip -6 neigh add proxy <some_prefix>:211:22ff:fe33:4455 dev eth0
注意点としては、ip neigh は proxy とそうじゃないものの二つがあるという点。
ip neigh show
ip neigh show proxy
host 側
どこか外のホストに対して ping6 が通るか確認。
メモ
route -A inet6 add <some_prefix>:211:22ff:fe33:4455 dev bt0 の代わりに、
ip -6 neigh add <some_prefix>:211:22ff:fe33:4455 lladdr 02:11:22:ff:fe:33:44:55 dev bt0 で行けそうな気がしたけど、ダメだった。理由は不明。
追記
(*1)について。今の Linux の実装だと 6lowpan 用のオプションが未実装の様子。RFC 6775 ND Optimization for 6LoWPAN にある NS message の ARO(Address Registration Option)で自動化するということのようだ。
(*2)について。eth0 だけでよい。