Creating frrouting image for GNS3

ゴール：GNS3 向けに alpine linux ベースの frr image を作る。

GNS3 であらかじめ用意されているものは少し古かったので、自前で作る。しかも小さいやつを。

# minimal 版

最初手作業で作っていたけれど、最終的にはこちらのスクリプトに落ち着いた。

`alpine-make-vm-image` というスクリプトを使う。alpine linux 上で次のスクリプトを流す。apline linux には kernel flavor があって、これだと vanilla kernel でなく virt kernel の構成にできて、サイズも 160MB 程度に収まる。

```bash
# 環境は最新のほうがよかろう
apk update
apk upgrade

apk add alpine-make-vm-image
cat > script.sh <<EOS
cat >> /etc/modules <<EOF
mpls_router
mpls_gso
mpls_iptunnel
EOF
cat > /etc/sysctl.d/90-frr.conf <<EOF
net.ipv4.conf.all.forwarding=1
net.ipv6.conf.all.forwarding=1
net.mpls.conf.eth0.input=1
net.mpls.conf.eth1.input=1
net.mpls.conf.eth2.input=1
net.mpls.conf.eth3.input=1
net.mpls.conf.eth4.input=1
net.mpls.conf.eth5.input=1
net.mpls.conf.eth6.input=1
net.mpls.conf.eth7.input=1
net.mpls.platform_labels=100000
EOF
sed -i -e 's/default_kernel_opts="/default_kernel_opts="console=ttyS0/g' /etc/update-extlinux.conf
update-extlinux
sed -i -e 's/^#ttyS0::/ttyS0::/g' /etc/inittab
echo "ttyS0" >> /etc/securetty
sed -i -e 's/=no/=yes/g' /etc/frr/daemons
rc-update add frr.initd default
echo vtysh >> /root/.profile
EOS
chmod +x script.sh
alpine-make-vm-image -f raw -s 160M -p frr -c frr6.img script.sh
```

ところで`alpine-make-vm-image` のソースコードは [github にある](https://github.com/alpinelinux/alpine-make-vm-image/)。github にある `Makefile` は `alpine-make-vm-image` スクリプト自体のもので、イメージを作るものではない。

このスクリプトは apk コマンドを使って、`qemu-nbd` でマウントした領域にファイルを展開する。特定の kernel module を使うので、docker コンテナ内ではビルドできなかったので、alpine linux installer で qemu 環境を作って、その中でイメージを作った。

# ほどほど版

telnet でも入れるようにする

```bash
# 環境は最新のほうがよかろう
apk update
apk upgrade

apk add busybox-extras
apk add alpine-make-vm-image
cat > script.sh <<EOS
cat > /etc/network/interfaces <<EOF
auto lo
iface lo inet loopback
EOF
cat > /etc/inetd.conf <<EOF
telnet stream tcp nowait root /usr/sbin/telnetd telnetd -i -l /bin/login
EOF
rc-update add inetd default
echo "pts/0" >> /etc/securetty
echo "pts/1" >> /etc/securetty
cat >> /etc/modules <<EOF
mpls_router
mpls_gso
mpls_iptunnel
EOF
cat > /etc/sysctl.d/90-frr.conf <<EOF
net.ipv4.conf.all.forwarding=1
net.ipv6.conf.all.forwarding=1
net.mpls.conf.eth0.input=1
net.mpls.conf.eth1.input=1
net.mpls.conf.eth2.input=1
net.mpls.conf.eth3.input=1
net.mpls.conf.eth4.input=1
net.mpls.conf.eth5.input=1
net.mpls.conf.eth6.input=1
net.mpls.conf.eth7.input=1
net.mpls.platform_labels=100000
EOF
sed -i -e 's/default_kernel_opts="/default_kernel_opts="console=ttyS0/g' /etc/update-extlinux.conf
update-extlinux
sed -i -e 's/^#ttyS0::/ttyS0::/g' /etc/inittab
echo "ttyS0" >> /etc/securetty
sed -i -e 's/=no/=yes/g' /etc/frr/daemons
cat > /etc/frr/bgpd.conf <<EOF
debug bgp updates
debug bgp zebra
debug nht
log syslog
EOF
cat > /etc/frr/ldpd.conf <<EOF
debug mpls ldp discovery
debug mpls ldp errors
debug mpls ldp events
debug mpls ldp labels
debug mpls ldp messages recv
debug mpls ldp messages sent
debug mpls ldp zebra
log syslog
EOF
rc-update add frr.initd default
echo vtysh >> /root/.profile
EOS
chmod +x script.sh
alpine-make-vm-image -f raw -s 160M -p frr -p busybox-extras -p tcpdump -c frr6.img script.sh
```

dhcp でアドレスを取るとき

```
udhcpc -i eth0 -f -q
```

# 手作業版

手元が Windows10 だったので、作業環境は次のような構成。Ubuntu / WSL で qemu を実行して、Windows からは UltraVNC で接続する。手元の Windows 10 からは qemu `-k ja` の設定と alpine linux `setup-keymap` を `jp-OADG109A` にすると合致した。


## base install

残念ながら qemu は acceleration 無し。ディスクイメージは 500M だと足りず、1G でインストール。

```
$ qemu-img create frr6.img 1G
$ qemu-system-x86_64 -drive file=frr6.img,format=raw \
    -cdrom alpine-extended-3.8.1-x86_64.iso \
    -netdev user,id=n1 -device virtio-net-pci,netdev=n1 \
    -m 512 -rtc base=utc -k ja \
    -serial mon:stdio -vnc :0
```

cdrom installer の ISOLINUX は `root` でパスワード無しでログインできるように設定されている。`setup-alipine` でインストールする。`poweroff` で終了。次回以降は cdrom 無しでよい。

```
$ qemu-system-x86_64 -drive file=frr6.img,format=raw \
    -netdev user,id=n1 -device virtio-net-pci,netdev=n1 \
    -m 512 -rtc base=utc -k ja \
    -serial mon:stdio -vnc :0
```

## serial console 有効化

GNS3 での「telnet 接続」は qemu VM の serial console 接続になる。

qemu 側でセットアップする際は `-serial mon:stdio` を付ける。

`/boot/extlinux.conf` で `console=ttyS0` 追加し、`/etc/securetty` に `ttyS0` を追加する。

`/etc/inittab` に serial console 用の行がコメントアウトされているので、有効にする。

## frr インストール

`/etc/apk/repositories` でコメントアウトを外して有効にする。`frr` package は `testing` チャンネルに入っている。その後 frr をインストールする。

```
apk add frr

rc-update add frr.initd

cat >> /etc/modules <<"EOF"
mpls_router
mpls_iptunnel
EOF

cat > /etc/sysctl.d/90-frr.conf <<"EOF"
net.ipv4.conf.all.forwarding=1
net.ipv6.conf.all.forwarding=1
net.mpls.conf.eth0.input=1
net.mpls.conf.eth1.input=1
net.mpls.conf.eth2.input=1
net.mpls.conf.eth3.input=1
net.mpls.conf.eth4.input=1
net.mpls.conf.eth5.input=1
net.mpls.conf.eth6.input=1
net.mpls.conf.eth7.input=1
net.mpls.platform_labels=100000
net.ipv4.tcp_l3mdev_accept=1
EOF
```

`/etc/frr/daemon` で各種プロトコルデーモンを有効にしておく。