で引き続きその2。分けたことに余り意味はない。っていうかあまりにいろいろ貼ってたら長くなって来たので途中で一息つきたかっただけですにょ。おほほ。
wide-dhcpv6c(wide-dhcpv6-client)とradvdについては、前出の"Memo - OCN IPv6"と変わる所はありません。そのまま持って来て通ります。
http://www.ln-lab.net/lunar-night.lab/page2-memo_ocnipv6/design-white/lang-ja
Memo - OCNIPv6
# /etc/wide-dhcpv6/dhcp6c.conf
interface ppp2 {
send ia-pd 0;
};
id-assoc pd 0{
prefix-interface eth0 {
sla-id 1;
sla-len 0;
};
};
# /etc/radvd.conf
interface eth0
{
AdvSendAdvert on;
MinRtrAdvInterval 30;
MaxRtrAdvInterval 100;
prefix 2001:380:aaaa:bbbb::/64
{
AdvOnLink on;
AdvAutonomous on;
};
};
wide-dhcpv6-clientを起動して、まず指定のインタフェイスにOCNから指定されたprefixでv6アドレスが付くことを確認しましょう。prefixが"2001:380:aaaa:bbbb"だとしたらこのようになっているはずです。
hironobu@nelly:~$ /sbin/ifconfig
eth0 Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx
inet addr:192.168.0.1 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: 2001:380:aaaa:bbbb:xxxx:xxxx:xxxx:xxxx/64 Scope:Global
inet6 addr: fe80::xxxx:xxxx:xxxx:xxxx/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:20969 errors:0 dropped:0 overruns:0 frame:0
TX packets:22630 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3654118 (3.4 MiB) TX bytes:15726726 (14.9 MiB)
Interrupt:252 Base address:0xe000
さらにradvdを起動して、RA(Router Advertisement)が同セグメントの他のPCに配信され、inet6アドレスが付くのを確認します。
hironobu@shirley:~$ /sbin/ifconfig
eth0 Link encap:Ethernet HWaddr zz:zz:zz:zz:zz:zz
inet addr:192.168.0.2 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: 2001:380:aaaa:bbbb:zzzz:zzzz:zzzz:zzzz/64 Scope:Global
inet6 addr: fe80::zzzz:zzzz:zzzz:zzzz/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:98633 errors:0 dropped:0 overruns:0 frame:0
TX packets:60699 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:87034901 (83.0 MiB) TX bytes:6714585 (6.4 MiB)
Interrupt:16 Base address:0x2400
ちなみにnellyがルータで、shirleyは同セグメント上のサーバです。ここまで確認してOKであれば、ipv6用のルーティングを登録します。
# ip -f inet6 route add default dev ppp2
$ ip -f inet6 route
2001:380:aaaa:bbbb::/64 dev eth0 metric 256 mtu 1500 advmss 1440 hoplimit 4294967295
fe80::/64 dev eth1 metric 256 mtu 1500 advmss 1440 hoplimit 4294967295
fe80::/64 dev eth0 metric 256 mtu 1500 advmss 1440 hoplimit 4294967295
fe80::/64 dev ppp2 metric 256 mtu 1390 advmss 1330 hoplimit 4294967295
fe80::/10 dev ppp2 metric 1 mtu 1390 advmss 1330 hoplimit 4294967295
fe80::/10 dev ppp2 metric 256 mtu 1390 advmss 1330 hoplimit 4294967295
default dev ppp2 metric 1024 mtu 1390 advmss 1330 hoplimit 4294967295
こうすることでipv6パケットがppp2インタフェイスを通じて外に出て行くようになります。早速ping6してみましょう。
hironobu@shirley:~$ ping6 www.ocnipv6.jp
PING www.ocnipv6.jp(www.ocnipv6.jp) 56 data bytes
64 bytes from www.ocnipv6.jp: icmp_seq=1 ttl=54 time=17.0 ms
64 bytes from www.ocnipv6.jp: icmp_seq=2 ttl=54 time=17.7 ms
64 bytes from www.ocnipv6.jp: icmp_seq=3 ttl=54 time=16.3 ms
64 bytes from www.ocnipv6.jp: icmp_seq=4 ttl=54 time=16.8 ms
64 bytes from www.ocnipv6.jp: icmp_seq=5 ttl=54 time=17.5 ms
hironobu@shirley:~$ traceroute6 www.ocnipv6.jp
traceroute to www.ocnipv6.jp (2001:218:2001:3005::7f), 30 hops max, 40 byte packets
1 2001:380:aaaa:bbbb:xxxx:xxxx:xxxx:xxxx (2001:380:aaaa:bbbb:xxxx:xxxx:xxxx:xxxx) 0.168 ms 0.162 ms 0.184 ms
2 2001:380:8140::a (2001:380:8140::a) 16.904 ms 16.969 ms 17.010 ms
3 2001:380:8140:9::1 (2001:380:8140:9::1) 17.050 ms 17.186 ms 17.353 ms
4 2001:380:8130:3::1 (2001:380:8130:3::1) 17.067 ms 17.177 ms 17.385 ms
5 2001:380:8130:12::4 (2001:380:8130:12::4) 17.594 ms 17.430 ms 17.617 ms
6 2001:380:8230:f::2 (2001:380:8230:f::2) 17.348 ms 16.086 ms 16.258 ms
7 ae-0-1.a20.tokyjp01.jp.ra.gin.ntt.net (2001:218:2000:5000::49) 16.339 ms 14.535 ms 14.307 ms
8 ae-7.r20.tokyjp01.jp.bb.gin.ntt.net (2001:218:0:6000::185) 13.996 ms 14.411 ms 14.337 ms
9 2001:218:0:6000::52 (2001:218:0:6000::52) 17.269 ms 17.430 ms 17.303 ms
10 (2001:218:2001:17::2) 17.715 ms 17.330 ms 17.749 ms
11 www.ocnipv6.jp (2001:218:2001:3005::7f) 17.763 ms 18.246 ms 17.849 ms
接続できましたにょ。
さて残る問題は、前回のxl2tpdも含めて、「OS起動時にどうするか」です。上に述べたようにxl2tpdに名前付きパイプへのechoを使ってxl2tpdへの操作を行いますが、これを/etc/init.d/*でやりたいですよね。Linuxルータを再起動したら何もせずとも自動的にipv6リンクも立ち上がっているようになるのが理想的です。
hironobu@nelly:~$ ls -l /etc/rc*/*xl2tpd
lrwxrwxrwx 1 root root 16 2010-04-10 01:02 /etc/rc0.d/K20xl2tpd -> ../init.d/xl2tpd
lrwxrwxrwx 1 root root 16 2010-04-10 01:02 /etc/rc1.d/K20xl2tpd -> ../init.d/xl2tpd
lrwxrwxrwx 1 root root 16 2010-04-10 01:02 /etc/rc2.d/S20xl2tpd -> ../init.d/xl2tpd
lrwxrwxrwx 1 root root 16 2010-04-10 01:02 /etc/rc3.d/S20xl2tpd -> ../init.d/xl2tpd
lrwxrwxrwx 1 root root 16 2010-04-10 01:02 /etc/rc4.d/S20xl2tpd -> ../init.d/xl2tpd
lrwxrwxrwx 1 root root 16 2010-04-10 01:02 /etc/rc5.d/S20xl2tpd -> ../init.d/xl2tpd
lrwxrwxrwx 1 root root 16 2010-04-10 01:02 /etc/rc6.d/K20xl2tpd -> ../init.d/xl2tpd
このxl2tpdが起動されたあとに、できるだけすぐにecho "c ocnipv6" > /var/run/xl2tpd/l2tp-controlを送りたい訳です。私が採った手は、このxl2tpdのすぐ後に起動するinitスクリプトを登録してやることです。下のようなスクリプトを作成し、まず/etc/init.d/ipv6として配置します。
#!/bin/sh
### BEGIN INIT INFO
# Provides: ipv6
# Required-Start: $remote_fs $network $syslog
# Required-Stop: $remote_fs $network $syslog
# Should-Start: $local_fs slapd
# Should-Stop: $local_fs slapd
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: IPv6 service
# Description: (empty)
### END INIT INFO
. /lib/lsb/init-functions
NAME="ocnipv6"
L2TPC="/var/run/xl2tpd/l2tp-control"
CMAX=10
do_start() {
C=0;
while [ ! -p $L2TPC ] && [ $C -lt $CMAX ]; do
sleep 1;
log_progress_msg '.';
let C=C+1;
done
if [ $C -lt $CMAX ]; then
echo "c $NAME" > $L2TPC
return 0
else
return 1
fi
}
do_end() {
echo "d $NAME" > $L2TPC
return 0
}
case "$1" in
start)
log_daemon_msg "Starting ipv6"
if do_start; then
log_end_msg 0
else
log_end_msg 1
exit 1
fi
;;
stop)
log_daemon_msg "Stopping ipv6"
do_end
log_end_msg 0
;;
restart)
log_daemon_msg "Restarting ipv6"
do_end
sleep 3
if do_start; then
log_end_msg 0
else
log_end_msg 1
exit 1
fi
;;
esac
exit 0
次に、update-rc.dを使って登録しますが、ランレベル2-5ではS21、同0-1,6ではK19になるようにします。つまり、起動時(2-5)ではxl2tpdの直後、終了時(0-1,6)ではxl2tpdの直前に、上のスクリプトを呼ぶ訳です。こうしないと、xl2tpdが起動しないうちに/var/run/xl2tpd/l2tp-controlをさわろうとするものの、当然起動前ならこのパイプは存在しないので、失敗することになるためです。
# update-rc.d ipv6 start 21 2 3 4 5 . stop 19 0 1 6 .
hironobu@nelly:~$ ls -l /etc/rc*/*ipv6
lrwxrwxrwx 1 root root 14 2010-04-10 01:26 /etc/rc0.d/K19ipv6 -> ../init.d/ipv6
lrwxrwxrwx 1 root root 14 2010-04-10 01:26 /etc/rc1.d/K19ipv6 -> ../init.d/ipv6
lrwxrwxrwx 1 root root 14 2010-04-10 01:26 /etc/rc2.d/S21ipv6 -> ../init.d/ipv6
lrwxrwxrwx 1 root root 14 2010-04-10 01:26 /etc/rc3.d/S21ipv6 -> ../init.d/ipv6
lrwxrwxrwx 1 root root 14 2010-04-10 01:26 /etc/rc4.d/S21ipv6 -> ../init.d/ipv6
lrwxrwxrwx 1 root root 14 2010-04-10 01:26 /etc/rc5.d/S21ipv6 -> ../init.d/ipv6
lrwxrwxrwx 1 root root 14 2010-04-10 01:26 /etc/rc6.d/K19ipv6 -> ../init.d/ipv6
さらに、スクリプト内でもパイプの生成を待つようにしています。上の例では10回=10秒間待ちますが、CMAXをいじれば調整可能です。
あとはルーティングですが、これはpppdを利用します。ipv6でのリンクが確立すると、pppdは/etc/ppp/ipv6-upおよび/etc/ppp/ipv6-up.d/*のスクリプトを起動しようとします。これを利用して、/etc/ppp/ipv6-up.d/routeスクリプトを下のように設置します。
#!/bin/sh
if [ "x$PPP_IFACE" = "xppp2" ]; then
ip -f inet6 route add default dev $PPP_IFACE
/etc/init.d/wide-dhcpv6-client restart
fi
また、/etc/ppp/ipv6-down.dディレクトリにも同じようにrouteスクリプトを置きます。
#!/bin/sh
if [ "x$PPP_IFACE" = "xppp2" ]; then
ip -f inet6 route del default dev $PPP_IFACE
fi
wide-dhcpv6-clientにrestartを掛けている点に注意してください。ipv6スクリプトによってppp2がlink upを開始しますが、その完了を待たずにwide-dhcpv6-clientが起動されてしまうのです。ppp2のリンクが完了したタイミングでもう一度wide-dhcpv6-client
lrwxrwxrwx 1 root root 15 2010-04-07 05:17 S20rsync -> ../init.d/rsync
lrwxrwxrwx 1 root root 16 2010-04-11 00:02 S20xl2tpd -> ../init.d/xl2tpd
lrwxrwxrwx 1 root root 14 2010-04-10 01:26 S21ipv6 -> ../init.d/ipv6
lrwxrwxrwx 1 root root 28 2010-04-05 23:20 S40wide-dhcpv6-client -> ../init.d/wide-dhcpv6-client
これによって、起動後自動的にipv6リンクの確立とルーティングが行われるようになります。